source: proto/s2k/trunk/demo/grep/src/grep.cpp @ 4053

Last change on this file since 4053 was 4053, checked in by ksherdy, 5 years ago

Added example s2k output file.

File size: 26.0 KB
Line 
1/*
2 * grep exact-string search C++ in \s2k{}.
3 *
4 * Usage:    grep [OPTIONS] <infile> [outfile]
5 *
6 * Warning:
7 *
8 * Template implementation limits line length to SEGMENT_SIZE bytes, i.e.,
9 * 1K on 32-bit architecture with 128-bit SIMD registers, and
10 * 4K on 64-bit with 128-bit SIMD registers.
11 *
12 * Program Description:   
13 *
14 * The \s2k{} demo grep program searches a file for lines containing matches
15 * to the fixed target pattern, `apple'.
16 * The default behaviour of \s2k{} grep is to print all matching lines.
17 *
18 * The flag -o specifies that only 
19 * the matched parts of a matching line are produced, with each
20 * such part on a separate output line.
21 *
22 * The flag -b, specifies that the 0-based byte offset within
23 * the input file before each line of output.
24 
25 * If -b is specified with -o, \s2k{} grep prints the offset of
26 * each match, formatted as `offset:apple', where `apple' is the target
27 * pattern read from memory and offset is the zero-index offset
28 * of the first character the match.
29 *
30 * For example, given an input file containing three occurrences of `apple'
31 * at zero-indexed offsets 47,107, and 189, the \s2k{} grep
32 * application writes the following results to standard output.
33 *
34 * 47:apple
35 * 107:apple
36 * 189:apple
37 *
38 * This behaviour is equivalent to the following GNU grep utility command.
39 *
40 * grep needle filename --only-matching --byte-offset
41 *
42 */
43/*
44 * Template Attributes:
45 *
46 * The \s2k{} compiler and substitutes generated code fragments for
47 * the following predefined template attributes bracked with
48 * hashhashhashamp and hashhashash.
49 *
50 * @global                - Stream structure and filter definitions.
51 *
52 * @struct_decls          - Stream structure declarations.
53 *
54 * @filter_decls          - Stream filter declarations.
55 *
56 * @filter_do_block       - Stream filter `do_block()' calls.
57 *
58 * @filter_do_final_block - Stream filter `do_final_block()' calls.
59 *
60 * @filter_clear          - Stream filter `clear()' calls.
61 */
62 
63/*
64 * GENERATED CODE. DO NOT MODIFY.
65 */
66 
67#define DEBUG 0
68
69// Runtime directives
70#define BASIS_BITS
71
72// Runtime libraries
73#include <simd-lib/bitblock.hpp>
74#include <simd-lib/runtime.hpp>
75#include <simd-lib/pabloSupport.hpp>
76#include <simd-lib/bitblock_iterator.hpp>
77#include <simd-lib/transpose.hpp>
78
79// C/C++ libraries
80#include <stdio.h>
81#include <stdlib.h>
82#include <string>
83#include <iostream>
84using namespace std;
85
86// S2K Generated
87struct Lex
88{
89        BitBlock a;
90        BitBlock p;
91        BitBlock l;
92        BitBlock e;
93        BitBlock LF;
94};
95 
96struct Output
97{
98        BitBlock match_follows;
99        BitBlock lines;
100        BitBlock line_starts;
101        BitBlock line_ends;
102};
103 
104struct Source
105{
106        Source()
107        {
108        }
109       
110        IDISA_INLINE void do_block()
111        {
112                carry_set_0.carryAdjust(0);
113        }
114       
115        IDISA_INLINE void do_final_block(BitBlock & EOF_mask)
116        {
117                carry_set_0.carryAdjust(0);
118        }
119       
120        IDISA_INLINE void clear()
121        {
122               
123        }
124       
125        DeclareRuntimeInfoSet(carry_set_0, 0, 0);
126};
127 
128struct ClassifyBytes
129{
130        ClassifyBytes()
131        {
132        }
133       
134        IDISA_INLINE void do_block(struct Basis_bits & basis_bits, struct Lex & lex)
135        {
136                BitBlock temp1;
137                temp1 = simd_andc(basis_bits.bit_1,basis_bits.bit_0);
138                BitBlock temp2;
139                temp2 = simd_andc(basis_bits.bit_2,basis_bits.bit_3);
140                BitBlock temp3;
141                temp3 = simd_and(temp1,temp2);
142                BitBlock temp4;
143                temp4 = simd_or(basis_bits.bit_4,basis_bits.bit_5);
144                BitBlock temp5;
145                temp5 = simd_andc(basis_bits.bit_7,basis_bits.bit_6);
146                BitBlock temp6;
147                temp6 = simd_andc(temp5,temp4);
148                lex.a = simd_and(temp3,temp6);
149                BitBlock temp7;
150                temp7 = simd_and(basis_bits.bit_2,basis_bits.bit_3);
151                BitBlock temp8;
152                temp8 = simd_and(temp1,temp7);
153                BitBlock temp9;
154                temp9 = simd_or(basis_bits.bit_6,basis_bits.bit_7);
155                BitBlock temp10;
156                temp10 = simd_or(temp4,temp9);
157                lex.p = simd_andc(temp8,temp10);
158                BitBlock temp11;
159                temp11 = simd_and(basis_bits.bit_4,basis_bits.bit_5);
160                BitBlock temp12;
161                temp12 = simd_andc(temp11,temp9);
162                lex.l = simd_and(temp3,temp12);
163                BitBlock temp13;
164                temp13 = simd_andc(basis_bits.bit_5,basis_bits.bit_4);
165                BitBlock temp14;
166                temp14 = simd_and(temp13,temp5);
167                lex.e = simd_and(temp3,temp14);
168                BitBlock temp15;
169                temp15 = simd_or(basis_bits.bit_0,basis_bits.bit_1);
170                BitBlock temp16;
171                temp16 = simd_or(basis_bits.bit_2,basis_bits.bit_3);
172                BitBlock temp17;
173                temp17 = simd_or(temp15,temp16);
174                BitBlock temp18;
175                temp18 = simd_andc(basis_bits.bit_4,basis_bits.bit_5);
176                BitBlock temp19;
177                temp19 = simd_andc(basis_bits.bit_6,basis_bits.bit_7);
178                BitBlock temp20;
179                temp20 = simd_and(temp18,temp19);
180                lex.LF = simd_andc(temp20,temp17);
181                carry_set_0.carryAdjust(0);
182        }
183       
184        IDISA_INLINE void do_final_block(struct Basis_bits & basis_bits, struct Lex & lex, BitBlock & EOF_mask)
185        {
186                BitBlock temp1;
187                temp1 = simd_andc(basis_bits.bit_1,basis_bits.bit_0);
188                BitBlock temp2;
189                temp2 = simd_andc(basis_bits.bit_2,basis_bits.bit_3);
190                BitBlock temp3;
191                temp3 = simd_and(temp1,temp2);
192                BitBlock temp4;
193                temp4 = simd_or(basis_bits.bit_4,basis_bits.bit_5);
194                BitBlock temp5;
195                temp5 = simd_andc(basis_bits.bit_7,basis_bits.bit_6);
196                BitBlock temp6;
197                temp6 = simd_andc(temp5,temp4);
198                lex.a = simd_and(temp3,temp6);
199                BitBlock temp7;
200                temp7 = simd_and(basis_bits.bit_2,basis_bits.bit_3);
201                BitBlock temp8;
202                temp8 = simd_and(temp1,temp7);
203                BitBlock temp9;
204                temp9 = simd_or(basis_bits.bit_6,basis_bits.bit_7);
205                BitBlock temp10;
206                temp10 = simd_or(temp4,temp9);
207                lex.p = simd_andc(temp8,temp10);
208                BitBlock temp11;
209                temp11 = simd_and(basis_bits.bit_4,basis_bits.bit_5);
210                BitBlock temp12;
211                temp12 = simd_andc(temp11,temp9);
212                lex.l = simd_and(temp3,temp12);
213                BitBlock temp13;
214                temp13 = simd_andc(basis_bits.bit_5,basis_bits.bit_4);
215                BitBlock temp14;
216                temp14 = simd_and(temp13,temp5);
217                lex.e = simd_and(temp3,temp14);
218                BitBlock temp15;
219                temp15 = simd_or(basis_bits.bit_0,basis_bits.bit_1);
220                BitBlock temp16;
221                temp16 = simd_or(basis_bits.bit_2,basis_bits.bit_3);
222                BitBlock temp17;
223                temp17 = simd_or(temp15,temp16);
224                BitBlock temp18;
225                temp18 = simd_andc(basis_bits.bit_4,basis_bits.bit_5);
226                BitBlock temp19;
227                temp19 = simd_andc(basis_bits.bit_6,basis_bits.bit_7);
228                BitBlock temp20;
229                temp20 = simd_and(temp18,temp19);
230                lex.LF = simd_andc(temp20,temp17);
231                carry_set_0.carryAdjust(0);
232        }
233       
234        IDISA_INLINE void clear()
235        {
236               
237        }
238       
239        DeclareRuntimeInfoSet(carry_set_0, 0, 0);
240};
241 
242struct Match
243{
244        Match()
245        {
246        }
247       
248        IDISA_INLINE void do_block(struct Lex & lex, struct Output & output)
249        {
250                BitBlock cursor;
251                carry_set_0.getCarry(0) = bitblock::srli<127>(pablo_blk_Advance(lex.a,carry_set_0.getCarry(0),cursor));
252                carry_set_0.getCarry(1) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.p),carry_set_0.getCarry(1),cursor));
253                carry_set_0.getCarry(2) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.p),carry_set_0.getCarry(2),cursor));
254                carry_set_0.getCarry(3) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.l),carry_set_0.getCarry(3),cursor));
255                carry_set_0.getCarry(4) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.e),carry_set_0.getCarry(4),cursor));
256                output.match_follows = cursor;
257                carry_set_0.carryAdjust(5);
258        }
259       
260        IDISA_INLINE void do_final_block(struct Lex & lex, struct Output & output, BitBlock & EOF_mask)
261        {
262                BitBlock cursor;
263                carry_set_0.getCarry(0) = bitblock::srli<127>(pablo_blk_Advance(lex.a,carry_set_0.getCarry(0),cursor));
264                carry_set_0.getCarry(1) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.p),carry_set_0.getCarry(1),cursor));
265                carry_set_0.getCarry(2) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.p),carry_set_0.getCarry(2),cursor));
266                carry_set_0.getCarry(3) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.l),carry_set_0.getCarry(3),cursor));
267                carry_set_0.getCarry(4) = bitblock::srli<127>(pablo_blk_Advance(simd_and(cursor,lex.e),carry_set_0.getCarry(4),cursor));
268                output.match_follows = cursor;
269                carry_set_0.carryAdjust(5);
270        }
271       
272        IDISA_INLINE void clear()
273        {
274               
275        }
276       
277        DeclareRuntimeInfoSet(carry_set_0, 5, 0);
278};
279 
280struct MatchLines
281{
282        MatchLines()
283        {
284                carry_set_0.setCarry(carry_set_0.carryFlip(0), 0);
285                carry_set_0.setCarry(carry_set_0.carryFlip(2), 2);
286        }
287       
288        IDISA_INLINE void do_block(struct Lex & lex, struct Output & output)
289        {
290                BitBlock all_line_starts;
291                BitBlock _temp0;
292                BitBlock _temp1;
293                carry_set_0.getCarry(0) = bitblock::srli<127>(pablo_blk_ScanToFirst(simd_not(lex.LF),carry_set_0.getCarry(0),_temp0));
294                carry_set_0.getCarry(1) = bitblock::srli<127>(pablo_blk_Advance(lex.LF,carry_set_0.getCarry(1),_temp1));
295                all_line_starts = simd_or(_temp0,simd_andc(_temp1,lex.LF));
296                BitBlock all_line_ends;
297                all_line_ends = lex.LF;
298                BitBlock last_line_start;
299                carry_set_0.getCarry(2) = bitblock::srli<127>(pablo_blk_ScanToFirst(all_line_starts,carry_set_0.getCarry(2),last_line_start));
300                BitBlock cursor;
301                cursor = last_line_start;
302                if (bitblock::any(simd_or(cursor,carry_set_0.carryRange(3,3))))
303                {
304                        if (bitblock::any(simd_and(cursor,all_line_starts)))
305                        {
306                                last_line_start = cursor;
307                        }
308                        if (bitblock::any(simd_or(simd_and(cursor,output.match_follows),carry_set_0.carryRange(3,2))))
309                        {
310                                carry_set_0.getCarry(3) = bitblock::srli<127>(pablo_blk_ScanThru(cursor,simd_not(lex.LF),carry_set_0.getCarry(3),cursor));
311                                BitBlock _temp2;
312                                carry_set_0.getCarry(4) = bitblock::srli<127>(pablo_blk_InclusiveSpan(last_line_start,cursor,carry_set_0.getCarry(4),_temp2));
313                                output.lines = simd_or(output.lines,_temp2);
314                        }
315                        else
316                        {
317                                carry_set_0.carryDequeueEnqueue(3, 2);
318                        }
319                        carry_set_0.getCarry(5) = bitblock::srli<127>(pablo_blk_AdvanceThenScanThru(cursor,simd_not(simd_or(all_line_starts,output.match_follows)),carry_set_0.getCarry(5),cursor));
320                        while (bitblock::any(cursor))
321                        {
322                                DeclareRuntimeInfoSet(carry_set_1, 3, 0);
323                                if (bitblock::any(simd_and(cursor,all_line_starts)))
324                                {
325                                        last_line_start = cursor;
326                                }
327                                if (bitblock::any(simd_and(cursor,output.match_follows)))
328                                {
329                                        carry_set_1.getCarry(0) = bitblock::srli<127>(pablo_blk_ScanThru(cursor,simd_not(lex.LF),carry_set_1.getCarry(0),cursor));
330                                        BitBlock _temp2;
331                                        carry_set_1.getCarry(1) = bitblock::srli<127>(pablo_blk_InclusiveSpan(last_line_start,cursor,carry_set_1.getCarry(1),_temp2));
332                                        output.lines = simd_or(output.lines,_temp2);
333                                }
334                                carry_set_1.getCarry(2) = bitblock::srli<127>(pablo_blk_AdvanceThenScanThru(cursor,simd_not(simd_or(all_line_starts,output.match_follows)),carry_set_1.getCarry(2),cursor));
335                                LocalCarryCombine(carry_set_0, carry_set_1, 3, 3);
336                        }
337                }
338                else
339                {
340                        carry_set_0.carryDequeueEnqueue(3, 3);
341                }
342                output.line_starts = simd_and(output.lines,all_line_starts);
343                carry_set_0.getCarry(6) = bitblock::srli<127>(pablo_blk_ScanThru(output.line_starts,simd_not(simd_and(output.lines,all_line_ends)),carry_set_0.getCarry(6),output.line_ends));
344                carry_set_0.carryAdjust(7);
345        }
346       
347        IDISA_INLINE void do_final_block(struct Lex & lex, struct Output & output, BitBlock & EOF_mask)
348        {
349                BitBlock all_line_starts;
350                BitBlock _temp0;
351                BitBlock _temp1;
352                carry_set_0.getCarry(0) = bitblock::srli<127>(pablo_blk_ScanToFirst(simd_or(simd_not(lex.LF),simd_not(EOF_mask)),carry_set_0.getCarry(0),_temp0));
353                carry_set_0.getCarry(1) = bitblock::srli<127>(pablo_blk_Advance(lex.LF,carry_set_0.getCarry(1),_temp1));
354                all_line_starts = simd_or(_temp0,simd_andc(_temp1,lex.LF));
355                BitBlock all_line_ends;
356                all_line_ends = lex.LF;
357                BitBlock last_line_start;
358                carry_set_0.getCarry(2) = bitblock::srli<127>(pablo_blk_ScanToFirst(simd_or(all_line_starts,simd_not(EOF_mask)),carry_set_0.getCarry(2),last_line_start));
359                BitBlock cursor;
360                cursor = last_line_start;
361                if (bitblock::any(simd_and(simd_or(simd_and(cursor,EOF_mask),carry_set_0.carryRange(3,3)),EOF_mask)))
362                {
363                        if (bitblock::any(simd_and(cursor,all_line_starts)))
364                        {
365                                last_line_start = cursor;
366                        }
367                        if (bitblock::any(simd_or(simd_and(cursor,output.match_follows),carry_set_0.carryRange(3,2))))
368                        {
369                                carry_set_0.getCarry(3) = bitblock::srli<127>(pablo_blk_ScanThru(cursor,simd_andc(EOF_mask,lex.LF),carry_set_0.getCarry(3),cursor));
370                                BitBlock _temp2;
371                                carry_set_0.getCarry(4) = bitblock::srli<127>(pablo_blk_InclusiveSpan(last_line_start,cursor,carry_set_0.getCarry(4),_temp2));
372                                output.lines = simd_or(output.lines,_temp2);
373                        }
374                        else
375                        {
376                                carry_set_0.carryDequeueEnqueue(3, 2);
377                        }
378                        carry_set_0.getCarry(5) = bitblock::srli<127>(pablo_blk_AdvanceThenScanThru(cursor,simd_andc(EOF_mask,simd_or(all_line_starts,output.match_follows)),carry_set_0.getCarry(5),cursor));
379                        while (bitblock::any(simd_and(simd_and(cursor,EOF_mask),EOF_mask)))
380                        {
381                                DeclareRuntimeInfoSet(carry_set_1, 3, 0);
382                                if (bitblock::any(simd_and(cursor,all_line_starts)))
383                                {
384                                        last_line_start = cursor;
385                                }
386                                if (bitblock::any(simd_and(cursor,output.match_follows)))
387                                {
388                                        carry_set_1.getCarry(0) = bitblock::srli<127>(pablo_blk_ScanThru(cursor,simd_andc(EOF_mask,lex.LF),carry_set_1.getCarry(0),cursor));
389                                        BitBlock _temp2;
390                                        carry_set_1.getCarry(1) = bitblock::srli<127>(pablo_blk_InclusiveSpan(last_line_start,cursor,carry_set_1.getCarry(1),_temp2));
391                                        output.lines = simd_or(output.lines,_temp2);
392                                }
393                                carry_set_1.getCarry(2) = bitblock::srli<127>(pablo_blk_AdvanceThenScanThru(cursor,simd_andc(EOF_mask,simd_or(all_line_starts,output.match_follows)),carry_set_1.getCarry(2),cursor));
394                                LocalCarryCombine(carry_set_0, carry_set_1, 3, 3);
395                        }
396                }
397                else
398                {
399                        carry_set_0.carryDequeueEnqueue(3, 3);
400                }
401                output.line_starts = simd_and(output.lines,all_line_starts);
402                carry_set_0.getCarry(6) = bitblock::srli<127>(pablo_blk_ScanThru(output.line_starts,simd_andc(EOF_mask,simd_and(output.lines,all_line_ends)),carry_set_0.getCarry(6),output.line_ends));
403                carry_set_0.carryAdjust(7);
404        }
405       
406        IDISA_INLINE void clear()
407        {
408                carry_set_0.setCarry(carry_set_0.carryFlip(0), 0);
409                carry_set_0.setCarry(carry_set_0.carryFlip(2), 2);
410        }
411       
412        DeclareRuntimeInfoSet(carry_set_0, 7, 0);
413};
414 
415struct Read
416{
417        Read()
418        {
419        }
420       
421        IDISA_INLINE void do_block(struct Output & output)
422        {
423                carry_set_0.carryAdjust(0);
424        }
425       
426        IDISA_INLINE void do_final_block(struct Output & output, BitBlock & EOF_mask)
427        {
428                carry_set_0.carryAdjust(0);
429        }
430       
431        IDISA_INLINE void clear()
432        {
433               
434        }
435       
436        DeclareRuntimeInfoSet(carry_set_0, 0, 0);
437};
438 
439struct Write
440{
441        Write()
442        {
443        }
444       
445        IDISA_INLINE void do_block(struct Output & output)
446        {
447                carry_set_0.carryAdjust(0);
448        }
449       
450        IDISA_INLINE void do_final_block(struct Output & output, BitBlock & EOF_mask)
451        {
452                carry_set_0.carryAdjust(0);
453        }
454       
455        IDISA_INLINE void clear()
456        {
457               
458        }
459       
460        DeclareRuntimeInfoSet(carry_set_0, 0, 0);
461};
462 
463
464
465// Segment-at-a-time buffered stream processing parameters.
466const int SCANBLOCK_SIZE     = sizeof(ScanWord) * 8;
467const int SCANFIELD_SIZE     = sizeof(ScanWord) * 8;
468const int SEGMENT_BLOCKS     = SCANBLOCK_SIZE * SCANFIELD_SIZE / BLOCK_SIZE;
469const int SEGMENT_SIZE       = SEGMENT_BLOCKS * BLOCK_SIZE;
470
471const char * fixed_pattern   = "apple";
472const int pattern_size       = strlen(fixed_pattern);
473
474int main(int argc, char * argv[]) {
475
476  char * infilename, * outfilename;
477  FILE * infile, * outfile;
478
479  int opt_code;
480  int byte_offset             = 0;
481  int pattern_only_matching   = 0;
482  int line_matching           = 1;   
483
484  while ((opt_code = getopt(argc, argv, "bo?")) != -1) {
485    switch (opt_code) {
486      case 'b':
487        byte_offset = 1;
488        break;
489      case 'o':
490        pattern_only_matching = 1;
491        line_matching = 0;
492        break;
493      case '?':
494      default:
495        printf ("Invalid option: %c\n", opt_code);
496        printf("Usage: %s [OPTION] <inputfile> [<outputfile>]\n", argv[0]);
497        printf("\t-b,\tprint the byte offset with output lines\n");
498        printf("\t-o,\tshow only the part of a line matching PATTERN\n");
499        printf("\t-V,\tprint version information and exit");           
500        exit(-1);
501    }
502  }
503 
504  if (optind >= argc) {
505    printf ("Too few arguments\n");
506    printf("Usage: %s [-c] [-v] <regex> <inputfile> [<outputfile>]\n", argv[0]);
507    exit(-1);
508  }
509
510  infilename = argv[optind++];
511  infile = fopen(infilename, "rb");
512  if (!infile) {
513    fprintf(stderr, "Error: cannot open %s.\n", infilename);
514    exit(-1);
515  }
516
517  if(optind >= argc) {
518      outfile = stdout;
519  } else {
520    outfilename = argv[optind++];
521    if (optind != argc) {
522      printf ("Too many arguments\n");
523      printf("Usage: %s [-c] [-v] <regex> <inputfile> [<outputfile>]\n", argv[0]);
524      exit(-1);
525    }
526    outfile = fopen(outfilename, "wb");
527    if (!outfile) {
528      fprintf(stderr, "Error: cannot open %s.\n", outfilename);
529      exit(-1);
530    }
531  }
532
533  // { // ___loop_preheader___
534
535
536// S2K Generated
537struct Basis_bits basis_bits;
538struct Lex lex;
539struct Output output;
540
541
542// Initialize struct members
543basis_bits.bit_7 = simd<1>::constant<0>();
544basis_bits.bit_6 = simd<1>::constant<0>();
545basis_bits.bit_5 = simd<1>::constant<0>();
546basis_bits.bit_4 = simd<1>::constant<0>();
547basis_bits.bit_3 = simd<1>::constant<0>();
548basis_bits.bit_2 = simd<1>::constant<0>();
549basis_bits.bit_1 = simd<1>::constant<0>();
550basis_bits.bit_0 = simd<1>::constant<0>();
551
552lex.a = simd<1>::constant<0>();
553lex.p = simd<1>::constant<0>();
554lex.l = simd<1>::constant<0>(); 
555lex.e = simd<1>::constant<0>(); 
556lex.LF = simd<1>::constant<0>();
557
558lex.a = simd<1>::constant<0>();
559lex.p = simd<1>::constant<0>();
560lex.l = simd<1>::constant<0>(); 
561lex.e = simd<1>::constant<0>(); 
562lex.LF = simd<1>::constant<0>();
563
564output.match_follows = simd<1>::constant<0>();
565output.lines= simd<1>::constant<0>();
566output.line_starts= simd<1>::constant<0>();
567output.line_ends= simd<1>::constant<0>();
568
569// S2K Generated
570struct Transpose transpose;
571struct ClassifyBytes classifyBytes;
572struct Match match;
573struct MatchLines matchLines;
574
575
576  // \s2k{} transpose.do_block() / transpose.do_final_block()
577  // bind to `char * byte_data' and `struct Basis_bits 'basis' argument names.
578  ATTRIBUTE_SIMD_ALIGN char buffer[SEGMENT_SIZE];
579  char * byte_data = buffer;
580
581  // Iterators
582  BitStreamScanner<BitBlock, ScanWord, ScanWord, SEGMENT_BLOCKS> matches_scanner;
583  BitStreamScanner<BitBlock, ScanWord, ScanWord, SEGMENT_BLOCKS> line_starts_scanner;
584  BitStreamScanner<BitBlock, ScanWord, ScanWord, SEGMENT_BLOCKS> line_ends_scanner;
585
586  // Segment-at-a-time variables
587  int bytes_read              = 0;
588  int bytes_avail             = 0;
589  int bytes_remaining         = 0;
590
591  int copy_back_size          = 0;
592  int copy_back_offset        = 0;
593
594  // Segment-at-a-time offset
595  int block_index             = 0;
596  int segment_base            = 0;
597
598  // Iterator offset
599  int match_offset            = 0;
600  int line_start_offset       = 0;
601  int line_end_offset         = 0;
602
603  int line_final_start_offset = 0;
604  int line_final_end_offset   = 0;
605
606  // { // ___loop_preheader___
607
608
609  while(!feof(infile)) {
610 
611    // __loop_header__ {
612    block_index = 0;
613
614    // initialize scanners
615    matches_scanner.init();
616    line_starts_scanner.init();
617    line_ends_scanner.init(); 
618 
619    bytes_read      = fread(buffer + copy_back_size, 1, 
620                        SEGMENT_SIZE - copy_back_size, infile);
621    bytes_avail     = bytes_read + copy_back_size;
622    bytes_remaining = bytes_avail;
623
624    if(ferror(infile)) { perror( "io error" ); exit(1); }
625    // } __loop_header__
626
627
628    // __loop_body__ {
629   
630    // Process full segment
631    if (bytes_remaining == SEGMENT_SIZE) { 
632
633      for(block_index = 0; block_index < SEGMENT_BLOCKS; block_index++) {
634
635        byte_data = &buffer[block_index * BLOCK_SIZE];
636       
637        // S2K Generated
638        transpose.do_block(byte_data, basis_bits);
639classifyBytes.do_block(basis_bits, lex);
640match.do_block(lex, output);
641matchLines.do_block(lex, output);
642
643
644        if(pattern_only_matching) {
645          matches_scanner.load_block(output.match_follows, block_index);
646        }
647
648        if(line_matching) {
649          line_starts_scanner.load_block(output.line_starts, block_index);
650          line_ends_scanner.load_block(output.line_ends, block_index);
651        }
652      }
653
654      if(pattern_only_matching) {
655        while(matches_scanner.has_next()) {
656          match_offset = matches_scanner.scan_to_next() - pattern_size;
657          if(byte_offset) {
658            int match_stream_offset = segment_base + match_offset;
659            fprintf(outfile, "%d:", match_stream_offset);
660          }
661
662          fwrite(&buffer[match_offset], 1, pattern_size, outfile); // lookahead
663          //fprintf(outfile, "%s\n", fixed_pattern);
664          fprintf(outfile, "\n");
665        }
666
667        copy_back_size      = pattern_size + 1;
668        copy_back_offset    = bytes_avail - copy_back_size;
669      }
670 
671      if(line_matching) {
672
673        assert(("Input line length exceeds segment size.", 
674          line_ends_scanner.has_next() && line_starts_scanner.has_next()));
675        line_final_start_offset = line_starts_scanner.get_final_pos();
676        line_final_end_offset = line_ends_scanner.get_final_pos();
677
678        while(line_starts_scanner.has_next() && line_ends_scanner.has_next()) {
679
680          line_start_offset  = line_starts_scanner.scan_to_next();
681          line_end_offset    = line_ends_scanner.scan_to_next();
682
683          if(byte_offset) {
684            fprintf(outfile, "%d:", segment_base + line_start_offset);
685          }
686
687          fwrite(&buffer[line_start_offset], 1, 
688            line_end_offset - line_start_offset + 1, outfile);
689        }
690
691        copy_back_offset = (line_final_start_offset > line_final_end_offset) 
692                         ? line_final_start_offset : (line_final_end_offset + 1);
693        copy_back_size   = bytes_avail - copy_back_offset;
694
695        assert(("copy_back_offset", (copy_back_offset >= 0)));
696        assert(("copy_back_offset", (copy_back_offset <= bytes_avail)));
697        assert(("copy_back_size", (copy_back_size >= 0)));
698        assert(("copy_back_size", (copy_back_size < SEGMENT_SIZE)));
699      } 
700     
701      bytes_remaining -= SEGMENT_SIZE;
702    }
703   
704    // Process a partial segment.
705    if(bytes_remaining > 0) {
706
707      while (bytes_remaining >= BLOCK_SIZE) {
708        byte_data = &buffer[block_index * BLOCK_SIZE];
709       
710        // Compiler 'do_block()' calls.
711        transpose.do_block(byte_data, basis_bits);
712classifyBytes.do_block(basis_bits, lex);
713match.do_block(lex, output);
714matchLines.do_block(lex, output);
715
716 
717        if(pattern_only_matching) {
718          matches_scanner.load_block(output.match_follows, block_index);
719        }       
720       
721        if(line_matching) {
722          line_starts_scanner.load_block(output.line_starts, block_index);
723          line_ends_scanner.load_block(output.line_ends, block_index);
724        }
725 
726        bytes_remaining -= BLOCK_SIZE;
727        block_index++;
728       }   
729
730       // Process a partial block.
731       BitBlock EOF_mask = bitblock::srl(simd<1>::constant<1>(), 
732                                        convert(BLOCK_SIZE - bytes_remaining));
733       byte_data = &buffer[block_index * BLOCK_SIZE];
734         
735       // Compiler 'do_final_block()' calls.
736       transpose.do_final_block(byte_data, basis_bits, EOF_mask);
737classifyBytes.do_final_block(basis_bits, lex, EOF_mask);
738match.do_final_block(lex, output, EOF_mask);
739matchLines.do_final_block(lex, output, EOF_mask);
740
741       
742       if(pattern_only_matching) {
743          matches_scanner.load_block(output.match_follows & EOF_mask, block_index);
744       }
745
746       if(line_matching) {   
747         line_starts_scanner.load_block(output.line_starts & EOF_mask, block_index);
748         line_ends_scanner.load_block(output.line_ends & EOF_mask, block_index);           
749       }
750 
751       if(pattern_only_matching) {
752         while(matches_scanner.has_next()) {
753           match_offset = matches_scanner.scan_to_next() - pattern_size;
754           if(byte_offset) {
755             int match_stream_offset = segment_base + match_offset;
756             fprintf(outfile, "%d:", match_stream_offset);
757           }
758
759           fwrite(&buffer[match_offset], 1, pattern_size, outfile); // lookahead
760           fprintf(outfile, "\n");
761         }
762   
763          copy_back_size      = pattern_size + 1;
764          copy_back_offset    = bytes_avail - copy_back_size;
765       }
766       
767       if(line_matching) {
768         assert(("Input line exceeds segment size.", 
769                  line_ends_scanner.has_next() && 
770                  line_starts_scanner.has_next()));
771         line_final_start_offset = line_starts_scanner.get_final_pos();
772         line_final_end_offset = line_ends_scanner.get_final_pos();
773       
774        while(line_starts_scanner.has_next() && line_ends_scanner.has_next()) {
775          line_start_offset  = line_starts_scanner.scan_to_next();
776          line_end_offset    = line_ends_scanner.scan_to_next();
777   
778          if(byte_offset) {
779            fprintf(outfile, "%d:", segment_base + line_start_offset, 
780                     segment_base + line_end_offset);
781          }
782   
783          fwrite(&buffer[line_start_offset], 1, 
784                 line_end_offset - line_start_offset + 1, outfile);
785        }
786   
787        copy_back_offset   = (line_final_start_offset > line_final_end_offset) 
788                              ? line_final_start_offset
789                              : (line_final_end_offset + 1);
790                             
791        copy_back_size     = bytes_avail - copy_back_offset;
792   
793        assert(("copy_back_offset", (copy_back_offset >= 0)));
794        assert(("copy_back_offset", (copy_back_offset <= bytes_avail)));
795        assert(("copy_back_size", (copy_back_size >= 0)));
796        assert(("copy_back_size", (copy_back_size < SEGMENT_SIZE)));           
797      }
798    }
799
800
801    // __loop_tail__ {
802    // S2K Generated 'clear()' calls.
803    transpose.clear();
804classifyBytes.clear();
805match.clear();
806matchLines.clear();
807
808
809    memmove(&buffer[0], &buffer[copy_back_offset], copy_back_size);
810
811    // segment_base()
812    segment_base += bytes_avail;
813    segment_base -= copy_back_size;
814    // } __loop_tail__
815
816
817  }
818
819
820  // __loop_exit__ {
821  if(infile) { fclose(infile); infile=NULL;}
822  if(outfile) { fclose(outfile); outfile=NULL;}
823  // } __loop_exit__
824
825
826  return 0;
827}
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857/*
858 * Segment-at-a-time Processing Issues:
859 *
860 * 1. Start-of-stream or equivalently start-of-segment clear()...
861 *    The ScanTo and EOF_mask processing ensure a 'fence post' at the
862 *    end of each segment as well as at the end of file.
863 *
864 * 'grep.py' and 'grep_template.cpp' are tightly coupled on a number of variables:
865 *
866 * 1. Tranpose.do_block expects 'byte_data' and 'basis_bits'.
867 * 2. All StreamFunction.do_final_block methods expect 'EOF_mask'.
868 * 3. Sequential iterators (scanners) expect 'output.matches'.
869 * 4. Sequential iterators (scanners) expect 'lex.LF'.
870 *
871 */
Note: See TracBrowser for help on using the repository browser.