source: icGREP/icgrep-devel/icgrep/kernels/interface.h @ 5408

Last change on this file since 5408 was 5408, checked in by nmedfort, 2 years ago

First attempt to allow Kernels to wait for consumers to finish processing before performing a realloc.

File size: 7.4 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#ifndef KERNEL_INTERFACE_H
7#define KERNEL_INTERFACE_H
8
9#include <string>  // for string
10#include <vector>  // for vector
11namespace IDISA { class IDISA_Builder; }
12//namespace llvm { class ConstantInt; }
13#include <llvm/IR/Constants.h>
14namespace llvm { class Function; }
15namespace llvm { class Module; }
16namespace llvm { class PointerType; }
17namespace llvm { class StructType; }
18namespace llvm { class Type; }
19namespace llvm { class Value; }
20
21
22// Processing rate attributes are required for all stream set bindings for a kernel.
23// These attributes describe the number of items that are processed or produced as
24// a ratio in comparison to the principal input stream set (or the principal output
25// stream set if there is no input.
26//
27// The default ratio is FixedRatio(1) which means that there is one item processed or
28// produced for every item of the principal input or output stream.
29// FixedRatio(m, n) means that for every group of n items of the principal stream,
30// there are m items in the output stream (rounding up).
31//
32// Kernels which produce a variable number of items use MaxRatio(n), for a maximum
33// of n items produced or consumed per principal input or output item.  MaxRatio(m, n)
34// means there are at most m items for every n items of the principal stream.
35//
36// RoundUpToMultiple(n) means that number of items produced is the same as the
37// number of input items, rounded up to an exact multiple of n.
38//
39
40struct ProcessingRate  {
41    enum class ProcessingRateKind : uint8_t { Fixed, RoundUp, Add1, Max, Unknown };
42    ProcessingRateKind getKind() const {return mKind;}
43    bool isExact() const {return (mKind == ProcessingRateKind::Fixed)||(mKind == ProcessingRateKind::RoundUp)||(mKind == ProcessingRateKind::Add1) ;}
44    bool isUnknown() const { return !isExact(); }
45    llvm::Value * CreateRatioCalculation(IDISA::IDISA_Builder * b, llvm::Value * principalInputItems, llvm::Value * doFinal = nullptr) const;
46    friend ProcessingRate FixedRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string && referenceStreamSet);
47    friend ProcessingRate MaxRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string && referenceStreamSet);
48    friend ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string && referenceStreamSet);
49    friend ProcessingRate Add1(std::string && referenceStreamSet);
50    friend ProcessingRate UnknownRate();
51    std::string referenceStreamSet() const { return mReferenceStreamSet;}
52protected:
53    ProcessingRate(ProcessingRateKind k, unsigned numerator, unsigned denominator, std::string && referenceStreamSet)
54    : mKind(k), mRatioNumerator(numerator), mRatioDenominator(denominator), mReferenceStreamSet(referenceStreamSet) {}
55private:
56    const ProcessingRateKind mKind;
57    const uint16_t mRatioNumerator;
58    const uint16_t mRatioDenominator;
59    const std::string mReferenceStreamSet;
60}; 
61
62ProcessingRate FixedRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems = 1, std::string && referenceStreamSet = "");
63ProcessingRate MaxRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems = 1, std::string && referenceStreamSet = "");
64ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string &&referenceStreamSet = "");
65ProcessingRate Add1(std::string && referenceStreamSet = "");
66ProcessingRate UnknownRate();
67
68struct Binding {
69    Binding(llvm::Type * type, const std::string & name, ProcessingRate r = FixedRatio(1))
70    : type(type), name(name), rate(r) { }
71    llvm::Type * const        type;
72    const std::string         name;
73    const ProcessingRate      rate;
74};
75
76class KernelInterface {
77public:
78    /*
79     
80     This class defines the methods to be used to generate the code 
81     necessary for declaring, allocating, calling and synchronizing
82     kernels.   The methods to be used for constructing kernels are defined
83     within the KernelBuilder class of kernel.h
84     
85     */
86   
87    const std::string & getName() const { return mKernelName; }
88
89    void setName(std::string newName) { mKernelName = newName; }
90       
91    const std::vector<Binding> & getStreamInputs() const { return mStreamSetInputs; }
92
93    const std::vector<Binding> & getStreamOutputs() const { return mStreamSetOutputs; }
94
95    const std::vector<Binding> & getScalarInputs() const { return mScalarInputs; }
96
97    const std::vector<Binding> & getScalarOutputs() const { return mScalarOutputs; }
98       
99    // Add ExternalLinkage method declarations for the kernel to a given client module.
100    void addKernelDeclarations(llvm::Module * client);
101
102    virtual llvm::Value * createInstance() = 0;
103
104    virtual void initializeInstance() = 0;
105
106    void setInitialArguments(std::vector<llvm::Value *> args);
107
108    llvm::Value * getInstance() const {
109        return mKernelInstance;
110    }
111
112    unsigned getLookAhead() const {
113        return mLookAheadPositions;
114    }
115   
116    IDISA::IDISA_Builder * getBuilder() const {
117        return iBuilder;
118    }
119
120    virtual llvm::Value * getProducedItemCount(const std::string & name, llvm::Value * doFinal = nullptr) const = 0;
121
122    virtual void setProducedItemCount(const std::string & name, llvm::Value * value) const = 0;
123
124    virtual llvm::Value * getProcessedItemCount(const std::string & name) const = 0;
125
126    virtual void setProcessedItemCount(const std::string & name, llvm::Value * value) const = 0;
127
128    virtual llvm::Value * getTerminationSignal() const = 0;
129
130    virtual void setTerminationSignal() const = 0;
131   
132    void setLookAhead(unsigned lookAheadPositions) {
133        mLookAheadPositions = lookAheadPositions;
134    }
135
136    llvm::Function * getInitFunction() const;
137
138    llvm::Function * getDoSegmentFunction() const;
139
140    llvm::Function * getAccumulatorFunction(const std::string & accumName) const;
141
142protected:
143
144    KernelInterface(IDISA::IDISA_Builder * builder,
145                    std::string kernelName,
146                    std::vector<Binding> && stream_inputs,
147                    std::vector<Binding> && stream_outputs,
148                    std::vector<Binding> && scalar_inputs,
149                    std::vector<Binding> && scalar_outputs,
150                    std::vector<Binding> && internal_scalars)
151    : iBuilder(builder)
152    , mKernelInstance(nullptr)
153    , mKernelStateType(nullptr)
154    , mLookAheadPositions(0)
155    , mKernelName(kernelName)
156    , mStreamSetInputs(stream_inputs)
157    , mStreamSetOutputs(stream_outputs)
158    , mScalarInputs(scalar_inputs)
159    , mScalarOutputs(scalar_outputs)
160    , mInternalScalars(internal_scalars)
161    {
162
163    }
164   
165    void setInstance(llvm::Value * const instance) {
166        assert ("kernel instance cannot be null!" && instance);
167        assert ("kernel instance must point to a valid kernel state type!" && (instance->getType()->getPointerElementType() == mKernelStateType));
168        mKernelInstance = instance;
169    }
170
171protected:
172   
173    IDISA::IDISA_Builder * const    iBuilder;
174    llvm::Value *                   mKernelInstance;
175    llvm::StructType *              mKernelStateType;
176    unsigned                        mLookAheadPositions;
177    std::string                     mKernelName;
178    std::vector<llvm::Value *>      mInitialArguments;
179    std::vector<Binding>            mStreamSetInputs;
180    std::vector<Binding>            mStreamSetOutputs;
181    std::vector<Binding>            mScalarInputs;
182    std::vector<Binding>            mScalarOutputs;
183    std::vector<Binding>            mInternalScalars;
184};
185
186#endif
Note: See TracBrowser for help on using the repository browser.