Ignore:
Timestamp:
Mar 11, 2016, 4:44:53 PM (3 years ago)
Author:
nmedfort
Message:

Added ability to name internal state types; removed unnecessary predefined states. Some progress towards supporting segment size > 1

File:
1 edited

Legend:

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

    r4968 r4970  
    1212using namespace pablo;
    1313
    14 static cl::opt<unsigned> SegmentSize("segment-size", cl::desc("Segment Size"), cl::value_desc("LLVM IR file"), cl::init(1));
     14static cl::opt<unsigned> SegmentSize("segment-size", cl::desc("Segment Size"), cl::value_desc("positive integer"), cl::init(1));
    1515
    1616inline bool isPowerOfTwo(const unsigned x) {
     
    2828, mCircularBufferModulo(1)
    2929, mSegmentIndex(0)
    30 , mStartIndex(0) {
     30, mBlockIndex(0) {
    3131    assert (mBlocksPerSegment > 0);
    32     addInternalStateType(b->getInt64Ty());
    33     addInternalStateType(b->getInt64Ty());
    34     addInternalStateType(b->getInt64Ty());
    35     addInternalStateType(b->getInt64Ty());
    36 }
    37 
    38 /** ------------------------------------------------------------------------------------------------------------- *
    39  * @brief addInternalStateType
    40  ** ------------------------------------------------------------------------------------------------------------- */
    41 unsigned KernelBuilder::addInternalStateType(Type * const type) {
     32    mBlockIndex = addInternalState(b->getInt64Ty(), "BlockNo");
     33}
     34
     35/** ------------------------------------------------------------------------------------------------------------- *
     36 * @brief addInternalState
     37 ** ------------------------------------------------------------------------------------------------------------- */
     38unsigned KernelBuilder::addInternalState(Type * const type) {
    4239    assert (type);
    4340    const unsigned index = mStates.size();
     
    4643}
    4744
     45unsigned KernelBuilder::addInternalState(llvm::Type * const type, std::string name) {
     46    if (LLVM_UNLIKELY(mStateNameMap.count(name) != 0)) {
     47        throw std::runtime_error("Kernel already contains internal state " + name);
     48    }
     49    const unsigned index = addInternalState(type);
     50    mStateNameMap.emplace(name, index);
     51    return index;
     52}
     53
    4854/** ------------------------------------------------------------------------------------------------------------- *
    4955 * @brief addOutputStream
     
    5561
    5662/** ------------------------------------------------------------------------------------------------------------- *
    57  * @brief addOutputAccum
    58  ** ------------------------------------------------------------------------------------------------------------- */
    59 void KernelBuilder::addOutputAccum(Type * const type) {
     63 * @brief addOutputScalar
     64 ** ------------------------------------------------------------------------------------------------------------- */
     65void KernelBuilder::addOutputScalar(Type * const type) {
    6066    assert (type);
    61     mOutputAccums.push_back(type);
     67    mOutputScalar.push_back(type);
    6268}
    6369
     
    6672 ** ------------------------------------------------------------------------------------------------------------- */
    6773void KernelBuilder::addInputStream(const unsigned fields, std::string name) {
    68     assert (fields > 0);
    69     if (name.empty())
    70         mInputStreamNames.push_back(mKernelName + "_inputstream_" + std::to_string(mInputStreams.size()));
    71     else
    72         mInputStreamNames.push_back(name);
    73 
     74    assert (fields > 0 && !name.empty());
     75    mInputStreamNames.push_back(name);
    7476    if (fields == 1){
    7577        mInputStreams.push_back(mBitBlockType);
     
    7981}
    8082
     83void KernelBuilder::addInputStream(const unsigned fields) {
     84    addInputStream(fields, std::move(mKernelName + "_inputstream_" + std::to_string(mInputStreams.size())));
     85}
     86
     87
     88/** ------------------------------------------------------------------------------------------------------------- *
     89 * @brief getInputStream
     90 ** ------------------------------------------------------------------------------------------------------------- */
     91Value * KernelBuilder::getInputStream(const unsigned index, const unsigned streamOffset) {
     92    Value * const indices[] = {getOffset(streamOffset), iBuilder->getInt32(index)};
     93    return iBuilder->CreateGEP(mInputParam, indices);
     94}
     95
     96/** ------------------------------------------------------------------------------------------------------------- *
     97 * @brief getInputScalar
     98 ** ------------------------------------------------------------------------------------------------------------- */
     99Value * KernelBuilder::getInputScalar(const unsigned) {
     100    throw std::runtime_error("currently not supported!");
     101}
     102
     103/** ------------------------------------------------------------------------------------------------------------- *
     104 * @brief getOutputStream
     105 ** ------------------------------------------------------------------------------------------------------------- */
     106Value * KernelBuilder::getOutputStream(const unsigned index, const unsigned streamOffset) {
     107    Value * const indices[] = {iBuilder->getInt32(0), iBuilder->getInt32(1), getOffset(streamOffset), iBuilder->getInt32(index)};
     108    return iBuilder->CreateGEP(mKernelParam, indices);
     109}
     110
     111/** ------------------------------------------------------------------------------------------------------------- *
     112 * @brief getOutputScalar
     113 ** ------------------------------------------------------------------------------------------------------------- */
     114Value * KernelBuilder::getOutputScalar(const unsigned) {
     115    throw std::runtime_error("currently not supported!");
     116}
     117
     118/** ------------------------------------------------------------------------------------------------------------- *
     119 * @brief getInternalState
     120 ** ------------------------------------------------------------------------------------------------------------- */
     121Value * KernelBuilder::getInternalState(const unsigned index, Value * const inputStruct) {
     122    Value* indices[] = {iBuilder->getInt64(0), iBuilder->getInt32(0), iBuilder->getInt32(index)};
     123    return iBuilder->CreateGEP(inputStruct ? inputStruct : mKernelParam, indices);
     124}
     125
     126Value * KernelBuilder::getInternalState(const std::string & name, Value * const inputStruct) {
     127    const auto f = mStateNameMap.find(name);
     128    if (LLVM_UNLIKELY(f == mStateNameMap.end())) {
     129        throw std::runtime_error("Kernel does not contain internal state " + name);
     130    }
     131    return getInternalState(f->second, inputStruct);
     132}
     133
     134/** ------------------------------------------------------------------------------------------------------------- *
     135 * @brief setInternalState
     136 ** ------------------------------------------------------------------------------------------------------------- */
     137void KernelBuilder::setInternalState(const unsigned index, Value * const value) {
     138    Value * ptr = getInternalState(index);
     139    assert (ptr->getType()->getPointerElementType() == value->getType());
     140    if (value->getType() == iBuilder->getBitBlockType()) {
     141        iBuilder->CreateBlockAlignedStore(value, ptr);
     142    } else {
     143        iBuilder->CreateStore(value, ptr);
     144    }
     145}
     146
    81147/** ------------------------------------------------------------------------------------------------------------- *
    82148 * @brief addInputScalar
    83149 ** ------------------------------------------------------------------------------------------------------------- */
    84150void KernelBuilder::addInputScalar(Type * const type, std::string name) {
    85     if (name.empty())
    86         mInputScalarNames.push_back(mKernelName + "_inputscalar_" + std::to_string(mInputScalars.size()));
    87     else
    88         mInputScalarNames.push_back(name);
    89 
     151    assert (type && !name.empty());
     152    mInputScalarNames.push_back(name);
    90153    mInputScalars.push_back(type);
     154}
     155
     156void KernelBuilder::addInputScalar(Type * const type) {
     157    addInputScalar(type, std::move(mKernelName + "_inputscalar_" + std::to_string(mInputScalars.size())));
    91158}
    92159
     
    96163Function * KernelBuilder::prepareFunction() {   
    97164    if (mCircularBufferModulo > 1) {
    98         mStartIndex = addInternalStateType(iBuilder->getInt32Ty());
     165        mBlockIndex = addInternalState(iBuilder->getInt32Ty());
    99166    }
    100167    const unsigned capacity = mBlocksPerSegment + mCircularBufferModulo - 1;
     
    103170    mInputScalarType = PointerType::get(StructType::get(mMod->getContext(), mInputScalars), 0);
    104171    Type * outputStreamType = ArrayType::get(StructType::get(mMod->getContext(), mOutputStreams), capacity);
    105     Type * outputAccumType = StructType::get(mMod->getContext(), mOutputAccums);
     172    Type * outputAccumType = StructType::get(mMod->getContext(), mOutputScalar);
    106173    Type * internalStateType = StructType::create(mMod->getContext(), mStates, mKernelName);
    107174    mKernelStructType = StructType::create(mMod->getContext(),std::vector<Type *>({internalStateType, outputStreamType, outputAccumType}), "KernelStruct_"+ mKernelName);
     
    116183    mKernelParam = args++;
    117184    mKernelParam->setName("this");
    118 
    119185    mInputParam = args++;
    120186    mInputParam->setName("input_stream");
     
    131197 ** ------------------------------------------------------------------------------------------------------------- */
    132198void KernelBuilder::finalize() {
     199
    133200    // Finish the actual function
    134     if (mCircularBufferModulo > 1) {
    135         Value * startIdx = getInternalState(mStartIndex);
    136         Value * value = iBuilder->CreateBlockAlignedLoad(startIdx);
    137         value = iBuilder->CreateAdd(value, iBuilder->getInt32(1));
    138         iBuilder->CreateBlockAlignedStore(value, startIdx);
    139     }
     201    Value * startIdx = getInternalState(mBlockIndex);
     202    Value * value = iBuilder->CreateBlockAlignedLoad(startIdx);
     203    value = iBuilder->CreateAdd(value, ConstantInt::get(value->getType(), 1));
     204    iBuilder->CreateBlockAlignedStore(value, startIdx);
    140205    iBuilder->CreateRetVoid();
    141 
    142206
    143207    // Generate the zero initializer
     
    145209    initializer->setCallingConv(CallingConv::C);
    146210    Function::arg_iterator args = initializer->arg_begin();
    147 
    148211    mKernelParam = args++;
    149212    mKernelParam->setName("this");
     
    176239    mKernelParam->setName("this");
    177240
    178     Value* block_size_param = args++;
    179     block_size_param->setName("block_size");
    180     Value* seg_size_param = args++;
    181     seg_size_param->setName("seg_size");
    182241    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", mConstructor, 0));
    183     setInternalState(0, block_size_param);
    184     setInternalState(1, seg_size_param);
    185242    iBuilder->CreateCall(initializer, mKernelParam);
    186243    iBuilder->CreateRetVoid();
     
    199256
    200257/** ------------------------------------------------------------------------------------------------------------- *
    201  * @brief getInputStream
    202  ** ------------------------------------------------------------------------------------------------------------- */
    203 Value * KernelBuilder::getInputStream(const unsigned index, const unsigned streamOffset) {
    204     Value * const indices[] = {getOffset(streamOffset), iBuilder->getInt32(index)};
    205     return iBuilder->CreateGEP(mInputParam, indices);
    206 }
    207 
    208 /** ------------------------------------------------------------------------------------------------------------- *
    209  * @brief getInputScalar
    210  ** ------------------------------------------------------------------------------------------------------------- */
    211 Value * KernelBuilder::getInputScalar(const unsigned index) {
    212     throw std::runtime_error("currently not supported!");
    213 }
    214 
    215 /** ------------------------------------------------------------------------------------------------------------- *
    216  * @brief getKernelState
    217  ** ------------------------------------------------------------------------------------------------------------- */
    218 Value * KernelBuilder::getKernelState(const unsigned index, const unsigned streamOffset) {
    219     Value * const indices[] = {iBuilder->getInt32(0), iBuilder->getInt32(0), getOffset(streamOffset), iBuilder->getInt32(index)};
    220     return iBuilder->CreateGEP(mKernelParam, indices);
    221 }
    222 
    223 /** ------------------------------------------------------------------------------------------------------------- *
    224  * @brief getOutputStream
    225  ** ------------------------------------------------------------------------------------------------------------- */
    226 Value * KernelBuilder::getOutputStream(const unsigned index, const unsigned streamOffset) {
    227     Value * const indices[] = {iBuilder->getInt32(0), iBuilder->getInt32(1), getOffset(streamOffset), iBuilder->getInt32(index)};
    228     return iBuilder->CreateGEP(mKernelParam, indices);
    229 }
    230 
    231 /** ------------------------------------------------------------------------------------------------------------- *
    232  * @brief getOutputScalar
    233  ** ------------------------------------------------------------------------------------------------------------- */
    234 Value * KernelBuilder::getOutputScalar(const unsigned index) {
    235 //    Value * const indices[] = {iBuilder->getInt32(0), iBuilder->getInt32(2), getOffset(0), iBuilder->getInt32(index)};
    236 //    return iBuilder->CreateGEP(mKernelParam, indices);
    237     throw std::runtime_error("currently not supported!");
    238 }
    239 
    240 /** ------------------------------------------------------------------------------------------------------------- *
    241  * @brief getInternalState
    242  ** ------------------------------------------------------------------------------------------------------------- */
    243 Value * KernelBuilder::getInternalState(const unsigned index){
    244     Value* indices[] = {iBuilder->getInt64(0), iBuilder->getInt32(0), iBuilder->getInt32(index)};
    245     return iBuilder->CreateGEP(mKernelParam, indices);
    246 }
    247 
    248 /** ------------------------------------------------------------------------------------------------------------- *
    249  * @brief setInternalState
    250  ** ------------------------------------------------------------------------------------------------------------- */
    251 void KernelBuilder::setInternalState(const unsigned index, Value * const value) {
    252     Value * ptr = getInternalState(index);
    253     assert (ptr->getType()->getPointerElementType() == value->getType());
    254     if (value->getType() == iBuilder->getBitBlockType()) {
    255         iBuilder->CreateBlockAlignedStore(value, ptr);
    256     } else {
    257         iBuilder->CreateStore(value, ptr);
    258     }
    259 }
    260 
    261 /** ------------------------------------------------------------------------------------------------------------- *
    262258 * @brief generateDoBlockCall
    263259 ** ------------------------------------------------------------------------------------------------------------- */
     
    283279    const unsigned adjustedOffset = (mSegmentIndex + value);
    284280    Value * offset = iBuilder->getInt32(adjustedOffset);
    285     if (mStartIndex) {
    286         Value * index = iBuilder->CreateBlockAlignedLoad(getInternalState(mStartIndex));
     281    if (mBlockIndex) {
     282        Value * index = iBuilder->CreateBlockAlignedLoad(getInternalState(mBlockIndex));
    287283        if (adjustedOffset) {
    288284            index = iBuilder->CreateAdd(index, offset);
Note: See TracChangeset for help on using the changeset viewer.