Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_DETAILS_PACKTRAITS_HPP
43 #define TPETRA_DETAILS_PACKTRAITS_HPP
44 
50 
51 #include "Tpetra_ConfigDefs.hpp"
52 #include "Kokkos_Core.hpp"
53 
54 namespace Tpetra {
55 namespace Details {
56 
62 template<class T, class D>
63 struct PackTraits {
65  typedef T value_type;
66 
80  static const bool compileTimeSize = true;
81 
83  typedef Kokkos::View<const char*, D, Kokkos::MemoryUnmanaged> input_buffer_type;
84 
86  typedef Kokkos::View<char*, D, Kokkos::MemoryUnmanaged> output_buffer_type;
87 
89  typedef Kokkos::View<const value_type*, D, Kokkos::MemoryUnmanaged> input_array_type;
90 
92  typedef Kokkos::View<value_type*, D, Kokkos::MemoryUnmanaged> output_array_type;
93 
108  KOKKOS_INLINE_FUNCTION
109  static size_t
110  numValuesPerScalar (const value_type& /* x */) {
111  // If your type T is something like Stokhos::UQ::PCE<S>, you must
112  // reimplement this function.
113  return static_cast<size_t> (1);
114  }
115 
140  static Kokkos::View<value_type*, D>
142  const size_t numEnt,
143  const std::string& label = "")
144  {
145  typedef Kokkos::View<value_type*, D> view_type;
146  typedef typename view_type::size_type size_type;
147 
148  // When the traits::specialize type is non-void this exploits
149  // the fact that Kokkos::View's constructor ignores
150  // size arguments beyond what the View's type specifies. For
151  // value_type = Stokhos::UQ::PCE<S>, numValuesPerScalar returns
152  // something other than 1, and the constructor will actually use
153  // that value.
154  // Otherwise, the number of arguments must match the dynamic rank
155  // (i.e. number *'s with the value_type of the View)
156  const size_type numVals = numValuesPerScalar (x);
157  if ( std::is_same< typename view_type::traits::specialize, void >::value ) {
158  return view_type (label, static_cast<size_type> (numEnt));
159  }
160  else {
161  return view_type (label, static_cast<size_type> (numEnt), numVals);
162  }
163  }
164 
178  // packArray error code (success = 0)}
179  KOKKOS_INLINE_FUNCTION
180  static Kokkos::pair<int, size_t>
181  packArray (char outBuf[],
182  const value_type inBuf[],
183  const size_t numEnt)
184  {
185  size_t numBytes = 0;
186  int errorCode = 0;
187  typedef Kokkos::pair<int, size_t> pair_type;
188 
189  if (numEnt == 0) {
190  return pair_type (errorCode, numBytes);
191  }
192  else {
193  // NOTE (mfh 02 Feb 2015) This assumes that all instances of T
194  // require the same number of bytes. To generalize this, we
195  // would need to sum up the counts for all entries of inBuf.
196  // That of course would suggest that we would need to memcpy
197  // each entry separately.
198  //
199  // We can't just default construct an instance of T, because if
200  // T's size is run-time dependent, a default-constructed T might
201  // not have the right size. However, we require that all
202  // entries of the input array have the correct size.
203  numBytes = numEnt * packValueCount (inBuf[0]);
204 
205  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
206  // function. It does what one would expect.
207  memcpy (outBuf, inBuf, numBytes);
208  return pair_type (errorCode, numBytes);
209  }
210  }
211 
226  // unpackArray error code (success = 0)}
227  KOKKOS_INLINE_FUNCTION
228  static Kokkos::pair<int, size_t>
230  const char inBuf[],
231  const size_t numEnt)
232  {
233  size_t numBytes = 0;
234  int errorCode = 0;
235  typedef Kokkos::pair<int, size_t> pair_type;
236 
237  if (numEnt == 0) {
238  return pair_type (errorCode, numBytes);
239  }
240  else {
241  // NOTE (mfh 02 Feb 2015) This assumes that all instances of
242  // value_type require the same number of bytes. To generalize
243  // this, we would need to sum up the counts for all entries of
244  // inBuf. That of course would suggest that we would need to
245  // memcpy each entry separately.
246  //
247  // We can't just default construct an instance of value_type,
248  // because if value_type's size is run-time dependent, a
249  // default-constructed value_type might not have the right size.
250  // However, we require that all entries of the input array have
251  // the correct size.
252  const value_type& val = outBuf[0];
253  numBytes = numEnt * packValueCount (val);
254 
255  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
256  // function. It does what one would expect.
257  memcpy (outBuf, inBuf, numBytes);
258  return pair_type (errorCode, numBytes);
259  }
260  }
261 
285  KOKKOS_INLINE_FUNCTION
286  static size_t
287  packValueCount (const T& /* inVal */)
288  {
289  return sizeof (T);
290  }
291 
301  KOKKOS_INLINE_FUNCTION
302  static size_t
303  packValue (char outBuf[],
304  const T& inVal)
305  {
306  // It's actually OK for packValueCount to return an upper bound
307  // (e.g., padding for alignment). The memcpy call below will copy
308  // any included padding as well as the actual data.
309  const size_t numBytes = packValueCount (inVal);
310 
311  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
312  // function. It does what one would expect.
313  memcpy (outBuf, &inVal, numBytes);
314  return numBytes;
315  }
316 
328  KOKKOS_INLINE_FUNCTION
329  static size_t
330  packValue (char outBuf[],
331  const size_t outBufIndex,
332  const T& inVal)
333  {
334  // It's actually OK for packValueCount to return an upper bound
335  // (e.g., padding for alignment). The memcpy call below will copy
336  // any included padding as well as the actual data.
337  const size_t numBytes = packValueCount (inVal);
338  const size_t offset = outBufIndex * numBytes;
339 
340  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
341  // function. It does what one would expect.
342  memcpy (outBuf + offset, &inVal, numBytes);
343  return numBytes;
344  }
345 
358  KOKKOS_INLINE_FUNCTION
359  static size_t
360  unpackValue (T& outVal, const char inBuf[])
361  {
362  // It's actually OK for packValueCount to return an upper bound
363  // (e.g., padding for alignment). The memcpy call below will copy
364  // any included padding as well as the actual data.
365  const size_t numBytes = packValueCount (outVal);
366 
367  // As of CUDA 6, it's totally fine to use memcpy in a CUDA device
368  // function. It does what one would expect.
369  memcpy (&outVal, inBuf, numBytes);
370  return numBytes;
371  }
372 }; // struct PackTraits
373 
374 } // namespace Details
375 } // namespace Tpetra
376 
377 #endif // TPETRA_DETAILS_PACKTRAITS_HPP
static KOKKOS_INLINE_FUNCTION size_t packValueCount(const T &)
Number of bytes required to pack or unpack the given value of type value_type.
Traits class for packing / unpacking data of type T, using Kokkos data structures that live in the gi...
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 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< char *, D, Kokkos::MemoryUnmanaged > output_buffer_type
The type of an output buffer of bytes.
static KOKKOS_INLINE_FUNCTION size_t unpackValue(T &outVal, const char inBuf[])
Unpack the given value from the given output buffer.
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 ...
Kokkos::View< const value_type *, D, Kokkos::MemoryUnmanaged > input_array_type
The type of an input array of value_type.
Kokkos::View< const char *, D, Kokkos::MemoryUnmanaged > input_buffer_type
The type of an input buffer of bytes.
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 numValuesPerScalar(const value_type &)
Given an instance of value_type allocated with the right size, return the &quot;number of values&quot; that mak...
Kokkos::View< value_type *, D, Kokkos::MemoryUnmanaged > output_array_type
The type of an output array of value_type.
static const bool compileTimeSize
Whether the number of bytes required to pack one instance of value_type is fixed at compile time...
T value_type
The type of data to pack or unpack.
static Kokkos::View< value_type *, D > allocateArray(const value_type &x, const size_t numEnt, const std::string &label="")
Given an instance of value_type allocated with the right size, allocate and return a one-dimensional ...