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

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

Stdout and Filesink kernels have improved performance with pagesize() as stride

File size: 4.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#include "stdout_kernel.h"
6#include <llvm/IR/Module.h>
7#include <kernels/kernel_builder.h>
8#include <kernels/streamset.h>
9
10namespace llvm { class Type; }
11
12using namespace llvm;
13using namespace parabix;
14
15namespace kernel {
16
17void StdOutKernel::generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & b, llvm::Value * const numOfStrides) {
18    Value * codeUnitBuffer = b->getInputStreamBlockPtr("codeUnitBuffer", b->getInt32(0));
19    codeUnitBuffer = b->CreatePointerCast(codeUnitBuffer, b->getInt8PtrTy());
20    Value * bytesToDo = mAccessibleInputItems[0];
21    if (LLVM_UNLIKELY(mCodeUnitWidth > 8)) {
22        bytesToDo = b->CreateMul(bytesToDo, b->getSize(mCodeUnitWidth / 8));
23    } else if (LLVM_UNLIKELY(mCodeUnitWidth < 8)) {
24        bytesToDo = b->CreateUDiv(bytesToDo, b->getSize(8 / mCodeUnitWidth));
25    }
26    b->CreateWriteCall(b->getInt32(1), codeUnitBuffer, bytesToDo);
27}
28
29StdOutKernel::StdOutKernel(const std::unique_ptr<kernel::KernelBuilder> & b, unsigned codeUnitWidth)
30: MultiBlockKernel("stdout",
31// input
32{Binding{b->getStreamSetTy(1, codeUnitWidth), "codeUnitBuffer", FixedRate(), RequiresLinearAccess()}}
33// output & scalars
34, {}, {}, {}, {})
35, mCodeUnitWidth(codeUnitWidth) {
36    setStride(getpagesize());
37}
38
39void FileSink::generateInitializeMethod(const std::unique_ptr<kernel::KernelBuilder> & b) {
40    BasicBlock * setTerminationOnFailure = b->CreateBasicBlock("setTerminationOnFailure");
41    BasicBlock * fileSinkInitExit = b->CreateBasicBlock("fileSinkInitExit");
42    Value * fileName = b->getScalarField("fileName");
43    Value * fileNameLength = b->CreateStrlenCall(fileName);
44    // Make a temporary file name template with the characters "XXXXXX" appended
45    // as required by mkstemp.
46    Constant * suffixPlusNullLength = b->getSize(7);
47    Value * tmpFileNamePtr = b->CreatePointerCast(b->CreateMalloc(b->CreateAdd(fileNameLength, suffixPlusNullLength)), b->getInt8PtrTy());
48    b->setScalarField("tmpFileName", tmpFileNamePtr);
49    b->CreateMemCpy(tmpFileNamePtr, fileName, fileNameLength, 1);
50#ifdef BACKUP_OLDFILE
51    b->CreateMemCpy(b->CreateGEP(tmpFileNamePtr, fileNameLength), b->GetString(".saved"), suffixPlusNullLength, 1);
52    b->CreateRenameCall(fileName, tmpFileNamePtr);
53#else
54    b->CreateUnlinkCall(fileName);
55#endif
56    b->CreateMemCpy(b->CreateGEP(tmpFileNamePtr, fileNameLength), b->GetString("XXXXXX"), suffixPlusNullLength, 1);
57    Value * fileDes = b->CreateMkstempCall(tmpFileNamePtr);
58    b->setScalarField("fileDes", fileDes);
59    Value * failure = b->CreateICmpEQ(fileDes, b->getInt32(-1));
60    b->CreateCondBr(failure, setTerminationOnFailure, fileSinkInitExit);
61
62    b->SetInsertPoint(setTerminationOnFailure);
63    b->setTerminationSignal();
64    b->CreateBr(fileSinkInitExit);
65
66    b->SetInsertPoint(fileSinkInitExit);
67}
68
69void FileSink::generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & b, Value * const numOfStrides) {
70    Value * const fileDes = b->getScalarField("fileDes");
71    Value * codeUnitBuffer = b->getInputStreamBlockPtr("codeUnitBuffer", b->getInt32(0));
72    codeUnitBuffer = b->CreatePointerCast(codeUnitBuffer, b->getInt8PtrTy());
73    Value * bytesToDo = mAccessibleInputItems[0];
74    if (LLVM_UNLIKELY(mCodeUnitWidth > 8)) {
75        bytesToDo = b->CreateMul(bytesToDo, b->getSize(mCodeUnitWidth / 8));
76    } else if (LLVM_UNLIKELY(mCodeUnitWidth < 8)) {
77        bytesToDo = b->CreateUDiv(bytesToDo, b->getSize(8 / mCodeUnitWidth));
78    }   
79    b->CreateWriteCall(fileDes, codeUnitBuffer, bytesToDo);
80}
81
82void FileSink::generateFinalizeMethod(const std::unique_ptr<KernelBuilder> & b) {
83    Value * const fileDes = b->getScalarField("fileDes");
84    b->CreateCloseCall(fileDes);
85    Value * newFileNamePtr = b->getScalarField("fileName");
86    Value * tmpFileNamePtr = b->getScalarField("tmpFileName");
87    b->CreateRenameCall(tmpFileNamePtr, newFileNamePtr);
88    b->CreateFree(tmpFileNamePtr);
89}
90
91FileSink::FileSink(const std::unique_ptr<kernel::KernelBuilder> & b, unsigned codeUnitWidth)
92: MultiBlockKernel("filesink" + std::to_string(codeUnitWidth),
93// input
94{Binding{b->getStreamSetTy(1, codeUnitWidth), "codeUnitBuffer", FixedRate(), RequiresLinearAccess()}},
95// output
96{},
97// scalars
98{Binding{b->getInt8PtrTy(), "fileName"}}, {}, {Binding{b->getInt8PtrTy(), "tmpFileName"}, Binding{b->getInt32Ty(), "fileDes"}})
99, mCodeUnitWidth(codeUnitWidth) {
100    setStride(getpagesize());
101}
102
103}
104
105
106
107
Note: See TracBrowser for help on using the repository browser.