diff --git a/src/coreComponents/common/MpiWrapper.hpp b/src/coreComponents/common/MpiWrapper.hpp index fd3264a5317..d0e392385e8 100644 --- a/src/coreComponents/common/MpiWrapper.hpp +++ b/src/coreComponents/common/MpiWrapper.hpp @@ -1307,7 +1307,7 @@ int MpiWrapper::scatterv( TS const * const sendbuf, #else static_assert( std::is_same< TS, TR >::value, "MpiWrapper::scatterv() for serial run requires send and receive buffers are of the same type" ); - std::size_t const sendBufferSize = sendcounts * sizeof(TS); + std::size_t const sendBufferSize = sendcounts[0] * sizeof(TS); std::size_t const recvBufferSize = recvcount * sizeof(TR); GEOS_ERROR_IF_NE_MSG( sendBufferSize, recvBufferSize, "size of send buffer and receive buffer are not equal" ); memcpy( recvbuf, sendbuf, sendBufferSize ); diff --git a/src/coreComponents/mesh/graphs/GraphColoringBase.cpp b/src/coreComponents/mesh/graphs/GraphColoringBase.cpp index 55f1208b480..6418e503ff3 100644 --- a/src/coreComponents/mesh/graphs/GraphColoringBase.cpp +++ b/src/coreComponents/mesh/graphs/GraphColoringBase.cpp @@ -27,16 +27,15 @@ namespace geos namespace graph { -bool GraphColoringBase::isColoringValid( const std::vector< camp::idx_t > & xadj, - const std::vector< camp::idx_t > & adjncy, +bool GraphColoringBase::isColoringValid( const std::vector< size_t > & xadj, + const std::vector< size_t > & adjncy, const std::vector< int > & coloring ) { for( size_t node = 0; node < coloring.size(); ++node ) { int node_color = coloring[node]; - std::unordered_set< camp::idx_t > neighbors = getGraphNodeNeighbors( node, xadj, adjncy ); - - for( camp::idx_t neighbor : neighbors ) + std::unordered_set< size_t > neighbors = getGraphNodeNeighbors( node, xadj, adjncy ); + for( size_t neighbor : neighbors ) { if( coloring[neighbor] == node_color ) { @@ -63,7 +62,7 @@ size_t GraphColoringBase::getNumberOfColors( const std::vector< int > & colors ) // Assume only one node per rank. -bool GraphColoringBase::isColoringValid( const std::vector< camp::idx_t > & adjncy, +bool GraphColoringBase::isColoringValid( const std::vector< size_t > & adjncy, const int color, MPI_Comm comm ) { diff --git a/src/coreComponents/mesh/graphs/GraphColoringBase.hpp b/src/coreComponents/mesh/graphs/GraphColoringBase.hpp index 2b8242c70cf..f4cb5880686 100644 --- a/src/coreComponents/mesh/graphs/GraphColoringBase.hpp +++ b/src/coreComponents/mesh/graphs/GraphColoringBase.hpp @@ -54,14 +54,14 @@ class GraphColoringBase * @param adjncy Adjacency list containing neighbors of each node. * @return A vector of colors assigned to each node. */ - virtual std::vector< int > colorGraph( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy ) = 0; + virtual std::vector< int > colorGraph( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ) = 0; /** * @brief Pure virtual method to color a graph assuming one node per rank. * @param adjncy Adjacency list containing neighbors of each node. * @return Color of the node. */ - virtual int colorGraph( const std::vector< camp::idx_t > & adjncy ) = 0; + virtual int colorGraph( const std::vector< size_t > & adjncy ) = 0; /** @@ -81,7 +81,7 @@ class GraphColoringBase * @param coloring A vector where the index represents the node and the value represents the assigned color.* * @return True if the coloring is valid, false otherwise. */ - static bool isColoringValid( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy, const std::vector< int > & coloring ); + static bool isColoringValid( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy, const std::vector< int > & coloring ); /** * @brief Checks the validity of the graph coloring assuming one node per rank. @@ -92,7 +92,7 @@ class GraphColoringBase * * @return True if the coloring is valid, false otherwise. */ - static bool isColoringValid( const std::vector< camp::idx_t > & adjncy, const int color, MPI_Comm comm ); + static bool isColoringValid( const std::vector< size_t > & adjncy, const int color, MPI_Comm comm ); /** * @brief Counts the number of distinct colors. diff --git a/src/coreComponents/mesh/graphs/GraphTools.cpp b/src/coreComponents/mesh/graphs/GraphTools.cpp index 84b5f287591..3ceef58817e 100644 --- a/src/coreComponents/mesh/graphs/GraphTools.cpp +++ b/src/coreComponents/mesh/graphs/GraphTools.cpp @@ -29,16 +29,16 @@ namespace geos namespace graph { -size_t getGraphNodeDegree( idx_t node, const std::vector< idx_t > & xadj ) +size_t getGraphNodeDegree( size_t node, const std::vector< size_t > & xadj ) { return xadj[node + 1] - xadj[node]; } -std::unordered_set< idx_t > getGraphNodeNeighbors( idx_t node, const std::vector< idx_t > & xadj, const std::vector< idx_t > & adjncy ) +std::unordered_set< size_t > getGraphNodeNeighbors( size_t node, const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ) { - std::unordered_set< idx_t > neighbors; - for( idx_t i = xadj[node]; i < xadj[node + 1]; ++i ) + std::unordered_set< size_t > neighbors; + for( size_t i = xadj[node]; i < xadj[node + 1]; ++i ) { neighbors.insert( adjncy[i] ); } @@ -46,17 +46,17 @@ std::unordered_set< idx_t > getGraphNodeNeighbors( idx_t node, const std::vector } -bool isGraphValid( const std::vector< idx_t > & xadj, - const std::vector< idx_t > & adjncy ) +bool isGraphValid( const std::vector< size_t > & xadj, + const std::vector< size_t > & adjncy ) { - idx_t num_nodes = xadj.size() - 1; + size_t num_nodes = xadj.size() - 1; - for( idx_t i = 0; i < num_nodes; ++i ) + for( size_t i = 0; i < num_nodes; ++i ) { - std::unordered_set< idx_t > neighbors; - for( idx_t j = xadj[i]; j < xadj[i + 1]; ++j ) + std::unordered_set< size_t > neighbors; + for( size_t j = xadj[i]; j < xadj[i + 1]; ++j ) { - idx_t neighbor = adjncy[j]; + size_t neighbor = adjncy[j]; // Check for out-of-bounds indices if( neighbor >= num_nodes ) @@ -75,7 +75,7 @@ bool isGraphValid( const std::vector< idx_t > & xadj, // Check for bidirectional connection bool bidirectional = false; - for( idx_t k = xadj[neighbor]; k < xadj[neighbor + 1]; ++k ) + for( size_t k = xadj[neighbor]; k < xadj[neighbor + 1]; ++k ) { if( adjncy[k] == i ) { @@ -95,7 +95,7 @@ bool isGraphValid( const std::vector< idx_t > & xadj, } -std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( size_t numVertices, size_t numEdges ) +std::tuple< std::vector< size_t >, std::vector< size_t > > generateGraphRandom( size_t numVertices, size_t numEdges ) { std::vector< std::pair< size_t, size_t > > edges; srand( static_cast< unsigned int >(time( 0 ))); @@ -116,8 +116,8 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( si std::sort( edges.begin(), edges.end()); // Initialize xadj and adjncy - std::vector< idx_t > xadj( numVertices + 1, 0 ); - std::vector< idx_t > adjncy; + std::vector< size_t > xadj( numVertices + 1, 0 ); + std::vector< size_t > adjncy; adjncy.reserve( edges.size()); // Fill xadj and adjncy @@ -142,25 +142,25 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( si } -std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D( idx_t nx, idx_t ny, idx_t nz, const std::vector< std::array< int, 3 > > & neighbor_offsets ) +std::tuple< std::vector< size_t >, std::vector< size_t > > generateGraphCartPartitioning3D( size_t nx, size_t ny, size_t nz, const std::vector< std::array< int, 3 > > & neighbor_offsets ) { - idx_t num_nodes = nx * ny * nz; - std::vector< idx_t > xadj( num_nodes + 1, 0 ); - std::vector< idx_t > adjncy; + size_t num_nodes = nx * ny * nz; + std::vector< size_t > xadj( num_nodes + 1, 0 ); + std::vector< size_t > adjncy; - auto getNodeIndex = [nx, ny] ( const idx_t x, const idx_t y, const idx_t z ) + auto getNodeIndex = [nx, ny] ( const size_t x, const size_t y, const size_t z ) { return x + nx * (y + ny * z); }; - idx_t node_counter = 0; - for( idx_t z = 0; z < nz; ++z ) + size_t node_counter = 0; + for( size_t z = 0; z < nz; ++z ) { - for( idx_t y = 0; y < ny; ++y ) + for( size_t y = 0; y < ny; ++y ) { - for( idx_t x = 0; x < nx; ++x ) + for( size_t x = 0; x < nx; ++x ) { - std::vector< idx_t > neighbors; + std::vector< size_t > neighbors; for( const auto & offset : neighbor_offsets ) { @@ -186,15 +186,15 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartit return {xadj, adjncy}; } -std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D6( idx_t nx, idx_t ny, idx_t nz ) +std::tuple< std::vector< size_t >, std::vector< size_t > > generateGraphCartPartitioning3D6( size_t nx, size_t ny, size_t nz ) { std::vector< std::array< int, 3 > > neighbor_offsets = { {-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1} }; - return generateGraphCartPartitionning3D( nx, ny, nz, neighbor_offsets ); + return generateGraphCartPartitioning3D( nx, ny, nz, neighbor_offsets ); } -std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D26( idx_t nx, idx_t ny, idx_t nz ) +std::tuple< std::vector< size_t >, std::vector< size_t > > generateGraphCartPartitioning3D26( size_t nx, size_t ny, size_t nz ) { std::vector< std::array< int, 3 > > neighbor_offsets; for( int dz = -1; dz <= 1; ++dz ) @@ -210,7 +210,7 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartit } } } - return generateGraphCartPartitionning3D( nx, ny, nz, neighbor_offsets ); + return generateGraphCartPartitioning3D( nx, ny, nz, neighbor_offsets ); } diff --git a/src/coreComponents/mesh/graphs/GraphTools.hpp b/src/coreComponents/mesh/graphs/GraphTools.hpp index 0aa09887889..ef976562eee 100644 --- a/src/coreComponents/mesh/graphs/GraphTools.hpp +++ b/src/coreComponents/mesh/graphs/GraphTools.hpp @@ -31,8 +31,6 @@ namespace geos namespace graph { -using camp::idx_t; - /** * @brief Validates the graph based on the given criteria. * @@ -45,7 +43,7 @@ using camp::idx_t; * @param adjncy The adjacency list containing the neighbors of each node. * @return True if the graph meets all criteria, false otherwise. */ -bool isGraphValid( const std::vector< idx_t > & xadj, const std::vector< idx_t > & adjncy ); +bool isGraphValid( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ); /** * @brief Calculates the degree of a node in the graph. @@ -56,7 +54,7 @@ bool isGraphValid( const std::vector< idx_t > & xadj, const std::vector< idx_t > * @param xadj The adjacency list offsets for each node. * @return The degree of the node. */ -size_t getGraphNodeDegree( idx_t node, const std::vector< idx_t > & xadj ); +size_t getGraphNodeDegree( size_t node, const std::vector< size_t > & xadj ); /** * @brief Retrieves the neighbors of a node in the graph. @@ -68,7 +66,7 @@ size_t getGraphNodeDegree( idx_t node, const std::vector< idx_t > & xadj ); * @param adjncy The adjacency list containing the neighbors of each node. * @return A set of indices representing the neighbors of the node. */ -std::unordered_set< idx_t > getGraphNodeNeighbors( idx_t node, const std::vector< idx_t > & xadj, const std::vector< idx_t > & adjncy ); +std::unordered_set< size_t > getGraphNodeNeighbors( size_t node, const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ); @@ -81,7 +79,7 @@ std::unordered_set< idx_t > getGraphNodeNeighbors( idx_t node, const std::vector * @param num_edges Number of edges in the graph. * @return A tuple containing xadj and adjncy. */ -std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( size_t num_nodes, size_t num_edges ); +std::tuple< std::vector< size_t >, std::vector< size_t > > generateGraphRandom( size_t num_nodes, size_t num_edges ); /** * @brief Generates the adjacency list representation (xadj and adjncy) for a Cartesian domain decomposition in 3D. @@ -94,7 +92,7 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( si * @param nz Number of divisions along the z-axis. * @return A tuple containing xadj and adjncy. */ -std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D6( idx_t nx, idx_t ny, idx_t nz ); +std::tuple< std::vector< size_t >, std::vector< size_t > > generateGraphCartPartitioning3D6( size_t nx, size_t ny, size_t nz ); /** * @brief Generates the adjacency list representation (xadj and adjncy) for a Cartesian domain decomposition in 3D. @@ -107,7 +105,7 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartit * @param nz Number of divisions along the z-axis. * @return A tuple containing xadj and adjncy. */ -std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D26( idx_t nx, idx_t ny, idx_t nz ); +std::tuple< std::vector< size_t >, std::vector< size_t > > generateGraphCartPartitioning3D26( size_t nx, size_t ny, size_t nz ); } // namespace geos diff --git a/src/coreComponents/mesh/graphs/GraphToolsMPI.cpp b/src/coreComponents/mesh/graphs/GraphToolsMPI.cpp index c5206b26dd2..72d4b54a749 100644 --- a/src/coreComponents/mesh/graphs/GraphToolsMPI.cpp +++ b/src/coreComponents/mesh/graphs/GraphToolsMPI.cpp @@ -26,9 +26,9 @@ namespace geos namespace graph { -std::pair< std::vector< camp::idx_t >, std::vector< camp::idx_t > > -scatterGraphData( const std::vector< camp::idx_t > & xadj, - const std::vector< camp::idx_t > & adjncy, +std::pair< std::vector< size_t >, std::vector< size_t > > +scatterGraphData( const std::vector< size_t > & xadj, + const std::vector< size_t > & adjncy, MPI_Comm comm ) { int const rank = MpiWrapper::commRank( comm ); @@ -42,7 +42,7 @@ scatterGraphData( const std::vector< camp::idx_t > & xadj, std::vector< int > sendCounts; std::vector< int > displacements; - std::vector< camp::idx_t > xadjToScatter; + std::vector< size_t > xadjToScatter; if( rank == 0 ) { @@ -64,13 +64,13 @@ scatterGraphData( const std::vector< camp::idx_t > & xadj, } } - std::vector< camp::idx_t > localXadj( 2 ); // Each rank will have two elements in localXadj: xadj[i] and xadj[i+1] + std::vector< size_t > localXadj( 2 ); // Each rank will have two elements in localXadj: xadj[i] and xadj[i+1] MpiWrapper::scatter( xadjToScatter.data(), 2, localXadj.data(), 2, 0, comm ); int localSize; MpiWrapper::scatter( sendCounts.data(), 1, &localSize, 1, 0, comm ); - std::vector< camp::idx_t > localAdjncy( localSize ); + std::vector< size_t > localAdjncy( localSize ); MpiWrapper::scatterv( adjncy.data(), sendCounts.data(), displacements.data(), localAdjncy.data(), localSize, 0, comm ); @@ -78,9 +78,9 @@ scatterGraphData( const std::vector< camp::idx_t > & xadj, } -std::pair< std::vector< camp::idx_t >, std::vector< camp::idx_t > > -gatherGraphData( const std::vector< camp::idx_t > & localXadj, - const std::vector< camp::idx_t > & localAdjncy, +std::pair< std::vector< size_t >, std::vector< size_t > > +gatherGraphData( const std::vector< size_t > & localXadj, + const std::vector< size_t > & localAdjncy, MPI_Comm comm ) { int const rank = MpiWrapper::commRank( comm ); @@ -105,7 +105,7 @@ gatherGraphData( const std::vector< camp::idx_t > & localXadj, } // Resize the xadj vector on rank 0 to hold the gathered data - std::vector< camp::idx_t > xadj; + std::vector< size_t > xadj; if( rank == 0 ) { int totalSize = std::accumulate( recvCounts.begin(), recvCounts.end(), 0 ); @@ -133,7 +133,7 @@ gatherGraphData( const std::vector< camp::idx_t > & localXadj, } // Resize the adjncy vector on rank 0 to hold the gathered data - std::vector< camp::idx_t > adjncy; + std::vector< size_t > adjncy; if( rank == 0 ) { int totalSize = std::accumulate( recvCounts.begin(), recvCounts.end(), 0 ); @@ -150,7 +150,7 @@ gatherGraphData( const std::vector< camp::idx_t > & localXadj, } -std::vector< camp::idx_t > createXadjFromAdjncy( const std::vector< camp::idx_t > & localAdjncy, MPI_Comm comm ) +std::vector< size_t > createXadjFromAdjncy( const std::vector< size_t > & localAdjncy, MPI_Comm comm ) { int const size = MpiWrapper::commSize( comm ); @@ -160,11 +160,11 @@ std::vector< camp::idx_t > createXadjFromAdjncy( const std::vector< camp::idx_t MpiWrapper::allgather( &localAdjncySize, 1, adjncyCounts.data(), 1, comm ); // Calculate xadj - std::vector< camp::idx_t > xadj( size + 1, 0 ); + std::vector< size_t > xadj( size + 1, 0 ); std::partial_sum( adjncyCounts.begin(), adjncyCounts.end(), xadj.begin() + 1 ); // Prepare data to scatter - std::vector< camp::idx_t > xadjToScatter( 2 * size ); + std::vector< size_t > xadjToScatter( 2 * size ); for( int i = 0; i < size; ++i ) { xadjToScatter[2 * i] = xadj[i]; @@ -172,14 +172,14 @@ std::vector< camp::idx_t > createXadjFromAdjncy( const std::vector< camp::idx_t } // Scatter the xadj data - std::vector< camp::idx_t > localXadj( 2 ); + std::vector< size_t > localXadj( 2 ); MpiWrapper::scatter( xadjToScatter.data(), 2, localXadj.data(), 2, 0, comm ); return localXadj; } -std::vector< int > createVertexGlobalID( const std::vector< camp::idx_t > & localXadj, MPI_Comm comm ) +std::vector< int > createVertexGlobalID( const std::vector< size_t > & localXadj, MPI_Comm comm ) { int const rank = MpiWrapper::commRank( comm ); int const size = MpiWrapper::commSize( comm ); diff --git a/src/coreComponents/mesh/graphs/GraphToolsMPI.hpp b/src/coreComponents/mesh/graphs/GraphToolsMPI.hpp index c0f09fe7086..4ce88ad1452 100644 --- a/src/coreComponents/mesh/graphs/GraphToolsMPI.hpp +++ b/src/coreComponents/mesh/graphs/GraphToolsMPI.hpp @@ -30,8 +30,6 @@ namespace geos namespace graph { -using camp::idx_t; - /** * @brief Distributes graph data and returns local adjacency lists for each rank. * @@ -44,9 +42,9 @@ using camp::idx_t; * @param comm The MPI communicator (default is MPI_COMM_GEOS). * @return A pair of vectors containing the local adjacency list offsets and neighbors for each rank. */ -std::pair< std::vector< camp::idx_t >, std::vector< camp::idx_t > > -scatterGraphData( const std::vector< camp::idx_t > & xadj, - const std::vector< camp::idx_t > & adjncy, +std::pair< std::vector< size_t >, std::vector< size_t > > +scatterGraphData( const std::vector< size_t > & xadj, + const std::vector< size_t > & adjncy, MPI_Comm comm = MPI_COMM_GEOS ); @@ -62,9 +60,9 @@ scatterGraphData( const std::vector< camp::idx_t > & xadj, * @return A pair of vectors: global xadj and adjncy. */ -std::pair< std::vector< camp::idx_t >, std::vector< camp::idx_t > > -gatherGraphData( const std::vector< camp::idx_t > & localXadj, - const std::vector< camp::idx_t > & localAdjncy, +std::pair< std::vector< size_t >, std::vector< size_t > > +gatherGraphData( const std::vector< size_t > & localXadj, + const std::vector< size_t > & localAdjncy, MPI_Comm comm= MPI_COMM_GEOS ); @@ -78,7 +76,7 @@ gatherGraphData( const std::vector< camp::idx_t > & localXadj, * @param comm The MPI communicator. * @return The xadj array. */ -std::vector< camp::idx_t > createXadjFromAdjncy( const std::vector< camp::idx_t > & localAdjncy, MPI_Comm comm ); +std::vector< size_t > createXadjFromAdjncy( const std::vector< size_t > & localAdjncy, MPI_Comm comm ); /** @@ -90,7 +88,7 @@ std::vector< camp::idx_t > createXadjFromAdjncy( const std::vector< camp::idx_t * @param comm MPI communicator. * @return A vector of global vertex IDs. */ -std::vector< int > createVertexGlobalID( const std::vector< camp::idx_t > & localXadj, MPI_Comm comm ); +std::vector< int > createVertexGlobalID( const std::vector< size_t > & localXadj, MPI_Comm comm ); } // namespace geos } // namespace graph diff --git a/src/coreComponents/mesh/graphs/RLFGraphColoring.cpp b/src/coreComponents/mesh/graphs/RLFGraphColoring.cpp index 0abb5b5066f..0ba5bff5cee 100644 --- a/src/coreComponents/mesh/graphs/RLFGraphColoring.cpp +++ b/src/coreComponents/mesh/graphs/RLFGraphColoring.cpp @@ -34,21 +34,27 @@ RLFGraphColoring::~RLFGraphColoring() {} -int RLFGraphColoring::colorGraph( const std::vector< camp::idx_t > & GEOS_UNUSED_PARAM( adjncy )) +int RLFGraphColoring::colorGraph( const std::vector< size_t > & GEOS_UNUSED_PARAM( adjncy )) { return -1; } -std::vector< int > RLFGraphColoring::colorGraph( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy ) +std::vector< int > RLFGraphColoring::colorGraph( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ) { return RecursiveLargestFirstColoring( xadj, adjncy ); } -std::vector< int > RLFGraphColoring::RecursiveLargestFirstColoring( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy ) + +std::vector< int > RLFGraphColoring::RecursiveLargestFirstColoring( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ) { + if( xadj.empty()) + { + return {}; + } + std::vector< int > color( xadj.size() - 1, -1 ); - std::unordered_set< camp::idx_t > uncoloredNodes; + std::unordered_set< size_t > uncoloredNodes; for( size_t i = 0; i < (xadj.size() - 1); ++i ) { uncoloredNodes.insert( i ); @@ -58,78 +64,105 @@ std::vector< int > RLFGraphColoring::RecursiveLargestFirstColoring( const std::v while( !uncoloredNodes.empty()) { // Find the uncolored node with the largest number of connections - idx_t largestDegreeNode = *std::max_element( uncoloredNodes.begin(), uncoloredNodes.end(), - [xadj]( const idx_t a, const idx_t b ){ return getGraphNodeDegree( a, xadj ) < getGraphNodeDegree( b, xadj ); } ); + auto cmp = [&]( size_t a, size_t b ) { + const auto degreeA = getGraphNodeDegree( a, xadj ); + const auto degreeB = getGraphNodeDegree( b, xadj ); + if( degreeA != degreeB ) + { + return degreeA < degreeB; + } + return a > b; + }; + size_t startNode = *std::max_element( uncoloredNodes.begin(), uncoloredNodes.end(), cmp ); - // Save its neighbors - std::unordered_set< camp::idx_t > largestDegreeNodeNeighbors = getGraphNodeNeighbors( largestDegreeNode, xadj, adjncy ); + // Declare the set of forbidden nodes (nodes adjacent to nodes_to_color) + std::unordered_set< size_t > forbiddenNodes; - // Initialize the node to be colored with the current color - int selectedNode = static_cast< int >(largestDegreeNode); + // Create the candidate set once per color. + // At this stage, candidates are all uncolored nodes... that set will shrink as we go + std::unordered_set< size_t > candidatesForThisColor = uncoloredNodes; - // Declare the set of forbidden nodes (nodes adjacent to nodes_to_color) - std::unordered_set< camp::idx_t > forbiddenNodes; + size_t selectedNode = startNode; - while( selectedNode != -1 ) + while( selectedNode != std::numeric_limits< size_t >::max()) { - // Color the selected node + // Color the selected node and remove it from future consideration color[selectedNode] = currentColor; - std::unordered_set< camp::idx_t > selectedNodeNeighbors = getGraphNodeNeighbors( selectedNode, xadj, adjncy ); - forbiddenNodes.insert( selectedNodeNeighbors.begin(), selectedNodeNeighbors.end()); uncoloredNodes.erase( selectedNode ); + candidatesForThisColor.erase( selectedNode ); - // Find new nodes to color with the current color - std::unordered_set< camp::idx_t > candidateNodesToColor; - for( camp::idx_t node : uncoloredNodes ) + // Update the set of forbidden nodes for the current color + // Any node adjacent to the selectedNode cannot be colored with currentColor + const auto selectedNodeNeighbors = getGraphNodeNeighbors( selectedNode, xadj, adjncy ); + forbiddenNodes.insert( selectedNodeNeighbors.begin(), selectedNodeNeighbors.end()); + + for( const auto & neighbor : selectedNodeNeighbors ) { - if( forbiddenNodes.find( node ) == forbiddenNodes.end()) - { - candidateNodesToColor.insert( node ); - } + candidatesForThisColor.erase( neighbor ); } - // Among the candidates, select one node + // Find the next best node to color from the remaining candidates + size_t bestCandidate = std::numeric_limits< size_t >::max(); size_t maxCommonNeighbors = 0; - selectedNode = -1; - for( camp::idx_t node : candidateNodesToColor ) + size_t bestCandidateDegree = std::numeric_limits< size_t >::max(); + + // Iterate over the shrinking set of candidates + for( const auto & node : candidatesForThisColor ) { - std::unordered_set< camp::idx_t > nodeNeighbors = getGraphNodeNeighbors( node, xadj, adjncy ); + const auto nodeNeighbors = getGraphNodeNeighbors( node, xadj, adjncy ); - size_t commonNeighbors = 0; - for( camp::idx_t neighbor : nodeNeighbors ) + // Count common neighbors with the forbidden set + size_t commonNeighborsCount = 0; + for( const auto & neighbor : nodeNeighbors ) { - if( largestDegreeNodeNeighbors.find( neighbor ) != largestDegreeNodeNeighbors.end()) + if( forbiddenNodes.count( neighbor )) { - ++commonNeighbors; + ++commonNeighborsCount; } } - size_t nodeDegree = getGraphNodeDegree( node, xadj ); - if( commonNeighbors > maxCommonNeighbors || (commonNeighbors == maxCommonNeighbors && nodeDegree < getGraphNodeDegree( selectedNode, xadj ))) + // Apply RLF heuristic + bool shouldSelect = false; + if( bestCandidate == std::numeric_limits< size_t >::max() || commonNeighborsCount > maxCommonNeighbors ) + { + shouldSelect = true; + } + else if( commonNeighborsCount == maxCommonNeighbors ) { - selectedNode = static_cast< int >(node); - maxCommonNeighbors = commonNeighbors; + const size_t nodeDegree = getGraphNodeDegree( node, xadj ); + if( nodeDegree < bestCandidateDegree ) + { + shouldSelect = true; + } + } + + if( shouldSelect ) + { + bestCandidate = node; + maxCommonNeighbors = commonNeighborsCount; + bestCandidateDegree = getGraphNodeDegree( node, xadj ); } } + selectedNode = bestCandidate; } - // Increment the current color + // Move to the next color ++currentColor; } return color; } + size_t RLFGraphColoring::getNumberOfColors( const std::vector< int > & colors ) const { return GraphColoringBase::getNumberOfColors( colors ); } -bool RLFGraphColoring::isColoringValid( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy, const std::vector< int > & colors ) const +bool RLFGraphColoring::isColoringValid( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy, const std::vector< int > & colors ) const { return GraphColoringBase::isColoringValid( xadj, adjncy, colors ); } - } // namespace graph } // namespace geos diff --git a/src/coreComponents/mesh/graphs/RLFGraphColoring.hpp b/src/coreComponents/mesh/graphs/RLFGraphColoring.hpp index af4c5338071..6f340bfb9be 100644 --- a/src/coreComponents/mesh/graphs/RLFGraphColoring.hpp +++ b/src/coreComponents/mesh/graphs/RLFGraphColoring.hpp @@ -63,14 +63,14 @@ class RLFGraphColoring : public GraphColoringBase * @param adjncy Adjacency list. * @return A vector of assigned colors. */ - std::vector< int > colorGraph( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy ) override; + std::vector< int > colorGraph( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ) override; /** * @brief Colors a graph assuming one node per rank. * @param localAdjncy Local adjacency list. * @return Color of the node. */ - int colorGraph( const std::vector< camp::idx_t > & localAdjncy ) override; + int colorGraph( const std::vector< size_t > & localAdjncy ) override; /** * @brief Returns the number of distinct colors used. @@ -86,7 +86,7 @@ class RLFGraphColoring : public GraphColoringBase * @param colors Vector of assigned colors. * @return True if coloring is valid, false otherwise. */ - bool isColoringValid( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy, const std::vector< int > & colors ) const; + bool isColoringValid( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy, const std::vector< int > & colors ) const; private: @@ -96,7 +96,7 @@ class RLFGraphColoring : public GraphColoringBase * @param adjncy The adjacency list containing the neighbors of each node. * @return A vector where the index represents the node and the value represents the assigned color. */ - std::vector< int > RecursiveLargestFirstColoring( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy ); + std::vector< int > RecursiveLargestFirstColoring( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ); }; } // namespace graph diff --git a/src/coreComponents/mesh/graphs/RLFGraphColoringMPI.cpp b/src/coreComponents/mesh/graphs/RLFGraphColoringMPI.cpp index 314ca4e577c..36e90c1bd24 100644 --- a/src/coreComponents/mesh/graphs/RLFGraphColoringMPI.cpp +++ b/src/coreComponents/mesh/graphs/RLFGraphColoringMPI.cpp @@ -35,16 +35,16 @@ RLFGraphColoringMPI::~RLFGraphColoringMPI() {} -int RLFGraphColoringMPI::colorGraph( const std::vector< camp::idx_t > & localAdjncy ) +int RLFGraphColoringMPI::colorGraph( const std::vector< size_t > & localAdjncy ) { - std::vector< camp::idx_t > localXadj = createXadjFromAdjncy( localAdjncy, m_comm ); + std::vector< size_t > localXadj = createXadjFromAdjncy( localAdjncy, m_comm ); std::vector< int > localColors = RLFGraphColoringMPI::colorGraph( localXadj, localAdjncy ); return localColors[0]; } -std::vector< int > RLFGraphColoringMPI::colorGraph( const std::vector< camp::idx_t > & localXadj, - const std::vector< camp::idx_t > & localAdjncy ) +std::vector< int > RLFGraphColoringMPI::colorGraph( const std::vector< size_t > & localXadj, + const std::vector< size_t > & localAdjncy ) { int const rank = MpiWrapper::commRank( m_comm ); int const size = MpiWrapper::commSize( m_comm ); @@ -99,7 +99,7 @@ size_t RLFGraphColoringMPI::getNumberOfColors( const std::vector< int > & colors } -bool RLFGraphColoringMPI::isColoringValid( const std::vector< camp::idx_t > & adjncy, const int color ) const +bool RLFGraphColoringMPI::isColoringValid( const std::vector< size_t > & adjncy, const int color ) const { return GraphColoringBase::isColoringValid( adjncy, color, m_comm ); } diff --git a/src/coreComponents/mesh/graphs/RLFGraphColoringMPI.hpp b/src/coreComponents/mesh/graphs/RLFGraphColoringMPI.hpp index 93990c8e586..d644f0db9eb 100644 --- a/src/coreComponents/mesh/graphs/RLFGraphColoringMPI.hpp +++ b/src/coreComponents/mesh/graphs/RLFGraphColoringMPI.hpp @@ -75,7 +75,7 @@ class RLFGraphColoringMPI : public GraphColoringBase * @param localColor Color assigned to the local node. * @return True if the coloring is valid, false otherwise. */ - bool isColoringValid( const std::vector< camp::idx_t > & localAdjncy, const int localColor ) const; + bool isColoringValid( const std::vector< size_t > & localAdjncy, const int localColor ) const; /** * @brief Colors a distributed graph. @@ -83,14 +83,14 @@ class RLFGraphColoringMPI : public GraphColoringBase * @param localAdjncy Local adjacency list. * @return A vector of assigned colors. */ - std::vector< int > colorGraph( const std::vector< camp::idx_t > & localXadj, const std::vector< camp::idx_t > & localAdjncy ) override; + std::vector< int > colorGraph( const std::vector< size_t > & localXadj, const std::vector< size_t > & localAdjncy ) override; /** * @brief Simplified coloring assuming one node per rank. * @param localAdjncy Local adjacency list. * @return Color of the node. */ - int colorGraph( const std::vector< camp::idx_t > & localAdjncy ) override; + int colorGraph( const std::vector< size_t > & localAdjncy ) override; }; } // namespace graph diff --git a/src/coreComponents/mesh/graphs/ZoltanGraphColoring.cpp b/src/coreComponents/mesh/graphs/ZoltanGraphColoring.cpp index 03fa9d0f5e5..0cc1f7ad00f 100644 --- a/src/coreComponents/mesh/graphs/ZoltanGraphColoring.cpp +++ b/src/coreComponents/mesh/graphs/ZoltanGraphColoring.cpp @@ -20,6 +20,7 @@ #include "ZoltanGraphColoring.hpp" #include "GraphToolsMPI.hpp" #include +#include #define GEOS_ZOLTAN_CHECK( call ) \ @@ -58,23 +59,34 @@ ZoltanGraphColoring::~ZoltanGraphColoring() } -int ZoltanGraphColoring::colorGraph( const std::vector< camp::idx_t > & localAdjncy ) +int ZoltanGraphColoring::colorGraph( const std::vector< size_t > & localAdjncy ) { - std::vector< camp::idx_t > localXadj = createXadjFromAdjncy( localAdjncy, m_comm ); + std::vector< size_t > localXadj = createXadjFromAdjncy( localAdjncy, m_comm ); std::vector< int > colors = colorGraph( localXadj, localAdjncy ); return colors[0]; } -std::vector< int > ZoltanGraphColoring::colorGraph( const std::vector< camp::idx_t > & xadj, - const std::vector< camp::idx_t > & adjncy ) +std::vector< int > ZoltanGraphColoring::colorGraph( const std::vector< size_t > & xadj, + const std::vector< size_t > & adjncy ) { int const rank = MpiWrapper::commRank( m_comm ); + // Convert size_t to int with overflow checking for Zoltan + auto safeConvert = []( size_t value ) -> int { + GEOS_ERROR_IF( value > static_cast< size_t >( std::numeric_limits< int >::max()), + "Value " << value << " exceeds maximum int value for Zoltan interface" ); + return static_cast< int >( value ); + }; + ZoltanGraph graph; - graph.m_xadj.assign( xadj.begin(), xadj.end()); - graph.m_adjncy.assign( adjncy.begin(), adjncy.end()); - graph.m_numVertices = xadj.size() - 1; + graph.m_xadj.reserve( xadj.size()); + std::transform( xadj.begin(), xadj.end(), std::back_inserter( graph.m_xadj ), safeConvert ); + + graph.m_adjncy.reserve( adjncy.size()); + std::transform( adjncy.begin(), adjncy.end(), std::back_inserter( graph.m_adjncy ), safeConvert ); + + graph.m_numVertices = safeConvert( xadj.size() - 1 ); graph.m_rank = rank; std::vector< int > vertexGID = createVertexGlobalID( xadj, m_comm ); @@ -204,7 +216,7 @@ size_t ZoltanGraphColoring::getNumberOfColors( const std::vector< int > & colors } -bool ZoltanGraphColoring::isColoringValid( const std::vector< camp::idx_t > & adjncy, const int color ) const +bool ZoltanGraphColoring::isColoringValid( const std::vector< size_t > & adjncy, const int color ) const { return GraphColoringBase::isColoringValid( adjncy, color, m_comm ); } diff --git a/src/coreComponents/mesh/graphs/ZoltanGraphColoring.hpp b/src/coreComponents/mesh/graphs/ZoltanGraphColoring.hpp index 219934b6471..ab15c9020ca 100644 --- a/src/coreComponents/mesh/graphs/ZoltanGraphColoring.hpp +++ b/src/coreComponents/mesh/graphs/ZoltanGraphColoring.hpp @@ -76,7 +76,7 @@ class ZoltanGraphColoring : public GraphColoringBase * @param color Color of the node. * @return True if the coloring is valid, false otherwise. */ - bool isColoringValid( const std::vector< camp::idx_t > & adjncy, const int color ) const; + bool isColoringValid( const std::vector< size_t > & adjncy, const int color ) const; /** * @brief Colors a graph. @@ -84,14 +84,14 @@ class ZoltanGraphColoring : public GraphColoringBase * @param adjncy Adjacency list. * @return A vector of assigned colors. */ - std::vector< int > colorGraph( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy ) override; + std::vector< int > colorGraph( const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy ) override; /** * @brief Simplified coloring assuming one node per rank. * @param adjncy Local adjacency list. * @return Number of colors used. */ - int colorGraph( const std::vector< camp::idx_t > & adjncy ) override; + int colorGraph( const std::vector< size_t > & adjncy ) override; private: diff --git a/src/coreComponents/mesh/mpiCommunications/SpatialPartition.cpp b/src/coreComponents/mesh/mpiCommunications/SpatialPartition.cpp index 5beecb1842c..3dc05f80a7b 100644 --- a/src/coreComponents/mesh/mpiCommunications/SpatialPartition.cpp +++ b/src/coreComponents/mesh/mpiCommunications/SpatialPartition.cpp @@ -91,49 +91,45 @@ void SpatialPartition::setPartitions( unsigned int xPartitions, int SpatialPartition::getColor() { - if( m_metisNeighborList.empty() ) - { - // Internal cartesian partitioner (for internal mesh) - int color=0; - if( isOdd( m_coords[0] ) ) - { - color += 1; - } - - if( isOdd( m_coords[1] ) ) - { - color += 2; - } + return getColor( {} ); +} - if( isOdd( m_coords[2] ) ) - { - color += 4; - } +int SpatialPartition::getColor( std::set< int > const & fullNeighbors ) +{ + // Determine neighbor source + std::vector< size_t > adjncy; + bool const useGraphColoring = !fullNeighbors.empty() || !m_metisNeighborList.empty(); - // With this algorithm, numbering may have gaps. - // In that case m_numColors is an upper bound, not the exact number of distinct colors used. - m_numColors = MpiWrapper::max( color )+1; - return color; - } - else + if( useGraphColoring ) { - // External partitioner such as ParMetis or PTScotch (for VTK external mesh) - std::vector< camp::idx_t > adjncy; - adjncy.reserve( m_metisNeighborList.size()); - std::copy( m_metisNeighborList.begin(), m_metisNeighborList.end(), std::back_inserter( adjncy )); + // Use provided neighbors or fall back to metis neighbors + auto const & neighbors = !fullNeighbors.empty() ? fullNeighbors : m_metisNeighborList; + adjncy.assign( neighbors.begin(), neighbors.end() ); + + // Apply graph coloring #ifdef GEOS_USE_TRILINOS geos::graph::ZoltanGraphColoring coloring; #else geos::graph::RLFGraphColoringMPI coloring; #endif - int color = coloring.colorGraph( adjncy ); + int const color = coloring.colorGraph( adjncy ); + + GEOS_ERROR_IF( !coloring.isColoringValid( adjncy, color ), + "Invalid partition coloring: two neighboring partitions share the same color" ); - if( !coloring.isColoringValid( adjncy, color )) - { - GEOS_ERROR( "Invalid partition coloring: two neighboring partitions share the same color" ); - } m_numColors = coloring.getNumberOfColors( color ); + return color; + } + else + { + // Cartesian partitioner coloring + int const color = (isOdd( m_coords[0] ) ? 1 : 0) | + (isOdd( m_coords[1] ) ? 2 : 0) | + (isOdd( m_coords[2] ) ? 4 : 0); + // With this algorithm, numbering may have gaps. + // In that case m_numColors is an upper bound, not the exact number of distinct colors used. + m_numColors = MpiWrapper::max( color ) + 1; return color; } } diff --git a/src/coreComponents/mesh/mpiCommunications/SpatialPartition.hpp b/src/coreComponents/mesh/mpiCommunications/SpatialPartition.hpp index 0ed1b526039..be5f70be9f8 100644 --- a/src/coreComponents/mesh/mpiCommunications/SpatialPartition.hpp +++ b/src/coreComponents/mesh/mpiCommunications/SpatialPartition.hpp @@ -71,8 +71,26 @@ class SpatialPartition : public PartitionBase unsigned int yPartitions, unsigned int zPartitions ) override; + /** + * @brief Get the color for graph coloring-based synchronization. + * @return The color assigned to this rank. + * + * @note Uses the default neighbor list (m_metisNeighborList for external meshes, + * or Cartesian coordinates for internal meshes). + */ int getColor() override; + /** + * @brief Get the color for graph coloring-based synchronization with custom neighbors. + * @param fullNeighbors Set of neighbor ranks to use for coloring. If provided, + * overrides the default neighbor list. May include second-order + * neighbors for more conservative coloring. + * @return The color assigned to this rank. + * + * @note When fullNeighbors is empty, falls back to the default getColor() behavior. + */ + int getColor( std::set< int > const & fullNeighbors ); + void repartitionMasterParticles( ParticleSubRegion & subRegion, MPI_iCommData & commData ); diff --git a/src/coreComponents/mesh/unitTests/CMakeLists.txt b/src/coreComponents/mesh/unitTests/CMakeLists.txt index a365e1f0b0a..01381a38081 100644 --- a/src/coreComponents/mesh/unitTests/CMakeLists.txt +++ b/src/coreComponents/mesh/unitTests/CMakeLists.txt @@ -38,7 +38,7 @@ if (ENABLE_TRILINOS) list( APPEND dependencyList trilinos ) endif() -set( nranks 8 ) +set( nranks 4 ) foreach( test ${mesh_tests_mpi} ) get_filename_component( file_we ${test} NAME_WE ) diff --git a/src/coreComponents/mesh/unitTests/testGraphColoring.cpp b/src/coreComponents/mesh/unitTests/testGraphColoring.cpp index db16eb574b0..e6e7399e880 100644 --- a/src/coreComponents/mesh/unitTests/testGraphColoring.cpp +++ b/src/coreComponents/mesh/unitTests/testGraphColoring.cpp @@ -34,8 +34,8 @@ TEST( GraphColoringTest, CountPositiveDistinctColors ) TEST( GraphColoringTest, CartesianDecomposition3D6 ) { - idx_t const nx = 3, ny = 4, nz = 3; - auto [xadj, adjncy] = generateGraphCartPartitionning3D6( nx, ny, nz ); + size_t const nx = 3, ny = 4, nz = 3; + auto [xadj, adjncy] = generateGraphCartPartitioning3D6( nx, ny, nz ); geos::graph::RLFGraphColoring graphColoring; std::vector< int > colors = graphColoring.colorGraph( xadj, adjncy ); @@ -46,8 +46,8 @@ TEST( GraphColoringTest, CartesianDecomposition3D6 ) TEST( GraphColoringTest, CartesianDecomposition3D26 ) { - idx_t const nx = 3, ny = 4, nz = 3; - auto [xadj, adjncy] = generateGraphCartPartitionning3D26( nx, ny, nz ); + size_t const nx = 3, ny = 4, nz = 3; + auto [xadj, adjncy] = generateGraphCartPartitioning3D26( nx, ny, nz ); geos::graph::RLFGraphColoring graphColoring; std::vector< int > colors = graphColoring.colorGraph( xadj, adjncy ); EXPECT_TRUE( graphColoring.isColoringValid( xadj, adjncy, colors )); @@ -73,8 +73,8 @@ TEST( GraphColoringTest, RandomGraphs ) TEST( GraphColoringTest, InvalidColoring ) { // Create a simple graph with 4 nodes and 3 edges - std::vector< idx_t > xadj = {0, 1, 2, 3, 3}; - std::vector< idx_t > adjncy = {1, 0, 2, 1}; + std::vector< size_t > xadj = {0, 1, 2, 3, 3}; + std::vector< size_t > adjncy = {1, 0, 2, 1}; // Intentionally create an invalid coloring where two adjacent nodes have the same color std::vector< int > colors = {0, 0, 1, 1}; diff --git a/src/coreComponents/mesh/unitTests/testGraphColoringMPI.cpp b/src/coreComponents/mesh/unitTests/testGraphColoringMPI.cpp index 65bdaf0aa77..38877c8c05c 100644 --- a/src/coreComponents/mesh/unitTests/testGraphColoringMPI.cpp +++ b/src/coreComponents/mesh/unitTests/testGraphColoringMPI.cpp @@ -47,7 +47,7 @@ class GraphColoringTest : public ::testing::Test }; -void runColoringTest( GraphColoringBase & graphColoring, const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy, int expectedNumberOfColors ) +void runColoringTest( GraphColoringBase & graphColoring, const std::vector< size_t > & xadj, const std::vector< size_t > & adjncy, int expectedNumberOfColors ) { auto [localXadj, localAdjncy] = scatterGraphData( xadj, adjncy, MPI_COMM_GEOS ); int color = graphColoring.colorGraph( localAdjncy ); @@ -67,13 +67,13 @@ TEST_F( GraphColoringTest, CartesianDecomposition3D6 ) #endif RLFGraphColoringMPI rlfColoringMPI; - std::vector< camp::idx_t > xadj; - std::vector< camp::idx_t > adjncy; + std::vector< size_t > xadj; + std::vector< size_t > adjncy; if( rank == 0 ) { - idx_t const nx = 4, ny = 2, nz = 1; - std::tie( xadj, adjncy ) = generateGraphCartPartitionning3D6( nx, ny, nz ); + size_t const nx = 2, ny = 2, nz = 1; + std::tie( xadj, adjncy ) = generateGraphCartPartitioning3D6( nx, ny, nz ); } #ifdef GEOS_USE_TRILINOS @@ -90,19 +90,19 @@ TEST_F( GraphColoringTest, CartesianDecomposition3D26 ) #endif RLFGraphColoringMPI rlfColoringMPI; - std::vector< camp::idx_t > xadj; - std::vector< camp::idx_t > adjncy; + std::vector< size_t > xadj; + std::vector< size_t > adjncy; if( rank == 0 ) { - idx_t const nx = 2, ny = 2, nz = 2; - std::tie( xadj, adjncy ) = generateGraphCartPartitionning3D26( nx, ny, nz ); + size_t const nx = 2, ny = 2, nz = 1; + std::tie( xadj, adjncy ) = generateGraphCartPartitioning3D26( nx, ny, nz ); } #ifdef GEOS_USE_TRILINOS - runColoringTest( zoltanColoring, xadj, adjncy, 8 ); + runColoringTest( zoltanColoring, xadj, adjncy, 4 ); #endif - runColoringTest( rlfColoringMPI, xadj, adjncy, 8 ); + runColoringTest( rlfColoringMPI, xadj, adjncy, 4 ); } @@ -116,12 +116,12 @@ TEST_F( GraphColoringTest, RandomGraphs ) size_t const iterations = 10; for( size_t i = 0; i < iterations; ++i ) { - std::vector< camp::idx_t > xadj; - std::vector< camp::idx_t > adjncy; + std::vector< size_t > xadj; + std::vector< size_t > adjncy; if( rank == 0 ) { - size_t num_nodes = 8; + size_t num_nodes = 4; size_t num_edges = rand() % (num_nodes * 3 + 1) + num_nodes; std::tie( xadj, adjncy ) = generateGraphRandom( num_nodes, num_edges ); } diff --git a/src/coreComponents/physicsSolvers/surfaceGeneration/SurfaceGenerator.cpp b/src/coreComponents/physicsSolvers/surfaceGeneration/SurfaceGenerator.cpp index 76a9fd032c4..e986d46ab11 100644 --- a/src/coreComponents/physicsSolvers/surfaceGeneration/SurfaceGenerator.cpp +++ b/src/coreComponents/physicsSolvers/surfaceGeneration/SurfaceGenerator.cpp @@ -466,16 +466,24 @@ real64 SurfaceGenerator::solverStep( real64 const & time_n, const int GEOS_UNUSED_PARAM( cycleNumber ), DomainPartition & domain ) { + + SpatialPartition & partition = dynamicCast< SpatialPartition & >( domain.getReference< PartitionBase >( dataRepository::keys::partitionManager ) ); + + // Build full neighbor set (includes neighbors of neighbors) from DomainPartition + std::set< int > fullNeighbors; + for( NeighborCommunicator const & neighbor : domain.getNeighbors() ) + { + fullNeighbors.insert( neighbor.neighborRank() ); + } + int const tileColor = partition.getColor( fullNeighbors ); + int const numTileColors = partition.numColor(); + int rval = 0; forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, MeshLevel & meshLevel, string_array const & ) { - SpatialPartition & partition = dynamicCast< SpatialPartition & >( domain.getReference< PartitionBase >( dataRepository::keys::partitionManager ) ); - int const tileColor=partition.getColor(); - int const numTileColors=partition.numColor(); - rval = separationDriver( domain, meshLevel, domain.getNeighbors(),