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

Last change on this file since 6144 was 6144, checked in by xwa163, 9 months ago

lz4_grep: Init checkin for utf8 character class multiplexing

File size: 6.7 KB
Line 
1
2#include "untwist_kernel.h"
3#include <kernels/kernel_builder.h>
4
5using namespace llvm;
6
7namespace kernel {
8
9    void untwistByPEXT(const std::unique_ptr <kernel::KernelBuilder> &b, Value* inputBasePtr, unsigned mTwistWidth, Value *outputBlocks[]){
10        Function* PEXT_func = Intrinsic::getDeclaration(b->getModule(), Intrinsic::x86_bmi_pext_64);
11        uint64_t pextBaseMask = mTwistWidth == 2 ? 0x5555555555555555: 0x1111111111111111;
12
13        for (unsigned i = 0; i < mTwistWidth; i++) {
14            outputBlocks[i] = ConstantVector::getNullValue(b->getBitBlockType());
15        }
16
17        for (unsigned i = 0; i < b->getBitBlockWidth() / 64; i++) {
18            Value* currentOutput[mTwistWidth];
19
20            for (unsigned iIndex = 0; iIndex < mTwistWidth; iIndex++) {
21                currentOutput[iIndex] = b->getInt64(0);
22            }
23
24            for (unsigned j = 0; j < mTwistWidth; j++) {
25                unsigned inputIndex = i * mTwistWidth + j;
26
27                Value* currentInput = b->CreateLoad(b->CreateGEP(inputBasePtr, b->getInt32(inputIndex)));
28                for (unsigned k = 0; k < mTwistWidth; k++) {
29
30                    Value* newBits = b->CreateCall(
31                            PEXT_func,{
32                                    currentInput,
33                                    b->getInt64(pextBaseMask << k)
34                            }
35                    );
36
37                    currentOutput[k] = b->CreateOr(currentOutput[k], b->CreateShl(newBits, 64 / mTwistWidth * j));
38                }
39            }
40
41            for (unsigned iIndex = 0; iIndex < mTwistWidth; iIndex++) {
42                outputBlocks[iIndex] = b->CreateInsertElement(outputBlocks[iIndex], currentOutput[iIndex], i);
43            }
44        }
45    }
46
47
48
49
50    UntwistByPEXTKernel::UntwistByPEXTKernel(const std::unique_ptr<kernel::KernelBuilder> &b, unsigned numberOfOutputStream, unsigned twistWidth)
51            :BlockOrientedKernel("UntwistByPEXTKernel",
52                                 {
53                                         Binding{b->getStreamSetTy(1, twistWidth), "byteStream", FixedRate(), Principal()}
54                                 },
55                                 {
56                                         Binding{b->getStreamSetTy(numberOfOutputStream, 1), "basisBits"}
57                                 }, {}, {}, {}),
58             mNumberOfOutputStream(numberOfOutputStream),
59             mTwistWidth(twistWidth)
60    {
61        assert(twistWidth == 2 || twistWidth == 4);
62        assert(numberOfInputStream <= twistWidth);
63
64    }
65
66    void UntwistByPEXTKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> &b) {
67        Value* inputBasePtr = b->CreatePointerCast(b->getInputStreamBlockPtr("byteStream", b->getSize(0)), b->getInt64Ty()->getPointerTo());
68        Value* outputBlocks[mTwistWidth];
69
70        untwistByPEXT(b, inputBasePtr, mTwistWidth, outputBlocks);
71
72        for (unsigned i = 0; i < mNumberOfOutputStream; i++) {
73            b->storeOutputStreamBlock("basisBits", b->getInt32(i), outputBlocks[i]);
74        }
75    }
76
77
78    UntwistMultipleByPEXTKernel::UntwistMultipleByPEXTKernel(const std::unique_ptr<kernel::KernelBuilder> &b,
79                                                             std::vector<unsigned> numberOfOutputStreams,
80                                                             unsigned twistWidth) :
81            BlockOrientedKernel("UntwistMultipleByPEXTKernel",
82                                {
83                                        Binding{b->getStreamSetTy(1, twistWidth), "byteStream", FixedRate(),
84                                                Principal()}
85                                },
86                                {
87                                        //Binding{b->getStreamSetTy(numberOfOutputStream, 1), "basisBits"}
88                                }, {}, {}, {}),
89            mNumberOfOutputStreams(numberOfOutputStreams),
90            mTwistWidth(twistWidth) {
91        assert(twistWidth == 2 || twistWidth == 4);
92
93        size_t totalNumOfStreams = 0;
94        for (unsigned i = 0; i < numberOfOutputStreams.size(); i++) {
95            totalNumOfStreams += numberOfOutputStreams[i];
96            mStreamSetOutputs.push_back(Binding{b->getStreamSetTy(numberOfOutputStreams[i]), "basisBits_" + std::to_string(i) });
97        }
98        assert(totalNumOfStreams < twistWidth);
99    }
100
101    void UntwistMultipleByPEXTKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> &b) {
102        Value* inputBasePtr = b->CreatePointerCast(b->getInputStreamBlockPtr("byteStream", b->getSize(0)), b->getInt64Ty()->getPointerTo());
103        Value* outputBlocks[mTwistWidth];
104        untwistByPEXT(b, inputBasePtr, mTwistWidth, outputBlocks);
105
106        unsigned iStreamIndex = 0;
107        for (unsigned i = 0; i < mNumberOfOutputStreams.size(); i++) {
108            for (unsigned j = 0; j < mNumberOfOutputStreams[i]; j++) {
109                b->storeOutputStreamBlock("basisBits_" + std::to_string(i), b->getInt32(j), outputBlocks[iStreamIndex]);
110                iStreamIndex++;
111            }
112        }
113    }
114
115    StreamCompareKernel::StreamCompareKernel(const std::unique_ptr<kernel::KernelBuilder> &b,
116                                             unsigned int numberOfStream):
117            BlockOrientedKernel("UntwistByPEXTKernel",
118                                {
119                                        Binding{b->getStreamSetTy(numberOfStream, 1), "stream1", FixedRate(), Principal()},
120                                        Binding{b->getStreamSetTy(numberOfStream, 1), "stream2", FixedRate()}
121                                },
122                                {
123//                                        Binding{b->getStreamSetTy(numberOfOutputStream, 1), "basisBits"}
124                                }, {}, {}, {}),mNumberOfStream(numberOfStream)
125    {
126//        this->setStride(4 * 1024 * 1024);
127        this->addScalar(b->getSizeTy(), "pos");
128    }
129
130    void StreamCompareKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> &b) {
131        Value* s1 = b->loadInputStreamBlock("stream1", b->getSize(0));
132        Value* s2 = b->loadInputStreamBlock("stream2", b->getSize(0));
133
134        for (unsigned i = 0 ; i < 4; i++) {
135            Value* v1 = b->CreateExtractElement(s1, i);
136            Value* v2 = b->CreateExtractElement(s2, i);
137            Value* shouldPrint = b->CreateICmpNE(v1, v2);
138            b->CallPrintIntCond("---pos", b->getScalarField("pos"), shouldPrint);
139
140//            b->CallPrintIntCond("s1_available", b->getAvailableItemCount("stream1"), shouldPrint);
141            b->CallPrintRegisterCond("s1", s1, shouldPrint);
142            b->CallPrintRegisterCond("s2", s2, shouldPrint);
143        }
144        b->setScalarField("pos", b->CreateAdd(b->getScalarField("pos"), b->getSize(b->getBitBlockWidth())));
145    };
146}
Note: See TracBrowser for help on using the repository browser.