source: icGREP/icgrep-devel/icgrep/kernels/kernel.h @ 5000

Last change on this file since 5000 was 5000, checked in by nmedfort, 3 years ago

Redesigned buffer system to allow the pipeline to control selection of the current input and output streams; DoBlock? functions containing lookahead now take multiple input stream arguments. Selection and passing occurs automatically. Some work on Symbol Table.

File size: 9.7 KB
Line 
1#ifndef KERNEL_H
2#define KERNEL_H
3/*
4 *  Copyright (c) 2016 International Characters.
5 *  This software is licensed to the public under the Open Software License 3.0.
6 */
7
8#include <string>
9#include <vector>
10#include <boost/container/flat_map.hpp>
11#include <IDISA/idisa_builder.h>
12
13namespace llvm {
14    class Value;
15    class Module;
16    class ExecutionEngine;
17    class VectorType;
18    class PointerType;
19    class Constant;
20    class FunctionType;
21    class Function;
22    class BasicBlock;
23    class Type;
24}
25
26namespace pablo {
27    class PabloAST;
28    class PabloFunction;
29}
30
31namespace kernel {
32
33class Instance;
34
35class KernelBuilder {
36    friend class Instance;
37    friend llvm::Function * generateScanWordRoutine(llvm::Module *, IDISA::IDISA_Builder *, unsigned, KernelBuilder *, bool);
38    using InputStreamMap = boost::container::flat_map<unsigned, llvm::Value *>;
39    using NameMap = boost::container::flat_map<std::string, llvm::ConstantInt *>;
40public:
41
42    KernelBuilder(IDISA::IDISA_Builder * builder, std::string && name, const unsigned defaultBufferSize);
43
44    template<typename T>
45    struct disable_implicit_conversion {
46        inline disable_implicit_conversion(T const value) : _value(value) { assert(_value); }
47        inline disable_implicit_conversion(std::nullptr_t) = delete;
48        inline disable_implicit_conversion(unsigned) = delete;
49        operator T() const { return _value; }
50        T operator-> () const { return _value; }
51        T get() const { return _value; }
52    private:
53        T const  _value;
54    };
55
56    unsigned addInternalState(llvm::Type * const type);
57    unsigned addInternalState(llvm::Type * const type, std::string && name);
58
59    void addInputStream(const unsigned fields);
60    void addInputStream(const unsigned fields, std::string && name);
61
62    void addInputScalar(llvm::Type * const type);
63    void addInputScalar(llvm::Type * const type, std::string && name);
64
65    unsigned addOutputStream(const unsigned fields);
66    unsigned addOutputScalar(llvm::Type * const type);
67
68    inline llvm::Function * prepareFunction() {
69        return prepareFunction({0});
70    }
71
72    llvm::Function * prepareFunction(std::vector<unsigned> && inputStreamOffsets);
73
74    inline llvm::Value * getInternalState(const std::string & name) {
75        return getInternalState(mKernelStateParam, name);
76    }
77
78    inline void setInternalState(const std::string & name, llvm::Value * value) {
79        setInternalState(mKernelStateParam, name, value);
80    }
81
82    inline llvm::Value * getInternalState(const unsigned index) {
83        assert (index < mInternalState.size());
84        return getInternalState(mKernelStateParam, iBuilder->getInt32(index));
85    }
86
87    inline llvm::Value * getInternalState(disable_implicit_conversion<llvm::Value *> const index) {
88        return getInternalState(mKernelStateParam, index);
89    }
90
91    void setInternalState(const unsigned index, llvm::Value * value) {
92        assert (index < mInternalState.size());
93        setInternalState(mKernelStateParam, iBuilder->getInt32(index), value);
94    }
95
96    void setInternalState(disable_implicit_conversion<llvm::Value *> const index, llvm::Value * value) {
97        setInternalState(mKernelStateParam, index, value);
98    }
99    inline llvm::Type * getKernelStateType() const{
100        return mKernelStateType;
101    }
102
103    inline llvm::Value * getInputStream(const unsigned index, const unsigned streamOffset = 0) {
104        assert (index < getNumOfInputStreams());
105        return getInputStream(iBuilder->getInt32(index), streamOffset);
106    }
107
108    inline llvm::Value * getInputStream(disable_implicit_conversion<llvm::Value *> index, const unsigned streamOffset = 0) {
109        const auto f = mInputStreamParam.find(streamOffset);
110        if (LLVM_UNLIKELY(f == mInputStreamParam.end())) {
111            throw std::runtime_error("Kernel compilation error: No input stream parameter for stream offset " + std::to_string(streamOffset));
112        }
113        return getInputStream(f->second, index);
114    }
115
116    inline unsigned getNumOfInputStreams() const {
117        return mInputStream.size();
118    }
119
120    inline llvm::Type * getInputStreamType() const {
121        return mInputStreamType;
122    }
123
124    inline llvm::Value * getInputScalar(const unsigned index) {
125        assert (index < getNumOfInputScalars());
126        return getInputScalar(iBuilder->getInt32(index));
127    }
128
129    inline llvm::Value * getInputScalar(disable_implicit_conversion<llvm::Value *> const index) {
130        return getInputScalar(mInputScalarParam, index);
131    }
132
133    inline unsigned getNumOfInputScalars() const {
134        return mInputScalar.size();
135    }
136
137    inline llvm::Type * getInputScalarType() const {
138        return mInputScalarType;
139    }
140
141    inline llvm::Value * getOutputStream(const unsigned index) {
142        assert (index < getNumOfOutputStreams());
143        return getOutputStream(mOutputStreamParam, iBuilder->getInt32(index));
144    }
145
146    inline llvm::Value * getOutputStream(disable_implicit_conversion<llvm::Value *> const index) {
147        return getOutputStream(mOutputStreamParam, index);
148    }
149
150    inline unsigned getNumOfOutputStreams() const {
151        return mOutputStream.size();
152    }
153
154    inline llvm::Type * getOutputStreamType() const {
155        return mOutputStreamType;
156    }
157
158    inline llvm::Value * getOutputScalar(const unsigned index) {
159        assert (index < getNumOfOutputScalars());
160        return getOutputScalar(mOutputScalarParam, iBuilder->getInt32(index));
161    }
162
163    inline llvm::Value * getOutputScalar(disable_implicit_conversion<llvm::Value *> const index) {
164        return getOutputScalar(mOutputScalarParam, index);
165    }
166
167    inline unsigned getNumOfOutputScalars() const {
168        return mOutputScalar.size();
169    }
170
171    inline llvm::Type * getOutputScalarType() const {
172        return mOutputStreamType;
173    }
174
175    inline llvm::Value * getBlockNo() {
176        return getBlockNo(mKernelStateParam);
177    }
178
179    unsigned getDefaultBufferSize() const;
180
181    void finalize();
182
183    kernel::Instance * instantiate(std::pair<llvm::Value *, unsigned> && inputStreamSet) {
184        return instantiate(std::move(inputStreamSet), getDefaultBufferSize());
185    }
186
187    kernel::Instance * instantiate(std::pair<llvm::Value *, unsigned> && inputStreamSet, const unsigned outputBufferSize);
188
189    kernel::Instance * instantiate(llvm::Value * const inputStream) {
190        return instantiate(std::make_pair(inputStream, 0));
191    }
192
193    kernel::Instance * instantiate(std::initializer_list<llvm::Value *> inputStreams);
194
195    llvm::Value * getKernelState() const;
196
197    llvm::Function * getDoBlockFunction() const;
198
199protected:
200
201    Type * packDataTypes(const std::vector<llvm::Type *> & types);
202
203    llvm::Value * getInputStream(llvm::Value * const inputStreamSet, disable_implicit_conversion<llvm::Value *> index);
204
205    llvm::Value * getInputScalar(llvm::Value * const inputScalarSet, disable_implicit_conversion<llvm::Value *> index);
206
207    llvm::Value * getInternalState(llvm::Value * const kernelState, const std::string & name);
208
209    void setInternalState(llvm::Value * const kernelState, const std::string & name, llvm::Value * const value);
210
211    llvm::Value * getInternalState(llvm::Value * const kernelState, disable_implicit_conversion<llvm::Value *> index);
212
213    void setInternalState(llvm::Value * const kernelState, const unsigned index, llvm::Value * const value);
214
215    void setInternalState(llvm::Value * const kernelState, disable_implicit_conversion<llvm::Value *> index, llvm::Value * const value);
216
217    llvm::Value * getOutputStream(llvm::Value * const outputStreamSet, disable_implicit_conversion<llvm::Value *> index);
218
219    llvm::Value * getOutputScalar(llvm::Value * const outputScalarSet, disable_implicit_conversion<llvm::Value *> index);
220
221    llvm::Value * getBlockNo(llvm::Value * const instance);
222
223    llvm::Function * getOutputStreamSetFunction() const;
224
225    const std::vector<unsigned> & getInputStreamOffsets() const {
226        return mInputStreamOffsets;
227    }
228
229private:
230
231    IDISA::IDISA_Builder * const        iBuilder;
232    const std::string                   mKernelName;
233    unsigned                            mDefaultBufferSize;
234
235    llvm::Type *                        mBitBlockType;
236    llvm::ConstantInt *                 mBlockNoIndex;
237    llvm::Function *                                    mConstructor;
238    llvm::Function *                                    mDoBlock;
239
240    llvm::Type *                        mKernelStateType;
241    llvm::Type *                        mInputScalarType;
242    llvm::Type *                        mInputStreamType;
243    llvm::Type *                        mOutputScalarType;
244    llvm::Type *                        mOutputStreamType;
245
246    llvm::Value *                       mKernelStateParam;
247    llvm::Value *                       mInputScalarParam;
248    InputStreamMap                      mInputStreamParam;
249    llvm::Value *                       mOutputScalarParam;
250    llvm::Value *                       mOutputStreamParam;
251
252    std::vector<llvm::Type *>           mInputScalar;
253    std::vector<std::string>            mInputScalarName;   
254    std::vector<llvm::Type *>           mInputStream;
255    std::vector<std::string>            mInputStreamName;
256    std::vector<unsigned>               mInputStreamOffsets;
257    std::vector<llvm::Type *>           mOutputScalar;
258    std::vector<llvm::Type *>           mOutputStream;
259    std::vector<llvm::Type *>                   mInternalState;
260    NameMap                             mInternalStateNameMap;
261};
262
263inline llvm::Function * KernelBuilder::getDoBlockFunction() const {
264    return mDoBlock;
265}
266
267inline llvm::Value * KernelBuilder::getKernelState() const {
268    return mKernelStateParam;
269}
270
271inline llvm::Value * KernelBuilder::getBlockNo(llvm::Value * const instance) {
272    return getInternalState(instance, mBlockNoIndex);
273}
274
275inline unsigned KernelBuilder::getDefaultBufferSize() const {
276    return mDefaultBufferSize;
277}
278
279} // end of namespace kernel
280
281#endif // KERNEL_H
Note: See TracBrowser for help on using the repository browser.