source: icGREP/icgrep-devel/icgrep/idisa_test.cpp @ 6133

Last change on this file since 6133 was 6058, checked in by cameron, 12 months ago

Small fixes

File size: 24.2 KB
Line 
1/*
2 *  Copyright (c) 2018 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 <vector>
8#include <string>
9#include <toolchain/toolchain.h>
10#include <llvm/IR/Function.h>
11#include <llvm/IR/Module.h>
12#include <llvm/Support/CommandLine.h>
13#include <llvm/Support/raw_ostream.h>
14#include <kernels/kernel_builder.h>
15#include <IR_Gen/idisa_target.h>
16#include <kernels/interface.h>
17#include <kernels/streamset.h>
18#include <kernels/source_kernel.h>
19#include <kernels/hex_convert.h>
20#include <kernels/s2p_kernel.h>
21#include <kernels/stdout_kernel.h>
22#include <toolchain/toolchain.h>
23#include <toolchain/cpudriver.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <boost/filesystem.hpp>
27namespace fs = boost::filesystem;
28
29using namespace llvm;
30
31static cl::OptionCategory testFlags("Command Flags", "test options");
32
33static cl::opt<std::string> TestOperation(cl::Positional, cl::desc("Operation to test"), cl::Required, cl::cat(testFlags));
34
35static cl::opt<int> TestFieldWidth(cl::Positional, cl::desc("Test field width (default 64)."), cl::init(64), cl::Required, cl::cat(testFlags));
36
37static cl::opt<std::string> Operand1TestFile(cl::Positional, cl::desc("Operand 1 data file."), cl::Required, cl::cat(testFlags));
38static cl::opt<std::string> Operand2TestFile(cl::Positional, cl::desc("Operand 2 data file."), cl::Required, cl::cat(testFlags));
39static cl::opt<std::string> TestOutputFile("o", cl::desc("Test output file."), cl::cat(testFlags));
40static cl::opt<bool> QuietMode("q", cl::desc("Suppress output, set the return code only."), cl::cat(testFlags));
41static cl::opt<int> ShiftLimit("ShiftLimit", cl::desc("Upper limit for the shift operand (2nd operand) of sllv, srlv, srav."), cl::init(0));
42static cl::opt<int> Immediate("i", cl::desc("Immediate value for mvmd_dslli"), cl::init(1));
43
44class ShiftLimitKernel : public kernel::BlockOrientedKernel {
45public:
46    ShiftLimitKernel(const std::unique_ptr<kernel::KernelBuilder> & b, unsigned fw, unsigned limit);
47    bool isCachable() const override { return true; }
48    bool hasSignature() const override { return false; }
49protected:
50    void generateDoBlockMethod(const std::unique_ptr<kernel::KernelBuilder> & kb) override;
51private:
52    const unsigned mTestFw;
53    const unsigned mShiftLimit;
54};
55
56ShiftLimitKernel::ShiftLimitKernel(const std::unique_ptr<kernel::KernelBuilder> & b, unsigned fw, unsigned limit)
57: kernel::BlockOrientedKernel("shiftLimit" + std::to_string(fw) + "_" + std::to_string(limit),
58                              {kernel::Binding{b->getStreamSetTy(1, fw), "shiftOperand"}},
59                              {kernel::Binding{b->getStreamSetTy(1, fw), "limitedShift"}},
60                              {}, {}, {}),
61mTestFw(fw), mShiftLimit(limit) {}
62
63void ShiftLimitKernel::generateDoBlockMethod(const std::unique_ptr<kernel::KernelBuilder> & kb) {
64    Type * fwTy = kb->getIntNTy(mTestFw);
65    Constant * const ZeroConst = kb->getSize(0);
66    Value * shiftOperand = kb->loadInputStreamBlock("shiftOperand", ZeroConst);
67    unsigned fieldCount = kb->getBitBlockWidth()/mTestFw;
68    Value * limited = kb->simd_umin(mTestFw, shiftOperand, ConstantVector::getSplat(fieldCount, ConstantInt::get(fwTy, mShiftLimit)));
69    kb->storeOutputStreamBlock("limitedShift", ZeroConst, limited);
70}
71
72class IdisaBinaryOpTestKernel : public kernel::MultiBlockKernel {
73public:
74    IdisaBinaryOpTestKernel(const std::unique_ptr<kernel::KernelBuilder> & b, std::string idisa_op, unsigned fw, unsigned imm=0);
75    bool isCachable() const override { return true; }
76    bool hasSignature() const override { return false; }
77protected:
78    void generateMultiBlockLogic(const std::unique_ptr<kernel::KernelBuilder> & kb, llvm::Value * const numOfStrides) override;
79private:
80    const std::string mIdisaOperation;
81    const unsigned mTestFw;
82    const unsigned mImmediateShift;
83};
84
85IdisaBinaryOpTestKernel::IdisaBinaryOpTestKernel(const std::unique_ptr<kernel::KernelBuilder> & b, std::string idisa_op, unsigned fw, unsigned imm)
86: kernel::MultiBlockKernel(idisa_op + std::to_string(fw) + "_test",
87     {kernel::Binding{b->getStreamSetTy(1, 1), "operand1"}, kernel::Binding{b->getStreamSetTy(1, 1), "operand2"}},
88     {kernel::Binding{b->getStreamSetTy(1, 1), "result"}},
89     {}, {}, {}),
90mIdisaOperation(idisa_op), mTestFw(fw), mImmediateShift(imm) {}
91
92void IdisaBinaryOpTestKernel::generateMultiBlockLogic(const std::unique_ptr<kernel::KernelBuilder> & kb, llvm::Value * const numOfBlocks) {
93    BasicBlock * entry = kb->GetInsertBlock();
94    BasicBlock * processBlock = kb->CreateBasicBlock("processBlock");
95    BasicBlock * done = kb->CreateBasicBlock("done");
96    Constant * const ZeroConst = kb->getSize(0);
97    kb->CreateBr(processBlock);
98    kb->SetInsertPoint(processBlock);
99    PHINode * blockOffsetPhi = kb->CreatePHI(kb->getSizeTy(), 2);
100    blockOffsetPhi->addIncoming(ZeroConst, entry);
101    Value * operand1 = kb->loadInputStreamBlock("operand1", ZeroConst, blockOffsetPhi);
102    Value * operand2 = kb->loadInputStreamBlock("operand2", ZeroConst, blockOffsetPhi);
103    Value * result = nullptr;
104    if (mIdisaOperation == "simd_add") {
105        result = kb->simd_add(mTestFw, operand1, operand2);
106    } else if (mIdisaOperation == "simd_sub") {
107        result = kb->simd_sub(mTestFw, operand1, operand2);
108    } else if (mIdisaOperation == "simd_mult") {
109        result = kb->simd_mult(mTestFw, operand1, operand2);
110    } else if (mIdisaOperation == "simd_eq") {
111        result = kb->simd_eq(mTestFw, operand1, operand2);
112    } else if (mIdisaOperation == "simd_gt") {
113        result = kb->simd_gt(mTestFw, operand1, operand2);
114    } else if (mIdisaOperation == "simd_ugt") {
115        result = kb->simd_ugt(mTestFw, operand1, operand2);
116    } else if (mIdisaOperation == "simd_uge") {
117        result = kb->simd_uge(mTestFw, operand1, operand2);
118    } else if (mIdisaOperation == "simd_lt") {
119        result = kb->simd_lt(mTestFw, operand1, operand2);
120    } else if (mIdisaOperation == "simd_ult") {
121        result = kb->simd_ult(mTestFw, operand1, operand2);
122    } else if (mIdisaOperation == "simd_ule") {
123        result = kb->simd_ule(mTestFw, operand1, operand2);
124    } else if (mIdisaOperation == "simd_max") {
125        result = kb->simd_max(mTestFw, operand1, operand2);
126    } else if (mIdisaOperation == "simd_min") {
127        result = kb->simd_min(mTestFw, operand1, operand2);
128    } else if (mIdisaOperation == "simd_umax") {
129        result = kb->simd_umax(mTestFw, operand1, operand2);
130    } else if (mIdisaOperation == "simd_umin") {
131        result = kb->simd_umin(mTestFw, operand1, operand2);
132    } else if (mIdisaOperation == "simd_sllv") {
133        result = kb->simd_sllv(mTestFw, operand1, operand2);
134    } else if (mIdisaOperation == "simd_srlv") {
135        result = kb->simd_srlv(mTestFw, operand1, operand2);
136    } else if (mIdisaOperation == "simd_pext") {
137        result = kb->simd_pext(mTestFw, operand1, operand2);
138    } else if (mIdisaOperation == "simd_pdep") {
139        result = kb->simd_pdep(mTestFw, operand1, operand2);
140    } else if (mIdisaOperation == "hsimd_packh") {
141        result = kb->hsimd_packh(mTestFw, operand1, operand2);
142    } else if (mIdisaOperation == "hsimd_packl") {
143        result = kb->hsimd_packl(mTestFw, operand1, operand2);
144    } else if (mIdisaOperation == "esimd_mergeh") {
145        result = kb->esimd_mergeh(mTestFw, operand1, operand2);
146    } else if (mIdisaOperation == "esimd_mergel") {
147        result = kb->esimd_mergel(mTestFw, operand1, operand2);
148    } else if (mIdisaOperation == "mvmd_shuffle") {
149        result = kb->mvmd_shuffle(mTestFw, operand1, operand2);
150    } else if (mIdisaOperation == "mvmd_compress") {
151        result = kb->mvmd_compress(mTestFw, operand1, operand2);
152    } else if (mIdisaOperation == "mvmd_dslli") {
153        result = kb->mvmd_dslli(mTestFw, operand1, operand2, mImmediateShift);
154    } else {
155        llvm::report_fatal_error("Binary operation " + mIdisaOperation + " is unknown to the IdisaBinaryOpTestKernel kernel.");
156    }
157    kb->storeOutputStreamBlock("result", ZeroConst, blockOffsetPhi, kb->bitCast(result));
158    Value * nextBlk = kb->CreateAdd(blockOffsetPhi, kb->getSize(1));
159    blockOffsetPhi->addIncoming(nextBlk, processBlock);
160    Value * moreToDo = kb->CreateICmpNE(nextBlk, numOfBlocks);
161    kb->CreateCondBr(moreToDo, processBlock, done);
162    kb->SetInsertPoint(done);
163}
164
165class IdisaBinaryOpCheckKernel : public kernel::BlockOrientedKernel {
166public:
167    IdisaBinaryOpCheckKernel(const std::unique_ptr<kernel::KernelBuilder> & b, std::string idisa_op, unsigned fw, unsigned imm=0);
168    bool isCachable() const override { return true; }
169    bool hasSignature() const override { return false; }
170protected:
171    void generateDoBlockMethod(const std::unique_ptr<kernel::KernelBuilder> & kb) override;
172private:
173    const std::string mIdisaOperation;
174    const unsigned mTestFw;
175    const unsigned mImmediateShift;
176};
177
178IdisaBinaryOpCheckKernel::IdisaBinaryOpCheckKernel(const std::unique_ptr<kernel::KernelBuilder> & b, std::string idisa_op, unsigned fw, unsigned imm)
179: kernel::BlockOrientedKernel(idisa_op + std::to_string(fw) + "_check" + std::to_string(QuietMode),
180                           {kernel::Binding{b->getStreamSetTy(1, 1), "operand1"},
181                            kernel::Binding{b->getStreamSetTy(1, 1), "operand2"},
182                            kernel::Binding{b->getStreamSetTy(1, 1), "test_result"}},
183                           {kernel::Binding{b->getStreamSetTy(1, 1), "expected_result"}},
184                           {}, {kernel::Binding{b->getSizeTy(), "totalFailures"}}, {}),
185mIdisaOperation(idisa_op), mTestFw(fw), mImmediateShift(imm) {}
186
187void IdisaBinaryOpCheckKernel::generateDoBlockMethod(const std::unique_ptr<kernel::KernelBuilder> & kb) {
188    Type * fwTy = kb->getIntNTy(mTestFw);
189    BasicBlock * reportFailure = kb->CreateBasicBlock("reportFailure");
190    BasicBlock * continueTest = kb->CreateBasicBlock("continueTest");
191    Constant * const ZeroConst = kb->getSize(0);
192    Value * operand1Block = kb->loadInputStreamBlock("operand1", ZeroConst);
193    Value * operand2Block = kb->loadInputStreamBlock("operand2", ZeroConst);
194    Value * resultBlock = kb->loadInputStreamBlock("test_result", ZeroConst);
195    unsigned fieldCount = kb->getBitBlockWidth()/mTestFw;
196    Value * expectedBlock = kb->allZeroes();
197    if (mIdisaOperation == "mvmd_shuffle") {
198        for (unsigned i = 0; i < fieldCount; i++) {
199            Value * idx = kb->CreateURem(kb->mvmd_extract(mTestFw, operand2Block, i), ConstantInt::get(fwTy, fieldCount));
200            Value * elt = kb->CreateExtractElement(kb->fwCast(mTestFw, operand1Block), kb->CreateZExtOrTrunc(idx, kb->getInt32Ty()));
201            expectedBlock = kb->mvmd_insert(mTestFw, expectedBlock, elt, i);
202        }
203    } else if (mIdisaOperation == "mvmd_dslli") {
204        for (unsigned i = 0; i < fieldCount; i++) {
205            Value * elt = nullptr;
206            if (i < mImmediateShift) elt = kb->mvmd_extract(mTestFw, operand2Block, fieldCount - mImmediateShift + i);
207            else elt = kb->mvmd_extract(mTestFw, operand1Block, i - mImmediateShift);
208            expectedBlock = kb->mvmd_insert(mTestFw, expectedBlock, elt, i);
209        }
210    } else {
211        for (unsigned i = 0; i < fieldCount; i++) {
212            Value * operand1 = kb->mvmd_extract(mTestFw, operand1Block, i);
213            Value * operand2 = kb->mvmd_extract(mTestFw, operand2Block, i);
214            Value * expected = nullptr;
215            if (mIdisaOperation.substr(0,5) == "simd_") {
216                if (mIdisaOperation == "simd_add") {
217                    expected = kb->CreateAdd(operand1, operand2);
218                } else if (mIdisaOperation == "simd_sub") {
219                    expected = kb->CreateSub(operand1, operand2);
220                } else if (mIdisaOperation == "simd_mult") {
221                    expected = kb->CreateMul(operand1, operand2);
222                } else if (mIdisaOperation == "simd_eq") {
223                    expected = kb->CreateSExt(kb->CreateICmpEQ(operand1, operand2), fwTy);
224                } else if (mIdisaOperation == "simd_gt") {
225                    expected = kb->CreateSExt(kb->CreateICmpSGT(operand1, operand2), fwTy);
226                } else if (mIdisaOperation == "simd_ugt") {
227                    expected = kb->CreateSExt(kb->CreateICmpUGT(operand1, operand2), fwTy);
228                } else if (mIdisaOperation == "simd_uge") {
229                    expected = kb->CreateSExt(kb->CreateICmpUGE(operand1, operand2), fwTy);
230                } else if (mIdisaOperation == "simd_lt") {
231                    expected = kb->CreateSExt(kb->CreateICmpSLT(operand1, operand2), fwTy);
232                } else if (mIdisaOperation == "simd_ult") {
233                    expected = kb->CreateSExt(kb->CreateICmpULT(operand1, operand2), fwTy);
234                } else if (mIdisaOperation == "simd_ule") {
235                    expected = kb->CreateSExt(kb->CreateICmpULE(operand1, operand2), fwTy);
236                } else if (mIdisaOperation == "simd_max") {
237                    expected = kb->CreateSelect(kb->CreateICmpSGT(operand1, operand2), operand1, operand2);
238                } else if (mIdisaOperation == "simd_min") {
239                    expected = kb->CreateSelect(kb->CreateICmpSLT(operand1, operand2), operand1, operand2);
240                } else if (mIdisaOperation == "simd_umax") {
241                    expected = kb->CreateSelect(kb->CreateICmpUGT(operand1, operand2), operand1, operand2);
242                } else if (mIdisaOperation == "simd_umin") {
243                    expected = kb->CreateSelect(kb->CreateICmpULT(operand1, operand2), operand1, operand2);
244                } else if (mIdisaOperation == "simd_sllv") {
245                    expected = kb->CreateShl(operand1, operand2);
246                } else if (mIdisaOperation == "simd_srlv") {
247                    expected = kb->CreateLShr(operand1, operand2);
248                } else if (mIdisaOperation == "simd_pext") {
249                    Constant * zeroConst = ConstantInt::getNullValue(fwTy);
250                    Constant * oneConst = ConstantInt::get(fwTy, 1);
251                    expected = zeroConst;
252                    Value * out_bit = oneConst;
253                    for (unsigned i = 0; i < mTestFw; i++) {
254                        Value * i_bit = Constant::getIntegerValue(fwTy, APInt::getOneBitSet(mTestFw, i));
255                        Value * operand_i_isSet = kb->CreateICmpEQ(kb->CreateAnd(operand1, i_bit), i_bit);
256                        Value * mask_i_isSet = kb->CreateICmpEQ(kb->CreateAnd(operand2, i_bit), i_bit);
257                        expected = kb->CreateSelect(kb->CreateAnd(operand_i_isSet, mask_i_isSet), kb->CreateOr(expected, out_bit), expected);
258                        out_bit = kb->CreateSelect(mask_i_isSet, kb->CreateAdd(out_bit, out_bit), out_bit);
259                    }
260                } else if (mIdisaOperation == "simd_pdep") {
261                    Constant * zeroConst = ConstantInt::getNullValue(fwTy);
262                    Constant * oneConst = ConstantInt::get(fwTy, 1);
263                    expected = zeroConst;
264                    Value * shft = zeroConst;
265                    Value * select_bit = oneConst;
266                    for (unsigned i = 0; i < mTestFw; i++) {
267                        expected = kb->CreateOr(kb->CreateAnd(operand2, kb->CreateShl(kb->CreateAnd(operand1, select_bit), shft)), expected);
268                        Value * i_bit = Constant::getIntegerValue(fwTy, APInt::getOneBitSet(mTestFw, i));
269                        Value * mask_i_isSet = kb->CreateICmpEQ(kb->CreateAnd(operand2, i_bit), i_bit);
270                        select_bit = kb->CreateSelect(mask_i_isSet, kb->CreateAdd(select_bit, select_bit), select_bit);
271                        shft = kb->CreateSelect(mask_i_isSet, shft, kb->CreateAdd(shft, oneConst));
272                    }
273                } else {
274                    llvm::report_fatal_error("Unknown SIMD vertical operation: " + mIdisaOperation);
275                }
276                expectedBlock = kb->bitCast(kb->mvmd_insert(mTestFw, expectedBlock, expected, i));
277            } else if (mIdisaOperation == "hsimd_packh") {
278                operand1 = kb->CreateTrunc(kb->CreateLShr(operand1, mTestFw/2), kb->getIntNTy(mTestFw/2));
279                operand2 = kb->CreateTrunc(kb->CreateLShr(operand2, mTestFw/2), kb->getIntNTy(mTestFw/2));
280                expectedBlock = kb->mvmd_insert(mTestFw/2, expectedBlock, operand1, i);
281                expectedBlock = kb->bitCast(kb->mvmd_insert(mTestFw/2, expectedBlock, operand2, fieldCount + i));
282            } else if (mIdisaOperation == "hsimd_packl") {
283                operand1 = kb->CreateTrunc(operand1, kb->getIntNTy(mTestFw/2));
284                operand2 = kb->CreateTrunc(operand2, kb->getIntNTy(mTestFw/2));
285                expectedBlock = kb->mvmd_insert(mTestFw/2, expectedBlock, operand1, i);
286                expectedBlock = kb->bitCast(kb->mvmd_insert(mTestFw/2, expectedBlock, operand2, fieldCount + i));
287            } else if (mIdisaOperation == "esimd_mergeh") {
288                if (i >= fieldCount/2) {
289                    expectedBlock = kb->mvmd_insert(mTestFw, expectedBlock, operand1, 2*(i - fieldCount/2));
290                    expectedBlock = kb->bitCast(kb->mvmd_insert(mTestFw, expectedBlock, operand2, 2*(i - fieldCount/2) + 1));
291                }
292            } else if (mIdisaOperation == "esimd_mergel") {
293                if (i < fieldCount/2) {
294                    expectedBlock = kb->mvmd_insert(mTestFw, expectedBlock, operand1, 2*i);
295                    expectedBlock = kb->bitCast(kb->mvmd_insert(mTestFw, expectedBlock, operand2, 2*i + 1));
296                }
297            }
298        }
299    }
300    kb->storeOutputStreamBlock("expected_result", ZeroConst, expectedBlock);
301    Value * failures = kb->simd_ugt(mTestFw, kb->simd_xor(resultBlock, expectedBlock), kb->allZeroes());
302    Value * anyFailure = kb->bitblock_any(failures);
303    Value * failure_count = kb->CreateUDiv(kb->bitblock_popcount(failures), kb->getSize(mTestFw));
304    kb->setScalarField("totalFailures", kb->CreateAdd(kb->getScalarField("totalFailures"), failure_count));
305    if (!QuietMode) {
306        kb->CreateCondBr(anyFailure, reportFailure, continueTest);
307        kb->SetInsertPoint(reportFailure);
308        kb->CallPrintRegister("operand1", kb->bitCast(operand1Block));
309        kb->CallPrintRegister("operand2", kb->bitCast(operand2Block));
310        kb->CallPrintRegister(mIdisaOperation + "(" + std::to_string(mTestFw) + ", operand1, operand2)", resultBlock);
311        kb->CallPrintRegister("expecting", expectedBlock);
312        kb->CreateBr(continueTest);
313        kb->SetInsertPoint(continueTest);
314    }
315}
316
317// Open a file and return its file desciptor.
318int32_t openFile(const std::string & fileName, llvm::raw_ostream & msgstrm) {
319    if (fileName == "-") {
320        return STDIN_FILENO;
321    }
322    else {
323        struct stat sb;
324        int32_t fileDescriptor = open(fileName.c_str(), O_RDONLY);
325        if (LLVM_UNLIKELY(fileDescriptor == -1)) {
326            if (errno == EACCES) {
327                msgstrm << "idisa_test: " << fileName << ": Permission denied.\n";
328            }
329            else if (errno == ENOENT) {
330                msgstrm << "idisa_test: " << fileName << ": No such file.\n";
331            }
332            else {
333                msgstrm << "idisa_test: " << fileName << ": Failed.\n";
334            }
335            return fileDescriptor;
336        }
337        if (stat(fileName.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
338            msgstrm << "idisa_test: " << fileName << ": Is a directory.\n";
339            close(fileDescriptor);
340            return -1;
341        }
342        return fileDescriptor;
343    }
344}
345
346typedef size_t (*IDISAtestFunctionType)(int32_t fd1, int32_t fd2);
347
348using namespace parabix;
349
350void pipelineGen(ParabixDriver & pxDriver) {
351
352    auto & idb = pxDriver.getBuilder();
353    Module * m = idb->getModule();
354    Value * useMMap = idb->CreateZExt(idb->getTrue(), idb->getInt8Ty());
355    const auto bufferSize = codegen::SegmentSize * codegen::BufferSegments;
356   
357    Type * const int32Ty = idb->getInt32Ty();
358    Type * const sizeTy = idb->getSizeTy();
359
360    FunctionType * const mainType = FunctionType::get(sizeTy, {int32Ty, int32Ty}, false);
361    Function * const main = cast<Function>(m->getOrInsertFunction("Main", mainType));
362    main->setCallingConv(CallingConv::C);
363    Function::arg_iterator args = main->arg_begin();   
364    Value * const fileDecriptor1 = &*(args++);
365    fileDecriptor1->setName("operand1FileDecriptor");
366    Value * const fileDecriptor2 = &*(args++);
367    fileDecriptor2->setName("operand2FileDecriptor");
368
369    idb->SetInsertPoint(BasicBlock::Create(m->getContext(), "entry", main,0));
370
371    StreamSetBuffer * Operand1HexStream = pxDriver.addBuffer<ExternalBuffer>(idb, idb->getStreamSetTy(1, 8));
372    kernel::Kernel * sourceK1 = pxDriver.addKernelInstance<kernel::FDSourceKernel>(idb);
373    sourceK1->setInitialArguments({useMMap, fileDecriptor1});
374    pxDriver.makeKernelCall(sourceK1, {}, {Operand1HexStream});
375   
376    StreamSetBuffer * Operand1BitStream = pxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), bufferSize);
377    kernel::Kernel * hexbinK = pxDriver.addKernelInstance<kernel::HexToBinary>(idb);
378    pxDriver.makeKernelCall(hexbinK, {Operand1HexStream}, {Operand1BitStream});
379   
380    StreamSetBuffer * Operand2HexStream = pxDriver.addBuffer<ExternalBuffer>(idb, idb->getStreamSetTy(1, 8));
381    kernel::Kernel * sourceK2 = pxDriver.addKernelInstance<kernel::FDSourceKernel>(idb);
382    sourceK2->setInitialArguments({useMMap, fileDecriptor2});
383    pxDriver.makeKernelCall(sourceK2, {}, {Operand2HexStream});
384   
385    StreamSetBuffer * Operand2BitStream = pxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), bufferSize);
386    kernel::Kernel * hexbinK2 = pxDriver.addKernelInstance<kernel::HexToBinary>(idb);
387    pxDriver.makeKernelCall(hexbinK2, {Operand2HexStream}, {Operand2BitStream});
388   
389    if (ShiftLimit > 0) {
390        StreamSetBuffer * PreLimitBitStream = Operand2BitStream;
391        Operand2BitStream = pxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), bufferSize);
392        kernel::Kernel * limitK = pxDriver.addKernelInstance<ShiftLimitKernel>(idb, TestFieldWidth, ShiftLimit);
393        pxDriver.makeKernelCall(limitK, {PreLimitBitStream}, {Operand2BitStream});
394    }
395
396    StreamSetBuffer * ResultBitStream = pxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), bufferSize);
397    kernel::Kernel * testK = pxDriver.addKernelInstance<IdisaBinaryOpTestKernel>(idb, TestOperation, TestFieldWidth, Immediate);
398    pxDriver.makeKernelCall(testK, {Operand1BitStream, Operand2BitStream}, {ResultBitStream});
399   
400    StreamSetBuffer * ExpectedResultBitStream = pxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 1), bufferSize);
401    kernel::Kernel * checkK = pxDriver.addKernelInstance<IdisaBinaryOpCheckKernel>(idb, TestOperation, TestFieldWidth, Immediate);
402    pxDriver.makeKernelCall(checkK, {Operand1BitStream, Operand2BitStream, ResultBitStream}, {ExpectedResultBitStream});
403   
404    if (!TestOutputFile.empty()) {
405        StreamSetBuffer * ResultHexStream = pxDriver.addBuffer<StaticBuffer>(idb, idb->getStreamSetTy(1, 8), bufferSize);
406        kernel::Kernel * binhexK = pxDriver.addKernelInstance<kernel::BinaryToHex>(idb);
407        pxDriver.makeKernelCall(binhexK, {ResultBitStream}, {ResultHexStream});
408        kernel::Kernel * outK = pxDriver.addKernelInstance<kernel::FileSink>(idb, 8);
409        Value * fName = idb->CreatePointerCast(idb->GetString(TestOutputFile.c_str()), idb->getInt8PtrTy());
410        outK->setInitialArguments({fName});
411        pxDriver.makeKernelCall(outK, {ResultHexStream}, {});
412   }
413   
414    pxDriver.generatePipelineIR();
415    idb->setKernel(checkK);
416    Value * totalFailures = idb->getAccumulator("totalFailures");
417   
418    pxDriver.deallocateBuffers();
419    idb->CreateRet(totalFailures);
420    pxDriver.finalizeObject();
421}
422
423int main(int argc, char *argv[]) {
424    cl::ParseCommandLineOptions(argc, argv);
425    //codegen::SegmentSize = 1;
426    ParabixDriver pxDriver("idisa_test");
427    pipelineGen(pxDriver);
428   
429    int32_t fd1 = openFile(Operand1TestFile, llvm::outs());
430    int32_t fd2 = openFile(Operand2TestFile, llvm::outs());
431   
432    auto idisaTestFunction = reinterpret_cast<IDISAtestFunctionType>(pxDriver.getMain());
433    size_t failure_count = idisaTestFunction(fd1, fd2);
434    if (!QuietMode) {
435        if (failure_count == 0) {
436            llvm::outs() << "Test success: " << TestOperation << "<" << TestFieldWidth << ">\n";
437        } else {
438            llvm::outs() << "Test failure: " << TestOperation << "<" << TestFieldWidth << "> failed " << failure_count << " tests!\n";
439        }
440    }
441    close(fd1);
442    close(fd2);
443    return failure_count > 0;
444}
Note: See TracBrowser for help on using the repository browser.