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

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

Potential fix for Mac compilers.

File size: 9.6 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 getInternalStateInternal(mKernelStateParam, name);
76    }
77
78    inline void setInternalState(const std::string & name, llvm::Value * value) {
79        setInternalStateInternal(mKernelStateParam, name, value);
80    }
81
82    inline llvm::Value * getInternalState(const unsigned index) {
83        assert (index < mInternalState.size());
84        return getInternalStateInternal(mKernelStateParam, iBuilder->getInt32(index));
85    }
86
87    inline llvm::Value * getInternalState(disable_implicit_conversion<llvm::Value *> const index) {
88        return getInternalStateInternal(mKernelStateParam, index);
89    }
90
91    void setInternalState(const unsigned index, llvm::Value * value) {
92        assert (index < mInternalState.size());
93        setInternalStateInternal(mKernelStateParam, iBuilder->getInt32(index), value);
94    }
95
96    void setInternalState(disable_implicit_conversion<llvm::Value *> const index, llvm::Value * value) {
97        setInternalStateInternal(mKernelStateParam, index, value);
98    }
99
100    inline llvm::Type * getKernelStateType() const{
101        return mKernelStateType;
102    }
103
104    inline llvm::Value * getInputStream(const unsigned index, const unsigned streamOffset = 0) {
105        return getInputStreamInternal(getInputStreamParam(streamOffset), iBuilder->getInt32(index));
106    }
107
108    inline llvm::Value * getInputStream(disable_implicit_conversion<llvm::Value *> index, const unsigned streamOffset = 0) {
109        return getInputStreamInternal(getInputStreamParam(streamOffset), index);
110    }
111
112    inline unsigned getNumOfInputStreams() const {
113        return mInputStream.size();
114    }
115
116    inline llvm::Type * getInputStreamType() const {
117        return mInputStreamType;
118    }
119
120    inline llvm::Value * getInputScalar(const unsigned index) {
121        assert (index < getNumOfInputScalars());
122        return getInputScalarInternal(mInputScalarParam, iBuilder->getInt32(index));
123    }
124
125    inline llvm::Value * getInputScalar(disable_implicit_conversion<llvm::Value *> const index) {
126        return getInputScalarInternal(mInputScalarParam, index);
127    }
128
129    inline unsigned getNumOfInputScalars() const {
130        return mInputScalar.size();
131    }
132
133    inline llvm::Type * getInputScalarType() const {
134        return mInputScalarType;
135    }
136
137    inline llvm::Value * getOutputStream(const unsigned index) {
138        assert (index < getNumOfOutputStreams());
139        return getOutputStreamInternal(mOutputStreamParam, iBuilder->getInt32(index));
140    }
141
142    inline llvm::Value * getOutputStream(disable_implicit_conversion<llvm::Value *> const index) {
143        return getOutputStreamInternal(mOutputStreamParam, index);
144    }
145
146    inline unsigned getNumOfOutputStreams() const {
147        return mOutputStream.size();
148    }
149
150    inline llvm::Type * getOutputStreamType() const {
151        return mOutputStreamType;
152    }
153
154    inline llvm::Value * getOutputScalar(const unsigned index) {
155        assert (index < getNumOfOutputScalars());
156        return getOutputScalarInternal(mOutputScalarParam, iBuilder->getInt32(index));
157    }
158
159    inline llvm::Value * getOutputScalar(disable_implicit_conversion<llvm::Value *> const index) {
160        return getOutputScalarInternal(mOutputScalarParam, index);
161    }
162
163    inline unsigned getNumOfOutputScalars() const {
164        return mOutputScalar.size();
165    }
166
167    inline llvm::Type * getOutputScalarType() const {
168        return mOutputStreamType;
169    }
170
171    inline llvm::Value * getBlockNo() {
172        return getBlockNoInternal(mKernelStateParam);
173    }
174
175    unsigned getDefaultBufferSize() const;
176
177    void finalize();
178
179    kernel::Instance * instantiate(std::pair<llvm::Value *, unsigned> && inputStreamSet) {
180        return instantiate(std::move(inputStreamSet), getDefaultBufferSize());
181    }
182
183    kernel::Instance * instantiate(std::pair<llvm::Value *, unsigned> && inputStreamSet, const unsigned outputBufferSize);
184
185    kernel::Instance * instantiate(llvm::Value * const inputStream) {
186        return instantiate(std::make_pair(inputStream, 0));
187    }
188
189    kernel::Instance * instantiate(std::initializer_list<llvm::Value *> inputStreams);
190
191    llvm::Value * getKernelState() const;
192
193    llvm::Function * getDoBlockFunction() const;
194
195protected:
196
197    Type * packDataTypes(const std::vector<llvm::Type *> & types);
198
199    llvm::Value * getInputStreamInternal(llvm::Value * const inputStreamSet, disable_implicit_conversion<llvm::Value *> index);
200
201    llvm::Value * getInputScalarInternal(llvm::Value * const inputScalarSet, disable_implicit_conversion<llvm::Value *> index);
202
203    llvm::Value * getInternalStateInternal(llvm::Value * const kernelState, const std::string & name);
204
205    void setInternalStateInternal(llvm::Value * const kernelState, const std::string & name, llvm::Value * const value);
206
207    llvm::Value * getInternalStateInternal(llvm::Value * const kernelState, disable_implicit_conversion<llvm::Value *> index);
208
209    void setInternalStateInternal(llvm::Value * const kernelState, const unsigned index, llvm::Value * const value);
210
211    void setInternalStateInternal(llvm::Value * const kernelState, disable_implicit_conversion<llvm::Value *> index, llvm::Value * const value);
212
213    llvm::Value * getOutputStreamInternal(llvm::Value * const outputStreamSet, disable_implicit_conversion<llvm::Value *> index);
214
215    llvm::Value * getOutputScalarInternal(llvm::Value * const outputScalarSet, disable_implicit_conversion<llvm::Value *> index);
216
217    llvm::Value * getBlockNoInternal(llvm::Value * const instance) {
218        return getInternalStateInternal(instance, mBlockNoIndex);
219    }
220
221    llvm::Function * getOutputStreamSetFunction() const;
222
223    llvm::Value * getInputStreamParam(const unsigned streamOffset) 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 unsigned KernelBuilder::getDefaultBufferSize() const {
272    return mDefaultBufferSize;
273}
274
275} // end of namespace kernel
276
277#endif // KERNEL_H
Note: See TracBrowser for help on using the repository browser.