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

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

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

File size: 5.4 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
[6184]8namespace llvm { class raw_ostream; }
9
[5706]10namespace kernel {
11
[5782]12// Processing rate attributes are required for all stream set bindings. They describe
13// the relationship between processed items (inputs) and produced items (outputs).
[5706]14//
[5782]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.
[5706]20//
[5782]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.
[5706]23
[6184]24class Kernel;
[6253]25struct Binding;
[5782]26
[5706]27struct ProcessingRate  {
28
[5755]29    friend struct Binding;
30
[5706]31    enum class KindId {
[6184]32        Fixed, Bounded, PopCount, NegatedPopCount, Unknown, Relative, Greedy
[5706]33    };
34
[5755]35    using RateValue = boost::rational<unsigned>;
36
[5706]37    KindId getKind() const { return mKind; }
38
[5755]39    RateValue getRate() const {
40        return mLowerBound;
[5706]41    }
42
[5755]43    RateValue getLowerBound() const {
44        return mLowerBound;
[5706]45    }
46
[5755]47    RateValue getUpperBound() const {
[6184]48        assert (!isGreedy());
[5755]49        return mUpperBound;
[5706]50    }
51
52    const std::string & getReference() const {
[5985]53        assert (hasReference());
[5706]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
[6184]65    bool isGreedy() const {
66        return mKind == KindId::Greedy;
67    }
68
[5755]69    bool isRelative() const {
70        return mKind == KindId::Relative;
[5706]71    }
72
[5755]73    bool isPopCount() const {
74        return mKind == KindId::PopCount;
75    }
76
[5985]77    bool isNegatedPopCount() const {
78        return mKind == KindId::NegatedPopCount;
79    }
80
[5706]81    bool isUnknown() const {
82        return mKind == KindId::Unknown;
83    }
84
[5985]85    bool hasReference() const {
86        return isRelative() || isPopCount() || isNegatedPopCount();
87    }
88
[5706]89    bool isDerived() const {
[5985]90        return isRelative();
[5706]91    }
92
93    bool operator == (const ProcessingRate & other) const {
[5755]94        return mKind == other.mKind && mLowerBound == other.mLowerBound && mUpperBound == other.mUpperBound && mReference == other.mReference;
[5706]95    }
96
97    bool operator != (const ProcessingRate & other) const {
98        return !(*this == other);
99    }
100
[6184]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
[6228]113    friend ProcessingRate FixedRate(const unsigned);
[5706]114    friend ProcessingRate BoundedRate(const unsigned, const unsigned);
115    friend ProcessingRate UnknownRate(const unsigned);
116    friend ProcessingRate RateEqualTo(std::string);
[5985]117    friend ProcessingRate PopcountOf(std::string);
118    friend ProcessingRate PopcountOfNot(std::string);
[6184]119    friend ProcessingRate Greedy();
[5706]120
[5755]121    ProcessingRate(ProcessingRate &&) = default;
122    ProcessingRate(const ProcessingRate &) = default;
123    ProcessingRate & operator = (const ProcessingRate & other) = default;
[5706]124
[6228]125protected:
[6184]126
[5985]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) {
[6184]132
[5985]133    }
[6184]134
135    void print(const Kernel * const kernel, llvm::raw_ostream & out) const noexcept;
136
[5706]137private:
[5985]138    const KindId mKind;
139    const RateValue mLowerBound;
140    const RateValue mUpperBound;
141    const std::string mReference;
[5706]142};
143
144inline ProcessingRate FixedRate(const unsigned rate = 1) {
[6184]145    assert (rate > 0);
[5706]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 {
[6184]153        assert (upper > lower);
154        return ProcessingRate(ProcessingRate::KindId::Bounded, ProcessingRate::RateValue(lower), ProcessingRate::RateValue(upper));
[5706]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) {
[5985]163    return ProcessingRate(ProcessingRate::KindId::Relative, 1, 1, std::move(ref));
[5706]164}
165
[5985]166inline ProcessingRate PopcountOf(std::string ref) {
167    return ProcessingRate(ProcessingRate::KindId::PopCount, 0, 1, std::move(ref));
[5706]168}
169
[5985]170inline ProcessingRate PopcountOfNot(std::string ref) {
171    return ProcessingRate(ProcessingRate::KindId::NegatedPopCount, 0, 1, std::move(ref));
172}
173
[6184]174inline ProcessingRate Greedy() {
175    return ProcessingRate(ProcessingRate::KindId::Greedy, 0, 0);
176}
177
178
[5755]179ProcessingRate::RateValue lcm(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
180
181ProcessingRate::RateValue gcd(const ProcessingRate::RateValue & x, const ProcessingRate::RateValue & y);
182
[6184]183unsigned floor(const ProcessingRate::RateValue & r);
184
[5782]185unsigned ceiling(const ProcessingRate::RateValue & r);
186
[6253]187bool permits(const Kernel * const hostKernel, const Binding & host,
188             const Kernel * const visitorKernel, const Binding & visitor);
189
[5755]190}
191
[5706]192#endif // PROCESSING_RATE_H
Note: See TracBrowser for help on using the repository browser.