source: icGREP/icgrep-devel/icgrep/kernels/processing_rate.h @ 6297

Last change on this file since 6297 was 6253, checked in by nmedfort, 8 months ago

Moved consumed item counts for all buffers into pipeline state. Initial work on conditional kernel logic.

File size: 5.4 KB
Line 
1#ifndef PROCESSING_RATE_H
2#define PROCESSING_RATE_H
3
4#include <string>
5#include <assert.h>
6#include <boost/rational.hpp>
7
8namespace llvm { class raw_ostream; }
9
10namespace kernel {
11
12// Processing rate attributes are required for all stream set bindings. They describe
13// the relationship between processed items (inputs) and produced items (outputs).
14//
15// For example, the 3-to-4 kernel converts every 3 input items into 4 output items.
16// Thus it has a FixedRate(3) for its input stream and FixedRate(4) for its output
17// stream. Processing these every 3 items individually would be time consuming. Instead
18// the kernel processes a strides' worth of "iterations" and automatically scales the
19// FixedRates accordingly.
20//
21// NOTE: fixed and bounded rates should be the smallest number of input items for the
22// smallest number of output items that can be logically produced by a kernel.
23
24class Kernel;
25struct Binding;
26
27struct ProcessingRate  {
28
29    friend struct Binding;
30
31    enum class KindId {
32        Fixed, Bounded, PopCount, NegatedPopCount, Unknown, Relative, Greedy
33    };
34
35    using RateValue = boost::rational<unsigned>;
36
37    KindId getKind() const { return mKind; }
38
39    RateValue getRate() const {
40        return mLowerBound;
41    }
42
43    RateValue getLowerBound() const {
44        return mLowerBound;
45    }
46
47    RateValue getUpperBound() const {
48        assert (!isGreedy());
49        return mUpperBound;
50    }
51
52    const std::string & getReference() const {
53        assert (hasReference());
54        return mReference;
55    }
56
57    bool isFixed() const {
58        return mKind == KindId::Fixed;
59    }
60
61    bool isBounded() const {
62        return mKind == KindId::Bounded;
63    }
64
65    bool isGreedy() const {
66        return mKind == KindId::Greedy;
67    }
68
69    bool isRelative() const {
70        return mKind == KindId::Relative;
71    }
72
73    bool isPopCount() const {
74        return mKind == KindId::PopCount;
75    }
76
77    bool isNegatedPopCount() const {
78        return mKind == KindId::NegatedPopCount;
79    }
80
81    bool isUnknown() const {
82        return mKind == KindId::Unknown;
83    }
84
85    bool hasReference() const {
86        return isRelative() || isPopCount() || isNegatedPopCount();
87    }
88
89    bool isDerived() const {
90        return isRelative();
91    }
92
93    bool operator == (const ProcessingRate & other) const {
94        return mKind == other.mKind && mLowerBound == other.mLowerBound && mUpperBound == other.mUpperBound && mReference == other.mReference;
95    }
96
97    bool operator != (const ProcessingRate & other) const {
98        return !(*this == other);
99    }
100
101    bool operator < (const ProcessingRate & other) const {
102        if (mKind < other.mKind) {
103            return true;
104        } else if (mLowerBound < other.mLowerBound) {
105            return true;
106        } else if (mUpperBound < other.mUpperBound) {
107            return true;
108        } else {
109            return mReference < other.mReference;
110        }
111    }
112
113    friend ProcessingRate FixedRate(const unsigned);
114    friend ProcessingRate BoundedRate(const unsigned, const unsigned);
115    friend ProcessingRate UnknownRate(const unsigned);
116    friend ProcessingRate RateEqualTo(std::string);
117    friend ProcessingRate PopcountOf(std::string);
118    friend ProcessingRate PopcountOfNot(std::string);
119    friend ProcessingRate Greedy();
120
121    ProcessingRate(ProcessingRate &&) = default;
122    ProcessingRate(const ProcessingRate &) = default;
123    ProcessingRate & operator = (const ProcessingRate & other) = default;
124
125protected:
126
127    ProcessingRate(const KindId k, const RateValue lb, const RateValue ub, const std::string && ref = "")
128    : mKind(k)
129    , mLowerBound(lb)
130    , mUpperBound(ub)
131    , mReference(ref) {
132
133    }
134
135    void print(const Kernel * const kernel, llvm::raw_ostream & out) const noexcept;
136
137private:
138    const KindId mKind;
139    const RateValue mLowerBound;
140    const RateValue mUpperBound;
141    const std::string mReference;
142};
143
144inline ProcessingRate FixedRate(const unsigned rate = 1) {
145    assert (rate > 0);
146    return ProcessingRate(ProcessingRate::KindId::Fixed, rate, rate);
147}
148
149inline ProcessingRate BoundedRate(const unsigned lower, const unsigned upper) {
150    if (lower == upper) {
151        return FixedRate(lower);
152    } else {
153        assert (upper > lower);
154        return ProcessingRate(ProcessingRate::KindId::Bounded, ProcessingRate::RateValue(lower), ProcessingRate::RateValue(upper));
155    }
156}
157
158inline ProcessingRate UnknownRate(const unsigned lower = 0) {
159    return ProcessingRate(ProcessingRate::KindId::Unknown, lower, 0);
160}
161
162inline ProcessingRate RateEqualTo(std::string ref) {
163    return ProcessingRate(ProcessingRate::KindId::Relative, 1, 1, std::move(ref));
164}
165
166inline ProcessingRate PopcountOf(std::string ref) {
167    return ProcessingRate(ProcessingRate::KindId::PopCount, 0, 1, std::move(ref));
168}
169
170inline ProcessingRate PopcountOfNot(std::string ref) {
171    return ProcessingRate(ProcessingRate::KindId::NegatedPopCount, 0, 1, std::move(ref));
172}
173
174inline ProcessingRate Greedy() {
175    return ProcessingRate(ProcessingRate::KindId::Greedy, 0, 0);
176}
177
178
179ProcessingRate::RateValue lcm(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
180
181ProcessingRate::RateValue gcd(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
182
183unsigned floor(const ProcessingRate::RateValue & r);
184
185unsigned ceiling(const ProcessingRate::RateValue & r);
186
187bool permits(const Kernel * const hostKernel, const Binding & host,
188             const Kernel * const visitorKernel, const Binding & visitor);
189
190}
191
192#endif // PROCESSING_RATE_H
Note: See TracBrowser for help on using the repository browser.