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

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

Continued work on processing stdin input. Partial integration of ParabixDriver? methods into icgrep and editd. Object cache does not currently work for recursive REs.

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