Skip to content

Conversation

@abishekg7
Copy link
Collaborator

@abishekg7 abishekg7 commented Sep 24, 2025

This PR enables the use of MPAS atmosphere core without requiring any graph decomposition files specified as input, if the atmosphere core has been built with the Scotch graph partitioning library (built separately).

This PR supersedes #1348 to implement a Fortran interface to the PT-Scotch C library within MPAS.

Building MPAS with Scotch

Instructions to build Scotch are provided later in the description. The Scotch version must be at least v7.0.8. Once Scotch has been installed, the MPAS atmosphere core can be leveraged to use online graph partitioning by setting the path to Scotch prior to building MPAS.

export SCOTCH=/path/to/scotch/installation
make nvhpc CORE=atmosphere

If MPAS is built/linked with Scotch successfully, you should see a message stating that at the end of the build output.

Usage and run-time behavior

After building MPAS with Scotch, you can still choose whether or not to use online graph partitioning by setting appropriate values for the config_block_decomp_file_prefix namelist option.

  • If config_block_decomp_file_prefix+mpi_tasks points to a valid graph decomp file that already exists in the run directory, then it is used to proceed with the model run without invoking Scotch.

  • If config_block_decomp_file_prefix=='' or config_block_decomp_file_prefix+mpi_tasks does not match any valid graph decomp file in the run directory, then Scotch graph partitioning is invoked. During this process, the generated partition is saved as a graph decomp file to the run directory so that it may be reused in the following runs without needing to invoke Scotch again.

If MPAS has not been built with scotch, any code paths relating to Scotch will not be taken. And an incorrect specification of config_block_decomp_file_prefix+mpi_tasks should lead to the model halting.

Downloading and building Scotch

Scotch may be obtained from its gitlab repository or as tarballs from this link. The minimum Scotch version must be at least v7.0.8.

git clone https://gitlab.inria.fr/scotch/scotch.git && cd scotch 
git checkout v7.0.8

Build instructions are on this page

It can be as simple as

mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=prefix/scotch/install -DMPI_HOME=/your/mpi/path  ..
make -j5
make install

To be able to use the distributed graph partitioning provided by PT-Scotch, you will need to pass an appropriate MPI installation path during the Scotch build.

Other system pre-requisites are Bison and Flex. I have observed that an older Flex version (v2.6.1) on Eris caused the Scotch build to fail. After pulling in a more recent version of Flex v2.6.4 it seemed to build fine. Scotch documentation also references the requirement for a Bison version > 3.4.

PT-Scotch can be built with 64-bit integers or 32-bit integers. This is
determined from build-time options and the generic integer type SCOTCH_Num
covers either option. This commit replaces the type of certain integer
variables, in the MPAS interface to PT-Scotch, to use SCOTCH_Num to remain
consistent with the external library.

Note that MPAS doesn't yet support 64-bit integers, and variables of type
SCOTCH_Num are typecast into 32-bit integers in framework/mpas_block_decomp.F.
And in order for MPAS to correctly work with PT-Scotch, PT-Scotch must not be
built to use 64-bit integers.
Moving Scotch logic from mpas_block_decomp_cells_for_proc into a new subroutine
 mpas_block_decomp_scotch, in order to simplify the diff. In doing so, it also
introduces some changes to logic. If mpas_block_decomp_cells_for_proc cannot
find a suitable partition file AND the MPAS core has been built with Scotch,
then mpas_block_decomp_scotch is invoked. If successful, this writes out a
graph partition file which mpas_block_decomp_cells_for_proc then reads from
disk again.
@abishekg7 abishekg7 marked this pull request as ready for review December 29, 2025 18:11
@abishekg7 abishekg7 requested a review from mgduda December 29, 2025 18:11
use mpas_timer, only : mpas_timer_start, mpas_timer_stop
#ifdef MPAS_USE_MPI_F08
use mpi_f08, only : MPI_Comm, MPI_COMM_WORLD, MPI_INTEGER, MPI_Comm_dup, MPI_Comm_free, MPI_Gather, MPI_Gatherv
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like MPI_COMM_WORLD is needed in this use statement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

integer, dimension(:), allocatable :: local_block_list
integer, dimension(:), allocatable ::global_block_id_arr, local_block_id_arr
integer :: i, global_block_id, local_block_id, iunit, ounit, istatus, ostatus, j, k
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the -Wall flag, the gfortran compiler notes some unused variables:

mpas_block_decomp.F:375:35:

  375 |       integer :: i, global_block_id, local_block_id, iunit, ounit, istatus, ostatus, j, k
      |                                   1
Warning: Unused variable 'global_block_id' declared at (1) [-Wunused-variable]
mpas_block_decomp.F:375:74:

  375 |       integer :: i, global_block_id, local_block_id, iunit, ounit, istatus, ostatus, j, k
      |                                                                          1
Warning: Unused variable 'istatus' declared at (1) [-Wunused-variable]
mpas_block_decomp.F:375:58:

  375 |       integer :: i, global_block_id, local_block_id, iunit, ounit, istatus, ostatus, j, k
      |                                                          1
Warning: Unused variable 'iunit' declared at (1) [-Wunused-variable]
mpas_block_decomp.F:375:51:

  375 |       integer :: i, global_block_id, local_block_id, iunit, ounit, istatus, ostatus, j, k
      |                                                   1
Warning: Unused variable 'local_block_id' declared at (1) [-Wunused-variable]
mpas_block_decomp.F:371:59:

  371 |       integer, dimension(:), allocatable :: local_cell_list
      |                                                           1
Warning: Unused variable 'local_cell_list' declared at (1) [-Wunused-variable]
mpas_block_decomp.F:379:36:

  379 |       character (len=StrKIND) :: msg
      |                                    1
Warning: Unused variable 'msg' declared at (1) [-Wunused-variable]
mpas_block_decomp.F:385:54:

  385 |       doubleprecision :: scotchgraph (SCOTCH_GRAPHDIM)
      |                                                      1
Warning: Unused variable 'scotchgraph' declared at (1) [-Wunused-variable]

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch. Fixed.

{
SCOTCH_stratExit((SCOTCH_Strat *)strat_ptr);
}
#endif No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this file is missing and EOF character.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

end subroutine scotch_dgraphdata

end module mpas_ptscotch_interface
#endif No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add an EOF character to this file?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

integer(SCOTCH_NUMSIZE), intent(out) :: local_cell_list(*)

interface
subroutine scotchfdgraphdata(dgraph_ptr, cell_list) bind(C, name='scotchm_dgraphdata')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and elsewhere in this file, would it make the code easier to follow if we declared these interface names to match the C names? Or is there a reason for using interface names that differ from the names of the C routines that we're calling?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't entirely sure if that was allowed. But I've fixed this now.

endif
! Initialize the Scotch graph data structure, and an extra one to hold the re-distributed graph
#ifdef MPAS_USE_MPI_F08
call scotch_dgraphinit(scotchdgraph(1), localcomm% mpi_val)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and in other calls, it would be more in line with the rest of MPAS to pass array arguments simply using their names rather than by passing their first element.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


implicit none
! Arguments
doubleprecision, target, intent(in) :: dgraph (SCOTCH_DGRAPHDIM)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stylistically, I think it would be preferable to declare arrays using the dimension attribute. E.g.,

doubleprecision, dimension(SCOTCH_DGRAPHDIM), target, intent(in) :: dgraph

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

void scotchm_dgraphdata(void *ptr, SCOTCH_Num *cell_list)
{

int err;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The err variable doesn't appear to be used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

SCOTCH_Num *vendloctab = vertloctab_1 + 1;
SCOTCH_Num *edgeloctab = (SCOTCH_Num *)adjncy;

int i, err;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The i variable doesn't appear to be used anywhere in this function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

{
MPI_Comm comm;
MPI_Comm comm2;
int size, rank, err;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the -Wall flag, the gcc compiler reports several unused variables:

ptscotch_interface.c: In function 'scotchm_dgraphinit':
ptscotch_interface.c:37:19: warning: unused variable 'rank' [-Wunused-variable]
   37 |         int size, rank, err;
      |                   ^~~~
ptscotch_interface.c:37:13: warning: unused variable 'size' [-Wunused-variable]
   37 |         int size, rank, err;
      |             ^~~~
ptscotch_interface.c:36:18: warning: unused variable 'comm2' [-Wunused-variable]
   36 |         MPI_Comm comm2;
      |                  ^~~~~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants