Ignore:
Timestamp:
Mar 15, 2016, 10:20:07 PM (3 years ago)
Author:
nmedfort
Message:

Added the kernel instance class; removed original mmap file access in favour of the boost mmap system. corrected PrintRegister? routine.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/symboltablepipeline.cpp

    r4968 r4974  
    1010#include "utf_encoding.h"
    1111
    12 #include <kernels/scanmatchgen.h>
    1312#include <kernels/s2p_kernel.h>
     13#include <kernels/instance.h>
    1414
    1515#include <pablo/function.h>
     
    3030using namespace pablo;
    3131
     32namespace kernel {
     33
    3234SymbolTableBuilder::SymbolTableBuilder(Module * m, IDISA::IDISA_Builder * b)
    3335: mMod(m)
    3436, iBuilder(b)
    35 , mFileBufIdx(7)
    36 , mFileSizeIdx(8)
    37 , mFileNameIdx(9)
    3837, mLongestLookahead(0)
    3938, mBitBlockType(b->getBitBlockType())
    40 , mBlockSize(b->getBitBlockWidth()){
     39, mBlockSize(b->getBitBlockWidth()) {
    4140
    4241}
     
    9897    for (unsigned endpoint : endpoints) {
    9998        PabloAST * const M = function->getParameter(i + 1);
    100         PabloAST * const L = entry->createLookahead(M, endpoint);
     99        PabloAST * const L = entry->createLookahead(M, endpoint, "lookahead" + std::to_string(endpoint));
    101100        PabloAST * S = entry->createAnd(L, R);
    102101        Assign * Si = entry->createAssign("S_" + std::to_string(i), S);
     
    131130
    132131    PabloCompiler pablo_compiler(mMod, iBuilder);
    133 
    134     raw_os_ostream out(std::cerr);
    135 
    136     out << "LEADING:\n";
    137132    PabloFunction * const leading = generateLeadingFunction(endpoints);
    138     PabloPrinter::print(*leading, out);
    139 
    140     out << "\n\nSORTING:\n";
    141133    PabloFunction * const sorting = generateSortingFunction(leading, endpoints);
    142     PabloPrinter::print(*sorting, out);
    143 
    144     out.flush();
    145134
    146135    mS2PKernel = new KernelBuilder("s2p", mMod, iBuilder);
     
    164153}
    165154
    166 void SymbolTableBuilder::ExecuteKernels(){
    167 
    168     Type * T = iBuilder->getIntNTy(64);
    169     Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
     155Function * SymbolTableBuilder::ExecuteKernels(){
     156
     157    Type * intType = iBuilder->getInt64Ty();
     158
    170159    Type * inputType = PointerType::get(ArrayType::get(StructType::get(mMod->getContext(), std::vector<Type *>({ArrayType::get(mBitBlockType, 8)})), 1), 0);
    171     Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, T, nullptr));
     160    Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, intType, nullptr));
    172161    main->setCallingConv(CallingConv::C);
    173162    Function::arg_iterator args = main->arg_begin();
    174163
    175     Value * const input_param = args++;
    176     input_param->setName("input");
     164    Value * const inputStream = args++;
     165    inputStream->setName("input");
    177166
    178167    Value * const bufferSize = args++;
     
    183172    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
    184173
    185     BasicBlock * leadingTestBlock = BasicBlock::Create(mMod->getContext(), "ltb", main, 0);
    186     BasicBlock * leadingBodyBlock = BasicBlock::Create(mMod->getContext(), "lbb", main, 0);
    187     BasicBlock * leadingExitBlock = BasicBlock::Create(mMod->getContext(), "leb", main, 0);
    188 
    189     BasicBlock * regularTestBlock = BasicBlock::Create(mMod->getContext(), "rtb", main, 0);
    190     BasicBlock * regularBodyBlock = BasicBlock::Create(mMod->getContext(), "rbb", main, 0);
    191     BasicBlock * regularExitBlock = BasicBlock::Create(mMod->getContext(), "reb", main, 0);
    192 
    193 //    BasicBlock * pipeline_test_block = BasicBlock::Create(mMod->getContext(), "pipeline_test_block", main, 0);
    194 //    BasicBlock * pipeline_do_block = BasicBlock::Create(mMod->getContext(), "pipeline_do_block", main, 0);
    195 //    BasicBlock * pipeline_final_block = BasicBlock::Create(mMod->getContext(), "pipeline_final_block", main, 0);
    196 //    BasicBlock * pipeline_partial_block = BasicBlock::Create(mMod->getContext(), "pipeline_partial_block", main, 0);
    197 //    BasicBlock * pipeline_empty_block = BasicBlock::Create(mMod->getContext(), "pipeline_empty_block", main, 0);
    198 //    BasicBlock * pipeline_end_block = BasicBlock::Create(mMod->getContext(), "pipeline_end_block", main, 0);
    199 //    BasicBlock * pipeline_Unterminated_block = BasicBlock::Create(mMod->getContext(), "pipeline_Unterminated_block", main, 0);
    200 //    BasicBlock * pipeline_return_block = BasicBlock::Create(mMod->getContext(), "pipeline_return_block", main, 0);
    201 
    202     Value * s2pKernelStruct = mS2PKernel->generateKernelInstance();
    203     Value * leadingKernelStruct = mLeadingKernel->generateKernelInstance();
    204     Value * sortingKernelStruct = mSortingKernel->generateKernelInstance();
    205 
    206     Value * basis_bits = iBuilder->CreateGEP(s2pKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    207     Value * leadingData = iBuilder->CreateGEP(leadingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    208 
     174    BasicBlock * leadingTestBlock = BasicBlock::Create(mMod->getContext(), "leadingCond", main, 0);
     175    BasicBlock * leadingBodyBlock = BasicBlock::Create(mMod->getContext(), "leadingBody", main, 0);
     176
     177    BasicBlock * regularTestBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
     178    BasicBlock * regularBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
     179    BasicBlock * regularExitBlock = BasicBlock::Create(mMod->getContext(), "fullExit", main, 0);
     180
     181    BasicBlock * partialBlock = BasicBlock::Create(mMod->getContext(),  "partialBlock", main, 0);
     182
     183    BasicBlock * finalTestBlock = BasicBlock::Create(mMod->getContext(),  "finalCond", main, 0);
     184    BasicBlock * finalBodyBlock = BasicBlock::Create(mMod->getContext(),  "finalBody", main, 0);
     185
     186    BasicBlock * exitBlock = BasicBlock::Create(mMod->getContext(), "exit", main, 0);
     187
     188    Instance * s2pInstance = mS2PKernel->instantiate();
     189    Instance * leadingInstance = mLeadingKernel->instantiate();
     190    Instance * sortingInstance = mSortingKernel->instantiate();
     191
     192    Value * basisBits = s2pInstance->getOutputStreamSet();
     193    Value * leadingData = leadingInstance->getOutputStreamSet();
    209194
    210195    const unsigned leadingBlocks = (mLongestLookahead + iBuilder->getBitBlockWidth() - 1) / iBuilder->getBitBlockWidth();
    211196
     197    Value * const requiredBytes = iBuilder->getInt64(mBlockSize * leadingBlocks);
     198    Value * const blockSize = iBuilder->getInt64(mBlockSize);
     199
    212200    // If the buffer size is smaller than our largest length group, only check up to the buffer size.
    213     Value * safetyCheck = iBuilder->CreateICmpSLT(bufferSize, iBuilder->getInt64(leadingBlocks * iBuilder->getBitBlockWidth()));
    214     iBuilder->CreateCondBr(safetyCheck, regularExitBlock, leadingTestBlock);
    215 
    216     // Now process the leading blocks ...
     201    Value * safetyCheck = iBuilder->CreateICmpUGE(bufferSize, blockSize);
     202    if (blockSize == requiredBytes) {
     203        iBuilder->CreateCondBr(safetyCheck, leadingTestBlock, exitBlock); // fix this to be a special case
     204    } else {
     205        throw std::runtime_error("Not supported yet!");
     206    }
     207
     208    // First compute any necessary leading blocks to allow the sorting kernel access to the "future" data produced by
     209    // the leading kernel ...
    217210    iBuilder->SetInsertPoint(leadingTestBlock);
    218     PHINode * remainingBytes = iBuilder->CreatePHI(T, 2, "remainingBytes");
    219     PHINode * leadingOffset = iBuilder->CreatePHI(T, 2, "blockIndex");
     211    PHINode * blockNo = iBuilder->CreatePHI(intType, 2);
     212    blockNo->addIncoming(iBuilder->getInt64(0), entryBlock);
     213    PHINode * remainingBytes = iBuilder->CreatePHI(intType, 2);
    220214    remainingBytes->addIncoming(bufferSize, entryBlock);
    221     leadingOffset->addIncoming(iBuilder->getInt64(0), entryBlock);
    222     Value * remainingLeadingBlocksCond = iBuilder->CreateICmpULT(leadingOffset, iBuilder->getInt64(leadingBlocks));
    223     iBuilder->CreateCondBr(remainingLeadingBlocksCond, leadingBodyBlock, leadingExitBlock);
     215    Value * leadingBlocksCond = iBuilder->CreateICmpULT(blockNo, iBuilder->getInt64(leadingBlocks));
     216    iBuilder->CreateCondBr(leadingBlocksCond, leadingBodyBlock, regularTestBlock);
    224217    iBuilder->SetInsertPoint(leadingBodyBlock);
    225     Value * gep = iBuilder->CreateGEP(input_param, leadingOffset);
    226     mS2PKernel->generateDoBlockCall(gep);
    227     mLeadingKernel->generateDoBlockCall(basis_bits);
    228     leadingOffset->addIncoming(iBuilder->CreateAdd(leadingOffset, iBuilder->getInt64(1)), leadingBodyBlock);
    229     remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, iBuilder->getInt64(mBlockSize)), leadingBodyBlock);
     218    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
     219    leadingInstance->call(basisBits);
     220    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), leadingBodyBlock);
     221    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, blockSize), leadingBodyBlock);
    230222    iBuilder->CreateBr(leadingTestBlock);
    231     iBuilder->SetInsertPoint(leadingExitBlock);
    232 
    233     // Now process the leading blocks ...
    234     iBuilder->CreateBr(regularTestBlock);
     223
     224    // Now all the data for which we can produce and consume a full leading block...
    235225    iBuilder->SetInsertPoint(regularTestBlock);
    236     PHINode * remainingBytes2 = iBuilder->CreatePHI(T, 2, "remainingBytes");
    237     PHINode * leadingOffset2 = iBuilder->CreatePHI(T, 2, "blockIndex");
    238     remainingBytes2->addIncoming(remainingBytes, leadingExitBlock);
    239     leadingOffset2->addIncoming(leadingOffset, leadingExitBlock);
    240     Value * remainingBytesCond = iBuilder->CreateICmpUGE(remainingBytes2, iBuilder->getInt64(mBlockSize));
     226    PHINode * blockNo2 = iBuilder->CreatePHI(intType, 2);
     227    blockNo2->addIncoming(blockNo, leadingTestBlock);
     228    PHINode * remainingBytes2 = iBuilder->CreatePHI(intType, 2);
     229    remainingBytes2->addIncoming(remainingBytes, leadingTestBlock);
     230    Value * remainingBytesCond = iBuilder->CreateICmpUGE(remainingBytes2, requiredBytes);
    241231    iBuilder->CreateCondBr(remainingBytesCond, regularBodyBlock, regularExitBlock);
    242232    iBuilder->SetInsertPoint(regularBodyBlock);
    243     Value * gep2 = iBuilder->CreateGEP(input_param, leadingOffset2);
    244     mS2PKernel->generateDoBlockCall(gep2);
    245     mLeadingKernel->generateDoBlockCall(basis_bits);
    246     leadingOffset2->addIncoming(iBuilder->CreateAdd(leadingOffset2, iBuilder->getInt64(1)), regularBodyBlock);
    247     remainingBytes2->addIncoming(iBuilder->CreateSub(remainingBytes2, iBuilder->getInt64(mBlockSize)), regularBodyBlock);
    248     mSortingKernel->generateDoBlockCall(leadingData);
     233    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo2));
     234    leadingInstance->call(basisBits);
     235    sortingInstance->call(leadingData);
     236    blockNo2->addIncoming(iBuilder->CreateAdd(blockNo2, iBuilder->getInt64(1)), regularBodyBlock);
     237    remainingBytes2->addIncoming(iBuilder->CreateSub(remainingBytes2, blockSize), regularBodyBlock);
    249238    iBuilder->CreateBr(regularTestBlock);
     239
     240
     241    // Check if we have a partial blocks worth of leading data remaining
    250242    iBuilder->SetInsertPoint(regularExitBlock);
    251 
    252 
    253 
    254 //    Value * gep = iBuilder->CreateGEP(sortingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(mFileBufIdx)});
    255 //    Value* filebuf = iBuilder->CreateBitCast(input_param, S);
    256 //    iBuilder->CreateStore(filebuf, gep);
    257 
    258 //    gep = iBuilder->CreateGEP(sortingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(mFileSizeIdx)});
    259 //    iBuilder->CreateStore(buffersize_param, gep);
    260 
    261 //    gep = iBuilder->CreateGEP(sortingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(mFileNameIdx)});
    262 //    iBuilder->CreateStore(filename_param, gep);
    263 
    264 //    Value * basis_bits = iBuilder->CreateGEP(s2pKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    265 //    Value * results = iBuilder->CreateGEP(leadingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    266 
    267 //    iBuilder->CreateBr(pipeline_test_block);
    268 
    269 //    iBuilder->SetInsertPoint(pipeline_test_block);
    270 //    PHINode * remaining_phi = iBuilder->CreatePHI(T, 2, "remaining");
    271 //    PHINode * blkNo_phi = iBuilder->CreatePHI(T, 2, "blkNo");
    272 //    remaining_phi->addIncoming(buffersize_param, entry_block);
    273 //    blkNo_phi->addIncoming(iBuilder->getInt64(0), entry_block);
    274 
    275 //    Value * final_block_cond = iBuilder->CreateICmpSLT(remaining_phi, ConstantInt::get(T, mBlockSize));
    276 //    iBuilder->CreateCondBr(final_block_cond, pipeline_final_block, pipeline_do_block);
    277 
    278 //    iBuilder->SetInsertPoint(pipeline_do_block);
    279 
    280 //    gep = iBuilder->CreateGEP(input_param, {blkNo_phi});
    281 //    Value * update_blkNo = iBuilder->CreateAdd(blkNo_phi, iBuilder->getInt64(1));
    282 //    blkNo_phi->addIncoming(update_blkNo, pipeline_do_block);
    283 
    284 //    mS2PKernel->generateDoBlockCall(gep);
    285 //    mICgrepKernel->generateDoBlockCall(basis_bits);
    286 //    mScanMatchKernel->generateDoBlockCall(results);
    287 
    288 //    Value * update_remaining = iBuilder->CreateSub(remaining_phi, iBuilder->getInt64(mBlockSize));
    289 //    remaining_phi->addIncoming(update_remaining, pipeline_do_block);
    290 //    iBuilder->CreateBr(pipeline_test_block);
    291 
    292 //    iBuilder->SetInsertPoint(pipeline_final_block);
    293 
    294 //    Value * empty_block_cond = iBuilder->CreateICmpEQ(remaining_phi, ConstantInt::get(T, 0));
    295 //    iBuilder->CreateCondBr(empty_block_cond, pipeline_empty_block, pipeline_partial_block);
    296 
    297 //    iBuilder->SetInsertPoint(pipeline_partial_block);
    298 
    299 //    gep = iBuilder->CreateGEP(input_param, {blkNo_phi});
    300 //    mS2PKernel->generateDoBlockCall(gep);
    301 //    iBuilder->CreateBr(pipeline_end_block);
    302 
    303 //    iBuilder->SetInsertPoint(pipeline_empty_block);
    304 
    305 //    iBuilder->CreateMemSet(basis_bits, iBuilder->getInt8(0), mBlockSize, 4);
    306 //    iBuilder->CreateBr(pipeline_end_block);
    307 
    308 //    iBuilder->SetInsertPoint(pipeline_end_block);
    309 
    310 //    Value * return_block_cond = iBuilder->CreateICmpEQ(finalLineUnterminated_param, ConstantInt::get(T, 0));
    311 //    iBuilder->CreateCondBr(return_block_cond, pipeline_return_block, pipeline_Unterminated_block);
    312 
    313 //    iBuilder->SetInsertPoint(pipeline_Unterminated_block);
    314 
    315 //    Value * remaining = iBuilder->CreateZExt(remaining_phi, iBuilder->getIntNTy(mBlockSize));
    316 //    Value * EOF_pos = iBuilder->CreateShl(ConstantInt::get(iBuilder->getIntNTy(mBlockSize), 1), remaining);
    317 //    EOF_pos = iBuilder->CreateBitCast(EOF_pos, mBitBlockType);
    318 
    319 //    Value * gep_bits4 = iBuilder->CreateGEP(basis_bits, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(4)});
    320 //    Value * bits4 = iBuilder->CreateAlignedLoad(gep_bits4, mBlockSize/8, false, "bits4");
    321 //    bits4 = iBuilder->CreateOr(bits4, EOF_pos);
    322 //    iBuilder->CreateAlignedStore(bits4, gep_bits4, mBlockSize/8, false);
    323 
    324 //    Value * gep_bits6 = iBuilder->CreateGEP(basis_bits, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(6)});
    325 //    Value * bits6 = iBuilder->CreateAlignedLoad(gep_bits6, mBlockSize/8, false, "bits6");
    326 //    bits6 = iBuilder->CreateOr(bits6, EOF_pos);
    327 //    iBuilder->CreateAlignedStore(bits6, gep_bits6, mBlockSize/8, false);
    328 //    iBuilder->CreateBr(pipeline_return_block);
    329 
    330 //    iBuilder->SetInsertPoint(pipeline_return_block);
    331 
    332 //    mICgrepKernel->generateDoBlockCall(basis_bits);
    333 //    mScanMatchKernel->generateDoBlockCall(results);
     243    Value * partialBlockCond = iBuilder->CreateICmpUGT(remainingBytes2, ConstantInt::getNullValue(intType));
     244    iBuilder->CreateCondBr(partialBlockCond, partialBlock, finalTestBlock);
     245
     246    // If we do, process it and mask out the data
     247    iBuilder->SetInsertPoint(partialBlock);
     248    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo2));
     249    Value * partialLeadingData[2];
     250    for (unsigned i = 0; i < 2; ++i) {
     251        partialLeadingData[i] = leadingInstance->getOutputStream(i);
     252    }
     253    leadingInstance->call(basisBits);
     254    Type * fullBitBlockType = iBuilder->getIntNTy(mBlockSize);
     255    Value * remaining = iBuilder->CreateZExt(iBuilder->CreateSub(blockSize, remainingBytes2), fullBitBlockType);
     256    Value * eofMask = iBuilder->CreateLShr(ConstantInt::getAllOnesValue(fullBitBlockType), remaining);
     257    eofMask = iBuilder->CreateBitCast(eofMask, mBitBlockType);
     258    for (unsigned i = 0; i < 2; ++i) {
     259        Value * value = iBuilder->CreateAnd(iBuilder->CreateBlockAlignedLoad(partialLeadingData[i]), eofMask);
     260        iBuilder->CreateBlockAlignedStore(value, partialLeadingData[i]);
     261    }
     262    for (unsigned i = 0; i < 2; ++i) {
     263        iBuilder->CreateBlockAlignedStore(ConstantInt::getNullValue(mBitBlockType), leadingInstance->getOutputStream(i));
     264    }
     265    sortingInstance->call(leadingData);
     266    iBuilder->CreateBr(finalTestBlock);
     267
     268    // Now clear the leading data and test the final blocks
     269    iBuilder->SetInsertPoint(finalTestBlock);
     270    PHINode * remainingFullBlocks = iBuilder->CreatePHI(iBuilder->getInt64Ty(), 3);
     271    remainingFullBlocks->addIncoming(iBuilder->getInt64(leadingBlocks), regularExitBlock);
     272    remainingFullBlocks->addIncoming(iBuilder->getInt64(leadingBlocks), partialBlock);
     273    Value * remainingFullBlocksCond = iBuilder->CreateICmpUGT(remainingFullBlocks, ConstantInt::getNullValue(intType));
     274    iBuilder->CreateCondBr(remainingFullBlocksCond, finalBodyBlock, exitBlock);
     275
     276    iBuilder->SetInsertPoint(finalBodyBlock);
     277    for (unsigned i = 0; i < 2; ++i) {
     278        iBuilder->CreateBlockAlignedStore(ConstantInt::getNullValue(mBitBlockType), leadingInstance->getOutputStream(i));
     279    }
     280    Value * blockNoPtr = leadingInstance->getBlockNo();
     281    Value * blockNoValue = iBuilder->CreateLoad(blockNoPtr);
     282    blockNoValue = iBuilder->CreateAdd(blockNoValue, ConstantInt::get(blockNoValue->getType(), 1));
     283    iBuilder->CreateStore(blockNoValue, blockNoPtr);
     284
     285    sortingInstance->call(leadingData);
     286
     287    remainingFullBlocks->addIncoming(iBuilder->CreateSub(remainingFullBlocks, iBuilder->getInt64(1)), finalBodyBlock);
     288
     289    iBuilder->CreateBr(finalTestBlock);
     290
     291    iBuilder->SetInsertPoint(exitBlock);
    334292    iBuilder->CreateRetVoid();
    335293
    336 
    337     mMod->dump();
     294    main->dump();
     295
     296    return main;
    338297}
    339298
     
    343302    delete mSortingKernel;
    344303}
     304
     305}
Note: See TracChangeset for help on using the changeset viewer.