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

Last change on this file since 5540 was 5504, checked in by cameron, 2 years ago

Update base64 main

File size: 5.5 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>
[5464]14#include <toolchain/cpudriver.h>
[5238]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>
[5436]20#include <kernels/kernel_builder.h>
[5418]21#include <boost/interprocess/mapped_region.hpp>
[5232]22#include <boost/interprocess/anonymous_shared_memory.hpp>
[5418]23#include <sys/stat.h>
24#include <fcntl.h>
[5260]25
26using namespace llvm;
27
[5232]28static cl::OptionCategory base64Options("base64 Options",
29                                            "Transcoding control options.");
30
31static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<input file ...>"), cl::OneOrMore, cl::cat(base64Options));
32
33static cl::opt<bool> mMapBuffering("mmap-buffering", cl::desc("Enable mmap buffering."), cl::cat(base64Options));
34static cl::opt<bool> memAlignBuffering("memalign-buffering", cl::desc("Enable posix_memalign buffering."), cl::cat(base64Options));
35
36
37using namespace kernel;
38using namespace parabix;
39
[5396]40void base64PipelineGen(ParabixDriver & pxDriver) {
41       
[5435]42    auto & iBuilder = pxDriver.getBuilder();
[5396]43    Module * mod = iBuilder->getModule();
[5425]44    Type * bitBlockType = iBuilder->getBitBlockType();
[5232]45
[5425]46    Type * const voidTy = iBuilder->getVoidTy();
[5418]47    Type * const int32Ty = iBuilder->getInt32Ty();
[5425]48    Type * const outputType = PointerType::get(ArrayType::get(ArrayType::get(bitBlockType, 8), 1), 0);
[5254]49   
50   
[5418]51    Function * const main = cast<Function>(mod->getOrInsertFunction("Main", voidTy, int32Ty, outputType, nullptr));
[5254]52    main->setCallingConv(CallingConv::C);
53    Function::arg_iterator args = main->arg_begin();
54   
[5418]55    Value * const fileDescriptor = &*(args++);
56    fileDescriptor->setName("fileDescriptor");
[5254]57    Value * const outputStream = &*(args++);
58    outputStream->setName("outputStream");
[5504]59    iBuilder->SetInsertPoint(BasicBlock::Create(mod->getContext(), "entry", main,0));
[5254]60
[5277]61    //Round up to a multiple of 3.
[5504]62    const unsigned initSegSize = ((codegen::SegmentSize + 2)/3) * 3;
63    const unsigned bufferSize = initSegSize * 4/3 * codegen::BufferSegments;
64
65    StreamSetBuffer * ByteStream = pxDriver.addBuffer(make_unique<SourceBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 8)));
66
67    Kernel * mmapK = pxDriver.addKernelInstance(make_unique<MMapSourceKernel>(iBuilder, initSegSize));
68    mmapK->setInitialArguments({fileDescriptor});
69    pxDriver.makeKernelCall(mmapK, {}, {ByteStream});
[5232]70   
[5504]71    StreamSetBuffer * Expanded3_4Out = pxDriver.addBuffer(make_unique<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 8), bufferSize));
72    Kernel * expandK = pxDriver.addKernelInstance(make_unique<expand3_4Kernel>(iBuilder));
73    pxDriver.makeKernelCall(expandK, {ByteStream}, {Expanded3_4Out});
[5232]74   
[5504]75    StreamSetBuffer * Radix64out = pxDriver.addBuffer(make_unique<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 8), bufferSize));
76    Kernel * radix64K = pxDriver.addKernelInstance(make_unique<radix64Kernel>(iBuilder));
77    pxDriver.makeKernelCall(radix64K, {Expanded3_4Out}, {Radix64out});
[5254]78   
[5504]79    StreamSetBuffer * Base64out = pxDriver.addBuffer(make_unique<CircularBuffer>(iBuilder, iBuilder->getStreamSetTy(1, 8), bufferSize));
80    Kernel * base64K = pxDriver.addKernelInstance(make_unique<base64Kernel>(iBuilder));
81    pxDriver.makeKernelCall(base64K, {Radix64out}, {Base64out});
[5396]82   
[5504]83    Kernel * outK = pxDriver.addKernelInstance(make_unique<StdOutKernel>(iBuilder, 8));
84    pxDriver.makeKernelCall(outK, {Base64out}, {});
[5232]85   
[5396]86    pxDriver.generatePipelineIR();
[5232]87
88    iBuilder->CreateRetVoid();
[5401]89
[5474]90    pxDriver.finalizeObject();
[5232]91}
92
93
[5418]94typedef void (*base64FunctionType)(const uint32_t fd, char * outputBuffer);
[5232]95
[5418]96size_t file_size(const int fd) {
97    struct stat st;
98    if (LLVM_UNLIKELY(fstat(fd, &st) != 0)) {
99        st.st_size = 0;
100    }
101    return st.st_size;
102}
103
[5232]104void base64(base64FunctionType fn_ptr, const std::string & fileName) {
[5240]105
[5418]106    const int fd = open(fileName.c_str(), O_RDONLY);
107    if (LLVM_UNLIKELY(fd == -1)) {
108        std::cerr << "Error: cannot open " << fileName << " for processing. Skipped.\n";
[5232]109        return;
110    }
111    if (mMapBuffering) {
[5418]112        boost::interprocess::mapped_region outputBuffer(boost::interprocess::anonymous_shared_memory(2 * file_size(fd)));
[5232]113        outputBuffer.advise(boost::interprocess::mapped_region::advice_willneed);
114        outputBuffer.advise(boost::interprocess::mapped_region::advice_sequential);
[5418]115        fn_ptr(fd, static_cast<char*>(outputBuffer.get_address()));
116    } else if (memAlignBuffering) {
[5232]117        char * outputBuffer;
[5418]118        if (posix_memalign(reinterpret_cast<void **>(&outputBuffer), 32, 2 * file_size(fd))) {
[5240]119            throw std::bad_alloc();
120        }
[5418]121        fn_ptr(fd, outputBuffer);
[5232]122        free(reinterpret_cast<void *>(outputBuffer));
[5418]123    } else { /* No external output buffer */
124        fn_ptr(fd, nullptr);
[5232]125    }
[5418]126    close(fd);
[5232]127   
128}
129
130int main(int argc, char *argv[]) {
[5486]131    codegen::ParseCommandLineOptions(argc, argv, {&base64Options, codegen::codegen_flags()});
[5232]132
[5474]133    ParabixDriver pxDriver("base64");
134    base64PipelineGen(pxDriver);
135    auto main = reinterpret_cast<base64FunctionType>(pxDriver.getMain());
[5232]136
137    for (unsigned i = 0; i != inputFiles.size(); ++i) {
[5474]138        base64(main, inputFiles[i]);
[5232]139    }
140
141    return 0;
142}
143
Note: See TracBrowser for help on using the repository browser.