VTK-m  2.0
ZFPDecode.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_worklet_zfp_decode_h
11 #define vtk_m_worklet_zfp_decode_h
12 
13 #include <vtkm/Types.h>
18 
19 namespace vtkm
20 {
21 namespace worklet
22 {
23 namespace zfp
24 {
25 
26 
27 template <typename Int, typename Scalar>
28 inline VTKM_EXEC Scalar dequantize(const Int& x, const int& e);
29 
30 template <>
31 inline VTKM_EXEC vtkm::Float64 dequantize<vtkm::Int64, vtkm::Float64>(const vtkm::Int64& x,
32  const vtkm::Int32& e)
33 {
34  return vtkm::Ldexp((vtkm::Float64)x, e - (CHAR_BIT * scalar_sizeof<vtkm::Float64>() - 2));
35 }
36 
37 template <>
38 inline VTKM_EXEC vtkm::Float32 dequantize<vtkm::Int32, vtkm::Float32>(const vtkm::Int32& x,
39  const vtkm::Int32& e)
40 {
41  return vtkm::Ldexp((vtkm::Float32)x, e - (CHAR_BIT * scalar_sizeof<vtkm::Float32>() - 2));
42 }
43 
44 template <>
45 inline VTKM_EXEC vtkm::Int32 dequantize<vtkm::Int32, vtkm::Int32>(const vtkm::Int32&,
46  const vtkm::Int32&)
47 {
48  return 1;
49 }
50 
51 template <>
52 inline VTKM_EXEC vtkm::Int64 dequantize<vtkm::Int64, vtkm::Int64>(const vtkm::Int64&,
53  const vtkm::Int32&)
54 {
55  return 1;
56 }
57 
58 template <class Int, vtkm::UInt32 s>
59 VTKM_EXEC static void inv_lift(Int* p)
60 {
61  Int x, y, z, w;
62  x = *p;
63  p += s;
64  y = *p;
65  p += s;
66  z = *p;
67  p += s;
68  w = *p;
69 
70  /*
71  ** non-orthogonal transform
72  ** ( 4 6 -4 -1) (x)
73  ** 1/4 * ( 4 2 4 5) (y)
74  ** ( 4 -2 4 -5) (z)
75  ** ( 4 -6 -4 1) (w)
76  */
77  y += w >> 1;
78  w -= y >> 1;
79  y += w;
80  w <<= 1;
81  w -= y;
82  z += x;
83  x <<= 1;
84  x -= z;
85  y += z;
86  z <<= 1;
87  z -= y;
88  w += x;
89  x <<= 1;
90  x -= w;
91 
92  *p = w;
93  p -= s;
94  *p = z;
95  p -= s;
96  *p = y;
97  p -= s;
98  *p = x;
99 }
100 
101 template <vtkm::Int64 BlockSize>
103 
104 template <>
105 struct inv_transform<64>
106 {
107  template <typename Int>
108  VTKM_EXEC void inv_xform(Int* p)
109  {
110  unsigned int x, y, z;
111  /* transform along z */
112  for (y = 0; y < 4; y++)
113  for (x = 0; x < 4; x++)
114  inv_lift<Int, 16>(p + 1 * x + 4 * y);
115  /* transform along y */
116  for (x = 0; x < 4; x++)
117  for (z = 0; z < 4; z++)
118  inv_lift<Int, 4>(p + 16 * z + 1 * x);
119  /* transform along x */
120  for (z = 0; z < 4; z++)
121  for (y = 0; y < 4; y++)
122  inv_lift<Int, 1>(p + 4 * y + 16 * z);
123  }
124 };
125 
126 template <>
127 struct inv_transform<16>
128 {
129  template <typename Int>
130  VTKM_EXEC void inv_xform(Int* p)
131  {
132 
133  for (int x = 0; x < 4; ++x)
134  {
135  inv_lift<Int, 4>(p + 1 * x);
136  }
137  for (int y = 0; y < 4; ++y)
138  {
139  inv_lift<Int, 1>(p + 4 * y);
140  }
141  }
142 };
143 
144 template <>
145 struct inv_transform<4>
146 {
147  template <typename Int>
148  VTKM_EXEC void inv_xform(Int* p)
149  {
150  inv_lift<Int, 1>(p);
151  }
152 };
153 
154 
155 
156 inline VTKM_EXEC vtkm::Int64 uint2int(vtkm::UInt64 x)
157 {
158  return static_cast<vtkm::Int64>((x ^ 0xaaaaaaaaaaaaaaaaull) - 0xaaaaaaaaaaaaaaaaull);
159 }
160 
161 
163 {
164  return static_cast<vtkm::Int32>((x ^ 0xaaaaaaaau) - 0xaaaaaaaau);
165 }
166 
167 // Note: I die a little inside everytime I write this sort of template
168 template <vtkm::Int32 BlockSize,
169  typename PortalType,
170  template <int Size, typename Portal>
171  class ReaderType,
172  typename UInt>
173 VTKM_EXEC void decode_ints(ReaderType<BlockSize, PortalType>& reader,
174  vtkm::Int32& maxbits,
175  UInt* data,
176  const vtkm::Int32 intprec)
177 {
178  for (vtkm::Int32 i = 0; i < BlockSize; ++i)
179  {
180  data[i] = 0;
181  }
182 
183  vtkm::UInt64 x;
184  const vtkm::UInt32 kmin = 0;
185  vtkm::Int32 bits = maxbits;
186  for (vtkm::UInt32 k = static_cast<vtkm::UInt32>(intprec), n = 0; bits && k-- > kmin;)
187  {
188  // read bit plane
189  vtkm::UInt32 m = vtkm::Min(n, vtkm::UInt32(bits));
190  bits -= m;
191  x = reader.read_bits(static_cast<vtkm::Int32>(m));
192  for (; n < BlockSize && bits && (bits--, reader.read_bit()); x += (Word)1 << n++)
193  for (; n < (BlockSize - 1) && bits && (bits--, !reader.read_bit()); n++)
194  ;
195 
196  // deposit bit plane
197  for (int i = 0; x; i++, x >>= 1)
198  {
199  data[i] += (UInt)(x & 1u) << k;
200  }
201  }
202 }
203 
204 template <vtkm::Int32 BlockSize, typename Scalar, typename PortalType>
205 VTKM_EXEC void zfp_decode(Scalar* fblock,
206  vtkm::Int32 maxbits,
207  vtkm::UInt32 blockIdx,
208  PortalType stream)
209 {
210  zfp::BlockReader<BlockSize, PortalType> reader(stream, maxbits, vtkm::Int32(blockIdx));
211  using Int = typename zfp::zfp_traits<Scalar>::Int;
212  using UInt = typename zfp::zfp_traits<Scalar>::UInt;
213 
214  vtkm::UInt32 cont = 1;
215 
216  if (!zfp::is_int<Scalar>())
217  {
218  cont = reader.read_bit();
219  }
220 
221  if (cont)
222  {
223  vtkm::UInt32 ebits = static_cast<vtkm::UInt32>(zfp::get_ebits<Scalar>()) + 1;
224 
225  vtkm::UInt32 emax;
226  if (!zfp::is_int<Scalar>())
227  {
228  emax = vtkm::UInt32(reader.read_bits(static_cast<vtkm::Int32>(ebits) - 1));
229  emax -= static_cast<vtkm::UInt32>(zfp::get_ebias<Scalar>());
230  }
231  else
232  {
233  // no exponent bits
234  ebits = 0;
235  }
236 
237  maxbits -= ebits;
238  UInt ublock[BlockSize];
239  decode_ints<BlockSize>(reader, maxbits, ublock, zfp::get_precision<Scalar>());
240 
241  Int iblock[BlockSize];
242  const zfp::ZFPCodec<BlockSize> codec;
243  for (vtkm::Int32 i = 0; i < BlockSize; ++i)
244  {
245  vtkm::UInt8 idx = codec.CodecLookup(i);
246  iblock[idx] = uint2int(ublock[i]);
247  }
248 
250  trans.inv_xform(iblock);
251 
252  Scalar inv_w = dequantize<Int, Scalar>(1, static_cast<vtkm::Int32>(emax));
253 
254  for (vtkm::Int32 i = 0; i < BlockSize; ++i)
255  {
256  fblock[i] = inv_w * (Scalar)iblock[i];
257  }
258  }
259 }
260 }
261 }
262 } // namespace vtkm::worklet::zfp
263 #endif
vtkm::worklet::zfp::BlockReader
Definition: ZFPBlockReader.h:25
vtkm::worklet::zfp::inv_transform< 4 >::inv_xform
VTKM_EXEC void inv_xform(Int *p)
Definition: ZFPDecode.h:148
vtkm::worklet::zfp::ZFPCodec
Definition: ZFPCodec.h:27
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
Types.h
vtkm::worklet::zfp::zfp_decode
VTKM_EXEC void zfp_decode(Scalar *fblock, vtkm::Int32 maxbits, vtkm::UInt32 blockIdx, PortalType stream)
Definition: ZFPDecode.h:205
vtkm::worklet::zfp::BlockReader::read_bit
VTKM_EXEC unsigned int read_bit()
Definition: ZFPBlockReader.h:51
ZFPTypeInfo.h
vtkm::worklet::zfp::dequantize
VTKM_EXEC Scalar dequantize(const Int &x, const int &e)
vtkm::worklet::zfp::inv_transform< 16 >::inv_xform
VTKM_EXEC void inv_xform(Int *p)
Definition: ZFPDecode.h:130
ZFPCodec.h
ExportMacros.h
vtkm::worklet::zfp::BlockReader::read_bits
VTKM_EXEC vtkm::UInt64 read_bits(const int &n_bits)
Definition: ZFPBlockReader.h:70
ZFPBlockReader.h
vtkm::worklet::zfp::Word
vtkm::UInt64 Word
Definition: ZFPBlockReader.h:22
vtkm::worklet::zfp::inv_transform
Definition: ZFPDecode.h:102
vtkm::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkm::worklet::zfp::inv_transform< 64 >::inv_xform
VTKM_EXEC void inv_xform(Int *p)
Definition: ZFPDecode.h:108
vtkm::UInt32
uint32_t UInt32
Definition: Types.h:161
vtkm::Float32
float Float32
Definition: Types.h:154
vtkm::Int32
int32_t Int32
Definition: Types.h:160
vtkm::Float64
double Float64
Definition: Types.h:155
vtkm::worklet::zfp::uint2int
VTKM_EXEC vtkm::Int64 uint2int(vtkm::UInt64 x)
Definition: ZFPDecode.h:156
vtkm::worklet::zfp::decode_ints
VTKM_EXEC void decode_ints(ReaderType< BlockSize, PortalType > &reader, vtkm::Int32 &maxbits, UInt *data, const vtkm::Int32 intprec)
Definition: ZFPDecode.h:173
vtkm::Ldexp
VTKM_EXEC_CONT vtkm::Float32 Ldexp(vtkm::Float32 x, vtkm::Int32 exponent)
Definition: Math.h:2582
vtkm::worklet::zfp::zfp_traits
Definition: ZFPTypeInfo.h:162