Changeset 5615


Ignore:
Timestamp:
Aug 20, 2017, 10:19:39 PM (5 weeks ago)
Author:
cameron
Message:

Automatic expansion of dynamic buffers in pipeline

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

Legend:

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

    r5609 r5615  
    147147    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    148148        if ((mStreamSetInputBuffers[i]->getBufferBlocks() != 0) && (mStreamSetInputBuffers[i]->getBufferBlocks() < requiredBlocks)) {
    149             report_fatal_error(getName() + ": " + mStreamSetInputs[i].name + " requires buffer size " + std::to_string(requiredBlocks));
     149            //report_fatal_error(getName() + ": " + mStreamSetInputs[i].name + " requires buffer size " + std::to_string(requiredBlocks));
    150150        }
    151151        mScalarInputs.emplace_back(mStreamSetInputBuffers[i]->getStreamSetHandle()->getType(), mStreamSetInputs[i].name + BUFFER_PTR_SUFFIX);
     
    12221222   
    12231223}
    1224    
    1225 }
     1224 
     1225   
     1226void applyOutputBufferExpansions(const std::unique_ptr<KernelBuilder> & kb,
     1227                                 std::vector<Value *> inputAvailable,
     1228                                 Value * doFinal) {
     1229    auto kernel = kb->getKernel();
     1230    const unsigned inputSetCount = inputAvailable.size();
     1231    if (inputSetCount == 0) return;  //  Cannot calculate buffer items expected from input.
     1232    auto & outputs = kernel->getStreamSetOutputBuffers();
     1233    const unsigned outputSetCount = outputs.size();
     1234
     1235    Constant * blockSize = kb->getSize(kb->getBitBlockWidth());
     1236    Value * newlyAvailInputItems[inputSetCount];
     1237    Value * requiredOutputBufferSpace[outputSetCount];
     1238    for (unsigned i = 0; i < inputSetCount; i++) {
     1239        Value * processed = kb->getProcessedItemCount(kernel->getStreamInput(i).name);
     1240        newlyAvailInputItems[i] = kb->CreateSub(inputAvailable[i], processed);
     1241    }
     1242    //kb->GetInsertBlock()->dump();
     1243    for (unsigned i = 0; i < outputSetCount; i++) {
     1244        requiredOutputBufferSpace[i] = nullptr;
     1245        auto & rate = kernel->getStreamOutput(i).rate;
     1246        if (rate.isUnknownRate()) continue;  // No calculations possible.
     1247        Kernel::Port port; unsigned ssIdx;
     1248        std::tie(port, ssIdx) = kernel->getStreamPort(rate.referenceStreamSet());
     1249        if (port == Kernel::Port::Output) {
     1250            requiredOutputBufferSpace[i] = rate.CreateRatioCalculation(kb.get(), requiredOutputBufferSpace[ssIdx], doFinal);
     1251        }
     1252        else {
     1253            requiredOutputBufferSpace[i] = rate.CreateRatioCalculation(kb.get(), newlyAvailInputItems[ssIdx], doFinal);
     1254        }
     1255        if (auto db = dyn_cast<DynamicBuffer>(outputs[i])) {
     1256            Value * handle = db->getStreamSetHandle();
     1257            // This buffer can be expanded.
     1258            Value * producedBlock = kb->CreateUDivCeil(kb->getProducedItemCount(kernel->getStreamOutput(i).name), blockSize);
     1259            Value * consumedBlock = kb->CreateUDiv(kb->getConsumedItemCount(kernel->getStreamOutput(i).name), blockSize);
     1260            Value * blocksInUse = kb->CreateSub(producedBlock, consumedBlock);
     1261            Value * blocksRequired = kb->CreateAdd(blocksInUse, kb->CreateUDivCeil(requiredOutputBufferSpace[i], blockSize));
     1262            Value * spaceRequired = kb->CreateMul(blocksRequired, blockSize);
     1263            Value * expansionNeeded = kb->CreateICmpUGT(spaceRequired, db->getBufferedSize(kb.get(), handle));
     1264            BasicBlock * doExpand = kb->CreateBasicBlock("doExpand");
     1265            BasicBlock * bufferReady = kb->CreateBasicBlock("bufferReady");
     1266            kb->CreateCondBr(expansionNeeded, doExpand, bufferReady);
     1267            kb->SetInsertPoint(doExpand);
     1268            db->doubleCapacity(kb.get(), handle);
     1269            // Ensure that capacity is sufficient by successive doubling, if necessary.
     1270            expansionNeeded = kb->CreateICmpUGT(spaceRequired, db->getBufferedSize(kb.get(), handle));
     1271            kb->CreateCondBr(expansionNeeded, doExpand, bufferReady);
     1272            kb->SetInsertPoint(bufferReady);
     1273        }
     1274    }
     1275
     1276}
     1277
     1278}
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r5599 r5615  
    2626class Kernel : public KernelInterface {
    2727    friend class KernelBuilder;
     28public:
     29    enum class Port { Input, Output };
    2830protected:
    2931    using KernelMap = boost::container::flat_map<std::string, unsigned>;
    30     enum class Port { Input, Output };
    3132    using StreamPort = std::pair<Port, unsigned>;
    3233    using StreamMap = boost::container::flat_map<std::string, StreamPort>;
     
    8687    void bindPorts(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs);
    8788
     89    StreamPort getStreamPort(const std::string & name) const;
     90   
    8891    llvm::Module * makeModule(const std::unique_ptr<KernelBuilder> & idb);
    8992
     
    189192
    190193    void callGenerateFinalizeMethod(const std::unique_ptr<KernelBuilder> & idb);
    191 
    192     StreamPort getStreamPort(const std::string & name) const;
    193194
    194195    const parabix::StreamSetBuffer * getInputStreamSetBuffer(const std::string & name) const {
     
    420421};
    421422
     423void applyOutputBufferExpansions(const std::unique_ptr<KernelBuilder> & kb,
     424                                 std::vector<llvm::Value *> inputAvailable,
     425                                 llvm::Value * doFinal);
     426   
     427   
    422428
    423429}
  • icGREP/icgrep-devel/icgrep/kernels/streamset.cpp

    r5612 r5615  
    696696    b->CreateCondBr(priorBufIsNonNull, freePrior, freeCurrent);
    697697    b->SetInsertPoint(freePrior);
     698    //b->CallPrintInt("releasing: ", priorBuf);
    698699    b->CreateFree(priorBuf);
    699700    b->CreateBr(freeCurrent);
     
    722723    Value * oldBufPtr = b->CreateLoad(bufBasePtrField);
    723724    Value * const currentWorkingBlocks = b->CreateLoad(workingBlocksField);
     725    //b->CallPrintInt("currentWorkingBlocks: ", currentWorkingBlocks);
    724726    Value * workingBytes = b->CreateMul(currentWorkingBlocks, blockBytes);
    725727    Value * const curAllocated = b->CreateLoad(capacityField);
     
    742744    b->CreateCondBr(priorBufIsNonNull, deallocatePrior, allocateNew);
    743745    b->SetInsertPoint(deallocatePrior);
     746    //b->CallPrintInt("deallocating: ", priorBuf);
    744747    b->CreateFree(priorBuf);
    745748    b->CreateBr(allocateNew);
     
    747750    b->CreateStore(oldBufPtr, priorBasePtrField);
    748751    Value * newBufPtr = b->CreatePointerCast(b->CreateCacheAlignedMalloc(neededCapacity), bufPtrType);
     752    //b->CallPrintInt("allocated: ", newBufPtr);
     753    //b->CallPrintInt("allocated capacity: ", neededCapacity);
     754
    749755    b->CreateStore(newBufPtr, bufBasePtrField);
    750756    createBlockCopy(b, newBufPtr, oldBufPtr, currentWorkingBlocks);
     
    754760    PHINode * bufPtr = b->CreatePHI(oldBufPtr->getType(), 2);
    755761    bufPtr->addIncoming(oldBufPtr, doubleEntry);
    756     bufPtr->addIncoming(newBufPtr, doRealloc);
     762    bufPtr->addIncoming(newBufPtr, allocateNew);
    757763    createBlockCopy(b, b->CreateGEP(bufPtr, currentWorkingBlocks), bufPtr, currentWorkingBlocks);
    758764    b->CreateStore(b->CreateAdd(currentWorkingBlocks, currentWorkingBlocks), workingBlocksField);
  • icGREP/icgrep-devel/icgrep/toolchain/pipeline.cpp

    r5597 r5615  
    536536        const auto & outputs = kernel->getStreamOutputs();
    537537
     538        std::vector<Value *> inputAvail;
    538539        std::vector<Value *> args = {kernel->getInstance(), terminated};
     540       
    539541        for (unsigned i = 0; i < inputs.size(); ++i) {
    540542            const auto f = producedPos.find(kernel->getStreamSetInputBuffer(i));
     
    542544                report_fatal_error(kernel->getName() + " uses stream set " + inputs[i].name + " prior to its definition");
    543545            }
     546            inputAvail.push_back(f->second);
    544547            args.push_back(f->second);
    545548        }
     549        applyOutputBufferExpansions(iBuilder, inputAvail, terminated);
    546550
    547551        iBuilder->createDoSegmentCall(args);
Note: See TracChangeset for help on using the changeset viewer.