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

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

Potential bug fix for 32-bit. Modified MRemap to check for Linux OS support. Added MMapAdvise to CBuilder.

File size: 10.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        , 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
88    kernel::KernelBuilder * getProducer() const {
89        return mProducer;
90    }
91
92    const std::vector<kernel::KernelBuilder *> & getConsumers() const {
93        return mConsumers;
94    }
95
96protected:
97
98    StreamSetBuffer(BufferKind k, IDISA::IDISA_Builder * b, llvm::Type * baseType, llvm::Type * resolvedType, unsigned blocks, unsigned AddressSpace);
99
100    // Get the buffer pointer for a given block of the stream.
101    virtual llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const = 0;
102
103    bool isCapacityGuaranteed(const llvm::Value * const index, const size_t capacity) const;
104
105    llvm::Value * modByBufferBlocks(llvm::Value * const offset) const;
106
107    virtual llvm::Value * getBaseAddress(llvm::Value * self) const;
108
109    void setProducer(kernel::KernelBuilder * const producer) {
110        assert (producer);
111        mProducer = producer;
112    }
113
114    void addConsumer(kernel::KernelBuilder * const consumer) {
115        assert (consumer);
116        mConsumers.push_back(consumer);
117    }
118
119protected:
120    const BufferKind                        mBufferKind;
121    IDISA::IDISA_Builder * const            iBuilder;
122    llvm::Type * const                      mType;
123    const size_t                            mBufferBlocks;
124    const unsigned                          mAddressSpace;
125    llvm::Value *                           mStreamSetBufferPtr;
126    llvm::Type * const                      mBaseType;
127    std::string                             mUniqueID;
128    kernel::KernelBuilder *                 mProducer;
129    std::vector<kernel::KernelBuilder *>    mConsumers;
130};   
131
132class SingleBlockBuffer final : public StreamSetBuffer {
133public:
134    static inline bool classof(const StreamSetBuffer * b) {
135        return b->getBufferKind() == BufferKind::BlockBuffer;
136    }   
137
138    SingleBlockBuffer(IDISA::IDISA_Builder * b, llvm::Type * type);
139
140protected:
141
142    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
143};
144
145class ExternalFileBuffer final : public StreamSetBuffer {
146public:
147    static inline bool classof(const StreamSetBuffer * b) {
148        return b->getBufferKind() == BufferKind::ExternalFileBuffer;
149    }
150
151    ExternalFileBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, unsigned AddressSpace = 0);
152
153    void setStreamSetBuffer(llvm::Value * ptr);
154
155    // Can't allocate - raise an error. */
156    void allocateBuffer() override;
157
158    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const override;
159
160protected:
161    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
162};
163
164class SourceFileBuffer final : public StreamSetBuffer {
165public:
166    static inline bool classof(const StreamSetBuffer * b) {
167        return b->getBufferKind() == BufferKind::SourceFileBuffer;
168    }
169
170    SourceFileBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, unsigned AddressSpace = 0);
171
172    void setBaseAddress(llvm::Value * self, llvm::Value * addr) const override;
173
174    void setBufferedSize(llvm::Value * self, llvm::Value * size) const override;
175
176    llvm::Value * getBufferedSize(llvm::Value * self) const override;
177
178    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const override;
179
180protected:
181
182    llvm::Value * getBaseAddress(llvm::Value * self) const override;
183
184    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
185};
186
187class ExtensibleBuffer final : public StreamSetBuffer {
188public:
189    static inline bool classof(const StreamSetBuffer * b) {
190        return b->getBufferKind() == BufferKind::ExtensibleBuffer;
191    }
192
193    ExtensibleBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
194
195    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self,llvm::Value * fromPosition) const override;
196
197    void allocateBuffer() override;
198
199    void reserveBytes(llvm::Value * self, llvm::Value * required) const override;
200
201    void setBufferedSize(llvm::Value * self, llvm::Value * size) const override;
202
203    llvm::Value * getBufferedSize(llvm::Value * self) const override;
204
205    void releaseBuffer(llvm::Value * self) const override;
206
207protected:
208
209    llvm::Value * roundUpToPageSize(llvm::Value * const value) const;
210
211    llvm::Value * getBaseAddress(llvm::Value * self) const override;
212
213    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const override;
214
215};
216   
217class CircularBuffer final : public StreamSetBuffer {
218public:
219    static inline bool classof(const StreamSetBuffer * b) {
220        return b->getBufferKind() == BufferKind::CircularBuffer;
221    }
222   
223    CircularBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
224
225protected:
226    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
227};
228   
229
230//
231//  A CircularCopybackBuffer operates as a circular buffer buffer with an overflow area
232//  for temporary use by the kernel that writes to it.   If the kernel uses the overflow
233//  area, it must perform the doCopyBack action before releasing the buffer for use by
234//  subsequent kernels.
235//  Kernels that read from a CircularCopybackBuffer must not access the overflow area.
236//
237class CircularCopybackBuffer final : public StreamSetBuffer {
238public:
239    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::CircularCopybackBuffer;}
240   
241    CircularCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned AddressSpace = 0);
242
243    void allocateBuffer() override;
244   
245    // Generate copyback code for the given number of overflowItems.
246    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems) const;
247       
248protected:
249    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
250private:
251    size_t mOverflowBlocks;
252
253};
254   
255class SwizzledCopybackBuffer final : public StreamSetBuffer {
256public:
257    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::SwizzledCopybackBuffer;}
258   
259    SwizzledCopybackBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, size_t overflowBlocks, unsigned fieldwidth = 64, unsigned AddressSpace = 0);
260   
261    void allocateBuffer() override;
262   
263    // Generate copyback code for the given number of overflowItems.
264    void createCopyBack(llvm::Value * self, llvm::Value * overflowItems) const;
265protected:
266    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
267private:
268    size_t mOverflowBlocks;
269    unsigned mFieldWidth;
270   
271};
272
273// ExpandableBuffers do not allow access to the base stream set but will automatically increase the number of streams
274// within their set whenever the index exceeds its capacity
275//
276class ExpandableBuffer final : public StreamSetBuffer {
277public:
278    static inline bool classof(const StreamSetBuffer * b) {return b->getBufferKind() == BufferKind::ExpandableBuffer;}
279
280    ExpandableBuffer(IDISA::IDISA_Builder * b, llvm::Type * type, size_t bufferBlocks, unsigned AddressSpace = 0);
281
282    llvm::Value * getStreamBlockPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const override;
283
284    llvm::Value * getStreamPackPtr(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const override;
285
286    llvm::Value * getLinearlyAccessibleItems(llvm::Value * self, llvm::Value * fromPosition) const override;
287
288    void allocateBuffer() override;
289
290    llvm::Value * getStreamSetCount(llvm::Value * self) const override;
291
292    void releaseBuffer(llvm::Value * self) const override;
293
294protected:
295
296    llvm::Value * getBaseAddress(llvm::Value * self) const override;
297
298    llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockIndex) const override;
299
300private:
301
302    std::pair<llvm::Value *, llvm::Value *> getInternalStreamBuffer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
303
304private:
305
306    const uint64_t  mInitialCapacity;
307
308};
309
310}
311#endif // STREAMSET_H
Note: See TracBrowser for help on using the repository browser.