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 std::enable_if_t<( !std::is_same_v<
typename SrcAoSoA::memory_space,
41 typename Space::memory_space> )>* =
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 std::enable_if_t<( std::is_same_v<
typename SrcAoSoA::memory_space,
65 typename Space::memory_space> )>* =
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 std::enable_if_t<( !std::is_same_v<
typename SrcAoSoA::memory_space,
88 typename Space::memory_space> )>* =
92 "create_mirror_view() requires an AoSoA" );
107template <
class Space,
class SrcAoSoA>
109 const Space&,
const SrcAoSoA& src,
110 std::enable_if_t<( std::is_same_v<
typename SrcAoSoA::memory_space,
111 typename Space::memory_space> &&
128template <
class Space,
class SrcAoSoA>
129inline AoSoA<typename SrcAoSoA::member_types, Space, SrcAoSoA::vector_length>
131 const Space& space,
const SrcAoSoA& src,
132 std::enable_if_t<( !std::is_same_v<
typename SrcAoSoA::memory_space,
133 typename Space::memory_space> &&
139 typename decltype( dst )::soa_view( dst.data(), dst.numSoA() ),
140 typename SrcAoSoA::soa_view( src.data(), src.numSoA() ) );
154template <
class DstAoSoA,
class SrcAoSoA>
160 using dst_type = DstAoSoA;
161 using src_type = SrcAoSoA;
162 using dst_memory_space =
typename dst_type::memory_space;
163 using src_memory_space =
typename src_type::memory_space;
164 using dst_soa_type =
typename dst_type::soa_type;
165 using src_soa_type =
typename src_type::soa_type;
168 static_assert( std::is_same_v<
typename dst_type::member_types,
169 typename src_type::member_types>,
170 "Cabana::deep_copy: Attempted to deep copy AoSoA objects of "
171 "different member types" );
174 if ( dst.size() != src.size() )
176 throw std::runtime_error(
177 "Cabana::deep_copy: Attempted to deep copy "
178 "AoSoA objects of different sizes. (Labels: " +
179 src.label() +
", " + dst.label() +
")" );
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_v<dst_soa_type, src_soa_type> )
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 "Cabana::deep_copy: 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;
298 static_assert( std::is_same_v<
typename dst_type::value_type,
299 typename src_type::value_type>,
300 "Cabana::deep_copy: Attempted to deep copy Slice objects of "
301 "different value types" );
304 static_assert( SrcSlice::view_layout::D0 == SrcSlice::view_layout::D0,
305 "Cabana::deep_copy: Slice dimension 0 is different" );
306 static_assert( SrcSlice::view_layout::D1 == SrcSlice::view_layout::D1,
307 "Cabana::deep_copy: Slice dimension 1 is different" );
308 static_assert( SrcSlice::view_layout::D2 == SrcSlice::view_layout::D2,
309 "Cabana::deep_copy: Slice dimension 2 is different" );
310 static_assert( SrcSlice::view_layout::D3 == SrcSlice::view_layout::D3,
311 "Cabana::deep_copy: Slice dimension 3 is different" );
312 static_assert( SrcSlice::view_layout::D4 == SrcSlice::view_layout::D4,
313 "Cabana::deep_copy: Slice dimension 4 is different" );
314 static_assert( SrcSlice::view_layout::D5 == SrcSlice::view_layout::D5,
315 "Cabana::deep_copy: Slice dimension 5 is different" );
318 if ( dst.size() != src.size() )
320 throw std::runtime_error(
321 "Cabana::deep_copy: Attempted to deep copy Slice objects of "
322 "different sizes. (Labels: " +
323 src.label() +
", " + dst.label() +
")" );
327 auto dst_data = dst.data();
328 const auto src_data = src.data();
331 if ( dst_data ==
nullptr && src_data ==
nullptr )
337 auto dst_num_soa = dst.numSoA();
338 auto src_num_soa = src.numSoA();
341 if ( ( dst_data == src_data ) &&
342 ( dst_num_soa * dst.stride( 0 ) == src_num_soa * src.stride( 0 ) ) )
348 std::size_t num_comp = 1;
349 for ( std::size_t d = 2; d < dst.viewRank(); ++d )
350 num_comp *= dst.extent( d );
354 Kokkos::View<
typename dst_type::value_type*,
355 typename dst_type::memory_space>
356 gather_dst(
"gather_dst", num_comp * dst.size() );
358 Kokkos::View<
typename src_type::value_type*,
359 typename src_type::memory_space>
360 gather_src(
"gather_src", num_comp * src.size() );
361 auto gather_func = KOKKOS_LAMBDA(
const std::size_t i )
363 auto src_offset = SrcSlice::index_type::s( i ) * src.stride( 0 ) +
364 SrcSlice::index_type::a( i );
365 for ( std::size_t n = 0; n < num_comp; ++n )
366 gather_src( i * num_comp + n ) =
367 src_data[src_offset + SrcSlice::vector_length * n];
369 Kokkos::RangePolicy<typename src_type::execution_space> gather_policy(
371 Kokkos::parallel_for(
"Cabana::deep_copy::gather", gather_policy,
374 Kokkos::deep_copy( gather_dst, gather_src );
378 auto scatter_func = KOKKOS_LAMBDA(
const std::size_t i )
380 auto dst_offset = DstSlice::index_type::s( i ) * dst.stride( 0 ) +
381 DstSlice::index_type::a( i );
382 for ( std::size_t n = 0; n < num_comp; ++n )
383 dst_data[dst_offset + DstSlice::vector_length * n] =
384 gather_dst( i * num_comp + n );
386 Kokkos::RangePolicy<typename dst_type::execution_space> scatter_policy(
388 Kokkos::parallel_for(
"Cabana::deep_copy::scatter", scatter_policy,
400template <
class Slice_t>
402 const typename Slice_t::value_type scalar )
405 "Cabana::deep_copy: Only slices can be assigned scalars" );
406 Kokkos::deep_copy(
slice.view(), scalar );
417template <
class DstMemorySpace,
class SrcMemorySpace,
int VectorLength,
422 std::enable_if_t<std::is_same_v<SrcMemorySpace, DstMemorySpace>>* =
435template <
class DstMemorySpace,
class SrcMemorySpace,
int VectorLength,
440 std::enable_if_t<!std::is_same_v<SrcMemorySpace, DstMemorySpace>>* =
444 auto aosoa_src = plist_src.
aosoa();
447 using src_plist_type =
448 ParticleList<SrcMemorySpace, VectorLength, FieldTags...>;
449 using member_types =
typename src_plist_type::member_types;
451 aosoa_src.label(), aosoa_src.size() );
457 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:123
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, std::enable_if_t<(!std::is_same_v< typename SrcAoSoA::memory_space, typename Space::memory_space >)> *=nullptr)
Allocate a mirror of the given AoSoA in the given space.
Definition Cabana_DeepCopy.hpp:38
SrcAoSoA create_mirror_view_and_copy(const Space &, const SrcAoSoA &src, std::enable_if_t<(std::is_same_v< typename SrcAoSoA::memory_space, typename Space::memory_space > &&is_aosoa< SrcAoSoA >::value)> *=nullptr)
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
SrcAoSoA create_mirror_view(const Space &, const SrcAoSoA &src, std::enable_if_t<(std::is_same_v< typename SrcAoSoA::memory_space, typename Space::memory_space >)> *=nullptr)
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
void deep_copy(DstAoSoA &dst, const SrcAoSoA &src, std::enable_if_t<(is_aosoa< DstAoSoA >::value &&is_aosoa< SrcAoSoA >::value)> *=nullptr)
Deep copy data between compatible AoSoA objects.
Definition Cabana_DeepCopy.hpp:156
AoSoA static type checker.
Definition Cabana_AoSoA.hpp:61
Slice static type checker.
Definition Cabana_Slice.hpp:861