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 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // ************************************************************************
38 // @HEADER
39 
40 #ifndef TPETRA_DETAILS_PACKTRAITS_HPP
41 #define TPETRA_DETAILS_PACKTRAITS_HPP
42 
48 
49 #include "Tpetra_ConfigDefs.hpp"
50 #include "Kokkos_Core.hpp"
51 
52 namespace Tpetra {
53 namespace Details {
54 
58 template<class T>
59 struct PackTraits {
61  using value_type = T;
62 
76  static const bool compileTimeSize = true;
77 
79  using input_buffer_type = Kokkos::View<const char*, Kokkos::AnonymousSpace>;
80 
82  using output_buffer_type = Kokkos::View<char*, Kokkos::AnonymousSpace>;
83 
85  using input_array_type = Kokkos::View<const value_type*, Kokkos::AnonymousSpace>;
86 
88  using output_array_type = Kokkos::View<value_type*, Kokkos::AnonymousSpace>;
89 
104  KOKKOS_INLINE_FUNCTION
105  static size_t
106  numValuesPerScalar (const value_type& /* x */) {
107  // If your type T is something like Stokhos::UQ::PCE<S>, you must
108  // reimplement this function.
109  return static_cast<size_t> (1);
110  }
111 
125  // packArray error code (success = 0)}
126  KOKKOS_INLINE_FUNCTION
127  static Kokkos::pair<int, size_t>
128  packArray (char outBuf[],
129  const value_type inBuf[],
130  const size_t numEnt)
131  {
132  size_t numBytes = 0;
133  int errorCode = 0;
134  typedef Kokkos::pair<int, size_t> pair_type;
135 
136  if (numEnt == 0) {
137  return pair_type (errorCode, numBytes);
138  }
139  else {
140  // NOTE (mfh 02 Feb 2015) This assumes that all instances of T
141  // require the same number of bytes. To generalize this, we
142  // would need to sum up the counts for all entries of inBuf.
143  // That of course would suggest that we would need to memcpy
144  // each entry separately.
145  //
146  // We can't just default construct an instance of T, because if
147  // T's size is run-time dependent, a default-constructed T might
148  // not have the right size. However, we require that all
149  // entries of the input array have the correct size.
150  numBytes = numEnt * packValueCount (inBuf[0]);
151 
152  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
153  // function. It does what one would expect.
154  memcpy (outBuf, inBuf, numBytes);
155  return pair_type (errorCode, numBytes);
156  }
157  }
158 
173  // unpackArray error code (success = 0)}
174  KOKKOS_INLINE_FUNCTION
175  static Kokkos::pair<int, size_t>
177  const char inBuf[],
178  const size_t numEnt)
179  {
180  size_t numBytes = 0;
181  int errorCode = 0;
182  typedef Kokkos::pair<int, size_t> pair_type;
183 
184  if (numEnt == 0) {
185  return pair_type (errorCode, numBytes);
186  }
187  else {
188  // NOTE (mfh 02 Feb 2015) This assumes that all instances of
189  // value_type require the same number of bytes. To generalize
190  // this, we would need to sum up the counts for all entries of
191  // inBuf. That of course would suggest that we would need to
192  // memcpy each entry separately.
193  //
194  // We can't just default construct an instance of value_type,
195  // because if value_type's size is run-time dependent, a
196  // default-constructed value_type might not have the right size.
197  // However, we require that all entries of the input array have
198  // the correct size.
199  const value_type& val = outBuf[0];
200  numBytes = numEnt * packValueCount (val);
201 
202  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
203  // function. It does what one would expect.
204  memcpy (outBuf, inBuf, numBytes);
205  return pair_type (errorCode, numBytes);
206  }
207  }
208 
232  KOKKOS_INLINE_FUNCTION
233  static size_t
234  packValueCount (const T& /* inVal */)
235  {
236  return sizeof (T);
237  }
238 
248  KOKKOS_INLINE_FUNCTION
249  static size_t
250  packValue (char outBuf[],
251  const T& inVal)
252  {
253  // It's actually OK for packValueCount to return an upper bound
254  // (e.g., padding for alignment). The memcpy call below will copy
255  // any included padding as well as the actual data.
256  const size_t numBytes = packValueCount (inVal);
257 
258  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
259  // function. It does what one would expect.
260  memcpy (outBuf, &inVal, numBytes);
261  return numBytes;
262  }
263 
275  KOKKOS_INLINE_FUNCTION
276  static size_t
277  packValue (char outBuf[],
278  const size_t outBufIndex,
279  const T& inVal)
280  {
281  // It's actually OK for packValueCount to return an upper bound
282  // (e.g., padding for alignment). The memcpy call below will copy
283  // any included padding as well as the actual data.
284  const size_t numBytes = packValueCount (inVal);
285  const size_t offset = outBufIndex * numBytes;
286 
287  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
288  // function. It does what one would expect.
289  memcpy (outBuf + offset, &inVal, numBytes);
290  return numBytes;
291  }
292 
305  KOKKOS_INLINE_FUNCTION
306  static size_t
307  unpackValue (T& outVal, const char inBuf[])
308  {
309  // It's actually OK for packValueCount to return an upper bound
310  // (e.g., padding for alignment). The memcpy call below will copy
311  // any included padding as well as the actual data.
312  const size_t numBytes = packValueCount (outVal);
313 
314  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
315  // function. It does what one would expect.
316  memcpy (&outVal, inBuf, numBytes);
317  return numBytes;
318  }
319 }; // struct PackTraits
320 
321 } // namespace Details
322 } // namespace Tpetra
323 
324 #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 ...