source: icGREP/icgrep-devel/icgrep/kernels/lz4/untwist_kernel.cpp @ 6143

Last change on this file since 6143 was 6143, checked in by xwa163, 10 months ago

lz4_grep: some bug fixing and refactor

File size: 4.5 KB
Line 
1
2#include "untwist_kernel.h"
3#include <kernels/kernel_builder.h>
4
5using namespace llvm;
6
7namespace kernel {
8    UntwistByPEXTKernel::UntwistByPEXTKernel(const std::unique_ptr<kernel::KernelBuilder> &b, unsigned numberOfOutputStream, unsigned twistWidth)
9            :BlockOrientedKernel("UntwistByPEXTKernel",
10                                 {
11                                         Binding{b->getStreamSetTy(1, twistWidth), "byteStream", FixedRate(), Principal()}
12                                 },
13                                 {
14                                         Binding{b->getStreamSetTy(numberOfOutputStream, 1), "basisBits"}
15                                 }, {}, {}, {}),
16             mNumberOfOutputStream(numberOfOutputStream),
17             mTwistWidth(twistWidth)
18    {
19        assert(twistWidth == 2 || twistWidth == 4);
20        assert(numberOfInputStream <= twistWidth);
21
22    }
23
24    void UntwistByPEXTKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> &b) {
25        Function* PEXT_func = Intrinsic::getDeclaration(b->getModule(), Intrinsic::x86_bmi_pext_64);
26
27        uint64_t pextBaseMask = mTwistWidth == 2 ? 0x5555555555555555: 0x1111111111111111;
28
29        Value* inputBasePtr = b->CreatePointerCast(b->getInputStreamBlockPtr("byteStream", b->getSize(0)), b->getInt64Ty()->getPointerTo());
30
31        Value* outputBlocks[mTwistWidth];
32        for (unsigned i = 0; i < mTwistWidth; i++) {
33            outputBlocks[i] = ConstantVector::getNullValue(b->getBitBlockType());
34        }
35
36        for (unsigned i = 0; i < b->getBitBlockWidth() / 64; i++) {
37            Value* currentOutput[mTwistWidth];
38
39            for (unsigned iIndex = 0; iIndex < mTwistWidth; iIndex++) {
40                currentOutput[iIndex] = b->getInt64(0);
41            }
42
43            for (unsigned j = 0; j < mTwistWidth; j++) {
44                unsigned inputIndex = i * mTwistWidth + j;
45
46                Value* currentInput = b->CreateLoad(b->CreateGEP(inputBasePtr, b->getInt32(inputIndex)));
47                for (unsigned k = 0; k < mTwistWidth; k++) {
48
49                    Value* newBits = b->CreateCall(
50                            PEXT_func,{
51                                    currentInput,
52                                    b->getInt64(pextBaseMask << k)
53                            }
54                    );
55
56                    currentOutput[k] = b->CreateOr(currentOutput[k], b->CreateShl(newBits, 64 / mTwistWidth * j));
57                }
58            }
59
60            for (unsigned iIndex = 0; iIndex < mTwistWidth; iIndex++) {
61                outputBlocks[iIndex] = b->CreateInsertElement(outputBlocks[iIndex], currentOutput[iIndex], i);
62            }
63        }
64
65        for (unsigned i = 0; i < mNumberOfOutputStream; i++) {
66            b->storeOutputStreamBlock("basisBits", b->getInt32(i), outputBlocks[i]);
67        }
68    }
69
70    StreamCompareKernel::StreamCompareKernel(const std::unique_ptr<kernel::KernelBuilder> &b,
71                                             unsigned int numberOfStream):
72            BlockOrientedKernel("UntwistByPEXTKernel",
73                                {
74                                        Binding{b->getStreamSetTy(numberOfStream, 1), "stream1", FixedRate(), Principal()},
75                                        Binding{b->getStreamSetTy(numberOfStream, 1), "stream2", FixedRate()}
76                                },
77                                {
78//                                        Binding{b->getStreamSetTy(numberOfOutputStream, 1), "basisBits"}
79                                }, {}, {}, {}),mNumberOfStream(numberOfStream)
80    {
81//        this->setStride(4 * 1024 * 1024);
82        this->addScalar(b->getSizeTy(), "pos");
83    }
84
85    void StreamCompareKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> &b) {
86        Value* s1 = b->loadInputStreamBlock("stream1", b->getSize(0));
87        Value* s2 = b->loadInputStreamBlock("stream2", b->getSize(0));
88
89        for (unsigned i = 0 ; i < 4; i++) {
90            Value* v1 = b->CreateExtractElement(s1, i);
91            Value* v2 = b->CreateExtractElement(s2, i);
92            Value* shouldPrint = b->CreateICmpNE(v1, v2);
93            b->CallPrintIntCond("---pos", b->getScalarField("pos"), shouldPrint);
94
95//            b->CallPrintIntCond("s1_available", b->getAvailableItemCount("stream1"), shouldPrint);
96            b->CallPrintRegisterCond("s1", s1, shouldPrint);
97            b->CallPrintRegisterCond("s2", s2, shouldPrint);
98        }
99        b->setScalarField("pos", b->CreateAdd(b->getScalarField("pos"), b->getSize(b->getBitBlockWidth())));
100    };
101}
Note: See TracBrowser for help on using the repository browser.