Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_Details_PackTraits.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Tpetra: Templated Linear Algebra Services Package
4 //
5 // Copyright 2008 NTESS and the Tpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TPETRA_DETAILS_PACKTRAITS_HPP
11 #define TPETRA_DETAILS_PACKTRAITS_HPP
12 
18 
19 #include "Tpetra_ConfigDefs.hpp"
20 #include "Kokkos_Core.hpp"
21 
22 namespace Tpetra {
23 namespace Details {
24 
28 template<class T>
29 struct PackTraits {
31  using value_type = T;
32 
46  static const bool compileTimeSize = true;
47 
49  using input_buffer_type = Kokkos::View<const char*, Kokkos::AnonymousSpace>;
50 
52  using output_buffer_type = Kokkos::View<char*, Kokkos::AnonymousSpace>;
53 
55  using input_array_type = Kokkos::View<const value_type*, Kokkos::AnonymousSpace>;
56 
58  using output_array_type = Kokkos::View<value_type*, Kokkos::AnonymousSpace>;
59 
74  KOKKOS_INLINE_FUNCTION
75  static size_t
76  numValuesPerScalar (const value_type& /* x */) {
77  // If your type T is something like Stokhos::UQ::PCE<S>, you must
78  // reimplement this function.
79  return static_cast<size_t> (1);
80  }
81 
95  // packArray error code (success = 0)}
96  KOKKOS_INLINE_FUNCTION
97  static Kokkos::pair<int, size_t>
98  packArray (char outBuf[],
99  const value_type inBuf[],
100  const size_t numEnt)
101  {
102  size_t numBytes = 0;
103  int errorCode = 0;
104  typedef Kokkos::pair<int, size_t> pair_type;
105 
106  if (numEnt == 0) {
107  return pair_type (errorCode, numBytes);
108  }
109  else {
110  // NOTE (mfh 02 Feb 2015) This assumes that all instances of T
111  // require the same number of bytes. To generalize this, we
112  // would need to sum up the counts for all entries of inBuf.
113  // That of course would suggest that we would need to memcpy
114  // each entry separately.
115  //
116  // We can't just default construct an instance of T, because if
117  // T's size is run-time dependent, a default-constructed T might
118  // not have the right size. However, we require that all
119  // entries of the input array have the correct size.
120  numBytes = numEnt * packValueCount (inBuf[0]);
121 
122  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
123  // function. It does what one would expect.
124  memcpy (outBuf, inBuf, numBytes);
125  return pair_type (errorCode, numBytes);
126  }
127  }
128 
143  // unpackArray error code (success = 0)}
144  KOKKOS_INLINE_FUNCTION
145  static Kokkos::pair<int, size_t>
147  const char inBuf[],
148  const size_t numEnt)
149  {
150  size_t numBytes = 0;
151  int errorCode = 0;
152  typedef Kokkos::pair<int, size_t> pair_type;
153 
154  if (numEnt == 0) {
155  return pair_type (errorCode, numBytes);
156  }
157  else {
158  // NOTE (mfh 02 Feb 2015) This assumes that all instances of
159  // value_type require the same number of bytes. To generalize
160  // this, we would need to sum up the counts for all entries of
161  // inBuf. That of course would suggest that we would need to
162  // memcpy each entry separately.
163  //
164  // We can't just default construct an instance of value_type,
165  // because if value_type's size is run-time dependent, a
166  // default-constructed value_type might not have the right size.
167  // However, we require that all entries of the input array have
168  // the correct size.
169  const value_type& val = outBuf[0];
170  numBytes = numEnt * packValueCount (val);
171 
172  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
173  // function. It does what one would expect.
174  memcpy ((void*) outBuf, inBuf, numBytes);
175  return pair_type (errorCode, numBytes);
176  }
177  }
178 
202  KOKKOS_INLINE_FUNCTION
203  static size_t
204  packValueCount (const T& /* inVal */)
205  {
206  return sizeof (T);
207  }
208 
218  KOKKOS_INLINE_FUNCTION
219  static size_t
220  packValue (char outBuf[],
221  const T& inVal)
222  {
223  // It's actually OK for packValueCount to return an upper bound
224  // (e.g., padding for alignment). The memcpy call below will copy
225  // any included padding as well as the actual data.
226  const size_t numBytes = packValueCount (inVal);
227 
228  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
229  // function. It does what one would expect.
230  memcpy (outBuf, &inVal, numBytes);
231  return numBytes;
232  }
233 
245  KOKKOS_INLINE_FUNCTION
246  static size_t
247  packValue (char outBuf[],
248  const size_t outBufIndex,
249  const T& inVal)
250  {
251  // It's actually OK for packValueCount to return an upper bound
252  // (e.g., padding for alignment). The memcpy call below will copy
253  // any included padding as well as the actual data.
254  const size_t numBytes = packValueCount (inVal);
255  const size_t offset = outBufIndex * numBytes;
256 
257  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
258  // function. It does what one would expect.
259  memcpy (outBuf + offset, &inVal, numBytes);
260  return numBytes;
261  }
262 
275  KOKKOS_INLINE_FUNCTION
276  static size_t
277  unpackValue (T& outVal, const char inBuf[])
278  {
279  // It's actually OK for packValueCount to return an upper bound
280  // (e.g., padding for alignment). The memcpy call below will copy
281  // any included padding as well as the actual data.
282  const size_t numBytes = packValueCount (outVal);
283 
284  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
285  // function. It does what one would expect.
286  memcpy ((void*) &outVal, inBuf, numBytes);
287  return numBytes;
288  }
289 }; // struct PackTraits
290 
291 } // namespace Details
292 } // namespace Tpetra
293 
294 #endif // TPETRA_DETAILS_PACKTRAITS_HPP
LO value_type
The type of data to pack or unpack.
Kokkos::View< char *, Kokkos::AnonymousSpace > output_buffer_type
The type of an output buffer of bytes.
static KOKKOS_INLINE_FUNCTION size_t numValuesPerScalar(const value_type &)
Given an instance of value_type allocated with the right size, return the &quot;number of values&quot; that mak...
static KOKKOS_INLINE_FUNCTION size_t unpackValue(T &outVal, const char inBuf[])
Unpack the given value from the given output buffer.
Traits class for packing / unpacking data of type T.
static KOKKOS_INLINE_FUNCTION Kokkos::pair< int, size_t > packArray(char outBuf[], const value_type inBuf[], const size_t numEnt)
Pack the first numEnt entries of the given input buffer of value_type, into the output buffer of byte...
static const bool compileTimeSize
Whether the number of bytes required to pack one instance of value_type is fixed at compile time...
static KOKKOS_INLINE_FUNCTION size_t packValue(char outBuf[], const size_t outBufIndex, const T &inVal)
Pack the given value of type value_type into the given output buffer of bytes (char).
static KOKKOS_INLINE_FUNCTION size_t packValue(char outBuf[], const T &inVal)
Pack the given value of type value_type into the given output buffer of bytes (char).
Kokkos::View< const char *, Kokkos::AnonymousSpace > input_buffer_type
The type of an input buffer of bytes.
Kokkos::View< const value_type *, Kokkos::AnonymousSpace > input_array_type
The type of an input array of value_type.
Kokkos::View< value_type *, Kokkos::AnonymousSpace > output_array_type
The type of an output array of value_type.
static KOKKOS_INLINE_FUNCTION size_t packValueCount(const T &)
Number of bytes required to pack or unpack the given value of type value_type.
static KOKKOS_INLINE_FUNCTION Kokkos::pair< int, size_t > unpackArray(value_type outBuf[], const char inBuf[], const size_t numEnt)
Unpack numEnt value_type entries from the given input buffer of bytes, to the given output buffer of ...