source: icGREP/icgrep-devel/icgrep/kernels/stdin_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: 5.3 KB
Line 
1/*
2 *  Copyright (c) 2017 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5#include <kernels/stdin_kernel.h>
6#include <llvm/IR/Module.h>
7#include <kernels/kernel.h>
8#include <IR_Gen/idisa_builder.h>
9#include <llvm/Support/raw_ostream.h>
10
11using namespace llvm;
12
13inline static size_t round_up_to_nearest(const size_t x, const size_t y) {
14    return (((x - 1) | (y - 1)) + 1);
15}
16
17namespace kernel {
18
19void StdInKernel::generateDoSegmentMethod() {
20
21    BasicBlock * const entryBlock = iBuilder->GetInsertBlock();
22    BasicBlock * const readBlock = CreateBasicBlock("ReadMoreData");
23    BasicBlock * const setTermination = CreateBasicBlock("SetTermination");
24    BasicBlock * const stdInExit = CreateBasicBlock("StdInExit");
25
26    ConstantInt * const segmentSize = iBuilder->getSize(mSegmentBlocks * iBuilder->getBitBlockWidth());
27    Value * bufferedSize = getBufferedSize("InputStream");
28    Value * const itemsAlreadyRead = getProducedItemCount("InputStream");
29    Value * const bytesAlreadyRead = iBuilder->CreateMul(itemsAlreadyRead, iBuilder->getSize(mCodeUnitWidth / 8));
30    Value * unreadSize = iBuilder->CreateSub(bufferedSize, bytesAlreadyRead);
31
32    Value * const exaustedBuffer = iBuilder->CreateICmpULT(unreadSize, segmentSize);
33    iBuilder->CreateUnlikelyCondBr(exaustedBuffer, readBlock, stdInExit);
34
35    iBuilder->SetInsertPoint(readBlock);
36
37//    Value * consumed = getConsumedItemCount("InputStream");
38//    Value * remaining = iBuilder->CreateSub(itemsAlreadyRead, consumed);
39
40    // how many pages are required to have enough data for the segment plus one overflow block?
41    const auto PageAlignedSegmentSize = round_up_to_nearest((mSegmentBlocks + 1) * iBuilder->getBitBlockWidth() * (mCodeUnitWidth / 8), getpagesize());
42    ConstantInt * const bytesToRead = iBuilder->getSize(PageAlignedSegmentSize);
43    reserveBytes("InputStream", bytesToRead);
44    BasicBlock * const readExit = iBuilder->GetInsertBlock();
45
46
47    Value * const ptr = getRawOutputPointer("InputStream", iBuilder->getInt32(0), bufferedSize);
48    Value * const bytePtr = iBuilder->CreatePointerCast(ptr, iBuilder->getInt8PtrTy());
49    Value * const bytesRead = iBuilder->CreateReadCall(iBuilder->getInt32(STDIN_FILENO), bytePtr, bytesToRead);
50
51    unreadSize = iBuilder->CreateAdd(unreadSize, bytesRead);
52    bufferedSize = iBuilder->CreateAdd(bufferedSize, bytesRead);
53    setBufferedSize("InputStream", bufferedSize);
54
55    iBuilder->CreateUnlikelyCondBr(iBuilder->CreateICmpULT(unreadSize, segmentSize), setTermination, stdInExit);
56
57    iBuilder->SetInsertPoint(setTermination);
58    Value * const itemsRemaining = iBuilder->CreateUDiv(unreadSize, iBuilder->getSize(mCodeUnitWidth / 8));
59    setTerminationSignal();
60    iBuilder->CreateBr(stdInExit);
61
62    stdInExit->moveAfter(iBuilder->GetInsertBlock());
63
64    iBuilder->SetInsertPoint(stdInExit);
65    PHINode * const produced = iBuilder->CreatePHI(itemsAlreadyRead->getType(), 3);
66
67    produced->addIncoming(segmentSize, entryBlock);
68    produced->addIncoming(segmentSize, readExit);
69    produced->addIncoming(itemsRemaining, setTermination);
70    Value * const itemsRead = iBuilder->CreateAdd(itemsAlreadyRead, produced);
71
72    setProducedItemCount("InputStream", itemsRead);
73}
74
75StdInKernel::StdInKernel(IDISA::IDISA_Builder * iBuilder, unsigned blocksPerSegment, unsigned codeUnitWidth)
76: SegmentOrientedKernel(iBuilder, "Parabix:stdin_source", {}, {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "InputStream"}}, {}, {}, {})
77, mSegmentBlocks(blocksPerSegment)
78, mCodeUnitWidth(codeUnitWidth) {
79   
80}
81
82void FileSourceKernel::generateDoSegmentMethod() {
83
84    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
85    BasicBlock * setTermination = CreateBasicBlock("setTermination");
86    BasicBlock * mmapSourceExit = CreateBasicBlock("mmapSourceExit");
87    ConstantInt * segmentItems = iBuilder->getSize(mSegmentBlocks * iBuilder->getBitBlockWidth());
88    Value * fileItems = getScalarField("fileSize");
89    if (mCodeUnitWidth > 8) {
90        fileItems = iBuilder->CreateUDiv(fileItems, iBuilder->getSize(mCodeUnitWidth / 8));
91    }
92    Value * produced = getProducedItemCount("sourceBuffer");
93    produced = iBuilder->CreateAdd(produced, segmentItems);
94    Value * lessThanFullSegment = iBuilder->CreateICmpULT(fileItems, produced);
95    iBuilder->CreateCondBr(lessThanFullSegment, setTermination, mmapSourceExit);
96    iBuilder->SetInsertPoint(setTermination);
97    setTerminationSignal();
98    iBuilder->CreateBr(mmapSourceExit);
99
100    iBuilder->SetInsertPoint(mmapSourceExit);
101
102    PHINode * itemsRead = iBuilder->CreatePHI(produced->getType(), 2);
103    itemsRead->addIncoming(produced, entryBlock);
104    itemsRead->addIncoming(fileItems, setTermination);
105    setProducedItemCount("sourceBuffer", itemsRead);
106}
107
108void FileSourceKernel::generateInitializeMethod() {
109    setBaseAddress("sourceBuffer", getScalarField("fileSource"));
110    setBufferedSize("sourceBuffer", getScalarField("fileSize"));
111}
112
113FileSourceKernel::FileSourceKernel(IDISA::IDISA_Builder * iBuilder, Type * fileSourceTy, unsigned blocksPerSegment, unsigned codeUnitWidth)
114: SegmentOrientedKernel(iBuilder, "Parabix:file_source",
115    {},
116    {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "sourceBuffer"}},
117    {Binding{fileSourceTy, "fileSource"}, Binding{iBuilder->getSizeTy(), "fileSize"}}, {}, {})
118, mSegmentBlocks(blocksPerSegment)
119, mCodeUnitWidth(codeUnitWidth) {
120
121}
122
123
124
125}
Note: See TracBrowser for help on using the repository browser.