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

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

Consolidated s2k demos.

File size: 7.6 KB
Line 
1/**
2 * grep static fixed string search C++ template.
3 *
4 * Author:   Ken Herdy
5 *
6 * Usage: ./grep <infile> [-o outfile]
7 *
8 * Description:
9 *
10 * 'grep.py' and 'grep_template.cpp' are tightly coupled on a number of variables:
11 *
12 * 1. Tranpose.do_block expects 'byte_data' and 'basis_bits'.
13 * 2. All StreamFunction.do_final_block methods expect 'EOF_mask'.
14 * 3. Sequential iterators (scanners) expect 'output.matches'.
15 * 4. Sequential iterators (scanners) expect 'lex.LF'.
16 **/
17
18// Platform independent runtime support libraries and C++ libraries.
19#include <simd-lib/bitblock.hpp>
20#include <simd-lib/carryQ.hpp>
21#include <simd-lib/pabloSupport.hpp>
22#include <simd-lib/bitblock_iterator.hpp>
23#include <stdio.h>
24#include <stdlib.h>
25#include <simd-lib/s2p.hpp>
26
27// Fixed pattern.
28const char * fixed_pattern  = "apple";
29const int pattern_size      = strlen(fixed_pattern);
30
31// Platform dependent definitions. // Example only, defined in simd-lib/builtins.hpp.
32typedef __m128i BitBlock;
33typedef BitBlock BytePack;
34typedef uint32_t ScanWord;
35
36// Segment-at-a-time buffered stream processing parameters.
37const int SCANBLOCK_SIZE   = sizeof(ScanWord) * 8;
38const int SCANFIELD_SIZE   = sizeof(ScanWord) * 8;
39// const int BLOCK_SIZE       =  sizeof(BitBlock) * 8;
40const int SEGMENT_BLOCKS   = SCANBLOCK_SIZE * SCANFIELD_SIZE / BLOCK_SIZE;
41const int SEGMENT_SIZE     = SEGMENT_BLOCKS * BLOCK_SIZE;
42const int CACHE_SIZE       = 32768;
43const int BUFFER_SEGMENTS  = CACHE_SIZE / SEGMENT_SIZE;
44const int BUFFER_SIZE      = SEGMENT_SIZE; // KH: solve segment-at-a-time processing as a first step //BUFFER_SEGMENTS * SEGMENT_SIZE;
45
46BitBlock file_extent_mask(int size);
47
48/*
49// Transpostion runtime support
50struct Basis {
51  BitBlock b7;
52  BitBlock b6;
53  BitBlock b5;
54  BitBlock b4;
55  BitBlock b3;
56  BitBlock b2;
57  BitBlock b1;
58  BitBlock b0;
59};
60*/
61
62// @ global - Parameter replaced with C++ translation of stream structs
63//            and struct functions definitions
64@global
65
66/*
67struct Basis basis;
68*/
69
70// @ decl - Replaced with a set of C++ stream struct declarations.
71@decl
72
73// Transpostion (runtime support). Example only, defined in simd-lib/transpose.hpp.
74struct Transpose {
75
76  void do_block(char * byte_data, Basis_bits & basis_bits) {
77        BytePack * Byte = (BytePack *) byte_data;
78
79        s2p(Byte[0], Byte[1], Byte[2], Byte[3],
80            Byte[4], Byte[5], Byte[6], Byte[7],
81            basis_bits.bit_0, basis_bits.bit_1, basis_bits.bit_2, basis_bits.bit_3,
82            basis_bits.bit_4, basis_bits.bit_5, basis_bits.bit_6, basis_bits.bit_7);
83  }
84
85  void do_final_block(char * byte_data, Basis_bits & basis_bits, BitBlock & FEM_mask) {
86        BytePack * Byte = (BytePack *) byte_data;
87
88        s2p(Byte[0], Byte[1], Byte[2], Byte[3],
89            Byte[4], Byte[5], Byte[6], Byte[7],
90            basis_bits.bit_0, basis_bits.bit_1, basis_bits.bit_2, basis_bits.bit_3,
91            basis_bits.bit_4, basis_bits.bit_5, basis_bits.bit_6, basis_bits.bit_7);
92
93        basis_bits.bit_7 = simd_and(basis_bits.bit_7, FEM_mask);
94        basis_bits.bit_6 = simd_and(basis_bits.bit_6, FEM_mask);
95        basis_bits.bit_5 = simd_and(basis_bits.bit_5, FEM_mask);
96        basis_bits.bit_4 = simd_and(basis_bits.bit_4, FEM_mask);
97        basis_bits.bit_3 = simd_and(basis_bits.bit_3, FEM_mask);
98        basis_bits.bit_2 = simd_and(basis_bits.bit_2, FEM_mask);
99        basis_bits.bit_1 = simd_and(basis_bits.bit_1, FEM_mask);
100        basis_bits.bit_0 = simd_and(basis_bits.bit_0, FEM_mask);
101  }
102};
103
104
105struct Transpose transpose;
106// @ stream_stmts - Replaced with C++ stream functions declarations.
107@stream_stmts
108
109// Segment-at-a-time bufferd processing parameters.
110int bytes_read              = 0;
111int bytes_avail             = 0;
112
113int copy_back_size          = 0;
114int copy_back_pos           = 0;
115
116int block_index             = 0; // block index wrt current segment
117int block_base              = 0; // byte offset wrt current segment
118
119int segment_index           = 0; // segment index wrt current buffer  // unused
120int segment_base            = 0; // segment offset wrt current buffer // unused
121
122int final_segment_size      = 0; // size of final segment within a buffer
123
124int stream_base             = 0;
125int match_pos               = 0;
126
127int main(int argc, char * argv[]) {
128  if ((2 > argc) || (2 < argc)) {
129      printf("Usage: %s <filename>\n", argv[0]); exit(1);
130  }
131
132  char * infilename = argv[argc-1];
133  FILE * istream;
134  if((istream = fopen(infilename, "rb")) == NULL ) {
135      printf("fopen error\n"); exit(1);
136  }
137
138  ATTRIBUTE_SIMD_ALIGN char buffer[BUFFER_SIZE];
139  // Pablo transpose.do_block(), transpose.do_final_block()
140  // expect 'byte_data' and 'basis' names as input and output arguments.
141  char * byte_data = buffer;
142
143  // Marker stream iterator.
144  BitStreamScanner<BitBlock, ScanWord, ScanWord, SEGMENT_BLOCKS> match_scanner;
145  BitStreamScanner<BitBlock, ScanWord, ScanWord, SEGMENT_BLOCKS> LF_scanner;
146
147  // Segment-at-a-time processing.
148  while(!feof(istream)) {
149    // Read Stream in BUFFER_SIZE - strlen("needle") byte chunks.
150    bytes_read  = fread(buffer + copy_back_size, 1,
151                        BUFFER_SIZE - copy_back_size, istream);
152    bytes_avail = bytes_read + copy_back_size;
153
154    if(feof(istream)) { bytes_avail--; }
155    if(ferror(istream)) { perror( "io error" ); exit(1); }
156
157    // Process full segments.
158    block_base      = 0;
159
160    while (bytes_avail >= SEGMENT_SIZE) {
161      match_scanner.init();
162      LF_scanner.init();
163
164      for(block_index = 0;
165          block_index < SEGMENT_BLOCKS;
166          block_index++, block_base+=BLOCK_SIZE) {
167
168        byte_data = &buffer[block_base];
169        //Replaced with C++ stream function 'do_block()' calls.
170        @block_stmts
171
172        match_scanner.load_block(output.matches, block_index);
173        LF_scanner.load_block(lex.LF, block_index);
174      }
175
176      while(match_scanner.has_next()) {
177        match_pos = match_scanner.scan_to_next()
178                       + stream_base - pattern_size + 1;
179        printf("%d:%s\n", match_pos, fixed_pattern);
180      }
181
182      stream_base += SEGMENT_SIZE;
183      bytes_avail -= SEGMENT_SIZE;
184    }
185
186    // Process the final partial segment full blocks.
187    block_index = 0;
188    final_segment_size = bytes_avail;
189    match_scanner.init();
190
191    // Process full blocks.
192    while (bytes_avail >= BLOCK_SIZE) {
193      byte_data = &buffer[block_base];
194      //Replaced with C++ stream function 'do_block()' calls.
195      @block_stmts
196
197      match_scanner.load_block(output.matches, block_index);
198
199      block_base += BLOCK_SIZE;
200      bytes_avail -= BLOCK_SIZE;
201      block_index++;
202    }
203
204    // Process the final partial block.
205    if(bytes_avail > 0) {
206      BitBlock EOF_mask = file_extent_mask(bytes_avail);
207      byte_data = &buffer[block_base];
208      //Replaced with C++ stream function 'do_final_block()' calls.
209      @final_block_stmts
210
211      match_scanner.load_block(output.matches, block_index);
212    }
213
214    while(match_scanner.has_next()) {
215      match_pos = match_scanner.scan_to_next()
216                     + stream_base - pattern_size + 1;
217
218      printf("%d:%s\n", match_pos, fixed_pattern);
219    }
220
221    stream_base += final_segment_size;
222
223    // Copy strlen("needle") - 1 bytes at the segment boundary to handle
224    // partial matches of the "needle" at segment boundaries.
225    copy_back_size     = pattern_size - 1;
226    copy_back_pos      = block_base + bytes_avail - copy_back_size;
227
228//    int copy_back_size = SEGMENT_SIZE - copy_back_pos;
229//    int copy_back_pos = LF_scanner.get_final_pos() + 1;
230
231    memmove(&buffer[0], &buffer[copy_back_pos], copy_back_size);
232
233    stream_base -= copy_back_size;
234  }
235
236  fclose(istream);
237  return 0;
238}
239
240BitBlock file_extent_mask(int size) {
241  return bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-size));
242}
243
Note: See TracBrowser for help on using the repository browser.