source: icGREP/icgrep-devel/icgrep/kernels/p2s_kernel.cpp @ 5902

Last change on this file since 5902 was 5771, checked in by nmedfort, 20 months ago

Minor changes and hopefully a fix for bug exposed by base64 test

File size: 8.2 KB
Line 
1#include "p2s_kernel.h"
2#include <kernels/streamset.h>
3#include <kernels/kernel_builder.h>
4#include <toolchain/toolchain.h>
5#include <llvm/Support/Compiler.h>
6
7namespace llvm { class Value; }
8
9using namespace llvm;
10using namespace parabix;
11
12namespace kernel{
13       
14void p2s_step(const std::unique_ptr<KernelBuilder> & iBuilder, Value * p0, Value * p1, Value * hi_mask, unsigned shift, Value * &s1, Value * &s0) {
15    Value * t0 = iBuilder->simd_if(1, hi_mask, p0, iBuilder->simd_srli(16, p1, shift));
16    Value * t1 = iBuilder->simd_if(1, hi_mask, iBuilder->simd_slli(16, p0, shift), p1);
17    s1 = iBuilder->esimd_mergeh(8, t1, t0);
18    s0 = iBuilder->esimd_mergel(8, t1, t0);
19}
20
21inline void p2s(const std::unique_ptr<KernelBuilder> & iBuilder, Value * p[], Value * s[]) {
22    Value * bit00004444[2];
23    Value * bit22226666[2];
24    Value * bit11115555[2];
25    Value * bit33337777[2];
26    p2s_step(iBuilder, p[0], p[4], iBuilder->simd_himask(8), 4, bit00004444[1], bit00004444[0]);
27    p2s_step(iBuilder, p[1], p[5], iBuilder->simd_himask(8), 4, bit11115555[1], bit11115555[0]);
28    p2s_step(iBuilder, p[2], p[6], iBuilder->simd_himask(8), 4, bit22226666[1], bit22226666[0]);
29    p2s_step(iBuilder, p[3], p[7], iBuilder->simd_himask(8), 4, bit33337777[1], bit33337777[0]);
30    Value * bit00224466[4];
31    Value * bit11335577[4];
32    for (unsigned j = 0; j<2; j++) {
33        p2s_step(iBuilder, bit00004444[j], bit22226666[j],iBuilder->simd_himask(4), 2, bit00224466[2*j+1], bit00224466[2*j]);
34        p2s_step(iBuilder, bit11115555[j], bit33337777[j],iBuilder->simd_himask(4), 2, bit11335577[2*j+1], bit11335577[2*j]);
35    }
36    for (unsigned j = 0; j<4; j++) {
37        p2s_step(iBuilder, bit00224466[j], bit11335577[j], iBuilder->simd_himask(2), 1, s[2*j+1], s[2*j]);
38    }
39}
40               
41void P2SKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & b) {
42    Value * p_bitblock[8];
43    for (unsigned i = 0; i < 8; i++) {
44        p_bitblock[i] = b->loadInputStreamBlock("basisBits", b->getInt32(i));
45    }
46    Value * s_bytepack[8];
47    p2s(b, p_bitblock, s_bytepack);
48    for (unsigned j = 0; j < 8; ++j) {
49        b->storeOutputStreamPack("byteStream", b->getInt32(0), b->getInt32(j), s_bytepack[j]);
50    }
51}
52
53void P2SKernelWithCompressedOutput::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & b) {
54    IntegerType * i32 = b->getInt32Ty();
55    PointerType * bitBlockPtrTy = PointerType::get(b->getBitBlockType(), 0);
56
57    Value * basisBits[8];
58    for (unsigned i = 0; i < 8; i++) {
59        basisBits[i] = b->loadInputStreamBlock("basisBits", b->getInt32(i));
60    }
61    Value * bytePack[8];
62    p2s(b, basisBits, bytePack);
63
64    unsigned units_per_register = b->getBitBlockWidth()/8;
65    Value * delCountBlock_ptr = b->getInputStreamBlockPtr("deletionCounts", b->getInt32(0));
66    Value * unit_counts = b->fwCast(units_per_register, b->CreateBlockAlignedLoad(delCountBlock_ptr));
67
68    Value * output_ptr = b->getOutputStreamBlockPtr("byteStream", b->getInt32(0));
69    output_ptr = b->CreatePointerCast(output_ptr, b->getInt8PtrTy());
70    Value * offset = b->getInt32(0);
71    for (unsigned j = 0; j < 8; ++j) {
72        b->CreateStore(bytePack[j], b->CreateBitCast(b->CreateGEP(output_ptr, offset), bitBlockPtrTy));
73        offset = b->CreateZExt(b->CreateExtractElement(unit_counts, b->getInt32(j)), i32);
74    }
75
76    Value * unitsGenerated = b->getProducedItemCount("byteStream"); // units generated to buffer
77    unitsGenerated = b->CreateAdd(unitsGenerated, b->CreateZExt(offset, b->getSizeTy()));
78    b->setProducedItemCount("byteStream", unitsGenerated);
79}
80
81void P2S16Kernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & b) {
82    Value * hi_input[8];
83    for (unsigned j = 0; j < 8; ++j) {
84        hi_input[j] = b->loadInputStreamBlock("basisBits", b->getInt32(j));
85    }
86    Value * hi_bytes[8];
87    p2s(b, hi_input, hi_bytes);
88    Value * lo_input[8];
89    for (unsigned j = 0; j < 8; ++j) {
90        lo_input[j] = b->loadInputStreamBlock("basisBits", b->getInt32(j + 8));
91    }
92    Value * lo_bytes[8];
93    p2s(b, lo_input, lo_bytes);
94    for (unsigned j = 0; j < 8; ++j) {
95        Value * merge0 = b->bitCast(b->esimd_mergel(8, hi_bytes[j], lo_bytes[j]));
96        Value * merge1 = b->bitCast(b->esimd_mergeh(8, hi_bytes[j], lo_bytes[j]));
97        b->storeOutputStreamPack("i16Stream", b->getInt32(0), b->getInt32(2 * j), merge0);
98        b->storeOutputStreamPack("i16Stream", b->getInt32(0), b->getInt32(2 * j + 1), merge1);
99    }
100}
101       
102void P2S16KernelWithCompressedOutput::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & b) {
103    IntegerType * i32Ty = b->getInt32Ty();
104    PointerType * int16PtrTy = b->getInt16Ty()->getPointerTo();
105    PointerType * bitBlockPtrTy = b->getBitBlockType()->getPointerTo();
106    ConstantInt * blockMask = b->getSize(b->getBitBlockWidth() - 1);
107
108    Value * hi_input[8];
109    for (unsigned j = 0; j < 8; ++j) {
110        hi_input[j] = b->loadInputStreamBlock("basisBits", b->getInt32(j));
111    }
112    Value * hi_bytes[8];
113    p2s(b, hi_input, hi_bytes);
114
115    Value * lo_input[8];
116    for (unsigned j = 0; j < 8; ++j) {
117        lo_input[j] = b->loadInputStreamBlock("basisBits", b->getInt32(j + 8));
118    }
119    Value * lo_bytes[8];
120    p2s(b, lo_input, lo_bytes);
121
122    Value * const delCount = b->loadInputStreamBlock("deletionCounts", b->getInt32(0));
123    Value * const unitCounts = b->fwCast(b->getBitBlockWidth() / 16, delCount);
124    Value * outputPtr = b->getOutputStreamBlockPtr("i16Stream", b->getInt32(0));
125    outputPtr = b->CreatePointerCast(outputPtr, int16PtrTy);
126    Value * const i16UnitsGenerated = b->getProducedItemCount("i16Stream"); // units generated to buffer
127    outputPtr = b->CreateGEP(outputPtr, b->CreateAnd(i16UnitsGenerated, blockMask));
128
129    Value * offset = b->getInt32(0);
130
131    for (unsigned j = 0; j < 8; ++j) {
132        Value * const merge0 = b->bitCast(b->esimd_mergel(8, hi_bytes[j], lo_bytes[j]));
133        b->CreateAlignedStore(merge0, b->CreateBitCast(b->CreateGEP(outputPtr, offset), bitBlockPtrTy), 1);
134        Value * const nextOffset1 = b->CreateZExt(b->CreateExtractElement(unitCounts, b->getInt32(2 * j)), i32Ty);
135        if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
136            b->CreateAssert(b->CreateICmpULE(offset, nextOffset1), "deletion offset is not monotonically non-decreasing");
137        }
138        Value * const merge1 = b->bitCast(b->esimd_mergeh(8, hi_bytes[j], lo_bytes[j]));
139        b->CreateAlignedStore(merge1, b->CreateBitCast(b->CreateGEP(outputPtr, nextOffset1), bitBlockPtrTy), 1);
140        Value * const nextOffset2 = b->CreateZExt(b->CreateExtractElement(unitCounts, b->getInt32(2 * j + 1)), i32Ty);
141        if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
142            b->CreateAssert(b->CreateICmpULE(nextOffset1, nextOffset2), "deletion offset is not monotonically non-decreasing");
143        }
144        offset = nextOffset2;
145    }
146
147    Value * const i16UnitsFinal = b->CreateAdd(i16UnitsGenerated, b->CreateZExt(offset, b->getSizeTy()));
148    b->setProducedItemCount("i16Stream", i16UnitsFinal);
149}
150
151P2SKernel::P2SKernel(const std::unique_ptr<kernel::KernelBuilder> & b)
152: BlockOrientedKernel("p2s",
153              {Binding{b->getStreamSetTy(8, 1), "basisBits"}},
154              {Binding{b->getStreamSetTy(1, 8), "byteStream"}},
155              {}, {}, {}) {
156}
157
158P2SKernelWithCompressedOutput::P2SKernelWithCompressedOutput(const std::unique_ptr<kernel::KernelBuilder> & b)
159: BlockOrientedKernel("p2s_compress",
160              {Binding{b->getStreamSetTy(8, 1), "basisBits"}, Binding{b->getStreamSetTy(1, 1), "deletionCounts"}},
161              {Binding{b->getStreamSetTy(1, 8), "byteStream", BoundedRate(0, 1)}},
162              {}, {}, {}) {
163}
164
165P2S16Kernel::P2S16Kernel(const std::unique_ptr<kernel::KernelBuilder> & b)
166: BlockOrientedKernel("p2s_16",
167              {Binding{b->getStreamSetTy(16, 1), "basisBits"}},
168              {Binding{b->getStreamSetTy(1, 16), "i16Stream"}},
169              {}, {}, {}) {
170}
171
172
173P2S16KernelWithCompressedOutput::P2S16KernelWithCompressedOutput(const std::unique_ptr<kernel::KernelBuilder> & b)
174: BlockOrientedKernel("p2s_16_compress",
175              {Binding{b->getStreamSetTy(16, 1), "basisBits"}, Binding{b->getStreamSetTy(1, 1), "deletionCounts"}},
176              {Binding{b->getStreamSetTy(1, 16), "i16Stream", BoundedRate(0, 1)}},
177              {},
178              {},
179              {}) {
180
181}
182   
183   
184}
Note: See TracBrowser for help on using the repository browser.