source: icGREP/icgrep-devel/icgrep/kernels/attributes.h @ 5772

Last change on this file since 5772 was 5755, checked in by nmedfort, 19 months ago

Bug fixes and simplified MultiBlockKernel? logic

File size: 7.9 KB
Line 
1#ifndef ATTRIBUTES_H
2#define ATTRIBUTES_H
3
4#include <vector>
5
6namespace kernel {
7
8struct Attribute {
9
10    friend struct AttributeSet;
11
12    friend struct Binding;
13
14    enum class KindId {
15
16        /** INPUT STREAM ATTRIBUTES **/
17
18        LookAhead, /// NOT DONE
19
20        // A LookAhead(n) attribute on an input stream set S declares that the kernel
21        // looks ahead n positions in the input stream.   That is,
22        // processing of item S[i, j] may be defined in terms of S[i, j+n].
23
24        // Guarantee required: the pipeline compiler must ensure that, when
25        // the kernel is called with an available item count of N for the
26        // input stream, that the corresponding input data buffer has
27        // valid items in the buffer up to and including position N+n,
28        // and that the blocks containing the items from N-1 through N+n are
29        // linearly contiguous.  When the final doMultiBlock call is made,
30        // the pipeline compiler must ensure that the n items at lookahead
31        // positions are zero-initialized.
32
33        // (Note: this guarantee anticipates using a single buffer pointer
34        // for both normal stream access and lookahead access.   This avoids
35        // the cost of extra parameters per doMultiBlock call, but requires
36        // that the corresponding circular buffer have a "lookahead extension area"
37        // that holds a copy of the data at the physical start of buffer).
38
39        LookBehind, /// NOT DONE
40
41        // A LookBehind(n) attribute on an input stream S declares that the kernel
42        // requires access to input items up to n positions prior to the current
43        // processed item position.
44
45        // (Notes: this may allow more efficient advances within n (without saving state).
46        // However, a lookbehind extension area prior to the normal buffer base address
47        // is necessary, which must be initially zero-filled.)
48
49        // A LookBehind(n) attribute on an output stream S declares that the kernel
50        // requires access to up to n previously generated output items.
51        // (Example: lz4d lookbehind(65536)).
52
53        Principal,
54
55        // One input stream can be declared as the principal input buffer for a kernel.
56        // If a kernel has a principal input stream, when processing the final stride,
57        // a MultiBlockKernel assumes the item count of the principle is the correct
58        // one and zero extends / truncates all other input streams to match it.
59
60        Deferred,
61
62        // Normally, the processed item count of fixed rate streams is automatically
63        // updated by the MultiBlock kernel. However, some streams behave like Fixed
64        // rate streams (in that they will always eventually process a Fixed amount of
65        // data) but the kernel processes the data in unpredictable chunks. Rather than
66        // declaring those as Unknown or Bounded rates, marking their rate calculation
67        // as Deferred provides the pipeline with a stronger guarantee when it comes to
68        // buffer size calculations.
69
70        Greedy,
71
72        // Normally, the available item count of fixed rate streams is equal to the
73        // number of strides processed by the MultiBlock times its stride size for all
74        // strides except for the final stride. Some kernels consume
75
76        /** OUTPUT STREAM ATTRIBUTES **/
77
78        Add,
79
80        // An Add(K) attribute states that K items will be added to this stream after
81        // processing the final block.
82
83        RoundUpTo,
84
85        // A RoundUpTo(k) attribute indicates the final item count of this stream will
86        // be rounded up to the nearest multiple of k
87
88        /** INPUT/OUTPUT STREAM ATTRIBUTES **/
89
90        BlockSize, /// NOT DONE
91
92        // A BlockSize(K) attribute, where K=2^k for some value of k>=4 declares
93        // that the layout of stream data items within the corresponding input
94        // or output buffer is arranged in blocks of K items each.   In each
95        // block, the data buffer contains K items of the first stream in the
96        // set, followed by K items of the next stream in the set and so on,
97        // up to and including K items of the last stream in the set.
98
99        // (Note: this replaces the concept of swizzling and anticipates that
100        // the pipeline will take on the role of automatically inserting the
101        // swizzling code necessary).
102
103        /** KERNEL ATTRIBUTES **/
104
105        SelectMinimumInputLength, /// NOT DONE
106
107        // If a kernel has multiple input streams and their final item count differs,
108        // a MultiBlock kernel will select the *minimum* input item count as it's
109        // principle item length and truncate the streams to fit
110
111        // NOTE: this is the default if a kernel does not have SelectMaximumInputLength
112        // set and no PrincipalInputStream was declared.
113
114        SelectMaximumInputLength, /// NOT DONE
115
116        // If a kernel has multiple input streams and their final item count differs,
117        // a MultiBlock kernel will select the *maximum* input item count as it's
118        // principle item length and zero-extend the streams accordingly.
119
120        CanTerminate,
121
122        // Informs the pipeline that this kernel can pass a "termination" message to it.
123        // in which case the pipeline will propogate the message to the subsequent
124        // kernels and end the program once the final kernel has returned its result.
125
126        IndependentRegions,
127
128        // Some kernels can divide their processing into concrete non-overlapping regions
129        // between a start and end position in which the data produced by a kernel. If a
130        // kernel K is processed simultaneously by two threads, K_0 and K_1, and K_1 is
131        // waiting K_0 to finish and update it's kernel state for K_1 to resume at, K_1 can
132        // compute what its state will be and begin processing before K_0 is finished. This
133        // requires a the pipeline to intervene and call an optimized "output-less" instance
134        // of the kernel prior to calling B.
135
136    };
137
138    bool isAdd() const {
139        return mKind == KindId::Add;
140    }
141
142    bool isPrincipal() const {
143        return mKind == KindId::Principal;
144    }
145
146    bool isRoundUpTo() const {
147        return mKind == KindId::RoundUpTo;
148    }
149
150    bool isBlockSize() const {
151        return mKind == KindId::BlockSize;
152    }
153
154    unsigned getAmount() const {
155        return mK;
156    }
157
158    bool operator == (const Attribute & other) const {
159        return mKind == other.mKind && mK == other.mK;
160    }
161
162    bool operator != (const Attribute & other) const {
163        return !(*this == other);
164    }
165
166protected:
167
168    KindId getKind() const {
169        return mKind;
170    }
171
172    friend Attribute Add1();
173    friend Attribute Principal();
174    friend Attribute RoundUpTo(const unsigned);
175    friend Attribute LookBehind(const unsigned);
176    friend Attribute Deferred();
177
178    Attribute(const KindId kind, const unsigned k) : mKind(kind), mK(k) { }
179
180private:
181
182    const KindId    mKind;
183    unsigned        mK;
184};
185
186struct AttributeSet : public std::vector<Attribute> {
187
188    using AttributeId = Attribute::KindId;
189
190    const AttributeSet & getAttributes() const {
191        return *this;
192    }
193
194    const Attribute & getAttribute(const unsigned i) const {
195        return getAttributes()[i];
196    }
197
198    void addAttribute(Attribute attribute);
199
200    bool hasAttributes() const {
201        return !empty();
202    }
203
204    bool hasAttribute(const AttributeId id) const;
205
206    AttributeSet() = default;
207
208    AttributeSet(std::initializer_list<Attribute> attrs) : std::vector<Attribute>(attrs) { }
209};
210
211
212inline Attribute Add1() {
213    return Attribute(Attribute::KindId::Add, 1);
214}
215
216inline Attribute RoundUpTo(const unsigned k) {
217    return Attribute(Attribute::KindId::RoundUpTo, k);
218}
219
220inline Attribute Principal() {
221    return Attribute(Attribute::KindId::Principal, 0);
222}
223
224inline Attribute LookBehind(const unsigned k) {
225    return Attribute(Attribute::KindId::LookBehind, k);
226}
227
228inline Attribute Deferred() {
229    return Attribute(Attribute::KindId::Deferred, 0);
230}
231
232}
233
234
235#endif // ATTRIBUTES_H
Note: See TracBrowser for help on using the repository browser.