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

Last change on this file since 6135 was 5985, checked in by nmedfort, 11 months ago

Restructured MultiBlock? kernel. Removal of Swizzled buffers. Inclusion of PopCount? rates / non-linear access. Modifications to several kernels to better align them with the kernel and pipeline changes.

File size: 6.7 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 <kernels/processing_rate.h>
10#include <kernels/attributes.h>
11#include <llvm/Support/Compiler.h>
12#include <memory>
13#include <string>
14#include <vector>
15
16namespace IDISA { class IDISA_Builder; }
17namespace kernel { class Kernel; }
18namespace kernel { class KernelBuilder; }
19namespace llvm { class CallInst; }
20namespace llvm { class Function; }
21namespace llvm { class Value; }
22namespace llvm { class Module; }
23namespace llvm { class StructType; }
24namespace llvm { class Type; }
25
26namespace kernel {
27
28const static std::string LOGICAL_SEGMENT_NO_SCALAR = "segmentNo";
29const static std::string PROCESSED_ITEM_COUNT_SUFFIX = "_processedItemCount";
30const static std::string PRODUCED_ITEM_COUNT_SUFFIX = "_producedItemCount";
31const static std::string CONSUMED_ITEM_COUNT_SUFFIX = "_consumedItemCount";
32const static std::string NON_DEFERRED_ITEM_COUNT_SUFFIX = "_nonDeferredItemCount";
33const static std::string TERMINATION_SIGNAL = "terminationSignal";
34const static std::string BUFFER_SUFFIX = "_buffer";
35const static std::string CONSUMER_SUFFIX = "_consumerLocks";
36const static std::string CYCLECOUNT_SCALAR = "CPUcycles";
37
38struct Binding : public AttributeSet {
39
40    Binding(llvm::Type * type, const std::string & name, ProcessingRate r = FixedRate(1))
41    : AttributeSet()
42    , mType(type), mName(name), mRate(std::move(r)) { }
43
44
45    Binding(llvm::Type * type, const std::string & name, ProcessingRate r, Attribute && attribute)
46    : AttributeSet(std::move(attribute))
47    , mType(type), mName(name), mRate(std::move(r)) { }
48
49
50    Binding(llvm::Type * type, const std::string & name, ProcessingRate r, std::initializer_list<Attribute> attributes)
51    : AttributeSet(attributes)
52    , mType(type), mName(name), mRate(std::move(r)) { }
53
54    llvm::Type * getType() const {
55        return mType;
56    }
57
58    const std::string & getName() const {
59        return mName;
60    }
61
62    const ProcessingRate & getRate() const {
63        return mRate;
64    }
65
66    ProcessingRate & getRate() {
67        return mRate;
68    }
69
70    bool isPrincipal() const {
71        return hasAttribute(AttributeId::Principal);
72    }
73
74    bool hasLookahead() const {
75        return hasAttribute(AttributeId::LookAhead);
76    }
77
78    unsigned const getLookahead() const {
79        return findAttribute(AttributeId::LookAhead).amount();
80    }
81
82    bool isDeferred() const {
83        return hasAttribute(AttributeId::Deferred);
84    }
85
86private:
87    llvm::Type * const          mType;
88    const std::string           mName;
89    ProcessingRate              mRate;
90};
91
92using Bindings = std::vector<Binding>;
93
94class KernelInterface : public AttributeSet {
95public:
96    /*
97     
98     This class defines the methods to be used to generate the code 
99     necessary for declaring, allocating, calling and synchronizing
100     kernels.   The methods to be used for constructing kernels are defined
101     within the KernelBuilder class of kernel.h
102     
103     */
104   
105    const std::string & getName() const {
106        return mKernelName;
107    }
108       
109    virtual bool isCachable() const = 0;
110
111    virtual std::string makeSignature(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
112
113    const std::vector<Binding> & getStreamInputs() const {
114        return mStreamSetInputs;
115    }
116
117    const Binding & getStreamInput(const unsigned i) const {
118        assert (i < getNumOfStreamInputs());
119        return mStreamSetInputs[i];
120    }
121
122    unsigned getNumOfStreamInputs() const {
123        return mStreamSetInputs.size();
124    }
125
126    const std::vector<Binding> & getStreamOutputs() const {
127        return mStreamSetOutputs;
128    }
129
130    unsigned getNumOfStreamOutputs() const {
131        return mStreamSetOutputs.size();
132    }
133
134    const Binding & getStreamOutput(const unsigned i) const {
135        assert (i < getNumOfStreamOutputs());
136        return mStreamSetOutputs[i];
137    }
138
139    const std::vector<Binding> & getScalarInputs() const {
140        return mScalarInputs;
141    }
142
143    const Binding & getScalarInput(const unsigned i) const {
144        return mScalarInputs[i];
145    }
146
147    const std::vector<Binding> & getScalarOutputs() const {
148        return mScalarOutputs;
149    }
150
151    const Binding & getScalarOutput(const unsigned i) const {
152        return mScalarOutputs[i];
153    }
154
155    // Add ExternalLinkage method declarations for the kernel to a given client module.
156    void addKernelDeclarations(const std::unique_ptr<kernel::KernelBuilder> & idb);
157
158    virtual void linkExternalMethods(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
159
160    virtual llvm::Value * createInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
161
162    virtual void initializeInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
163
164    virtual void finalizeInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) = 0;
165
166    void setInitialArguments(std::vector<llvm::Value *> && args) {
167        mInitialArguments.swap(args);
168    }
169
170    llvm::Value * getInstance() const {
171        return mKernelInstance;
172    }
173
174    void setInstance(llvm::Value * const instance);
175
176    bool hasPrincipalItemCount() const {
177        return mHasPrincipalItemCount;
178    }
179
180protected:
181
182    llvm::Function * getInitFunction(llvm::Module * const module) const;
183
184    llvm::Function * getDoSegmentFunction(llvm::Module * const module) const;
185
186    llvm::Function * getTerminateFunction(llvm::Module * const module) const;
187
188    llvm::CallInst * makeDoSegmentCall(KernelBuilder & idb, const std::vector<llvm::Value *> & args) const;
189
190    KernelInterface(const std::string && kernelName,
191                    Bindings && stream_inputs,
192                    Bindings && stream_outputs,
193                    Bindings && scalar_inputs,
194                    Bindings && scalar_outputs,
195                    Bindings && internal_scalars)
196    : mKernelInstance(nullptr)
197    , mModule(nullptr)
198    , mKernelStateType(nullptr)
199    , mHasPrincipalItemCount(false)
200    , mKernelName(kernelName)
201    , mStreamSetInputs(stream_inputs)
202    , mStreamSetOutputs(stream_outputs)
203    , mScalarInputs(scalar_inputs)
204    , mScalarOutputs(scalar_outputs)
205    , mInternalScalars(internal_scalars) {
206
207    }
208   
209protected:
210
211    llvm::Value *                   mKernelInstance;
212    llvm::Module *                  mModule;
213    llvm::StructType *              mKernelStateType;
214    bool                            mHasPrincipalItemCount;
215    const std::string               mKernelName;
216    std::vector<llvm::Value *>      mInitialArguments;
217    Bindings                        mStreamSetInputs;
218    Bindings                        mStreamSetOutputs;
219    Bindings                        mScalarInputs;
220    Bindings                        mScalarOutputs;
221    Bindings                        mInternalScalars;
222};
223
224}
225
226#endif
Note: See TracBrowser for help on using the repository browser.