16#ifndef CABANA_DEEPCOPY_HPP
17#define CABANA_DEEPCOPY_HPP
22#include <impl/Cabana_TypeTraits.hpp>
24#include <Kokkos_Core.hpp>
36template <
class Space,
class SrcAoSoA>
39 const Space&,
const SrcAoSoA& src,
40 typename std::enable_if<
41 ( !std::is_same<
typename SrcAoSoA::memory_space,
42 typename Space::memory_space>::value )>::type* = 0 )
45 "create_mirror() requires an AoSoA" );
46 return AoSoA<
typename SrcAoSoA::member_types, Space,
47 SrcAoSoA::vector_length>(
48 std::string( src.label() ).append(
"_mirror" ), src.size() );
61template <
class Space,
class SrcAoSoA>
63 const Space&,
const SrcAoSoA& src,
64 typename std::enable_if<
65 ( std::is_same<
typename SrcAoSoA::memory_space,
66 typename Space::memory_space>::value )>::type* = 0 )
69 "create_mirror_view() requires an AoSoA" );
83template <
class Space,
class SrcAoSoA>
84inline AoSoA<typename SrcAoSoA::member_types, Space, SrcAoSoA::vector_length>
86 const Space& space,
const SrcAoSoA& src,
87 typename std::enable_if<
88 ( !std::is_same<
typename SrcAoSoA::memory_space,
89 typename Space::memory_space>::value )>::type* = 0 )
92 "create_mirror_view() requires an AoSoA" );
107template <
class Space,
class SrcAoSoA>
109 const Space&,
const SrcAoSoA& src,
110 typename std::enable_if<
111 ( std::is_same<
typename SrcAoSoA::memory_space,
112 typename Space::memory_space>::value &&
129template <
class Space,
class SrcAoSoA>
130inline AoSoA<typename SrcAoSoA::member_types, Space, SrcAoSoA::vector_length>
132 const Space& space,
const SrcAoSoA& src,
133 typename std::enable_if<
134 ( !std::is_same<
typename SrcAoSoA::memory_space,
135 typename Space::memory_space>::value &&
141 typename decltype( dst )::soa_view( dst.data(), dst.numSoA() ),
142 typename SrcAoSoA::soa_view( src.data(), src.numSoA() ) );
156template <
class DstAoSoA,
class SrcAoSoA>
162 using dst_type = DstAoSoA;
163 using src_type = SrcAoSoA;
164 using dst_memory_space =
typename dst_type::memory_space;
165 using src_memory_space =
typename src_type::memory_space;
166 using dst_soa_type =
typename dst_type::soa_type;
167 using src_soa_type =
typename src_type::soa_type;
171 std::is_same<
typename dst_type::member_types,
172 typename src_type::member_types>::value,
173 "Attempted to deep copy AoSoA objects of different member types" );
176 if ( dst.size() != src.size() )
178 throw std::runtime_error(
179 "Attempted to deep copy AoSoA objects of different sizes" );
183 void* dst_data = dst.data();
184 const void* src_data = src.data();
187 if ( dst_data ==
nullptr && src_data ==
nullptr )
193 auto dst_num_soa = dst.numSoA();
194 auto src_num_soa = src.numSoA();
197 if ( ( dst_data == src_data ) && ( dst_num_soa *
sizeof( dst_soa_type ) ==
198 src_num_soa *
sizeof( src_soa_type ) ) )
205 if ( std::is_same<dst_soa_type, src_soa_type>::value )
207 Kokkos::deep_copy( Kokkos::View<char*, dst_memory_space>(
208 reinterpret_cast<char*
>( dst.data() ),
209 dst.numSoA() *
sizeof( dst_soa_type ) ),
210 Kokkos::View<char*, src_memory_space>(
211 reinterpret_cast<char*
>( src.data() ),
212 src.numSoA() *
sizeof( src_soa_type ) ) );
222 typename dst_type::memory_space(), src );
225 auto copy_func = KOKKOS_LAMBDA(
const std::size_t i )
227 dst.setTuple( i, src_copy_on_dst.getTuple( i ) );
229 Kokkos::RangePolicy<typename dst_type::execution_space> exec_policy(
231 Kokkos::parallel_for(
"Cabana::deep_copy", exec_policy, copy_func );
242template <
class DstMemorySpace,
class SrcMemorySpace,
int DstVectorLength,
243 int SrcVectorLength,
class... FieldTags>
249 auto aosoa_src = src.
aosoa();
250 auto& aosoa_dst = dst.
aosoa();
263template <
class AoSoA_t>
265 const typename AoSoA_t::tuple_type& tuple )
268 "Only AoSoAs can be assigned tuples" );
269 auto assign_func = KOKKOS_LAMBDA(
const std::size_t i )
271 aosoa.setTuple( i, tuple );
273 Kokkos::RangePolicy<typename AoSoA_t::execution_space> exec_policy(
275 Kokkos::parallel_for(
"Cabana::deep_copy", exec_policy, assign_func );
288template <
class DstSlice,
class SrcSlice>
294 using dst_type = DstSlice;
295 using src_type = SrcSlice;
299 std::is_same<
typename dst_type::value_type,
300 typename src_type::value_type>::value,
301 "Attempted to deep copy Slice objects of different value types" );
304 static_assert( SrcSlice::view_layout::D0 == SrcSlice::view_layout::D0,
305 "Slice dimension 0 is different" );
306 static_assert( SrcSlice::view_layout::D1 == SrcSlice::view_layout::D1,
307 "Slice dimension 1 is different" );
308 static_assert( SrcSlice::view_layout::D2 == SrcSlice::view_layout::D2,
309 "Slice dimension 2 is different" );
310 static_assert( SrcSlice::view_layout::D3 == SrcSlice::view_layout::D3,
311 "Slice dimension 3 is different" );
312 static_assert( SrcSlice::view_layout::D4 == SrcSlice::view_layout::D4,
313 "Slice dimension 4 is different" );
314 static_assert( SrcSlice::view_layout::D5 == SrcSlice::view_layout::D5,
315 "Slice dimension 5 is different" );
318 if ( dst.size() != src.size() )
320 throw std::runtime_error(
321 "Attempted to deep copy Slice objects of different sizes" );
325 auto dst_data = dst.data();
326 const auto src_data = src.data();
329 if ( dst_data ==
nullptr && src_data ==
nullptr )
335 auto dst_num_soa = dst.numSoA();
336 auto src_num_soa = src.numSoA();
339 if ( ( dst_data == src_data ) &&
340 ( dst_num_soa * dst.stride( 0 ) == src_num_soa * src.stride( 0 ) ) )
346 std::size_t num_comp = 1;
347 for ( std::size_t d = 2; d < dst.viewRank(); ++d )
348 num_comp *= dst.extent( d );
352 Kokkos::View<
typename dst_type::value_type*,
353 typename dst_type::memory_space>
354 gather_dst(
"gather_dst", num_comp * dst.size() );
356 Kokkos::View<
typename src_type::value_type*,
357 typename src_type::memory_space>
358 gather_src(
"gather_src", num_comp * src.size() );
359 auto gather_func = KOKKOS_LAMBDA(
const std::size_t i )
361 auto src_offset = SrcSlice::index_type::s( i ) * src.stride( 0 ) +
362 SrcSlice::index_type::a( i );
363 for ( std::size_t n = 0; n < num_comp; ++n )
364 gather_src( i * num_comp + n ) =
365 src_data[src_offset + SrcSlice::vector_length * n];
367 Kokkos::RangePolicy<typename src_type::execution_space> gather_policy(
369 Kokkos::parallel_for(
"Cabana::deep_copy::gather", gather_policy,
372 Kokkos::deep_copy( gather_dst, gather_src );
376 auto scatter_func = KOKKOS_LAMBDA(
const std::size_t i )
378 auto dst_offset = DstSlice::index_type::s( i ) * dst.stride( 0 ) +
379 DstSlice::index_type::a( i );
380 for ( std::size_t n = 0; n < num_comp; ++n )
381 dst_data[dst_offset + DstSlice::vector_length * n] =
382 gather_dst( i * num_comp + n );
384 Kokkos::RangePolicy<typename dst_type::execution_space> scatter_policy(
386 Kokkos::parallel_for(
"Cabana::deep_copy::scatter", scatter_policy,
398template <
class Slice_t>
400 const typename Slice_t::value_type scalar )
403 "Only slices can be assigned scalars" );
404 Kokkos::deep_copy(
slice.view(), scalar );
415template <
class DstMemorySpace,
class SrcMemorySpace,
int VectorLength,
420 typename std::enable_if<
421 std::is_same<SrcMemorySpace, DstMemorySpace>::value>::type* = 0 )
433template <
class DstMemorySpace,
class SrcMemorySpace,
int VectorLength,
438 typename std::enable_if<
439 !std::is_same<SrcMemorySpace, DstMemorySpace>::value>::type* = 0 )
442 auto aosoa_src = plist_src.
aosoa();
445 using src_plist_type =
446 ParticleList<SrcMemorySpace, VectorLength, FieldTags...>;
447 using member_types =
typename src_plist_type::member_types;
449 aosoa_src.label(), aosoa_src.size() );
455 return ParticleList<DstMemorySpace, VectorLength, FieldTags...>(
Array-of-Struct-of-Arrays particle data structure.
Application-level particle storage and single particle access.
Slice a single particle property from an AoSoA.
Array-of-Struct-of-Arrays.
Definition Cabana_AoSoA.hpp:121
List of particle fields stored in AoSoA.
Definition Cabana_ParticleList.hpp:179
aosoa_type & aosoa()
Get the AoSoA.
Definition Cabana_ParticleList.hpp:221
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
AoSoA< typename SrcAoSoA::member_types, Space, SrcAoSoA::vector_length > create_mirror(const Space &, const SrcAoSoA &src, typename std::enable_if<(!std::is_same< typename SrcAoSoA::memory_space, typename Space::memory_space >::value)>::type *=0)
Allocate a mirror of the given AoSoA in the given space.
Definition Cabana_DeepCopy.hpp:38
void deep_copy(DstAoSoA &dst, const SrcAoSoA &src, typename std::enable_if<(is_aosoa< DstAoSoA >::value &&is_aosoa< SrcAoSoA >::value)>::type *=0)
Deep copy data between compatible AoSoA objects.
Definition Cabana_DeepCopy.hpp:158
SrcAoSoA create_mirror_view(const Space &, const SrcAoSoA &src, typename std::enable_if<(std::is_same< typename SrcAoSoA::memory_space, typename Space::memory_space >::value)>::type *=0)
Create a mirror view of the given AoSoA in the given space. Same space specialization returns the inp...
Definition Cabana_DeepCopy.hpp:62
AoSoA_t::template member_slice_type< M > slice(const AoSoA_t &aosoa, const std::string &slice_label="")
Create a slice from an AoSoA.
Definition Cabana_AoSoA.hpp:77
SrcAoSoA create_mirror_view_and_copy(const Space &, const SrcAoSoA &src, typename std::enable_if<(std::is_same< typename SrcAoSoA::memory_space, typename Space::memory_space >::value &&is_aosoa< SrcAoSoA >::value)>::type *=0)
Create a mirror view of the given AoSoA in the given memory space and copy the contents of the input ...
Definition Cabana_DeepCopy.hpp:108
AoSoA static type checker.
Definition Cabana_AoSoA.hpp:61
Slice static type checker.
Definition Cabana_Slice.hpp:861