source: proto/CSV/csv2xml/pablo_template.cpp @ 4177

Last change on this file since 4177 was 3382, checked in by linmengl, 6 years ago

add pabloSupport, fix tiny problem

File size: 10.2 KB
Line 
1#include <cstdio>
2#include <cstdlib>
3#include <cerrno>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <sstream>
7#include <cstring>
8
9#define LocalCarryDeclare(name, count)\
10CarryArray<count, 0> name;\
11
12#include "../lib/bitblock.hpp"
13#include "../lib/carryQ.hpp"
14#include "../lib/bitblock_iterator.hpp"
15#include "../lib/pabloSupport.hpp"
16#include "../lib/s2p.hpp"
17#include "../lib/perflib/perfsec.h"
18#include "../lib/pabloSupport.hpp"
19
20// Define the mappings for pablo.assert_0(strm, errkind) statements which
21// compile to the the form assert_0_error(errkind, strm)
22#define assert_0_error(errkind, errstrm) error_tracker.NoteError(errkind, errstrm);
23
24#ifdef BUFFER_PROFILING
25    BOM_Table * parser_timer;
26#elif CODE_CLOCKER
27    //#define NUM_EVENTS 1
28    //int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
29    //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
30    #define NUM_EVENTS 2
31    int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
32    int cal_size = 20;
33    CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size);
34#else
35    void * parser_timer;
36#endif
37
38BitBlock EOF_mask = simd<1>::constant<1>();
39
40//////////////////////////////////////////////////////////////////////////////////////////
41// Buffer Management // WARNING: Do Not update #defines. Results in TagMatcher errors.
42//////////////////////////////////////////////////////////////////////////////////////////
43#define PADDING_BLOCKS 0
44#define PADDING_SIZE (BLOCK_SIZE * PADDING_BLOCKS)
45#define COPYBACK_BLOCKS 2
46#define COPYBACK_SIZE (BLOCK_SIZE * COPYBACK_BLOCKS)
47#define LOOKAHEAD_BLOCKS 1
48#define LOOKAHEAD_SIZE (BLOCK_SIZE * LOOKAHEAD_BLOCKS)
49#define SEGMENT_BLOCKS 15 // WARNING: TagMatcher.hpp causes xmlconf test suite failures for SEGMENT_BLOCKS < 3.
50#define SEGMENT_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
51#define BUFFER_SIZE (COPYBACK_SIZE + SEGMENT_SIZE + LOOKAHEAD_SIZE + PADDING_SIZE)
52
53//////////////////////////////////////////////////////////////////////////////////////////
54// @ global depends on 'error_tracker' and 'EOF_mask' definitions.
55//////////////////////////////////////////////////////////////////////////////////////////
56BitBlock Simd_const_odd = simd<4>::constant<10>();
57BitBlock Simd_const_even = simd<4>::constant<5>();
58
59inline BitBlock parse_quote_mask(BitBlock quote)
60{
61    BitBlock p2, p4, p8, p16, p32, p64;
62    BitBlock t1, t2, t4, t8, t16, t32, t64;
63
64    t1 = bitblock::slli<1>(quote);
65    p2 = simd_xor(quote, t1);
66
67    t2 = bitblock::slli<2>(p2);
68    p4 = simd_xor(p2, t2);
69
70    t4 = bitblock::slli<4>(p4);
71    p8 = simd_xor(p4, t4);
72
73    t8 = bitblock::slli<8>(p8);
74    p16 = simd_xor(p8, t8);
75
76    t16 = bitblock::slli<16>(p16);
77    p32 = simd_xor(p16, t16);
78
79    t32 = bitblock::slli<32>(p32);
80    p64 = simd_xor(p32, t32);
81
82    t64 = bitblock::slli<64>(p64);
83    return simd_xor(p64, t64);
84}
85
86BitBlock FlipSignal;
87BitBlock UseTabSignal;
88
89@global
90
91//////////////////////////////////////////////////////////////////////////////////////////
92// Headers that depend @ global stream struct types.
93//////////////////////////////////////////////////////////////////////////////////////////
94#include "../lib/transpose.hpp"
95#include "../util/csv2xmlwriter.hpp"
96#include "../util/bitsegment_iterator.hpp"
97
98static void do_process(FILE *infile, FILE *outfile);
99
100const BitBlock ZERO = convert(0);
101const BitBlock ONE = convert(1);
102const BitBlock HIGH_ONE = bitblock::slli<BLOCK_SIZE-1>(convert(1));
103
104int main(int argc, char * argv[])
105{
106    char infilename[100] = "sample.csv";
107    char outfilename[100] = "sample_xml.txt";
108
109    UseTabSignal = ZERO;
110    if (argc == 3)
111    {
112        strcpy(infilename, argv[1]);
113        strcpy(outfilename, argv[2]);
114    }
115    else if (argc == 4)
116    {
117        if (strcmp(argv[1], "-tab") != 0)
118        {
119            printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
120            return 0;
121        }
122        else
123        {
124            UseTabSignal = ONE;
125            strcpy(infilename, argv[2]);
126            strcpy(outfilename, argv[3]);
127        }
128    }
129    else
130    {
131        printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
132    }
133
134    printf("Process %s as input and %s as output\n", infilename, outfilename);
135
136    FILE *infile = fopen(infilename, "rb");
137    FILE *outfile = fopen(outfilename, "wb");
138    setbuf(outfile, NULL); //shutdown default buffer system
139    // printf("setvbuf = %d\n", setvbuf(outfile, NULL, _IOFBF, SEGMENT_SIZE * 16));
140
141    PERF_SEC_BIND(1);
142
143    PERF_SEC_INIT(parser_timer);
144
145    do_process(infile, outfile);
146
147    PERF_SEC_DUMP(parser_timer);
148
149    PERF_SEC_DESTROY(parser_timer);
150
151    fclose(infile);
152    fclose(outfile);
153
154    return(0);
155}
156
157class IteratorPackage
158{
159public:
160    BitSegment<SEGMENT_BLOCKS> delimSeg, eolSeg, andSeg, hideSeg;
161
162    IteratorPackage()
163    {
164        init();
165    }
166
167    void init()
168    {
169        delimSeg.clear();
170        eolSeg.clear();
171        andSeg.clear();
172        hideSeg.clear();
173    }
174
175    void append(Marker &marker, Lex &lex)
176    {
177        delimSeg.append(marker.delim);
178        eolSeg.append(marker.eol);
179        andSeg.append(lex.AndSymbol);
180        hideSeg.append(marker.hide);
181    }
182};
183
184class BufferToXMLParser
185{
186    BitSegmentForwardIterator delimIter, eolIter, andIter, hideIter;
187    uint8_t *src_buffer;
188    Csv2XmlWriter *writer;
189    IteratorPackage *package;
190
191public:
192
193    BufferToXMLParser(uint8_t *buffer, Csv2XmlWriter *_writer, IteratorPackage *_package, int n)
194        : delimIter(_package->delimSeg.address(), n), eolIter(_package->eolSeg.address(), n),
195            andIter(_package->andSeg.address(), n), hideIter(_package->hideSeg.address(), n)
196    {
197        src_buffer = buffer;
198        writer = _writer;
199        package = _package;
200    }
201
202    void parseEachRow(int buffer_size)
203    {
204        int pos = 0;
205
206        while (!eolIter.is_end())
207        {
208            parseRowWithoutLastColumn(pos, *eolIter);
209
210            if (pos <= *eolIter)
211            {
212                int length = *eolIter - pos;
213                bufPrintWithAndSymbol(pos, length);
214                writer->nextCol();
215            }
216            pos = *eolIter + 1;
217
218            ++ eolIter;
219            writer->nextRow();
220        }
221
222        if (pos <= buffer_size)
223        {
224            //last line within a block
225            parseRowWithoutLastColumn(pos, buffer_size);
226
227            if (pos < buffer_size)
228            {
229                int length = buffer_size - pos;
230                bufPrintWithAndSymbol(pos, length);
231            }
232        }
233    }
234
235private:
236    void parseRowWithoutLastColumn(int &pos, int endofline)
237    {
238        while ((!delimIter.is_end()) && (*delimIter < endofline))
239        {
240            int length = *delimIter - pos;
241            bufPrintWithAndSymbol(pos, length);
242            writer->nextCol();
243            pos = (*delimIter) + 1;
244            ++delimIter;
245        }
246    }
247
248    void bufPrintWithAndSymbol(int startPos, int length)
249    {
250        char text[10] = "&amp;";
251
252        while (length > 0)
253        {
254            while ((!andIter.is_end()) && *andIter < startPos) ++andIter;
255
256            if (!andIter.is_end() && *andIter < startPos + length)
257            {
258                bufPrintWithHideSymbol(startPos, *andIter - startPos);
259                writer->writeColumn(text, 5);
260
261                length -= *andIter - startPos + 1;
262                startPos = *andIter + 1;
263            }
264            else
265            {
266                bufPrintWithHideSymbol(startPos, length);
267                length = 0;
268            }
269        }
270    }
271
272    void bufPrintWithHideSymbol(int startPos, int length)
273    {
274        while (length > 0)
275        {
276            while (!hideIter.is_end() && *hideIter < startPos) ++hideIter;
277
278            if (!hideIter.is_end() && *hideIter < startPos + length)
279            {
280                bufPrintSimple(startPos, *hideIter - startPos);
281                length -= *hideIter - startPos + 1;
282                startPos = *hideIter + 1;
283            }
284            else
285            {
286                bufPrintSimple(startPos, length);
287                length = 0;
288            }
289        }
290    }
291
292    void bufPrintSimple(int startPos, int length)
293    {
294        uint8_t *p = src_buffer + startPos;
295        writer->writeColumn((char *)p, length);
296    }
297};
298
299void do_process(FILE *infile, FILE *outfile) {
300
301    @decl;
302
303    BitBlock buf[9];//watch out buffer size, may cause memory leak!! shit!!
304    BitBlock segBuf[9 * SEGMENT_BLOCKS];
305
306    uint8_t * src_buffer = (uint8_t *) buf;
307    uint8_t * seg_buffer = (uint8_t *) segBuf;
308    size_t count;
309
310    @stream_stmts;
311
312    Csv2XmlWriter writer(outfile);
313    FlipSignal = ZERO;
314
315    bool infile_end = false;
316    int segment_count;
317    int segment_blocks;
318    unsigned long long infile_count = 0;
319    IteratorPackage package;
320
321    while (!infile_end)
322    {
323        segment_count = 0;
324        segment_blocks = 0;
325        package.init();
326        PERF_SEC_START(parser_timer);
327
328
329        //if quoted string spanned more than 1 block, next block's FlipSignal should be 1
330        while (segment_blocks < SEGMENT_BLOCKS && (count = fread(src_buffer, sizeof(uint8_t), BLOCK_SIZE, infile)) > 0)
331        {
332            memcpy(seg_buffer + segment_count, src_buffer, count);
333            segment_blocks ++;
334            segment_count += count;
335            infile_count += count;
336
337            if (count < BLOCK_SIZE)
338            {
339                EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-count));
340                s2p_do_final_block((BytePack *) src_buffer, basis_bits, EOF_mask);
341                @final_block_stmts
342            }
343            else
344            {
345                s2p_do_block((BytePack *) src_buffer, basis_bits);
346                @block_stmts
347                FlipSignal = ZERO;
348                if (bitblock::any(simd_and(marker.quote_mask, HIGH_ONE)))
349                {
350                    FlipSignal = ONE;
351                }
352            }
353
354            package.append(marker, lex);
355        }
356
357        if (segment_count)
358        {
359            BufferToXMLParser bufParser(seg_buffer, &writer, &package, segment_blocks);
360            bufParser.parseEachRow(segment_count);
361            writer.flush();
362
363            PERF_SEC_END(parser_timer, segment_count);
364        }
365
366        if (segment_blocks < SEGMENT_BLOCKS)
367        {
368            infile_end = true;
369        }
370    }
371
372
373    printf("input: %lld\t", infile_count);
374    printf("output: %lld\t", writer._outCount);
375    printf("rate: %lf\n", (double) writer._outCount / (double) infile_count);
376}
Note: See TracBrowser for help on using the repository browser.