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

Last change on this file since 5429 was 5429, checked in by nmedfort, 2 years ago

Refactored source kernels. icgrep from stdin should now be able to handle any file size.

File size: 9.5 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
10namespace IDISA { class IDISA_Builder; }
11namespace llvm { class Value; }
12namespace kernel { class KernelBuilder; }
13
14namespace parabix {
15   
16class StreamSetBuffer {
17    friend class kernel::KernelBuilder;
18
19public:
20
21    enum class BufferKind : unsigned {
22        BlockBuffer
23        , SourceBuffer
24        , ExternalBuffer
25        , CircularBuffer
26        , CircularCopybackBuffer
27        , SwizzledCopybackBuffer
28        , ExpandableBuffer
29    };
30
31    BufferKind getBufferKind() const {
32        return mBufferKind;
33    }
34   
35    std::string getUniqueID() const {
36        return mUniqueID;
37    }
38
39    llvm::Type * getType() const {
40        return mType;
41    }
42
43    llvm::Type * getBaseType() const {
44        return mBaseType;
45    }
46
47    llvm::PointerType * getPointerType() const {
48        return getType()->getPointerTo(mAddressSpace);
49    }
50
51    size_t getBufferBlocks() const {
52        return mBufferBlocks;
53    }
54
55    llvm::Value * getStreamSetBasePtr() const {
56        return mStreamSetBufferPtr;
57    }
58
59    virtual void allocateBuffer();
60
61    virtual void releaseBuffer(llvm::Value * self) const;
62
63    virtual llvm::Value * getStreamBlockPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
64
65    virtual llvm::Value * getStreamPackPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const;
66   
67    virtual llvm::Value * getStreamSetCount(llvm::Value * self) const;
68
69    llvm::Value * getRawItemPointer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * absolutePosition) const;
70
71
72    virtual void setBaseAddress(llvm::Value * self, llvm::Value * addr) const;
73
74    virtual void setBufferedSize(llvm::Value * self, llvm::Value * size) const;
75
76    virtual llvm::Value * getBufferedSize(llvm::Value * self) const;
77
78    // The number of items that cam be linearly accessed from a given logical stream position.
79    virtual llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const;
80
81    virtual llvm::Value * getLinearlyAccessibleBlocks(llvm::Value * self, llvm::Value * fromBlock) const;
82
83    virtual void reserveBytes(llvm::Value * self, llvm::Value * requested) const;
84
85    virtual ~StreamSetBuffer() = 0;
86
87    kernel::KernelBuilder * getProducer() const {
88        return mProducer;
89    }
90
91    const std::vector<kernel::KernelBuilder *> & getConsumers() const {
92        return mConsumers;
93    }
94
95protected:
96
97    StreamSetBuffer(BufferKind k, IDISA::IDISA_Builder * b, llvm::Type * baseType, llvm::Type * resolvedType, unsigned blocks, unsigned AddressSpace);
98
99    // Get the buffer pointer for a given block of the stream.
100    virtual llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const = 0;
101
102    bool isCapacityGuaranteed(const llvm::Value * const index, const size_t capacity) const;
103
104    llvm::Value * modByBufferBlocks(llvm::Value * const offset) const;
105
106    virtual llvm::Value * getBaseAddress(llvm::Value * self) const;
107
108    void setProducer(kernel::KernelBuilder * const producer) {
109        assert (producer);
110        mProducer = producer;
111    }
112
113    void addConsumer(kernel::KernelBuilder * const consumer) {
114        assert (consumer);
115        mConsumers.push_back(consumer);
116    }
117
118protected:
119    const BufferKind                        mBufferKind;
120    IDISA::IDISA_Builder * const            iBuilder;
121    llvm::Type * const                      mType;
122    const size_t                            mBufferBlocks;
123    const unsigned                          mAddressSpace;
124    llvm::Value *                           mStreamSetBufferPtr;
125    llvm::Type * const                      mBaseType;
126    std::string                             mUniqueID;
127    kernel::KernelBuilder *                 mProducer;
128    std::vector<kernel::KernelBuilder *>    mConsumers;
129};   
130
131class SingleBlockBuffer final : public StreamSetBuffer {
132public:
133    static inline bool classof(const StreamSetBuffer * b) {
134        return b->getBufferKind() == BufferKind::BlockBuffer;
135    }   
136
137    SingleBlockBuffer(IDISA::IDISA_Builder * b, llvm::Type * type);
138
139protected:
140
141    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
142};
143
144class SourceBuffer final : public StreamSetBuffer {
145public:
146    static inline bool classof(const StreamSetBuffer * b) {
147        return b->getBufferKind() == BufferKind::SourceBuffer;
148    }
149
150    SourceBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, unsigned AddressSpace = 0);
151
152    void setBaseAddress(llvm::Value * self, llvm::Value * addr) const override;
153
154    void setBufferedSize(llvm::Value * self, llvm::Value * size) const override;
155
156    llvm::Value * getBufferedSize(llvm::Value * self) const override;
157
158    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const override;
159
160protected:
161
162    llvm::Value * getBaseAddress(llvm::Value * self) const override;
163
164    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
165
166};
167
168class ExternalBuffer final : public StreamSetBuffer {
169public:
170    static inline bool classof(const StreamSetBuffer * b) {
171        return b->getBufferKind() == BufferKind::ExternalBuffer;
172    }
173
174    ExternalBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, llvm::Value * addr, unsigned AddressSpace = 0);
175
176    // Can't allocate - raise an error. */
177    void allocateBuffer() override;
178
179    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const override;
180
181protected:
182    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
183};
184
185class CircularBuffer final : public StreamSetBuffer {
186public:
187    static inline bool classof(const StreamSetBuffer * b) {
188        return b->getBufferKind() == BufferKind::CircularBuffer;
189    }
190   
191    CircularBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
192
193protected:
194    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
195};
196   
197
198//
199//  A CircularCopybackBuffer operates as a circular buffer buffer with an overflow area
200//  for temporary use by the kernel that writes to it.   If the kernel uses the overflow
201//  area, it must perform the doCopyBack action before releasing the buffer for use by
202//  subsequent kernels.
203//  Kernels that read from a CircularCopybackBuffer must not access the overflow area.
204//
205class CircularCopybackBuffer final : public StreamSetBuffer {
206public:
207    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::CircularCopybackBuffer;}
208   
209    CircularCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned AddressSpace = 0);
210
211    void allocateBuffer() override;
212   
213    // Generate copyback code for the given number of overflowItems.
214    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems) const;
215       
216protected:
217    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
218private:
219    size_t mOverflowBlocks;
220
221};
222   
223class SwizzledCopybackBuffer final : public StreamSetBuffer {
224public:
225    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::SwizzledCopybackBuffer;}
226   
227    SwizzledCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned fieldwidth = 64, unsigned AddressSpace = 0);
228   
229    void allocateBuffer() override;
230   
231    // Generate copyback code for the given number of overflowItems.
232    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems) const;
233protected:
234    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
235private:
236    size_t mOverflowBlocks;
237    unsigned mFieldWidth;
238   
239};
240
241// ExpandableBuffers do not allow access to the base stream set but will automatically increase the number of streams
242// within their set whenever the index exceeds its capacity
243//
244class ExpandableBuffer final : public StreamSetBuffer {
245public:
246    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::ExpandableBuffer;}
247
248    ExpandableBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
249
250    llvm::Value * getStreamBlockPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const override;
251
252    llvm::Value * getStreamPackPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const override;
253
254    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const override;
255
256    void allocateBuffer() override;
257
258    llvm::Value * getStreamSetCount(llvm::Value * self) const override;
259
260    void releaseBuffer(llvm::Value * self) const override;
261
262protected:
263
264    llvm::Value * getBaseAddress(llvm::Value * self) const override;
265
266    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
267
268private:
269
270    std::pair<llvm::Value *, llvm::Value *> getInternalStreamBuffer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
271
272private:
273
274    const uint64_t  mInitialCapacity;
275
276};
277
278}
279#endif // STREAMSET_H
Note: See TracBrowser for help on using the repository browser.