LvArray
memcpy.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors.
3  * All rights reserved.
4  * See the LICENSE file for details.
5  * SPDX-License-Identifier: (BSD-3-Clause)
6  */
7 
13 #pragma once
14 
15 // Source includes
16 #include "ArrayView.hpp"
17 #include "umpireInterface.hpp"
18 
19 // System includes
20 #include <cstring>
21 
22 namespace LvArray
23 {
24 
25 namespace internal
26 {
27 
38 template< int N_LEFT, typename T, int NDIM, int USD, typename INDEX_TYPE >
39 std::enable_if_t< N_LEFT == 0, ArraySlice< T, NDIM, USD, INDEX_TYPE > >
40 slice( ArraySlice< T, NDIM, USD, INDEX_TYPE > const curSlice, INDEX_TYPE const * )
41 { return curSlice; }
42 
54 template< int N_LEFT, typename T, int NDIM, int USD, typename INDEX_TYPE >
55 std::enable_if_t< N_LEFT != 0, ArraySlice< T, NDIM - N_LEFT, USD - N_LEFT, INDEX_TYPE > >
56 slice( ArraySlice< T, NDIM, USD, INDEX_TYPE > const curSlice, INDEX_TYPE const * const remainingIndices )
57 { return slice< N_LEFT - 1 >( curSlice[ remainingIndices[ 0 ] ], remainingIndices + 1 ); }
58 
59 } // namespace internal
60 
73 template< typename T, int NDIM, int USD, typename DST_INDEX_TYPE, typename SRC_INDEX_TYPE >
76 {
77  LVARRAY_ERROR_IF_NE( dst.size(), src.size() );
78 
79  for( int i = 0; i < NDIM; ++i )
80  {
81  LVARRAY_ERROR_IF_NE( dst.stride( i ), src.stride( i ) );
82  }
83 
84  T * const dstPointer = dst.dataIfContiguous();
85  T * const srcPointer = const_cast< T * >( src.dataIfContiguous() );
86  std::size_t numBytes = dst.size() * sizeof( T );
87 
88  umpireInterface::copy( dstPointer, srcPointer, numBytes );
89 }
90 
107 template< typename T, int NDIM, int USD, typename DST_INDEX_TYPE, typename SRC_INDEX_TYPE >
108 camp::resources::Event memcpy( camp::resources::Resource & resource,
111 {
112  LVARRAY_ERROR_IF_NE( dst.size(), src.size() );
113 
114  for( int i = 0; i < NDIM; ++i )
115  {
116  LVARRAY_ERROR_IF_NE( dst.stride( i ), src.stride( i ) );
117  }
118 
119  T * const dstPointer = dst.dataIfContiguous();
120  T * const srcPointer = const_cast< T * >( src.dataIfContiguous() );
121  std::size_t numBytes = dst.size() * sizeof( T );
122 
123  return umpireInterface::copy( dstPointer, srcPointer, resource, numBytes );
124 }
125 
152 template< std::size_t N_DST_INDICES, std::size_t N_SRC_INDICES, typename T, int DST_NDIM, int DST_USD,
153  typename DST_INDEX_TYPE, template< typename > class DST_BUFFER, int SRC_NDIM, int SRC_USD,
154  typename SRC_INDEX_TYPE, template< typename > class SRC_BUFFER >
156  std::array< DST_INDEX_TYPE, N_DST_INDICES > const & dstIndices,
158  std::array< SRC_INDEX_TYPE, N_SRC_INDICES > const & srcIndices )
159 {
160 #if !defined( LVARRAY_USE_UMPIRE )
161  LVARRAY_ERROR_IF_NE_MSG( dst.getPreviousSpace(), MemorySpace::host, "Without Umpire only host memory is supported." );
162  LVARRAY_ERROR_IF_NE_MSG( src.getPreviousSpace(), MemorySpace::host, "Without Umpire only host memory is supported." );
163 #endif
164 
165  dst.move( dst.getPreviousSpace(), true );
166  src.move( src.getPreviousSpace(), false );
167 
168  ArraySlice< T, DST_NDIM - N_DST_INDICES, DST_USD - N_DST_INDICES, DST_INDEX_TYPE > const dstSlice =
169  internal::slice< N_DST_INDICES >( dst.toSlice(), dstIndices.data() );
170 
171  ArraySlice< T const, SRC_NDIM - N_SRC_INDICES, SRC_USD - N_SRC_INDICES, SRC_INDEX_TYPE > const srcSlice =
172  internal::slice< N_SRC_INDICES >( src.toSlice(), srcIndices.data() );
173 
174  memcpy( dstSlice, srcSlice );
175 }
176 
199 template< std::size_t N_DST_INDICES, std::size_t N_SRC_INDICES, typename T, int DST_NDIM, int DST_USD,
200  typename DST_INDEX_TYPE, template< typename > class DST_BUFFER, int SRC_NDIM, int SRC_USD,
201  typename SRC_INDEX_TYPE, template< typename > class SRC_BUFFER >
202 camp::resources::Event memcpy( camp::resources::Resource & resource,
204  std::array< DST_INDEX_TYPE, N_DST_INDICES > const & dstIndices,
206  std::array< SRC_INDEX_TYPE, N_SRC_INDICES > const & srcIndices )
207 {
208  dst.move( dst.getPreviousSpace(), true );
209  src.move( src.getPreviousSpace(), false );
210 
211  ArraySlice< T, DST_NDIM - N_DST_INDICES, DST_USD - N_DST_INDICES, DST_INDEX_TYPE > const dstSlice =
212  internal::slice< N_DST_INDICES >( dst.toSlice(), dstIndices.data() );
213 
214  ArraySlice< T const, SRC_NDIM - N_SRC_INDICES, SRC_USD - N_SRC_INDICES, SRC_INDEX_TYPE > const srcSlice =
215  internal::slice< N_SRC_INDICES >( src.toSlice(), srcIndices.data() );
216 
217  return memcpy( resource, dstSlice, srcSlice );
218 }
219 
220 } // namespace LvArray
LVARRAY_HOST_DEVICE T * dataIfContiguous() const
Definition: ArraySlice.hpp:318
This class serves to provide a sliced multidimensional interface to the family of LvArray classes...
Definition: ArraySlice.hpp:89
std::enable_if_t< N_LEFT==0, ArraySlice< T, NDIM, USD, INDEX_TYPE > > slice(ArraySlice< T, NDIM, USD, INDEX_TYPE > const curSlice, INDEX_TYPE const *)
Specialization for when all the indices have been consumed.
Definition: memcpy.hpp:40
LVARRAY_HOST_DEVICE constexpr ArraySlice< T, NDIM, USD, INDEX_TYPE > toSlice() const &noexcept
Definition: ArrayView.hpp:308
#define LVARRAY_ERROR_IF_NE_MSG(lhs, rhs, msg)
Raise a hard error if two values are not equal.
Definition: Macros.hpp:305
LVARRAY_HOST_DEVICE constexpr INDEX_TYPE size() const noexcept
Definition: ArraySlice.hpp:170
LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK void copy(DST_VECTOR &&LVARRAY_RESTRICT_REF dstVector, SRC_VECTOR const &LVARRAY_RESTRICT_REF srcVector)
Copy srcVector into dstVector.
Definition: genericTensorOps.hpp:360
Contains the LvArray umpire interface. This is only used to keep umpire/ResourceManager.hpp out of the includes for most headers.
This class serves to provide a "view" of a multidimensional array.
Definition: ArrayView.hpp:68
void memcpy(ArraySlice< T, NDIM, USD, DST_INDEX_TYPE > const dst, ArraySlice< T const, NDIM, USD, SRC_INDEX_TYPE > const src)
Use memcpy to copy src in to dst.
Definition: memcpy.hpp:74
LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK INDEX_TYPE stride(int const dim) const noexcept
Definition: ArraySlice.hpp:203
void move(MemorySpace const space, bool const touch=true) const
Move the Array to the given execution space, optionally touching it.
Definition: ArrayView.hpp:690
The top level namespace.
Definition: Array.hpp:24
MemorySpace getPreviousSpace() const
Definition: ArrayView.hpp:674
#define LVARRAY_ERROR_IF_NE(lhs, rhs)
Raise a hard error if two values are not equal.
Definition: Macros.hpp:321
Contains the implementation of LvArray::ArrayView.