Changeset 5325 for icGREP


Ignore:
Timestamp:
Feb 16, 2017, 6:06:31 PM (2 years ago)
Author:
cameron
Message:

Processing rate attributes on stream set inputs and outputs; initial check-in

Location:
icGREP/icgrep-devel/icgrep/kernels
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5307 r5325  
    1919
    2020
     21// Processing rate attributes are required for all stream set bindings for a kernel.
     22// These attributes describe the number of items that are processed or produced as
     23// a ratio in comparison to the principal input stream set (or the principal output
     24// stream set if there is no input.
     25//
     26// The default ratio is FixedRatio(1) which means that there is one item processed or
     27// produced for every item of the principal input or output item.
     28//
     29// Kernels which produce a variable number of items use MaxRatio(n), for a maximum
     30// of n items produced or consumed per principal input or output item.
     31struct ProcessingRate {
     32    enum class ClassTypeId : unsigned {FixedRatio, MaxRatio, Unknown};
     33    inline ClassTypeId getClassTypeId() const noexcept {
     34        return mClassTypeId;
     35    }
     36   
     37    ProcessingRate(ClassTypeId t = ClassTypeId::Unknown) : mClassTypeId(t) {}
     38
     39    const ClassTypeId       mClassTypeId;
     40};
     41
     42// FixedRatio(m, n) means that the number of items processed or produced for a principal
     43// stream set of length L are  m * L/n + L mod n
     44struct FixedRatio : ProcessingRate {
     45    FixedRatio(unsigned strmItems = 1, unsigned perPrincipalInputItems = 1)
     46    : ProcessingRate(ClassTypeId::FixedRatio), thisStreamItems(strmItems), principalInputItems(perPrincipalInputItems) {
     47    }
     48    static inline bool classof(const ProcessingRate * e) {
     49        return e->getClassTypeId() == ClassTypeId::FixedRatio;
     50    }
     51   
     52    unsigned thisStreamItems;
     53    unsigned principalInputItems;
     54};
     55
     56struct MaxRatio : ProcessingRate {
     57    MaxRatio(unsigned strmItems, unsigned perPrincipalInputItems = 1)
     58    : ProcessingRate(ClassTypeId::MaxRatio), thisStreamItems(strmItems), principalInputItems(perPrincipalInputItems) {
     59    }
     60    static inline bool classof(const ProcessingRate * e) {
     61        return e->getClassTypeId() == ClassTypeId::MaxRatio;
     62    }
     63   
     64    unsigned thisStreamItems;
     65    unsigned principalInputItems;
     66};
     67
     68       
     69
    2170struct Binding {
    22     Binding(llvm::Type * type, const std::string & name, const unsigned step = 0)
    23     : type(type), name(name), step(step) {
    24 
     71    Binding(llvm::Type * type, const std::string & name, ProcessingRate * r = nullptr)
     72    : type(type), name(name) {
     73        rate = (r == nullptr) ? new FixedRatio(1, 1) : r;
    2574    }
    2675
    2776    llvm::Type *        type;
    2877    std::string         name;
    29     const unsigned      step;
     78    ProcessingRate *    rate;
    3079};
    3180
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5320 r5325  
    9292        mScalarInputs.emplace_back(mStreamSetInputBuffers[i]->getPointerType(), mStreamSetInputs[i].name + BUFFER_PTR_SUFFIX);
    9393        addScalar(iBuilder->getSizeTy(), mStreamSetInputs[i].name + PROCESSED_ITEM_COUNT_SUFFIX);
     94       
    9495    }
    9596    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
     
    246247
    247248void KernelBuilder::setProcessedItemCount(Value * instance, const std::string & name, Value * value) const {
     249    //iBuilder->CallPrintInt(getName() + " " + name + " processed", value);
    248250    setScalarField(instance, name + PROCESSED_ITEM_COUNT_SUFFIX, value);
    249251}
    250252
    251253void KernelBuilder::setProducedItemCount(Value * instance, const std::string & name, Value * value) const {
     254    //iBuilder->CallPrintInt(getName() + " " + name +  " produced", value);
    252255    setScalarField(instance, name + PRODUCED_ITEM_COUNT_SUFFIX, value);
    253256}
     
    272275    for (const Binding & b : bindings) {
    273276        if (b.name == name) {
    274             const auto divisor = (b.step == 0) ? iBuilder->getBitBlockWidth() : b.step;
     277            const auto divisor = iBuilder->getBitBlockWidth();
    275278            if (LLVM_LIKELY((divisor & (divisor - 1)) == 0)) {
    276279                return iBuilder->CreateLShr(itemCount, std::log2(divisor));
     
    463466    CreateDoBlockMethodCall();
    464467
    465     // Update counts
     468    processed = getProcessedItemCount(mStreamSetInputs[0].name);
     469    Value * itemsDone = iBuilder->CreateAdd(processed, stride);
     470   
     471    // Update counts for stream sets with FixedRatio processing rates.
    466472    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    467         Value * processed = getProcessedItemCount(mStreamSetInputs[i].name);
    468         processed = iBuilder->CreateAdd(processed, stride);
    469         setProcessedItemCount(mStreamSetInputs[i].name, processed);
    470     }
    471 
     473        if (auto * ratio = dyn_cast<FixedRatio>(mStreamSetInputs[i].rate)) {
     474            Value * items = itemsDone;
     475            if (ratio->thisStreamItems != 1) {
     476                items = iBuilder->CreateMul(iBuilder->getSize(ratio->thisStreamItems), itemsDone);
     477            }
     478            if (ratio->principalInputItems != 1) {
     479                Value * divisor = iBuilder->getSize(ratio->principalInputItems);
     480                items = iBuilder->CreateAdd(iBuilder->CreateUDiv(items, divisor), iBuilder->CreateURem(items, divisor));
     481            }
     482            setProcessedItemCount(mStreamSetInputs[i].name, items);
     483        }
     484    }
    472485    if (!mDoBlockUpdatesProducedItemCountsAttribute) {
    473486        for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    474             Value * produced = getProducedItemCount(mStreamSetOutputs[i].name);
    475             produced = iBuilder->CreateAdd(produced, stride);
    476             setProducedItemCount(mStreamSetOutputs[i].name, produced);
    477         }
    478     }
    479 
     487            if (auto * ratio = dyn_cast<FixedRatio>(mStreamSetOutputs[i].rate)) {
     488                Value * produced = itemsDone;
     489                if (ratio->thisStreamItems != 1) {
     490                    produced = iBuilder->CreateMul(iBuilder->getSize(ratio->thisStreamItems), itemsDone);
     491                }
     492                if (ratio->principalInputItems != 1) {
     493                    Value * divisor = iBuilder->getSize(ratio->principalInputItems);
     494                    produced = iBuilder->CreateAdd(iBuilder->CreateUDiv(produced, divisor), iBuilder->CreateURem(produced, divisor));
     495                }
     496                setProducedItemCount(mStreamSetOutputs[i].name, produced);
     497            }
     498        }
     499    }
     500   
    480501    stridesRemaining->addIncoming(iBuilder->CreateSub(stridesRemaining, iBuilder->getSize(1)), strideLoopBody);
    481502    iBuilder->CreateBr(strideLoopCond);
     
    490511
    491512    CreateDoFinalBlockMethodCall(remainingItems);
    492 
     513   
     514    itemsDone = producerPos[0];
     515       
    493516    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    494         Value * preProcessed = getProcessedItemCount(mStreamSetInputs[i].name);
    495         setProcessedItemCount(mStreamSetInputs[i].name, iBuilder->CreateAdd(preProcessed, remainingItems));
     517        if (auto * ratio = dyn_cast<FixedRatio>(mStreamSetInputs[i].rate)) {
     518            Value * items = itemsDone;
     519            if (ratio->thisStreamItems != 1) {
     520                items = iBuilder->CreateMul(iBuilder->getSize(ratio->thisStreamItems), itemsDone);
     521            }
     522            if (ratio->principalInputItems != 1) {
     523                Value * divisor = iBuilder->getSize(ratio->principalInputItems);
     524                items = iBuilder->CreateAdd(iBuilder->CreateUDiv(items, divisor), iBuilder->CreateURem(items, divisor));
     525            }
     526            setProcessedItemCount(mStreamSetInputs[i].name, items);
     527        }
    496528    }
    497529    if (!mDoBlockUpdatesProducedItemCountsAttribute) {
    498530        for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    499             Value * preProduced = getProducedItemCount(mStreamSetOutputs[i].name);
    500             setProducedItemCount(mStreamSetOutputs[i].name, iBuilder->CreateAdd(preProduced, remainingItems));
    501         }
    502     }
     531            if (auto * ratio = dyn_cast<FixedRatio>(mStreamSetOutputs[i].rate)) {
     532                Value * produced = itemsDone;
     533                if (ratio->thisStreamItems != 1) {
     534                    produced = iBuilder->CreateMul(iBuilder->getSize(ratio->thisStreamItems), itemsDone);
     535                }
     536                if (ratio->principalInputItems != 1) {
     537                    Value * divisor = iBuilder->getSize(ratio->principalInputItems);
     538                    produced = iBuilder->CreateAdd(iBuilder->CreateUDiv(produced, divisor), iBuilder->CreateURem(produced, divisor));
     539                }
     540                setProducedItemCount(mStreamSetOutputs[i].name, produced);
     541            }
     542        }
     543    }
     544   
    503545    setTerminationSignal();
    504546    iBuilder->CreateBr(segmentDone);
  • icGREP/icgrep-devel/icgrep/kernels/mmap_kernel.cpp

    r5307 r5325  
    4343: SegmentOrientedKernel(iBuilder, "mmap_source",
    4444    {},
    45     {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "sourceBuffer", iBuilder->getBitBlockWidth()}},
     45    {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "sourceBuffer"}},
    4646    {Binding{iBuilder->getSizeTy(), "fileSize"}}, {}, {})
    4747, mSegmentBlocks(blocksPerSegment)
  • icGREP/icgrep-devel/icgrep/kernels/p2s_kernel.cpp

    r5317 r5325  
    9393: BlockOrientedKernel(iBuilder, "p2s_compress",
    9494              {Binding{iBuilder->getStreamSetTy(8, 1), "basisBits"}, Binding{iBuilder->getStreamSetTy(1, 1), "deletionCounts"}},
    95               {Binding{iBuilder->getStreamSetTy(1, 8), "byteStream"}},
     95                      {Binding{iBuilder->getStreamSetTy(1, 8), "byteStream", new MaxRatio(1)}},
    9696              {}, {}, {}) {
    9797    setDoBlockUpdatesProducedItemCountsAttribute(true);
     
    196196: BlockOrientedKernel(b, "p2s_16_compress",
    197197              {Binding{b->getStreamSetTy(16, 1), "basisBits"}, Binding{b->getStreamSetTy(1, 1), "deletionCounts"}},
    198               {Binding{b->getStreamSetTy(1, 16), "i16Stream", b->getStride()}},
     198              {Binding{b->getStreamSetTy(1, 16), "i16Stream", new MaxRatio(1)}},
    199199              {},
    200200              {},
    201               {Binding{b->getSizeTy(), "unitsGenerated"}, Binding{b->getSizeTy(), "unitsWritten"}}) {
     201              {}) {
    202202    setDoBlockUpdatesProducedItemCountsAttribute(true);
    203203}
  • icGREP/icgrep-devel/icgrep/kernels/radix64.cpp

    r5317 r5325  
    8080    Constant * Const3 = iBuilder->getSize(3);
    8181    Constant * Const4 = iBuilder->getSize(4);
     82    Constant * Const6 = iBuilder->getSize(6);
     83    Constant * Const5 = iBuilder->getSize(5);
     84
    8285    Constant * tripleBlockSize = iBuilder->getSize(3 * iBuilder->getStride());
    8386    Constant * packSize = iBuilder->getSize(PACK_SIZE);
     
    159162    processed = iBuilder->CreateAdd(processed, loopItemsToDo);
    160163    setProcessedItemCount("sourceStream", processed);
    161    
     164
    162165    // We have produced 4 output bytes for every 3 input bytes.
    163166    Value * totalProduced = iBuilder->CreateMul(iBuilder->CreateUDiv(processed, Const3), Const4);
    164167    setProducedItemCount("expandedStream", totalProduced);
    165    
     168
    166169    // Except for final segment processing, we are done.
    167170    iBuilder->CreateCondBr(doFinal, expand3_4_final, expand3_4_exit);
     
    233236    setProcessedItemCount("sourceStream", processed);
    234237
    235     // We have produced 4 output bytes for every 3 input bytes.  If the number of input
    236     // bytes is not a multiple of 3, then we have one more output byte for each excess
    237     // input byte.
    238     totalProduced = iBuilder->CreateAdd(iBuilder->CreateMul(iBuilder->CreateUDiv(processed, Const3), Const4), iBuilder->CreateURem(processed, Const3));
     238    // We have produced 4 output bytes for every 3 input bytes.  For radix64 applications,
     239    // each output byte will have six significant bits.   If the number of bytes is not
     240    // a multiple of 3, then there will be 8 or 16 additional bits to encode.  This will
     241    // require 2 or 3 additional output bytes given that each output byte only encodes 6 bits.
     242   
     243    Value * totalBits = iBuilder->CreateShl(processed, Const3);
     244    totalProduced = iBuilder->CreateUDiv(iBuilder->CreateAdd(totalBits, Const5), Const6);
    239245    setProducedItemCount("expandedStream", totalProduced);
    240246   
     
    286292        Value * bytepack = loadInputStreamPack("expandedStream", iBuilder->getInt32(0), iBuilder->getInt32(i));
    287293        Value * radix64pack = processPackData(bytepack);
    288         storeOutputStreamPack("radix64stream",iBuilder->getInt32(0), iBuilder->getInt32(i), radix64pack);
     294        storeOutputStreamPack("radix64stream", iBuilder->getInt32(0), iBuilder->getInt32(i), radix64pack);
    289295    }
    290     Value * produced = getProducedItemCount("radix64stream");
    291     produced = iBuilder->CreateAdd(produced, iBuilder->getSize(iBuilder->getStride()));
    292     setProducedItemCount("radix64stream", produced);
    293296}
    294297
     
    297300    BasicBlock * entry = iBuilder->GetInsertBlock();
    298301    BasicBlock * radix64_loop = CreateBasicBlock("radix64_loop");
    299     BasicBlock * loopExit = CreateBasicBlock("loopExit");
    300302    BasicBlock * fbExit = CreateBasicBlock("fbExit");
    301     // Final Block arguments: self, remaining.
    302     Value * remainMod4 = iBuilder->CreateAnd(remainingBytes, iBuilder->getSize(3));
    303 
     303   
    304304    const unsigned PACK_SIZE = iBuilder->getStride()/8;
    305305    Constant * packSize = iBuilder->getSize(PACK_SIZE);
     
    325325    Value* continueLoop = iBuilder->CreateICmpSGT(remainAfterLoop, iBuilder->getSize(0));
    326326
    327     iBuilder->CreateCondBr(continueLoop, radix64_loop, loopExit);
    328 
    329     iBuilder->SetInsertPoint(loopExit);
    330 
    331     iBuilder->CreateBr(fbExit);
     327    iBuilder->CreateCondBr(continueLoop, radix64_loop, fbExit);
    332328
    333329    iBuilder->SetInsertPoint(fbExit);
    334     Value * outputNumberAdd = iBuilder->CreateSelect(iBuilder->CreateICmpEQ(remainMod4, iBuilder->getSize(0)), iBuilder->getSize(0), iBuilder->getSize(1));
    335     Value * produced = iBuilder->CreateAdd(getProducedItemCount("radix64stream"), iBuilder->CreateAdd(remainingBytes, outputNumberAdd));
    336     setProducedItemCount("radix64stream", produced);
    337330}
    338331
     
    479472: SegmentOrientedKernel(iBuilder, "expand3_4",
    480473            {Binding{iBuilder->getStreamSetTy(1, 8), "sourceStream"}},
    481             {Binding{iBuilder->getStreamSetTy(1, 8), "expandedStream"}},
     474            {Binding{iBuilder->getStreamSetTy(1, 8), "expandedStream", new FixedRatio(4,3)}},
    482475            {}, {}, {}) {
    483     setDoBlockUpdatesProducedItemCountsAttribute(true);
    484476}
    485477
     
    489481            {Binding{iBuilder->getStreamSetTy(1, 8), "radix64stream"}},
    490482            {}, {}, {}) {
    491     setDoBlockUpdatesProducedItemCountsAttribute(true);
    492483}
    493484
Note: See TracChangeset for help on using the changeset viewer.