source: proto/CSV/csv2xml/standalone/post_process.cpp @ 3383

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

first version of standalone PabloAPI

File size: 10.3 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#include "pablo_api.hpp"
90using PabloAPI::Basis_bits;
91
92//////////////////////////////////////////////////////////////////////////////////////////
93// Headers that depend @ global stream struct types.
94//////////////////////////////////////////////////////////////////////////////////////////
95#include "../lib/transpose.hpp"
96#include "../util/csv2xmlwriter.hpp"
97#include "../util/bitsegment_iterator.hpp"
98
99static void do_process(FILE *infile, FILE *outfile);
100
101const BitBlock ZERO = convert(0);
102const BitBlock ONE = convert(1);
103const BitBlock HIGH_ONE = bitblock::slli<BLOCK_SIZE-1>(convert(1));
104
105int main(int argc, char * argv[])
106{
107    char infilename[100] = "sample.csv";
108    char outfilename[100] = "sample_xml.txt";
109
110    UseTabSignal = ZERO;
111    if (argc == 3)
112    {
113        strcpy(infilename, argv[1]);
114        strcpy(outfilename, argv[2]);
115    }
116    else if (argc == 4)
117    {
118        if (strcmp(argv[1], "-tab") != 0)
119        {
120            printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
121            return 0;
122        }
123        else
124        {
125            UseTabSignal = ONE;
126            strcpy(infilename, argv[2]);
127            strcpy(outfilename, argv[3]);
128        }
129    }
130    else
131    {
132        printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
133    }
134
135    printf("Process %s as input and %s as output\n", infilename, outfilename);
136
137    FILE *infile = fopen(infilename, "rb");
138    FILE *outfile = fopen(outfilename, "wb");
139    setbuf(outfile, NULL); //shutdown default buffer system
140    // printf("setvbuf = %d\n", setvbuf(outfile, NULL, _IOFBF, SEGMENT_SIZE * 16));
141
142    PERF_SEC_BIND(1);
143
144    PERF_SEC_INIT(parser_timer);
145
146    do_process(infile, outfile);
147
148    PERF_SEC_DUMP(parser_timer);
149
150    PERF_SEC_DESTROY(parser_timer);
151
152    fclose(infile);
153    fclose(outfile);
154
155    return(0);
156}
157
158class IteratorPackage
159{
160public:
161    BitSegment<SEGMENT_BLOCKS> delimSeg, eolSeg, andSeg, hideSeg;
162
163    IteratorPackage()
164    {
165        init();
166    }
167
168    void init()
169    {
170        delimSeg.clear();
171        eolSeg.clear();
172        andSeg.clear();
173        hideSeg.clear();
174    }
175
176    void append(PabloAPI::Marker &marker, PabloAPI::Lex &lex)
177    {
178        delimSeg.append(marker.delim);
179        eolSeg.append(marker.eol);
180        andSeg.append(lex.AndSymbol);
181        hideSeg.append(marker.hide);
182    }
183};
184
185class BufferToXMLParser
186{
187    BitSegmentForwardIterator delimIter, eolIter, andIter, hideIter;
188    uint8_t *src_buffer;
189    Csv2XmlWriter *writer;
190    IteratorPackage *package;
191
192public:
193
194    BufferToXMLParser(uint8_t *buffer, Csv2XmlWriter *_writer, IteratorPackage *_package, int n)
195        : delimIter(_package->delimSeg.address(), n), eolIter(_package->eolSeg.address(), n),
196            andIter(_package->andSeg.address(), n), hideIter(_package->hideSeg.address(), n)
197    {
198        src_buffer = buffer;
199        writer = _writer;
200        package = _package;
201    }
202
203    void parseEachRow(int buffer_size)
204    {
205        int pos = 0;
206
207        while (!eolIter.is_end())
208        {
209            parseRowWithoutLastColumn(pos, *eolIter);
210
211            if (pos <= *eolIter)
212            {
213                int length = *eolIter - pos;
214                bufPrintWithAndSymbol(pos, length);
215                writer->nextCol();
216            }
217            pos = *eolIter + 1;
218
219            ++ eolIter;
220            writer->nextRow();
221        }
222
223        if (pos <= buffer_size)
224        {
225            //last line within a block
226            parseRowWithoutLastColumn(pos, buffer_size);
227
228            if (pos < buffer_size)
229            {
230                int length = buffer_size - pos;
231                bufPrintWithAndSymbol(pos, length);
232            }
233        }
234    }
235
236private:
237    void parseRowWithoutLastColumn(int &pos, int endofline)
238    {
239        while ((!delimIter.is_end()) && (*delimIter < endofline))
240        {
241            int length = *delimIter - pos;
242            bufPrintWithAndSymbol(pos, length);
243            writer->nextCol();
244            pos = (*delimIter) + 1;
245            ++delimIter;
246        }
247    }
248
249    void bufPrintWithAndSymbol(int startPos, int length)
250    {
251        char text[10] = "&amp;";
252
253        while (length > 0)
254        {
255            while ((!andIter.is_end()) && *andIter < startPos) ++andIter;
256
257            if (!andIter.is_end() && *andIter < startPos + length)
258            {
259                bufPrintWithHideSymbol(startPos, *andIter - startPos);
260                writer->writeColumn(text, 5);
261
262                length -= *andIter - startPos + 1;
263                startPos = *andIter + 1;
264            }
265            else
266            {
267                bufPrintWithHideSymbol(startPos, length);
268                length = 0;
269            }
270        }
271    }
272
273    void bufPrintWithHideSymbol(int startPos, int length)
274    {
275        while (length > 0)
276        {
277            while (!hideIter.is_end() && *hideIter < startPos) ++hideIter;
278
279            if (!hideIter.is_end() && *hideIter < startPos + length)
280            {
281                bufPrintSimple(startPos, *hideIter - startPos);
282                length -= *hideIter - startPos + 1;
283                startPos = *hideIter + 1;
284            }
285            else
286            {
287                bufPrintSimple(startPos, length);
288                length = 0;
289            }
290        }
291    }
292
293    void bufPrintSimple(int startPos, int length)
294    {
295        uint8_t *p = src_buffer + startPos;
296        writer->writeColumn((char *)p, length);
297    }
298};
299
300void do_process(FILE *infile, FILE *outfile) {
301   
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    Csv2XmlWriter writer(outfile);
311    FlipSignal = ZERO;
312
313    bool infile_end = false;
314    int segment_count;
315    int segment_blocks;
316    unsigned long long infile_count = 0;
317    IteratorPackage package;
318
319    while (!infile_end)
320    {
321        segment_count = 0;
322        segment_blocks = 0;
323        package.init();
324        PERF_SEC_START(parser_timer);
325
326
327        //if quoted string spanned more than 1 block, next block's FlipSignal should be 1
328        while (segment_blocks < SEGMENT_BLOCKS && (count = fread(src_buffer, sizeof(uint8_t), BLOCK_SIZE, infile)) > 0)
329        {
330            memcpy(seg_buffer + segment_count, src_buffer, count);
331            segment_blocks ++;
332            segment_count += count;
333            infile_count += count;
334
335            if (count < BLOCK_SIZE)
336            {
337                EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-count));
338                s2p_do_final_block((BytePack *) src_buffer, PabloAPI::basis_bits, EOF_mask);
339                PabloAPI::do_final_block_stmts();
340            }
341            else
342            {
343                s2p_do_block((BytePack *) src_buffer, PabloAPI::basis_bits);
344                PabloAPI::do_block_stmts();
345                FlipSignal = ZERO;
346                if (bitblock::any(simd_and(PabloAPI::marker.quote_mask, HIGH_ONE)))
347                {
348                    FlipSignal = ONE;
349                }
350            }
351
352            package.append(PabloAPI::marker, PabloAPI::lex);
353        }
354
355        if (segment_count)
356        {
357            BufferToXMLParser bufParser(seg_buffer, &writer, &package, segment_blocks);
358            bufParser.parseEachRow(segment_count);
359            writer.flush();
360
361            PERF_SEC_END(parser_timer, segment_count);
362        }
363
364        if (segment_blocks < SEGMENT_BLOCKS)
365        {
366            infile_end = true;
367        }
368    }
369
370
371    printf("input: %lld\t", infile_count);
372    printf("output: %lld\t", writer._outCount);
373    printf("rate: %lf\n", (double) writer._outCount / (double) infile_count);
374}
Note: See TracBrowser for help on using the repository browser.