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

Last change on this file since 5757 was 5755, checked in by nmedfort, 20 months ago

Bug fixes and simplified MultiBlockKernel? logic

File size: 5.0 KB
RevLine 
[4988]1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
[5260]5#include "stdout_kernel.h"
6#include <llvm/IR/Module.h>
[5436]7#include <kernels/kernel_builder.h>
[5267]8#include <kernels/streamset.h>
[5436]9
[5267]10namespace llvm { class Type; }
[4988]11
[5260]12using namespace llvm;
[5303]13using namespace parabix;
[5260]14
[4988]15namespace kernel {
[5307]16
[5755]17Value * StdOutKernel::generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & iBuilder, llvm::Value * const numOfStrides) {
[5706]18    Value * codeUnitBuffer = iBuilder->getInputStreamBlockPtr("codeUnitBuffer", iBuilder->getInt32(0));
19    codeUnitBuffer = iBuilder->CreatePointerCast(codeUnitBuffer, iBuilder->getInt8PtrTy());
20    Value * bytesToDo = mAvailableItemCount[0];
21    if (LLVM_UNLIKELY(mCodeUnitWidth > 8)) {
22        bytesToDo = iBuilder->CreateMul(bytesToDo, iBuilder->getSize(mCodeUnitWidth / 8));
23    } else if (LLVM_UNLIKELY(mCodeUnitWidth < 8)) {
24        bytesToDo = iBuilder->CreateUDiv(bytesToDo, iBuilder->getSize(8 / mCodeUnitWidth));
25    }
26    iBuilder->CreateWriteCall(iBuilder->getInt32(1), codeUnitBuffer, bytesToDo);
[5755]27    return numOfStrides;
[4988]28}
[5007]29
[5436]30StdOutKernel::StdOutKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, unsigned codeUnitWidth)
[5441]31: MultiBlockKernel("stdout", {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "codeUnitBuffer"}}, {}, {}, {}, {})
[5267]32, mCodeUnitWidth(codeUnitWidth) {
33    setNoTerminateAttribute(true);
[5706]34    // setKernelStride(getpagesize());
[4988]35}
[5267]36
[5440]37void FileSink::generateInitializeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
38    BasicBlock * setTerminationOnFailure = iBuilder->CreateBasicBlock("setTerminationOnFailure");
39    BasicBlock * fileSinkInitExit = iBuilder->CreateBasicBlock("fileSinkInitExit");
40    Value * fileName = iBuilder->getScalarField("fileName");
[5415]41    Value * fileNameLength = iBuilder->CreateStrlenCall(fileName);
42    // Make a temporary file name template with the characters "XXXXXX" appended
43    // as required by mkstemp.
44    Constant * suffixPlusNullLength = iBuilder->getSize(7);
45    Value * tmpFileNamePtr = iBuilder->CreatePointerCast(iBuilder->CreateMalloc(iBuilder->CreateAdd(fileNameLength, suffixPlusNullLength)), iBuilder->getInt8PtrTy());
[5440]46    iBuilder->setScalarField("tmpFileName", tmpFileNamePtr);
[5415]47    iBuilder->CreateMemCpy(tmpFileNamePtr, fileName, fileNameLength, 1);
48#ifdef BACKUP_OLDFILE
[5440]49    iBuilder->CreateMemCpy(iBuilder->CreateGEP(tmpFileNamePtr, fileNameLength), iBuilder->GetString(".saved"), suffixPlusNullLength, 1);
[5415]50    iBuilder->CreateRenameCall(fileName, tmpFileNamePtr);
51#else
52    iBuilder->CreateUnlinkCall(fileName);
53#endif
[5440]54    iBuilder->CreateMemCpy(iBuilder->CreateGEP(tmpFileNamePtr, fileNameLength), iBuilder->GetString("XXXXXX"), suffixPlusNullLength, 1);
[5415]55    Value * fileDes = iBuilder->CreateMkstempCall(tmpFileNamePtr);
[5440]56    iBuilder->setScalarField("fileDes", fileDes);
[5415]57    Value * failure = iBuilder->CreateICmpEQ(fileDes, iBuilder->getInt32(-1));
[5280]58    iBuilder->CreateCondBr(failure, setTerminationOnFailure, fileSinkInitExit);
59    iBuilder->SetInsertPoint(setTerminationOnFailure);
[5440]60    iBuilder->setTerminationSignal();
[5280]61    iBuilder->CreateBr(fileSinkInitExit);
62    iBuilder->SetInsertPoint(fileSinkInitExit);
[5267]63}
[5280]64
[5755]65Value * FileSink::generateMultiBlockLogic(const std::unique_ptr<KernelBuilder> & iBuilder, Value * const numOfStrides) {
[5706]66    BasicBlock * const closeFile = iBuilder->CreateBasicBlock("closeFile");
67    BasicBlock * const fileOutExit = iBuilder->CreateBasicBlock("fileOutExit");
[5307]68
[5706]69    Value * const fileDes = iBuilder->getScalarField("fileDes");
[5755]70    Value * codeUnitBuffer = iBuilder->getInputStreamBlockPtr("codeUnitBuffer", iBuilder->getInt32(0));
71    codeUnitBuffer = iBuilder->CreatePointerCast(codeUnitBuffer, iBuilder->getInt8PtrTy());
[5706]72    Value * bytesToDo = mAvailableItemCount[0];
73    if (LLVM_UNLIKELY(mCodeUnitWidth > 8)) {
74        bytesToDo = iBuilder->CreateMul(bytesToDo, iBuilder->getSize(mCodeUnitWidth / 8));
75    } else if (LLVM_UNLIKELY(mCodeUnitWidth < 8)) {
76        bytesToDo = iBuilder->CreateUDiv(bytesToDo, iBuilder->getSize(8 / mCodeUnitWidth));
77    }   
78    iBuilder->CreateWriteCall(fileDes, codeUnitBuffer, bytesToDo);
79    iBuilder->CreateUnlikelyCondBr(mIsFinal, closeFile, fileOutExit);
80
81    iBuilder->SetInsertPoint(closeFile);   
[5415]82    iBuilder->CreateCloseCall(fileDes);
[5440]83    Value * newFileNamePtr = iBuilder->getScalarField("fileName");
84    Value * tmpFileNamePtr = iBuilder->getScalarField("tmpFileName");
[5415]85    iBuilder->CreateRenameCall(tmpFileNamePtr, newFileNamePtr);
[5706]86    iBuilder->CreateFree(tmpFileNamePtr);   
[5280]87    iBuilder->CreateBr(fileOutExit);
[5449]88   
[5280]89    iBuilder->SetInsertPoint(fileOutExit);
[5755]90    return numOfStrides;
[5280]91}
92
[5436]93FileSink::FileSink(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, unsigned codeUnitWidth)
[5706]94: MultiBlockKernel("filesink" + std::to_string(codeUnitWidth),
95{Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "codeUnitBuffer"}},
96{},
97{Binding{iBuilder->getInt8PtrTy(), "fileName"}}, {}, {Binding{iBuilder->getInt8PtrTy(), "tmpFileName"}, Binding{iBuilder->getInt32Ty(), "fileDes"}})
[5280]98, mCodeUnitWidth(codeUnitWidth) {
[5706]99    // setKernelStride(getpagesize());
[5280]100}
101
102}
103
104
105
[5307]106
Note: See TracBrowser for help on using the repository browser.