55 const char*
const DEFAULT_READ_OPTS =
"PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS";
60 std::cout <<
"Usage: mpiexec -np <num_procs> " << program_name <<
" [meshfile] [num_communicators]\n"
63 <<
"\n num_communicators - Number of MPI communicator groups to create (default: 1)\n";
67 void print_entity_stats(
const std::vector< int >& counts,
int nprocs,
const std::string& title =
"" )
71 std::cout <<
"\n" << title <<
":\n";
74 for(
int i = 0; i < nprocs; ++i )
76 std::cout <<
" Shared, owned entities on proc " << i <<
": " << counts[4 * i] <<
" verts, "
77 << counts[4 * i + 1] <<
" edges, " << counts[4 * i + 2] <<
" faces, " << counts[4 * i + 3]
83 int main(
int argc,
char** argv )
86 int mpi_initialized = 0;
87 MPI_Initialized( &mpi_initialized );
88 if( !mpi_initialized )
90 MPI_Init( &argc, &argv );
93 int global_rank = 0, global_size = 1;
94 MPI_Comm_rank( MPI_COMM_WORLD, &global_rank );
95 MPI_Comm_size( MPI_COMM_WORLD, &global_size );
103 if( argc > 1 && ( std::string( argv[1] ) ==
"-h" || std::string( argv[1] ) ==
"--help" ) )
117 num_comms = std::atoi( argv[2] );
120 if( global_rank == 0 )
122 std::cerr <<
"Error: Number of communicators must be at least 1\n";
131 auto moab = std::make_unique< Core >();
134 std::cerr <<
"Error: Failed to create MOAB instance\n";
135 MPI_Abort( MPI_COMM_WORLD, 1 );
140 int color = global_rank % num_comms;
145 MPI_Comm_split( MPI_COMM_WORLD, color, global_rank, &comm );
150 comm = MPI_COMM_WORLD;
154 int local_rank = 0, local_size = 1;
155 MPI_Comm_rank( comm, &local_rank );
156 MPI_Comm_size( comm, &local_size );
159 if( global_rank == 0 )
161 std::cout <<
"\n=== MOAB Parallel Hello World ===\n"
162 <<
"Global processes: " << global_size <<
"\n"
163 <<
"Number of communicator groups: " << num_comms <<
"\n"
164 <<
"Processes per group: ~" << ( global_size + num_comms - 1 ) / num_comms <<
"\n"
165 <<
"Reading file: " << mesh_file <<
"\n"
170 if( global_rank == 0 )
172 std::cout <<
"Loading mesh file..." << std::endl;
182 auto pcomm = std::auto_ptr< moab::ParallelComm >( ParallelComm::get_pcomm(
moab.get(), partnset, &comm ) );
185 "Failed to load mesh file: " << mesh_file );
192 Range shared_sets, shared_ents, owned_entities;
199 MB_CHK_SET_ERR( pcomm->get_shared_sets( shared_sets ),
"Failed to get shared sets" );
201 shared_sets.
print(
"Shared sets: " );
204 for(
int dim = 0; dim < 4; ++dim )
206 MB_CHK_SET_ERR( pcomm->get_part_entities( shared_ents, dim ),
"Failed to get shared entities" );
207 shared_ents.
print(
"Shared entities: " );
217 "Failed to filter owned entities" );
219 shared_ents.
print(
"Owned entities: " );
222 unsigned int entity_counts[4] = { 0 };
223 for(
int dim = 0; dim < 4; ++dim )
225 entity_counts[dim] =
static_cast< unsigned int >( owned_entities.
num_of_dimension( dim ) );
229 std::vector< int > recv_buffer( local_size * 4, 0 );
230 MPI_Gather( entity_counts, 4, MPI_INT, recv_buffer.data(), 4, MPI_INT, 0, comm );
233 if( local_rank == 0 )
235 std::cout <<
"\n=== Initial Shared Entity Statistics (Group " << color <<
") ===\n";
236 print_entity_stats( std::vector< int >( entity_counts, entity_counts + 4 ), local_size );
241 if( global_rank == 0 ) std::cout <<
"\nExchanging ghost elements..." << std::endl;
243 pcomm->exchange_ghost_cells( 3,
249 "Failed to exchange ghost cells" );
253 owned_entities.
clear();
256 "Failed to get shared entities after ghost exchange" );
259 "Failed to filter owned entities after ghost exchange" );
262 for(
int dim = 0; dim < 4; ++dim )
264 entity_counts[dim] =
static_cast< unsigned int >( owned_entities.
num_of_dimension( dim ) );
268 MPI_Gather( entity_counts, 4, MPI_INT, recv_buffer.data(), 4, MPI_INT, 0, comm );
271 if( local_rank == 0 )
273 std::cout <<
"\n=== Final Shared Entity Statistics After Ghost Exchange (Group " << color <<
") ===\n";
275 std::cout <<
"\n=== Parallel Example Completed Successfully ===\n\n";
281 MPI_Comm_free( &comm );
289 if( !mpi_initialized )
296 catch(
const std::exception& e )
298 std::cerr <<
"Error on rank " << global_rank <<
": " << e.what() << std::endl;
299 MPI_Abort( MPI_COMM_WORLD, 1 );
304 std::cerr <<
"Unknown error occurred on rank " << global_rank << std::endl;
305 MPI_Abort( MPI_COMM_WORLD, 1 );