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

Last change on this file since 6133 was 5985, checked in by nmedfort, 15 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
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 {
[5985]30        Fixed, Bounded, Unknown, Relative, PopCount, NegatedPopCount
[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        return mLowerBound;
[5706]39    }
40
[5755]41    RateValue getLowerBound() const {
42        return mLowerBound;
[5706]43    }
44
[5755]45    RateValue getUpperBound() const {
46        return mUpperBound;
[5706]47    }
48
49    const std::string & getReference() const {
[5985]50        assert (hasReference());
[5706]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
[5755]62    bool isRelative() const {
63        return mKind == KindId::Relative;
[5706]64    }
65
[5755]66    bool isPopCount() const {
67        return mKind == KindId::PopCount;
68    }
69
[5985]70    bool isNegatedPopCount() const {
71        return mKind == KindId::NegatedPopCount;
72    }
73
[5706]74    bool isUnknown() const {
75        return mKind == KindId::Unknown;
76    }
77
[5985]78    bool hasReference() const {
79        return isRelative() || isPopCount() || isNegatedPopCount();
80    }
81
[5706]82    bool isDerived() const {
[5985]83        return isRelative();
[5706]84    }
85
86    bool operator == (const ProcessingRate & other) const {
[5755]87        return mKind == other.mKind && mLowerBound == other.mLowerBound && mUpperBound == other.mUpperBound && mReference == other.mReference;
[5706]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);
[5985]98    friend ProcessingRate PopcountOf(std::string);
99    friend ProcessingRate PopcountOfNot(std::string);
[5706]100
[5755]101    ProcessingRate(ProcessingRate &&) = default;
102    ProcessingRate(const ProcessingRate &) = default;
103    ProcessingRate & operator = (const ProcessingRate & other) = default;
[5706]104
[5755]105protected:   
[5985]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    }
[5706]113private:
[5985]114    const KindId mKind;
115    const RateValue mLowerBound;
116    const RateValue mUpperBound;
117    const std::string mReference;
[5706]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) {
[5756]125    using RateValue = boost::rational<unsigned>;
[5706]126    if (lower == upper) {
127        return FixedRate(lower);
128    } else {
[5756]129        return ProcessingRate(ProcessingRate::KindId::Bounded, RateValue(lower), RateValue(upper));
[5706]130    }
131}
132
[5755]133/**
134 * @brief UnknownRate
135 *
136 * The produced item count per stride should never be dependent on an unknown rate input stream.
137 */
[5706]138inline ProcessingRate UnknownRate(const unsigned lower = 0) {
139    return ProcessingRate(ProcessingRate::KindId::Unknown, lower, 0);
140}
141
142inline ProcessingRate RateEqualTo(std::string ref) {
[5985]143    return ProcessingRate(ProcessingRate::KindId::Relative, 1, 1, std::move(ref));
[5706]144}
145
[5985]146inline ProcessingRate PopcountOf(std::string ref) {
147    return ProcessingRate(ProcessingRate::KindId::PopCount, 0, 1, std::move(ref));
[5706]148}
149
[5985]150inline ProcessingRate PopcountOfNot(std::string ref) {
151    return ProcessingRate(ProcessingRate::KindId::NegatedPopCount, 0, 1, std::move(ref));
152}
153
[5755]154ProcessingRate::RateValue lcm(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
155
156ProcessingRate::RateValue gcd(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
157
[5782]158unsigned ceiling(const ProcessingRate::RateValue & r);
159
[5755]160}
161
[5706]162#endif // PROCESSING_RATE_H
Note: See TracBrowser for help on using the repository browser.