Skip to content

Commit 5c790b6

Browse files
bd713DENEL BertrandOmarDurancastelletto1
authored
fix: Fix RLF coloring (#3814)
* Switched to size_t, adressed reviews. * Fixed sequential mode * Limit parallel test to 4 ranks * zoltan int * Missing size_t * Included extended neighbors for coloring * Uncrustify * container * random graph test * rebaseline --------- Co-authored-by: DENEL Bertrand <bertrand.denel@total.com> Co-authored-by: Omar Duran <oduran@stanford.edu> Co-authored-by: Nicola Castelletto <38361926+castelletto1@users.noreply.github.com>
1 parent a458b6e commit 5c790b6

20 files changed

Lines changed: 304 additions & 250 deletions

.integrated_tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
baselines:
22
bucket: geosx
3-
baseline: integratedTests/baseline_integratedTests-pr4008-16688-17c55fe
3+
baseline: integratedTests/baseline_integratedTests-pr3814-16717-d17ea59
44

55
allow_fail:
66
all: ''

BASELINE_NOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ This file is designed to track changes to the integrated test baselines.
55
Any developer who updates the baseline ID in the .integrated_tests.yaml file is expected to create an entry in this file with the pull request number, date, and their justification for rebaselining.
66
These notes should be in reverse-chronological order, and use the following time format: (YYYY-MM-DD).
77

8+
PR #3814 (2026-05-20) <https://storage.googleapis.com/geosx/integratedTests/baseline_integratedTests-pr3814-16717-d17ea59.tar.gz>
9+
Fix RLF coloring
10+
811
PR #4008 (2026-05-18) <https://storage.googleapis.com/geosx/integratedTests/baseline_integratedTests-pr4008-16688-17c55fe.tar.gz>
912
Fix Fracture/3D cell co-location in parallel mesh redistribution
1013

src/coreComponents/common/MpiWrapper.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1307,7 +1307,7 @@ int MpiWrapper::scatterv( TS const * const sendbuf,
13071307
#else
13081308
static_assert( std::is_same< TS, TR >::value,
13091309
"MpiWrapper::scatterv() for serial run requires send and receive buffers are of the same type" );
1310-
std::size_t const sendBufferSize = sendcounts * sizeof(TS);
1310+
std::size_t const sendBufferSize = sendcounts[0] * sizeof(TS);
13111311
std::size_t const recvBufferSize = recvcount * sizeof(TR);
13121312
GEOS_ERROR_IF_NE_MSG( sendBufferSize, recvBufferSize, "size of send buffer and receive buffer are not equal" );
13131313
memcpy( recvbuf, sendbuf, sendBufferSize );

src/coreComponents/mesh/graphs/GraphColoringBase.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,15 @@ namespace geos
2727
namespace graph
2828
{
2929

30-
bool GraphColoringBase::isColoringValid( const std::vector< camp::idx_t > & xadj,
31-
const std::vector< camp::idx_t > & adjncy,
32-
const std::vector< int > & coloring )
30+
bool GraphColoringBase::isColoringValid( const stdVector< size_t > & xadj,
31+
const stdVector< size_t > & adjncy,
32+
const stdVector< int > & coloring )
3333
{
3434
for( size_t node = 0; node < coloring.size(); ++node )
3535
{
3636
int node_color = coloring[node];
37-
std::unordered_set< camp::idx_t > neighbors = getGraphNodeNeighbors( node, xadj, adjncy );
38-
39-
for( camp::idx_t neighbor : neighbors )
37+
std::unordered_set< size_t > neighbors = getGraphNodeNeighbors( node, xadj, adjncy );
38+
for( size_t neighbor : neighbors )
4039
{
4140
if( coloring[neighbor] == node_color )
4241
{
@@ -48,7 +47,7 @@ bool GraphColoringBase::isColoringValid( const std::vector< camp::idx_t > & xadj
4847
}
4948

5049

51-
size_t GraphColoringBase::getNumberOfColors( const std::vector< int > & colors )
50+
size_t GraphColoringBase::getNumberOfColors( const stdVector< int > & colors )
5251
{
5352
std::unordered_set< int > uniqueColors;
5453
for( int color : colors )
@@ -63,7 +62,7 @@ size_t GraphColoringBase::getNumberOfColors( const std::vector< int > & colors )
6362

6463

6564
// Assume only one node per rank.
66-
bool GraphColoringBase::isColoringValid( const std::vector< camp::idx_t > & adjncy,
65+
bool GraphColoringBase::isColoringValid( const stdVector< size_t > & adjncy,
6766
const int color,
6867
MPI_Comm comm )
6968
{
@@ -74,7 +73,7 @@ bool GraphColoringBase::isColoringValid( const std::vector< camp::idx_t > & adjn
7473
// matched by the wrong iRecv, producing false color conflicts.
7574
// Allgather has no tag and is always safe.
7675
int const size = MpiWrapper::commSize( comm );
77-
std::vector< int > allColors( size );
76+
stdVector< int > allColors( size );
7877
MpiWrapper::allgather( &color, 1, allColors.data(), 1, comm );
7978

8079
// Check for color conflicts with each listed neighbor.
@@ -97,27 +96,27 @@ bool GraphColoringBase::isColoringValid( const std::vector< camp::idx_t > & adjn
9796

9897
size_t GraphColoringBase::getNumberOfColors( const int color, MPI_Comm comm )
9998
{
100-
std::vector< int > colors = {color};
99+
stdVector< int > colors = {color};
101100
return getNumberOfColors( colors, comm );
102101
}
103102

104103

105-
size_t GraphColoringBase::getNumberOfColors( const std::vector< int > & colors, MPI_Comm comm )
104+
size_t GraphColoringBase::getNumberOfColors( const stdVector< int > & colors, MPI_Comm comm )
106105
{
107106
int const rank = MpiWrapper::commRank( comm );
108107
int const size = MpiWrapper::commSize( comm );
109108

110109
std::set< int > localDistinctColors = std::set< int >( colors.begin(), colors.end());
111-
std::vector< int > localDistinctColorsVector( localDistinctColors.begin(), localDistinctColors.end());
110+
stdVector< int > localDistinctColorsVector( localDistinctColors.begin(), localDistinctColors.end());
112111
int const localSize = localDistinctColorsVector.size();
113112

114113
// Gather the sizes of the local color vectors from all ranks
115-
std::vector< int > allSizes( size );
114+
stdVector< int > allSizes( size );
116115
MpiWrapper::gather( &localSize, 1, allSizes.data(), 1, 0, comm );
117116

118117
// Calculate the total number of colors and the displacements for gathering
119118
int totalSize = 0;
120-
std::vector< int > displacements( size, 0 );
119+
stdVector< int > displacements( size, 0 );
121120
if( rank == 0 )
122121
{
123122
for( int i = 0; i < size; ++i )
@@ -128,7 +127,7 @@ size_t GraphColoringBase::getNumberOfColors( const std::vector< int > & colors,
128127
}
129128

130129
// Gather all colors from all ranks to rank 0
131-
std::vector< int > allColors( totalSize );
130+
stdVector< int > allColors( totalSize );
132131
MpiWrapper::gatherv( localDistinctColorsVector.data(), localSize,
133132
allColors.data(), allSizes.data(), displacements.data(),
134133
0, comm );

src/coreComponents/mesh/graphs/GraphColoringBase.hpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ namespace graph
3434
* @class GraphColoringBase
3535
* @brief Abstract base class for graph coloring strategies.
3636
*
37-
* Provides a common interface for graph coloring algorithms used in GEOS.
38-
* Derived classes must implement the coloring logic for adjacency graphs.
37+
* Provides a common interface for graph coloring algorithms used in GEOS. Derived classes must implement the coloring logic for adjacency
38+
* graphs.
3939
*/
4040
class GraphColoringBase
4141
{
@@ -54,14 +54,14 @@ class GraphColoringBase
5454
* @param adjncy Adjacency list containing neighbors of each node.
5555
* @return A vector of colors assigned to each node.
5656
*/
57-
virtual std::vector< int > colorGraph( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy ) = 0;
57+
virtual stdVector< int > colorGraph( const stdVector< size_t > & xadj, const stdVector< size_t > & adjncy ) = 0;
5858

5959
/**
6060
* @brief Pure virtual method to color a graph assuming one node per rank.
6161
* @param adjncy Adjacency list containing neighbors of each node.
6262
* @return Color of the node.
6363
*/
64-
virtual int colorGraph( const std::vector< camp::idx_t > & adjncy ) = 0;
64+
virtual int colorGraph( const stdVector< size_t > & adjncy ) = 0;
6565

6666

6767
/**
@@ -81,7 +81,7 @@ class GraphColoringBase
8181
* @param coloring A vector where the index represents the node and the value represents the assigned color.*
8282
* @return True if the coloring is valid, false otherwise.
8383
*/
84-
static bool isColoringValid( const std::vector< camp::idx_t > & xadj, const std::vector< camp::idx_t > & adjncy, const std::vector< int > & coloring );
84+
static bool isColoringValid( const stdVector< size_t > & xadj, const stdVector< size_t > & adjncy, const stdVector< int > & coloring );
8585

8686
/**
8787
* @brief Checks the validity of the graph coloring assuming one node per rank.
@@ -92,26 +92,25 @@ class GraphColoringBase
9292
*
9393
* @return True if the coloring is valid, false otherwise.
9494
*/
95-
static bool isColoringValid( const std::vector< camp::idx_t > & adjncy, const int color, MPI_Comm comm );
95+
static bool isColoringValid( const stdVector< size_t > & adjncy, const int color, MPI_Comm comm );
9696

9797
/**
9898
* @brief Counts the number of distinct colors.
9999
*
100-
* This function takes a vector of integers representing colors
101-
* and returns the number of distinct (positive) colors present in the vector.
100+
* This function takes a vector of integers representing colors and returns the number of distinct (positive) colors present in the vector.
102101
*
103102
* @param colors A vector of integers representing colors.
104103
* @return The number of distinct colors in the vector.
105104
*/
106-
static size_t getNumberOfColors( const std::vector< int > & colors );
105+
static size_t getNumberOfColors( const stdVector< int > & colors );
107106

108107
/**
109108
* @brief Counts the number of distinct colors (parallel version).
110109
* @param colors Vector of color values.
111110
* @param comm MPI communicator.
112111
* @return Number of distinct colors.
113112
*/
114-
static size_t getNumberOfColors( const std::vector< int > & colors, MPI_Comm comm );
113+
static size_t getNumberOfColors( const stdVector< int > & colors, MPI_Comm comm );
115114

116115
/**
117116
* @brief Counts the number of distinct colors assuming one node per rank (parallel version).

src/coreComponents/mesh/graphs/GraphTools.cpp

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,34 @@ namespace geos
2929
namespace graph
3030
{
3131

32-
size_t getGraphNodeDegree( idx_t node, const std::vector< idx_t > & xadj )
32+
size_t getGraphNodeDegree( size_t node, const stdVector< size_t > & xadj )
3333
{
3434
return xadj[node + 1] - xadj[node];
3535
}
3636

3737

38-
std::unordered_set< idx_t > getGraphNodeNeighbors( idx_t node, const std::vector< idx_t > & xadj, const std::vector< idx_t > & adjncy )
38+
std::unordered_set< size_t > getGraphNodeNeighbors( size_t node, const stdVector< size_t > & xadj, const stdVector< size_t > & adjncy )
3939
{
40-
std::unordered_set< idx_t > neighbors;
41-
for( idx_t i = xadj[node]; i < xadj[node + 1]; ++i )
40+
std::unordered_set< size_t > neighbors;
41+
for( size_t i = xadj[node]; i < xadj[node + 1]; ++i )
4242
{
4343
neighbors.insert( adjncy[i] );
4444
}
4545
return neighbors;
4646
}
4747

4848

49-
bool isGraphValid( const std::vector< idx_t > & xadj,
50-
const std::vector< idx_t > & adjncy )
49+
bool isGraphValid( const stdVector< size_t > & xadj,
50+
const stdVector< size_t > & adjncy )
5151
{
52-
idx_t num_nodes = xadj.size() - 1;
52+
size_t num_nodes = xadj.size() - 1;
5353

54-
for( idx_t i = 0; i < num_nodes; ++i )
54+
for( size_t i = 0; i < num_nodes; ++i )
5555
{
56-
std::unordered_set< idx_t > neighbors;
57-
for( idx_t j = xadj[i]; j < xadj[i + 1]; ++j )
56+
std::unordered_set< size_t > neighbors;
57+
for( size_t j = xadj[i]; j < xadj[i + 1]; ++j )
5858
{
59-
idx_t neighbor = adjncy[j];
59+
size_t neighbor = adjncy[j];
6060

6161
// Check for out-of-bounds indices
6262
if( neighbor >= num_nodes )
@@ -75,7 +75,7 @@ bool isGraphValid( const std::vector< idx_t > & xadj,
7575

7676
// Check for bidirectional connection
7777
bool bidirectional = false;
78-
for( idx_t k = xadj[neighbor]; k < xadj[neighbor + 1]; ++k )
78+
for( size_t k = xadj[neighbor]; k < xadj[neighbor + 1]; ++k )
7979
{
8080
if( adjncy[k] == i )
8181
{
@@ -95,9 +95,9 @@ bool isGraphValid( const std::vector< idx_t > & xadj,
9595
}
9696

9797

98-
std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( size_t numVertices, size_t numEdges )
98+
std::tuple< stdVector< size_t >, stdVector< size_t > > generateGraphRandom( size_t numVertices, size_t numEdges )
9999
{
100-
std::vector< std::pair< size_t, size_t > > edges;
100+
stdVector< std::pair< size_t, size_t > > edges;
101101
srand( static_cast< unsigned int >(time( 0 )));
102102

103103
// Generate random edges
@@ -116,8 +116,8 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( si
116116
std::sort( edges.begin(), edges.end());
117117

118118
// Initialize xadj and adjncy
119-
std::vector< idx_t > xadj( numVertices + 1, 0 );
120-
std::vector< idx_t > adjncy;
119+
stdVector< size_t > xadj( numVertices + 1, 0 );
120+
stdVector< size_t > adjncy;
121121
adjncy.reserve( edges.size());
122122

123123
// Fill xadj and adjncy
@@ -142,25 +142,25 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( si
142142
}
143143

144144

145-
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 )
145+
std::tuple< stdVector< size_t >, stdVector< size_t > > generateGraphCartPartitioning3D( size_t nx, size_t ny, size_t nz, const stdVector< stdArray< int, 3 > > & neighbor_offsets )
146146
{
147-
idx_t num_nodes = nx * ny * nz;
148-
std::vector< idx_t > xadj( num_nodes + 1, 0 );
149-
std::vector< idx_t > adjncy;
147+
size_t num_nodes = nx * ny * nz;
148+
stdVector< size_t > xadj( num_nodes + 1, 0 );
149+
stdVector< size_t > adjncy;
150150

151-
auto getNodeIndex = [nx, ny] ( const idx_t x, const idx_t y, const idx_t z )
151+
auto getNodeIndex = [nx, ny] ( const size_t x, const size_t y, const size_t z )
152152
{
153153
return x + nx * (y + ny * z);
154154
};
155155

156-
idx_t node_counter = 0;
157-
for( idx_t z = 0; z < nz; ++z )
156+
size_t node_counter = 0;
157+
for( size_t z = 0; z < nz; ++z )
158158
{
159-
for( idx_t y = 0; y < ny; ++y )
159+
for( size_t y = 0; y < ny; ++y )
160160
{
161-
for( idx_t x = 0; x < nx; ++x )
161+
for( size_t x = 0; x < nx; ++x )
162162
{
163-
std::vector< idx_t > neighbors;
163+
stdVector< size_t > neighbors;
164164
for( const auto & offset : neighbor_offsets )
165165
{
166166

@@ -186,17 +186,17 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartit
186186
return {xadj, adjncy};
187187
}
188188

189-
std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D6( idx_t nx, idx_t ny, idx_t nz )
189+
std::tuple< stdVector< size_t >, stdVector< size_t > > generateGraphCartPartitioning3D6( size_t nx, size_t ny, size_t nz )
190190
{
191-
std::vector< std::array< int, 3 > > neighbor_offsets = {
191+
stdVector< stdArray< int, 3 > > neighbor_offsets = {
192192
{-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1}
193193
};
194-
return generateGraphCartPartitionning3D( nx, ny, nz, neighbor_offsets );
194+
return generateGraphCartPartitioning3D( nx, ny, nz, neighbor_offsets );
195195
}
196196

197-
std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D26( idx_t nx, idx_t ny, idx_t nz )
197+
std::tuple< stdVector< size_t >, stdVector< size_t > > generateGraphCartPartitioning3D26( size_t nx, size_t ny, size_t nz )
198198
{
199-
std::vector< std::array< int, 3 > > neighbor_offsets;
199+
stdVector< stdArray< int, 3 > > neighbor_offsets;
200200
for( int dz = -1; dz <= 1; ++dz )
201201
{
202202
for( int dy = -1; dy <= 1; ++dy )
@@ -210,7 +210,7 @@ std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartit
210210
}
211211
}
212212
}
213-
return generateGraphCartPartitionning3D( nx, ny, nz, neighbor_offsets );
213+
return generateGraphCartPartitioning3D( nx, ny, nz, neighbor_offsets );
214214
}
215215

216216

src/coreComponents/mesh/graphs/GraphTools.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ namespace geos
3131
namespace graph
3232
{
3333

34-
using camp::idx_t;
35-
3634
/**
3735
* @brief Validates the graph based on the given criteria.
3836
*
@@ -45,7 +43,7 @@ using camp::idx_t;
4543
* @param adjncy The adjacency list containing the neighbors of each node.
4644
* @return True if the graph meets all criteria, false otherwise.
4745
*/
48-
bool isGraphValid( const std::vector< idx_t > & xadj, const std::vector< idx_t > & adjncy );
46+
bool isGraphValid( const stdVector< size_t > & xadj, const stdVector< size_t > & adjncy );
4947

5048
/**
5149
* @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 >
5654
* @param xadj The adjacency list offsets for each node.
5755
* @return The degree of the node.
5856
*/
59-
size_t getGraphNodeDegree( idx_t node, const std::vector< idx_t > & xadj );
57+
size_t getGraphNodeDegree( size_t node, const stdVector< size_t > & xadj );
6058

6159
/**
6260
* @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 );
6866
* @param adjncy The adjacency list containing the neighbors of each node.
6967
* @return A set of indices representing the neighbors of the node.
7068
*/
71-
std::unordered_set< idx_t > getGraphNodeNeighbors( idx_t node, const std::vector< idx_t > & xadj, const std::vector< idx_t > & adjncy );
69+
std::unordered_set< size_t > getGraphNodeNeighbors( size_t node, const stdVector< size_t > & xadj, const stdVector< size_t > & adjncy );
7270

7371

7472

@@ -81,7 +79,7 @@ std::unordered_set< idx_t > getGraphNodeNeighbors( idx_t node, const std::vector
8179
* @param num_edges Number of edges in the graph.
8280
* @return A tuple containing xadj and adjncy.
8381
*/
84-
std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphRandom( size_t num_nodes, size_t num_edges );
82+
std::tuple< stdVector< size_t >, stdVector< size_t > > generateGraphRandom( size_t num_nodes, size_t num_edges );
8583

8684
/**
8785
* @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
9492
* @param nz Number of divisions along the z-axis.
9593
* @return A tuple containing xadj and adjncy.
9694
*/
97-
std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D6( idx_t nx, idx_t ny, idx_t nz );
95+
std::tuple< stdVector< size_t >, stdVector< size_t > > generateGraphCartPartitioning3D6( size_t nx, size_t ny, size_t nz );
9896

9997
/**
10098
* @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
107105
* @param nz Number of divisions along the z-axis.
108106
* @return A tuple containing xadj and adjncy.
109107
*/
110-
std::tuple< std::vector< idx_t >, std::vector< idx_t > > generateGraphCartPartitionning3D26( idx_t nx, idx_t ny, idx_t nz );
108+
std::tuple< stdVector< size_t >, stdVector< size_t > > generateGraphCartPartitioning3D26( size_t nx, size_t ny, size_t nz );
111109

112110

113111
} // namespace geos

0 commit comments

Comments
 (0)