source: icGREP/icgrep-devel/icgrep/array-test.cpp @ 5256

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

noTerminate attribute for stdout kernel

File size: 6.4 KB
Line 
1/*
2 *  Copyright (c) 2015 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 <string>
8#include <iostream>
9#include <iomanip>
10#include <fstream>
11#include <sstream>
12
13
14#include <toolchain.h>
15#include <pablo/pablo_toolchain.h>
16#include <llvm/IR/Function.h>
17#include <llvm/IR/Module.h>
18#include <llvm/ExecutionEngine/ExecutionEngine.h>
19#include <llvm/ExecutionEngine/MCJIT.h>
20#include "llvm/Linker/Linker.h"
21#include <llvm/IR/Verifier.h>
22#include <llvm/Support/CommandLine.h>
23#include <llvm/Support/raw_ostream.h>
24
25#include <pablo/pablo_kernel.h>
26#include <IR_Gen/idisa_builder.h>
27#include <IR_Gen/idisa_target.h>
28#include <kernels/streamset.h>
29#include <kernels/interface.h>
30#include <kernels/kernel.h>
31#include <kernels/mmap_kernel.h>
32#include <kernels/pipeline.h>
33#include <pablo/builder.hpp>
34#include <pablo/pablo_compiler.h>
35#include <pablo/pablo_toolchain.h>
36#include <kernels/s2p_kernel.h>
37#include <kernels/stdout_kernel.h>
38#include <boost/filesystem.hpp>
39#include <boost/iostreams/device/mapped_file.hpp>
40
41static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<input file ...>"), cl::OneOrMore);
42
43using namespace pablo;
44using namespace kernel;
45using namespace parabix;
46
47void generate(PabloKernel * kernel, const unsigned size) {
48
49    PabloBuilder pb(kernel->getEntryBlock());
50
51    Var * input = kernel->addInput("input", kernel->getStreamSetTy(8));
52    Var * matches = kernel->addOutput("matches", kernel->getStreamSetTy(size));
53
54    PabloAST * basis[8];
55    for (int i = 0; i < 8; ++i) {
56        basis[i] = pb.createExtract(input, i);
57    }
58
59    PabloAST * temp1 = pb.createOr(basis[0], basis[1]);
60    PabloAST * temp2 = pb.createAnd(basis[2], pb.createNot(basis[3]));
61    PabloAST * temp3 = pb.createAnd(temp2, pb.createNot(temp1));
62    PabloAST * temp4 = pb.createAnd(basis[4], pb.createNot(basis[5]));
63    PabloAST * temp5 = pb.createOr(basis[6], basis[7]);
64    PabloAST * temp6 = pb.createAnd(temp4, pb.createNot(temp5));
65    PabloAST * lparen = pb.createAnd(temp3, temp6, "lparens");
66    PabloAST * temp7 = pb.createAnd(basis[7], pb.createNot(basis[6]));
67    PabloAST * temp8 = pb.createAnd(temp4, temp7);
68    PabloAST * rparen = pb.createAnd(temp3, temp8, "rparens");
69    PabloAST * parens = pb.createOr(lparen, rparen);
70
71    PabloAST * pscan = pb.createScanTo(pb.createAdvance(lparen, 1), parens, "pscan");
72
73    PabloAST * closed = pb.createAnd(pscan, rparen, "closed");
74
75    pb.createAssign(pb.createExtract(matches, 0), closed);
76
77    Var * all_closed = pb.createVar("all_closed", closed);
78    Var * pending_lparen = pb.createVar("pending_lparen", pb.createAnd(pscan, lparen));
79    Var * unmatched_rparen = pb.createVar("unmatched_rparen", pb.createAnd(rparen, pb.createNot(closed)));
80    Var * in_play = pb.createVar("in_play", pb.createOr(pending_lparen, unmatched_rparen));
81
82
83    Integer * one = pb.getInteger(1);
84
85    Var * index = pb.createVar("i", one);
86
87    PabloBuilder body = PabloBuilder::Create(pb);
88
89    pb.createWhile(pending_lparen, body);
90
91        pscan = body.createScanTo(body.createAdvance(pending_lparen, 1), in_play);
92        closed = body.createAnd(pscan, rparen);
93        body.createAssign(body.createExtract(matches, index), closed);
94        body.createAssign(pending_lparen, body.createAnd(pscan, lparen));
95        body.createAssign(all_closed, body.createOr(all_closed, closed));
96        body.createAssign(unmatched_rparen, body.createAnd(rparen, body.createNot(all_closed)));
97        body.createAssign(in_play, body.createOr(pending_lparen, unmatched_rparen));
98        body.createAssign(index, body.createAdd(index, one));
99
100
101    pb.print(errs());
102
103}
104
105Function * pipeline(IDISA::IDISA_Builder * iBuilder, const unsigned count) {
106
107    Type * byteStreamTy = iBuilder->getStreamSetTy(1, 8);
108
109    Module * const mod = iBuilder->getModule();
110   
111    Function * const main = cast<Function>(mod->getOrInsertFunction("Main", iBuilder->getVoidTy(), byteStreamTy->getPointerTo(), iBuilder->getSizeTy(), nullptr));
112    main->setCallingConv(CallingConv::C);
113    Function::arg_iterator args = main->arg_begin();
114   
115    Value * const inputStream = &*(args++);
116    inputStream->setName("input");
117    Value * const fileSize = &*(args++);
118    fileSize->setName("fileSize");
119   
120    ExternalFileBuffer ByteStream(iBuilder, byteStreamTy);
121    SingleBlockBuffer BasisBits(iBuilder, iBuilder->getStreamSetTy(8, 1));
122    SingleBlockBuffer matches(iBuilder, iBuilder->getStreamSetTy(count, 1));
123
124    MMapSourceKernel mmapK(iBuilder); 
125    mmapK.generateKernel({}, {&ByteStream});
126    mmapK.setInitialArguments({fileSize});
127   
128    S2PKernel  s2pk(iBuilder);
129    s2pk.generateKernel({&ByteStream}, {&BasisBits});
130
131    PabloKernel bm(iBuilder, "MatchParens");
132    generate(&bm, count);
133
134    bm.generateKernel({&BasisBits}, {&matches});
135
136    iBuilder->SetInsertPoint(BasicBlock::Create(mod->getContext(), "entry", main, 0));
137
138    ByteStream.setStreamSetBuffer(inputStream, fileSize);
139    BasisBits.allocateBuffer();
140    matches.allocateBuffer();
141
142    generatePipelineLoop(iBuilder, {&mmapK, &s2pk, &bm});
143    iBuilder->CreateRetVoid();
144
145    return main;
146}
147
148typedef void (*MatchParens)(char * byteStream, size_t fileSize);
149
150MatchParens generateAlgorithm() {
151    LLVMContext ctx;
152    Module * M = new Module("mp", ctx);
153    IDISA::IDISA_Builder * idb = IDISA::GetIDISA_Builder(M);
154
155    llvm::Function * f = pipeline(idb, 10);
156
157    verifyModule(*M, &dbgs());
158
159    ExecutionEngine * wcEngine = JIT_to_ExecutionEngine(M);
160
161    wcEngine->finalizeObject();
162
163    delete idb;
164
165    return reinterpret_cast<MatchParens>(wcEngine->getPointerToFunction(f));
166}
167
168void run(MatchParens f, const std::string & fileName) {
169    const boost::filesystem::path file(fileName);
170    if (exists(file)) {
171        if (is_directory(file)) {
172            return;
173        }
174        size_t fileSize = file_size(file);
175        boost::iostreams::mapped_file_source mappedFile;
176        if (fileSize > 0) {
177            mappedFile.open(fileName);
178            char * fileBuffer = const_cast<char *>(mappedFile.data());
179            f(fileBuffer, fileSize);
180            mappedFile.close();
181        }
182    } else {
183        std::cerr << "Error: cannot open " << fileName << " for processing. Skipped.\n";
184    }
185}
186
187int main(int argc, char *argv[]) {
188    cl::ParseCommandLineOptions(argc, argv);
189    auto f = generateAlgorithm();
190    for (const auto & inputFile : inputFiles) {
191        run(f, inputFile);
192    }
193    return 0;
194}
Note: See TracBrowser for help on using the repository browser.