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
139 // FIXME: extracting the self type for backwards compatibility with previous
140 // template on DeviceType. Should simply be MemorySpace after next release.
142 using memory_space = typename MemorySpace::memory_space;
143 // FIXME: replace warning with memory space assert after next release.
144 static_assert( Impl::deprecated( Kokkos::is_device<MemorySpace>() ) );
145
147 using device_type [[deprecated]] = typename memory_space::device_type;
149 using execution_space = typename memory_space::execution_space;
150
151 static_assert( Impl::IsVectorLengthValid<VectorLength>::value,
152 "Vector length must be valid" );
154 static constexpr int vector_length = VectorLength;
155
157 using memory_traits = MemoryTraits;
158
160 using size_type = typename memory_space::size_type;
161
164
166 using soa_view = Kokkos::View<soa_type*, memory_space, memory_traits>;
167
169 static constexpr std::size_t number_of_members = member_types::size;
170
172 static constexpr std::size_t max_supported_rank = 3;
173
176
179
183 template <std::size_t M>
185
187 template <std::size_t M>
189 typename std::remove_all_extents<member_data_type<M>>::type;
190
192 template <std::size_t M>
194 typename std::add_pointer<member_value_type<M>>::type;
195
197 template <std::size_t M>
201 sizeof( soa_type ) / sizeof( member_value_type<M> )>;
202
203 public:
211 AoSoA( const std::string& label = "" )
212 : _size( 0 )
213 , _capacity( 0 )
214 , _num_soa( 0 )
215 , _data( Kokkos::ViewAllocateWithoutInitializing( label ), 0 )
216 {
217 static_assert(
218 !memory_traits::is_unmanaged,
219 "Construction by allocation cannot use unmanaged memory" );
220 }
221
229 AoSoA( const std::string label, const size_type n )
230 : _size( n )
231 , _capacity( 0 )
232 , _num_soa( 0 )
233 , _data( Kokkos::ViewAllocateWithoutInitializing( label ), 0 )
234 {
235 static_assert(
236 !memory_traits::is_unmanaged,
237 "Construction by allocation cannot use unmanaged memory" );
238 resize( _size );
239 }
240
250 AoSoA( soa_type* ptr, const size_type num_soa, const size_type n )
251 : _size( n )
252 , _capacity( num_soa * vector_length )
253 , _num_soa( num_soa )
254 , _data( ptr, num_soa )
255 {
256 static_assert( memory_traits::is_unmanaged,
257 "Pointer construction requires unmanaged memory" );
258 }
259
267 std::string label() const { return _data.label(); }
268
276 KOKKOS_FUNCTION
277 size_type size() const { return _size; }
278
286 KOKKOS_FUNCTION
287 bool empty() const { return ( size() == 0 ); }
288
306 KOKKOS_FUNCTION
307 size_type capacity() const { return _capacity; }
308
326 void resize( const size_type n )
327 {
328 static_assert( !memory_traits::is_unmanaged,
329 "Cannot resize unmanaged memory" );
330
331 // Reserve memory if needed.
332 reserve( n );
333
334 // Update the sizes of the data. This is potentially different than
335 // the amount of allocated data.
336 _size = n;
337 _num_soa = std::ceil( static_cast<double>( n ) / vector_length );
338 }
339
358 void reserve( const size_type n )
359 {
360 static_assert( !memory_traits::is_unmanaged,
361 "Cannot reserve unmanaged memory" );
362
363 // If we aren't asking for more memory then we have nothing to do.
364 if ( n <= _capacity )
365 return;
366
367 // Figure out the new capacity.
368 size_type num_soa_alloc = std::floor( n / vector_length );
369 if ( 0 < n % vector_length )
370 ++num_soa_alloc;
371
372 // If we aren't asking for any more SoA objects then we still have
373 // nothing to do.
374 if ( num_soa_alloc <= _num_soa )
375 return;
376
377 // Assign the new capacity.
378 _capacity = num_soa_alloc * vector_length;
379
380 // We need more SoA objects so allocate a new view and copy the
381 // existing data.
382 soa_view resized_data(
383 Kokkos::ViewAllocateWithoutInitializing( _data.label() ),
384 num_soa_alloc );
385 if ( _num_soa > 0 )
386 Kokkos::deep_copy(
387 Kokkos::subview(
388 resized_data,
389 Kokkos::pair<size_type, size_type>( 0, _num_soa ) ),
390 Kokkos::subview( _data, Kokkos::pair<size_type, size_type>(
391 0, _num_soa ) ) );
392 _data = resized_data;
393 }
394
404 {
405 static_assert( !memory_traits::is_unmanaged,
406 "Cannot shrink unmanaged memory" );
407
408 // If we aren't asking for any fewer SoA objects then we have nothing
409 // to do. The amount of allocated data has to be at least as big as
410 // _num_soa so we just need to check here that they are equivalent. If
411 // they are equivalent, the container is already as small as it can be.
412 if ( _data.size() == _num_soa )
413 return;
414
415 // Assign the new capacity.
416 _capacity = _num_soa * vector_length;
417
418 // We need fewer SoA objects so allocate a new view and copy the
419 // existing data.
420 soa_view resized_data(
421 Kokkos::ViewAllocateWithoutInitializing( _data.label() ),
422 _num_soa );
423 if ( _num_soa > 0 )
424 Kokkos::deep_copy(
425 resized_data,
426 Kokkos::subview( _data, Kokkos::pair<size_type, size_type>(
427 0, _num_soa ) ) );
428 _data = resized_data;
429 }
430
435 KOKKOS_INLINE_FUNCTION
436 size_type numSoA() const { return _num_soa; }
437
443 KOKKOS_INLINE_FUNCTION
445 {
446 // the SoA struct size should be full size, i.e. vector_length if:
447 // 1) s is not the last SoA struct
448 // or 2) if _size = _num_soa * vector_length
449 return ( ( (size_type)s < _num_soa - 1 ) ||
450 ( _size % vector_length == 0 ) )
451 ? vector_length // if s is a full SoA struct
452 : ( _size % vector_length ); // if s is the last SoA struct
453 }
454
460 KOKKOS_FORCEINLINE_FUNCTION
461 soa_type& access( const size_type s ) const { return _data( s ); }
462
468 KOKKOS_INLINE_FUNCTION
470 {
471 tuple_type tpl;
472 Impl::tupleCopy( tpl, 0, _data( index_type::s( i ) ),
473 index_type::a( i ) );
474 return tpl;
475 }
476
482 KOKKOS_INLINE_FUNCTION
483 void setTuple( const size_type i, const tuple_type& tpl ) const
484 {
485 Impl::tupleCopy( _data( index_type::s( i ) ), index_type::a( i ), tpl,
486 0 );
487 }
488
493 soa_type* data() const { return _data.data(); }
494
495 private:
496 // Total number of tuples in the container.
497 size_type _size;
498
499 // Allocated number of tuples in all arrays in all structs.
500 size_type _capacity;
501
502 // Number of structs-of-arrays in the array.
503 size_type _num_soa;
504
505 // Structs-of-Arrays managed data. This Kokkos View manages the block of
506 // memory owned by this class such that the copy constructor and
507 // assignment operator for this class perform a shallow and reference
508 // counted copy of the data.
509 soa_view _data;
510};
511
512//---------------------------------------------------------------------------//
513
514} // end namespace Cabana
515
516#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:175
typename MemberTypeAtIndex< M, member_types >::type member_data_type
Definition Cabana_AoSoA.hpp:184
Tuple< member_types > tuple_type
Definition Cabana_AoSoA.hpp:178
void reserve(const size_type n)
Requests that the container capacity be at least enough to contain n tuples.
Definition Cabana_AoSoA.hpp:358
typename MemorySpace::memory_space memory_space
Definition Cabana_AoSoA.hpp:142
std::string label() const
Definition Cabana_AoSoA.hpp:267
typename memory_space::size_type size_type
Definition Cabana_AoSoA.hpp:160
void shrinkToFit()
Remove unused capacity.
Definition Cabana_AoSoA.hpp:403
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:250
static constexpr int vector_length
Definition Cabana_AoSoA.hpp:154
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:444
MemoryTraits memory_traits
Definition Cabana_AoSoA.hpp:157
KOKKOS_FUNCTION bool empty() const
Returns if the container is empty or not.
Definition Cabana_AoSoA.hpp:287
typename memory_space::execution_space execution_space
Definition Cabana_AoSoA.hpp:149
soa_type * data() const
Get a typed raw pointer to the entire data block.
Definition Cabana_AoSoA.hpp:493
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:469
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:198
typename std::add_pointer< member_value_type< M > >::type member_pointer_type
Definition Cabana_AoSoA.hpp:193
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:483
SoA< member_types, vector_length > soa_type
Definition Cabana_AoSoA.hpp:163
KOKKOS_FUNCTION size_type size() const
Returns the number of tuples in the container.
Definition Cabana_AoSoA.hpp:277
typename std::remove_all_extents< member_data_type< M > >::type member_value_type
Definition Cabana_AoSoA.hpp:188
static constexpr std::size_t number_of_members
Definition Cabana_AoSoA.hpp:169
KOKKOS_INLINE_FUNCTION size_type numSoA() const
Get the number of structs-of-arrays in the container.
Definition Cabana_AoSoA.hpp:436
Kokkos::View< soa_type *, memory_space, memory_traits > soa_view
Definition Cabana_AoSoA.hpp:166
static constexpr std::size_t max_supported_rank
Definition Cabana_AoSoA.hpp:172
AoSoA(const std::string &label="")
Default constructor.
Definition Cabana_AoSoA.hpp:211
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:229
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:461
void resize(const size_type n)
Resizes the container so that it contains n tuples.
Definition Cabana_AoSoA.hpp:326
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:307
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