source: icGREP/icgrep-devel/icgrep/kernels/kernel.h @ 5261

Last change on this file since 5261 was 5261, checked in by cameron, 2 years ago

Move responsibility for ProducedItemCount? into doSegment unless overridden

File size: 8.7 KB
RevLine 
[4924]1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
[5063]6#ifndef KERNEL_BUILDER_H
7#define KERNEL_BUILDER_H
8
[5260]9#include <string>           // for string
10#include <memory>           // for unique_ptr
11#include "interface.h"      // for KernelInterface
12#include <boost/container/flat_map.hpp>
[5238]13#include <IR_Gen/idisa_builder.h>
[5260]14namespace llvm { class ConstantInt; }
15namespace llvm { class Function; }
16namespace llvm { class IntegerType; }
17namespace llvm { class LoadInst; }
18namespace llvm { class Type; }
19namespace llvm { class Value; }
20namespace parabix { class StreamSetBuffer; }
[4924]21
[5086]22const std::string blockNoScalar = "blockNo";
[5174]23const std::string logicalSegmentNoScalar = "logicalSegNo";
[5247]24const std::string processedItemCountSuffix = "_processedItemCount";
25const std::string producedItemCountSuffix = "_producedItemCount";
[5174]26const std::string terminationSignal = "terminationSignal";
[5185]27const std::string structPtrSuffix = "_structPtr";
[5086]28const std::string blkMaskSuffix = "_blkMask";
[4924]29
[4974]30namespace kernel {
[5051]31   
[5063]32class KernelBuilder : public KernelInterface {
[5104]33    using NameMap = boost::container::flat_map<std::string, unsigned>;
[4924]34public:
[5051]35   
[5074]36    // Create a module for the kernel, including the kernel state type declaration and
37    // the full implementation of all required methods.     
38    //
[5260]39    std::unique_ptr<llvm::Module> createKernelModule(const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs);
[5051]40   
[5074]41    // Generate the Kernel to the current module (iBuilder->getModule()).
[5260]42    void generateKernel(const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs);
[5051]43   
[5220]44    void createInstance() override;
[5135]45
[5260]46    llvm::Function * generateThreadFunction(const std::string & name) const;
[5165]47
[5260]48    llvm::Value * getBlockNo(llvm::Value * self) const;
49    virtual llvm::Value * getProcessedItemCount(llvm::Value * self, const std::string & ssName) const override;
50    virtual llvm::Value * getProducedItemCount(llvm::Value * self, const std::string & ssName) const override;
[5252]51   
52    bool hasNoTerminateAttribute() { return mNoTerminateAttribute;}
53   
[5260]54    llvm::Value * getTerminationSignal(llvm::Value * self) const override;
[5133]55   
[5260]56    inline llvm::IntegerType * getSizeTy() const {
[5217]57        return getBuilder()->getSizeTy();
58    }
[5202]59
[5260]60    inline llvm::Type * getStreamTy(const unsigned FieldWidth = 1) {
[5229]61        return getBuilder()->getStreamTy(FieldWidth);
62    }
63   
[5260]64    inline llvm::Type * getStreamSetTy(const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
[5217]65        return getBuilder()->getStreamSetTy(NumElements, FieldWidth);
66    }
[5224]67   
68    // Synchronization actions for executing a kernel for a particular logical segment.
69    //
70    // Before the segment is processed, acquireLogicalSegmentNo must be used to load
71    // the segment number of the kernel state to ensure that the previous segment is
72    // complete (by checking that the acquired segment number is equal to the desired segment
73    // number).
74    // After all segment processing actions for the kernel are complete, and any necessary
75    // data has been extracted from the kernel for further pipeline processing, the
76    // segment number must be incremented and stored using releaseLogicalSegmentNo.
[5260]77    llvm::LoadInst * acquireLogicalSegmentNo(llvm::Value * self) const;
[5217]78
[5260]79    void releaseLogicalSegmentNo(llvm::Value * self, llvm::Value * newFieldVal) const;
[5224]80
[5246]81    virtual ~KernelBuilder() = 0;
[5251]82   
[5260]83    const std::vector<const parabix::StreamSetBuffer *> & getStreamSetInputBuffers() const { return mStreamSetInputBuffers; }
[5246]84
[5260]85    const std::vector<const parabix::StreamSetBuffer *> & getStreamSetOutputBuffers() const { return mStreamSetOutputBuffers; }
[5251]86
[5260]87
[5097]88protected:
[5246]89
90    // Constructor
91    KernelBuilder(IDISA::IDISA_Builder * builder,
92                    std::string kernelName,
93                    std::vector<Binding> stream_inputs,
94                    std::vector<Binding> stream_outputs,
95                    std::vector<Binding> scalar_parameters,
96                    std::vector<Binding> scalar_outputs,
97                    std::vector<Binding> internal_scalars);
98
[5063]99    //
[5074]100    // Kernel builder subtypes define their logic of kernel construction
101    // in terms of 3 virtual methods for
102    // (a) preparing the Kernel state data structure
103    // (b) defining the logic of the doBlock function, and
104    // (c) defining the logic of the finalBlock function.
105    //
106    // Note: the kernel state data structure must only be finalized after
107    // all scalar fields have been added.   If there are no fields to
108    // be added, the default method for preparing kernel state may be used.
[5051]109   
[5252]110    void setNoTerminateAttribute(bool noTerminate = true) {mNoTerminateAttribute = noTerminate;}
[5261]111    void setDoBlockUpdatesProducedItemCountsAttribute(bool doesUpdate = true) {mDoBlockUpdatesProducedItemCountsAttribute = doesUpdate;}
[5252]112   
[5076]113    virtual void prepareKernel();
[5063]114   
[5074]115    // Each kernel builder subtype must provide its own logic for generating
116    // doBlock calls.
[5246]117    virtual void generateDoBlockMethod() const = 0;
[5174]118
[5260]119    virtual void generateDoBlockLogic(llvm::Value * self, llvm::Value * blockNo) const;
[5246]120
[5074]121    // Each kernel builder subtypre must also specify the logic for processing the
122    // final block of stream data, if there is any special processing required
123    // beyond simply calling the doBlock function.   In the case that the final block
124    // processing may be trivially implemented by dispatching to the doBlock method
125    // without additional preparation, the default generateFinalBlockMethod need
126    // not be overridden.
127   
[5246]128    virtual void generateFinalBlockMethod() const;
[5250]129   
130    virtual void generateInitMethod() const;
131   
[5246]132    virtual void generateDoSegmentMethod() const;
[5074]133   
[5257]134    virtual void generateFinalSegmentMethod() const;
135   
[5074]136    // Add an additional scalar field to the KernelState struct.
137    // Must occur before any call to addKernelDeclarations or createKernelModule.
[5260]138    unsigned addScalar(llvm::Type * type, const std::string & name);
[5227]139
140    unsigned getScalarCount() const;
141
[5063]142    // Run-time access of Kernel State and parameters of methods for
143    // use in implementing kernels.
144   
145    // Get the index of a named scalar field within the kernel state struct.
[5260]146    llvm::ConstantInt * getScalarIndex(const std::string & name) const;
[5063]147   
148    // Get the value of a scalar field for a given instance.
[5260]149    llvm::Value * getScalarField(llvm::Value * self, const std::string & fieldName) const;
[5202]150
[5063]151    // Set the value of a scalar field for a given instance.
[5260]152    void setScalarField(llvm::Value * self, const std::string & fieldName, llvm::Value * newFieldVal) const;
[5063]153   
154    // Get a parameter by name.
[5260]155    llvm::Value * getParameter(llvm::Function * f, const std::string & paramName) const;
[5246]156
[5260]157    llvm::Value * getStream(llvm::Value * self, const std::string & name, llvm::Value * blockNo, llvm::Value * index) const;
[5246]158
[5260]159    llvm::Value * getStream(llvm::Value * self, const std::string & name, llvm::Value * blockNo, llvm::Value * index1, llvm::Value * index2) const;
160
161    llvm::Value * getStreamView(llvm::Value * self, const std::string & name, llvm::Value * blockNo, llvm::Value * index) const;
162
163    llvm::Value * getStreamView(llvm::Type * type, llvm::Value * self, const std::string & name, llvm::Value * blockNo, llvm::Value * index) const;
164
[5104]165    // Stream set helpers.
[5246]166    unsigned getStreamSetIndex(const std::string & name) const;
[5104]167   
[5260]168    llvm::Value * getScalarFieldPtr(llvm::Value * self, const std::string & name) const;
[5109]169
[5260]170    llvm::Value * getStreamSetStructPtr(llvm::Value * self, const std::string & name) const;
[5202]171
[5260]172    llvm::Value * getStreamSetPtr(llvm::Value * self, const std::string & name, llvm::Value * blockNo) const;
[5194]173   
[5260]174    void setBlockNo(llvm::Value * self, llvm::Value * value) const;
[5194]175
[5260]176    virtual void setProcessedItemCount(llvm::Value * self, const std::string & ssName, llvm::Value * newFieldVal) const;
[5246]177
[5260]178    virtual void setProducedItemCount(llvm::Value * self, const std::string & ssName, llvm::Value * newFieldVal) const;
[5246]179
[5260]180    void setTerminationSignal(llvm::Value * self) const;
[5246]181
[5260]182private:
183
184    const parabix::StreamSetBuffer * getStreamSetBuffer(const std::string & name) const;
185
[5097]186protected:
[4959]187
[5260]188    std::vector<llvm::Type *>                       mKernelFields;
189    NameMap                                         mKernelMap;
190    NameMap                                         mStreamSetNameMap;
191    std::vector<const parabix::StreamSetBuffer *>   mStreamSetInputBuffers;
192    std::vector<const parabix::StreamSetBuffer *>   mStreamSetOutputBuffers;
193    bool                                            mNoTerminateAttribute;
[5261]194    bool                                            mDoBlockUpdatesProducedItemCountsAttribute;
[5133]195
[4924]196};
[4959]197}
[5063]198#endif
Note: See TracBrowser for help on using the repository browser.