source: icGREP/icgrep-devel/icgrep/kernels/u8u16_pipeline.cpp @ 5009

Last change on this file since 5009 was 5009, checked in by cameron, 2 years ago

u8u16 transcoder demo program now working

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#include <kernels/u8u16_pipeline.h>
7#include <utf_encoding.h>
8
9#include <kernels/s2p_kernel.h>
10#include <kernels/deletion.h>
11#include <kernels/p2s_kernel.h>
12#include <kernels/stdout_kernel.h>
13#include <kernels/instance.h>
14
15#include <pablo/function.h>
16#include <pablo/pablo_compiler.h>
17#include <pablo/pablo_toolchain.h>
18
19static cl::opt<unsigned> SegmentSize("segment-size", cl::desc("Segment Size"), cl::value_desc("positive integer"), cl::init(1));
20
21
22using namespace pablo;
23using namespace kernel;
24
25PipelineBuilder::PipelineBuilder(Module * m, IDISA::IDISA_Builder * b)
26: mMod(m)
27, iBuilder(b)
28, mBitBlockType(b->getBitBlockType())
29, mBlockSize(b->getBitBlockWidth()){
30
31}
32
33PipelineBuilder::~PipelineBuilder(){
34    delete mS2PKernel;
35    delete mU8U16Kernel;
36    delete mDelKernel;
37    delete mP2SKernel;
38    //delete mStdOutKernel;
39}
40
41void PipelineBuilder::CreateKernels(PabloFunction * function){
42    mS2PKernel = new KernelBuilder(iBuilder, "s2p", SegmentSize);
43    mU8U16Kernel = new KernelBuilder(iBuilder, "u8u16", SegmentSize);
44    mDelKernel = new KernelBuilder(iBuilder, "del", SegmentSize);
45    mP2SKernel = new KernelBuilder(iBuilder, "p2s", SegmentSize);   
46    //mStdOutKernel = new KernelBuilder(iBuilder, "stdout", SegmentSize);
47
48    generateS2PKernel(mMod, iBuilder, mS2PKernel);
49    generateP2S_16_withCompressedOutputKernel(mMod, iBuilder, mP2SKernel);
50    generateDeletionKernel(mMod, iBuilder, iBuilder->getBitBlockWidth()/16, /*stream_count=*/16, mDelKernel);
51    //generateStdOutKernel(mMod, iBuilder, mStdOutKernel, 16);
52
53    pablo_function_passes(function);
54
55    PabloCompiler pablo_compiler(mMod, iBuilder);
56    try {
57        pablo_compiler.setKernel(mU8U16Kernel);
58        pablo_compiler.compile(function);
59        delete function;
60        releaseSlabAllocatorMemory();
61    } catch (std::runtime_error e) {
62        delete function;
63        releaseSlabAllocatorMemory();
64        std::cerr << "Runtime error: " << e.what() << std::endl;
65        exit(1);
66    }
67   
68}
69
70Function *  PipelineBuilder::ExecuteKernels() {
71    Type * const int64ty = iBuilder->getInt64Ty();
72    Type * const inputType = PointerType::get(ArrayType::get(StructType::get(mMod->getContext(), std::vector<Type *>({ArrayType::get(mBitBlockType, 8)})), 1), 0);
73   
74    Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, int64ty, nullptr));
75    main->setCallingConv(CallingConv::C);
76    Function::arg_iterator args = main->arg_begin();
77   
78    Value * const inputStream = args++;
79    inputStream->setName("input");
80    Value * const bufferSize = args++;
81    bufferSize->setName("bufferSize");
82   
83    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", main,0));
84   
85    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
86
87    BasicBlock * segmentCondBlock = nullptr;
88    BasicBlock * segmentBodyBlock = nullptr;
89    const unsigned segmentSize = SegmentSize;
90    if (segmentSize > 1) {
91        segmentCondBlock = BasicBlock::Create(mMod->getContext(), "segmentCond", main, 0);
92        segmentBodyBlock = BasicBlock::Create(mMod->getContext(), "segmentBody", main, 0);
93    }
94    BasicBlock * fullCondBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
95    BasicBlock * fullBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
96    BasicBlock * finalBlock = BasicBlock::Create(mMod->getContext(), "final", main, 0);
97    BasicBlock * finalPartialBlock = BasicBlock::Create(mMod->getContext(), "partial", main, 0);
98    BasicBlock * finalEmptyBlock = BasicBlock::Create(mMod->getContext(), "empty", main, 0);
99    BasicBlock * endBlock = BasicBlock::Create(mMod->getContext(), "end", main, 0);
100
101    Instance * s2pInstance = mS2PKernel->instantiate(inputStream);
102    Instance * u8u16Instance = mU8U16Kernel->instantiate(s2pInstance->getOutputStreamSet());
103    Instance * delInstance = mDelKernel->instantiate(u8u16Instance->getOutputStreamSet());
104    Instance * p2sInstance = mP2SKernel->instantiate(delInstance->getOutputStreamSet());
105
106   
107    Value * initialBufferSize = nullptr;
108    BasicBlock * initialBlock = nullptr;
109   
110    if (segmentSize > 1) {
111        iBuilder->CreateBr(segmentCondBlock);
112        iBuilder->SetInsertPoint(segmentCondBlock);
113        PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
114        remainingBytes->addIncoming(bufferSize, entryBlock);
115        Constant * const step = ConstantInt::get(int64ty, mBlockSize * segmentSize);
116        Value * segmentCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
117        iBuilder->CreateCondBr(segmentCondTest, fullCondBlock, segmentBodyBlock);
118        iBuilder->SetInsertPoint(segmentBodyBlock);
119        for (unsigned i = 0; i < segmentSize; ++i) {
120            s2pInstance->CreateDoBlockCall();
121        }
122        for (unsigned i = 0; i < segmentSize; ++i) {
123            u8u16Instance->CreateDoBlockCall();
124        }
125        for (unsigned i = 0; i < segmentSize; ++i) {
126            delInstance->CreateDoBlockCall();
127        }
128        for (unsigned i = 0; i < segmentSize; ++i) {
129            p2sInstance->CreateDoBlockCall();
130        }
131        remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), segmentBodyBlock);
132        iBuilder->CreateBr(segmentCondBlock);
133        initialBufferSize = remainingBytes;
134        initialBlock = segmentCondBlock;
135    } else {
136        initialBufferSize = bufferSize;
137        initialBlock = entryBlock;
138        iBuilder->CreateBr(fullCondBlock);
139    }
140
141    iBuilder->SetInsertPoint(fullCondBlock);
142    PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
143    remainingBytes->addIncoming(initialBufferSize, initialBlock);
144
145    Constant * const step = ConstantInt::get(int64ty, mBlockSize);
146    Value * fullCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
147    iBuilder->CreateCondBr(fullCondTest, finalBlock, fullBodyBlock);
148   
149    iBuilder->SetInsertPoint(fullBodyBlock);
150
151    s2pInstance->CreateDoBlockCall();
152    u8u16Instance->CreateDoBlockCall();
153    delInstance->CreateDoBlockCall();
154    p2sInstance->CreateDoBlockCall();
155
156    Value * diff = iBuilder->CreateSub(remainingBytes, step);
157
158    remainingBytes->addIncoming(diff, fullBodyBlock);
159    iBuilder->CreateBr(fullCondBlock);
160   
161    iBuilder->SetInsertPoint(finalBlock);
162    Value * emptyBlockCond = iBuilder->CreateICmpEQ(remainingBytes, ConstantInt::get(int64ty, 0));
163    iBuilder->CreateCondBr(emptyBlockCond, finalEmptyBlock, finalPartialBlock);
164   
165   
166    iBuilder->SetInsertPoint(finalPartialBlock);
167    s2pInstance->CreateDoBlockCall();
168    iBuilder->CreateBr(endBlock);
169   
170    iBuilder->SetInsertPoint(finalEmptyBlock);
171    s2pInstance->clearOutputStreamSet();
172    iBuilder->CreateBr(endBlock);
173   
174    iBuilder->SetInsertPoint(endBlock);
175
176    u8u16Instance->CreateDoBlockCall();
177    Value * remaining = iBuilder->CreateZExt(remainingBytes, iBuilder->getIntNTy(mBlockSize));
178    Value * EOF_del = iBuilder->bitCast(iBuilder->CreateShl(Constant::getAllOnesValue(iBuilder->getIntNTy(mBlockSize)), remaining));
179    Value * const delmask = u8u16Instance->getOutputStream(16);
180    iBuilder->CreateBlockAlignedStore(iBuilder->CreateOr(EOF_del, iBuilder->CreateBlockAlignedLoad(delmask)), delmask);
181    delInstance->CreateDoBlockCall();
182    p2sInstance->CreateDoBlockCall();
183    iBuilder->CreateRetVoid();
184    return main;
185}
Note: See TracBrowser for help on using the repository browser.