Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_AoSoA.hpp
Go to the documentation of this file.
1/****************************************************************************
2 * Copyright (c) 2018-2023 by the Cabana authors *
3 * All rights reserved. *
4 * *
5 * This file is part of the Cabana library. Cabana is distributed under a *
6 * BSD 3-clause license. For the licensing terms see the LICENSE file in *
7 * the top-level directory. *
8 * *
9 * SPDX-License-Identifier: BSD-3-Clause *
10 ****************************************************************************/
11
16#ifndef CABANA_AOSOA_HPP
17#define CABANA_AOSOA_HPP
18
20#include <Cabana_Slice.hpp>
21#include <Cabana_SoA.hpp>
22#include <Cabana_Tuple.hpp>
23#include <Cabana_Types.hpp>
24#include <Cabana_Utils.hpp>
25#include <impl/Cabana_Index.hpp>
27
28#include <Kokkos_Core.hpp>
29
30#include <cmath>
31#include <cstdlib>
32#include <string>
33#include <type_traits>
34
35namespace Cabana
36{
37//---------------------------------------------------------------------------//
38// AoSoA forward declaration.
39template <class DataTypes, class MemorySpace, int VectorLength,
40 class MemoryTraits>
41class AoSoA;
42
43//---------------------------------------------------------------------------//
45template <class>
46struct is_aosoa_impl : public std::false_type
47{
48};
49
50template <class DataTypes, class MemorySpace, int VectorLength,
51 class MemoryTraits>
52struct is_aosoa_impl<AoSoA<DataTypes, MemorySpace, VectorLength, MemoryTraits>>
53 : public std::true_type
54{
55};
57
59template <class T>
60struct is_aosoa : public is_aosoa_impl<typename std::remove_cv<T>::type>::type
61{
62};
63
64//---------------------------------------------------------------------------//
75template <std::size_t M, class AoSoA_t>
76typename AoSoA_t::template member_slice_type<M>
77slice( const AoSoA_t& aosoa, const std::string& slice_label = "" )
78{
79 static_assert(
80 0 == sizeof( typename AoSoA_t::soa_type ) %
81 sizeof( typename AoSoA_t::template member_value_type<M> ),
82 "Slice stride cannot be calculated for misaligned memory!" );
83
84 return typename AoSoA_t::template member_slice_type<M>(
85 Impl::soaMemberPtr<M>( aosoa.data() ), aosoa.size(), aosoa.numSoA(),
86 slice_label );
87}
88
89//---------------------------------------------------------------------------//
116template <class DataTypes, class MemorySpace,
117 int VectorLength = Impl::PerformanceTraits<
118 typename MemorySpace::execution_space>::vector_length,
119 // FIXME: MemoryManaged removed post 4.6 when default was added.
120 // Remove 0 when 4.7 is required.
121 class MemoryTraits = Kokkos::MemoryTraits<0>>
122class AoSoA
123{
124 public:
128
131
133 "AoSoA data types must be member types" );
135 "AoSoA data type failure" );
137 using member_types = DataTypes;
138
140 using memory_space = MemorySpace;
141 static_assert( Kokkos::is_memory_space<MemorySpace>() );
142
144 using execution_space = typename memory_space::execution_space;
145
146 static_assert( Impl::IsVectorLengthValid<VectorLength>::value,
147 "Vector length must be valid" );
149 static constexpr int vector_length = VectorLength;
150
152 using memory_traits = MemoryTraits;
153
155 using size_type = typename memory_space::size_type;
156
159
161 using soa_view = Kokkos::View<soa_type*, memory_space, memory_traits>;
162
164 static constexpr std::size_t number_of_members = member_types::size;
165
167 static constexpr std::size_t max_supported_rank = 3;
168
171
174
178 template <std::size_t M>
180
182 template <std::size_t M>
184 typename std::remove_all_extents<member_data_type<M>>::type;
185
187 template <std::size_t M>
189 typename std::add_pointer<member_value_type<M>>::type;
190
192 template <std::size_t M>
196 sizeof( soa_type ) / sizeof( member_value_type<M> )>;
197
198 public:
206 AoSoA( const std::string& label = "" )
207 : _size( 0 )
208 , _capacity( 0 )
209 , _num_soa( 0 )
210 , _data( Kokkos::ViewAllocateWithoutInitializing( label ), 0 )
211 {
212 static_assert(
213 !memory_traits::is_unmanaged,
214 "Construction by allocation cannot use unmanaged memory" );
215 }
216
224 AoSoA( const std::string label, const size_type n )
225 : _size( n )
226 , _capacity( 0 )
227 , _num_soa( 0 )
228 , _data( Kokkos::ViewAllocateWithoutInitializing( label ), 0 )
229 {
230 static_assert(
231 !memory_traits::is_unmanaged,
232 "Construction by allocation cannot use unmanaged memory" );
233 resize( _size );
234 }
235
245 AoSoA( soa_type* ptr, const size_type num_soa, const size_type n )
246 : _size( n )
247 , _capacity( num_soa * vector_length )
248 , _num_soa( num_soa )
249 , _data( ptr, num_soa )
250 {
251 static_assert( memory_traits::is_unmanaged,
252 "Pointer construction requires unmanaged memory" );
253 }
254
262 std::string label() const { return _data.label(); }
263
271 KOKKOS_FUNCTION
272 size_type size() const { return _size; }
273
281 KOKKOS_FUNCTION
282 bool empty() const { return ( size() == 0 ); }
283
301 KOKKOS_FUNCTION
302 size_type capacity() const { return _capacity; }
303
321 void resize( const size_type n )
322 {
323 static_assert( !memory_traits::is_unmanaged,
324 "Cannot resize unmanaged memory" );
325
326 // Reserve memory if needed.
327 reserve( n );
328
329 // Update the sizes of the data. This is potentially different than
330 // the amount of allocated data.
331 _size = n;
332 _num_soa = std::ceil( static_cast<double>( n ) / vector_length );
333 }
334
353 void reserve( const size_type n )
354 {
355 static_assert( !memory_traits::is_unmanaged,
356 "Cannot reserve unmanaged memory" );
357
358 // If we aren't asking for more memory then we have nothing to do.
359 if ( n <= _capacity )
360 return;
361
362 // Figure out the new capacity.
363 size_type num_soa_alloc = std::floor( n / vector_length );
364 if ( 0 < n % vector_length )
365 ++num_soa_alloc;
366
367 // If we aren't asking for any more SoA objects then we still have
368 // nothing to do.
369 if ( num_soa_alloc <= _num_soa )
370 return;
371
372 // Assign the new capacity.
373 _capacity = num_soa_alloc * vector_length;
374
375 // We need more SoA objects so allocate a new view and copy the
376 // existing data.
377 soa_view resized_data(
378 Kokkos::ViewAllocateWithoutInitializing( _data.label() ),
379 num_soa_alloc );
380 if ( _num_soa > 0 )
381 Kokkos::deep_copy(
382 Kokkos::subview(
383 resized_data,
384 Kokkos::pair<size_type, size_type>( 0, _num_soa ) ),
385 Kokkos::subview( _data, Kokkos::pair<size_type, size_type>(
386 0, _num_soa ) ) );
387 _data = resized_data;
388 }
389
399 {
400 static_assert( !memory_traits::is_unmanaged,
401 "Cannot shrink unmanaged memory" );
402
403 // If we aren't asking for any fewer SoA objects then we have nothing
404 // to do. The amount of allocated data has to be at least as big as
405 // _num_soa so we just need to check here that they are equivalent. If
406 // they are equivalent, the container is already as small as it can be.
407 if ( _data.size() == _num_soa )
408 return;
409
410 // Assign the new capacity.
411 _capacity = _num_soa * vector_length;
412
413 // We need fewer SoA objects so allocate a new view and copy the
414 // existing data.
415 soa_view resized_data(
416 Kokkos::ViewAllocateWithoutInitializing( _data.label() ),
417 _num_soa );
418 if ( _num_soa > 0 )
419 Kokkos::deep_copy(
420 resized_data,
421 Kokkos::subview( _data, Kokkos::pair<size_type, size_type>(
422 0, _num_soa ) ) );
423 _data = resized_data;
424 }
425
430 KOKKOS_INLINE_FUNCTION
431 size_type numSoA() const { return _num_soa; }
432
438 KOKKOS_INLINE_FUNCTION
440 {
441 // the SoA struct size should be full size, i.e. vector_length if:
442 // 1) s is not the last SoA struct
443 // or 2) if _size = _num_soa * vector_length
444 return ( ( (size_type)s < _num_soa - 1 ) ||
445 ( _size % vector_length == 0 ) )
446 ? vector_length // if s is a full SoA struct
447 : ( _size % vector_length ); // if s is the last SoA struct
448 }
449
455 KOKKOS_FORCEINLINE_FUNCTION
456 soa_type& access( const size_type s ) const { return _data( s ); }
457
463 KOKKOS_INLINE_FUNCTION
465 {
466 tuple_type tpl;
467 Impl::tupleCopy( tpl, 0, _data( index_type::s( i ) ),
468 index_type::a( i ) );
469 return tpl;
470 }
471
477 KOKKOS_INLINE_FUNCTION
478 void setTuple( const size_type i, const tuple_type& tpl ) const
479 {
480 Impl::tupleCopy( _data( index_type::s( i ) ), index_type::a( i ), tpl,
481 0 );
482 }
483
488 soa_type* data() const { return _data.data(); }
489
490 private:
491 // Total number of tuples in the container.
492 size_type _size;
493
494 // Allocated number of tuples in all arrays in all structs.
495 size_type _capacity;
496
497 // Number of structs-of-arrays in the array.
498 size_type _num_soa;
499
500 // Structs-of-Arrays managed data. This Kokkos View manages the block of
501 // memory owned by this class such that the copy constructor and
502 // assignment operator for this class perform a shallow and reference
503 // counted copy of the data.
504 soa_view _data;
505};
506
507//---------------------------------------------------------------------------//
508
509} // end namespace Cabana
510
511#endif // CABANA_AOSOA_HPP
AoSoA indexing.
AoSoA tuple member types.
Default settings for execution spaces.
Slice a single particle property from an AoSoA.
Struct-of-Arrays for building AoSoA.
Tuple of single particle information to build AoSoA.
Memory access type checking.
Cabana utilities.
Array-of-Struct-of-Arrays.
Definition Cabana_AoSoA.hpp:123
Impl::Index< vector_length > index_type
Definition Cabana_AoSoA.hpp:170
typename MemberTypeAtIndex< M, member_types >::type member_data_type
Definition Cabana_AoSoA.hpp:179
Tuple< member_types > tuple_type
Definition Cabana_AoSoA.hpp:173
void reserve(const size_type n)
Requests that the container capacity be at least enough to contain n tuples.
Definition Cabana_AoSoA.hpp:353
std::string label() const
Definition Cabana_AoSoA.hpp:262
typename memory_space::size_type size_type
Definition Cabana_AoSoA.hpp:155
void shrinkToFit()
Remove unused capacity.
Definition Cabana_AoSoA.hpp:398
AoSoA(soa_type *ptr, const size_type num_soa, const size_type n)
Create an unmanaged AoSoA with user-provided memory.
Definition Cabana_AoSoA.hpp:245
static constexpr int vector_length
Definition Cabana_AoSoA.hpp:149
KOKKOS_INLINE_FUNCTION size_type arraySize(const size_type s) const
Get the size of the data array at a given struct member index.
Definition Cabana_AoSoA.hpp:439
MemoryTraits memory_traits
Definition Cabana_AoSoA.hpp:152
KOKKOS_FUNCTION bool empty() const
Returns if the container is empty or not.
Definition Cabana_AoSoA.hpp:282
typename memory_space::execution_space execution_space
Definition Cabana_AoSoA.hpp:144
soa_type * data() const
Get a typed raw pointer to the entire data block.
Definition Cabana_AoSoA.hpp:488
KOKKOS_INLINE_FUNCTION tuple_type getTuple(const size_type i) const
Get a tuple at a given index via a deep copy.
Definition Cabana_AoSoA.hpp:464
Slice< member_data_type< M >, memory_space, DefaultAccessMemory, vector_length, sizeof(soa_type)/sizeof(member_value_type< M >)> member_slice_type
Definition Cabana_AoSoA.hpp:193
typename std::add_pointer< member_value_type< M > >::type member_pointer_type
Definition Cabana_AoSoA.hpp:188
KOKKOS_INLINE_FUNCTION void setTuple(const size_type i, const tuple_type &tpl) const
Set a tuple at a given index via a deep copy.
Definition Cabana_AoSoA.hpp:478
MemorySpace memory_space
Definition Cabana_AoSoA.hpp:140
SoA< member_types, vector_length > soa_type
Definition Cabana_AoSoA.hpp:158
KOKKOS_FUNCTION size_type size() const
Returns the number of tuples in the container.
Definition Cabana_AoSoA.hpp:272
typename std::remove_all_extents< member_data_type< M > >::type member_value_type
Definition Cabana_AoSoA.hpp:183
static constexpr std::size_t number_of_members
Definition Cabana_AoSoA.hpp:164
KOKKOS_INLINE_FUNCTION size_type numSoA() const
Get the number of structs-of-arrays in the container.
Definition Cabana_AoSoA.hpp:431
Kokkos::View< soa_type *, memory_space, memory_traits > soa_view
Definition Cabana_AoSoA.hpp:161
static constexpr std::size_t max_supported_rank
Definition Cabana_AoSoA.hpp:167
AoSoA(const std::string &label="")
Default constructor.
Definition Cabana_AoSoA.hpp:206
AoSoA< DataTypes, MemorySpace, VectorLength, MemoryTraits > aosoa_type
AoSoA type.
Definition Cabana_AoSoA.hpp:126
AoSoA(const std::string label, const size_type n)
Allocate a container with n tuples.
Definition Cabana_AoSoA.hpp:224
KOKKOS_FORCEINLINE_FUNCTION soa_type & access(const size_type s) const
Get a reference to the SoA at a given index.
Definition Cabana_AoSoA.hpp:456
void resize(const size_type n)
Resizes the container so that it contains n tuples.
Definition Cabana_AoSoA.hpp:321
AoSoA< DataTypes, Kokkos::HostSpace, VectorLength > host_mirror_type
Definition Cabana_AoSoA.hpp:130
KOKKOS_FUNCTION size_type capacity() const
Returns the size of the storage space currently allocated for the container, expressed in terms of tu...
Definition Cabana_AoSoA.hpp:302
Class for converting between 1d and 2d aosoa indices.
Definition Cabana_Index.hpp:38
static KOKKOS_FORCEINLINE_FUNCTION constexpr std::size_t a(const std::size_t i)
Definition Cabana_Index.hpp:77
static KOKKOS_FORCEINLINE_FUNCTION constexpr std::size_t s(const std::size_t i)
Definition Cabana_Index.hpp:62
A slice of an array-of-structs-of-arrays with data access to a single multidimensional member.
Definition Cabana_Slice.hpp:502
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
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
Check that member types are valid.
Definition Cabana_MemberTypes.hpp:124
Definition Cabana_Types.hpp:37
Get the type of the member at a given index.
Definition Cabana_MemberTypes.hpp:75
Definition Cabana_SoA.hpp:32
Definition Cabana_Tuple.hpp:32
AoSoA static type checker.
Definition Cabana_AoSoA.hpp:61
Static type checker.
Definition Cabana_MemberTypes.hpp:50