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

Last change on this file since 5793 was 5793, checked in by nmedfort, 17 months ago

Bug fix for pipeline: it was terminating too early when there was insufficient output space to process all of the input for a kernel.

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