Ignore:
Timestamp:
Jun 18, 2016, 9:48:28 PM (3 years ago)
Author:
cameron
Message:

Kernel interface provides only those services used for building pipelines

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

Legend:

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

    r5054 r5060  
    1313using namespace kernel;
    1414
    15 KernelInterface::KernelInterface(IDISA::IDISA_Builder * builder,
    16                                  std::string kernelName,
    17                                  std::vector<StreamSetBinding> stream_inputs,
    18                                  std::vector<StreamSetBinding> stream_outputs,
    19                                  std::vector<ScalarBinding> scalar_parameters,
    20                                  std::vector<ScalarBinding> scalar_outputs,
    21                                  std::vector<ScalarBinding> internal_scalars) :
    22                 iBuilder(builder),
    23                 mKernelName(kernelName),
    24                 mStreamSetInputs(stream_inputs),
    25                 mStreamSetOutputs(stream_outputs),
    26                 mScalarInputs(scalar_parameters),
    27                 mScalarOutputs(scalar_outputs),
    28                 mInternalScalars(internal_scalars),
    29                 mKernelStateType(nullptr) {
    30    
    31     for (auto binding : scalar_parameters) {
    32         addScalar(binding.scalarType, binding.scalarName);
     15void KernelInterface::addKernelDeclarations(Module * client) {
     16    errs() << "KernelInterface::addKernelDeclarations\n";
     17    Module * saveModule = iBuilder->getModule();
     18    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
     19    iBuilder->setModule(client);
     20    if (mKernelStateType == nullptr) {
     21        throw std::runtime_error("Kernel interface " + mKernelName + " not yet finalized.");
    3322    }
    34     for (auto binding : scalar_outputs) {
    35         addScalar(binding.scalarType, binding.scalarName);
    36     }
    37     for (auto binding : internal_scalars) {
    38         addScalar(binding.scalarType, binding.scalarName);
    39     }
    40 }
    41 
    42 const std::string init_suffix = "_Init";
    43 const std::string doBlock_suffix = "_DoBlock";
    44 const std::string finalBlock_suffix = "_FinalBlock";
    45 const std::string accumulator_infix = "_get_";
    46 
    47 
    48 void KernelInterface::addScalar(Type * t, std::string scalarName) {
    49     if (LLVM_UNLIKELY(mKernelStateType != nullptr)) {
    50         throw std::runtime_error("Illegal addition of kernel field after kernel state finalized: " + scalarName);
    51     }
    52     unsigned index = mKernelFields.size();
    53     mKernelFields.push_back(t);
    54     mInternalStateNameMap.emplace(scalarName, iBuilder->getInt32(index));
    55 }
    56 
    57 void KernelInterface::finalizeKernelStateType() {
    58     mKernelStateType = StructType::create(getGlobalContext(), mKernelFields, mKernelName);
    59 }
    60 
    61 void KernelInterface::addKernelDeclarations(Module * client) {
    62     finalizeKernelStateType();
    6323    Type * selfType = PointerType::getUnqual(mKernelStateType);
    6424    // Create the accumulator get function prototypes
     
    146106        finalBlockArg->setName(outputSet.ssName);
    147107    }
    148 }
    149 
    150 
    151 std::unique_ptr<Module> KernelInterface::createKernelModule() {
    152     std::unique_ptr<Module> theModule = make_unique<Module>(mKernelName, getGlobalContext());
    153     addKernelDeclarations(theModule.get());
    154    
    155     // Implement the accumulator get functions
    156     for (auto binding : mScalarOutputs) {
    157         auto fnName = mKernelName + "_get_" + binding.scalarName;
    158         Function * accumFn = theModule->getFunction(fnName);
    159         iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "get_" + binding.scalarName, accumFn, 0));
    160         Value * self = &*(accumFn->arg_begin());
    161         Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(binding.scalarName)});
    162         Value * retVal = iBuilder->CreateLoad(ptr);
    163         iBuilder->CreateRet(retVal);
    164     }
    165    
    166     // Implement the initializer function
    167     Function * initFunction = theModule->getFunction(mKernelName + "_Init");
    168     iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "Init_entry", initFunction, 0));
    169    
    170     Function::arg_iterator args = initFunction->arg_begin();
    171     Value * self = &*(args++);
    172     iBuilder->CreateStore(Constant::getNullValue(mKernelStateType), self);
    173     for (auto binding : mScalarInputs) {
    174         Value * parm = &*(args++);
    175         Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(binding.scalarName)});
    176         iBuilder->CreateStore(parm, ptr);
    177     }
    178     iBuilder->CreateRetVoid();
    179     return theModule;
    180 }
    181 
    182 Value * KernelInterface::getScalarIndex(std::string fieldName) {
    183     const auto f = mInternalStateNameMap.find(fieldName);
    184     if (LLVM_UNLIKELY(f == mInternalStateNameMap.end())) {
    185         throw std::runtime_error("Kernel does not contain internal state: " + fieldName);
    186     }
    187     return f->second;
    188 }
    189 
    190 
    191 Value * KernelInterface::getScalarField(Value * self, std::string fieldName) {
    192     Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(fieldName)});
    193     return iBuilder->CreateLoad(ptr);
    194 }
    195 
    196 void KernelInterface::setScalarField(Value * self, std::string fieldName, Value * newFieldVal) {
    197     Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(fieldName)});
    198     iBuilder->CreateStore(newFieldVal, ptr);
    199 }
    200 
    201 
    202 Value * KernelInterface::getParameter(Function * f, std::string paramName) {
    203     for (Function::arg_iterator argIter = f->arg_begin(), end = f->arg_end(); argIter != end; argIter++) {
    204         Value * arg = &*argIter;
    205         if (arg->getName() == paramName) return arg;
    206     }
    207     throw std::runtime_error("Method does not have parameter: " + paramName);
     108    iBuilder->setModule(saveModule);
     109    iBuilder->restoreIP(savePoint);
    208110}
    209111
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5053 r5060  
    1212#include <llvm/IR/Type.h>
    1313#include <IDISA/idisa_builder.h>
    14 #include <boost/container/flat_map.hpp>
    1514#include "streamset.h"
    1615
     
    2524};
    2625   
     26const std::string init_suffix = "_Init";
     27const std::string doBlock_suffix = "_DoBlock";
     28const std::string finalBlock_suffix = "_FinalBlock";
     29const std::string accumulator_infix = "_get_";
     30
    2731class KernelInterface {
    28     using NameMap = boost::container::flat_map<std::string, llvm::ConstantInt *>;
    2932
    3033public:
     
    3538                    std::vector<ScalarBinding> scalar_parameters,
    3639                    std::vector<ScalarBinding> scalar_outputs,
    37                     std::vector<ScalarBinding> internal_scalars);
     40                    std::vector<ScalarBinding> internal_scalars) :
     41    iBuilder(builder),
     42    mKernelName(kernelName),
     43    mStreamSetInputs(stream_inputs),
     44    mStreamSetOutputs(stream_outputs),
     45    mScalarInputs(scalar_parameters),
     46    mScalarOutputs(scalar_outputs),
     47    mInternalScalars(internal_scalars),
     48    mKernelStateType(nullptr) {}
    3849   
    39     void finalizeKernelStateType();
    4050   
    4151    // Add ExternalLinkage method declarations for the kernel to a given client module.
    4252    void addKernelDeclarations(Module * client);
    43    
    44     // Create a module for the kernel, including the kernel state type and
    45     // all required methods.  The init and accumulator output methods will be
    46     // defined, while the doBlock and finalBlock methods will initially be empty.
    47     //
    48     virtual std::unique_ptr<llvm::Module> createKernelModule();
    4953   
    5054    llvm::Value * createInstance(std::vector<llvm::Value *> initialParameters);
     
    5357    llvm::Value * createGetAccumulatorCall(llvm::Value * kernelInstance, std::string accumName);
    5458   
     59protected:
    5560   
    56 protected:
    57     // Add an additional scalar field to the KernelState struct.
    58     // Must occur before any call to addKernelDeclarations or createKernelModule.
    59     void addScalar(llvm::Type * t, std::string scalarName);
    60    
    61     // Run-time access of Kernel State and parameters of methods for
    62     // use in implementing kernels.
    63    
    64     // Get the index of a named scalar field within the kernel state struct.
    65     llvm::Value * getScalarIndex(std::string);
    66    
    67     // Get the value of a scalar field for a given instance.
    68     llvm::Value * getScalarField(llvm::Value * self, std::string fieldName);
    69    
    70     // Set the value of a scalar field for a given instance.
    71     void setScalarField(llvm::Value * self, std::string fieldName, llvm::Value * newFieldVal);
    72    
    73     // Get a parameter by name.
    74     llvm::Value * getParameter(llvm::Function * f, std::string paramName);
    75 
    76 
    7761    IDISA::IDISA_Builder * iBuilder;
    7862    std::string mKernelName;
    7963    std::vector<StreamSetBinding> mStreamSetInputs;
    8064    std::vector<StreamSetBinding> mStreamSetOutputs;
    81    
    8265    std::vector<ScalarBinding> mScalarInputs;
    8366    std::vector<ScalarBinding> mScalarOutputs;
    8467    std::vector<ScalarBinding> mInternalScalars;
    85 
    86     std::vector<llvm::Type *>  mKernelFields;
    87     llvm::Type *               mKernelStateType;
    88     NameMap                    mInternalStateNameMap;
     68    llvm::Type * mKernelStateType;
    8969};
    9070
Note: See TracChangeset for help on using the changeset viewer.