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

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

MaxReferenceItems? for MaxRatio?

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