Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: MpiWrapper::allReduce overload for arrays. #3446

Merged
merged 19 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreComponents/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ set( common_headers
Tensor.hpp
TimingMacros.hpp
TypeDispatch.hpp
TypesHelpers.hpp
initializeEnvironment.hpp
LifoStorage.hpp
LifoStorageCommon.hpp
Expand Down
21 changes: 21 additions & 0 deletions src/coreComponents/common/MpiWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "common/DataTypes.hpp"
#include "common/Span.hpp"
#include "common/TypesHelpers.hpp"

#if defined(GEOS_USE_MPI)
#include <mpi.h>
Expand Down Expand Up @@ -385,6 +386,17 @@ struct MpiWrapper
template< typename T >
static void allReduce( Span< T const > src, Span< T > dst, Reduction const op, MPI_Comm comm = MPI_COMM_GEOS );

/**
* @brief Convenience wrapper for the MPI_Allreduce function. Version for arrays.
* @tparam T type of data to reduce. Must correspond to a valid MPI_Datatype.
* @param src[in] The values to send to the reduction.
* @param dst[out] The resulting values.
* @param op The Reduction enum to perform.
* @param comm The communicator.
*/
template< typename CONTAINER_TYPE >
static void allReduce( CONTAINER_TYPE const & src, CONTAINER_TYPE & dst, Reduction const op, MPI_Comm const comm = MPI_COMM_GEOS );


/**
* @brief Strongly typed wrapper around MPI_Reduce.
Expand Down Expand Up @@ -1073,6 +1085,15 @@ void MpiWrapper::allReduce( Span< T const > const src, Span< T > const dst, Redu
allReduce( src.data(), dst.data(), LvArray::integerConversion< int >( src.size() ), getMpiOp( op ), comm );
}

template< typename CONTAINER_TYPE >
void MpiWrapper::allReduce( CONTAINER_TYPE const & src, CONTAINER_TYPE & dst, Reduction const op, MPI_Comm const comm )
{
static_assert( std::is_trivially_copyable< typename get_value_type< CONTAINER_TYPE >::type >::value,
"The type in the container must be trivially copiable." );
GEOS_ASSERT_EQ( src.size(), dst.size() );
allReduce( src.data(), dst.data(), LvArray::integerConversion< int >( src.size() ), getMpiOp( op ), comm );
}

template< typename T >
T MpiWrapper::sum( T const & value, MPI_Comm comm )
{
Expand Down
66 changes: 66 additions & 0 deletions src/coreComponents/common/TypesHelpers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* ------------------------------------------------------------------------------------------------------------
* SPDX-License-Identifier: LGPL-2.1-only
*
* Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
* Copyright (c) 2018-2024 Total, S.A
* Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
* Copyright (c) 2023-2024 Chevron
* Copyright (c) 2019- GEOS/GEOSX Contributors
* All rights reserved
*
* See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
* ------------------------------------------------------------------------------------------------------------
*/

/**
* @file TypeHelpers.hpp
*
*/

#ifndef TYPES_HELPERS_HPP
#define TYPES_HELPERS_HPP

#include <type_traits>

namespace geos
{

namespace internal
{

template< typename T, typename = void >
struct has_value_type : std::false_type {};

template< typename T >
struct has_value_type< T, std::void_t< typename T::value_type > > : std::true_type {};

template< typename T, typename = void >
struct has_ValueType : std::false_type {};

template< typename T >
struct has_ValueType< T, std::void_t< typename T::ValueType > > : std::true_type {};

} // namespace internal

template< typename T, typename Enable = void >
struct get_value_type
{
static_assert( sizeof(T) == 0, "CONTAINER_TYPE must define either value_type or ValueType." );
};

template< typename T >
struct get_value_type< T, std::enable_if_t< internal::has_value_type< T >::value > >
{
using type = typename T::value_type;
};

template< typename T >
struct get_value_type< T, std::enable_if_t< !internal::has_value_type< T >::value && internal::has_ValueType< T >::value > >
{
using type = typename T::ValueType;
};

} // namespace geos

#endif /* TYPES_HELPERS_HPP */
13 changes: 7 additions & 6 deletions src/coreComponents/physicsSolvers/PhysicsSolverBaseKernels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,16 +309,17 @@ class L2ResidualNormHelper
{
array1d< real64 > sumLocalResidualNorm( localResidualNorm.size() );
array1d< real64 > sumLocalResidualNormalizer( localResidualNormalizer.size() );
MpiWrapper::allReduce( localResidualNorm.data(),
sumLocalResidualNorm.data(),
localResidualNorm.size(),
MpiWrapper::getMpiOp( MpiWrapper::Reduction::Sum ),

MpiWrapper::allReduce( localResidualNorm,
sumLocalResidualNorm,
MpiWrapper::Reduction::Sum,
MPI_COMM_GEOS );

MpiWrapper::allReduce( localResidualNormalizer.data(),
sumLocalResidualNormalizer.data(),
localResidualNormalizer.size(),
MpiWrapper::getMpiOp( MpiWrapper::Reduction::Sum ),
MpiWrapper::Reduction::Sum,
MPI_COMM_GEOS );

for( integer i = 0; i < localResidualNorm.size(); ++i )
{
globalResidualNorm[i] = sqrt( sumLocalResidualNorm[i] ) / sqrt( sumLocalResidualNormalizer[i] );
Expand Down
Loading