-
Slattery, Stuart authoredSlattery, Stuart authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
tstParallel.hpp 6.81 KiB
#include <Cabana_Parallel.hpp>
#include <Cabana_ExecutionPolicy.hpp>
#include <Cabana_AoSoA.hpp>
#include <boost/test/unit_test.hpp>
//---------------------------------------------------------------------------//
// Check the data given a set of values.
template<class aosoa_type>
void checkDataMembers(
aosoa_type aosoa,
const float fval, const double dval, const int ival,
const std::size_t dim_1, const std::size_t dim_2,
const std::size_t dim_3, const std::size_t dim_4 )
{
for ( auto idx = aosoa.begin(); idx != aosoa.end(); ++idx )
{
// Member 0.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
for ( std::size_t k = 0; k < dim_3; ++k )
BOOST_CHECK( aosoa.template get<0>( idx, i, j, k ) ==
fval * (i+j+k) );
// Member 1.
BOOST_CHECK( aosoa.template get<1>( idx ) == ival );
// Member 2.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
for ( std::size_t k = 0; k < dim_3; ++k )
for ( std::size_t l = 0; l < dim_4; ++l )
BOOST_CHECK( aosoa.template get<2>( idx, i, j, k, l ) ==
fval * (i+j+k+l) );
// Member 3.
for ( std::size_t i = 0; i < dim_1; ++i )
BOOST_CHECK( aosoa.template get<3>( idx, i ) == dval * i );
// Member 4.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
BOOST_CHECK( aosoa.template get<4>( idx, i, j ) == dval * (i+j) );
}
}
//---------------------------------------------------------------------------//
// TESTS
//---------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE( parallel_for_test )
{
// Manually set the inner array size.
using inner_array_size = Cabana::InnerArraySize<10>;
// 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 data types.
using DataTypes =
Cabana::MemberDataTypes<float[dim_1][dim_2][dim_3],
int,
float[dim_1][dim_2][dim_3][dim_4],
double[dim_1],
double[dim_1][dim_2]
>;
// Declare the AoSoA type.
using AoSoA_t = Cabana::AoSoA<DataTypes,inner_array_size,TEST_MEMSPACE>;
// Create an AoSoA.
std::size_t num_data = 155;
AoSoA_t aosoa( num_data );
// Create an execution policy.
Cabana::IndexRangePolicy<TEST_EXECSPACE>
range_policy( aosoa.begin(), aosoa.end() );
// Write a functor to operate on.
float fval = 3.4;
double dval = 1.23;
int ival = 1;
auto func_1 = KOKKOS_LAMBDA( const Cabana::Index idx )
{
// Member 0.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
for ( std::size_t k = 0; k < dim_3; ++k )
aosoa.get<0>( idx, i, j, k ) = fval * (i+j+k);
// Member 1.
aosoa.get<1>( idx ) = ival;
// Member 2.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
for ( std::size_t k = 0; k < dim_3; ++k )
for ( std::size_t l = 0; l < dim_4; ++l )
aosoa.get<2>( idx, i, j, k, l ) = fval * (i+j+k+l);
// Member 3.
for ( std::size_t i = 0; i < dim_1; ++i )
aosoa.get<3>( idx, i ) = dval * i;
// Member 4.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
aosoa.get<4>( idx, i, j ) = dval * (i+j);
};
// Loop in parallel using 1D struct parallelism.
Cabana::parallel_for( range_policy, func_1, Cabana::StructParallelTag() );
// Check data members for proper initialization.
checkDataMembers( aosoa, fval, dval, ival, dim_1, dim_2, dim_3, dim_4 );
// Change values and write a second functor.
fval = 93.4;
dval = 12.1;
ival = 4;
auto func_2 = KOKKOS_LAMBDA( const Cabana::Index idx )
{
// Member 0.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
for ( std::size_t k = 0; k < dim_3; ++k )
aosoa.get<0>( idx, i, j, k ) = fval * (i+j+k);
// Member 1.
aosoa.get<1>( idx ) = ival;
// Member 2.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
for ( std::size_t k = 0; k < dim_3; ++k )
for ( std::size_t l = 0; l < dim_4; ++l )
aosoa.get<2>( idx, i, j, k, l ) = fval * (i+j+k+l);
// Member 3.
for ( std::size_t i = 0; i < dim_1; ++i )
aosoa.get<3>( idx, i ) = dval * i;
// Member 4.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
aosoa.get<4>( idx, i, j ) = dval * (i+j);
};
// Loop in parallel using 1D array parallelism.
Cabana::parallel_for( range_policy, func_2, Cabana::ArrayParallelTag() );
// Check data members for proper initialization.
checkDataMembers( aosoa, fval, dval, ival, dim_1, dim_2, dim_3, dim_4 );
// Change values and write a third functor.
fval = 7.7;
dval = 3.2;
ival = 9;
auto func_3 = KOKKOS_LAMBDA( const Cabana::Index idx )
{
// Member 0.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
for ( std::size_t k = 0; k < dim_3; ++k )
aosoa.get<0>( idx, i, j, k ) = fval * (i+j+k);
// Member 1.
aosoa.get<1>( idx ) = ival;
// Member 2.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
for ( std::size_t k = 0; k < dim_3; ++k )
for ( std::size_t l = 0; l < dim_4; ++l )
aosoa.get<2>( idx, i, j, k, l ) = fval * (i+j+k+l);
// Member 3.
for ( std::size_t i = 0; i < dim_1; ++i )
aosoa.get<3>( idx, i ) = dval * i;
// Member 4.
for ( std::size_t i = 0; i < dim_1; ++i )
for ( std::size_t j = 0; j < dim_2; ++j )
aosoa.get<4>( idx, i, j ) = dval * (i+j);
};
// Loop in parallel using 2D struct and array parallelism.
Cabana::parallel_for(
range_policy, func_3, Cabana::StructAndArrayParallelTag() );
// Check data members for proper initialization.
checkDataMembers( aosoa, fval, dval, ival, dim_1, dim_2, dim_3, dim_4 );
}