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

Last change on this file since 6014 was 5985, checked in by nmedfort, 14 months ago

Restructured MultiBlock? kernel. Removal of Swizzled buffers. Inclusion of PopCount? rates / non-linear access. Modifications to several kernels to better align them with the kernel and pipeline changes.

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