From b49a406ec194cdd97cc7a7bd06f37ef947f77bc0 Mon Sep 17 00:00:00 2001 From: Stuart Slattery Date: Tue, 7 May 2019 15:47:03 -0400 Subject: [PATCH] Replacing atomic add instances with scatter view --- core/src/Cabana_CommunicationPlan.hpp | 16 +++++++++++++--- core/src/Cabana_Halo.hpp | 18 +++++++++++------- core/src/Cabana_LinkedCellList.hpp | 7 +++++-- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/core/src/Cabana_CommunicationPlan.hpp b/core/src/Cabana_CommunicationPlan.hpp index 2e850c3ac..fb1d38459 100644 --- a/core/src/Cabana_CommunicationPlan.hpp +++ b/core/src/Cabana_CommunicationPlan.hpp @@ -13,6 +13,7 @@ #define CABANA_COMMUNICATIONPLAN_HPP #include +#include #include @@ -250,12 +251,15 @@ class CommunicationPlan num_export_host( _num_export.data(), num_n ); auto export_counts = Kokkos::create_mirror_view_and_copy( memory_space(), num_export_host ); + auto export_counts_sv = + Kokkos::Experimental::create_scatter_view( export_counts ); auto count_neighbor_func = KOKKOS_LAMBDA( const int i ) { + auto export_counts_data = export_counts_sv.access(); for ( int n = 0; n < num_n; ++n ) if ( topology(n) == element_export_ranks(i) ) - Kokkos::atomic_increment( &export_counts(n) ); + export_counts_data(n) += 1; }; Kokkos::RangePolicy count_neighbor_policy( 0, _num_export_element ); @@ -263,6 +267,7 @@ class CommunicationPlan count_neighbor_policy, count_neighbor_func ); Kokkos::fence(); + Kokkos::Experimental::contribute( export_counts, export_counts_sv ); // Copy counts back to the host. Kokkos::deep_copy( num_export_host, export_counts ); @@ -357,12 +362,16 @@ class CommunicationPlan // Count the number of sends this rank will do to other ranks. Kokkos::View neighbor_counts( "neighbor_counts", comm_size ); + auto neighbor_counts_sv = + Kokkos::Experimental::create_scatter_view( neighbor_counts ); auto count_sends_func = KOKKOS_LAMBDA( const int i ) { if ( element_export_ranks(i) >= 0 ) - Kokkos::atomic_increment( - &neighbor_counts(element_export_ranks(i)) ); + { + auto neighbor_counts_data = neighbor_counts_sv.access(); + neighbor_counts_data(element_export_ranks(i)) += 1; + } }; Kokkos::RangePolicy count_sends_policy( 0, _num_export_element ); @@ -370,6 +379,7 @@ class CommunicationPlan count_sends_policy, count_sends_func ); Kokkos::fence(); + Kokkos::Experimental::contribute( neighbor_counts, neighbor_counts_sv ); // Copy the counts to the host. auto neighbor_counts_host = Kokkos::create_mirror_view_and_copy( diff --git a/core/src/Cabana_Halo.hpp b/core/src/Cabana_Halo.hpp index cf75a0768..efc805fc4 100644 --- a/core/src/Cabana_Halo.hpp +++ b/core/src/Cabana_Halo.hpp @@ -42,9 +42,9 @@ namespace Cabana number of exports is the number of exports in the gather and the number of imports is the number of imports in the gather. The reverse *SCATTER* operation sends the ghosted data back the the uniquely-owned decomposition - and resolves collisions with atomic addition. Based on input for the forward - communication plan (where local data will be sent) the local number of - ghosts is computed. Some nomenclature: + and resolves collisions. Based on input for the forward communication plan + (where local data will be sent) the local number of ghosts is computed. Some + nomenclature: Export - the local data we uniquely own that we will send to other ranks for those ranks to be used as ghosts. Export is used in the context of the @@ -550,8 +550,12 @@ void scatter( const Halo_t& halo, for ( int d = 2; d < slice.rank(); ++d ) num_comp *= slice.extent(d); - // Get the raw slice data. - auto slice_data = slice.data(); + // Get the raw slice data. Wrap in a 1D Kokkos View so we can unroll the + // components of each slice element. + Kokkos::View > + slice_data( slice.data(), slice.numSoA() * slice.stride(0) ); // Allocate a send buffer. Note this one is layout right so the components // are consecutive. @@ -573,7 +577,7 @@ void scatter( const Halo_t& halo, std::size_t slice_offset = s*slice.stride(0) + a; for ( int n = 0; n < num_comp; ++n ) send_buffer( i, n ) = - slice_data[ slice_offset + Slice_t::vector_length * n ]; + slice_data( slice_offset + Slice_t::vector_length * n ); }; Kokkos::RangePolicy extract_send_buffer_policy( 0, halo.totalNumImport() ); @@ -650,7 +654,7 @@ void scatter( const Halo_t& halo, std::size_t slice_offset = s*slice.stride(0) + a; for ( int n = 0; n < num_comp; ++n ) Kokkos::atomic_add( - slice_data + slice_offset + Slice_t::vector_length * n, + &slice_data(slice_offset + Slice_t::vector_length * n), recv_buffer(i,n) ); }; Kokkos::RangePolicy diff --git a/core/src/Cabana_LinkedCellList.hpp b/core/src/Cabana_LinkedCellList.hpp index c20537ce0..14a1cabe5 100644 --- a/core/src/Cabana_LinkedCellList.hpp +++ b/core/src/Cabana_LinkedCellList.hpp @@ -17,6 +17,7 @@ #include #include +#include namespace Cabana { @@ -225,19 +226,21 @@ class LinkedCellList Kokkos::RangePolicy particle_range( begin, end ); Kokkos::deep_copy( counts, 0 ); + auto counts_sv = Kokkos::Experimental::create_scatter_view( counts ); auto cell_count = KOKKOS_LAMBDA( const std::size_t p ) { int i, j, k; grid.locatePoint( positions(p,0), positions(p,1), positions(p,2), i , j, k ); - Kokkos::atomic_increment( - &counts(grid.cardinalCellIndex(i,j,k)) ); + auto counts_data = counts_sv.access(); + counts_data(grid.cardinalCellIndex(i,j,k)) += 1; }; Kokkos::parallel_for( "Cabana::LinkedCellList::build::cell_count", particle_range, cell_count ); Kokkos::fence(); + Kokkos::Experimental::contribute( counts, counts_sv ); // Compute offsets. Kokkos::RangePolicy