Ignore:
Timestamp:
Jun 19, 2016, 3:00:47 PM (3 years ago)
Author:
cameron
Message:

New kernel infrastructure

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/wc.cpp

    r5042 r5063  
    2626#include <cc/cc_compiler.h>
    2727#include <pablo/function.h>
     28#include <pablo/pablo_kernel.h>
    2829#include <IDISA/idisa_builder.h>
    2930#include <IDISA/idisa_target.h>
    30 #include <kernels/instance.h>
     31#include <kernels/interface.h>
    3132#include <kernels/kernel.h>
    3233#include <kernels/s2p_kernel.h>
     
    101102pablo::PabloFunction * wc_gen(Encoding encoding) {
    102103    //  input: 8 basis bit streams
    103     //  output: 3 count streams
    104    
    105     pablo::PabloFunction * function = pablo::PabloFunction::Create("wc", 8, 3);
     104    //  output: 3 counters
     105   
     106    pablo::PabloFunction * function = pablo::PabloFunction::Create("wc", 8, 0);
    106107    cc::CC_Compiler ccc(*function, encoding);
    107108   
     
    111112    if (CountLines) {
    112113        pablo::PabloAST * LF = ccc.compileCC(re::makeCC(0x0A));
    113         function->setResult(0, pBuilder.createAssign("lineCount", pBuilder.createCount(LF)));
    114     }
    115     else function->setResult(0, pBuilder.createAssign("lineCount", pBuilder.createZeroes()));
     114        function->setResultCount(pBuilder.createCount("lineCount", LF));
     115    }
    116116    if (CountWords) {
    117117        pablo::PabloAST * WS = ccc.compileCC(re::makeCC(re::makeCC(0x09, 0x0D), re::makeCC(0x20)));
     
    122122        //
    123123        pablo::PabloAST * wordStart = pBuilder.createInFile(pBuilder.createAnd(wordChar, WS_follow_or_start));
    124         function->setResult(1, pBuilder.createAssign("wordCount", pBuilder.createCount(wordStart)));
    125     }
    126     else function->setResult(1, pBuilder.createAssign("wordCount", pBuilder.createZeroes()));
     124        function->setResultCount(pBuilder.createCount("wordCount", wordStart));
     125    }
    127126    if (CountChars) {
    128127        //
     
    131130        //
    132131        pablo::PabloAST * u8Begin = ccc.compileCC(re::makeCC(re::makeCC(0, 0x7F), re::makeCC(0xC2, 0xF4)));
    133         function->setResult(2, pBuilder.createAssign("charCount", pBuilder.createCount(u8Begin)));
    134     }
    135     else function->setResult(2, pBuilder.createAssign("charCount", pBuilder.createZeroes()));
     132        function->setResultCount(pBuilder.createCount("charCount", u8Begin));
     133    }
    136134    return function;
    137135}
     
    146144    ~wcPipelineBuilder();
    147145   
    148     void CreateKernels(pablo::PabloFunction * function);
    149     llvm::Function * ExecuteKernels();
     146    llvm::Function * ExecuteKernels(pablo::PabloFunction * function);
    150147   
    151148private:
    152149    llvm::Module *                      mMod;
    153150    IDISA::IDISA_Builder *              iBuilder;
    154     KernelBuilder *                     mS2PKernel;
    155     KernelBuilder *                     mWC_Kernel;
    156151    llvm::Type *                        mBitBlockType;
    157152    int                                 mBlockSize;
     
    171166
    172167wcPipelineBuilder::~wcPipelineBuilder(){
    173     delete mS2PKernel;
    174     delete mWC_Kernel;
    175 }
    176 
    177 void wcPipelineBuilder::CreateKernels(PabloFunction * function){
    178     mS2PKernel = new KernelBuilder(iBuilder, "s2p", codegen::SegmentSize);
    179     mWC_Kernel = new KernelBuilder(iBuilder, "wc", codegen::SegmentSize);
    180    
    181     generateS2PKernel(mMod, iBuilder, mS2PKernel);
     168}
     169
     170
     171Function * wcPipelineBuilder::ExecuteKernels(PabloFunction * function) {
     172    s2pKernel  s2pk(iBuilder);
     173    s2pk.generateKernel();
    182174   
    183175    pablo_function_passes(function);
    184    
    185     PabloCompiler pablo_compiler(mMod, iBuilder);
    186     try {
    187         pablo_compiler.setKernel(mWC_Kernel);
    188         pablo_compiler.compile(function);
    189         delete function;
    190         releaseSlabAllocatorMemory();
    191     } catch (std::runtime_error e) {
    192         delete function;
    193         releaseSlabAllocatorMemory();
    194         std::cerr << "Runtime error: " << e.what() << std::endl;
    195         exit(1);
    196     }
    197    
    198 }
    199 
    200 
    201 
    202 
    203 Function * wcPipelineBuilder::ExecuteKernels() {
     176    PabloKernel  wck(iBuilder, "wc", function, {"lineCount", "wordCount", "charCount"});
     177    wck.prepareKernel();
     178    wck.generateKernel();
     179
    204180    Constant * record_counts_routine;
    205181    Type * const int64ty = iBuilder->getInt64Ty();
     
    223199    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
    224200
    225     BasicBlock * segmentCondBlock = nullptr;
    226     BasicBlock * segmentBodyBlock = nullptr;
    227     const unsigned segmentSize = codegen::SegmentSize;
    228     if (segmentSize > 1) {
    229         segmentCondBlock = BasicBlock::Create(mMod->getContext(), "segmentCond", main, 0);
    230         segmentBodyBlock = BasicBlock::Create(mMod->getContext(), "segmentBody", main, 0);
    231     }
    232201    BasicBlock * fullCondBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
    233202    BasicBlock * fullBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
    234203    BasicBlock * finalBlock = BasicBlock::Create(mMod->getContext(), "final", main, 0);
    235     BasicBlock * finalPartialBlock = BasicBlock::Create(mMod->getContext(), "partial", main, 0);
    236     BasicBlock * finalEmptyBlock = BasicBlock::Create(mMod->getContext(), "empty", main, 0);
    237     BasicBlock * endBlock = BasicBlock::Create(mMod->getContext(), "end", main, 0);
    238 
    239     Instance * s2pInstance = mS2PKernel->instantiate(inputStream);
    240     Instance * wcInstance = mWC_Kernel->instantiate(s2pInstance->getOutputStreamBuffer());
    241 
    242     Value * initialBufferSize = nullptr;
    243     BasicBlock * initialBlock = nullptr;
    244    
    245     if (segmentSize > 1) {
    246         iBuilder->CreateBr(segmentCondBlock);
    247         iBuilder->SetInsertPoint(segmentCondBlock);
    248         PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
    249         remainingBytes->addIncoming(bufferSize, entryBlock);
    250         Constant * const step = ConstantInt::get(int64ty, mBlockSize * segmentSize);
    251         Value * segmentCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
    252         iBuilder->CreateCondBr(segmentCondTest, fullCondBlock, segmentBodyBlock);
    253         iBuilder->SetInsertPoint(segmentBodyBlock);
    254         for (unsigned i = 0; i < segmentSize; ++i) {
    255             s2pInstance->CreateDoBlockCall();
    256         }
    257         for (unsigned i = 0; i < segmentSize; ++i) {
    258             wcInstance->CreateDoBlockCall();
    259         }
    260         remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), segmentBodyBlock);
    261         iBuilder->CreateBr(segmentCondBlock);
    262         initialBufferSize = remainingBytes;
    263         initialBlock = segmentCondBlock;
    264     } else {
    265         initialBufferSize = bufferSize;
    266         initialBlock = entryBlock;
    267         iBuilder->CreateBr(fullCondBlock);
    268     }
    269 
     204
     205    StreamSetBuffer ByteStream(iBuilder, StreamSetType(1, 8), 0);
     206    StreamSetBuffer BasisBits(iBuilder, StreamSetType(8, 1), 1);
     207    ByteStream.setStreamSetBuffer(inputStream);
     208    Value * basisBits = BasisBits.allocateBuffer();
     209
     210    Value * s2pInstance = s2pk.createInstance({});
     211    Value * wcInstance = wck.createInstance({});
     212   
     213    Value * initialBufferSize = bufferSize;
     214    BasicBlock * initialBlock = entryBlock;
     215    Value * initialBlockNo = iBuilder->getInt64(0);
     216
     217    iBuilder->CreateBr(fullCondBlock);
     218
     219   
    270220    iBuilder->SetInsertPoint(fullCondBlock);
    271221    PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
    272222    remainingBytes->addIncoming(initialBufferSize, initialBlock);
     223    PHINode * blockNo = iBuilder->CreatePHI(int64ty, 2, "blockNo");
     224    blockNo->addIncoming(initialBlockNo, initialBlock);
    273225
    274226    Constant * const step = ConstantInt::get(int64ty, mBlockSize);
     
    278230    iBuilder->SetInsertPoint(fullBodyBlock);
    279231
    280     s2pInstance->CreateDoBlockCall();
    281     wcInstance->CreateDoBlockCall();
     232    s2pk.createDoBlockCall(s2pInstance, {ByteStream.getBlockPointer(blockNo), basisBits});
     233    wck.createDoBlockCall(wcInstance, {basisBits});
    282234
    283235    Value * diff = iBuilder->CreateSub(remainingBytes, step);
    284236
    285237    remainingBytes->addIncoming(diff, fullBodyBlock);
     238    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), fullBodyBlock);
    286239    iBuilder->CreateBr(fullCondBlock);
    287240   
    288241    iBuilder->SetInsertPoint(finalBlock);
    289     Value * EOFmark = iBuilder->CreateShl(ConstantInt::get(iBuilder->getIntNTy(mBlockSize), 1), remainingBytes);
    290         wcInstance->setInternalState("EOFmark", iBuilder->CreateBitCast(EOFmark, mBitBlockType));
    291    
    292     Value * emptyBlockCond = iBuilder->CreateICmpEQ(remainingBytes, ConstantInt::get(int64ty, 0));
    293     iBuilder->CreateCondBr(emptyBlockCond, finalEmptyBlock, finalPartialBlock);
    294    
    295    
    296     iBuilder->SetInsertPoint(finalPartialBlock);
    297     s2pInstance->CreateDoBlockCall();
    298 
    299     iBuilder->CreateBr(endBlock);
    300    
    301     iBuilder->SetInsertPoint(finalEmptyBlock);
    302     s2pInstance->clearOutputStreamSet();
    303     iBuilder->CreateBr(endBlock);
    304    
    305     iBuilder->SetInsertPoint(endBlock);
    306 
    307     wcInstance->CreateDoBlockCall();
    308    
    309     Value * lineCount = iBuilder->CreateExtractElement(iBuilder->CreateBlockAlignedLoad(wcInstance->getOutputStream((int) 0)), iBuilder->getInt32(0));
    310     Value * wordCount = iBuilder->CreateExtractElement(iBuilder->CreateBlockAlignedLoad(wcInstance->getOutputStream(1)), iBuilder->getInt32(0));
    311     Value * charCount = iBuilder->CreateExtractElement(iBuilder->CreateBlockAlignedLoad(wcInstance->getOutputStream(2)), iBuilder->getInt32(0));
    312    
     242    s2pk.createFinalBlockCall(s2pInstance, remainingBytes, {ByteStream.getBlockPointer(blockNo), basisBits});
     243    wck.createFinalBlockCall(wcInstance, remainingBytes, {basisBits});
     244   
     245    Value * lineCount = wck.createGetAccumulatorCall(wcInstance, "lineCount");
     246    Value * wordCount = wck.createGetAccumulatorCall(wcInstance, "wordCount");
     247    Value * charCount = wck.createGetAccumulatorCall(wcInstance, "charCount");;
     248
    313249    iBuilder->CreateCall(record_counts_routine, std::vector<Value *>({lineCount, wordCount, charCount, bufferSize, fileIdx}));
    314250   
    315251    iBuilder->CreateRetVoid();
    316    
    317252    return main;
    318253}
     
    331266    Encoding encoding(Encoding::Type::UTF_8, 8);
    332267    pablo::PabloFunction * function = wc_gen(encoding);
    333     pipelineBuilder.CreateKernels(function);
    334     llvm::Function * main_IR = pipelineBuilder.ExecuteKernels();
     268    llvm::Function * main_IR = pipelineBuilder.ExecuteKernels(function);
    335269
    336270    wcEngine = JIT_to_ExecutionEngine(M);
Note: See TracChangeset for help on using the changeset viewer.