source: icGREP/icgrep-devel/icgrep/base64.cpp @ 5431

Last change on this file since 5431 was 5431, checked in by nmedfort, 2 years ago

partial refactoring check in with change for Linda.

File size: 5.4 KB
RevLine 
[5232]1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include <iostream>
8#include <llvm/IR/Function.h>
9#include <llvm/IR/Module.h>
10#include <llvm/ExecutionEngine/ExecutionEngine.h>
11#include <llvm/IR/Verifier.h>
12#include <llvm/Support/CommandLine.h>
[5425]13#include <toolchain/toolchain.h>
[5238]14#include <IR_Gen/idisa_builder.h>
15#include <IR_Gen/idisa_target.h>
[5429]16#include <kernels/source_kernel.h>
[5267]17#include <kernels/streamset.h>
[5232]18#include <kernels/radix64.h>
19#include <kernels/stdout_kernel.h>
[5418]20#include <boost/interprocess/mapped_region.hpp>
[5232]21#include <boost/interprocess/anonymous_shared_memory.hpp>
[5418]22#include <sys/stat.h>
23#include <fcntl.h>
[5260]24
25using namespace llvm;
26
[5232]27static cl::OptionCategory base64Options("base64 Options",
28                                            "Transcoding control options.");
29
30static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<input file ...>"), cl::OneOrMore, cl::cat(base64Options));
31
32static cl::opt<bool> mMapBuffering("mmap-buffering", cl::desc("Enable mmap buffering."), cl::cat(base64Options));
33static cl::opt<bool> memAlignBuffering("memalign-buffering", cl::desc("Enable posix_memalign buffering."), cl::cat(base64Options));
34
35
36using namespace kernel;
37using namespace parabix;
38
[5396]39void base64PipelineGen(ParabixDriver & pxDriver) {
40       
[5425]41    auto iBuilder = pxDriver.getIDISA_Builder();
[5396]42    Module * mod = iBuilder->getModule();
[5425]43    Type * bitBlockType = iBuilder->getBitBlockType();
[5232]44
[5425]45    Type * const voidTy = iBuilder->getVoidTy();
[5418]46    Type * const int32Ty = iBuilder->getInt32Ty();
[5425]47    Type * const outputType = PointerType::get(ArrayType::get(ArrayType::get(bitBlockType, 8), 1), 0);
[5254]48   
49   
[5418]50    Function * const main = cast<Function>(mod->getOrInsertFunction("Main", voidTy, int32Ty, outputType, nullptr));
[5254]51    main->setCallingConv(CallingConv::C);
52    Function::arg_iterator args = main->arg_begin();
53   
[5418]54    Value * const fileDescriptor = &*(args++);
55    fileDescriptor->setName("fileDescriptor");
[5254]56    Value * const outputStream = &*(args++);
57    outputStream->setName("outputStream");
58
[5277]59    //Round up to a multiple of 3.
60    const unsigned segmentSize = ((codegen::SegmentSize + 2)/3) * 3;
[5232]61   
62    const unsigned bufferSegments = codegen::BufferSegments;
63   
[5429]64    SourceBuffer ByteStream(iBuilder, iBuilder->getStreamSetTy(1, 8));
[5232]65
[5277]66    CircularBuffer Expanded3_4Out(iBuilder, iBuilder->getStreamSetTy(1, 8), segmentSize * 4/3 * bufferSegments);
67    CircularBuffer Radix64out(iBuilder, iBuilder->getStreamSetTy(1, 8), segmentSize * 4/3 * bufferSegments);
[5302]68    CircularCopybackBuffer Base64out(iBuilder, iBuilder->getStreamSetTy(1, 8), segmentSize * 4/3 * bufferSegments, 1);
[5254]69   
[5277]70    MMapSourceKernel mmapK(iBuilder, segmentSize);
[5418]71    mmapK.setInitialArguments({fileDescriptor});
[5396]72    pxDriver.addKernelCall(mmapK, {}, {&ByteStream});
73   
[5232]74    expand3_4Kernel expandK(iBuilder);
[5396]75    pxDriver.addKernelCall(expandK, {&ByteStream}, {&Expanded3_4Out});
[5232]76
77    radix64Kernel radix64K(iBuilder);
[5396]78    pxDriver.addKernelCall(radix64K, {&Expanded3_4Out}, {&Radix64out});
[5232]79
80    base64Kernel base64K(iBuilder);
[5396]81    pxDriver.addKernelCall(base64K, {&Radix64out}, {&Base64out});
[5232]82   
83    StdOutKernel stdoutK(iBuilder, 8);
[5396]84    pxDriver.addKernelCall(stdoutK, {&Base64out}, {});
[5232]85   
[5396]86    iBuilder->SetInsertPoint(BasicBlock::Create(mod->getContext(), "entry", main,0));
[5232]87
[5431]88    ByteStream.allocateBuffer(iBuilder);
89    Expanded3_4Out.allocateBuffer(iBuilder);
90    Radix64out.allocateBuffer(iBuilder);
91    Base64out.allocateBuffer(iBuilder);
[5232]92
[5396]93    pxDriver.generatePipelineIR();
[5232]94
95    iBuilder->CreateRetVoid();
[5401]96
[5396]97    pxDriver.linkAndFinalize();
[5232]98}
99
100
[5418]101typedef void (*base64FunctionType)(const uint32_t fd, char * outputBuffer);
[5232]102
103base64FunctionType base64CodeGen(void) {
[5425]104    ParabixDriver pxDriver("base64");
[5396]105    base64PipelineGen(pxDriver);
[5425]106    return reinterpret_cast<base64FunctionType>(pxDriver.getPointerToMain());
[5232]107}
108
[5418]109size_t file_size(const int fd) {
110    struct stat st;
111    if (LLVM_UNLIKELY(fstat(fd, &st) != 0)) {
112        st.st_size = 0;
113    }
114    return st.st_size;
115}
116
[5232]117void base64(base64FunctionType fn_ptr, const std::string & fileName) {
[5240]118
[5418]119    const int fd = open(fileName.c_str(), O_RDONLY);
120    if (LLVM_UNLIKELY(fd == -1)) {
121        std::cerr << "Error: cannot open " << fileName << " for processing. Skipped.\n";
[5232]122        return;
123    }
124    if (mMapBuffering) {
[5418]125        boost::interprocess::mapped_region outputBuffer(boost::interprocess::anonymous_shared_memory(2 * file_size(fd)));
[5232]126        outputBuffer.advise(boost::interprocess::mapped_region::advice_willneed);
127        outputBuffer.advise(boost::interprocess::mapped_region::advice_sequential);
[5418]128        fn_ptr(fd, static_cast<char*>(outputBuffer.get_address()));
129    } else if (memAlignBuffering) {
[5232]130        char * outputBuffer;
[5418]131        if (posix_memalign(reinterpret_cast<void **>(&outputBuffer), 32, 2 * file_size(fd))) {
[5240]132            throw std::bad_alloc();
133        }
[5418]134        fn_ptr(fd, outputBuffer);
[5232]135        free(reinterpret_cast<void *>(outputBuffer));
[5418]136    } else { /* No external output buffer */
137        fn_ptr(fd, nullptr);
[5232]138    }
[5418]139    close(fd);
[5232]140   
141}
142
143
144int main(int argc, char *argv[]) {
[5373]145    AddParabixVersionPrinter();
[5232]146    cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>{&base64Options, codegen::codegen_flags()});
147    cl::ParseCommandLineOptions(argc, argv);
148
149    base64FunctionType fn_ptr = base64CodeGen();
150
151    for (unsigned i = 0; i != inputFiles.size(); ++i) {
152        base64(fn_ptr, inputFiles[i]);
153    }
154
155    return 0;
156}
157
Note: See TracBrowser for help on using the repository browser.