source: proto/parabix2/pablo_template_avx.cpp @ 2161

Last change on this file since 2161 was 1761, checked in by ksherdy, 8 years ago

Revert s2p 128,256.

File size: 14.6 KB
RevLine 
[972]1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include "../lib/lib_simd_avx.h"
7
8#define BLOCK_SIZE (sizeof(SIMD_type) * 8)
9#define SEGMENT_BLOCKS 12
10#define BUFFER_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
11#define OVERLAP_BUFSIZE (sizeof(SIMD_type))
12
13#include "xmldecl.h"
14#include "namechars.h"
[1757]15#include "../lib/bitblock.hpp"
[1497]16#include "../lib/carryQ_avx.h"
[972]17#include "../lib/perflib/perfsec.h"
[1761]18#include "../lib/s2p.hpp"
[972]19
20#include "TagMatcher_avx.h"
21#include "LineColTracker.h"
[1497]22#include "ErrorUtil.h"
23#include "ErrorTracker.h"
24#include "XMLTestSuiteError.h"
[972]25
26#ifdef BUFFER_PROFILING
27        BOM_Table * parser_timer;
28
29#elif CODE_CLOCKER
30        #define NUM_EVENTS 1
31        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
32        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
33        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
34        int cal_size = 20;
35        CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size);
36#else
37        void * parser_timer;
38#endif
39
40int block_base=0;
41int buffer_base=0;
42char * source;
[1497]43
[972]44LineColTracker tracker;
45TagMatcher matcher;
[1497]46ErrorTracker error_tracker;
[972]47BitBlock EOF_mask = simd_const_1(1);
48
[1497]49/* StreamScan & Post Process Declarations */
50//      static inline int StreamScanToFirst(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block)
51static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block);
[972]52
[1497]53static inline int NameStrt_check(int pos);
54static inline int Name_check(int pos);
55static inline int PIName_check(int pos);
56static inline int CD_check(int pos);
57static inline int GenRef_check(int pos);
58static inline int HexRef_check(int pos);
59static inline int DecRef_check(int pos);
60static inline int AttRef_check(int pos);
61
62@global
63
64static inline void s2p_do_block(BytePack U8[], Basis_bits & basis_bits);
65static inline void s2p_do_final_block(BytePack U8[], Basis_bits & basis_bits, BitBlock EOF_mask);
66static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, int chars_avail);
67
68void do_process(FILE *infile, FILE *outfile);
69
70int main(int argc, char * argv[]) {
71        char * infilename, * outfilename;
72        FILE *infile, *outfile;
73        struct stat fileinfo;
74
75        if (argc < 2) {
76                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
77                exit(-1);
78        }
79
80        infilename = argv[1];
81        stat(infilename, &fileinfo);
82        infile = fopen(infilename, "rb");
83        if (!infile) {
84                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
85                exit(-1);
86        }
87
88        if (argc < 3) outfile = stdout;
89        else {
90                outfilename = argv[2];
91                outfile = fopen(outfilename, "wb");
92                if (!outfile) {
93                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
94                        exit(-1);
95                }
96        }
97
98//      PERF_SEC_BIND(1);
99
100        PERF_SEC_INIT(parser_timer);
101
102        do_process(infile, outfile);
103
104        PERF_SEC_DUMP(parser_timer);
105
106        PERF_SEC_DESTROY(parser_timer);
107
108        fclose(infile);
109        fclose(outfile);
110
111        return(0);
112}
113
114/* s2p Definitions */
115static inline void s2p_do_block(BytePack U8[], Basis_bits & basis_bits) {
116  s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
117        basis_bits.bit_0, basis_bits.bit_1, basis_bits.bit_2, basis_bits.bit_3, basis_bits.bit_4, basis_bits.bit_5, basis_bits.bit_6, basis_bits.bit_7);
118}
119
120static inline void s2p_do_final_block(BytePack U8[], Basis_bits & basis_bits, BitBlock EOF_mask) {
121  s2p_do_block(U8, basis_bits);
122  basis_bits.bit_0 = simd_and(basis_bits.bit_0, EOF_mask);
123  basis_bits.bit_1 = simd_and(basis_bits.bit_1, EOF_mask);
124  basis_bits.bit_2 = simd_and(basis_bits.bit_2, EOF_mask);
125  basis_bits.bit_3 = simd_and(basis_bits.bit_3, EOF_mask);
126  basis_bits.bit_4 = simd_and(basis_bits.bit_4, EOF_mask);
127  basis_bits.bit_5 = simd_and(basis_bits.bit_5, EOF_mask);
128  basis_bits.bit_6 = simd_and(basis_bits.bit_6, EOF_mask);
129  basis_bits.bit_7 = simd_and(basis_bits.bit_7, EOF_mask);
130}
131
132
133/* StreamScan & Post Process Definitions */
134static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block) {
135
[972]136        int blk;
137        int block_pos = 0;
[1497]138        int pos;
[972]139
140        for (blk = 0; blk < blk_count; blk++) {
141                ScanBlock s = stream[blk];
142                while(s) {
[1497]143                        pos = (cfzl(s) + block_pos);
144                        int code = (ProcessPos(pos));
145                        if (code) {
146                                *error_pos_in_block = pos;
147                                return code; // error code
148                        }
[972]149                        s = s & (s-1);  // clear rightmost bit.
150                }
151                block_pos += 8 * sizeof(ScanBlock);
152        }
153        return 0;
154}
155
156static inline int NameStrt_check(int pos) {
157        int block_pos = block_base + pos;
158        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
[1497]159              return XMLTestSuiteError::NAME_START;
[972]160        }
161        return 0;
162}
163
164static inline int Name_check(int pos) {
165        int block_pos = block_base + pos;
166        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
[1497]167                  return XMLTestSuiteError::NAME;
[972]168        }
169        return 0;
170}
171
172static inline int PIName_check(int pos) {
173        int block_pos = block_base + pos;
174        int file_pos = block_pos+buffer_base;
175        if (at_XxMmLll<ASCII>((unsigned char*)&source[block_pos]) && (source[block_pos+3]=='?' || source[block_pos+3]<= ' ')) {
176              // "<?xml" legal at start of file.
[1497]177              if (!((file_pos == 2) && at_XmlDecl_start<ASCII>((unsigned char*)&source[0]))) {
178                  return XMLTestSuiteError::XMLPINAME;
179              }
[972]180        }
181        return 0;
182}
183
184static inline int CD_check(int pos) {
185        int block_pos = block_base + pos;
186        if (!at_CDATA1<ASCII>((unsigned char*)&source[block_pos])){
[1497]187                  return XMLTestSuiteError::CDATA;
[972]188        }
189        return 0;
190}
191
192static inline int GenRef_check(int pos) {
193        int block_pos = block_base + pos;
194        unsigned char* s = (unsigned char*)&source[block_pos];
195        if (!(at_Ref_gt<ASCII>(s)||at_Ref_lt<ASCII>(s)||at_Ref_amp<ASCII>(s)||at_Ref_quot<ASCII>(s)||at_Ref_apos<ASCII>(s))){
[1497]196              return XMLTestSuiteError::UNDEFREF;
[972]197        }
198        return 0;
199}
200
201static inline int HexRef_check(int pos) {
202        int block_pos = block_base + pos;
203        unsigned char* s = (unsigned char*)&source[block_pos];
204        int ch_val = 0;
205        while(at_HexDigit<ASCII>(s)){
206          ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
207          if (ch_val> 0x10FFFF ){
[1497]208                return XMLTestSuiteError::CHARREF;
[972]209          }
210          s++;
211        }
212        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
[1497]213          return XMLTestSuiteError::CHARREF;
[972]214        }
215        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
[1497]216          return XMLTestSuiteError::XML10CHARREF;
[972]217        }
218        return 0;
219}
220
221static inline int DecRef_check(int pos) {
222        int block_pos = block_base + pos;
223        unsigned char* s = (unsigned char*)&source[block_pos];
224        int ch_val = 0;
225        while(at_HexDigit<ASCII>(s)){
226          ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
227          if (ch_val> 0x10FFFF ){
[1497]228                        return XMLTestSuiteError::CHARREF;
[972]229          }
230          s++;
231        }
232        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
[1497]233                  return XMLTestSuiteError::CHARREF;
[972]234        }
235        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
[1497]236                  return XMLTestSuiteError::XML10CHARREF;
[972]237        }
238        return 0;
239}
240
241static inline int AttRef_check(int pos) {
242        int block_pos = block_base + pos;
243        unsigned char* s = (unsigned char*)&source[block_pos];
244        int ch_val = 0;
245        if(s[0]=='#'){
246          s++;
247          if(s[0]=='x' || s[0]=='X'){
248            s++;
249            while(at_HexDigit<ASCII>(s)){
250              ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
251              s++;
252            }
253          }
254          else{
255            while(at_HexDigit<ASCII>(s)){
256              ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
257              s++;
258            }
259          }
260          if (ch_val==60){
[1497]261            return XMLTestSuiteError::ATTREF;
[972]262          }
263        }
264        else if(at_Ref_lt<ASCII>(s)){
[1497]265          return XMLTestSuiteError::ATTREF;
[972]266        }
267        return 0;
268}
269
270static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, int chars_avail){
271            tracker.StoreNewlines(lex.LF);
[1497]272            int rv, error_pos_in_block, error_line, error_column;
[972]273
274                if (bitblock_has_bit(simd_or(check_streams.non_ascii_name_starts, check_streams.non_ascii_names))) {
[1497]275                  rv = StreamScan((ScanBlock *) &check_streams.non_ascii_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check, &error_pos_in_block);
276                  if (rv) {
277                          tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
278                          ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
279                          exit(-1);
280                  }
281
282                  rv = StreamScan((ScanBlock *) &check_streams.non_ascii_names, sizeof(BitBlock)/sizeof(ScanBlock), Name_check, &error_pos_in_block);
283                  if (rv) {
284                          tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
285                          ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
286                          exit(-1);
287                  }
[972]288                }
289
290                if (bitblock_has_bit(ctCDPI_Callouts.PI_name_starts)){
[1497]291                  rv = StreamScan((ScanBlock *) &ctCDPI_Callouts.PI_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check, &error_pos_in_block);
292                  if (rv) {
293                          tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
294                          ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
295                          exit(-1);
296                  }
[972]297                }
298
299                if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
[1497]300                  rv = StreamScan((ScanBlock *) &ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check, &error_pos_in_block);
301                  if (rv) {
302                          tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
303                          ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
304                          exit(-1);
305                  }
[972]306                }
307
308                if (bitblock_has_bit(ref_Callouts.GenRef_starts)){
[1497]309                  rv = StreamScan((ScanBlock *) &ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check, &error_pos_in_block);
310                  if (rv) {
311                          tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
312                          ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
313                          exit(-1);
314                  }
[972]315                }
316
317                if (bitblock_has_bit(ref_Callouts.DecRef_starts)){
[1497]318                  rv = StreamScan((ScanBlock *) &ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check, &error_pos_in_block);
319                  if (rv) {
320                          tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
321                          ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
322                          exit(-1);
323                  }
[972]324                }
325
326                if (bitblock_has_bit(ref_Callouts.HexRef_starts)){
[1497]327                  rv = StreamScan((ScanBlock *) &ref_Callouts.HexRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check, &error_pos_in_block);
328                  if (rv) {
329                          tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
330                          ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
331                          exit(-1);
332                  }
[972]333                }
334
335                if (bitblock_has_bit(check_streams.att_refs)){
[1497]336                  rv = StreamScan((ScanBlock *) &check_streams.att_refs, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check, &error_pos_in_block);
337                  if (rv) {
338                          tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
339                          ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
340                          exit(-1);
341                  }
[972]342                }
343
[1497]344                if(error_tracker.Has_Noted_Error()){
345                        tracker.get_Line_and_Column(error_tracker.Noted_Pos_In_Block(), error_line, error_column);
346                        ReportError(error_tracker.Noted_Error_Msg(), error_line, error_column);
347                        exit(-1);
[972]348                }
349
[1497]350                matcher.store_streams(check_streams.tag_marks, check_streams.name_follows, check_streams.misc_mask, chars_avail);
[972]351                tracker.AdvanceBlock();
352}
353
354void do_process(FILE *infile, FILE *outfile) {
355
356@decl
357
358  int buf_pos = 0;
359  int block_pos = 0;
360  int errpos = 0;
361  int chars_avail = 0;
362  int check_pos = 0;
363  int chars_read = 0;
364  BytePack buf[(BUFFER_SIZE+BLOCK_SIZE+OVERLAP_BUFSIZE*2)/sizeof(SIMD_type)];
365
366  char * srcbuf = ((char *) buf) + OVERLAP_BUFSIZE;
367  buffer_base = buf_pos;
368  source = srcbuf;
369
370  chars_read = fread((void *)srcbuf, 1, BUFFER_SIZE + OVERLAP_BUFSIZE, infile);
371  chars_avail = chars_read;
372  if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
373
374  matcher.setSrc(srcbuf);
375
376  if(chars_read<4){
377    fprintf(stderr,"File is too short. Not well formed.\n");
378    exit(-1);
379  }
380
381  Entity_Info * e = new Entity_Info;
382  e->AnalyzeSignature((unsigned char *)srcbuf);
383
384  if (e->code_unit_base == ASCII) {
385
386    XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
387
388    decl_parser.ReadXMLInfo(*e);
389
390    if (e->code_unit_size != SingleByte || (e->has_encoding_decl && (!at_UTF_8(e->encoding)))){
391        fprintf(stderr,"Sorry, this xmlwf demo only works for UTF-8.\n");
392        exit(-1);
393    }
394  }
395  else {
396    fprintf(stderr,"Sorry, this xmlwf demo does not process EBCDIC.\n");
397        exit(-1);
398  }
399
400  if (e->content_start != 0) {
401        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_read - e->content_start);
402        buf_pos = e->content_start;
403        if (chars_avail == BUFFER_SIZE) {
404                chars_read = chars_read - e->content_start +
405                             fread(&srcbuf[chars_read-e->content_start], 1, e->content_start, infile);
406                chars_avail = chars_read;
407                if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
408        }
409        else {
410          chars_read -=e->content_start;
411          chars_avail -=e->content_start;
412        }
413  }
414
415@stream_stmts
416
417/* Full Buffers */
418
419    while (chars_avail == BUFFER_SIZE) {
420      PERF_SEC_START(parser_timer);
421      for (int blk = 0; blk < SEGMENT_BLOCKS; blk++) {
422          block_base = blk*BLOCK_SIZE;
423          s2p_do_block((BytePack *) &srcbuf[block_base], basis_bits);
424          @block_stmts
[1497]425          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, chars_avail);
[972]426      }
427      matcher.StreamScan(chars_avail);
428      matcher.Advance_buffer();
429      tracker.Advance_buffer();
430      PERF_SEC_END(parser_timer, chars_avail);
[1497]431
[972]432      int bytes_left = chars_read - chars_avail;
433      memmove(srcbuf, &srcbuf[BUFFER_SIZE], bytes_left);
434      chars_read = fread(&srcbuf[bytes_left],1, BUFFER_SIZE + OVERLAP_BUFSIZE - bytes_left, infile) + bytes_left;
435      chars_avail = chars_read;
436      if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
437      buf_pos += chars_avail;
438      buffer_base = buf_pos;
439    }
440/* Final Partial Buffer */
441    PERF_SEC_START(parser_timer);
442
443    block_pos = 0;
444    int remaining = chars_avail;
445/* Full Blocks */
446    while (remaining >= BLOCK_SIZE) {
447          block_base = block_pos;
448          s2p_do_block((BytePack *) &srcbuf[block_pos], basis_bits);
449          @block_stmts
450          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, chars_avail);
451          block_pos += BLOCK_SIZE;
452          remaining -= BLOCK_SIZE;
453    }
454    block_base = block_pos;
455    if (remaining > 0 || @any_carry) {
456          EOF_mask = sisd_srl(simd_const_1(1),sisd_from_int(BLOCK_SIZE-remaining));
457          s2p_do_final_block((BytePack *) &srcbuf[block_pos], basis_bits, EOF_mask);
458          @final_block_stmts
459          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, chars_avail);
460    }
461    buf_pos += chars_avail;
462    buffer_base = buf_pos;
463
464    matcher.StreamScan(chars_avail);
465    matcher.Advance_buffer();
466    tracker.Advance_buffer();
467
468
469    PERF_SEC_END(parser_timer, chars_avail);
470    if (matcher.depth != 0) {
471      fprintf(stderr, "tag matching error (depth %i) at position %i\n", matcher.depth, buffer_base);
472      exit(-1);
473    }
474}
475
Note: See TracBrowser for help on using the repository browser.