source: icGREP/icgrep-devel/icgrep/pablo/pablo_kernel.cpp @ 5418

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

Removed non-functional CUDA code from icgrep and consolidated grep and multigrep mode into a single function; allowed segment parallel pipeline to utilize process as its initial thread; modified MMapSourceKernel to map and perform mmap directly and advise the OS to drop consumed data streams.

File size: 6.3 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#include "pablo_kernel.h"
7#include <pablo/codegenstate.h>
8#include <pablo/pablo_compiler.h>
9#include <pablo/pe_var.h>
10#include <pablo/pe_zeroes.h>
11#include <pablo/pe_ones.h>
12#include <pablo/pablo_toolchain.h>
13#include "llvm/Support/Debug.h"
14
15using namespace pablo;
16using namespace kernel;
17using namespace parabix;
18using namespace IDISA;
19using namespace llvm;
20
21inline bool isStreamType(const Type * ty) {
22    if (ty->isArrayTy()) {
23        ty = ty->getArrayElementType();
24    }
25    if (ty->isVectorTy()) {
26        return (ty->getVectorNumElements() == 0);
27    }
28    return false;
29}
30
31Var * PabloKernel::getInputStreamVar(const std::string & name) {
32    Port port; unsigned index;
33    std::tie(port, index) = getStreamPort(name);
34    assert (port == Port::Input);
35    return mInputs[index];
36}
37
38Var * PabloKernel::getOutputStreamVar(const std::string & name) {
39    Port port; unsigned index;
40    std::tie(port, index) = getStreamPort(name);
41    assert (port == Port::Output);
42    return mOutputs[index];
43}
44
45Var * PabloKernel::getOutputScalarVar(const std::string & name) {
46    const auto f = mScalarOutputNameMap.find(name);
47    if (LLVM_UNLIKELY(f == mScalarOutputNameMap.end())) {
48        report_fatal_error("Kernel does not contain scalar: " + name);
49    }
50    return f->second;
51}
52
53Var * PabloKernel::addInput(const std::string & name, Type * const type) {
54    Var * param = new (mAllocator) Var(mSymbolTable->makeString(name, iBuilder), type, mAllocator, Var::KernelInputParameter);
55    param->addUser(this);
56    mInputs.push_back(param);
57    mVariables.push_back(param);
58    if (isStreamType(type)) {
59        mStreamMap.emplace(name, std::make_pair(Port::Input, mStreamSetInputs.size()));
60        mStreamSetInputs.emplace_back(type, name);       
61    } else {
62        mScalarInputs.emplace_back(type, name);
63        param->setScalar();
64    }
65    assert (mStreamSetInputs.size() + mScalarInputs.size() == mInputs.size());
66    return param;
67}
68
69Var * PabloKernel::addOutput(const std::string & name, Type * const type) {
70    Var * result = new (mAllocator) Var(mSymbolTable->makeString(name, iBuilder), type, mAllocator, Var::KernelOutputParameter);
71    result->addUser(this);
72    mOutputs.push_back(result);
73    mVariables.push_back(result);
74    if (isStreamType(type)) {
75        mStreamMap.emplace(name, std::make_pair(Port::Output, mStreamSetOutputs.size()));
76        mStreamSetOutputs.emplace_back(type, name);
77    } else {
78        mScalarOutputs.emplace_back(type, name);
79        mScalarOutputNameMap.emplace(name, result);
80        result->setScalar();
81    }
82    assert (mStreamSetOutputs.size() + mScalarOutputs.size() == mOutputs.size());
83    return result;
84}
85
86Var * PabloKernel::makeVariable(String * name, Type * const type) {
87    Var * const var = new (mAllocator) Var(name, type, mAllocator);
88    mVariables.push_back(var);
89    return var;
90}
91
92Zeroes * PabloKernel::getNullValue(Type * type) {
93    if (type == nullptr) {
94        type = getStreamTy();
95    }
96    for (PabloAST * constant : mConstants) {
97        if (isa<Zeroes>(constant) && constant->getType() == type) {
98            return cast<Zeroes>(constant);
99        }
100    }
101    Zeroes * value = new (mAllocator) Zeroes(type, mAllocator);
102    mConstants.push_back(value);
103    return value;
104}
105
106Ones * PabloKernel::getAllOnesValue(Type * type) {
107    if (type == nullptr) {
108        type = getStreamTy();
109    }
110    for (PabloAST * constant : mConstants) {
111        if (isa<Ones>(constant) && constant->getType() == type) {
112            return cast<Ones>(constant);
113        }
114    }
115    Ones * value = new (mAllocator) Ones(type, mAllocator);
116    mConstants.push_back(value);
117    return value;
118}
119
120void PabloKernel::prepareKernel() {
121    mPabloCompiler->initializeKernelData();
122    BlockOrientedKernel::prepareKernel();
123}
124
125void PabloKernel::generateDoBlockMethod() {
126    mPabloCompiler->compile();
127}
128
129void PabloKernel::generateFinalBlockMethod(Value * remainingBytes) {
130    // Standard Pablo convention for final block processing: set a bit marking
131    // the position just past EOF, as well as a mask marking all positions past EOF.
132    setScalarField("EOFbit", iBuilder->bitblock_set_bit(remainingBytes));
133    setScalarField("EOFmask", iBuilder->bitblock_mask_from(remainingBytes));
134    CreateDoBlockMethodCall();
135}
136
137PabloKernel::PabloKernel(IDISA::IDISA_Builder * builder, std::string kernelName,
138                         std::vector<Binding> stream_inputs,
139                         std::vector<Binding> stream_outputs,
140                         std::vector<Binding> scalar_parameters,
141                         std::vector<Binding> scalar_outputs)
142: BlockOrientedKernel(builder, std::move(kernelName), 
143                      std::move(stream_inputs), std::move(stream_outputs), 
144                      std::move(scalar_parameters), std::move(scalar_outputs),
145                      {Binding{builder->getBitBlockType(), "EOFbit"}, Binding{builder->getBitBlockType(), "EOFmask"}})
146, PabloAST(PabloAST::ClassTypeId::Kernel, nullptr, mAllocator)
147, mPabloCompiler(new PabloCompiler(this))
148, mSymbolTable(new SymbolGenerator(mAllocator))
149, mEntryBlock(PabloBlock::Create(this)) {
150    prepareStreamSetNameMap();
151    for (const Binding & ss : mStreamSetInputs) {
152        Var * param = new (mAllocator) Var(mSymbolTable->makeString(ss.name, iBuilder), ss.type, mAllocator, Var::KernelInputParameter);
153        param->addUser(this);
154        mInputs.push_back(param);
155        mVariables.push_back(param);
156    }
157    for (const Binding & ss : mStreamSetOutputs) {
158        Var * result = new (mAllocator) Var(mSymbolTable->makeString(ss.name, iBuilder), ss.type, mAllocator, Var::KernelOutputParameter);
159        result->addUser(this);
160        mOutputs.push_back(result);
161        mVariables.push_back(result);
162    }
163    for (const Binding & ss : mScalarOutputs) {
164        Var * result = new (mAllocator) Var(mSymbolTable->makeString(ss.name, iBuilder), ss.type, mAllocator, Var::KernelOutputParameter);
165        result->addUser(this);
166        mOutputs.push_back(result);
167        mVariables.push_back(result);
168        mScalarOutputNameMap.emplace(ss.name, result);
169        result->setScalar();
170    }
171    if (DebugOptionIsSet(DumpTrace)) {
172        setName(getName() + "_DumpTrace");
173    }
174}
175
176PabloKernel::~PabloKernel() {
177    delete mPabloCompiler;
178    delete mSymbolTable; 
179}
180
Note: See TracBrowser for help on using the repository browser.