source: icGREP/icgrep-devel/icgrep/kernels/interface.h @ 5438

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

static ratio calculations

File size: 8.9 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#ifndef KERNEL_INTERFACE_H
7#define KERNEL_INTERFACE_H
8
9#include <llvm/IR/Constants.h>
10#include <string>
11#include <vector>
12
13namespace IDISA { class IDISA_Builder; }
14namespace kernel { class KernelBuilder; }
15
16// Processing rate attributes are required for all stream set bindings for a kernel.
17// These attributes describe the number of items that are processed or produced as
18// a ratio in comparison to a reference stream set, normally the principal input stream set
19// by default (or the principal output stream set if there is no input).
20//
21// The default ratio is FixedRatio(1) which means that there is one item processed or
22// produced for every item of the reference stream.
23// FixedRatio(m, n) means that for every group of n items of the refrence stream,
24// there are m items in the output stream (rounding up).
25//
26// Kernels which produce a variable number of items use MaxRatio(n), for a maximum
27// of n items produced or consumed per principal input or output item.  MaxRatio(m, n)
28// means there are at most m items for every n items of the reference stream.
29//
30// RoundUpToMultiple(n) means that number of items produced is the same as the
31// number of reference items, rounded up to an exact multiple of n.
32//
33
34struct ProcessingRate  {
35    enum class ProcessingRateKind : uint8_t { FixedRatio, RoundUp, Add1, MaxRatio, Unknown };
36    ProcessingRateKind getKind() const {return mKind;}
37    bool isFixedRatio() const {return mKind == ProcessingRateKind::FixedRatio;}
38    bool isMaxRatio() const {return mKind == ProcessingRateKind::MaxRatio;}
39    bool isExact() const {return (mKind == ProcessingRateKind::FixedRatio)||(mKind == ProcessingRateKind::RoundUp)||(mKind == ProcessingRateKind::Add1) ;}
40    bool isUnknownRate() const { return mKind == ProcessingRateKind::Unknown; }
41    unsigned calculateRatio(unsigned referenceItems, bool doFinal = false) const;
42    unsigned calculateMaxReferenceItems(unsigned outputItems, bool doFinal = false) const;
43    llvm::Value * CreateRatioCalculation(IDISA::IDISA_Builder * const b, llvm::Value * referenceItems, llvm::Value * doFinal = nullptr) const;
44    llvm::Value * CreateMaxReferenceItemsCalculation(IDISA::IDISA_Builder * const b, llvm::Value * outputItems, llvm::Value * doFinal = nullptr) const;
45    friend ProcessingRate FixedRatio(unsigned strmItems, unsigned referenceItems, std::string && referenceStreamSet);
46    friend ProcessingRate MaxRatio(unsigned strmItems, unsigned referenceItems, std::string && referenceStreamSet);
47    friend ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string && referenceStreamSet);
48    friend ProcessingRate Add1(std::string && referenceStreamSet);
49    friend ProcessingRate UnknownRate();
50    uint16_t getRatioNumerator() const { return mRatioNumerator;}
51    uint16_t getRatioDenominator() const { return mRatioDenominator;}
52    const std::string & referenceStreamSet() const { return mReferenceStreamSet;}
53protected:
54    ProcessingRate(ProcessingRateKind k, unsigned numerator, unsigned denominator, std::string && referenceStreamSet)
55    : mKind(k), mRatioNumerator(numerator), mRatioDenominator(denominator), mReferenceStreamSet(referenceStreamSet) {}
56private:
57    const ProcessingRateKind mKind;
58    const uint16_t mRatioNumerator;
59    const uint16_t mRatioDenominator;
60    const std::string mReferenceStreamSet;
61}; 
62
63ProcessingRate FixedRatio(unsigned strmItems, unsigned referenceItems = 1, std::string && referenceStreamSet = "");
64ProcessingRate MaxRatio(unsigned strmItems, unsigned referenceItems = 1, std::string && referenceStreamSet = "");
65ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string &&referenceStreamSet = "");
66ProcessingRate Add1(std::string && referenceStreamSet = "");
67ProcessingRate UnknownRate();
68
69struct Binding {
70    Binding(llvm::Type * type, const std::string & name, ProcessingRate r = FixedRatio(1))
71    : type(type), name(name), rate(r) { }
72    llvm::Type * const        type;
73    const std::string         name;
74    const ProcessingRate      rate;
75};
76
77class KernelInterface {
78public:
79    /*
80     
81     This class defines the methods to be used to generate the code 
82     necessary for declaring, allocating, calling and synchronizing
83     kernels.   The methods to be used for constructing kernels are defined
84     within the KernelBuilder class of kernel.h
85     
86     */
87   
88    const std::string & getName() const { return mKernelName; }
89
90    void setName(std::string newName) { mKernelName = newName; }
91       
92    virtual bool isCachable() const = 0;
93
94    virtual std::string makeSignature() = 0;
95
96    const std::vector<Binding> & getStreamInputs() const {
97        return mStreamSetInputs;
98    }
99
100    const Binding & getStreamInput(const unsigned i) const {
101        return mStreamSetInputs[i];
102    }
103
104    const std::vector<Binding> & getStreamOutputs() const {
105        return mStreamSetOutputs;
106    }
107
108    const Binding & getStreamOutput(const unsigned i) const {
109        return mStreamSetOutputs[i];
110    }
111
112    const std::vector<Binding> & getScalarInputs() const {
113        return mScalarInputs;
114    }
115
116    const Binding & getScalarInput(const unsigned i) const {
117        return mScalarInputs[i];
118    }
119
120    const std::vector<Binding> & getScalarOutputs() const {
121        return mScalarOutputs;
122    }
123
124    const Binding & getScalarOutput(const unsigned i) const {
125        return mScalarOutputs[i];
126    }
127
128    // Add ExternalLinkage method declarations for the kernel to a given client module.
129    void addKernelDeclarations();
130
131    virtual void linkExternalMethods() = 0;
132
133    virtual llvm::Value * createInstance() = 0;
134
135    virtual void initializeInstance() = 0;
136
137    virtual void finalizeInstance() = 0;
138
139    void setInitialArguments(std::vector<llvm::Value *> && args) {
140        mInitialArguments.swap(args);
141    }
142
143    llvm::Value * getInstance() const {
144        return mKernelInstance;
145    }
146
147    unsigned getLookAhead() const {
148        return mLookAheadPositions;
149    }
150
151    void setLookAhead(const unsigned lookAheadPositions) {
152        mLookAheadPositions = lookAheadPositions;
153    }
154
155    kernel::KernelBuilder * getBuilder() const {
156        return iBuilder;
157    }
158
159    void setBuilder(const std::unique_ptr<kernel::KernelBuilder> & builder) {
160        iBuilder = builder.get();
161    }
162
163protected:
164
165    virtual llvm::Value * getProducedItemCount(const std::string & name, llvm::Value * doFinal = nullptr) const = 0;
166
167    virtual void setProducedItemCount(const std::string & name, llvm::Value * value) const = 0;
168
169    virtual llvm::Value * getProcessedItemCount(const std::string & name) const = 0;
170
171    virtual void setProcessedItemCount(const std::string & name, llvm::Value * value) const = 0;
172
173    virtual llvm::Value * getConsumedItemCount(const std::string & name) const = 0;
174
175    virtual void setConsumedItemCount(const std::string & name, llvm::Value * value) const = 0;
176
177    virtual llvm::Value * getTerminationSignal() const = 0;
178
179    virtual void setTerminationSignal() const = 0;
180
181    llvm::Function * getInitFunction(llvm::Module * const module) const;
182
183    llvm::Function * getDoSegmentFunction(llvm::Module * const module) const;
184
185    llvm::Function * getTerminateFunction(llvm::Module * const module) const;
186
187    KernelInterface(std::string kernelName,
188                    std::vector<Binding> && stream_inputs,
189                    std::vector<Binding> && stream_outputs,
190                    std::vector<Binding> && scalar_inputs,
191                    std::vector<Binding> && scalar_outputs,
192                    std::vector<Binding> && internal_scalars)
193    : iBuilder(nullptr)
194    , mModule(nullptr)
195    , mKernelInstance(nullptr)
196    , mKernelStateType(nullptr)
197    , mLookAheadPositions(0)
198    , mKernelName(kernelName)
199    , mStreamSetInputs(stream_inputs)
200    , mStreamSetOutputs(stream_outputs)
201    , mScalarInputs(scalar_inputs)
202    , mScalarOutputs(scalar_outputs)
203    , mInternalScalars(internal_scalars)
204    {
205
206    }
207   
208    void setInstance(llvm::Value * const instance) {
209        assert ("kernel instance cannot be null!" && instance);
210        assert ("kernel instance must point to a valid kernel state type!" && (instance->getType()->getPointerElementType() == mKernelStateType));
211        mKernelInstance = instance;
212    }
213
214protected:
215   
216    kernel::KernelBuilder *                 iBuilder;
217    llvm::Module *                          mModule;
218
219    llvm::Value *                           mKernelInstance;
220    llvm::StructType *                      mKernelStateType;
221    unsigned                                mLookAheadPositions;
222    std::string                             mKernelName;
223    std::vector<llvm::Value *>              mInitialArguments;
224    std::vector<Binding>                    mStreamSetInputs;
225    std::vector<Binding>                    mStreamSetOutputs;
226    std::vector<Binding>                    mScalarInputs;
227    std::vector<Binding>                    mScalarOutputs;
228    std::vector<Binding>                    mInternalScalars;
229};
230
231#endif
Note: See TracBrowser for help on using the repository browser.