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

Last change on this file since 6184 was 6184, checked in by nmedfort, 7 months ago

Initial version of PipelineKernel? + revised StreamSet? model.

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