source: icGREP/icgrep-devel/icgrep/kernels/kernel.h @ 5240

Last change on this file since 5240 was 5240, checked in by nmedfort, 3 years ago

Cleaned up memory leaks + some warning messages.

File size: 6.5 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_BUILDER_H
7#define KERNEL_BUILDER_H
8
9
10#include "streamset.h"
11#include "interface.h"
12#include <vector>
13#include <llvm/IR/Type.h>
14#include <IR_Gen/idisa_builder.h>
15#include <boost/container/flat_map.hpp>
16
17const std::string blockNoScalar = "blockNo";
18const std::string logicalSegmentNoScalar = "logicalSegNo";
19const std::string processedItemCount = "processedItemCount";
20const std::string producedItemCount = "producedItemCount";
21const std::string terminationSignal = "terminationSignal";
22const std::string structPtrSuffix = "_structPtr";
23const std::string blkMaskSuffix = "_blkMask";
24
25using namespace parabix;
26namespace kernel {
27   
28class KernelBuilder : public KernelInterface {
29    using NameMap = boost::container::flat_map<std::string, unsigned>;
30
31public:
32    KernelBuilder(IDISA::IDISA_Builder * builder,
33                    std::string kernelName,
34                    std::vector<Binding> stream_inputs,
35                    std::vector<Binding> stream_outputs,
36                    std::vector<Binding> scalar_parameters,
37                    std::vector<Binding> scalar_outputs,
38                    std::vector<Binding> internal_scalars);
39   
40    // Create a module for the kernel, including the kernel state type declaration and
41    // the full implementation of all required methods.     
42    //
43    std::unique_ptr<llvm::Module> createKernelModule(std::vector<StreamSetBuffer *> input_buffers, std::vector<StreamSetBuffer *> output_buffers);
44   
45    // Generate the Kernel to the current module (iBuilder->getModule()).
46    void generateKernel(std::vector<StreamSetBuffer *> input_buffers, std::vector<StreamSetBuffer *> output_buffers);
47   
48    void createInstance() override;
49
50    Function * generateThreadFunction(std::string name);
51
52    Value * getBlockNo(Value * self);
53    virtual llvm::Value * getProcessedItemCount(llvm::Value * kernelInstance) override;
54    virtual llvm::Value * getProducedItemCount(llvm::Value * kernelInstance) override;
55    virtual void initializeKernelState(Value * self);
56    llvm::Value * getTerminationSignal(llvm::Value * kernelInstance) override;
57   
58    inline llvm::IntegerType * getSizeTy() {
59        return getBuilder()->getSizeTy();
60    }
61
62    inline Type * getStreamTy(const unsigned FieldWidth = 1) {
63        return getBuilder()->getStreamTy(FieldWidth);
64    }
65   
66    inline Type * getStreamSetTy(const unsigned NumElements = 1, const unsigned FieldWidth = 1) {
67        return getBuilder()->getStreamSetTy(NumElements, FieldWidth);
68    }
69   
70    // Synchronization actions for executing a kernel for a particular logical segment.
71    //
72    // Before the segment is processed, acquireLogicalSegmentNo must be used to load
73    // the segment number of the kernel state to ensure that the previous segment is
74    // complete (by checking that the acquired segment number is equal to the desired segment
75    // number).
76    // After all segment processing actions for the kernel are complete, and any necessary
77    // data has been extracted from the kernel for further pipeline processing, the
78    // segment number must be incremented and stored using releaseLogicalSegmentNo.
79    llvm::Value * acquireLogicalSegmentNo(llvm::Value * kernelInstance);
80    void releaseLogicalSegmentNo(llvm::Value * kernelInstance, Value * newFieldVal);
81
82
83protected:
84    //
85    // Kernel builder subtypes define their logic of kernel construction
86    // in terms of 3 virtual methods for
87    // (a) preparing the Kernel state data structure
88    // (b) defining the logic of the doBlock function, and
89    // (c) defining the logic of the finalBlock function.
90    //
91    // Note: the kernel state data structure must only be finalized after
92    // all scalar fields have been added.   If there are no fields to
93    // be added, the default method for preparing kernel state may be used.
94   
95    virtual void prepareKernel();
96   
97    // Each kernel builder subtype must provide its own logic for generating
98    // doBlock calls.
99    virtual void generateDoBlockMethod() = 0;
100    virtual void generateDoBlockLogic(Value * self, Value * blockNo);
101
102    // Each kernel builder subtypre must also specify the logic for processing the
103    // final block of stream data, if there is any special processing required
104    // beyond simply calling the doBlock function.   In the case that the final block
105    // processing may be trivially implemented by dispatching to the doBlock method
106    // without additional preparation, the default generateFinalBlockMethod need
107    // not be overridden.
108   
109    virtual void generateFinalBlockMethod();
110   
111    virtual void generateDoSegmentMethod();
112   
113    // Add an additional scalar field to the KernelState struct.
114    // Must occur before any call to addKernelDeclarations or createKernelModule.
115    unsigned addScalar(llvm::Type * type, std::string name);
116
117    unsigned getScalarCount() const;
118
119    // Run-time access of Kernel State and parameters of methods for
120    // use in implementing kernels.
121   
122    // Get the index of a named scalar field within the kernel state struct.
123    ConstantInt * getScalarIndex(const std::string & name) const;
124   
125    // Get the value of a scalar field for a given instance.
126    llvm::Value * getScalarField(llvm::Value * self, std::string fieldName);
127
128    // Set the value of a scalar field for a given instance.
129    void setScalarField(llvm::Value * self, std::string fieldName, llvm::Value * newFieldVal);
130   
131    // Get a parameter by name.
132    llvm::Value * getParameter(llvm::Function * f, std::string paramName);
133   
134    // Stream set helpers.
135    unsigned getStreamSetIndex(std::string name);
136   
137    llvm::Value * getScalarFieldPtr(Value * self, const std::string & name);
138
139    llvm::Value * getStreamSetStructPtr(Value * self, std::string name);
140    size_t getStreamSetBufferSize(Value * self, std::string name);
141
142    llvm::Value * getStreamSetBlockPtr(Value * self, std::string name, Value * blockNo);
143   
144    void setBlockNo(Value * self, Value * newFieldVal);
145    virtual void setProcessedItemCount(llvm::Value * self, Value * newFieldVal);
146    virtual void setProducedItemCount(llvm::Value * self, Value * newFieldVal);
147    void setTerminationSignal(llvm::Value * self);
148
149protected:
150
151    std::vector<llvm::Type *>  mKernelFields;
152    NameMap                    mKernelMap;
153    NameMap                    mStreamSetNameMap;
154    std::vector<StreamSetBuffer *> mStreamSetInputBuffers;
155    std::vector<StreamSetBuffer *> mStreamSetOutputBuffers;
156
157};
158}
159#endif
Note: See TracBrowser for help on using the repository browser.