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

Last change on this file since 5682 was 5646, checked in by nmedfort, 22 months ago

Minor clean up. Bug fix for object cache when the same cached kernel is used twice in a single run. Improvement to RE Minimizer.

File size: 8.8 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    virtual bool isCachable() const = 0;
97
98    virtual std::string makeSignature(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
99
100    const std::vector<Binding> & getStreamInputs() const {
101        return mStreamSetInputs;
102    }
103
104    const Binding & getStreamInput(const unsigned i) const {
105        return mStreamSetInputs[i];
106    }
107
108    unsigned getNumOfStreamInputs() const {
109        return mStreamSetInputs.size();
110    }
111
112    const std::vector<Binding> & getStreamOutputs() const {
113        return mStreamSetOutputs;
114    }
115
116    unsigned getNumOfStreamOutputs() const {
117        return mStreamSetOutputs.size();
118    }
119
120    const Binding & getStreamOutput(const unsigned i) const {
121        return mStreamSetOutputs[i];
122    }
123
124    const std::vector<Binding> & getScalarInputs() const {
125        return mScalarInputs;
126    }
127
128    const Binding & getScalarInput(const unsigned i) const {
129        return mScalarInputs[i];
130    }
131
132    const std::vector<Binding> & getScalarOutputs() const {
133        return mScalarOutputs;
134    }
135
136    const Binding & getScalarOutput(const unsigned i) const {
137        return mScalarOutputs[i];
138    }
139
140    // Add ExternalLinkage method declarations for the kernel to a given client module.
141    void addKernelDeclarations(const std::unique_ptr<kernel::KernelBuilder> & idb);
142
143    virtual void linkExternalMethods(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
144
145    virtual llvm::Value * createInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
146
147    virtual void initializeInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
148
149    virtual void finalizeInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
150
151    void setInitialArguments(std::vector<llvm::Value *> && args) {
152        mInitialArguments.swap(args);
153    }
154
155    llvm::Value * getInstance() const {
156        return mKernelInstance;
157    }
158
159    void setInstance(llvm::Value * const instance) {
160        assert ("kernel instance cannot be null!" && instance);
161        assert ("kernel instance must point to a valid kernel state type!" && (instance->getType()->getPointerElementType() == mKernelStateType));
162        mKernelInstance = instance;
163    }
164
165    unsigned getLookAhead(const unsigned i) const {
166        assert (i < mStreamSetInputLookahead.size());
167        return mStreamSetInputLookahead[i];
168    }
169
170    void setLookAhead(const unsigned i, const unsigned lookAheadPositions) {
171        assert (i < mStreamSetInputLookahead.size());
172        mStreamSetInputLookahead[i] = lookAheadPositions;
173    }
174
175protected:
176
177    llvm::Function * getInitFunction(llvm::Module * const module) const;
178
179    llvm::Function * getDoSegmentFunction(llvm::Module * const module) const;
180
181    llvm::Function * getTerminateFunction(llvm::Module * const module) const;
182
183    KernelInterface(const std::string && kernelName,
184                    std::vector<Binding> && stream_inputs,
185                    std::vector<Binding> && stream_outputs,
186                    std::vector<Binding> && scalar_inputs,
187                    std::vector<Binding> && scalar_outputs,
188                    std::vector<Binding> && internal_scalars)
189    : mKernelInstance(nullptr)
190    , mModule(nullptr)
191    , mKernelStateType(nullptr)
192    , mKernelName(kernelName)
193    , mStreamSetInputs(stream_inputs)
194    , mStreamSetInputLookahead(mStreamSetInputs.size(), 0)
195    , mStreamSetOutputs(stream_outputs)
196    , mScalarInputs(scalar_inputs)
197    , mScalarOutputs(scalar_outputs)
198    , mInternalScalars(internal_scalars) {
199
200    }
201   
202protected:
203
204    llvm::Value *                           mKernelInstance;
205    llvm::Module *                          mModule;
206    llvm::StructType *                      mKernelStateType;
207    const std::string                       mKernelName;
208    std::vector<llvm::Value *>              mInitialArguments;
209    std::vector<Binding>                    mStreamSetInputs;
210    std::vector<unsigned>                   mStreamSetInputLookahead;
211    std::vector<Binding>                    mStreamSetOutputs;
212    std::vector<Binding>                    mScalarInputs;
213    std::vector<Binding>                    mScalarOutputs;
214    std::vector<Binding>                    mInternalScalars;
215};
216
217#endif
Note: See TracBrowser for help on using the repository browser.