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

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

Continued work on processing stdin input. Partial integration of ParabixDriver? methods into icgrep and editd. Object cache does not currently work for recursive REs.

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