source: icGREP/icgrep-devel/icgrep/lz4/grep/lz4_grep_base_generator.cpp @ 6152

Last change on this file since 6152 was 6152, checked in by xwa163, 7 months ago

lz4_grep: Merge u8NonFinal into multiplexed character classes

File size: 27.8 KB
Line 
1
2#include "lz4_grep_base_generator.h"
3
4#include <boost/iostreams/device/mapped_file.hpp>
5
6#include <llvm/Support/PrettyStackTrace.h>
7
8#include <cc/cc_compiler.h>
9
10#include <kernels/cc_kernel.h>
11#include <kernels/s2p_kernel.h>
12#include <kernels/p2s_kernel.h>
13#include <kernels/source_kernel.h>
14#include <kernels/stdout_kernel.h>
15#include <kernels/fake_stream_generating_kernel.h>
16#include <re/re_toolchain.h>
17
18#include <re/collect_ccs.h>
19#include <re/replaceCC.h>
20
21#include <re/casing.h>
22#include <re/exclude_CC.h>
23#include <re/to_utf8.h>
24#include <re/re_analysis.h>
25#include <re/re_name_resolve.h>
26#include <re/re_name_gather.h>
27#include <re/re_multiplex.h>
28#include <re/re_utility.h>
29
30#include <UCD/resolve_properties.h>
31#include <kernels/charclasses.h>
32#include <kernels/grep_kernel.h>
33#include <kernels/UCD_property_kernel.h>
34#include <kernels/grapheme_kernel.h>
35#include <kernels/linebreak_kernel.h>
36#include <kernels/streams_merge.h>
37#include <kernels/scanmatchgen.h>
38#include <kernels/until_n.h>
39#include <re/grapheme_clusters.h>
40#include <re/printer_re.h>
41#include <llvm/Support/raw_ostream.h>
42#include <llvm/Support/Debug.h>
43#include <kernels/lz4/lz4_block_decoder.h>
44#include <kernels/lz4/lz4_match_detector.h>
45
46#include <re/re_seq.h>
47#include <kernels/kernel_builder.h>
48#include <re/re_alt.h>
49#include <kernels/lz4/decompression/lz4_bytestream_decompression.h>
50#include <kernels/lz4/lz4_not_kernel.h>
51
52namespace re { class CC; }
53
54using namespace llvm;
55using namespace parabix;
56using namespace kernel;
57using namespace grep;
58using namespace re;
59
60LZ4GrepBaseGenerator::LZ4GrepBaseGenerator()
61        : LZ4BaseGenerator(),
62          u8NonFinalRe(makeAlt({makeByte(0xC2, 0xF4),
63                                makeSeq({makeByte(0xE0, 0xF4), makeByte(0x80, 0xBF)}),
64                                makeSeq({makeByte(0xF0, 0xF4), makeByte(0x80, 0xBF), makeByte(0x80, 0xBF)})})),
65          u8FinalRe(makeCC(0x0, 0x1FFFFF))
66{
67    mGrepRecordBreak = grep::GrepRecordBreakKind::LF;
68    mMoveMatchesToEOL = true;
69}
70
71void LZ4GrepBaseGenerator::generateScanMatchGrepPipeline(re::RE* regex, bool enableMultiplexing, bool utf8CC) {
72    if (enableMultiplexing) {
73        this->generateMultiplexingScanMatchGrepPipeline(regex, utf8CC);
74    } else {
75        this->generateFullyDecompressionScanMatchGrepPipeline(regex);
76    }
77}
78
79void LZ4GrepBaseGenerator::generateCountOnlyGrepPipeline(re::RE* regex, bool enableMultiplexing, bool utf8CC){
80    if (enableMultiplexing) {
81        this->generateMultiplexingCountOnlyGrepPipeline(regex, utf8CC);
82    } else {
83        this->generateFullyDecompressionCountOnlyGrepPipeline(regex);
84    }
85}
86
87void LZ4GrepBaseGenerator::initREs(re::RE * RE) {
88    if (mGrepRecordBreak == GrepRecordBreakKind::Unicode) {
89        mBreakCC = re::makeCC(re::makeCC(0x0A, 0x0D), re::makeCC(re::makeCC(0x85), re::makeCC(0x2028, 0x2029)));
90    } else if (mGrepRecordBreak == GrepRecordBreakKind::Null) {
91        mBreakCC = re::makeByte(0);  // Null
92    } else {
93        mBreakCC = re::makeByte(0x0A); // LF
94    }
95    re::RE * anchorRE = mBreakCC;
96    if (mGrepRecordBreak == GrepRecordBreakKind::Unicode) {
97        re::Name * anchorName = re::makeName("UTF8_LB", re::Name::Type::Unicode);
98        anchorName->setDefinition(re::makeUnicodeBreak());
99        anchorRE = anchorName;
100    }
101
102    mRE = RE;
103    bool allAnchored = true;
104
105    if (!hasEndAnchor(mRE)) allAnchored = false;
106    mRE = resolveModesAndExternalSymbols(mRE);
107    mRE = re::exclude_CC(mRE, mBreakCC);
108    mRE = resolveAnchors(mRE, anchorRE);
109    re::gatherUnicodeProperties(mRE, mUnicodeProperties);
110    mRE = regular_expression_passes(mRE);
111
112    if (allAnchored && (mGrepRecordBreak != GrepRecordBreakKind::Unicode)) mMoveMatchesToEOL = false;
113
114}
115
116parabix::StreamSetBuffer * LZ4GrepBaseGenerator::linefeedStreamFromUncompressedBits(
117        parabix::StreamSetBuffer *uncompressedBasisBits) {
118    auto & idb = mPxDriver.getBuilder();
119    const unsigned baseBufferSize = this->getDefaultBufferBlocks();
120    StreamSetBuffer * LineFeedStream = mPxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
121    kernel::Kernel * linefeedK = mPxDriver.addKernelInstance<kernel::LineFeedKernelBuilder>(idb, Binding{idb->getStreamSetTy(8), "basis", FixedRate(), Principal()}, cc::BitNumbering::BigEndian);
122    mPxDriver.makeKernelCall(linefeedK, {uncompressedBasisBits}, {LineFeedStream});
123    return LineFeedStream;
124}
125
126std::pair<parabix::StreamSetBuffer *, parabix::StreamSetBuffer *> LZ4GrepBaseGenerator::multiplexingGrep(
127        re::RE *RE,
128        parabix::StreamSetBuffer *compressedByteStream,
129        parabix::StreamSetBuffer *compressedBitStream,
130        bool utf8CC
131) {
132
133    this->initREs(RE);
134    auto mGrepDriver = &mPxDriver;
135
136    auto & idb = mGrepDriver->getBuilder();
137    const unsigned baseBufferSize = this->getDefaultBufferBlocks();
138    int MaxCountFlag = 0;
139
140    //  Regular Expression Processing and Analysis Phase
141    const auto nREs = 1;
142
143    std::vector<StreamSetBuffer *> MatchResultsBufs(nREs);
144
145
146    std::map<std::string, StreamSetBuffer *> propertyStream;
147
148    std::vector<std::string> externalStreamNames;
149    std::set<re::Name *> UnicodeProperties;
150
151    StreamSetBuffer* fakeMatchCopiedBits = nullptr;
152    StreamSetBuffer* u8NoFinalStream = nullptr;
153    StreamSetBuffer * uncompressedCharClasses = nullptr;
154
155    re::CC* linefeedCC = nullptr;
156
157
158    if (utf8CC) {
159        re::Seq* seq = re::makeSeq();
160        re::RE* targetRe = mRE;
161
162        bool allCcByteLength = re::isAllCcByteLength(mRE);
163
164        linefeedCC = re::makeCC(0x0A);
165
166        seq->push_back(targetRe);
167        seq->push_back(std::move(linefeedCC));
168        seq->push_back(u8FinalRe);
169
170        std::vector<re::CC*> UnicodeSets = re::collectCCs(seq, &cc::Unicode, std::set<re::Name *>({re::makeZeroWidth("\\b{g}")}));;
171
172        mpx = make_unique<cc::MultiplexedAlphabet>("mpx", UnicodeSets);
173        mRE = transformCCs(mpx.get(), targetRe);
174
175
176        std::vector<re::CC *> mpx_basis = mpx->getMultiplexedCCs();
177        auto numOfCharacterClasses = mpx_basis.size();
178        llvm::errs() << "numOfUnicodeSet:" << UnicodeSets.size() << "\n";
179
180        llvm::errs() << "numOfCharacterClasses:" << numOfCharacterClasses << "\n";
181        StreamSetBuffer * CharClasses = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(numOfCharacterClasses), baseBufferSize, 1);
182
183        kernel::Kernel * ccK = mGrepDriver->addKernelInstance<kernel::CharClassesKernel>(idb, std::move(mpx_basis), false, cc::BitNumbering::BigEndian);
184        mGrepDriver->makeKernelCall(ccK, {compressedBitStream}, {CharClasses});
185
186        if (allCcByteLength) {
187            // We do not need to decompress U8 NonFinal Stream is all of the character class in target regular expression is byte length
188            uncompressedCharClasses = this->decompressBitStream(compressedByteStream, CharClasses);
189            auto fakeStreams = this->generateFakeStreams(idb, uncompressedCharClasses, std::vector<unsigned>{8, 1});
190            fakeMatchCopiedBits = fakeStreams[0];
191            u8NoFinalStream = fakeStreams[1];
192        } else {
193//            StreamSetBuffer* compressedNonFinalStream = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
194//            kernel::Kernel * nonFinalK = mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, u8NonFinalRe, externalStreamNames, std::vector<cc::Alphabet *>(), cc::BitNumbering::BigEndian);
195//            mGrepDriver->makeKernelCall(nonFinalK, {compressedBitStream}, {compressedNonFinalStream});
196
197            auto decompressedStreams = this->decompressBitStreams(compressedByteStream, {CharClasses/*, compressedNonFinalStream*/});
198            uncompressedCharClasses = decompressedStreams[0];
199//            u8NoFinalStream = decompressedStreams[1];
200
201            auto fakeStreams = this->generateFakeStreams(idb, uncompressedCharClasses, std::vector<unsigned>{8});
202            fakeMatchCopiedBits = fakeStreams[0];
203
204            StreamSetBuffer * u8FinalStream = mPxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), this->getDefaultBufferBlocks(), 1);
205            ICGrepKernel * u8FinalGrepK = (ICGrepKernel *)mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, transformCCs(mpx.get(), u8FinalRe), externalStreamNames, std::vector<cc::Alphabet *>{mpx.get()}, cc::BitNumbering::BigEndian);
206            u8FinalGrepK->setCachable(false);
207            mGrepDriver->makeKernelCall(u8FinalGrepK, {fakeMatchCopiedBits, uncompressedCharClasses}, {u8FinalStream});
208
209            u8NoFinalStream = mPxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), this->getDefaultBufferBlocks(), 1);
210            Kernel* notK = mGrepDriver->addKernelInstance<LZ4NotKernel>(idb);
211            mGrepDriver->makeKernelCall(notK, {u8FinalStream}, {u8NoFinalStream});
212
213        }
214    } else {
215        re::Seq* seq = re::makeSeq();
216        re::RE* targetRe = mRE;
217        targetRe = re::toUTF8(targetRe, true);
218
219        linefeedCC = re::makeByte(0x0A);
220
221        seq->push_back(targetRe);
222        seq->push_back(std::move(linefeedCC));
223
224        std::vector<re::CC*> UnicodeSets = re::collectCCs(seq, &cc::Byte, std::set<re::Name *>({re::makeZeroWidth("\\b{g}")}));
225
226        mpx = make_unique<cc::MultiplexedAlphabet>("mpx", UnicodeSets);
227        mRE = transformCCs(mpx.get(), targetRe);
228
229        std::vector<re::CC *> mpx_basis = mpx->getMultiplexedCCs();
230        auto numOfCharacterClasses = mpx_basis.size();
231        llvm::errs() << "numOfUnicodeSet:" << UnicodeSets.size() << "\n";
232        llvm::errs() << "numOfCharacterClasses:" << numOfCharacterClasses << "\n";
233        StreamSetBuffer * CharClasses = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(numOfCharacterClasses), baseBufferSize, 1);
234
235        kernel::Kernel * ccK = mGrepDriver->addKernelInstance<kernel::ByteClassesKernel>(idb, std::move(mpx_basis), false, cc::BitNumbering::BigEndian);
236        mGrepDriver->makeKernelCall(ccK, {compressedBitStream}, {CharClasses});
237
238        uncompressedCharClasses = this->decompressBitStream(compressedByteStream, CharClasses);
239        auto fakeStreams = this->generateFakeStreams(idb, uncompressedCharClasses, std::vector<unsigned>{8, 1});
240        fakeMatchCopiedBits = fakeStreams[0];
241        u8NoFinalStream = fakeStreams[1];
242    }
243
244    StreamSetBuffer * const MatchResults = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
245
246    // Multiplexing Grep Kernel is not Cachable, since it is possible that two REs with name "mpx_1" have different alphabets
247    StreamSetBuffer * LineBreakStream = mPxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), this->getDefaultBufferBlocks(), 1);
248    ICGrepKernel * lineFeedGrepK = (ICGrepKernel *)mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, transformCCs(mpx.get(), linefeedCC), externalStreamNames, std::vector<cc::Alphabet *>{mpx.get()}, cc::BitNumbering::BigEndian);
249    lineFeedGrepK->setCachable(false);
250    mGrepDriver->makeKernelCall(lineFeedGrepK, {fakeMatchCopiedBits, uncompressedCharClasses}, {LineBreakStream});
251
252
253    externalStreamNames.push_back("UTF8_nonfinal");
254
255    ICGrepKernel * icgrepK = (ICGrepKernel *)mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, mRE, externalStreamNames, std::vector<cc::Alphabet *>{mpx.get()}, cc::BitNumbering::BigEndian);
256    icgrepK->setCachable(false);
257    mGrepDriver->makeKernelCall(icgrepK, {fakeMatchCopiedBits, u8NoFinalStream, uncompressedCharClasses}, {MatchResults});
258    MatchResultsBufs[0] = MatchResults;
259
260    StreamSetBuffer * MergedResults = MatchResultsBufs[0];
261
262    StreamSetBuffer * Matches = MergedResults;
263    if (mMoveMatchesToEOL) {
264        StreamSetBuffer * OriginalMatches = Matches;
265        kernel::Kernel * matchedLinesK = mGrepDriver->addKernelInstance<kernel::MatchedLinesKernel>(idb);
266        Matches = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
267        mGrepDriver->makeKernelCall(matchedLinesK, {OriginalMatches, LineBreakStream}, {Matches});
268    }
269
270    if (MaxCountFlag > 0) {
271        kernel::Kernel * untilK = mGrepDriver->addKernelInstance<kernel::UntilNkernel>(idb);
272        untilK->setInitialArguments({idb->getSize(MaxCountFlag)});
273        StreamSetBuffer * const AllMatches = Matches;
274        Matches = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
275        mGrepDriver->makeKernelCall(untilK, {AllMatches}, {Matches});
276    }
277
278    return std::pair<StreamSetBuffer *, StreamSetBuffer *>(LineBreakStream, Matches);
279};
280
281std::pair<parabix::StreamSetBuffer *, parabix::StreamSetBuffer *> LZ4GrepBaseGenerator::grep(
282        re::RE *RE, parabix::StreamSetBuffer *byteStream, parabix::StreamSetBuffer *uncompressedBasisBits, bool ccMultiplexing) {
283
284    this->initREs(RE);
285    auto mGrepDriver = &mPxDriver;
286
287    auto & idb = mGrepDriver->getBuilder();
288    // TODO: until we automate stream buffer sizing, use this calculation to determine how large our matches buffer needs to be.
289    const unsigned baseBufferSize = this->getDefaultBufferBlocks();
290    int MaxCountFlag = 0;
291
292    //  Regular Expression Processing and Analysis Phase
293    const auto nREs = 1;
294
295    std::vector<StreamSetBuffer *> MatchResultsBufs(nREs);
296
297    StreamSetBuffer * LineBreakStream = nullptr;
298
299
300    std::map<std::string, StreamSetBuffer *> propertyStream;
301
302    for(unsigned i = 0; i < nREs; ++i) {
303
304
305        if (ccMultiplexing) {
306
307            if (uncompressedBasisBits == nullptr) {
308                uncompressedBasisBits = this->s2p(byteStream);
309            }
310            this->linefeedStreamFromUncompressedBits(uncompressedBasisBits);
311            std::vector<std::string> externalStreamNames;
312            std::vector<StreamSetBuffer *> icgrepInputSets = {uncompressedBasisBits};
313
314            const auto UnicodeSets = re::collectCCs(mRE, &cc::Unicode, std::set<re::Name *>({re::makeZeroWidth("\\b{g}")}));
315            StreamSetBuffer * const MatchResults = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
316
317            std::unique_ptr<cc::MultiplexedAlphabet> mpx = make_unique<cc::MultiplexedAlphabet>("mpx", UnicodeSets);
318            mRE = transformCCs(mpx.get(), mRE);
319            std::vector<re::CC *> mpx_basis = mpx->getMultiplexedCCs();
320            auto numOfCharacterClasses = mpx_basis.size();
321            StreamSetBuffer * CharClasses = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(numOfCharacterClasses), baseBufferSize, 1);
322            kernel::Kernel * ccK = mGrepDriver->addKernelInstance<kernel::CharClassesKernel>(idb, std::move(mpx_basis), false, cc::BitNumbering::BigEndian);
323            mGrepDriver->makeKernelCall(ccK, {uncompressedBasisBits}, {CharClasses});
324
325            kernel::Kernel * icgrepK = mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, mRE, externalStreamNames, std::vector<cc::Alphabet *>{mpx.get()}, cc::BitNumbering::BigEndian);
326            icgrepInputSets.push_back(CharClasses);
327            mGrepDriver->makeKernelCall(icgrepK, icgrepInputSets, {MatchResults});
328            MatchResultsBufs[i] = MatchResults;
329        } else {
330
331            bool anyGCB = hasGraphemeClusterBoundary(mRE);
332            bool isSimple = (mGrepRecordBreak != GrepRecordBreakKind::Unicode) && (!anyGCB);
333            if (isSimple) {
334                mRE = toUTF8(mRE);
335            }
336            const unsigned ByteCClimit = 6;
337
338            if (byteTestsWithinLimit(mRE, ByteCClimit)) {
339                LineBreakStream = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
340                kernel::Kernel * breakK = mGrepDriver->addKernelInstance<kernel::DirectCharacterClassKernelBuilder>(idb, "breakCC", std::vector<re::CC *>{mBreakCC});
341                mGrepDriver->makeKernelCall(breakK, {byteStream}, {LineBreakStream});
342
343                std::vector<std::string> externalStreamNames;
344                std::vector<StreamSetBuffer *> icgrepInputSets = {byteStream};
345                StreamSetBuffer * MatchResults = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize);
346                kernel::Kernel * icgrepK = mGrepDriver->addKernelInstance<kernel::ByteGrepKernel>(idb, mRE, externalStreamNames);
347                mGrepDriver->makeKernelCall(icgrepK, icgrepInputSets, {MatchResults});
348                MatchResultsBufs[i] = MatchResults;
349
350            } else {
351
352                if (uncompressedBasisBits == nullptr) {
353                    uncompressedBasisBits = this->s2p(byteStream);
354                }
355                this->linefeedStreamFromUncompressedBits(uncompressedBasisBits);
356                std::vector<std::string> externalStreamNames;
357                std::vector<StreamSetBuffer *> icgrepInputSets = {uncompressedBasisBits};
358
359                std::set<re::Name *> UnicodeProperties;
360                StreamSetBuffer * MatchResults = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
361                kernel::Kernel * icgrepK = mGrepDriver->addKernelInstance<kernel::ICGrepKernel>(idb, mRE, externalStreamNames, std::vector<cc::Alphabet *>(), cc::BitNumbering::BigEndian);
362                mGrepDriver->makeKernelCall(icgrepK, icgrepInputSets, {MatchResults});
363                MatchResultsBufs[i] = MatchResults;
364            }
365        }
366    }
367
368    StreamSetBuffer * MergedResults = MatchResultsBufs[0];
369
370    StreamSetBuffer * Matches = MergedResults;
371    if (mMoveMatchesToEOL) {
372        StreamSetBuffer * OriginalMatches = Matches;
373        kernel::Kernel * matchedLinesK = mGrepDriver->addKernelInstance<kernel::MatchedLinesKernel>(idb);
374        Matches = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
375        mGrepDriver->makeKernelCall(matchedLinesK, {OriginalMatches, LineBreakStream}, {Matches});
376    }
377
378    if (MaxCountFlag > 0) {
379        kernel::Kernel * untilK = mGrepDriver->addKernelInstance<kernel::UntilNkernel>(idb);
380        untilK->setInitialArguments({idb->getSize(MaxCountFlag)});
381        StreamSetBuffer * const AllMatches = Matches;
382        Matches = mGrepDriver->addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), baseBufferSize, 1);
383        mGrepDriver->makeKernelCall(untilK, {AllMatches}, {Matches});
384    }
385
386    return std::pair<StreamSetBuffer *, StreamSetBuffer *>(LineBreakStream, Matches);
387
388}
389
390void LZ4GrepBaseGenerator::invokeScanMatchGrep(char* fileBuffer, size_t blockStart, size_t blockEnd, bool hasBlockChecksum) {
391    auto main = this->getScanMatchGrepMainFunction();
392    std::ostringstream s;
393    EmitMatch accum("", false, false, s);
394
395    main(fileBuffer, blockStart, blockEnd, hasBlockChecksum, reinterpret_cast<intptr_t>(&accum));
396    llvm::outs() << s.str();
397}
398
399
400void LZ4GrepBaseGenerator::generateFullyDecompressionScanMatchGrepPipeline(re::RE *regex) {
401    auto & iBuilder = mPxDriver.getBuilder();
402    this->generateScanMatchMainFunc(iBuilder);
403
404    StreamSetBuffer* compressedByteStream = this->loadByteStream();
405
406    StreamSetBuffer * const uncompressedByteStream = this->byteStreamDecompression(compressedByteStream);
407    StreamSetBuffer * uncompressedBitStream = this->s2p(uncompressedByteStream);
408
409    StreamSetBuffer * LineBreakStream;
410    StreamSetBuffer * Matches;
411    std::tie(LineBreakStream, Matches) = grep(regex, uncompressedByteStream, uncompressedBitStream);
412
413    kernel::Kernel * scanMatchK = mPxDriver.addKernelInstance<kernel::ScanMatchKernel>(iBuilder);
414    scanMatchK->setInitialArguments({match_accumulator});
415    mPxDriver.makeKernelCall(scanMatchK, {Matches, LineBreakStream, uncompressedByteStream}, {});
416    mPxDriver.LinkFunction(*scanMatchK, "accumulate_match_wrapper", &accumulate_match_wrapper);
417    mPxDriver.LinkFunction(*scanMatchK, "finalize_match_wrapper", &finalize_match_wrapper);
418
419    mPxDriver.generatePipelineIR();
420    mPxDriver.deallocateBuffers();
421
422    iBuilder->CreateRetVoid();
423
424    mPxDriver.finalizeObject();
425}
426
427void LZ4GrepBaseGenerator::generateMultiplexingScanMatchGrepPipeline(re::RE *regex, bool utf8CC) {
428    auto & iBuilder = mPxDriver.getBuilder();
429    this->generateScanMatchMainFunc(iBuilder);
430
431    StreamSetBuffer *compressedByteStream = nullptr, *compressedBasisBits = nullptr;
432    std::tie(compressedByteStream, compressedBasisBits) = this->loadByteStreamAndBitStream();
433
434    StreamSetBuffer * LineBreakStream;
435    StreamSetBuffer * Matches;
436    std::tie(LineBreakStream, Matches) = multiplexingGrep(regex, compressedByteStream, compressedBasisBits, utf8CC);
437
438//    Kernel* matchDetector = mPxDriver.addKernelInstance<LZ4MatchDetectorKernel>(iBuilder);
439//    StreamSetBuffer* hasMatch = mPxDriver.addBuffer<StaticBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 8),
440//                                                                  this->getDefaultBufferBlocks(), 1);
441//    mPxDriver.makeKernelCall(matchDetector, {Matches, LineBreakStream}, {hasMatch});
442
443
444    LZ4BlockInfo blockInfo = this->getBlockInfo(compressedByteStream);
445
446    StreamSetBuffer *const uncompressedByteStream =
447            mPxDriver.addBuffer<StaticBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 8),
448                                              this->getDefaultBufferBlocks(), 1);
449    Kernel* lz4AioK = mPxDriver.addKernelInstance<LZ4ByteStreamDecompressionKernel>(iBuilder, false, 4 * 1024 * 1024, true);
450    lz4AioK->setInitialArguments({mFileSize});
451    mPxDriver.makeKernelCall(
452            lz4AioK,
453            {
454                    compressedByteStream,
455
456                    // Block Data
457                    blockInfo.isCompress,
458                    blockInfo.blockStart,
459                    blockInfo.blockEnd,
460                    Matches
461            }, {
462                    uncompressedByteStream
463            });
464
465
466    kernel::Kernel * scanMatchK = mPxDriver.addKernelInstance<kernel::ScanMatchKernel>(iBuilder);
467    scanMatchK->setInitialArguments({match_accumulator});
468    mPxDriver.makeKernelCall(scanMatchK, {Matches, LineBreakStream, uncompressedByteStream}, {});
469    mPxDriver.LinkFunction(*scanMatchK, "accumulate_match_wrapper", &accumulate_match_wrapper);
470    mPxDriver.LinkFunction(*scanMatchK, "finalize_match_wrapper", &finalize_match_wrapper);
471
472
473    mPxDriver.generatePipelineIR();
474
475    mPxDriver.deallocateBuffers();
476    iBuilder->CreateRetVoid();
477    mPxDriver.finalizeObject();
478}
479
480
481void LZ4GrepBaseGenerator::generateMultiplexingCountOnlyGrepPipeline(re::RE *regex, bool utf8CC) {
482    auto & iBuilder = mPxDriver.getBuilder();
483    this->generateCountOnlyMainFunc(iBuilder);
484
485    StreamSetBuffer *compressedByteStream = nullptr, *compressedBasisBits = nullptr;
486    std::tie(compressedByteStream, compressedBasisBits) = this->loadByteStreamAndBitStream();
487
488    StreamSetBuffer * LineBreakStream;
489    StreamSetBuffer * Matches;
490    std::tie(LineBreakStream, Matches) = multiplexingGrep(regex, compressedByteStream, compressedBasisBits, utf8CC);
491
492    kernel::Kernel * matchCountK = mPxDriver.addKernelInstance<kernel::PopcountKernel>(iBuilder);
493    mPxDriver.makeKernelCall(matchCountK, {Matches}, {});
494    mPxDriver.generatePipelineIR();
495
496    iBuilder->setKernel(matchCountK);
497    Value * matchedLineCount = iBuilder->getAccumulator("countResult");
498    matchedLineCount = iBuilder->CreateZExt(matchedLineCount, iBuilder->getInt64Ty());
499
500    mPxDriver.deallocateBuffers();
501
502    iBuilder->CreateRet(matchedLineCount);
503
504    mPxDriver.finalizeObject();
505}
506
507
508void LZ4GrepBaseGenerator::generateFullyDecompressionCountOnlyGrepPipeline(re::RE *regex) {
509    auto & iBuilder = mPxDriver.getBuilder();
510    this->generateCountOnlyMainFunc(iBuilder);
511
512    StreamSetBuffer * const uncompressedByteStream = this->generateUncompressedByteStream();
513//    StreamSetBuffer * const uncompressedBitStream = this->generateUncompressedBitStreams();
514
515    StreamSetBuffer * LineBreakStream;
516    StreamSetBuffer * Matches;
517
518    std::tie(LineBreakStream, Matches) = grep(regex, uncompressedByteStream, nullptr);
519
520    kernel::Kernel * matchCountK = mPxDriver.addKernelInstance<kernel::PopcountKernel>(iBuilder);
521    mPxDriver.makeKernelCall(matchCountK, {Matches}, {});
522    mPxDriver.generatePipelineIR();
523
524    iBuilder->setKernel(matchCountK);
525    Value * matchedLineCount = iBuilder->getAccumulator("countResult");
526    matchedLineCount = iBuilder->CreateZExt(matchedLineCount, iBuilder->getInt64Ty());
527
528    mPxDriver.deallocateBuffers();
529
530    iBuilder->CreateRet(matchedLineCount);
531
532    mPxDriver.finalizeObject();
533}
534
535
536ScanMatchGrepMainFunctionType LZ4GrepBaseGenerator::getScanMatchGrepMainFunction() {
537    return reinterpret_cast<ScanMatchGrepMainFunctionType>(mPxDriver.getMain());
538}
539CountOnlyGrepMainFunctionType LZ4GrepBaseGenerator::getCountOnlyGrepMainFunction() {
540    return reinterpret_cast<CountOnlyGrepMainFunctionType>(mPxDriver.getMain());
541}
542
543void LZ4GrepBaseGenerator::generateCountOnlyMainFunc(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
544    Module * M = iBuilder->getModule();
545    Type * const int64Ty = iBuilder->getInt64Ty();
546    Type * const sizeTy = iBuilder->getSizeTy();
547    Type * const boolTy = iBuilder->getIntNTy(sizeof(bool) * 8);
548//    Type * const voidTy = iBuilder->getVoidTy();
549    Type * const inputType = iBuilder->getInt8PtrTy();
550
551    Function * const main = cast<Function>(M->getOrInsertFunction("Main", int64Ty, inputType, sizeTy, sizeTy, boolTy, nullptr));
552    main->setCallingConv(CallingConv::C);
553    Function::arg_iterator args = main->arg_begin();
554    mInputStream = &*(args++);
555    mInputStream->setName("input");
556
557    mHeaderSize = &*(args++);
558    mHeaderSize->setName("mHeaderSize");
559
560    mFileSize = &*(args++);
561    mFileSize->setName("mFileSize");
562
563    mHasBlockChecksum = &*(args++);
564    mHasBlockChecksum->setName("mHasBlockChecksum");
565    // TODO for now, we do not handle blockCheckSum
566    mHasBlockChecksum = iBuilder->getInt1(false);
567
568    iBuilder->SetInsertPoint(BasicBlock::Create(M->getContext(), "entry", main, 0));
569}
570
571void LZ4GrepBaseGenerator::generateScanMatchMainFunc(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
572    Module * M = iBuilder->getModule();
573    Type * const sizeTy = iBuilder->getSizeTy();
574    Type * const boolTy = iBuilder->getIntNTy(sizeof(bool) * 8);
575    Type * const voidTy = iBuilder->getVoidTy();
576    Type * const inputType = iBuilder->getInt8PtrTy();
577    Type * const intAddrTy = iBuilder->getIntAddrTy();
578
579    Function * const main = cast<Function>(M->getOrInsertFunction("Main", voidTy, inputType, sizeTy, sizeTy, boolTy, intAddrTy, nullptr));
580    main->setCallingConv(CallingConv::C);
581    Function::arg_iterator args = main->arg_begin();
582    mInputStream = &*(args++);
583    mInputStream->setName("input");
584
585    mHeaderSize = &*(args++);
586    mHeaderSize->setName("mHeaderSize");
587
588    mFileSize = &*(args++);
589    mFileSize->setName("mFileSize");
590
591    mHasBlockChecksum = &*(args++);
592    mHasBlockChecksum->setName("mHasBlockChecksum");
593
594    match_accumulator = &*(args++);
595    match_accumulator->setName("match_accumulator");
596
597    iBuilder->SetInsertPoint(BasicBlock::Create(M->getContext(), "entry", main, 0));
598}
599
600std::vector<parabix::StreamSetBuffer *>
601LZ4GrepBaseGenerator::generateFakeStreams(const std::unique_ptr<kernel::KernelBuilder> &idb,
602                                          parabix::StreamSetBuffer *refStream, std::vector<unsigned> numOfStreams) {
603
604    if (!numOfStreams.size()) {
605        return std::vector<StreamSetBuffer *>();
606    }
607    std::vector<StreamSetBuffer *> outputStreams;
608    for (unsigned i = 0; i < numOfStreams.size(); i++) {
609        outputStreams.push_back(mPxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(numOfStreams[i]),
610                                                                  this->getDefaultBufferBlocks(), 1));
611    }
612    Kernel* fakeStreamGeneratorK = mPxDriver.addKernelInstance<FakeStreamGeneratingKernel>(idb, refStream->getNumOfStreams(), numOfStreams);
613    mPxDriver.makeKernelCall(fakeStreamGeneratorK, {refStream}, outputStreams);
614    return outputStreams;
615}
616
617
618
619std::vector<parabix::StreamSetBuffer *>
620LZ4GrepBaseGenerator::decompressBitStreams(parabix::StreamSetBuffer *compressedByteStream,
621                                           std::vector<parabix::StreamSetBuffer *> compressedBitStreams) {
622    // Default implementation here will be slow
623    std::vector<parabix::StreamSetBuffer *> retVec;
624    for (unsigned i = 0; i < compressedBitStreams.size(); i++) {
625        retVec.push_back(this->decompressBitStream(compressedByteStream, compressedBitStreams[i]));
626    }
627    return retVec;
628}
Note: See TracBrowser for help on using the repository browser.