source: icGREP/icgrep-devel/icgrep/lz4/lz4_base_generator.cpp @ 6137

Last change on this file since 6137 was 6137, checked in by xwa163, 10 months ago
  1. LZ4 ScanMatch? pipeline
  2. Refactor LZ4 Generator
  3. Adjust some naming
File size: 12.7 KB
Line 
1
2
3#include "lz4_base_generator.h"
4#include <kernels/lz4/lz4_block_decoder.h>
5#include <kernels/kernel_builder.h>
6#include <kernels/source_kernel.h>
7#include <kernels/s2p_kernel.h>
8#include <kernels/swizzle.h>
9#include <kernels/lz4/twist_kernel.h>
10#include <kernels/lz4/untwist_kernel.h>
11#include <kernels/lz4/decompression/lz4_bytestream_decompression.h>
12#include <kernels/lz4/decompression/lz4_swizzled_decompression.h>
13#include <kernels/lz4/decompression/lz4_twist_decompression.h>
14#include <kernels/lz4/decompression/lz4_bitstream_decompression.h>
15#include <kernels/lz4/decompression/lz4_parallel_bytestream_decompression.h>
16
17
18using namespace llvm;
19using namespace parabix;
20using namespace kernel;
21
22LZ4BaseGenerator::LZ4BaseGenerator():mPxDriver("lz4"), mLz4BlockSize(4 * 1024 * 1024) {
23
24}
25
26StreamSetBuffer* LZ4BaseGenerator::loadByteStream() {
27    auto & b = mPxDriver.getBuilder();
28    StreamSetBuffer* byteStream = mPxDriver.addBuffer<ExternalBuffer>(b, b->getStreamSetTy(1, 8));
29    kernel::Kernel * sourceK = mPxDriver.addKernelInstance<MemorySourceKernel>(b);
30    sourceK->setInitialArguments({mInputStream, mFileSize});
31    mPxDriver.makeKernelCall(sourceK, {}, {byteStream});
32    return byteStream;
33}
34
35StreamSetBuffer* LZ4BaseGenerator::s2p(parabix::StreamSetBuffer* byteStream) {
36    auto & b = mPxDriver.getBuilder();
37    StreamSetBuffer* basisBits = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(8, 1),
38                                                             this->getDefaultBufferBlocks());
39    Kernel * s2pk = mPxDriver.addKernelInstance<S2PKernel>(b, cc::BitNumbering::BigEndian);
40    mPxDriver.makeKernelCall(s2pk, {byteStream}, {basisBits});
41    return basisBits;
42}
43
44std::pair<parabix::StreamSetBuffer*, parabix::StreamSetBuffer*>  LZ4BaseGenerator::loadByteStreamAndBitStream() {
45    StreamSetBuffer* byteStream = this->loadByteStream();
46    StreamSetBuffer*  basisBits = s2p(byteStream);
47    return std::make_pair(byteStream, basisBits);
48}
49
50
51LZ4BlockInfo LZ4BaseGenerator::getBlockInfo(StreamSetBuffer* compressedByteStream) {
52    auto & b = mPxDriver.getBuilder();
53    LZ4BlockInfo blockInfo;
54    blockInfo.isCompress = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(1, 8), this->getDefaultBufferBlocks(), 1);
55    blockInfo.blockStart = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(1, 64),
56                                                             this->getDefaultBufferBlocks(), 1);
57    blockInfo.blockEnd = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(1, 64), this->getDefaultBufferBlocks(), 1);
58
59    Kernel * blockDecoderK = mPxDriver.addKernelInstance<LZ4BlockDecoderKernel>(b);
60    blockDecoderK->setInitialArguments({b->CreateTrunc(mHasBlockChecksum, b->getInt1Ty()), mHeaderSize, mFileSize});
61    mPxDriver.makeKernelCall(blockDecoderK, {compressedByteStream}, {blockInfo.isCompress, blockInfo.blockStart, blockInfo.blockEnd});
62
63    return blockInfo;
64}
65
66StreamSetBuffer * LZ4BaseGenerator::byteStreamDecompression(StreamSetBuffer* compressedByteStream) {
67    auto & b = mPxDriver.getBuilder();
68    LZ4BlockInfo blockInfo = this->getBlockInfo(compressedByteStream);
69
70    StreamSetBuffer *const decompressionByteStream =
71            mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(1, 8),
72                                              this->getDefaultBufferBlocks(), 1);
73    Kernel* lz4AioK = mPxDriver.addKernelInstance<LZ4ByteStreamDecompressionKernel>(b);
74    lz4AioK->setInitialArguments({mFileSize});
75    mPxDriver.makeKernelCall(
76            lz4AioK,
77            {
78                    compressedByteStream,
79
80                    // Block Data
81                    blockInfo.isCompress,
82                    blockInfo.blockStart,
83                    blockInfo.blockEnd
84            }, {
85                    decompressionByteStream
86            });
87
88    return decompressionByteStream;
89}
90
91StreamSetBuffer * LZ4BaseGenerator::swizzledDecompression(
92        StreamSetBuffer* compressedByteStream,
93        StreamSetBuffer* compressedBasisBits
94) {
95    auto & b = mPxDriver.getBuilder();
96    LZ4BlockInfo blockInfo = this->getBlockInfo(compressedByteStream);
97
98    // Produce unswizzled bit streams
99    StreamSetBuffer * u16Swizzle0 = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(4),
100                                                                      this->getDefaultBufferBlocks(), 1);
101    StreamSetBuffer * u16Swizzle1 = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(4),
102                                                                      this->getDefaultBufferBlocks(), 1);
103    Kernel * unSwizzleK = mPxDriver.addKernelInstance<SwizzleGenerator>(b, 8, 2, 1, 64, "source");
104    mPxDriver.makeKernelCall(unSwizzleK, {compressedBasisBits}, {u16Swizzle0, u16Swizzle1});
105
106
107
108    StreamSetBuffer * uncompressedSwizzled0 = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(4),
109                                                                                this->getDefaultBufferBlocks(), 1);
110    StreamSetBuffer * uncompressedSwizzled1 = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(4),
111                                                                                this->getDefaultBufferBlocks(), 1);
112
113
114    Kernel* lz4AioK = mPxDriver.addKernelInstance<LZ4SwizzledDecompressionKernel>(b, 4, 2, 4);
115    lz4AioK->setInitialArguments({mFileSize});
116    mPxDriver.makeKernelCall(
117            lz4AioK,
118            {
119                    compressedByteStream,
120
121                    blockInfo.isCompress,
122                    blockInfo.blockStart,
123                    blockInfo.blockEnd,
124
125                    u16Swizzle0,
126                    u16Swizzle1
127            }, {
128                    uncompressedSwizzled0,
129                    uncompressedSwizzled1
130            });
131
132
133    StreamSetBuffer * const decompressionBitStream = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(8, 1),
134                                                                                       this->getDefaultBufferBlocks());
135
136    Kernel * unSwizzleK2 = mPxDriver.addKernelInstance<SwizzleGenerator>(b, 8, 1, 2);
137    mPxDriver.makeKernelCall(unSwizzleK2, {uncompressedSwizzled0, uncompressedSwizzled1}, {decompressionBitStream});
138
139    return decompressionBitStream;
140}
141
142StreamSetBuffer * LZ4BaseGenerator::bitStreamDecompression(
143        parabix::StreamSetBuffer* compressedByteStream,
144        parabix::StreamSetBuffer* compressedBasisBits
145) {
146    return this->convertCompressedBitsStreamWithBitStreamAioApproach(compressedByteStream, {compressedBasisBits})[0];
147}
148
149parabix::StreamSetBuffer *LZ4BaseGenerator::parallelByteStreamDecompression(
150        parabix::StreamSetBuffer *compressedByteStream,
151        bool enableGather, bool enableScatter,
152        int minParallelLevel) {
153    auto & iBuilder = mPxDriver.getBuilder();
154    LZ4BlockInfo blockInfo = this->getBlockInfo(compressedByteStream);
155    StreamSetBuffer *const decompressionByteStream
156            = mPxDriver.addBuffer<StaticBuffer>(iBuilder,
157                                                iBuilder->getStreamSetTy(1, 8),
158                                                this->getDefaultBufferBlocks(), 1);
159
160    Kernel *lz4AioK
161            = mPxDriver.addKernelInstance<LZ4ParallelByteStreamDecompressionKernel>(iBuilder, mLz4BlockSize,
162                                                                                    enableGather, enableScatter,
163                                                                                    minParallelLevel);
164    lz4AioK->setInitialArguments({mFileSize});
165    mPxDriver.makeKernelCall(
166            lz4AioK,
167            {
168                    compressedByteStream,
169
170                    blockInfo.isCompress,
171                    blockInfo.blockStart,
172                    blockInfo.blockEnd
173            }, {
174                    decompressionByteStream
175            });
176
177    return decompressionByteStream;
178}
179
180std::vector<StreamSetBuffer*> LZ4BaseGenerator::convertCompressedBitsStreamWithBitStreamAioApproach(
181        parabix::StreamSetBuffer* compressedByteStream,
182        std::vector<StreamSetBuffer*> compressedBitStreams
183) {
184    auto & b = mPxDriver.getBuilder();
185
186    LZ4BlockInfo blockInfo = this->getBlockInfo(compressedByteStream);
187
188    unsigned numOfStreams = compressedBitStreams[0]->getNumOfStreams();
189
190    // 1, 2, 4, 8
191
192    if (numOfStreams <= 2) {
193        StreamSetBuffer* twistedCharClasses = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(1, 2),
194                                                                                   this->getDefaultBufferBlocks());
195        kernel::Kernel* twistK = mPxDriver.addKernelInstance<kernel::TwistByPDEPKernel>(b, numOfStreams, 2);
196        mPxDriver.makeKernelCall(twistK, {compressedBitStreams[0]}, {twistedCharClasses});
197
198        StreamSetBuffer* uncompressedTwistedCharClasses = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(1, 2),
199                                                                                               this->getDefaultBufferBlocks());
200        Kernel* lz4I4AioK = mPxDriver.addKernelInstance<LZ4TwistDecompressionKernel>(b, 2);
201        lz4I4AioK->setInitialArguments({mFileSize});
202        mPxDriver.makeKernelCall(lz4I4AioK, {
203                compressedByteStream,
204
205                blockInfo.isCompress,
206                blockInfo.blockStart,
207                blockInfo.blockEnd,
208
209                twistedCharClasses
210        }, {
211                                            uncompressedTwistedCharClasses
212                                    });
213
214        StreamSetBuffer* untwistedCharClasses = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(numOfStreams),
215                                                                                     this->getDefaultBufferBlocks());
216        kernel::Kernel* untwistK = mPxDriver.addKernelInstance<kernel::UntwistByPEXTKernel>(b, numOfStreams, 2);
217        mPxDriver.makeKernelCall(untwistK, {uncompressedTwistedCharClasses}, {untwistedCharClasses});
218        return {untwistedCharClasses};
219    }
220
221    if (numOfStreams <= 4) {
222        StreamSetBuffer* twistedCharClasses = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(1, 4),
223                                                                                   this->getDefaultBufferBlocks());
224        kernel::Kernel* twistK = mPxDriver.addKernelInstance<kernel::TwistByPDEPKernel>(b, numOfStreams, 4);
225        mPxDriver.makeKernelCall(twistK, {compressedBitStreams[0]}, {twistedCharClasses});
226
227
228        StreamSetBuffer* uncompressedTwistedCharClasses = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(1, 4),
229                                                                                               this->getDefaultBufferBlocks());
230
231        Kernel* lz4I4AioK = mPxDriver.addKernelInstance<LZ4TwistDecompressionKernel>(b, 4);
232        lz4I4AioK->setInitialArguments({mFileSize});
233        mPxDriver.makeKernelCall(lz4I4AioK, {
234                compressedByteStream,
235
236                blockInfo.isCompress,
237                blockInfo.blockStart,
238                blockInfo.blockEnd,
239
240                twistedCharClasses
241        }, {
242                                            uncompressedTwistedCharClasses
243                                    });
244
245        StreamSetBuffer* untwistedCharClasses = mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(numOfStreams),
246                                                                                     this->getDefaultBufferBlocks());
247        kernel::Kernel* untwistK = mPxDriver.addKernelInstance<kernel::UntwistByPEXTKernel>(b, numOfStreams, 4);
248        mPxDriver.makeKernelCall(untwistK, {uncompressedTwistedCharClasses}, {untwistedCharClasses});
249        return {untwistedCharClasses};
250    }
251
252    std::vector<StreamSetBuffer *> inputStreams = {
253            compressedByteStream,
254
255            blockInfo.isCompress,
256            blockInfo.blockStart,
257            blockInfo.blockEnd,
258    };
259
260    std::vector<StreamSetBuffer *> outputStream;
261    std::vector<unsigned> numbersOfStreams;
262
263    for (unsigned i = 0; i < compressedBitStreams.size(); i++) {
264        unsigned numOfStreams = compressedBitStreams[i]->getNumOfStreams();
265        numbersOfStreams.push_back(numOfStreams);
266        inputStreams.push_back(compressedBitStreams[i]);
267        outputStream.push_back(mPxDriver.addBuffer<StaticBuffer>(b, b->getStreamSetTy(numOfStreams, 1),
268                                                                 this->getDefaultBufferBlocks()));
269    }
270
271    Kernel* lz4AioK = mPxDriver.addKernelInstance<LZ4BitStreamDecompressionKernel>(b, numbersOfStreams);
272    lz4AioK->setInitialArguments({mFileSize});
273    mPxDriver.makeKernelCall(lz4AioK, inputStreams, outputStream);
274
275    return outputStream;
276}
277
278unsigned LZ4BaseGenerator::getBlockSizeBufferBlocks() {
279    return mLz4BlockSize / codegen::BlockSize;
280}
281
282unsigned LZ4BaseGenerator::getDefaultBufferBlocks() {
283    return this->getBlockSizeBufferBlocks() * 2; // buffer 2 LZ4 Block By Default
284}
Note: See TracBrowser for help on using the repository browser.