Ignore:
Timestamp:
Jun 19, 2016, 3:00:47 PM (3 years ago)
Author:
cameron
Message:

New kernel infrastructure

File:
1 edited

Legend:

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

    r5051 r5063  
    1 #ifndef KERNEL_H
    2 #define KERNEL_H
    31/*
    42 *  Copyright (c) 2016 International Characters.
     
    64 */
    75
    8 #include <string>
     6#ifndef KERNEL_BUILDER_H
     7#define KERNEL_BUILDER_H
     8
     9
     10#include "interface.h"
    911#include <vector>
     12#include <llvm/IR/Type.h>
     13#include <IDISA/idisa_builder.h>
    1014#include <boost/container/flat_map.hpp>
    11 #include <IDISA/idisa_builder.h>
    1215
    13 namespace llvm {
    14     class Value;
    15     class Module;
    16     class ExecutionEngine;
    17     class VectorType;
    18     class PointerType;
    19     class Constant;
    20     class FunctionType;
    21     class Function;
    22     class BasicBlock;
    23     class Type;
    24 }
    25 
    26 namespace pablo {
    27     class PabloAST;
    28     class PabloFunction;
    29 }
    30 
    31 template<typename T>
    32 struct disable_implicit_conversion {
    33     inline disable_implicit_conversion(T const value) : _value(value) { assert(_value); }
    34     inline disable_implicit_conversion(std::nullptr_t) = delete;
    35     inline disable_implicit_conversion(unsigned) = delete;
    36     operator T() const { return _value; }
    37     T operator-> () const { return _value; }
    38     T get() const { return _value; }
    39 private:
    40     T const  _value;
    41 };
    4216
    4317namespace kernel {
    44     struct ParameterBinding {
    45         llvm::Type * parameterType;
    46         std::string parameterName;
    47     };
    4818   
     19class KernelBuilder : public KernelInterface {
     20    using NameMap = boost::container::flat_map<std::string, llvm::ConstantInt *>;
     21
     22public:
     23    KernelBuilder(IDISA::IDISA_Builder * builder,
     24                    std::string kernelName,
     25                    std::vector<StreamSetBinding> stream_inputs,
     26                    std::vector<StreamSetBinding> stream_outputs,
     27                    std::vector<ScalarBinding> scalar_parameters,
     28                    std::vector<ScalarBinding> scalar_outputs,
     29                    std::vector<ScalarBinding> internal_scalars);
    4930   
     31    // Add an additional scalar field to the KernelState struct.
     32    // Must occur before any call to addKernelDeclarations or createKernelModule.
     33    void addScalar(llvm::Type * t, std::string scalarName);
    5034   
    51 class Instance;
    52 
    53 class KernelBuilder {
    54     friend class Instance;
    55     friend llvm::Function * generateScanWordRoutine(llvm::Module *, IDISA::IDISA_Builder *, unsigned, KernelBuilder *, bool);
    56     using InputStreamMap = boost::container::flat_map<unsigned, llvm::Value *>;
    57     using NameMap = boost::container::flat_map<std::string, llvm::ConstantInt *>;
    58 public:
    59 
    60     KernelBuilder(IDISA::IDISA_Builder * builder, std::string && name, const unsigned defaultBufferSize);
    61 
     35    void finalizeKernelStateType();
    6236   
    63     void setInstanceParameters(std::vector<ParameterBinding> binding);
    64 
    65     unsigned addInternalState(llvm::Type * const type);
    66     unsigned addInternalState(llvm::Type * const type, std::string name);
    67 
    68     void addInputStream(const unsigned fields);
    69     void addInputStream(const unsigned fields, std::string && name);
    70 
    71     unsigned addOutputStream(const unsigned fields);
    72 
     37    // Create a module for the kernel, including the kernel state type and
     38    // all required methods.  The init and accumulator output methods will be
     39    // defined, while the doBlock and finalBlock methods will initially be empty.
     40    //
     41    virtual std::unique_ptr<llvm::Module> createKernelModule();
    7342   
     43    // Generate Kernel to the current module.
     44    virtual void generateKernel();
    7445   
    75     llvm::Function * createInitMethod();
    76 
     46    // Add a FinalBlock method that simply calls DoBlock without additional
     47    // preparation.
     48    void addTrivialFinalBlockMethod(Module * m);
    7749   
    78     inline llvm::Function * prepareFunction() {
    79         return prepareFunction({0});
    80     }
    81 
    82     llvm::Function * prepareFunction(std::vector<unsigned> && inputStreamOffsets);
    83 
    84     inline llvm::Value * getInternalState(const std::string & name) {
    85         return getInternalStateInternal(mKernelStateParam, name);
    86     }
    87 
    88     inline void setInternalState(const std::string & name, llvm::Value * value) {
    89         setInternalStateInternal(mKernelStateParam, name, value);
    90     }
    91 
    92     inline llvm::Value * getInternalState(const unsigned index) {
    93         assert (index < mInternalState.size());
    94         return getInternalStateInternal(mKernelStateParam, iBuilder->getInt32(index));
    95     }
    96 
    97     inline llvm::Value * getInternalState(disable_implicit_conversion<llvm::Value *> const index) {
    98         return getInternalStateInternal(mKernelStateParam, index);
    99     }
    100 
    101     void setInternalState(const unsigned index, llvm::Value * value) {
    102         assert (index < mInternalState.size());
    103         setInternalStateInternal(mKernelStateParam, iBuilder->getInt32(index), value);
    104     }
    105 
    106     void setInternalState(disable_implicit_conversion<llvm::Value *> const index, llvm::Value * value) {
    107         setInternalStateInternal(mKernelStateParam, index, value);
    108     }
    109 
    110     inline llvm::Type * getKernelStateType() const{
    111         return mKernelStateType;
    112     }
    113 
    114     inline llvm::Value * getInputStream(const unsigned index, const unsigned streamOffset = 0) {
    115         return getInputStreamInternal(getInputStreamParam(streamOffset), iBuilder->getInt32(index));
    116     }
    117 
    118     inline llvm::Value * getInputStream(disable_implicit_conversion<llvm::Value *> index, const unsigned streamOffset = 0) {
    119         return getInputStreamInternal(getInputStreamParam(streamOffset), index);
    120     }
    121 
    122     inline unsigned getNumOfInputStreams() const {
    123         return mInputStream.size();
    124     }
    125 
    126     inline llvm::Type * getInputStreamType() const {
    127         return mInputStreamType;
    128     }
    129 
    130     inline llvm::Value * getOutputStream(const unsigned index) {
    131         assert (index < getNumOfOutputStreams());
    132         return getOutputStreamInternal(mOutputStreamParam, iBuilder->getInt32(index));
    133     }
    134 
    135     inline llvm::Value * getOutputStream(disable_implicit_conversion<llvm::Value *> const index) {
    136         return getOutputStreamInternal(mOutputStreamParam, index);
    137     }
    138 
    139     inline unsigned getNumOfOutputStreams() const {
    140         return mOutputStream.size();
    141     }
    142 
    143     inline llvm::Type * getOutputStreamType() const {
    144         return mOutputStreamType;
    145     }
    146 
    147     inline llvm::Value * getBlockNo() {
    148         return getBlockNoInternal(mKernelStateParam);
    149     }
    150 
    151     unsigned getDefaultBufferSize() const;
    152 
    153     void finalize();
    154 
    155     kernel::Instance * instantiate(std::pair<llvm::Value *, unsigned> && inputStreamSet) {
    156         return instantiate(std::move(inputStreamSet), getDefaultBufferSize());
    157     }
    158 
    159     kernel::Instance * instantiate(std::pair<llvm::Value *, unsigned> && inputStreamSet, const unsigned outputBufferSize);
    160 
    161     kernel::Instance * instantiate(llvm::Value * const inputStream) {
    162         return instantiate(std::make_pair(inputStream, 0));
    163     }
    164 
    165     kernel::Instance * instantiate(std::initializer_list<llvm::Value *> inputStreams);
    166 
    167     llvm::Value * getKernelState() const;
    168 
    169     llvm::Function * getDoBlockFunction() const;
     50    // Run-time access of Kernel State and parameters of methods for
     51    // use in implementing kernels.
     52   
     53    // Get the index of a named scalar field within the kernel state struct.
     54    llvm::Value * getScalarIndex(std::string);
     55   
     56    // Get the value of a scalar field for a given instance.
     57    llvm::Value * getScalarField(llvm::Value * self, std::string fieldName);
     58   
     59    // Set the value of a scalar field for a given instance.
     60    void setScalarField(llvm::Value * self, std::string fieldName, llvm::Value * newFieldVal);
     61   
     62    // Get a parameter by name.
     63    llvm::Value * getParameter(llvm::Function * f, std::string paramName);
    17064
    17165protected:
    17266
    173     Type * packDataTypes(const std::vector<llvm::Type *> & types);
    174 
    175     llvm::Value * getInputStreamInternal(llvm::Value * const inputStreamSet, disable_implicit_conversion<llvm::Value *> index);
    176 
    177     llvm::Value * getInternalStateInternal(llvm::Value * const kernelState, const std::string & name);
    178 
    179     void setInternalStateInternal(llvm::Value * const kernelState, const std::string & name, llvm::Value * const value);
    180 
    181     llvm::Value * getInternalStateInternal(llvm::Value * const kernelState, disable_implicit_conversion<llvm::Value *> index);
    182 
    183     void setInternalStateInternal(llvm::Value * const kernelState, const unsigned index, llvm::Value * const value);
    184 
    185     void setInternalStateInternal(llvm::Value * const kernelState, disable_implicit_conversion<llvm::Value *> index, llvm::Value * const value);
    186 
    187     llvm::Value * getOutputStreamInternal(llvm::Value * const outputStreamSet, disable_implicit_conversion<llvm::Value *> index);
    188 
    189     llvm::Value * getBlockNoInternal(llvm::Value * const instance) {
    190         return getInternalStateInternal(instance, mBlockNoIndex);
    191     }
    192 
    193     llvm::Function * getOutputStreamSetFunction() const;
    194 
    195     llvm::Value * getInputStreamParam(const unsigned streamOffset) const;
    196 
    197     const std::vector<unsigned> & getInputStreamOffsets() const {
    198         return mInputStreamOffsets;
    199     }
    200 
    201 private:
    202 
    203     IDISA::IDISA_Builder * const        iBuilder;
    204     const std::string                   mKernelName;
    205     unsigned                            mDefaultBufferSize;
    206 
    207     llvm::Type *                        mBitBlockType;
    208     llvm::ConstantInt *                 mBlockNoIndex;
    209     llvm::Function *                                    mConstructor;
    210     llvm::Function *                                    mDoBlock;
    211 
    212     std::vector<ParameterBinding>           mInstanceParameters;
    213     unsigned                            mInstanceParametersOffset;
    214    
    215     llvm::Type *                        mKernelStateType;
    216     llvm::Type *                        mInputStreamType;
    217     llvm::Type *                        mOutputStreamType;
    218 
    219     llvm::Value *                       mKernelStateParam;
    220     InputStreamMap                      mInputStreamParam;
    221     llvm::Value *                       mOutputStreamParam;
    222 
    223     std::vector<std::string>            mInputScalarName;   
    224     std::vector<llvm::Type *>           mInputStream;
    225     std::vector<std::string>            mInputStreamName;
    226     std::vector<unsigned>               mInputStreamOffsets;
    227     std::vector<llvm::Type *>           mOutputStream;
    228     std::vector<llvm::Type *>                   mInternalState;
    229     NameMap                             mInternalStateNameMap;
     67    std::vector<llvm::Type *>  mKernelFields;
     68    NameMap                    mInternalStateNameMap;
    23069};
    231 
    232 inline llvm::Function * KernelBuilder::getDoBlockFunction() const {
    233     return mDoBlock;
    23470}
    235 
    236 inline llvm::Value * KernelBuilder::getKernelState() const {
    237     return mKernelStateParam;
    238 }
    239 
    240 inline unsigned KernelBuilder::getDefaultBufferSize() const {
    241     return mDefaultBufferSize;
    242 }
    243    
    244 llvm::Value * make_New(IDISA::IDISA_Builder * iBuilder, std::string kernel_name, std::vector<Value *> args);
    245 
    246     llvm::Value * make_DoBlock_Call(IDISA::IDISA_Builder * iBuilder, std::string kernel_name, std::vector<Value *> args);
    247     llvm::Value * make_FinalBlock_Call(IDISA::IDISA_Builder * iBuilder, std::string kernel_name, std::vector<Value *> args);
    248    
    249 } // end of namespace kernel
    250 
    251 #endif // KERNEL_H
     71#endif
Note: See TracChangeset for help on using the changeset viewer.