source: proto/grepdebug/grep_template.cpp @ 4911

Last change on this file since 4911 was 4517, checked in by cameron, 5 years ago

grep debugging template for icgrep using -print-pablo

File size: 11.3 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// mmap system
39#include <sys/mman.h>
40#include <fcntl.h>
41
42#if (BLOCK_SIZE == 128)
43#define SEGMENT_BLOCKS 7
44#endif
45
46#if (BLOCK_SIZE == 256)
47#define SEGMENT_BLOCKS 15
48#endif
49
50#define SEGMENT_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
51
52#define BUFFER_SEGMENTS 15
53#define BUFFER_SIZE (BUFFER_SEGMENTS * SEGMENT_SIZE)
54@global
55
56#include <simd-lib/transpose.hpp>
57
58#define USE_MMAP
59
60#ifndef USE_MMAP
61static void do_process(FILE *infile, FILE *outfile, int count_only_option);
62#endif
63#ifdef USE_MMAP
64static void do_process(char * infile_buffer, size_t infile_size, FILE *outfile, int count_only_option);
65#endif
66
67int main(int argc, char * argv[]) {
68
69        char * infilename, * outfilename;
70        FILE *infile, *outfile;
71#ifdef USE_MMAP
72    int fdSrc;
73    struct stat infile_sb;
74    char * infile_buffer;
75#endif
76
77
78        int opt_code;
79        int count_only_option = 0;
80        int print_version_option = 0;
81        while ( (opt_code = getopt(argc, argv, "cv")) != -1) {
82                switch (opt_code) {
83                case 'c':
84                        count_only_option = 1;
85                        break;
86                case 'v':
87                        print_version_option = 1;
88                        break;
89                case '?':
90                        break;
91                default:
92                        printf ("Invalid option: %c\n", opt_code);
93                        printf("Usage: %s [-c] [-v] <filename> [<outputfile>]\n", argv[0]);
94                                        exit(-1);
95                }
96        }
97       
98       
99        if (optind >= argc) {
100                printf ("Too few arguments\n");
101                printf("Usage: %s [-c] [-v] <filename> [<outputfile>]\n", argv[0]);
102                exit(-1);
103        }
104
105        infilename = argv[optind++];
106#ifndef USE_MMAP
107        infile = fopen(infilename, "rb");
108        if (!infile) {
109                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
110                exit(-1);
111        }
112#endif
113
114        if (optind >= argc) outfile = stdout;
115        else {
116                outfilename = argv[optind++];
117                if (optind != argc) {
118                        printf ("Too many arguments\n");
119                        printf("Usage: %s [-c] [-v] <filename> [<outputfile>]\n", argv[0]);
120                        exit(-1);
121                }
122
123
124                outfile = fopen(outfilename, "wb");
125                if (!outfile) {
126                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
127                        exit(-1);
128                }
129        }
130
131#ifdef USE_MMAP
132    fdSrc = open(infilename, O_RDONLY);
133    if (fdSrc == -1) {
134        fprintf(stderr, "Error: cannot open %s for processing.\n", infilename);
135        exit(-1);
136    }
137    if (fstat(fdSrc, &infile_sb) == -1) {
138        fprintf(stderr, "Error: cannot stat %s for processing.\n", infilename);
139        exit(-1);
140    }
141    if (infile_sb.st_size == 0) {
142        if (count_only_option) fprintf(outfile, "Matching Lines: %d\n", 0);
143        exit(0);
144    }
145    infile_buffer = (char *) mmap(NULL, infile_sb.st_size, PROT_READ, MAP_PRIVATE, fdSrc, 0);
146    if (infile_buffer == MAP_FAILED) {
147        fprintf(stderr, "Error: mmap of %s failure.\n", infilename);
148        exit(-1);
149    }
150#endif
151
152        if (print_version_option) {
153                fprintf(outfile, "Parabix grep implementation: July 2013\n");
154        }
155
156        PERF_SEC_BIND(1);
157
158        PERF_SEC_INIT(parser_timer);
159
160#ifndef USE_MMAP
161        do_process(infile, outfile, count_only_option);
162#endif
163#ifdef USE_MMAP
164        do_process(infile_buffer, infile_sb.st_size, outfile, count_only_option);
165#endif
166
167        PERF_SEC_DUMP(parser_timer);
168
169        PERF_SEC_DESTROY(parser_timer);
170
171#ifndef USE_MMAP
172    fclose(infile);
173#endif
174#ifdef USE_MMAP
175    munmap((void *) infile_buffer, infile_sb.st_size);
176    close(fdSrc);
177#endif
178        fclose(outfile);
179
180        return(0);
181}
182
183#if (BLOCK_SIZE == 256)
184typedef BitStreamScanner<BitBlock, uint64_t, uint64_t, SEGMENT_BLOCKS> ScannerT;
185#endif
186
187#if (BLOCK_SIZE == 128)
188typedef BitStreamScanner<BitBlock, uint32_t, uint32_t, SEGMENT_BLOCKS> ScannerT;
189#endif
190
191//
192// Write matched lines from a buffer to an output file, given segment
193// scanners for line ends and matches (where matches are a subset of line ends).
194// The buffer pointer must point to the first byte of the segment
195// corresponding to the scanner indexes.   The first_line_start is the
196// start position of the first line relative to the buffer start position.
197// It must be zero or negative;  if negative, the buffer must permit negative
198// indexing so that the lineup to the buffer start position can also be printed.
199// The start position of the final line in the processed segment is returned.
200//
201
202ssize_t write_matches(FILE * outfile, ScannerT line_scanner, ScannerT match_scanner, char * buffer, ssize_t first_line_start) {
203       
204        ssize_t line_start = first_line_start;
205        size_t match_pos;
206        size_t line_end;
207        while (match_scanner.has_next()) {
208                match_pos = match_scanner.scan_to_next();
209                // If we found a match, it must be at a line end.
210                line_end = line_scanner.scan_to_next();
211                while (line_end < match_pos) {
212                        line_start = line_end + 1;
213                        line_end = line_scanner.scan_to_next();
214                }
215                fwrite(&buffer[line_start], 1, line_end - line_start + 1, outfile);
216                line_start = line_end + 1;
217               
218        }
219        while(line_scanner.has_next()) {
220                line_end = line_scanner.scan_to_next();
221                line_start = line_end+1;
222  }
223  return line_start;
224}
225
226
227
228#ifndef USE_MMAP
229void do_process(FILE *infile, FILE *outfile, int count_only_option) {
230#endif
231#ifdef USE_MMAP
232        void do_process(char * infile_buffer, size_t infile_size, FILE *outfile, int count_only_option){
233#endif
234
235        @decl
236
237        bool line_match_found=false;
238
239        BitBlock match_vector = simd<1>::constant<0>();
240        int match_count=0;
241        int blk = 0;
242        int block_base  = 0;
243        int block_pos   = 0;
244        int buffer_base = 0;
245        int buffer_pos  = 0;
246        int chars_avail = 0;
247        int chars_read  = 0;
248                int line_start = 0;
249                int line_end = 0;
250                int match_pos = 0;
251                int line_no = 0;
252               
253                ScannerT LF_scanner;
254                ScannerT match_scanner;
255
256                char * buffer_ptr;
257#ifndef USE_MMAP
258                ATTRIBUTE_SIMD_ALIGN char src_buffer[SEGMENT_SIZE];
259                buffer_ptr = &src_buffer;
260                chars_read = fread((void *)&src_buffer[0], 1, SEGMENT_SIZE, infile);
261                chars_avail = chars_read;
262                if (chars_avail >= SEGMENT_SIZE) chars_avail = SEGMENT_SIZE;
263#endif
264#ifdef USE_MMAP
265                int segment = 0;
266                int segment_base = 0;
267                chars_avail = infile_size;
268
269#endif
270
271        @stream_stmts
272
273//////////////////////////////////////////////////////////////////////////////////////////
274// Full Segments
275//////////////////////////////////////////////////////////////////////////////////////////
276       
277        while (chars_avail >= SEGMENT_SIZE) {
278#ifdef USE_MMAP
279                segment_base = segment * SEGMENT_SIZE;
280#endif
281                LF_scanner.init();
282                match_scanner.init();
283
284                PERF_SEC_START(parser_timer);
285                for (blk = 0; blk < SEGMENT_BLOCKS; blk++) {
286#ifndef USE_MMAP
287            block_base = blk*BLOCK_SIZE;
288            s2p_do_block((BytePack *) &src_buffer[block_base], basis_bits);
289#endif
290#ifdef USE_MMAP
291            block_base = blk*BLOCK_SIZE + segment_base;
292            s2p_do_block((BytePack *) &infile_buffer[block_base], basis_bits);
293#endif
294
295                        @block_stmts
296
297                        LF_scanner.load_block(output.lf, blk);
298                        match_scanner.load_block(output.matches, blk);
299                        if (count_only_option) {
300                          if (bitblock::any(output.matches)) {
301                                if (bitblock::any(simd_and(match_vector, output.matches))) {
302                                  match_count += bitblock::popcount(match_vector);
303                                  match_vector = output.matches;
304                                }
305                                else {
306                                  match_vector = simd_or(match_vector, output.matches);
307                                }
308                          }
309                        }
310
311                }
312#ifndef USE_MMAP
313 
314                demo.clear();
315                 
316                int copy_back_pos = LF_scanner.get_final_pos() + 1;
317                int copy_back_size = SEGMENT_SIZE - copy_back_pos;
318
319                match_scanner.clear_from(copy_back_pos);
320#endif
321#ifdef USE_MMAP
322                buffer_ptr = &infile_buffer[segment_base];
323#endif
324
325
326        if (!count_only_option) {
327                        line_start = write_matches(outfile, LF_scanner, match_scanner, buffer_ptr, line_start);
328        }
329
330#ifndef USE_MMAP
331                memmove(&src_buffer[0], &src_buffer[copy_back_pos], copy_back_size);
332               
333                PERF_SEC_END(parser_timer, chars_avail);
334               
335                chars_read = fread(&src_buffer[copy_back_size], 1, copy_back_pos, infile);
336                chars_avail = chars_read + copy_back_size;
337                if (chars_avail >= SEGMENT_SIZE) chars_avail = SEGMENT_SIZE;
338                buffer_pos += chars_avail;
339                buffer_base = buffer_pos;
340#endif
341#ifdef USE_MMAP
342                segment++;
343                line_start -= SEGMENT_SIZE;  /* Will be negative offset for use within next segment. */
344                chars_avail -= SEGMENT_SIZE;
345#endif
346        }
347
348
349//////////////////////////////////////////////////////////////////////////////////////////
350// Final Partial Segment
351//////////////////////////////////////////////////////////////////////////////////////////
352        PERF_SEC_START(parser_timer);
353
354#ifdef USE_MMAP
355                segment_base = segment * SEGMENT_SIZE;
356#endif
357        int remaining = chars_avail;
358
359
360        LF_scanner.init();
361        match_scanner.init();
362
363        /* Full Blocks */
364        blk = 0;
365        while (remaining >= BLOCK_SIZE) {
366#ifndef USE_MMAP
367        block_base = block_pos;
368        s2p_do_block((BytePack *) &src_buffer[block_base], basis_bits);
369#endif
370#ifdef USE_MMAP
371        block_base = block_pos + segment_base;
372        s2p_do_block((BytePack *) &infile_buffer[block_base], basis_bits);
373#endif
374                @block_stmts
375                LF_scanner.load_block(output.lf, blk);
376                match_scanner.load_block(output.matches, blk);
377                        if (count_only_option) {
378                          if (bitblock::any(output.matches)) {
379                                if (bitblock::any(simd_and(match_vector, output.matches))) {
380                                  match_count += bitblock::popcount(match_vector);
381                                  match_vector = output.matches;
382                                }
383                                else {
384                                  match_vector = simd_or(match_vector, output.matches);
385                                }
386                          }
387                        }
388                block_pos += BLOCK_SIZE;
389                remaining -= BLOCK_SIZE;
390                blk++;
391        }
392        block_base = block_pos;
393
394//    Partial Block or Any Carry
395//
396        EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-remaining));
397#ifndef USE_MMAP
398                block_base = block_pos;
399                s2p_do_final_block((BytePack *) &src_buffer[block_base], basis_bits, EOF_mask);
400#endif
401#ifdef USE_MMAP
402                block_base = block_pos + segment_base;
403                s2p_do_final_block((BytePack *) &infile_buffer[block_base], basis_bits, EOF_mask);
404#endif
405        @final_block_stmts
406
407        if (count_only_option) {
408                match_count += bitblock::popcount(match_vector);
409                if (bitblock::any(output.matches)) {
410                        match_count += bitblock::popcount(output.matches);
411                }
412                fprintf(outfile, "Matching Lines:%d\n",match_count);
413        }
414        else {
415                LF_scanner.load_block(output.lf, blk);
416                match_scanner.load_block(output.matches, blk);
417                blk++;
418
419                for (int i = blk; i < SEGMENT_BLOCKS; i++){
420                        LF_scanner.load_block(simd<1>::constant<0>(), i);
421                        match_scanner.load_block(simd<1>::constant<0>(), i);
422                }
423#ifndef USE_MMAP
424        line_start = 0;
425#endif
426#ifdef USE_MMAP
427        buffer_ptr = &infile_buffer[segment_base];
428#endif
429        line_start = write_matches(outfile, LF_scanner, match_scanner, buffer_ptr, line_start);
430
431        }
432
433        buffer_pos += chars_avail;
434
435        PERF_SEC_END(parser_timer, chars_avail);
436}
437
Note: See TracBrowser for help on using the repository browser.