source: icGREP/icgrep-devel/icgrep/editd/editd.cpp @ 5577

Last change on this file since 5577 was 5577, checked in by lindanl, 2 years ago

minor fixes.

  • Property svn:executable set to *
File size: 24.2 KB
Line 
1/*
2 *  Copyright (c) 2015 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include <string>
8#include <iostream>
9#include <fstream>
10#include <toolchain/toolchain.h>
11#include <pablo/pablo_toolchain.h>
12#include <llvm/IR/Function.h>
13#include <llvm/IR/Module.h>
14#include <llvm/Support/CommandLine.h>
15#include <cc/cc_compiler.h>
16#include <pablo/pablo_compiler.h>
17#include <pablo/pablo_kernel.h>
18#include <kernels/kernel_builder.h>
19#include <IR_Gen/idisa_target.h>
20#include <kernels/streamset.h>
21#include <kernels/source_kernel.h>
22#include <kernels/s2p_kernel.h>
23#include <editd/editdscan_kernel.h>
24#include <editd/pattern_compiler.h>
25#include <toolchain/cpudriver.h>
26#include <sys/stat.h>
27#include <fcntl.h>
28#include <mutex>
29
30#include <toolchain/NVPTXDriver.h>
31#include <editd/editd_gpu_kernel.h>
32#ifdef CUDA_ENABLED
33#include <editd/EditdCudaDriver.h>
34#endif
35
36using namespace llvm;
37
38static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<regex> <input file ...>"), cl::OneOrMore);
39
40static cl::list<std::string> pattVector("e", cl::desc("pattern"), cl::ZeroOrMore);
41static cl::opt<std::string> PatternFilename("f", cl::desc("Take patterns (one per line) from a file"), cl::value_desc("regex file"), cl::init(""));
42
43static cl::opt<bool> CaseInsensitive("i", cl::desc("Ignore case distinctions in the pattern and the file."));
44
45static cl::opt<int> editDistance("edit-dist", cl::desc("Edit Distance Value"), cl::init(2));
46static cl::opt<int> optPosition("opt-pos", cl::desc("Optimize position"), cl::init(8));
47static cl::opt<int> stepSize("step-size", cl::desc("Step Size"), cl::init(3));
48static cl::opt<int> prefixLen("prefix", cl::desc("Prefix length"), cl::init(3));
49static cl::opt<bool> ShowPositions("display", cl::desc("Display the match positions."), cl::init(false));
50
51static cl::opt<int> Threads("threads", cl::desc("Total number of threads."), cl::init(1));
52
53using namespace kernel;
54using namespace pablo;
55using namespace parabix;
56
57const static std::string PTXFilename = "editd.ptx";
58
59struct matchPosition
60{
61    size_t pos;
62    size_t dist;
63};
64
65std::vector<struct matchPosition> matchList;
66std::vector<std::vector<std::string>> pattGroups;
67
68void run_second_filter(int total_len, int pattern_segs, float errRate){
69
70    if(matchList.empty()) return;
71
72    //remove the duplicates
73    bool cleared = true;
74    while(cleared){
75        cleared = false;
76        for (unsigned i=0; i<matchList.size()-1; i++){
77            if(matchList[i].pos == matchList[i+1].pos && matchList[i].dist == matchList[i+1].dist){
78                matchList.erase(matchList.begin() + i);
79                cleared = true;
80            }
81        }
82    }
83
84    //Sort match position
85    bool exchanged = true;
86    while(exchanged){
87        exchanged = false;
88        for (unsigned i=0; i<matchList.size()-1; i++){
89            if(matchList[i].pos > matchList[i+1].pos){
90                size_t tmp_pos = matchList[i].pos;
91                size_t tmp_dist = matchList[i].dist;
92                matchList[i].pos = matchList[i+1].pos;
93                matchList[i].dist = matchList[i+1].dist;
94                matchList[i+1].pos = tmp_pos;
95                matchList[i+1].dist = tmp_dist;
96                exchanged = true;
97            }
98        }
99    }
100
101    std::cout << "pattern_segs = " << pattern_segs << ", total_len = " << total_len << std::endl;
102
103    int v = pattern_segs * (editDistance+1) - total_len * errRate;
104
105    int startPos = matchList[0].pos;
106    int sum = matchList[0].dist;
107    int curIdx = 0;
108    unsigned i = 0;
109    int count = 0;
110    while (i < matchList.size()){
111        if(matchList[i].pos - startPos < total_len * (errRate+1)){
112            sum += matchList[i].dist;
113            i++;
114        }
115        else{
116            if(sum > v) count++;
117            sum -= matchList[curIdx].dist;
118            curIdx++;
119            startPos = matchList[curIdx].pos;
120        }
121    }
122
123    std::cout << "total candidate from the first filter is " << matchList.size() << std::endl;
124    std::cout << "total candidate from the second filter is " << count << std::endl;
125}
126
127void get_editd_pattern(int & pattern_segs, int & total_len) {
128
129    if (PatternFilename != "") {
130        std::ifstream pattFile(PatternFilename.c_str());
131        std::string r;
132        if (pattFile.is_open()) {
133            while (std::getline(pattFile, r)) {
134                pattVector.push_back(r);
135                pattern_segs ++;
136                total_len += r.size();
137            }
138            std::sort(pattVector.begin(), pattVector.end());
139            unsigned i = 0;
140            while(i < pattVector.size()){
141                std::vector<std::string> pattGroup;
142                std::string prefix = pattVector[i].substr(0, prefixLen);
143                while(i < pattVector.size() && pattVector[i].substr(0, prefixLen) == prefix){
144                    pattGroup.push_back(pattVector[i]);
145                    i++;
146                }
147                pattGroups.push_back(pattGroup);
148            }
149            pattFile.close();
150        }
151        codegen::GroupNum = pattVector.size();
152    }
153
154    // if there are no regexes specified through -e or -f, the first positional argument
155    // must be a regex, not an input file.
156
157    if (pattVector.size() == 0) {
158        pattVector.push_back(inputFiles[0]);
159        inputFiles.erase(inputFiles.begin());
160    }
161}
162
163class PatternKernel final: public pablo::PabloKernel {
164public:
165    PatternKernel(const std::unique_ptr<kernel::KernelBuilder> & b, const std::vector<std::string> & patterns);
166    std::string makeSignature(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override;
167    bool isCachable() const override { return true;}
168protected:
169    void generatePabloMethod() override;
170private:
171    const std::vector<std::string> & mPatterns;
172};
173
174PatternKernel::PatternKernel(const std::unique_ptr<kernel::KernelBuilder> & b, const std::vector<std::string> & patterns)
175: PabloKernel(b, std::string(patterns[0]), {{b->getStreamSetTy(4), "pat"}}, {{b->getStreamSetTy(editDistance + 1), "E"}})
176, mPatterns(patterns) {
177}
178
179std::string PatternKernel::makeSignature(const std::unique_ptr<kernel::KernelBuilder> &) {
180    return getName();
181}
182
183void PatternKernel::generatePabloMethod() {
184    PabloBuilder entry(getEntryBlock());
185    Var * const pat = getInputStreamVar("pat");
186    PabloAST * basisBits[4];
187    basisBits[0] = entry.createExtract(pat, 0, "A");
188    basisBits[1] = entry.createExtract(pat, 1, "C");
189    basisBits[2] = entry.createExtract(pat, 2, "T");
190    basisBits[3] = entry.createExtract(pat, 3, "G");
191    re::Pattern_Compiler pattern_compiler(*this);
192    pattern_compiler.compile(mPatterns, entry, basisBits, editDistance, optPosition, stepSize);
193}
194
195std::mutex store_mutex;
196void wrapped_report_pos(size_t match_pos, int dist) {
197    struct matchPosition curMatch;
198    curMatch.pos = match_pos;
199    curMatch.dist = dist;
200
201    store_mutex.lock();
202    matchList.push_back(curMatch);
203    if(ShowPositions)
204        std::cout << "pos: " << match_pos << ", dist:" << dist << "\n";
205    store_mutex.unlock();
206}
207
208void editdPipeline(ParabixDriver & pxDriver, const std::vector<std::string> & patterns) {
209
210    auto & idb = pxDriver.getBuilder();
211    Module * const m = idb->getModule();
212    Type * const sizeTy = idb->getSizeTy();
213    Type * const voidTy = idb->getVoidTy();
214    Type * const inputType = PointerType::get(ArrayType::get(ArrayType::get(idb->getBitBlockType(), 8), 1), 0);
215
216    idb->LinkFunction("wrapped_report_pos", &wrapped_report_pos);
217
218    const unsigned segmentSize = codegen::SegmentSize;
219    const unsigned bufferSegments = codegen::BufferSegments;
220
221    Function * const main = cast<Function>(m->getOrInsertFunction("Main", voidTy, inputType, sizeTy, nullptr));
222    main->setCallingConv(CallingConv::C);
223    auto args = main->arg_begin();
224    Value * const inputStream = &*(args++);
225    inputStream->setName("input");
226    Value * const fileSize = &*(args++);
227    fileSize->setName("fileSize");
228    idb->SetInsertPoint(BasicBlock::Create(m->getContext(), "entry", main,0));
229
230    auto ChStream = pxDriver.addBuffer(make_unique<SourceBuffer>(idb, idb->getStreamSetTy(4)));
231    auto mmapK = pxDriver.addKernelInstance(make_unique<MemorySourceKernel>(idb, inputType));
232    mmapK->setInitialArguments({inputStream, fileSize});
233    pxDriver.makeKernelCall(mmapK, {}, {ChStream});
234
235    auto MatchResults = pxDriver.addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(editDistance + 1), segmentSize * bufferSegments));
236    auto editdk = pxDriver.addKernelInstance(make_unique<PatternKernel>(idb, patterns));
237    pxDriver.makeKernelCall(editdk, {ChStream}, {MatchResults});
238
239    auto editdScanK = pxDriver.addKernelInstance(make_unique<editdScanKernel>(idb, editDistance));
240    pxDriver.makeKernelCall(editdScanK, {MatchResults}, {});
241
242    pxDriver.generatePipelineIR();
243
244    idb->CreateRetVoid();
245
246    pxDriver.finalizeObject();
247}
248
249class PreprocessKernel final: public pablo::PabloKernel {
250public:
251    PreprocessKernel(const std::unique_ptr<kernel::KernelBuilder> & b);
252    bool isCachable() const override { return true; }
253    bool hasSignature() const override { return false; }
254protected:
255    void generatePabloMethod() override;
256};
257
258PreprocessKernel::PreprocessKernel(const std::unique_ptr<kernel::KernelBuilder> & b)
259: PabloKernel(b, "ccc", {{b->getStreamSetTy(8), "basis"}}, {{b->getStreamSetTy(4), "pat"}}) {
260
261}
262
263void PreprocessKernel::generatePabloMethod() {
264    cc::CC_Compiler ccc(this, getInputStreamVar("basis"));
265    PabloBuilder & pb = ccc.getBuilder();
266    PabloAST * A = ccc.compileCC(re::makeCC(re::makeCC(0x41), re::makeCC(0x61)), pb);
267    PabloAST * C = ccc.compileCC(re::makeCC(re::makeCC(0x43), re::makeCC(0x63)), pb);
268    PabloAST * T = ccc.compileCC(re::makeCC(re::makeCC(0x54), re::makeCC(0x74)), pb);
269    PabloAST * G = ccc.compileCC(re::makeCC(re::makeCC(0x47), re::makeCC(0x67)), pb);
270    Var * const pat = getOutputStreamVar("pat");
271    pb.createAssign(pb.createExtract(pat, 0), A);
272    pb.createAssign(pb.createExtract(pat, 1), C);
273    pb.createAssign(pb.createExtract(pat, 2), T);
274    pb.createAssign(pb.createExtract(pat, 3), G);
275}
276
277void preprocessPipeline(ParabixDriver & pxDriver) {
278
279    auto & iBuilder = pxDriver.getBuilder();
280    Module * m = iBuilder->getModule();
281
282    Type * const voidTy = iBuilder->getVoidTy();
283    Type * const int32Ty = iBuilder->getInt32Ty();
284    Type * const outputType = PointerType::get(ArrayType::get(iBuilder->getBitBlockType(), 4), 0);
285
286    const unsigned segmentSize = codegen::SegmentSize;
287    const unsigned bufferSegments = codegen::BufferSegments;
288
289    Function * const main = cast<Function>(m->getOrInsertFunction("Main", voidTy, int32Ty, outputType, nullptr));
290    main->setCallingConv(CallingConv::C);
291    Function::arg_iterator args = main->arg_begin();
292
293    Value * const fileDescriptor = &*(args++);
294    fileDescriptor->setName("fileDescriptor");
295    Value * const outputStream = &*(args++);
296    outputStream->setName("output");
297
298    iBuilder->SetInsertPoint(BasicBlock::Create(m->getContext(), "entry", main));
299
300    auto ByteStream = pxDriver.addBuffer(make_unique<SourceBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 8)));
301
302    auto mmapK = pxDriver.addKernelInstance(make_unique<MMapSourceKernel>(iBuilder, 1));
303    mmapK->setInitialArguments({fileDescriptor});
304    pxDriver.makeKernelCall(mmapK, {}, {ByteStream});
305
306    auto BasisBits = pxDriver.addBuffer(make_unique<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(8), segmentSize * bufferSegments));
307    auto s2pk = pxDriver.addKernelInstance(make_unique<S2PKernel>(iBuilder));
308    pxDriver.makeKernelCall(s2pk, {ByteStream}, {BasisBits});
309
310    auto CCResults = pxDriver.addExternalBuffer(make_unique<ExternalBuffer>(iBuilder, iBuilder->getStreamSetTy(4), outputStream));
311    auto ccck = pxDriver.addKernelInstance(make_unique<PreprocessKernel>(iBuilder));
312    pxDriver.makeKernelCall(ccck, {BasisBits}, {CCResults});
313
314    pxDriver.generatePipelineIR();
315
316    iBuilder->CreateRetVoid();
317
318    pxDriver.finalizeObject();
319}
320
321
322typedef void (*preprocessFunctionType)(const int fd, char * output_data);
323
324typedef void (*editdFunctionType)(char * byte_data, size_t filesize);
325
326static char * chStream;
327static size_t size;
328
329size_t file_size(const int fd) {
330    struct stat st;
331    if (LLVM_UNLIKELY(fstat(fd, &st) != 0)) {
332        st.st_size = 0;
333    }
334    return st.st_size;
335}
336
337char * preprocess(preprocessFunctionType fn_ptr) {
338    std::string fileName = inputFiles[0];
339    const int fd = open(inputFiles[0].c_str(), O_RDONLY);
340    if (LLVM_UNLIKELY(fd == -1)) {
341        std::cerr << "Error: cannot open " << fileName << " for processing. Skipped.\n";
342        exit(-1);
343    }
344    size = file_size(fd);
345    int ret = posix_memalign((void**)&chStream, 32, size);
346    if (ret) {
347        std::cerr << "Cannot allocate memory for output.\n";
348        exit(-2);
349    }
350    fn_ptr(fd, chStream);
351    close(fd);
352    return chStream;
353}
354
355void editd(editdFunctionType fn_ptr, char * inputStream, size_t size) {
356    fn_ptr(inputStream, size);
357}
358
359std::mutex count_mutex;
360size_t groupCount;
361void * DoEditd(void *)
362{
363    size_t groupIdx;
364    count_mutex.lock();
365    groupIdx = groupCount;
366    groupCount++;
367    count_mutex.unlock();
368
369    while (groupIdx < pattGroups.size()){
370
371        ParabixDriver pxDriver("editd");
372        editdPipeline(pxDriver, pattGroups[groupIdx]);
373        auto editd_ptr = reinterpret_cast<editdFunctionType>(pxDriver.getMain());
374        editd(editd_ptr, chStream, size);
375
376        count_mutex.lock();
377        groupIdx = groupCount;
378        groupCount++;
379        count_mutex.unlock();
380    }
381
382    pthread_exit(NULL);
383}
384
385#define GROUPTHREADS 64
386
387void editdGPUCodeGen(unsigned patternLen){
388    NVPTXDriver pxDriver("editd");
389    auto & iBuilder = pxDriver.getBuilder();
390    Module * M = iBuilder->getModule();
391
392    const unsigned segmentSize = codegen::SegmentSize;
393
394    Type * const mBitBlockType = iBuilder->getBitBlockType();
395    Type * const inputSizeTy = PointerType::get(iBuilder->getSizeTy(), 1);
396    Type * const int32ty = iBuilder->getInt32Ty();
397    Type * const voidTy = Type::getVoidTy(M->getContext());
398    Type * const inputTy = PointerType::get(ArrayType::get(mBitBlockType, 4), 1);
399    Type * const patternPtrTy = PointerType::get(iBuilder->getInt8Ty(), 1);
400    Type * const outputTy = PointerType::get(ArrayType::get(mBitBlockType, editDistance+1), 1);
401    Type * const stridesTy = PointerType::get(int32ty, 1);
402
403    Function * const main = cast<Function>(M->getOrInsertFunction("Main", voidTy, inputTy, inputSizeTy, patternPtrTy, outputTy, stridesTy, nullptr));
404    main->setCallingConv(CallingConv::C);
405    Function::arg_iterator args = main->arg_begin();
406
407    Value * const inputStream = &*(args++);
408    inputStream->setName("input");
409    Value * const inputSizePtr = &*(args++);
410    inputSizePtr->setName("inputSizePtr");
411    Value * const pattStream = &*(args++);
412    pattStream->setName("pattStream");
413    Value * const resultStream = &*(args++);
414    resultStream->setName("resultStream");
415    Value * const stridesPtr = &*(args++);
416    stridesPtr->setName("stridesPtr");
417
418    iBuilder->SetInsertPoint(BasicBlock::Create(M->getContext(), "entry", main,0));
419
420    Function * tidFunc = M->getFunction("llvm.nvvm.read.ptx.sreg.tid.x");
421    Value * tid = iBuilder->CreateCall(tidFunc);
422    Function * bidFunc = cast<Function>(M->getOrInsertFunction("llvm.nvvm.read.ptx.sreg.ctaid.x", int32ty, nullptr));
423    Value * bid = iBuilder->CreateCall(bidFunc);
424
425    Value * inputThreadPtr = iBuilder->CreateGEP(inputStream, tid);
426    Value * strides = iBuilder->CreateLoad(stridesPtr);
427    Value * outputBlocks = iBuilder->CreateMul(strides, ConstantInt::get(int32ty, GROUPTHREADS));
428    Value * resultStreamPtr = iBuilder->CreateGEP(resultStream, iBuilder->CreateAdd(iBuilder->CreateMul(bid, outputBlocks), tid));
429    Value * inputSize = iBuilder->CreateLoad(inputSizePtr);
430
431    StreamSetBuffer * CCStream = pxDriver.addBuffer(make_unique<SourceBuffer>(iBuilder, iBuilder->getStreamSetTy(4), 1));
432    kernel::Kernel * sourceK = pxDriver.addKernelInstance(make_unique<kernel::MemorySourceKernel>(iBuilder, inputTy, segmentSize));
433    sourceK->setInitialArguments({inputThreadPtr, inputSize});
434    pxDriver.makeKernelCall(sourceK, {}, {CCStream});
435
436    ExternalBuffer * ResultStream = pxDriver.addExternalBuffer(make_unique<ExternalBuffer>(iBuilder, iBuilder->getStreamSetTy(editDistance+1), resultStreamPtr, 1));   
437    kernel::Kernel * editdk = pxDriver.addKernelInstance(make_unique<kernel::editdGPUKernel>(iBuilder, editDistance, patternLen));
438     
439    const unsigned numOfCarries = patternLen * (editDistance + 1) * 4;
440    Type * strideCarryTy = ArrayType::get(mBitBlockType, numOfCarries);
441    Value * strideCarry = iBuilder->CreateAlloca(strideCarryTy);
442    iBuilder->CreateStore(Constant::getNullValue(strideCarryTy), strideCarry);
443
444    editdk->setInitialArguments({pattStream, strideCarry});
445    pxDriver.makeKernelCall(editdk, {CCStream}, {ResultStream});
446
447    pxDriver.generatePipelineIR();
448
449    iBuilder->CreateRetVoid();
450
451    pxDriver.finalizeObject();
452
453}
454
455void mergeGPUCodeGen(){
456    NVPTXDriver pxDriver("merge");
457    auto & iBuilder = pxDriver.getBuilder();
458    Module * M = iBuilder->getModule();
459
460    Type * const mBitBlockType = iBuilder->getBitBlockType();
461    Type * const int32ty = iBuilder->getInt32Ty();
462    Type * const voidTy = Type::getVoidTy(M->getContext());
463    Type * const resultTy = PointerType::get(ArrayType::get(mBitBlockType, editDistance+1), 1);
464    Type * const stridesTy = PointerType::get(int32ty, 1);
465
466    Function * const main = cast<Function>(M->getOrInsertFunction("Main", voidTy, resultTy, stridesTy, nullptr));
467    main->setCallingConv(CallingConv::C);
468    Function::arg_iterator args = main->arg_begin();
469
470    Value * const resultStream = &*(args++);
471    resultStream->setName("resultStream");
472    Value * const stridesPtr = &*(args++);
473    stridesPtr->setName("stridesPtr");
474
475    BasicBlock * entryBlock = BasicBlock::Create(iBuilder->getContext(), "entryBlock", main, 0);
476    BasicBlock * strideLoopCond = BasicBlock::Create(iBuilder->getContext(), "strideLoopCond", main, 0);
477    BasicBlock * strideLoopBody = BasicBlock::Create(iBuilder->getContext(), "strideLoopBody", main, 0);
478    BasicBlock * stridesDone = BasicBlock::Create(iBuilder->getContext(), "stridesDone", main, 0);
479
480    iBuilder->SetInsertPoint(entryBlock);
481
482    Function * tidFunc = M->getFunction("llvm.nvvm.read.ptx.sreg.tid.x");
483    Value * tid = iBuilder->CreateCall(tidFunc);
484    Function * bidFunc = cast<Function>(M->getOrInsertFunction("llvm.nvvm.read.ptx.sreg.ctaid.x", int32ty, nullptr));
485    Value * bid = iBuilder->CreateCall(bidFunc);
486
487    Value * strides = iBuilder->CreateLoad(stridesPtr);
488    Value * strideBlocks = ConstantInt::get(int32ty, iBuilder->getStride() / iBuilder->getBitBlockWidth());
489    Value * outputBlocks = iBuilder->CreateMul(strides, strideBlocks);
490    Value * resultStreamPtr = iBuilder->CreateGEP(resultStream, tid);
491
492    iBuilder->CreateBr(strideLoopCond);
493    iBuilder->SetInsertPoint(strideLoopCond);
494    PHINode * strideNo = iBuilder->CreatePHI(int32ty, 2, "strideNo");
495    strideNo->addIncoming(ConstantInt::get(int32ty, 0), entryBlock);
496    Value * notDone = iBuilder->CreateICmpULT(strideNo, strides);
497    iBuilder->CreateCondBr(notDone, strideLoopBody, stridesDone);
498
499    iBuilder->SetInsertPoint(strideLoopBody);
500    Value * myResultStreamPtr = iBuilder->CreateGEP(resultStreamPtr, {iBuilder->CreateMul(strideBlocks, strideNo)});
501    Value * myResultStream = iBuilder->CreateLoad(iBuilder->CreateGEP(myResultStreamPtr, {iBuilder->getInt32(0), bid}));
502    for (int i=1; i<codegen::GroupNum; i++){
503        Value * nextStreamPtr = iBuilder->CreateGEP(myResultStreamPtr, {iBuilder->CreateMul(outputBlocks, iBuilder->getInt32(i)), bid});
504        myResultStream = iBuilder->CreateOr(myResultStream, iBuilder->CreateLoad(nextStreamPtr));
505    }
506    iBuilder->CreateStore(myResultStream, iBuilder->CreateGEP(myResultStreamPtr, {iBuilder->getInt32(0), bid}));
507    strideNo->addIncoming(iBuilder->CreateAdd(strideNo, ConstantInt::get(int32ty, 1)), strideLoopBody);
508    iBuilder->CreateBr(strideLoopCond);
509
510    iBuilder->SetInsertPoint(stridesDone);
511    iBuilder->CreateRetVoid();
512
513    pxDriver.finalizeObject();
514
515}
516
517editdFunctionType editdScanCPUCodeGen(ParabixDriver & pxDriver) {
518   
519    auto & iBuilder = pxDriver.getBuilder();
520    Module * M = iBuilder->getModule();
521
522    const unsigned segmentSize = codegen::SegmentSize;
523
524    Type * mBitBlockType = iBuilder->getBitBlockType();
525    Type * const size_ty = iBuilder->getSizeTy();
526    Type * const voidTy = Type::getVoidTy(M->getContext());
527    Type * const inputType = PointerType::get(ArrayType::get(mBitBlockType, editDistance+1), 0);
528
529    Function * const main = cast<Function>(M->getOrInsertFunction("Main", voidTy, inputType, size_ty, nullptr));
530    main->setCallingConv(CallingConv::C);
531    iBuilder->SetInsertPoint(BasicBlock::Create(M->getContext(), "entry", main, 0));
532    Function::arg_iterator args = main->arg_begin();
533    Value * const inputStream = &*(args++);
534    inputStream->setName("input");
535    Value * const fileSize = &*(args++);
536    fileSize->setName("fileSize");
537
538
539    StreamSetBuffer * MatchResults = pxDriver.addBuffer(make_unique<SourceBuffer>(iBuilder, iBuilder->getStreamSetTy(editDistance+1)));
540    kernel::Kernel * sourceK = pxDriver.addKernelInstance(make_unique<kernel::MemorySourceKernel>(iBuilder, inputType, segmentSize));
541    sourceK->setInitialArguments({inputStream, fileSize});
542    pxDriver.makeKernelCall(sourceK, {}, {MatchResults});
543
544    auto editdScanK = pxDriver.addKernelInstance(make_unique<editdScanKernel>(iBuilder, editDistance));
545    pxDriver.makeKernelCall(editdScanK, {MatchResults}, {});
546       
547    pxDriver.generatePipelineIR();
548    iBuilder->CreateRetVoid();
549
550    pxDriver.LinkFunction(*editdScanK, "wrapped_report_pos", &wrapped_report_pos);
551    pxDriver.finalizeObject();
552
553    return reinterpret_cast<editdFunctionType>(pxDriver.getMain());
554
555}
556
557int main(int argc, char *argv[]) {
558    codegen::ParseCommandLineOptions(argc, argv);
559    int pattern_segs = 0;
560    int total_len = 0;
561
562    get_editd_pattern(pattern_segs, total_len);
563
564#ifdef CUDA_ENABLED
565    codegen::BlockSize = 64;
566#endif
567
568    ParabixDriver pxDriver("preprocess");
569    preprocessPipeline(pxDriver);
570    auto preprocess_ptr = reinterpret_cast<preprocessFunctionType>(pxDriver.getMain());
571    preprocess(preprocess_ptr);
572
573#ifdef CUDA_ENABLED
574    if(codegen::NVPTX){
575
576        std::ifstream t(PatternFilename);
577        if (!t.is_open()) {
578            std::cerr << "Error: cannot open " << PatternFilename << " for processing. Skipped.\n";
579            exit(-1);
580        }
581        std::string patterns((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
582
583        editdGPUCodeGen(patterns.length()/codegen::GroupNum - 1);
584        mergeGPUCodeGen();
585        ulong * rslt = RunPTX(PTXFilename, chStream, size, patterns.c_str(), patterns.length(), editDistance);
586
587        ParabixDriver scanDriver("scan");
588        editdFunctionType editd_ptr = editdScanCPUCodeGen(scanDriver);
589        editd(editd_ptr, (char*)rslt, size);
590
591        run_second_filter(pattern_segs, total_len, 0.15);
592
593        return 0;
594    }
595#endif
596
597    if(pattVector.size() == 1){
598
599        ParabixDriver pxDriver("editd");
600        editdPipeline(pxDriver, pattVector);
601        auto editd_ptr = reinterpret_cast<editdFunctionType>(pxDriver.getMain());
602        editd(editd_ptr, chStream, size);
603    }
604    else{
605        if (Threads == 1) {
606            for(unsigned i=0; i<pattGroups.size(); i++){
607
608                ParabixDriver pxDriver("editd");
609                editdPipeline(pxDriver, pattGroups[i]);
610                auto editd_ptr = reinterpret_cast<editdFunctionType>(pxDriver.getMain());
611                editd(editd_ptr, chStream, size);
612            }
613        }
614        else{
615            const unsigned numOfThreads = Threads;
616            pthread_t threads[numOfThreads];
617            groupCount = 0;
618
619            for(unsigned long i = 0; i < numOfThreads; ++i){
620                const int rc = pthread_create(&threads[i], NULL, DoEditd, (void *)i);
621                if (rc) {
622                    llvm::report_fatal_error("Failed to create thread: code " + std::to_string(rc));
623                }
624            }
625
626            for(unsigned i = 0; i < numOfThreads; ++i) {
627                void * status = nullptr;
628                const int rc = pthread_join(threads[i], &status);
629                if (rc) {
630                    llvm::report_fatal_error("Failed to join thread: code " + std::to_string(rc));
631                }
632            }
633
634        }
635        run_second_filter(pattern_segs, total_len, 0.15);
636    }
637
638    return 0;
639}
Note: See TracBrowser for help on using the repository browser.