Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
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
52namespace Tpetra {
53namespace Details {
54
58template<class T>
59struct 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
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
Implementation details of Tpetra.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
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 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 ...
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).
T value_type
The type of data to pack or unpack.
static KOKKOS_INLINE_FUNCTION size_t numValuesPerScalar(const value_type &)
Given an instance of value_type allocated with the right size, return the "number of values" that mak...
static KOKKOS_INLINE_FUNCTION size_t unpackValue(T &outVal, const char inBuf[])
Unpack the given value from the given output buffer.
Kokkos::View< value_type *, Kokkos::AnonymousSpace > 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.
Kokkos::View< const char *, Kokkos::AnonymousSpace > input_buffer_type
The type of an input buffer of bytes.
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 *, Kokkos::AnonymousSpace > output_buffer_type
The type of an output buffer of bytes.
static KOKKOS_INLINE_FUNCTION size_t packValueCount(const T &)
Number of bytes required to pack or unpack the given value of type value_type.
Kokkos::View< const value_type *, Kokkos::AnonymousSpace > input_array_type
The type of an input array of value_type.