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

Last change on this file since 5941 was 5782, checked in by nmedfort, 20 months ago

Initial check-in of LookAhead? support; modified LineBreakKernel? to compute CR+LF using LookAhead?(1) + misc. fixes.

File size: 4.6 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
31    };
32
33    using RateValue = boost::rational<unsigned>;
34
35    KindId getKind() const { return mKind; }
36
37    RateValue getRate() const {
38        assert (isFixed() || isRelative());
39        return mLowerBound;
40    }
41
42    RateValue getLowerBound() const {
43        assert (isFixed() || isBounded() || isUnknown());
44        return mLowerBound;
45    }
46
47    RateValue getUpperBound() const {
48        assert (isFixed() || isBounded());
49        assert (isFixed() ? mUpperBound == mLowerBound : mUpperBound > mLowerBound);
50        return mUpperBound;
51    }
52
53    const std::string & getReference() const {
54        assert (isRelative());
55        return mReference;
56    }
57
58    bool isFixed() const {
59        return mKind == KindId::Fixed;
60    }
61
62    bool isBounded() const {
63        return mKind == KindId::Bounded;
64    }
65
66    bool isRelative() const {
67        return mKind == KindId::Relative;
68    }
69
70    bool isPopCount() const {
71        return mKind == KindId::PopCount;
72    }
73
74    bool isUnknown() const {
75        return mKind == KindId::Unknown;
76    }
77
78    bool isDerived() const {
79        return isRelative(); // isFixed() ||
80    }
81
82    bool operator == (const ProcessingRate & other) const {
83        return mKind == other.mKind && mLowerBound == other.mLowerBound && mUpperBound == other.mUpperBound && mReference == other.mReference;
84    }
85
86    bool operator != (const ProcessingRate & other) const {
87        return !(*this == other);
88    }
89
90    friend ProcessingRate FixedRate(const unsigned);
91    friend ProcessingRate BoundedRate(const unsigned, const unsigned);
92    friend ProcessingRate UnknownRate(const unsigned);
93    friend ProcessingRate RateEqualTo(std::string);
94    friend ProcessingRate PopcountOf(std::string, const ProcessingRate::RateValue);
95
96    ProcessingRate(ProcessingRate &&) = default;
97    ProcessingRate(const ProcessingRate &) = default;
98    ProcessingRate & operator = (const ProcessingRate & other) = default;
99
100protected:   
101    ProcessingRate(const KindId k, const unsigned n, const unsigned m, const std::string && ref = "") : mKind(k), mLowerBound(n), mUpperBound(m), mReference(ref) {}
102    ProcessingRate(const KindId k, const RateValue n, const RateValue m, const std::string && ref = "") : mKind(k), mLowerBound(n), mUpperBound(m), mReference(ref) {}
103private:
104    KindId mKind;
105    RateValue mLowerBound;
106    RateValue mUpperBound;
107    std::string mReference;
108};
109
110inline ProcessingRate FixedRate(const unsigned rate = 1) {
111    return ProcessingRate(ProcessingRate::KindId::Fixed, rate, rate);
112}
113
114inline ProcessingRate BoundedRate(const unsigned lower, const unsigned upper) {
115    using RateValue = boost::rational<unsigned>;
116    if (lower == upper) {
117        return FixedRate(lower);
118    } else {
119        return ProcessingRate(ProcessingRate::KindId::Bounded, RateValue(lower), RateValue(upper));
120    }
121}
122
123/**
124 * @brief UnknownRate
125 *
126 * The produced item count per stride should never be dependent on an unknown rate input stream.
127 */
128inline ProcessingRate UnknownRate(const unsigned lower = 0) {
129    return ProcessingRate(ProcessingRate::KindId::Unknown, lower, 0);
130}
131
132inline ProcessingRate RateEqualTo(std::string ref) {
133    return ProcessingRate(ProcessingRate::KindId::Relative, 1, 0, std::move(ref));
134}
135
136inline ProcessingRate PopcountOf(std::string ref, const ProcessingRate::RateValue ratio = ProcessingRate::RateValue{1}) {
137    return ProcessingRate(ProcessingRate::KindId::PopCount, ratio, ProcessingRate::RateValue{0}, std::move(ref));
138}
139
140ProcessingRate::RateValue lcm(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
141
142ProcessingRate::RateValue gcd(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
143
144unsigned ceiling(const ProcessingRate::RateValue & r);
145
146}
147
148#endif // PROCESSING_RATE_H
Note: See TracBrowser for help on using the repository browser.