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
RevLine 
[5706]1#ifndef PROCESSING_RATE_H
2#define PROCESSING_RATE_H
3
4#include <string>
5#include <assert.h>
[5755]6#include <boost/rational.hpp>
[5706]7
8namespace kernel {
9
[5782]10// Processing rate attributes are required for all stream set bindings. They describe
11// the relationship between processed items (inputs) and produced items (outputs).
[5706]12//
[5782]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.
[5706]18//
[5782]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.
[5706]21
[5782]22
23
24
[5706]25struct ProcessingRate  {
26
[5755]27    friend struct Binding;
28
[5706]29    enum class KindId {
[5755]30        Fixed, Bounded, Unknown, Relative, PopCount
[5706]31    };
32
[5755]33    using RateValue = boost::rational<unsigned>;
34
[5706]35    KindId getKind() const { return mKind; }
36
[5755]37    RateValue getRate() const {
38        assert (isFixed() || isRelative());
39        return mLowerBound;
[5706]40    }
41
[5755]42    RateValue getLowerBound() const {
[5706]43        assert (isFixed() || isBounded() || isUnknown());
[5755]44        return mLowerBound;
[5706]45    }
46
[5755]47    RateValue getUpperBound() const {
[5706]48        assert (isFixed() || isBounded());
[5755]49        assert (isFixed() ? mUpperBound == mLowerBound : mUpperBound > mLowerBound);
50        return mUpperBound;
[5706]51    }
52
53    const std::string & getReference() const {
[5755]54        assert (isRelative());
[5706]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
[5755]66    bool isRelative() const {
67        return mKind == KindId::Relative;
[5706]68    }
69
[5755]70    bool isPopCount() const {
71        return mKind == KindId::PopCount;
72    }
73
[5706]74    bool isUnknown() const {
75        return mKind == KindId::Unknown;
76    }
77
78    bool isDerived() const {
[5755]79        return isRelative(); // isFixed() ||
[5706]80    }
81
82    bool operator == (const ProcessingRate & other) const {
[5755]83        return mKind == other.mKind && mLowerBound == other.mLowerBound && mUpperBound == other.mUpperBound && mReference == other.mReference;
[5706]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);
[5755]94    friend ProcessingRate PopcountOf(std::string, const ProcessingRate::RateValue);
[5706]95
[5755]96    ProcessingRate(ProcessingRate &&) = default;
97    ProcessingRate(const ProcessingRate &) = default;
98    ProcessingRate & operator = (const ProcessingRate & other) = default;
[5706]99
[5755]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) {}
[5706]103private:
104    KindId mKind;
[5755]105    RateValue mLowerBound;
106    RateValue mUpperBound;
[5706]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) {
[5756]115    using RateValue = boost::rational<unsigned>;
[5706]116    if (lower == upper) {
117        return FixedRate(lower);
118    } else {
[5756]119        return ProcessingRate(ProcessingRate::KindId::Bounded, RateValue(lower), RateValue(upper));
[5706]120    }
121}
122
[5755]123/**
124 * @brief UnknownRate
125 *
126 * The produced item count per stride should never be dependent on an unknown rate input stream.
127 */
[5706]128inline ProcessingRate UnknownRate(const unsigned lower = 0) {
129    return ProcessingRate(ProcessingRate::KindId::Unknown, lower, 0);
130}
131
132inline ProcessingRate RateEqualTo(std::string ref) {
[5755]133    return ProcessingRate(ProcessingRate::KindId::Relative, 1, 0, std::move(ref));
[5706]134}
135
[5755]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));
[5706]138}
139
[5755]140ProcessingRate::RateValue lcm(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
141
142ProcessingRate::RateValue gcd(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
143
[5782]144unsigned ceiling(const ProcessingRate::RateValue & r);
145
[5755]146}
147
[5706]148#endif // PROCESSING_RATE_H
Note: See TracBrowser for help on using the repository browser.