Buffer Particle
Adds an implementation detail providing the ability to take a single element of a Cabana::AoSoA
as indicated by a given Cabana::Index
and serialize all of the data members associated with that index into a byte stream represented by a Cabana::BufferParticle
. In reverse, it also provides the ability to unpack the data members from a Cabana::BufferParticle
into an individual Cabana::AoSoA
element as indicated by a given Cabana::Index
.
To support this a new function Cabana::Index::oneD()
which creates a 1-dimensional index for a given Cabana::AoSoA
element. This is useful for iterating through linear structures, such as a particle buffer.
This allows one to effectively do the following:
// Data dimensions.
const std::size_t dim_1 = 3;
const std::size_t dim_2 = 2;
const std::size_t dim_3 = 4;
const std::size_t dim_4 = 3;
// Declare member types.
using T0 = float[dim_1][dim_2][dim_3];
using T1 = int;
using T2 = float[dim_1][dim_2][dim_3][dim_4];
using T3 = double[dim_1];
using T4 = double[dim_1][dim_2];
// Declare data types.
using DataTypes = Cabana::MemberDataTypes<T0,T1,T2,T3,T4>;
// Declare the AoSoA type.
using AoSoA_t = Cabana::AoSoA<DataTypes,Kokkos::CudaUVMSpace>;
// Create an AoSoA.
std::size_t num_data = 453;
AoSoA_t aosoa( num_data );
// Create a particle buffer. Effectively a giant byte stream because
// BufferParticle simply holds a char pointer.
using BufferParticle = Cabana::Impl::BufferParticle<DataTypes>;
Kokkos::View<BufferParticle*,Kokkos::CudaUVMSpace> buffer( "buffer", num_data );
// Create an execution policy for packing/unpacking.
Cabana::IndexRangePolicy<Kokkos::Cuda> policy( aosoa );
// Pack the data into a buffer.
auto pack_op = KOKKOS_LAMBDA( const Cabana::Index idx )
{
Cabana::Impl::pack( idx, aosoa, buffer(idx.oneD()) );
};
Cabana::parallel_for( policy, pack_op );
// Make a new AoSoA.
AoSoA_t aosoa_2( num_data );
// Unpack the buffer into the new AoSoA.
auto unpack_op = KOKKOS_LAMBDA( const Cabana::Index idx )
{
Cabana::Impl::unpack( idx, buffer(idx.oneD()), aosoa_2 );
};
Cabana::parallel_for( policy, unpack_op );