source: icGREP/icgrep-devel/icgrep/kernels/streamset.h @ 6133

Last change on this file since 6133 was 6047, checked in by nmedfort, 13 months ago

Major refactoring of buffer types. Static buffers replace Circular and CircularCopyback?. External buffers unify Source/External?.

File size: 11.0 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 STREAMSET_H
7#define STREAMSET_H
8
9#include <llvm/IR/Type.h>  // for Type
10#include <llvm/IR/DerivedTypes.h>  // for Type
11namespace IDISA { class IDISA_Builder; }
12namespace llvm { class Value; }
13namespace llvm { class Constant; }
14namespace kernel { class Kernel; }
15namespace kernel { class KernelBuilder; }
16
17namespace parabix {
18   
19class StreamSetBuffer {
20    friend class kernel::Kernel;
21    friend class kernel::KernelBuilder;
22public:
23
24    enum class BufferKind : unsigned {
25        ExternalBuffer
26        , StaticBuffer
27        , DynamicBuffer
28    };
29
30    BufferKind getBufferKind() const {
31        return mBufferKind;
32    }
33   
34    std::string getUniqueID() const {
35        return mUniqueID;
36    }
37
38    llvm::Type * getType() const {
39        return mType;
40    }
41   
42    llvm::Type * getBaseType() const {
43        return mBaseType;
44    }
45
46    unsigned getNumOfStreams () const {
47        size_t numStreams = 1;
48        if (mBaseType->isArrayTy()) {
49            numStreams = mBaseType->getArrayNumElements();
50        }
51        return numStreams;
52    }
53   
54    unsigned getStreamFieldWidth () const {
55        if (mBaseType->isArrayTy()) {
56            return mBaseType->getArrayElementType()->getScalarSizeInBits();
57        }
58        return mBaseType->getScalarSizeInBits();
59    }
60   
61    unsigned getAddressSpace() const {
62        return mAddressSpace;
63    }
64
65    llvm::PointerType * getPointerType() const {
66        return getType()->getPointerTo(getAddressSpace());
67    }
68
69    virtual bool supportsCopyBack() const {
70        return false;
71    }
72
73    virtual bool isUnbounded() const {
74        return false;
75    }
76
77    virtual ~StreamSetBuffer() = 0;
78
79    kernel::Kernel * getProducer() const {
80        return mProducer;
81    }
82
83    const std::vector<kernel::Kernel *> & getConsumers() const {
84        return mConsumers;
85    }
86
87    virtual void allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & kb) = 0;
88
89    virtual void releaseBuffer(const std::unique_ptr<kernel::KernelBuilder> & kb) const = 0;
90
91    llvm::PointerType * getStreamSetPointerType() const {
92        return mType->getPointerTo(mAddressSpace);
93    }
94
95protected:
96
97    virtual llvm::Value * getStreamBlockPtr(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
98
99    virtual llvm::Value * getStreamPackPtr(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const;
100   
101    virtual llvm::Value * getStreamSetCount(IDISA::IDISA_Builder * const b, llvm::Value * handle) const;
102
103    virtual llvm::Value * getBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle) const = 0;
104
105    virtual void setBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * addr) const = 0;
106
107    virtual llvm::Value * getOverflowAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle) const = 0;
108
109    virtual void setCapacity(IDISA::IDISA_Builder * const b, llvm::Value * size, llvm::Value *) const = 0;
110   
111    virtual llvm::Value * getCapacity(IDISA::IDISA_Builder * const b, llvm::Value * handle) const = 0;
112
113    virtual llvm::Value * getRawItemPointer(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * absolutePosition) const = 0;
114
115    // The number of items that cam be linearly accessed from a given logical stream position.
116    virtual llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPos, llvm::Value * avail, bool reverse = false) const = 0;
117
118    virtual llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, llvm::Value * consumed, bool reverse = false) const = 0;
119   
120    void setProducer(kernel::Kernel * const producer) {
121        assert (producer);
122        mProducer = producer;
123    }
124
125    void addConsumer(kernel::Kernel * const consumer) {
126        assert (consumer);
127        mConsumers.push_back(consumer);
128    }
129
130    llvm::Value * getStreamSetHandle() const {
131        return mStreamSetHandle;
132    }
133
134    StreamSetBuffer(const BufferKind k, const std::unique_ptr<kernel::KernelBuilder> & b, llvm::Type * baseType, unsigned AddressSpace);
135
136protected:
137    const BufferKind                 mBufferKind;
138    llvm::Type * const               mType;
139    const unsigned                   mAddressSpace;
140    llvm::Value *                    mStreamSetHandle;
141    llvm::Type * const               mBaseType;
142    std::string                      mUniqueID;
143    kernel::Kernel *                 mProducer;
144    std::vector<kernel::Kernel *>    mConsumers;
145};   
146
147class ExternalBuffer final : public StreamSetBuffer {
148    friend class kernel::KernelBuilder;
149public:
150    static inline bool classof(const StreamSetBuffer * b) {
151        return b->getBufferKind() == BufferKind::ExternalBuffer;
152    }
153
154    enum Field {BaseAddress, Capacity};
155
156    ExternalBuffer(const std::unique_ptr<kernel::KernelBuilder> & b, llvm::Type * const type,
157                   llvm::Value * const externalAddress = nullptr, const unsigned AddressSpace = 0);
158
159    void allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & b) override;
160
161    void releaseBuffer(const std::unique_ptr<kernel::KernelBuilder> & kb) const override;
162
163    bool isUnbounded() const override {
164        return true;
165    }
166
167protected:
168
169    llvm::Value * getBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
170
171    void setBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * addr) const override;
172
173    llvm::Value * getOverflowAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
174
175    void setCapacity(IDISA::IDISA_Builder * const b, llvm::Value * size, llvm::Value * capacity) const override;
176
177    llvm::Value * getCapacity(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
178
179    llvm::Value * getRawItemPointer(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * absolutePosition) const override;
180
181    llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, llvm::Value * avail, bool reverse = false) const override;
182   
183    llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, llvm::Value * consumed, bool reverse = false) const override;
184
185private:
186
187    llvm::Value * mExternalAddress;
188
189};
190
191class StaticBuffer final : public StreamSetBuffer {
192    friend class kernel::KernelBuilder;
193public:
194    static inline bool classof(const StreamSetBuffer * b) {
195        return b->getBufferKind() == BufferKind::StaticBuffer;
196    }
197   
198    StaticBuffer(const std::unique_ptr<kernel::KernelBuilder> & b, llvm::Type * const type,
199                 const size_t capacity, const size_t overflowBlocks = 0, const unsigned AddressSpace = 0);
200
201    void allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & b) override;
202
203    void releaseBuffer(const std::unique_ptr<kernel::KernelBuilder> & kb) const override;
204
205    bool supportsCopyBack() const override {
206        return mOverflow > 0;
207    }
208
209protected:
210
211    llvm::Value * getBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
212
213    void setBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * addr) const override;
214
215    llvm::Value * getOverflowAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
216
217    llvm::Value * getCapacity(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
218
219    void setCapacity(IDISA::IDISA_Builder * const b, llvm::Value * size, llvm::Value *) const override;
220
221    llvm::Value * getStreamBlockPtr(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const override;
222
223    llvm::Value * getStreamPackPtr(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const override;
224
225    llvm::Value * getRawItemPointer(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * absolutePosition) const override;
226
227    llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, llvm::Value * avail, bool reverse = false) const override;
228
229    llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, llvm::Value * consumed, bool reverse = false) const override;
230
231private:
232
233    llvm::Value * modByCapacity(IDISA::IDISA_Builder * const b, llvm::Value * const offset) const;
234
235private:
236
237    const size_t    mCapacity;
238    const size_t    mOverflow;
239
240};
241       
242// Dynamically allocated circular buffers: TODO: add copyback, swizzle support, dynamic allocation, producer, consumer, length
243class DynamicBuffer final : public StreamSetBuffer {
244
245    friend class kernel::KernelBuilder;
246
247    enum Field {BaseAddress, PriorBaseAddress, Capacity};
248
249public:
250    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::DynamicBuffer;}
251   
252    DynamicBuffer(const std::unique_ptr<kernel::KernelBuilder> & b, llvm::Type * type, size_t initialCapacity, size_t overflowBlocks = 0, unsigned AddressSpace = 0);
253
254    void allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & b) override;
255
256    void releaseBuffer(const std::unique_ptr<kernel::KernelBuilder> & b) const override;
257   
258    bool supportsCopyBack() const override {
259        return mOverflow > 0;
260    }
261
262protected:
263
264    llvm::Value * getBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
265
266    void setBaseAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * addr) const override;
267
268    llvm::Value * getOverflowAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
269   
270    llvm::Value * getCapacity(IDISA::IDISA_Builder * const b, llvm::Value * handle) const override;
271   
272    void setCapacity(IDISA::IDISA_Builder * const b, llvm::Value * size, llvm::Value *) const override;
273
274    llvm::Value * getBlockAddress(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * blockIndex) const;
275
276    llvm::Value * getRawItemPointer(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * absolutePosition) const override;
277
278    llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, llvm::Value * avail, bool reverse = false) const override;
279
280    llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, llvm::Value * consumed, bool reverse = false) const override;
281
282private:
283
284    llvm::Value * getAllocationSize(IDISA::IDISA_Builder * const b, llvm::Value * const handle, llvm::Value * const requiredItemCapacity) const;
285
286private:
287
288    const size_t    mInitialCapacity;
289    const size_t    mOverflow;
290
291};
292
293
294}
295#endif // STREAMSET_H
Note: See TracBrowser for help on using the repository browser.