Changeset 5257


Ignore:
Timestamp:
Jan 12, 2017, 7:03:38 PM (8 months ago)
Author:
cameron
Message:

finalSegment kernel methods initial check-in

Location:
icGREP/icgrep-devel/icgrep
Files:
8 edited

Legend:

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

    r5255 r5257  
    222222Function * editdPipeline(Module * mMod, IDISA::IDISA_Builder * iBuilder, const std::vector<std::string> & patterns) {
    223223   
    224     ExternalFileBuffer ChStream(iBuilder, iBuilder->getStreamSetTy(4));
    225     SingleBlockBuffer MatchResults(iBuilder, iBuilder->getStreamSetTy(editDistance + 1));
    226 
    227     PabloKernel editdk(iBuilder, "editd");
    228 
    229     buildPatternKernel(editdk, iBuilder, patterns);
    230 
    231     kernel::editdScanKernel editdScanK(iBuilder, editDistance);
    232    
    233     std::unique_ptr<Module> editdM = editdk.createKernelModule({&ChStream}, {&MatchResults});
    234     std::unique_ptr<Module> scanM = editdScanK.createKernelModule({&MatchResults}, {});               
    235    
    236     editdk.addKernelDeclarations(mMod);
    237     editdScanK.addKernelDeclarations(mMod);
    238 
    239224    Type * const size_ty = iBuilder->getSizeTy();
    240225    Type * const voidTy = iBuilder->getVoidTy();
     
    250235    fileSize->setName("fileSize");
    251236   
     237    ExternalFileBuffer ChStream(iBuilder, iBuilder->getStreamSetTy(4));
     238    SingleBlockBuffer MatchResults(iBuilder, iBuilder->getStreamSetTy(editDistance + 1));
     239
     240    MMapSourceKernel mmapK(iBuilder);
     241    std::unique_ptr<Module> mmapM = mmapK.createKernelModule({}, {&ChStream});
     242    mmapK.setInitialArguments({fileSize});
     243   
     244    PabloKernel editdk(iBuilder, "editd");
     245
     246    buildPatternKernel(editdk, iBuilder, patterns);
     247
     248    kernel::editdScanKernel editdScanK(iBuilder, editDistance);
     249   
     250    std::unique_ptr<Module> editdM = editdk.createKernelModule({&ChStream}, {&MatchResults});
     251    std::unique_ptr<Module> scanM = editdScanK.createKernelModule({&MatchResults}, {});               
     252   
     253    mmapK.addKernelDeclarations(mMod);
     254    editdk.addKernelDeclarations(mMod);
     255    editdScanK.addKernelDeclarations(mMod);
     256
    252257    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", main,0));
    253258
     
    255260    MatchResults.allocateBuffer();
    256261   
    257     generatePipelineLoop(iBuilder, {&editdk, &editdScanK});
     262    generatePipelineLoop(iBuilder, {&mmapK, &editdk, &editdScanK});
    258263       
    259264    iBuilder->CreateRetVoid();
    260265   
    261266    Linker L(*mMod);
     267    L.linkInModule(std::move(mmapM));
    262268    L.linkInModule(std::move(editdM));
    263269    L.linkInModule(std::move(scanM));
  • icGREP/icgrep-devel/icgrep/kernels/interface.cpp

    r5246 r5257  
    9191    arg->setName("blockCnt");
    9292    doSegmentFn->setDoesNotCapture(1); // for self parameter only.
     93    //
     94    // Create the finalSegment function prototype.
     95    std::vector<Type *> finalSegmentParameters = {selfType, iBuilder->getSizeTy()};
     96    FunctionType * finalSegmentFunctionType = FunctionType::get(iBuilder->getVoidTy(), finalSegmentParameters, false);
     97    std::string finalSegmentName = mKernelName + finalSegment_suffix;
     98    Function * finalSegmentFn = Function::Create(finalSegmentFunctionType, GlobalValue::ExternalLinkage, finalSegmentName, client);
     99    finalSegmentFn->setCallingConv(CallingConv::C);
     100    finalSegmentFn->setDoesNotThrow();
     101    Function::arg_iterator finalSegmentArgs = finalSegmentFn->arg_begin();
     102    Value * finalSegmentArg = &*(finalSegmentArgs++);
     103    finalSegmentArg->setName("self");
     104    finalSegmentArg = &*(finalSegmentArgs++);
     105    finalSegmentArg->setName("blockCnt");
     106    finalSegmentFn->setDoesNotCapture(1); // for self parameter only.
    93107    iBuilder->setModule(saveModule);
    94108    iBuilder->restoreIP(savePoint);
     
    132146}
    133147
     148Value * KernelInterface::createFinalSegmentCall(Value * self, Value * blksToDo) const {
     149    Module * m = iBuilder->getModule();
     150    std::string fnName = mKernelName + finalSegment_suffix;
     151    Function * method = m->getFunction(fnName);
     152    if (!method) {
     153        throw std::runtime_error("Cannot find " + fnName);
     154    }
     155    return iBuilder->CreateCall(method, {self, blksToDo});
     156}
     157
    134158Value * KernelInterface::createGetAccumulatorCall(Value * self, std::string accumName) const {
    135159    Module * m = iBuilder->getModule();
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5251 r5257  
    2323static const std::string doBlock_suffix = "_DoBlock";
    2424static const std::string doSegment_suffix = "_DoSegment";
     25static const std::string finalSegment_suffix = "_FinalSegment";
    2526static const std::string finalBlock_suffix = "_FinalBlock";
    2627static const std::string accumulator_infix = "_get_";
     
    5354
    5455    llvm::Value * createDoSegmentCall(llvm::Value * self, llvm::Value * blkCount) const;
     56    llvm::Value * createFinalSegmentCall(llvm::Value * self, llvm::Value * blkCount) const;
    5557    llvm::Value * createFinalBlockCall(llvm::Value * self, llvm::Value * remainingBytes) const;
    5658    llvm::Value * createGetAccumulatorCall(llvm::Value * self, std::string accumName) const;
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5252 r5257  
    109109    generateFinalBlockMethod(); // possibly overridden by the KernelBuilder subtype
    110110    generateDoSegmentMethod();
     111    generateFinalSegmentMethod();
    111112
    112113    // Implement the accumulator get functions
     
    169170}
    170171
     172
    171173//  The default doSegment method dispatches to the doBlock routine for
    172174//  each block of the given number of blocksToDo, and then updates counts.
     
    180182    BasicBlock * strideLoopBody = BasicBlock::Create(iBuilder->getContext(), "strideLoopBody", doSegmentFunction, 0);
    181183    BasicBlock * stridesDone = BasicBlock::Create(iBuilder->getContext(), "stridesDone", doSegmentFunction, 0);
    182     BasicBlock * checkFinalStride = BasicBlock::Create(iBuilder->getContext(), "checkFinalStride", doSegmentFunction, 0);
    183     BasicBlock * checkEndSignals = BasicBlock::Create(iBuilder->getContext(), "checkEndSignals", doSegmentFunction, 0);
    184     BasicBlock * callFinalBlock = BasicBlock::Create(iBuilder->getContext(), "callFinalBlock", doSegmentFunction, 0);
    185184    BasicBlock * segmentDone = BasicBlock::Create(iBuilder->getContext(), "segmentDone", doSegmentFunction, 0);
    186185    BasicBlock * finalExit = BasicBlock::Create(iBuilder->getContext(), "finalExit", doSegmentFunction, 0);
     
    214213    Value * processed = getProcessedItemCount(self, mStreamSetInputs[0].name);
    215214    Value * itemsAvail = iBuilder->CreateSub(availablePos, processed);
    216 //#ifndef NDEBUG
    217 //    iBuilder->CallPrintInt(mKernelName + "_itemsAvail", itemsAvail);
    218 //#endif
     215#ifndef NDEBUG
     216    iBuilder->CallPrintInt(mKernelName + "_itemsAvail", itemsAvail);
     217#endif
    219218    Value * stridesToDo = iBuilder->CreateUDiv(blocksToDo, strideBlocks);
    220219    Value * stridesAvail = iBuilder->CreateUDiv(itemsAvail, stride);
     
    242241    processed = iBuilder->CreateAdd(processed, iBuilder->CreateMul(stridesToDo, stride));
    243242    setProcessedItemCount(self, mStreamSetInputs[0].name, processed);
    244     iBuilder->CreateCondBr(lessThanFullSegment, checkFinalStride, segmentDone);
    245    
    246     iBuilder->SetInsertPoint(checkFinalStride);
    247    
    248     /* We had less than a full segment of data; we may have reached the end of input
    249        on one of the stream sets.  */
    250    
    251     Value * alreadyDone = getTerminationSignal(self);
    252     iBuilder->CreateCondBr(alreadyDone, finalExit, checkEndSignals);
    253    
    254     iBuilder->SetInsertPoint(checkEndSignals);
    255     Value * endOfInput = iBuilder->CreateLoad(endSignalPtrs[0]);
    256     if (endSignalPtrs.size() > 1) {
    257         /* If there is more than one input stream set, then we need to confirm that one of
    258            them has both the endSignal set and the length = to availablePos. */
    259         endOfInput = iBuilder->CreateAnd(endOfInput, iBuilder->CreateICmpEQ(availablePos, producerPos[0]));
    260         for (unsigned i = 1; i < endSignalPtrs.size(); i++) {
    261             Value * e = iBuilder->CreateAnd(iBuilder->CreateLoad(endSignalPtrs[i]), iBuilder->CreateICmpEQ(availablePos, producerPos[i]));
    262             endOfInput = iBuilder->CreateOr(endOfInput, e);
    263         }
    264     }
    265     iBuilder->CreateCondBr(endOfInput, callFinalBlock, segmentDone);
    266    
    267     iBuilder->SetInsertPoint(callFinalBlock);
    268    
    269     Value * remainingItems = iBuilder->CreateSub(availablePos, processed);
    270     createFinalBlockCall(self, remainingItems);
    271     setProcessedItemCount(self, mStreamSetInputs[0].name, availablePos);
    272    
    273     for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    274         Value * ssStructPtr = getStreamSetStructPtr(self, mStreamSetOutputs[i].name);
    275         mStreamSetOutputBuffers[i]->setEndOfInput(ssStructPtr);
    276     }
    277     setTerminationSignal(self);
    278243    iBuilder->CreateBr(segmentDone);
    279    
    280244    iBuilder->SetInsertPoint(segmentDone);
    281 //#ifndef NDEBUG
    282 //    iBuilder->CallPrintInt(mKernelName + "_produced", produced);
    283 //#endif
     245#ifndef NDEBUG
     246    iBuilder->CallPrintInt(mKernelName + "_processed", processed);
     247#endif
    284248    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    285249        Value * produced = getProducedItemCount(self, mStreamSetOutputs[i].name);
     
    294258    iBuilder->restoreIP(savePoint);
    295259}
     260
     261void KernelBuilder::generateFinalSegmentMethod() const {
     262    auto savePoint = iBuilder->saveIP();
     263    Module * m = iBuilder->getModule();
     264    Function * finalSegmentFunction = m->getFunction(mKernelName + finalSegment_suffix);
     265    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", finalSegmentFunction, 0));
     266    BasicBlock * doStrides = BasicBlock::Create(iBuilder->getContext(), "doStrides", finalSegmentFunction, 0);
     267    BasicBlock * stridesDone = BasicBlock::Create(iBuilder->getContext(), "stridesDone", finalSegmentFunction, 0);
     268    Type * const size_ty = iBuilder->getSizeTy();
     269    Constant * stride = ConstantInt::get(size_ty, iBuilder->getStride());
     270    Value * strideBlocks = ConstantInt::get(size_ty, iBuilder->getStride() / iBuilder->getBitBlockWidth());
     271    Function::arg_iterator args = finalSegmentFunction->arg_begin();
     272    Value * self = &*(args++);
     273    Value * blocksToDo = &*(args);
     274    std::vector<Value *> inbufProducerPtrs;
     275    std::vector<Value *> endSignalPtrs;
     276    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
     277        Value * param = getStreamSetStructPtr(self, mStreamSetInputs[i].name);
     278        inbufProducerPtrs.push_back(mStreamSetInputBuffers[i]->getProducerPosPtr(param));
     279        endSignalPtrs.push_back(mStreamSetInputBuffers[i]->getEndOfInputPtr(param));
     280    }
     281   
     282    std::vector<Value *> producerPos;
     283    /* Determine the actually available data examining all input stream sets. */
     284    LoadInst * p = iBuilder->CreateAtomicLoadAcquire(inbufProducerPtrs[0]);
     285    producerPos.push_back(p);
     286    Value * availablePos = producerPos[0];
     287    for (unsigned i = 1; i < inbufProducerPtrs.size(); i++) {
     288        LoadInst * p = iBuilder->CreateAtomicLoadAcquire(inbufProducerPtrs[i]);
     289        producerPos.push_back(p);
     290        /* Set the available position to be the minimum of availablePos and producerPos. */
     291        availablePos = iBuilder->CreateSelect(iBuilder->CreateICmpULT(availablePos, p), availablePos, p);
     292    }
     293    Value * processed = getProcessedItemCount(self, mStreamSetInputs[0].name);
     294    Value * itemsAvail = iBuilder->CreateSub(availablePos, processed);
     295#ifndef NDEBUG
     296    iBuilder->CallPrintInt(mKernelName + "_itemsAvail final", itemsAvail);
     297#endif
     298    Value * stridesToDo = iBuilder->CreateUDiv(blocksToDo, strideBlocks);
     299    Value * stridesAvail = iBuilder->CreateUDiv(itemsAvail, stride);
     300    /* Adjust the number of full blocks to do, based on the available data, if necessary. */
     301    Value * lessThanFullSegment = iBuilder->CreateICmpULT(stridesAvail, stridesToDo);
     302    stridesToDo = iBuilder->CreateSelect(lessThanFullSegment, stridesAvail, stridesToDo);
     303    Value * notDone = iBuilder->CreateICmpUGT(stridesToDo, ConstantInt::get(size_ty, 0));
     304    iBuilder->CreateCondBr(notDone, doStrides, stridesDone);
     305   
     306    iBuilder->SetInsertPoint(doStrides);
     307    createDoSegmentCall(self, blocksToDo);
     308    iBuilder->CreateBr(stridesDone);
     309   
     310    iBuilder->SetInsertPoint(stridesDone);
     311    /* Now at most a partial block remains. */
     312   
     313    processed = getProcessedItemCount(self, mStreamSetInputs[0].name);   
     314    Value * remainingItems = iBuilder->CreateSub(producerPos[0], processed);
     315    //iBuilder->CallPrintInt(mKernelName + " remainingItems", remainingItems);
     316       
     317    createFinalBlockCall(self, remainingItems);
     318    processed = iBuilder->CreateAdd(processed, remainingItems);
     319    setProcessedItemCount(self, mStreamSetInputs[0].name, processed);
     320       
     321#ifndef NDEBUG
     322    iBuilder->CallPrintInt(mKernelName + "_processed final", processed);
     323#endif
     324    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
     325        Value * produced = getProducedItemCount(self, mStreamSetOutputs[i].name);
     326        Value * ssStructPtr = getStreamSetStructPtr(self, mStreamSetOutputs[i].name);
     327        Value * producerPosPtr = mStreamSetOutputBuffers[i]->getProducerPosPtr(ssStructPtr);
     328        iBuilder->CreateAtomicStoreRelease(produced, producerPosPtr);
     329    }
     330
     331    iBuilder->CreateRetVoid();
     332
     333    iBuilder->restoreIP(savePoint);
     334}
     335
     336
    296337
    297338ConstantInt * KernelBuilder::getScalarIndex(const std::string & name) const {
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r5252 r5257  
    125125    virtual void generateDoSegmentMethod() const;
    126126   
     127    virtual void generateFinalSegmentMethod() const;
     128   
    127129    // Add an additional scalar field to the KernelState struct.
    128130    // Must occur before any call to addKernelDeclarations or createKernelModule.
  • icGREP/icgrep-devel/icgrep/kernels/mmap_kernel.cpp

    r5255 r5257  
    4141}
    4242
     43void MMapSourceKernel::generateFinalSegmentMethod() const {
     44    auto savePoint = iBuilder->saveIP();
     45    Module * m = iBuilder->getModule();
     46    Function * finalSegmentFunction = m->getFunction(mKernelName + finalSegment_suffix);
     47    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", finalSegmentFunction, 0));
     48       
     49    Function::arg_iterator args = finalSegmentFunction->arg_begin();
     50    Value * self = &*(args++);
     51    Value * blocksToDo = &*(args);
     52   
     53    createDoSegmentCall(self, blocksToDo);
     54
     55    iBuilder->CreateRetVoid();
     56    iBuilder->restoreIP(savePoint);
     57}
     58
     59
    4360// The doBlock method is deprecated.   But in case it is used, just call doSegment with
    4461// 1 as the number of blocks to do.
  • icGREP/icgrep-devel/icgrep/kernels/mmap_kernel.h

    r5255 r5257  
    3333    void generateDoBlockMethod() const override;
    3434    void generateDoSegmentMethod() const override;
     35    void generateFinalSegmentMethod() const override;
    3536   
    3637};
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp

    r5253 r5257  
    152152           
    153153            iBuilder->SetInsertPoint(partialSegmentLoopBody[i]);
    154             kernels[i]->createDoSegmentCall(instancePtrs[i], segmentBlocks);
     154            kernels[i]->createFinalSegmentCall(instancePtrs[i], segmentBlocks);
    155155            kernels[i]->releaseLogicalSegmentNo(instancePtrs[i], iBuilder->CreateAdd(processedSegmentCount, iBuilder->getSize(1)));
    156156            iBuilder->CreateBr(partialSegmentWait[i+1]);
     
    321321            iBuilder->SetInsertPoint(finalSegmentBlocks[i]);
    322322            Value * segNo = kernels[i]->acquireLogicalSegmentNo(kernels[i]->getInstance());
    323             kernels[i]->createDoSegmentCall(kernels[i]->getInstance(), segBlocks);
     323            kernels[i]->createFinalSegmentCall(kernels[i]->getInstance(), segBlocks);
    324324            kernels[i]->releaseLogicalSegmentNo(kernels[i]->getInstance(), iBuilder->CreateAdd(segNo, iBuilder->getSize(1)));
    325325            if (finalSegmentBlocks[i] != finalSegmentBlocks[i+1]) {
Note: See TracChangeset for help on using the changeset viewer.