Ignore:
Timestamp:
Oct 25, 2017, 4:57:58 PM (19 months ago)
Author:
nmedfort
Message:

First stage of MultiBlockKernel? and pipeline restructuring

File:
1 edited

Legend:

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

    r5630 r5706  
    99#include "interface.h"
    1010#include <boost/container/flat_map.hpp>
    11 #include <llvm/IR/Constants.h>
    12 
     11
     12namespace llvm { class BasicBlock; }
    1313namespace llvm { class Function; }
    1414namespace llvm { class IntegerType; }
     
    2828public:
    2929    enum class Port { Input, Output };
    30 protected:
     30
     31    using StreamPort = std::pair<Port, unsigned>;
     32
     33protected:
     34
    3135    using KernelMap = boost::container::flat_map<std::string, unsigned>;
    32     using StreamPort = std::pair<Port, unsigned>;
    3336    using StreamMap = boost::container::flat_map<std::string, StreamPort>;
    3437    using StreamSetBuffers = std::vector<parabix::StreamSetBuffer *>;
     
    4548    static const std::string BUFFER_PTR_SUFFIX;
    4649    static const std::string CONSUMER_SUFFIX;
    47 public:
    4850    static const std::string CYCLECOUNT_SCALAR;
    4951
     
    7476    // guaranteeing uniqueness.  In this case, hasSignature() should return false.
    7577    //
     78
     79    //
     80    // Kernel builder subtypes define their logic of kernel construction
     81    // in terms of 3 virtual methods for
     82    // (a) preparing the Kernel state data structure
     83    // (c) defining the logic of the finalBlock function.
     84    //
     85    // Note: the kernel state data structure must only be finalized after
     86    // all scalar fields have been added.   If there are no fields to
     87    // be added, the default method for preparing kernel state may be used.
     88
    7689       
    7790    bool isCachable() const override { return false; }
     
    131144    //
    132145   
    133     unsigned getKernelStride() const { return mStride;}
    134    
    135     void setKernelStride(unsigned stride) {mStride = stride;}
     146    unsigned getKernelStride() const { return mStride; }
    136147   
    137148    virtual ~Kernel() = 0;
     
    145156protected:
    146157
     158    void setKernelStride(unsigned stride) { mStride = stride; }
     159
    147160    virtual void addInternalKernelProperties(const std::unique_ptr<KernelBuilder> & idb) { }
     161
     162    void getDoSegmentFunctionArguments(const std::vector<llvm::Value *> & availItems) const;
    148163
    149164    // Constructor
     
    155170                  std::vector<Binding> && internal_scalars);
    156171
    157     //
    158     // Kernel builder subtypes define their logic of kernel construction
    159     // in terms of 3 virtual methods for
    160     // (a) preparing the Kernel state data structure
    161     // (c) defining the logic of the finalBlock function.
    162     //
    163     // Note: the kernel state data structure must only be finalized after
    164     // all scalar fields have been added.   If there are no fields to
    165     // be added, the default method for preparing kernel state may be used.
    166 
    167172    void setNoTerminateAttribute(const bool noTerminate = true) {
    168173        mNoTerminateAttribute = noTerminate;
    169174    }
    170175
     176    llvm::Value * getPrincipleItemCount() const {
     177        return mAvailablePrincipleItemCount;
     178    }
     179
    171180    unsigned getScalarIndex(const std::string & name) const;
    172181
    173182    void prepareStreamSetNameMap();
    174183   
    175     void processingRateAnalysis();
    176 
    177184    void linkExternalMethods(const std::unique_ptr<kernel::KernelBuilder> &) override { }
    178185
    179186    virtual void generateInitializeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) { }
    180187   
    181     virtual void generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & iBuilder) = 0;
     188    virtual void generateKernelMethod(const std::unique_ptr<KernelBuilder> & iBuilder) = 0;
    182189
    183190    virtual void generateFinalizeMethod(const std::unique_ptr<KernelBuilder> & iBuilder) { }
     
    189196    unsigned addUnnamedScalar(llvm::Type * type);
    190197
    191     llvm::Value * getIsFinal() const {
    192         return mIsFinal;
    193     }
    194 
    195198    void callGenerateInitializeMethod(const std::unique_ptr<KernelBuilder> & idb);
    196199
     
    198201
    199202    void callGenerateFinalizeMethod(const std::unique_ptr<KernelBuilder> & idb);
     203
     204
     205    std::pair<unsigned, unsigned> getStreamRate(const Port p, const unsigned i) const;
    200206
    201207    const parabix::StreamSetBuffer * getInputStreamSetBuffer(const std::string & name) const {
     
    229235    }
    230236
     237    llvm::Value * getStreamSetInputBufferPtr(const unsigned i) const {
     238        return mStreamSetInputBufferPtr[i];
     239    }
     240
     241    llvm::Value * getStreamSetOutputBufferPtr(const unsigned i) const {
     242        return mStreamSetOutputBufferPtr[i];
     243    }
     244
    231245private:
     246
     247    void addBaseKernelProperties(const std::unique_ptr<KernelBuilder> & idb);
    232248
    233249    llvm::Value * getAvailableItemCount(const unsigned i) const {
     
    238254
    239255    llvm::Function *                    mCurrentMethod;
     256    llvm::Value *                       mAvailablePrincipleItemCount;
    240257    bool                                mNoTerminateAttribute;
    241258    bool                                mIsGenerated;
    242 
     259    unsigned                            mStride;
    243260    llvm::Value *                       mIsFinal;
     261    llvm::Value *                       mOutputScalarResult;
     262
     263
    244264    std::vector<llvm::Value *>          mAvailableItemCount;
    245     llvm::Value *                       mOutputScalarResult;
    246265
    247266    std::vector<llvm::Type *>           mKernelFields;
     
    249268    StreamMap                           mStreamMap;
    250269    StreamSetBuffers                    mStreamSetInputBuffers;
     270    std::vector<llvm::Value *>          mStreamSetInputBufferPtr;
    251271    StreamSetBuffers                    mStreamSetOutputBuffers;
    252     unsigned                            mStride;
    253     std::vector<unsigned>               mItemsPerStride;
    254     std::vector<unsigned>               mIsDerived;
     272    std::vector<llvm::Value *>          mStreamSetOutputBufferPtr;
    255273
    256274};
     
    265283                          std::vector<Binding> && scalar_outputs,
    266284                          std::vector<Binding> && internal_scalars);
    267 
    268 };
    269 
    270 class BlockOrientedKernel : public Kernel {
    271 protected:
    272 
    273     void CreateDoBlockMethodCall(const std::unique_ptr<KernelBuilder> & idb);
    274 
    275     // Each kernel builder subtype must provide its own logic for generating
    276     // doBlock calls.
    277     virtual void generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & idb) = 0;
    278 
    279     // Each kernel builder subtypre must also specify the logic for processing the
    280     // final block of stream data, if there is any special processing required
    281     // beyond simply calling the doBlock function.   In the case that the final block
    282     // processing may be trivially implemented by dispatching to the doBlock method
    283     // without additional preparation, the default generateFinalBlockMethod need
    284     // not be overridden.
    285 
    286     virtual void generateFinalBlockMethod(const std::unique_ptr<KernelBuilder> & idb, llvm::Value * remainingItems);
    287 
    288     void generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & idb) final;
    289 
    290     BlockOrientedKernel(std::string && kernelName,
    291                         std::vector<Binding> && stream_inputs,
    292                         std::vector<Binding> && stream_outputs,
    293                         std::vector<Binding> && scalar_parameters,
    294                         std::vector<Binding> && scalar_outputs,
    295                         std::vector<Binding> && internal_scalars);
    296 
    297 private:
    298 
    299     void writeDoBlockMethod(const std::unique_ptr<KernelBuilder> & idb);
    300 
    301     void writeFinalBlockMethod(const std::unique_ptr<KernelBuilder> & idb, llvm::Value * remainingItems);
    302 
    303 private:
    304 
    305     llvm::Function *        mDoBlockMethod;
    306     llvm::BasicBlock *      mStrideLoopBody;
    307     llvm::IndirectBrInst *  mStrideLoopBranch;
    308     llvm::PHINode *         mStrideLoopTarget;
     285protected:
     286
     287    void generateKernelMethod(const std::unique_ptr<KernelBuilder> & b) final;
     288
     289    virtual void generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & kb) = 0;
     290
    309291};
    310292
     
    417399    // exit the RetVoid instruction will be added to complete the method.
    418400    //
    419     virtual void generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & idb) = 0;
    420    
     401    virtual void generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & idb, llvm::Value * const numOfStrides) = 0;
     402
    421403private:
     404
    422405    // Given a kernel subtype with an appropriate interface, the generateDoSegment
    423406    // method of the multi-block kernel builder makes all the necessary arrangements
    424407    // to translate doSegment calls into a minimal sequence of doMultiBlock calls.
    425     void generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & kb) final;
     408    void generateKernelMethod(const std::unique_ptr<KernelBuilder> & kb) final;
     409
     410    bool requiresCopyBack(const ProcessingRate & rate) const;
    426411
    427412};
    428413
    429 void applyOutputBufferExpansions(const std::unique_ptr<KernelBuilder> & kb,
    430                                  std::vector<llvm::Value *> inputAvailable,
    431                                  llvm::Value * doFinal);
    432    
    433    
     414
     415class BlockOrientedKernel : public MultiBlockKernel {
     416protected:
     417
     418    void CreateDoBlockMethodCall(const std::unique_ptr<KernelBuilder> & idb);
     419
     420    // Each kernel builder subtype must provide its own logic for generating
     421    // doBlock calls.
     422    virtual void generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & idb) = 0;
     423
     424    // Each kernel builder subtypre must also specify the logic for processing the
     425    // final block of stream data, if there is any special processing required
     426    // beyond simply calling the doBlock function.   In the case that the final block
     427    // processing may be trivially implemented by dispatching to the doBlock method
     428    // without additional preparation, the default generateFinalBlockMethod need
     429    // not be overridden.
     430
     431    virtual void generateFinalBlockMethod(const std::unique_ptr<KernelBuilder> & idb, llvm::Value * remainingItems);
     432
     433    void generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & idb, llvm::Value * const numOfStrides) final;
     434
     435    BlockOrientedKernel(std::string && kernelName,
     436                        std::vector<Binding> && stream_inputs,
     437                        std::vector<Binding> && stream_outputs,
     438                        std::vector<Binding> && scalar_parameters,
     439                        std::vector<Binding> && scalar_outputs,
     440                        std::vector<Binding> && internal_scalars);
     441
     442private:
     443
     444    void writeDoBlockMethod(const std::unique_ptr<KernelBuilder> & idb);
     445
     446    void writeFinalBlockMethod(const std::unique_ptr<KernelBuilder> & idb, llvm::Value * remainingItems);
     447
     448private:
     449
     450    llvm::Function *        mDoBlockMethod;
     451    llvm::BasicBlock *      mStrideLoopBody;
     452    llvm::IndirectBrInst *  mStrideLoopBranch;
     453    llvm::PHINode *         mStrideLoopTarget;
     454};
    434455
    435456}
     457
    436458#endif
Note: See TracChangeset for help on using the changeset viewer.