GENIE
DeviceCompositeCodec.cu
Go to the documentation of this file.
1 #include <genie/utility/scan.h>
2 
4 #include "DeviceVarintCodec.h"
5 
6 #include "DeviceCompositeCodec.h"
7 
8 #include "DeviceCodecTemplatesImpl.hpp"
9 
10 using namespace genie::compression;
11 
12 // Explicit template instances for Composite Codecs
13 
14 template class
16 template class
18 
19 // Explicit template instances for CPU decoding wrapper function for Composite Codecs
20 // NOTE: This is intentionally separated into mutliple codec implementation files in order to facilitiate separate
21 // compilation units, as opposed to defining all these templates in one place
22 template void
23 genie::compression::decodeArrayParallel<DeviceCompositeCodec<DeviceBitPackingCodec,DeviceCopyCodec>>(int, int, uint32_t*, size_t, uint32_t*, size_t, size_t*);
24 template void
25 genie::compression::decodeArrayParallel<DeviceCompositeCodec<DeviceBitPackingCodec,DeviceVarintCodec>>(int, int, uint32_t*, size_t, uint32_t*, size_t, size_t*);
26 
27 
28 template <class Codec1, class Codec2> void
29 genie::compression::DeviceCompositeCodec<Codec1,Codec2>::encodeArray(uint32_t *in, const size_t length, uint32_t *out, size_t &nvalue)
30 {
31  assert(length > 0);
32  assert(nvalue > 0);
33  int codec1minEffLength = codec1.decodeArrayParallel_minEffectiveLength();
34  size_t codec1Length = (length / codec1minEffLength) * codec1minEffLength;
35  size_t codec2Length = length - codec1Length;
36  assert (codec1Length + codec2Length == length);
37  assert (codec2Length <= length);
38 
39  size_t nvalue1 = 0;
40  if (codec1Length){
41  nvalue1 = nvalue;
42  codec1.encodeArray(in, codec1Length, out + 1, nvalue1);
43  assert(nvalue >= nvalue1); // Error - compression overflow
44  }
45 
46  size_t nvalue2 = 0;
47  if (codec2Length) {
48  nvalue2 = nvalue - nvalue1;
49  codec2.encodeArray(in + codec1Length, codec2Length, out + 1 + nvalue1, nvalue2);
50  assert(nvalue - nvalue1 >= nvalue2); // Error - compression overflow
51  }
52 
53  out[0] = nvalue1; // store infromation about compressed length from the first codec
54 
55  nvalue = 1 + nvalue1 + nvalue2;
56 }
57 
58 template <class Codec1, class Codec2> const uint32_t*
59 genie::compression::DeviceCompositeCodec<Codec1,Codec2>::decodeArray(const uint32_t *in, const size_t comprLength, uint32_t *out, size_t &nvalue)
60 {
61  size_t firstCodecComprLength = *in++;
62 
63  // Codec1 decompresses as much as it can
64  size_t nvalue1 = 0;
65  const uint32_t *inForCodec2 = in;
66 
67  if (firstCodecComprLength){
68  nvalue1 = nvalue; // set capacity for codec1 to overall capacity
69  inForCodec2 = codec1.decodeArray(in, firstCodecComprLength, out, nvalue1);
70 
71  if (nvalue1 > nvalue){ // Error - Codec1 does not have enough capacity
72  nvalue = nvalue1; // Set nvalue to required capacity of codec1
73  return in; // Return pointer to the deginning of the compressed array
74  }
75 
76  if (inForCodec2 == in + comprLength - 1){ // Codec1 decompressed everything
77  nvalue = nvalue1;
78  return inForCodec2;
79  }
80  }
81 
82  assert(inForCodec2 == in + firstCodecComprLength); // Make sure codec1 returned correct d_in pointer
83 
84  // Codec2 decompresses the leftover
85  size_t nvalue2 = nvalue - nvalue1; // remaining capacity
86  size_t leftoverLength = comprLength - 1 - (inForCodec2 - in);
87  const uint32_t *inAfterBothCodecs = codec2.decodeArray(inForCodec2, leftoverLength, out + nvalue1, nvalue2);
88 
89  if (nvalue2 > nvalue - nvalue1){ // Error - Codec2 does not have enough capacity
90  nvalue = nvalue1 + nvalue2; // Set nvalue to required capacity of codec1 + codec2
91  return in; // Return pointer to the deginning of the compressed array
92  }
93 
94  assert(in + comprLength - 1 == inAfterBothCodecs);
95  nvalue = nvalue1 + nvalue2;
96  return inAfterBothCodecs;
97 }
98 
99 
100 template <class Codec1, class Codec2> __device__ uint32_t*
101 genie::compression::DeviceCompositeCodec<Codec1,Codec2>::decodeArraySequential(uint32_t *d_in, size_t length, uint32_t *d_out, size_t &nvalue)
102 {
103  return nullptr;
104 }
105 
106 
107 
108 template <class Codec1, class Codec2> __device__ uint32_t*
110  uint32_t *d_in, size_t comprLength, uint32_t *d_out, size_t &nvalue)
111 {
112  size_t firstCodecComprLength = *d_in++;
113 
114  // Codec1 decompresses as much as it can
115  size_t nvalue1 = 0;
116  uint32_t *d_inForCodec2 = d_in;
117 
118  if (firstCodecComprLength){
119  nvalue1 = nvalue; // set capacity for codec1 to overall capacity
120 
121  d_inForCodec2 = codec1.decodeArrayParallel(d_in, firstCodecComprLength, d_out, nvalue1);
122  __syncthreads();
123 
124  if (nvalue1 > nvalue){ // Error - Codec1 does not have enough capacity
125  nvalue = nvalue1; // Set nvalue to required capacity of codec1
126  return d_in; // Return pointer to the deginning of the compressed array
127  }
128 
129  if (d_inForCodec2 == d_in + comprLength - 1){ // Codec1 decompressed everything
130  nvalue = nvalue1;
131  return d_inForCodec2;
132  }
133  }
134 
135  assert(d_inForCodec2 == d_in + firstCodecComprLength); // Make sure codec1 returned correct d_in pointer
136 
137  // Codec2 decompresses the leftover
138  size_t nvalue2 = nvalue - nvalue1; // remaining capacity
139  size_t leftoverLength = comprLength - 1 - firstCodecComprLength;
140  uint32_t *d_inAfterBothCodecs = codec2.decodeArrayParallel(d_inForCodec2, leftoverLength, d_out + nvalue1, nvalue2);
141  __syncthreads();
142 
143  if (nvalue2 > nvalue - nvalue1){ // Error - Codec2 does not have enough capacity
144  nvalue = nvalue1 + nvalue2; // Set nvalue to required capacity of codec1 + codec2
145  return d_in; // Return pointer to the deginning of the compressed array
146  }
147 
148  assert(d_in + comprLength - 1 == d_inAfterBothCodecs);
149  nvalue = nvalue1 + nvalue2;
150  return d_inAfterBothCodecs;
151 }
152 
const uint32_t * decodeArray(const uint32_t *in, const size_t length, uint32_t *out, size_t &nvalue)
__device__ uint32_t * decodeArrayParallel(uint32_t *d_in, size_t length, uint32_t *d_out, size_t &nvalue)
void encodeArray(uint32_t *in, const size_t length, uint32_t *out, size_t &nvalue)
__device__ uint32_t * decodeArraySequential(uint32_t *d_in, size_t length, uint32_t *d_out, size_t &nvalue)