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

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

Code clean-up. Removed Pablo Call, SetIthBit? and Prototype.

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