source: proto/charsetcompiler/grep_template.cpp @ 4150

Last change on this file since 4150 was 3978, checked in by cameron, 5 years ago

Bug fix for Advance chains; if-hierarchy options; grep option

File size: 7.8 KB
Line 
1// Stream struct and function headers and definitions
2
3#include <simd-lib/bitblock.hpp>
4#include <simd-lib/carryQ.hpp>
5#include <simd-lib/pabloSupport.hpp>
6
7#define LocalCarryDeclare(name, count)\
8CarryArray<count, 0> name;\
9
10#define assert_0_error(errkind, errstrm)
11
12BitBlock EOF_mask = simd<1>::constant<1>();
13
14// XMLWF application headers and definitions
15#include <stdio.h>
16#include <stdlib.h>
17#include <unistd.h>
18#include <errno.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21
22#include <simd-lib/s2p.hpp>
23#include <simd-lib/buffer.hpp>
24#include <simd-lib/bitblock_iterator.hpp>
25#include <simd-lib/perflib/perfsec.h>
26
27
28#ifdef BUFFER_PROFILING
29        BOM_Table * parser_timer;
30#elif PAPI
31                #define PAPI_EVENTS_COUNT 2
32                int PAPI_EVENTS[PAPI_EVENTS_COUNT] = {PAPI_TOT_CYC, PAPI_BR_MSP};       
33        CC * parser_timer;
34#else
35        void * parser_timer;
36#endif
37
38#define SEGMENT_BLOCKS 15
39#define SEGMENT_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
40
41#define BUFFER_SEGMENTS 15
42#define BUFFER_SIZE (BUFFER_SEGMENTS * SEGMENT_SIZE)
43@global
44
45#include <simd-lib/transpose.hpp>
46
47static void do_process(FILE *infile, FILE *outfile, int count_only_option);
48
49int main(int argc, char * argv[]) {
50
51        char * infilename, * outfilename;
52        FILE *infile, *outfile;
53
54        int opt_code;
55        int count_only_option = 0;
56        int print_version_option = 0;
57        while ( (opt_code = getopt(argc, argv, "cv")) != -1) {
58                switch (opt_code) {
59                case 'c':
60                        count_only_option = 1;
61                        break;
62                case 'v':
63                        print_version_option = 1;
64                        break;
65                case '?':
66                        break;
67                default:
68                        printf ("Invalid option: %c\n", opt_code);
69                        printf("Usage: %s [-c] [-v] <filename> [<outputfile>]\n", argv[0]);
70                                        exit(-1);
71                }
72        }
73       
74       
75        if (optind >= argc) {
76                printf ("Too few arguments\n");
77                printf("Usage: %s [-c] [-v] <filename> [<outputfile>]\n", argv[0]);
78                exit(-1);
79        }
80
81        infilename = argv[optind++];
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 (optind >= argc) outfile = stdout;
89        else {
90                outfilename = argv[optind++];
91                if (optind != argc) {
92                        printf ("Too many arguments\n");
93                        printf("Usage: %s [-c] [-v] <filename> [<outputfile>]\n", argv[0]);
94                        exit(-1);
95                }
96
97
98                outfile = fopen(outfilename, "wb");
99                if (!outfile) {
100                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
101                        exit(-1);
102                }
103        }
104
105
106        if (print_version_option) {
107                fprintf(outfile, "Parabix grep implementation: July 2013\n");
108        }
109
110        PERF_SEC_BIND(1);
111
112        PERF_SEC_INIT(parser_timer);
113
114        do_process(infile, outfile, count_only_option);
115
116        PERF_SEC_DUMP(parser_timer);
117
118        PERF_SEC_DESTROY(parser_timer);
119
120        fclose(infile);
121        fclose(outfile);
122
123        return(0);
124}
125
126void do_process(FILE *infile, FILE *outfile, int count_only_option) {
127
128        @decl
129
130        bool line_match_found=false;
131
132        BitBlock match_vector = simd<1>::constant<0>();
133        int match_count=0;
134        int blk = 0;
135        int block_base  = 0;
136        int block_pos   = 0;
137        int buffer_base = 0;
138        int buffer_pos  = 0;
139        int chars_avail = 0;
140        int chars_read  = 0;
141
142        int line_start, line_end, match_pos, line_no;
143        line_no = 0;
144
145        BitStreamScanner<BitBlock, uint64_t, uint64_t, SEGMENT_BLOCKS> LF_scanner;
146        BitStreamScanner<BitBlock, uint64_t, uint64_t, SEGMENT_BLOCKS> match_scanner;
147        ATTRIBUTE_SIMD_ALIGN char src_buffer[SEGMENT_SIZE];     
148       
149        chars_read = fread((void *)&src_buffer[0], 1, SEGMENT_SIZE, infile);
150        chars_avail = chars_read;
151        if (chars_avail >= SEGMENT_SIZE) chars_avail = SEGMENT_SIZE;
152
153
154        @stream_stmts
155
156//////////////////////////////////////////////////////////////////////////////////////////
157// Full Segments
158//////////////////////////////////////////////////////////////////////////////////////////
159       
160        while (chars_avail >= SEGMENT_SIZE) {
161                LF_scanner.init();
162                match_scanner.init();
163
164                PERF_SEC_START(parser_timer);
165                for (blk = 0; blk < SEGMENT_BLOCKS; blk++) {
166                        block_base = blk*BLOCK_SIZE;
167                        s2p_do_block((BytePack *) &src_buffer[block_base], basis_bits);
168
169                        @block_stmts
170
171                        LF_scanner.load_block(lex.LF, blk);
172                        match_scanner.load_block(output.matches, blk);
173                        if (count_only_option) {
174                          if (bitblock::any(output.matches)) {
175                                if (bitblock::any(simd_and(match_vector, output.matches))) {
176                                  match_count += bitblock::popcount(match_vector);
177                                  match_vector = output.matches;
178                                }
179                                else {
180                                  match_vector = simd_or(match_vector, output.matches);
181                                }
182                          }
183                        }
184
185                }
186 
187                demo.clear();
188                 
189                int copy_back_pos = LF_scanner.get_final_pos() + 1;
190                int copy_back_size = SEGMENT_SIZE - copy_back_pos;
191
192                match_scanner.clear_from(copy_back_pos);
193
194
195                if (!count_only_option) {
196                        line_start = 0;
197
198                        while (match_scanner.has_next()) {
199                                match_pos = match_scanner.scan_to_next();       
200                                line_end = LF_scanner.scan_to_next();
201                                while (line_end < match_pos) { 
202                                        line_start = line_end+1;
203                                        line_no++; 
204                                        line_end = LF_scanner.scan_to_next();
205                                }
206                                fwrite(&src_buffer[line_start], 1, line_end - line_start + 1, outfile);
207                                line_start = line_end+1;
208                                line_no++; 
209                        }
210                        while (LF_scanner.has_next()) {
211                                line_end = LF_scanner.scan_to_next();
212                                line_no++;
213                        }       
214                }
215
216                memmove(&src_buffer[0], &src_buffer[copy_back_pos], copy_back_size);
217
218                PERF_SEC_END(parser_timer, chars_avail);
219
220                chars_read = fread(&src_buffer[copy_back_size], 1, copy_back_pos, infile);
221                chars_avail = chars_read + copy_back_size;
222                if (chars_avail >= SEGMENT_SIZE) chars_avail = SEGMENT_SIZE;
223                buffer_pos += chars_avail;
224                buffer_base = buffer_pos;
225        }
226
227
228//////////////////////////////////////////////////////////////////////////////////////////
229// Final Partial Segment
230//////////////////////////////////////////////////////////////////////////////////////////
231        PERF_SEC_START(parser_timer);
232
233        block_pos = 0;
234        int remaining = chars_avail;
235
236
237        LF_scanner.init();
238        match_scanner.init();
239
240        /* Full Blocks */
241        blk = 0;
242        while (remaining >= BLOCK_SIZE) {
243                block_base = block_pos;
244                s2p_do_block((BytePack *) &src_buffer[block_pos], basis_bits);
245                @block_stmts
246                LF_scanner.load_block(lex.LF, blk);
247                match_scanner.load_block(output.matches, blk);
248                        if (count_only_option) {
249                          if (bitblock::any(output.matches)) {
250                                if (bitblock::any(simd_and(match_vector, output.matches))) {
251                                  match_count += bitblock::popcount(match_vector);
252                                  match_vector = output.matches;
253                                }
254                                else {
255                                  match_vector = simd_or(match_vector, output.matches);
256                                }
257                          }
258                        }
259                block_pos += BLOCK_SIZE;
260                remaining -= BLOCK_SIZE;
261                blk++;
262        }
263        block_base = block_pos;
264
265//    Partial Block or Any Carry
266//
267        EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-remaining));
268                                s2p_do_final_block((BytePack *) &src_buffer[block_pos], basis_bits, EOF_mask);
269        @final_block_stmts
270
271        if (count_only_option) {
272                match_count += bitblock::popcount(match_vector);
273                if (bitblock::any(output.matches)) {
274                        match_count += bitblock::popcount(output.matches);
275                }
276                fprintf(outfile, "Matching Lines:%d\n",match_count);
277        }
278        else {
279                LF_scanner.load_block(lex.LF, blk);
280                match_scanner.load_block(output.matches, blk);
281                blk++;
282
283                for (int i = blk; i < SEGMENT_BLOCKS; i++){
284                        LF_scanner.load_block(simd<1>::constant<0>(), i);
285                        match_scanner.load_block(simd<1>::constant<0>(), i);
286                }
287                line_start = 0;
288
289                while (match_scanner.has_next()) {
290                        match_pos = match_scanner.scan_to_next();       
291                        line_end = LF_scanner.scan_to_next();
292                        while (line_end < match_pos) { 
293                                line_start = line_end+1;
294                                line_no++; 
295                                line_end = LF_scanner.scan_to_next();
296                        }
297                        fwrite(&src_buffer[line_start], 1, line_end - line_start + 1, outfile);
298                        line_start = line_end+1;
299                        line_no++; 
300                }
301                while (LF_scanner.has_next()) {
302                        line_end = LF_scanner.scan_to_next();
303                        line_no++;     
304                }       
305        }
306
307        buffer_pos += chars_avail;
308        buffer_base = buffer_pos;
309
310        PERF_SEC_END(parser_timer, chars_avail);
311}
312
Note: See TracBrowser for help on using the repository browser.