source: icGREP/icgrep-devel/icgrep/kernels/stdout_kernel.cpp @ 5247

Last change on this file since 5247 was 5247, checked in by cameron, 11 months ago

Separate processedItemCounts and producedItemCounts for each stream set

File size: 5.7 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#include <kernels/stdout_kernel.h>
6#include <kernels/kernel.h>
7#include <IR_Gen/idisa_builder.h>
8
9namespace kernel {
10
11// The doBlock method is deprecated.   But in case it is used, just call doSegment with
12// 1 as the number of blocks to do.
13void StdOutKernel::generateDoBlockMethod() const {
14    auto savePoint = iBuilder->saveIP();
15    Module * m = iBuilder->getModule();
16    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
17    Function * doSegmentFunction = m->getFunction(mKernelName + doSegment_suffix);
18    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doBlockFunction, 0));
19    Value * self = getParameter(doBlockFunction, "self");
20    iBuilder->CreateCall(doSegmentFunction, {self, iBuilder->getSize(1)});
21    iBuilder->CreateRetVoid();
22    iBuilder->restoreIP(savePoint);
23}
24           
25// Rather than using doBlock logic to write one block at a time, this custom
26// doSegment method, writes the entire segment with a single write call.
27void StdOutKernel::generateDoSegmentMethod() const {
28    auto savePoint = iBuilder->saveIP();
29    Module * m = iBuilder->getModule();
30    Function * doSegmentFunction = m->getFunction(mKernelName + doSegment_suffix);
31    Type * i8PtrTy = iBuilder->getInt8PtrTy();
32   
33    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doSegmentFunction, 0));
34    BasicBlock * setTermination = BasicBlock::Create(iBuilder->getContext(), "setTermination", doSegmentFunction, 0);
35    BasicBlock * stdOutexit = BasicBlock::Create(iBuilder->getContext(), "stdOutexit", doSegmentFunction, 0);
36    Constant * blockItems = iBuilder->getSize(iBuilder->getBitBlockWidth());
37    Constant * itemBytes = iBuilder->getSize(mCodeUnitWidth/8);
38   
39    Function::arg_iterator args = doSegmentFunction->arg_begin();
40    Value * self = &*(args++);
41    Value * blocksToDo = &*(args);
42    ////iBuilder->CallPrintInt("blocksToDo", blocksToDo);
43    Value * streamStructPtr = getStreamSetStructPtr(self, "codeUnitBuffer");
44    //iBuilder->CallPrintInt("streamStructPtr", iBuilder->CreatePtrToInt(streamStructPtr, iBuilder->getInt64Ty()));
45
46    LoadInst * producerPos = iBuilder->CreateAtomicLoadAcquire(mStreamSetInputBuffers[0]->getProducerPosPtr(streamStructPtr));
47    //iBuilder->CallPrintInt("producerPos", producerPos);
48    Value * processed = getProcessedItemCount(self, "codeUnitBuffer");
49    Value * itemsAvail = iBuilder->CreateSub(producerPos, processed);
50    Value * itemsMax = iBuilder->CreateMul(blocksToDo, blockItems);
51    Value * lessThanFullSegment = iBuilder->CreateICmpULT(itemsAvail, itemsMax);
52    Value * itemsToDo = iBuilder->CreateSelect(lessThanFullSegment, itemsAvail, itemsMax);
53   
54    Value * blockNo = getScalarField(self, blockNoScalar);
55    //iBuilder->CallPrintInt("blockNo", blockNo);
56    Value * basePtr = getStreamSetBlockPtr(self, "codeUnitBuffer", blockNo);
57    //iBuilder->CallPrintInt("basePtr", iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty()));
58    Value * byteOffset = iBuilder->CreateMul(iBuilder->CreateURem(processed, blockItems), itemBytes);
59    Value * bytePtr = iBuilder->CreateGEP(iBuilder->CreateBitCast(basePtr, i8PtrTy), byteOffset);
60
61    iBuilder->CreateWriteCall(iBuilder->getInt32(1), bytePtr, iBuilder->CreateMul(itemsToDo, itemBytes));
62
63    processed = iBuilder->CreateAdd(processed, itemsToDo);
64    setProcessedItemCount(self, "codeUnitBuffer", processed);
65    setScalarField(self, blockNoScalar, iBuilder->CreateUDiv(processed, blockItems));
66    mStreamSetInputBuffers[0]->setConsumerPos(streamStructPtr, processed);
67
68    Value * endSignal = iBuilder->CreateLoad(mStreamSetInputBuffers[0]->getEndOfInputPtr(streamStructPtr));
69    Value * inFinalSegment = iBuilder->CreateAnd(endSignal, lessThanFullSegment);
70   
71    iBuilder->CreateCondBr(inFinalSegment, setTermination, stdOutexit);
72    iBuilder->SetInsertPoint(setTermination);
73
74    setTerminationSignal(self);
75
76    iBuilder->CreateBr(stdOutexit);
77    iBuilder->SetInsertPoint(stdOutexit);
78    iBuilder->CreateRetVoid();
79    iBuilder->restoreIP(savePoint);
80}
81
82void StdOutKernel::generateFinalBlockMethod() const {
83    auto savePoint = iBuilder->saveIP();
84    Module * m = iBuilder->getModule();
85    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
86    Type * i8PtrTy = iBuilder->getInt8PtrTy();
87   
88    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "fb_flush", finalBlockFunction, 0));
89    Constant * blockItems = iBuilder->getSize(iBuilder->getBitBlockWidth());
90    Constant * itemBytes = iBuilder->getSize(mCodeUnitWidth/8);
91    Value * self = getParameter(finalBlockFunction, "self");
92    Value * streamStructPtr = getStreamSetStructPtr(self, "codeUnitBuffer");
93    LoadInst * producerPos = iBuilder->CreateAtomicLoadAcquire(mStreamSetInputBuffers[0]->getProducerPosPtr(streamStructPtr));
94    Value * processed = getProcessedItemCount(self, "codeUnitBuffer");
95    Value * itemsAvail = iBuilder->CreateSub(producerPos, processed);
96    Value * blockNo = getScalarField(self, blockNoScalar);
97    Value * basePtr = getStreamSetBlockPtr(self, "codeUnitBuffer", blockNo);
98    Value * byteOffset = iBuilder->CreateMul(iBuilder->CreateURem(processed, blockItems), itemBytes);
99    Value * bytePtr = iBuilder->CreateGEP(iBuilder->CreateBitCast(basePtr, i8PtrTy), byteOffset);
100    iBuilder->CreateWriteCall(iBuilder->getInt32(1), bytePtr, iBuilder->CreateMul(itemsAvail, itemBytes));
101    setProcessedItemCount(self, "codeUnitBuffer", producerPos);
102    mStreamSetInputBuffers[0]->setConsumerPos(streamStructPtr, producerPos);
103    setTerminationSignal(self);
104    iBuilder->CreateRetVoid();
105    iBuilder->restoreIP(savePoint);
106}
107}
Note: See TracBrowser for help on using the repository browser.