Ignore:
Timestamp:
Jun 27, 2016, 9:43:17 AM (3 years ago)
Author:
cameron
Message:

Updates for kernels with variable output length; stdout kernel

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

Legend:

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

    r5063 r5076  
    6464        finalBlockParameters.push_back(outputSetParmType);
    6565    }
    66     FunctionType * doBlockFunctionType = FunctionType::get(iBuilder->getVoidTy(), doBlockParameters, false);
     66    FunctionType * doBlockFunctionType = FunctionType::get(mDoBlockReturnType, doBlockParameters, false);
    6767    std::string doBlockName = mKernelName + doBlock_suffix;
    6868    Function * doBlockFn = Function::Create(doBlockFunctionType, GlobalValue::ExternalLinkage, doBlockName, client);
     
    7373    }
    7474   
    75     FunctionType * finalBlockType = FunctionType::get(iBuilder->getVoidTy(), finalBlockParameters, false);
     75    FunctionType * finalBlockType = FunctionType::get(mDoBlockReturnType, finalBlockParameters, false);
    7676    std::string finalBlockName = mKernelName + finalBlock_suffix;
    7777    Function * finalBlockFn = Function::Create(finalBlockType, GlobalValue::ExternalLinkage, finalBlockName, client);
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5060 r5076  
    4646    mScalarOutputs(scalar_outputs),
    4747    mInternalScalars(internal_scalars),
     48    mDoBlockReturnType(nullptr),
    4849    mKernelStateType(nullptr) {}
    4950   
     
    6667    std::vector<ScalarBinding> mScalarOutputs;
    6768    std::vector<ScalarBinding> mInternalScalars;
     69    llvm::Type * mDoBlockReturnType;
    6870    llvm::Type * mKernelStateType;
    6971};
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5074 r5076  
    2020                                 std::vector<ScalarBinding> scalar_outputs,
    2121                                 std::vector<ScalarBinding> internal_scalars) :
    22     KernelInterface(builder, kernelName, stream_inputs, stream_outputs, scalar_parameters, scalar_outputs, internal_scalars) {
    23    
    24     for (auto binding : scalar_parameters) {
    25         addScalar(binding.scalarType, binding.scalarName);
    26     }
    27     for (auto binding : scalar_outputs) {
    28         addScalar(binding.scalarType, binding.scalarName);
    29     }
    30     for (auto binding : internal_scalars) {
    31         addScalar(binding.scalarType, binding.scalarName);
    32     }
    33 }
     22    KernelInterface(builder, kernelName, stream_inputs, stream_outputs, scalar_parameters, scalar_outputs, internal_scalars) {}
    3423
    3524void KernelBuilder::addScalar(Type * t, std::string scalarName) {
     
    4231}
    4332
    44 void KernelBuilder::prepareKernelStateType() {
     33void KernelBuilder::setDoBlockReturnType(llvm::Type * t) {
     34    mDoBlockReturnType = t;
     35}
     36
     37void KernelBuilder::prepareKernel() {
     38    if (!mDoBlockReturnType) mDoBlockReturnType = iBuilder->getVoidTy();
     39    for (auto binding : mScalarInputs) {
     40        addScalar(binding.scalarType, binding.scalarName);
     41    }
     42    for (auto binding : mScalarOutputs) {
     43        addScalar(binding.scalarType, binding.scalarName);
     44    }
     45    for (auto binding : mInternalScalars) {
     46        addScalar(binding.scalarType, binding.scalarName);
     47    }
    4548    mKernelStateType = StructType::create(getGlobalContext(), mKernelFields, mKernelName);
    4649}
     
    6265    Module * m = iBuilder->getModule();
    6366
    64     prepareKernelStateType();  // possibly overriden by the KernelBuilder subtype
     67    prepareKernel();  // possibly overriden by the KernelBuilder subtype
    6568    KernelInterface::addKernelDeclarations(m);
    6669    generateDoBlockMethod();     // must be implemented by the KernelBuilder subtype
     
    108111        doBlockArgs.push_back(&*args++);
    109112    }
    110     iBuilder->CreateCall(doBlockFunction, doBlockArgs);
    111     iBuilder->CreateRetVoid();
     113    Value * rslt = iBuilder->CreateCall(doBlockFunction, doBlockArgs);
     114    if (mDoBlockReturnType->isVoidTy()) {
     115        iBuilder->CreateRetVoid();
     116    }
     117    else {
     118        iBuilder->CreateRet(rslt);
     119    }
    112120    iBuilder->restoreIP(savePoint);
    113121}
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r5074 r5076  
    4949    // be added, the default method for preparing kernel state may be used.
    5050   
    51     virtual void prepareKernelStateType();
     51    virtual void prepareKernel();
    5252   
    5353    // Each kernel builder subtype must provide its own logic for generating
     
    6767    // Must occur before any call to addKernelDeclarations or createKernelModule.
    6868    void addScalar(llvm::Type * t, std::string scalarName);
     69   
     70    // Set a specific _DoBlock return type;
     71   
     72    void setDoBlockReturnType(llvm::Type * t);
    6973       
    7074    // Run-time access of Kernel State and parameters of methods for
  • icGREP/icgrep-devel/icgrep/kernels/p2s_kernel.cpp

    r5074 r5076  
    1010
    1111
    12 
    13 extern "C" {
    14     void buffered_write(const char * ptr, size_t bytes) {
    15         outs().write(ptr, bytes);
    16     }
    17 };
    1812
    1913namespace kernel{
     
    106100       
    107101   
    108 Function * create_write(Module * const mod) {
    109     Function * write = mod->getFunction("write");
    110     if (write == nullptr) {
    111         FunctionType *write_type =
    112         TypeBuilder<long(int, char *, long), false>::get(mod->getContext());
    113         write = cast<Function>(mod->getOrInsertFunction("write", write_type,
    114                                                         AttributeSet().addAttribute(mod->getContext(), 2U, Attribute::NoAlias)));
    115     }
    116     return write;
     102void p2s_16Kernel_withCompressedOutputKernel::prepareKernel() {
     103    setDoBlockReturnType(iBuilder->getInt32Ty());
     104    KernelBuilder::prepareKernel();
    117105}
    118 
    119 const size_t OutputBufferSize=65536;
    120 
     106   
    121107void p2s_16Kernel_withCompressedOutputKernel::generateDoBlockMethod() {
    122     outs().SetBufferSize(OutputBufferSize);
    123108    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
    124109    Module * m = iBuilder->getModule();
    125110    Type * i8PtrTy = iBuilder->getInt8PtrTy();
    126     Type * i64 = iBuilder->getIntNTy(64);
     111    Type * i32 = iBuilder->getIntNTy(32);
    127112    Type * bitBlockPtrTy = llvm::PointerType::get(iBuilder->getBitBlockType(), 0);
    128113   
    129     Function * writefn = cast<Function>(m->getOrInsertFunction("buffered_write", iBuilder->getVoidTy(), i8PtrTy, i64, nullptr));
    130 
    131114    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
    132115   
     
    156139   
    157140    Value * u16_output_ptr = iBuilder->CreateBitCast(i16StreamBlock_ptr, PointerType::get(iBuilder->getInt16Ty(), 0));
    158     Value * offset = ConstantInt::get(i64, 0);
     141    Value * offset = ConstantInt::get(i32, 0);
    159142   
    160143    for (unsigned j = 0; j < 8; ++j) {
     
    163146        //iBuilder->CallPrintRegister("merge0", merge0);
    164147        iBuilder->CreateAlignedStore(merge0, iBuilder->CreateBitCast(iBuilder->CreateGEP(u16_output_ptr, offset), bitBlockPtrTy), 1);
    165         offset = iBuilder->CreateZExt(iBuilder->CreateExtractElement(unit_counts, iBuilder->getInt32(2*j)), i64);
     148        offset = iBuilder->CreateZExt(iBuilder->CreateExtractElement(unit_counts, iBuilder->getInt32(2*j)), i32);
    166149        //iBuilder->CallPrintInt("offset", offset);
    167150        iBuilder->CreateAlignedStore(merge1, iBuilder->CreateBitCast(iBuilder->CreateGEP(u16_output_ptr, offset), bitBlockPtrTy), 1);
    168151        //iBuilder->CallPrintRegister("merge1", merge1);
    169         offset = iBuilder->CreateZExt(iBuilder->CreateExtractElement(unit_counts, iBuilder->getInt32(2*j+1)), i64);
     152        offset = iBuilder->CreateZExt(iBuilder->CreateExtractElement(unit_counts, iBuilder->getInt32(2*j+1)), i32);
    170153        //iBuilder->CallPrintInt("offset", offset);
    171154    }
    172     Value * byte_offset = iBuilder->CreateAdd(offset, offset);
    173     iBuilder->CreateCall(writefn, std::vector<Value *>({iBuilder->CreateBitCast(i16StreamBlock_ptr, i8PtrTy), byte_offset}));
    174     iBuilder->CreateRetVoid();
     155    iBuilder->CreateRet(offset);
    175156    iBuilder->restoreIP(savePoint);
    176157}
  • icGREP/icgrep-devel/icgrep/kernels/p2s_kernel.h

    r5074 r5076  
    6060       
    6161private:
     62    void prepareKernel() override;
    6263    void generateDoBlockMethod() override;
    6364};
  • icGREP/icgrep-devel/icgrep/kernels/stdout_kernel.cpp

    r5007 r5076  
    1010namespace kernel {
    1111
    12     static Function * create_write(Module * const mod) {
    13         Function * write = mod->getFunction("write");
    14         if (write == nullptr) {
    15             FunctionType *write_type =
    16             TypeBuilder<long(int, char *, long), false>::get(mod->getContext());
    17             write = cast<Function>(mod->getOrInsertFunction("write", write_type,
    18                                                              AttributeSet().addAttribute(mod->getContext(), 2U, Attribute::NoAlias)));
    19         }
    20         return write;
     12static Function * create_write(Module * const mod) {
     13    Function * write = mod->getFunction("write");
     14    if (write == nullptr) {
     15        FunctionType *write_type =
     16        TypeBuilder<long(int, char *, long), false>::get(mod->getContext());
     17        write = cast<Function>(mod->getOrInsertFunction("write", write_type,
     18                                                         AttributeSet().addAttribute(mod->getContext(), 2U, Attribute::NoAlias)));
    2119    }
    22    
     20    return write;
     21}
    2322
    24 void generateStdOutKernel(Module * m, IDISA::IDISA_Builder * iBuilder, KernelBuilder * kBuilder, unsigned fw) {
    25     LLVMContext & ctxt = m->getContext();
    26 
    27     Type * i32 = iBuilder->getIntNTy(32);
    28     Type * i64 = iBuilder->getIntNTy(64);
    29    
    30     // Insert this declaration in the module (if necessary):  declare i64 @write(i32, i8*, i64)
    31     Function * writefn = create_write(m);
    32     kBuilder->addInputStream(fw, "byte_pack");
    33     // No output streams.
    34     kBuilder->addInternalState(i64, "RemainingBytes");
    35 
    36     Function * function = kBuilder->prepareFunction();
    37    
    38     BasicBlock * full_block_write = BasicBlock::Create(ctxt, "full_block_write", function, 0);
    39     BasicBlock * final_block_write = BasicBlock::Create(ctxt, "final_block_write", function, 0);
    40     BasicBlock * exit_block = BasicBlock::Create(ctxt, "exit_stdout", function, 0);
    41     Value * bytes = iBuilder->CreateLoad(kBuilder->getInternalState("RemainingBytes"));
    42 
    43     Value * input = iBuilder->CreateBitCast(kBuilder->getInputStream(0), iBuilder->getInt8PtrTy());
    44     Value * blockSize = ConstantInt::get(i64, iBuilder->getBitBlockWidth());
    45 
    46     Value * fullblock_cond = iBuilder->CreateICmpULT(bytes, blockSize);
    47     iBuilder->CreateCondBr(fullblock_cond, final_block_write, full_block_write);
    48    
    49     iBuilder->SetInsertPoint(full_block_write);
    50     Value * outputBytes = ConstantInt::get(i64, iBuilder->getBitBlockWidth() * fw/8);
    51     iBuilder->CreateCall(writefn, std::vector<Value *>({ConstantInt::get(i32, 1), input, outputBytes}));
    52     Value * remain = iBuilder->CreateSub(bytes, blockSize);
    53     kBuilder->setInternalState("RemainingBytes", remain);
    54     iBuilder->CreatePtrToInt(remain, iBuilder->getInt64Ty());
    55     iBuilder->CreateBr(exit_block);
    56    
    57     iBuilder->SetInsertPoint(final_block_write);
    58     outputBytes = iBuilder->CreateMul(bytes, ConstantInt::get(i64, fw/8));
    59     iBuilder->CreateCall(writefn, std::vector<Value *>({ConstantInt::get(i32, 1), input, outputBytes}));
    60     kBuilder->setInternalState("RemainingBytes", ConstantInt::getNullValue(i64));
    61     iBuilder->CreateBr(exit_block);
    62 
    63    
    64     iBuilder->SetInsertPoint(exit_block);
    65    
    66     kBuilder->finalize();
     23//  Override the default void type for DoBlock functions.
     24void stdOutKernel::prepareKernel() {
     25    setDoBlockReturnType(mStreamType);
     26    KernelBuilder::prepareKernel();
    6727}
    6828
    6929
     30void stdOutKernel::generateDoBlockMethod() {
     31    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
     32    Module * m = iBuilder->getModule();
     33    Function * writefn = create_write(m);
     34    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
     35    Type * i8PtrTy = iBuilder->getInt8PtrTy();
     36
     37    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doBlockFunction, 0));
     38
     39    Value * self = getParameter(doBlockFunction, "self");
     40    Value * bufferPtr = getParameter(doBlockFunction, "bufferPtr");
     41    Value * bufferFinalBlockPtr = getScalarField(self, "bufferFinalBlockPtr");
     42    //iBuilder->CallPrintInt("bufferPtr", iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty()));
     43    //iBuilder->CallPrintInt("bufferFinalBlockPtr", iBuilder->CreatePtrToInt(bufferFinalBlockPtr, iBuilder->getInt64Ty()));
    7044   
     45   
     46    BasicBlock * flushBlock = BasicBlock::Create(iBuilder->getContext(), "flush", doBlockFunction, 0);
     47    BasicBlock * exitBlock = BasicBlock::Create(iBuilder->getContext(), "exit", doBlockFunction, 0);
     48    Value * inFinal = iBuilder->CreateICmpUGT(bufferPtr, bufferFinalBlockPtr);
     49    iBuilder->CreateCondBr(inFinal, flushBlock, exitBlock);
     50   
     51    iBuilder->SetInsertPoint(flushBlock);
     52    Value * basePtr = getScalarField(self, "bufferBasePtr");
     53    //iBuilder->CallPrintInt("bufferBasePtr", iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty()));
     54    Value * baseAddress = iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty());
     55    Value * pointerAddress = iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty());
     56    Value * bytesToFlush = iBuilder->CreateSub(pointerAddress, baseAddress);
     57   
     58    iBuilder->CreateCall(writefn, std::vector<Value *>({iBuilder->getInt32(1), iBuilder->CreateBitCast(basePtr, i8PtrTy), bytesToFlush}));
     59    // Buffer is flushed, return the buffer base pointer for subsequent output to the buffer.
     60    iBuilder->CreateRet(basePtr);
     61
     62    iBuilder->SetInsertPoint(exitBlock);
     63    iBuilder->CreateRet(bufferPtr);
     64    iBuilder->restoreIP(savePoint);
    7165}
     66
     67void stdOutKernel::generateFinalBlockMethod() {
     68    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
     69    Module * m = iBuilder->getModule();
     70    Function * writefn = create_write(m);
     71    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
     72    Type * i8PtrTy = iBuilder->getInt8PtrTy();
     73   
     74    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "fb_flush", finalBlockFunction, 0));
     75    Value * self = getParameter(finalBlockFunction, "self");
     76    Value * bufferPtr = getParameter(finalBlockFunction, "bufferPtr");
     77    Value * basePtr = getScalarField(self, "bufferBasePtr");
     78    // Flush the output.
     79    Value * baseAddress = iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty());
     80    Value * pointerAddress = iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty());
     81    Value * bytesToFlush = iBuilder->CreateSub(pointerAddress, baseAddress);
     82   
     83    iBuilder->CreateCall(writefn, std::vector<Value *>({iBuilder->getInt32(1), iBuilder->CreateBitCast(basePtr, i8PtrTy), bytesToFlush}));
     84    // Buffer is flushed, return the buffer base pointer for subsequent output to the buffer.
     85    iBuilder->CreateRet(basePtr);
     86    iBuilder->restoreIP(savePoint);
     87}
     88}
  • icGREP/icgrep-devel/icgrep/kernels/stdout_kernel.h

    r5007 r5076  
    66#define STDOUT_KERNEL_H
    77
    8 namespace llvm { class Module; }
     8#include "streamset.h"
     9#include "kernel.h"
     10#include <llvm/IR/Type.h>
    911
    1012namespace IDISA { class IDISA_Builder; }
     
    1214namespace kernel {
    1315
    14 class KernelBuilder;
    15 
    16     void generateStdOutKernel(llvm::Module *, IDISA::IDISA_Builder * iBuilder, KernelBuilder * kBuilder, unsigned fw = 8);
     16class stdOutKernel : public KernelBuilder {
     17public:
     18    stdOutKernel(IDISA::IDISA_Builder * iBuilder, unsigned codeUnitWidth) :
     19    KernelBuilder(iBuilder, "stdout",
     20                  {StreamSetBinding{StreamSetType(1, codeUnitWidth), "bufferPtr"}}, {}, {}, {}, {}) {
     21        mStreamType = PointerType::get(StreamSetType(1, codeUnitWidth).getStreamSetBlockType(iBuilder), 0);
     22        mScalarInputs = {ScalarBinding{mStreamType , "bufferBasePtr"}, ScalarBinding{mStreamType, "bufferFinalBlockPtr"}};
     23    }
     24   
     25private:
     26    void prepareKernel() override;
     27    void generateDoBlockMethod() override;
     28    void generateFinalBlockMethod() override;
     29   
     30    llvm::Type * mStreamType;
     31};
    1732}
    1833
  • icGREP/icgrep-devel/icgrep/kernels/streamset.cpp

    r5075 r5076  
    1616    return ArrayType::get(streamType, mStreamCount);
    1717}
    18    
     18
    1919llvm::Type * StreamSetBuffer::getStreamSetBlockType() {
    2020    return mStreamSetType.getStreamSetBlockType(iBuilder);
    2121}
    2222
     23llvm::Type * StreamSetBuffer::getStreamSetBufferType() {
     24    if (mSegmentSize == 1) return getStreamSetBlockType();
     25    return ArrayType::get(getStreamSetBlockType(), mSegmentSize);
     26}
     27
    2328llvm::Value * StreamSetBuffer::allocateBuffer() {
    2429    if (mStreamSetBufferPtr == nullptr) {
    25         llvm::Type * streamBufferType = getStreamSetBlockType();
    26         if (mSegmentSize > 1) streamBufferType = ArrayType::get(getStreamSetBlockType(), mSegmentSize);
    27         mStreamSetBufferPtr = iBuilder->CreateAlloca(streamBufferType);
     30        mStreamSetBufferPtr = iBuilder->CreateAlloca(getStreamSetBlockType(), iBuilder->getInt32(mSegmentSize));
    2831    }
    2932    return mStreamSetBufferPtr;
Note: See TracChangeset for help on using the changeset viewer.