Changeset 5301


Ignore:
Timestamp:
Feb 4, 2017, 9:43:22 PM (8 months ago)
Author:
cameron
Message:

Circular copy-back buffers: initial check-in

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

Legend:

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

    r5299 r5301  
    8787    unsigned blockSize = iBuilder->getBitBlockWidth();
    8888    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    89         if ((mStreamSetInputBuffers[i]->getBufferSize() > 0) && (mStreamSetInputBuffers[i]->getBufferSize() < codegen::SegmentSize + (blockSize + mLookAheadPositions - 1)/blockSize)) {
     89        if ((mStreamSetInputBuffers[i]->getBufferBlocks() > 0) && (mStreamSetInputBuffers[i]->getBufferBlocks() < codegen::SegmentSize + (blockSize + mLookAheadPositions - 1)/blockSize)) {
    9090            llvm::report_fatal_error("Kernel preparation: Buffer size too small " + mStreamSetInputs[i].name);
    9191        }
  • icGREP/icgrep-devel/icgrep/kernels/streamset.cpp

    r5298 r5301  
    4646
    4747void StreamSetBuffer::allocateBuffer() {
    48     mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(getType(), iBuilder->getSize(mBufferSize));
     48    mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(getType(), iBuilder->getSize(mBufferBlocks));
    4949}
    5050
     
    6060    return iBuilder->CreateGEP(iBuilder->CreatePointerCast(getStreamSetPtr(self, blockNo), type), index, "view");
    6161}
     62
     63Value * StreamSetBuffer::getLinearlyAccessibleItems(llvm::Value * fromPosition) const {
     64    if (isa<ArrayType>(mStreamSetType) && dyn_cast<ArrayType>(mStreamSetType)->getNumElements() > 1) {
     65        Constant * stride = iBuilder->getSize(iBuilder->getStride());
     66        return iBuilder->CreateSub(stride, iBuilder->CreateURem(fromPosition, stride));
     67    }
     68    else {
     69        Constant * bufSize = iBuilder->getSize(mBufferBlocks * iBuilder->getStride());
     70        return iBuilder->CreateSub(bufSize, iBuilder->CreateURem(fromPosition, bufSize));
     71    }
     72}
     73
    6274
    6375// Single Block Buffer
     
    8597}
    8698
     99Value * ExternalFileBuffer::getLinearlyAccessibleItems(llvm::Value * fromPosition) const {
     100    throw std::runtime_error("External buffers: getLinearlyAccessibleItems not supported.");
     101}
     102
    87103// Circular Buffer
    88104
     
    91107
    92108    Value * offset = nullptr;
    93     if (mBufferSize == 1) {
     109    if (mBufferBlocks == 1) {
    94110        offset = ConstantInt::getNullValue(iBuilder->getSizeTy());
    95     } else if ((mBufferSize & (mBufferSize - 1)) == 0) { // is power of 2
    96         offset = iBuilder->CreateAnd(blockNo, ConstantInt::get(blockNo->getType(), mBufferSize - 1));
     111    } else if ((mBufferBlocks & (mBufferBlocks - 1)) == 0) { // is power of 2
     112        offset = iBuilder->CreateAnd(blockNo, ConstantInt::get(blockNo->getType(), mBufferBlocks - 1));
    97113    } else {
    98         offset = iBuilder->CreateURem(blockNo, ConstantInt::get(blockNo->getType(), mBufferSize));
     114        offset = iBuilder->CreateURem(blockNo, ConstantInt::get(blockNo->getType(), mBufferBlocks));
    99115    }
    100116    return iBuilder->CreateGEP(self, offset);
    101117}
    102118
    103 // Linear Copyback Buffer
    104 
    105 Value * LinearCopybackBuffer::getStreamSetPtr(Value * self, Value * blockNo) const {
     119
     120// CircularCopybackBuffer Buffer
     121
     122void CircularCopybackBuffer::allocateBuffer() {
     123    mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(getType(), iBuilder->getSize(mBufferBlocks + mOverflowBlocks));
     124}
     125
     126void CircularCopybackBuffer::createCopyBack(Value * self, Value * overFlowItems) {
     127    // Must copy back one full block for each of the streams in the stream set.
     128    Constant * blockSize = iBuilder->getSize(iBuilder->getBitBlockWidth());
     129    Constant * blockSizeLess1 = iBuilder->getSize(iBuilder->getBitBlockWidth() - 1);
     130    Value * overFlowBlocks = iBuilder->CreateUDiv(iBuilder->CreateAdd(overFlowItems, blockSizeLess1), blockSize);
     131    Value * overFlowAreaPtr = iBuilder->CreateGEP(mStreamSetBufferPtr, iBuilder->getSize(mBufferBlocks));
     132    DataLayout dl(iBuilder->getModule());
     133    Constant * blockBytes = ConstantInt::get(iBuilder->getSizeTy(), dl.getTypeAllocSize(mStreamSetType) * iBuilder->getBitBlockWidth());
     134    Value * copyLength = iBuilder->CreateMul(overFlowBlocks, blockBytes);
     135    Type * i8ptr = iBuilder->getInt8Ty()->getPointerTo();
     136    unsigned alignment = iBuilder->getBitBlockWidth() / 8;
     137    iBuilder->CreateMemMove(iBuilder->CreateBitCast(mStreamSetBufferPtr, i8ptr), iBuilder->CreateBitCast(overFlowAreaPtr, i8ptr), copyLength, alignment);
     138}
     139
     140Value * CircularCopybackBuffer::getStreamSetPtr(Value * self, Value * blockNo) const {
     141    assert (blockNo->getType()->isIntegerTy());
     142   
    106143    Value * offset = nullptr;
    107     if (mBufferSize == 1) {
     144    if (mBufferBlocks == 1) {
    108145        offset = ConstantInt::getNullValue(iBuilder->getSizeTy());
    109     } else if ((mBufferSize & (mBufferSize - 1)) == 0) { // is power of 2
    110         offset = iBuilder->CreateAnd(blockNo, ConstantInt::get(blockNo->getType(), mBufferSize - 1));
     146    } else if ((mBufferBlocks & (mBufferBlocks - 1)) == 0) { // is power of 2
     147        offset = iBuilder->CreateAnd(blockNo, ConstantInt::get(blockNo->getType(), mBufferBlocks - 1));
    111148    } else {
    112         offset = iBuilder->CreateURem(blockNo, ConstantInt::get(blockNo->getType(), mBufferSize));
     149        offset = iBuilder->CreateURem(blockNo, ConstantInt::get(blockNo->getType(), mBufferBlocks));
    113150    }
    114151    return iBuilder->CreateGEP(self, offset);
    115152}
     153
    116154
    117155
     
    151189}
    152190
    153 LinearCopybackBuffer::LinearCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace)
    154 : StreamSetBuffer(BufferKind::LinearCopybackBuffer, b, type, bufferBlocks, AddressSpace) {
    155 
    156 }
     191CircularCopybackBuffer::CircularCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned AddressSpace)
     192: StreamSetBuffer(BufferKind::CircularCopybackBuffer, b, type, bufferBlocks, AddressSpace), mOverflowBlocks(overflowBlocks) {
     193
     194}
     195
    157196
    158197ExpandableBuffer::ExpandableBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace)
     
    160199
    161200}
     201
     202Value * ExpandableBuffer::getLinearlyAccessibleItems(llvm::Value * fromPosition) const {
     203    throw std::runtime_error("Expandable buffers: getLinearlyAccessibleItems not supported.");
     204}
     205
    162206
    163207StreamSetBuffer::StreamSetBuffer(BufferKind k, IDISA::IDISA_Builder * b, Type * type, unsigned blocks, unsigned AddressSpace)
     
    165209, iBuilder(b)
    166210, mStreamSetType(resolveStreamSetBufferType(type))
    167 , mBufferSize(blocks)
     211, mBufferBlocks(blocks)
    168212, mAddressSpace(AddressSpace)
    169213, mStreamSetBufferPtr(nullptr)
  • icGREP/icgrep-devel/icgrep/kernels/streamset.h

    r5297 r5301  
    2020public:
    2121
    22     enum class BufferKind : unsigned {BlockBuffer, ExternalFileBuffer, CircularBuffer, LinearCopybackBuffer, ExpandableBuffer};
     22    enum class BufferKind : unsigned {BlockBuffer, ExternalFileBuffer, CircularBuffer, CircularCopybackBuffer, ExpandableBuffer};
    2323
    2424    BufferKind getBufferKind() const {
     
    3838    }
    3939
    40     size_t getBufferSize() const {
    41         return mBufferSize;
     40    size_t getBufferBlocks() const {
     41        return mBufferBlocks;
    4242    }
    4343
     
    5454    virtual llvm::Value * getStreamView(llvm::Type * type, llvm::Value * self, llvm::Value * blockNo, llvm::Value * index) const;
    5555
     56    // The number of items that cam be linearly accessed from a given logical stream position.
     57    virtual llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const;
     58   
    5659protected:
    5760
     
    6770    IDISA::IDISA_Builder * const    iBuilder;
    6871    llvm::Type * const              mStreamSetType;
    69     const size_t                    mBufferSize;
     72    const size_t                    mBufferBlocks;
    7073    const unsigned                  mAddressSpace;
    7174    llvm::Value *                   mStreamSetBufferPtr;
     
    100103    void allocateBuffer() override;
    101104
     105    llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const override;
     106   
    102107protected:
    103108    llvm::Value * getStreamSetPtr(llvm::Value * self, llvm::Value * blockNo) const override;
     
    109114        return b->getBufferKind() == BufferKind::CircularBuffer;
    110115    }
    111  
     116   
    112117    CircularBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
    113118
     
    116121};
    117122   
    118 // Linear buffers extending from the current ConsumerPos forward.   Within the buffer, the
    119 // offset of the block containing the current consumer position is always zero.
     123
    120124//
    121 class LinearCopybackBuffer : public StreamSetBuffer {
     125//  A CircularCopybackBuffer operates as a circular buffer buffer with an overflow area
     126//  for temporary use by the kernel that writes to it.   If the kernel uses the overflow
     127//  area, it must perform the doCopyBack action before releasing the buffer for use by
     128//  subsequent kernels.
     129//  Kernels that read from a CircularCopybackBuffer must not access the overflow area.
     130//
     131class CircularCopybackBuffer : public StreamSetBuffer {
    122132public:
    123     static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::LinearCopybackBuffer;}
     133    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::CircularCopybackBuffer;}
    124134   
    125     LinearCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
     135    CircularCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned AddressSpace = 0);
    126136
    127     // Reset the buffer to contain data starting at the base block of new_consumer_pos,
    128     // copying back any data beyond that position.
    129     //void setConsumerPos(llvm::Value * self, llvm::Value * newConsumerPos) const override;
     137    void allocateBuffer() override;
     138   
     139    // Generate copyback code for the given number of overflowItems.
     140    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems);
     141   
     142   
     143protected:
     144    llvm::Value * getStreamSetPtr(llvm::Value * bufferBasePtr, llvm::Value * blockNo) const override;
     145private:
     146    size_t mOverflowBlocks;
    130147
    131 protected:
    132     llvm::Value * getStreamSetPtr(llvm::Value * self, llvm::Value * blockNo) const override;
    133148};
    134149
     
    148163    llvm::Value * getStreamView(llvm::Type * type, llvm::Value * self, llvm::Value * blockNo, llvm::Value * index) const override;
    149164
     165    llvm::Value * getLinearlyAccessibleItems(llvm::Value * fromPosition) const override;
     166   
    150167protected:
    151168
  • icGREP/icgrep-devel/icgrep/u8u16.cpp

    r5299 r5301  
    255255
    256256    const unsigned segmentSize = codegen::SegmentSize;
    257     const unsigned bufferSegments = codegen::ThreadNum;
     257    const unsigned bufferSegments = codegen::ThreadNum+1;
    258258   
    259259    assert (iBuilder);
     
    290290    // Different choices for the output buffer depending on chosen option.
    291291    ExternalFileBuffer U16external(iBuilder, iBuilder->getStreamSetTy(1, 16));
    292     LinearCopybackBuffer U16out(iBuilder, iBuilder->getStreamSetTy(1, 16), (segmentSize + 1) * bufferSegments);
     292    CircularCopybackBuffer U16out(iBuilder, iBuilder->getStreamSetTy(1, 16), segmentSize * bufferSegments, 1 /*overflow block*/);
    293293
    294294    MMapSourceKernel mmapK(iBuilder, segmentSize);
Note: See TracChangeset for help on using the changeset viewer.