Skip to content

Commit 913573c

Browse files
committed
Make MPI decomposition stage-independent
1 parent b504645 commit 913573c

4 files changed

Lines changed: 99 additions & 99 deletions

File tree

src/common/m_mpi_common.fpp

Lines changed: 81 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ module m_mpi_common
1717
use m_helper
1818
use ieee_arithmetic
1919
use m_nvtx
20-
use m_constants, only: recon_type_weno, format_silo
20+
use m_constants, only: recon_type_weno
2121

2222
implicit none
2323

24+
private :: s_apply_decomposition_policies
25+
2426
integer, private :: v_size
2527
$:GPU_DECLARE(create='[v_size]')
2628

@@ -1314,21 +1316,29 @@ contains
13141316
!> The purpose of this procedure is to optimally decompose the computational domain among the available processors. This is
13151317
!! performed by attempting to award each processor, in each of the coordinate directions, approximately the same number of
13161318
!! cells, and then recomputing the affected global parameters.
1317-
subroutine s_mpi_decompose_computational_domain
1319+
subroutine s_mpi_decompose_computational_domain(write_silo_ghost_offsets, adjust_local_domains, output_offsets, local_domains)
1320+
1321+
logical, intent(in) :: write_silo_ghost_offsets
1322+
logical, intent(in) :: adjust_local_domains
1323+
type(int_bounds_info), dimension(3), intent(inout), optional :: output_offsets
1324+
type(bounds_info), dimension(3), intent(inout), optional :: local_domains
13181325

13191326
#ifdef MFC_MPI
13201327
!> Non-optimal number of processors in the x-, y- and z-directions
13211328
real(wp) :: tmp_num_procs_x, tmp_num_procs_y, tmp_num_procs_z
13221329
real(wp) :: fct_min !< Processor factorization (fct) minimization parameter
13231330
integer :: MPI_COMM_CART !< Cartesian processor topology communicator
13241331
integer :: rem_cells !< Remaining cells after distribution among processors
1332+
integer :: rem_cells_by_dim(3)
13251333
integer :: recon_order !< WENO or MUSCL reconstruction order
13261334
integer :: i, j, k !< Generic loop iterators
13271335
integer :: ierr !< Generic flag used to identify and report MPI errors
13281336

13291337
! temp array to store neighbor rank coordinates
13301338
integer, dimension(1:num_dims) :: neighbor_coords
13311339

1340+
rem_cells_by_dim = 0
1341+
13321342
! Zeroing out communication needs for moving EL bubbles/particles
13331343
nidx(1)%beg = 0; nidx(1)%end = 0
13341344
nidx(2)%beg = 0; nidx(2)%end = 0
@@ -1470,6 +1480,7 @@ contains
14701480

14711481
! Number of remaining cells
14721482
rem_cells = mod(p + 1, num_procs_z)
1483+
rem_cells_by_dim(3) = rem_cells
14731484

14741485
! Optimal number of cells per processor
14751486
p = (p + 1)/num_procs_z - 1
@@ -1497,44 +1508,13 @@ contains
14971508
nidx(3)%end = 1
14981509
end if
14991510

1500-
#ifdef MFC_POST_PROCESS
1501-
! Ghost zone at the beginning
1502-
if (proc_coords(3) > 0 .and. format == format_silo) then
1503-
offset_z%beg = 2
1504-
else
1505-
offset_z%beg = 0
1506-
end if
1507-
1508-
! Ghost zone at the end
1509-
if (proc_coords(3) < num_procs_z - 1 .and. format == format_silo) then
1510-
offset_z%end = 2
1511-
else
1512-
offset_z%end = 0
1513-
end if
1514-
#endif
1515-
15161511
! Beginning and end sub-domain boundary locations
15171512
if (parallel_io) then
15181513
if (proc_coords(3) < rem_cells) then
15191514
start_idx(3) = (p + 1)*proc_coords(3)
15201515
else
15211516
start_idx(3) = (p + 1)*proc_coords(3) + rem_cells
15221517
end if
1523-
else
1524-
#ifdef MFC_PRE_PROCESS
1525-
if (old_grid .neqv. .true.) then
1526-
dz_min = (z_domain%end - z_domain%beg)/real(p_glb + 1, wp)
1527-
1528-
if (proc_coords(3) < rem_cells) then
1529-
z_domain%beg = z_domain%beg + dz_min*real((p + 1)*proc_coords(3))
1530-
z_domain%end = z_domain%end - dz_min*real((p + 1)*(num_procs_z - proc_coords(3) - 1) - (num_procs_z &
1531-
& - rem_cells))
1532-
else
1533-
z_domain%beg = z_domain%beg + dz_min*real((p + 1)*proc_coords(3) + rem_cells)
1534-
z_domain%end = z_domain%end - dz_min*real((p + 1)*(num_procs_z - proc_coords(3) - 1))
1535-
end if
1536-
end if
1537-
#endif
15381518
end if
15391519

15401520
! 2D Cartesian Processor Topology
@@ -1584,6 +1564,7 @@ contains
15841564

15851565
! Number of remaining cells
15861566
rem_cells = mod(n + 1, num_procs_y)
1567+
rem_cells_by_dim(2) = rem_cells
15871568

15881569
! Optimal number of cells per processor
15891570
n = (n + 1)/num_procs_y - 1
@@ -1611,44 +1592,13 @@ contains
16111592
nidx(2)%end = 1
16121593
end if
16131594

1614-
#ifdef MFC_POST_PROCESS
1615-
! Ghost zone at the beginning
1616-
if (proc_coords(2) > 0 .and. format == format_silo) then
1617-
offset_y%beg = 2
1618-
else
1619-
offset_y%beg = 0
1620-
end if
1621-
1622-
! Ghost zone at the end
1623-
if (proc_coords(2) < num_procs_y - 1 .and. format == format_silo) then
1624-
offset_y%end = 2
1625-
else
1626-
offset_y%end = 0
1627-
end if
1628-
#endif
1629-
16301595
! Beginning and end sub-domain boundary locations
16311596
if (parallel_io) then
16321597
if (proc_coords(2) < rem_cells) then
16331598
start_idx(2) = (n + 1)*proc_coords(2)
16341599
else
16351600
start_idx(2) = (n + 1)*proc_coords(2) + rem_cells
16361601
end if
1637-
else
1638-
#ifdef MFC_PRE_PROCESS
1639-
if (old_grid .neqv. .true.) then
1640-
dy_min = (y_domain%end - y_domain%beg)/real(n_glb + 1, wp)
1641-
1642-
if (proc_coords(2) < rem_cells) then
1643-
y_domain%beg = y_domain%beg + dy_min*real((n + 1)*proc_coords(2))
1644-
y_domain%end = y_domain%end - dy_min*real((n + 1)*(num_procs_y - proc_coords(2) - 1) - (num_procs_y &
1645-
& - rem_cells))
1646-
else
1647-
y_domain%beg = y_domain%beg + dy_min*real((n + 1)*proc_coords(2) + rem_cells)
1648-
y_domain%end = y_domain%end - dy_min*real((n + 1)*(num_procs_y - proc_coords(2) - 1))
1649-
end if
1650-
end if
1651-
#endif
16521602
end if
16531603

16541604
! 1D Cartesian Processor Topology
@@ -1667,6 +1617,7 @@ contains
16671617

16681618
! Number of remaining cells
16691619
rem_cells = mod(m + 1, num_procs_x)
1620+
rem_cells_by_dim(1) = rem_cells
16701621

16711622
! Optimal number of cells per processor
16721623
m = (m + 1)/num_procs_x - 1
@@ -1696,46 +1647,19 @@ contains
16961647
nidx(1)%end = 1
16971648
end if
16981649

1699-
#ifdef MFC_POST_PROCESS
1700-
! Ghost zone at the beginning
1701-
if (proc_coords(1) > 0 .and. format == format_silo) then
1702-
offset_x%beg = 2
1703-
else
1704-
offset_x%beg = 0
1705-
end if
1706-
1707-
! Ghost zone at the end
1708-
if (proc_coords(1) < num_procs_x - 1 .and. format == format_silo) then
1709-
offset_x%end = 2
1710-
else
1711-
offset_x%end = 0
1712-
end if
1713-
#endif
1714-
17151650
! Beginning and end sub-domain boundary locations
17161651
if (parallel_io) then
17171652
if (proc_coords(1) < rem_cells) then
17181653
start_idx(1) = (m + 1)*proc_coords(1)
17191654
else
17201655
start_idx(1) = (m + 1)*proc_coords(1) + rem_cells
17211656
end if
1722-
else
1723-
#ifdef MFC_PRE_PROCESS
1724-
if (old_grid .neqv. .true.) then
1725-
dx_min = (x_domain%end - x_domain%beg)/real(m_glb + 1, wp)
1726-
1727-
if (proc_coords(1) < rem_cells) then
1728-
x_domain%beg = x_domain%beg + dx_min*real((m + 1)*proc_coords(1))
1729-
x_domain%end = x_domain%end - dx_min*real((m + 1)*(num_procs_x - proc_coords(1) - 1) - (num_procs_x &
1730-
& - rem_cells))
1731-
else
1732-
x_domain%beg = x_domain%beg + dx_min*real((m + 1)*proc_coords(1) + rem_cells)
1733-
x_domain%end = x_domain%end - dx_min*real((m + 1)*(num_procs_x - proc_coords(1) - 1))
1734-
end if
1735-
end if
1736-
#endif
17371657
end if
17381658

1659+
call s_apply_decomposition_policies((/num_procs_x, num_procs_y, num_procs_z/), rem_cells_by_dim, (/m, n, p/), (/m_glb, &
1660+
& n_glb, p_glb/), write_silo_ghost_offsets, &
1661+
& adjust_local_domains .and. (.not. parallel_io), output_offsets, local_domains)
1662+
17391663
@:ALLOCATE(neighbor_ranks(nidx(1)%beg:nidx(1)%end, nidx(2)%beg:nidx(2)%end, nidx(3)%beg:nidx(3)%end))
17401664
do k = nidx(3)%beg, nidx(3)%end
17411665
do j = nidx(2)%beg, nidx(2)%end
@@ -1753,6 +1677,68 @@ contains
17531677

17541678
end subroutine s_mpi_decompose_computational_domain
17551679

1680+
!> Apply executable-configured output and local-domain policies after the shared Cartesian decomposition.
1681+
subroutine s_apply_decomposition_policies(proc_counts, remainders, local_cells, global_cells, write_silo_ghost_offsets, &
1682+
& adjust_local_domains, output_offsets, local_domains)
1683+
1684+
integer, dimension(3), intent(in) :: proc_counts, remainders, local_cells, global_cells
1685+
logical, intent(in) :: write_silo_ghost_offsets, adjust_local_domains
1686+
type(int_bounds_info), dimension(3), intent(inout), optional :: output_offsets
1687+
type(bounds_info), dimension(3), intent(inout), optional :: local_domains
1688+
integer :: dim
1689+
real(wp) :: domain_beg, domain_end, spacing
1690+
1691+
if (write_silo_ghost_offsets .and. .not. present(output_offsets)) then
1692+
call s_mpi_abort('Silo ghost-offset policy requires output offset storage.')
1693+
end if
1694+
if (adjust_local_domains .and. .not. present(local_domains)) then
1695+
call s_mpi_abort('Local-domain adjustment policy requires domain storage.')
1696+
end if
1697+
1698+
if (present(output_offsets)) then
1699+
do dim = 1, 3
1700+
output_offsets(dim)%beg = 0
1701+
output_offsets(dim)%end = 0
1702+
end do
1703+
1704+
if (write_silo_ghost_offsets) then
1705+
do dim = 1, num_dims
1706+
if (proc_coords(dim) > 0) output_offsets(dim)%beg = 2
1707+
if (proc_coords(dim) < proc_counts(dim) - 1) output_offsets(dim)%end = 2
1708+
end do
1709+
end if
1710+
end if
1711+
1712+
if (adjust_local_domains) then
1713+
do dim = 1, num_dims
1714+
domain_beg = local_domains(dim)%beg
1715+
domain_end = local_domains(dim)%end
1716+
spacing = (domain_end - domain_beg)/real(global_cells(dim) + 1, wp)
1717+
1718+
select case (dim)
1719+
case (1)
1720+
dx_min = spacing
1721+
case (2)
1722+
dy_min = spacing
1723+
case (3)
1724+
dz_min = spacing
1725+
end select
1726+
1727+
if (proc_coords(dim) < remainders(dim)) then
1728+
local_domains(dim)%beg = domain_beg + spacing*real((local_cells(dim) + 1)*proc_coords(dim), wp)
1729+
local_domains(dim)%end = domain_end - spacing*real((local_cells(dim) + 1)*(proc_counts(dim) - proc_coords(dim) &
1730+
& - 1) - (proc_counts(dim) - remainders(dim)), wp)
1731+
else
1732+
local_domains(dim)%beg = domain_beg + spacing*real((local_cells(dim) + 1)*proc_coords(dim) + remainders(dim), &
1733+
& wp)
1734+
local_domains(dim)%end = domain_end - spacing*real((local_cells(dim) + 1)*(proc_counts(dim) - proc_coords(dim) &
1735+
& - 1), wp)
1736+
end if
1737+
end do
1738+
end if
1739+
1740+
end subroutine s_apply_decomposition_policies
1741+
17561742
!> The goal of this procedure is to populate the buffers of the grid variables by communicating with the neighboring processors.
17571743
!! Note that only the buffers of the cell-width distributions are handled in such a way. This is because the buffers of
17581744
!! cell-boundary locations may be calculated directly from those of the cell-width distributions.

src/post_process/m_start_up.fpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module m_start_up
2626
use m_checker
2727
use m_thermochem, only: num_species, species_names
2828
use m_finite_differences
29-
use m_constants, only: model_eqns_gamma_law, model_eqns_5eq, model_eqns_6eq, model_eqns_4eq
29+
use m_constants, only: model_eqns_gamma_law, model_eqns_5eq, model_eqns_6eq, model_eqns_4eq, format_silo
3030
use m_chemistry
3131

3232
#ifdef MFC_MPI
@@ -932,6 +932,8 @@ contains
932932
!> Set up the MPI environment, read and broadcast user inputs, and decompose the computational domain.
933933
impure subroutine s_initialize_mpi_domain
934934
935+
type(int_bounds_info), dimension(3) :: output_offsets
936+
935937
num_dims = 1 + min(1, n) + min(1, p)
936938
937939
call s_mpi_initialize()
@@ -946,7 +948,12 @@ contains
946948
947949
call s_mpi_bcast_user_inputs()
948950
call s_initialize_parallel_io()
949-
call s_mpi_decompose_computational_domain()
951+
output_offsets = (/offset_x, offset_y, offset_z/)
952+
call s_mpi_decompose_computational_domain(write_silo_ghost_offsets=format == format_silo, adjust_local_domains=.false., &
953+
& output_offsets=output_offsets)
954+
offset_x = output_offsets(1)
955+
offset_y = output_offsets(2)
956+
offset_z = output_offsets(3)
950957
call s_check_inputs_fft()
951958
952959
bc = bc_xyz_info(bc_x, bc_y, bc_z)

src/pre_process/m_start_up.fpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,8 @@ contains
608608
!> Initialize MPI, read and validate user inputs on rank 0, and decompose the computational domain.
609609
impure subroutine s_initialize_mpi_domain
610610

611+
type(bounds_info), dimension(3) :: local_domains
612+
611613
call s_mpi_initialize()
612614

613615
if (proc_rank == 0) then
@@ -628,7 +630,12 @@ contains
628630
y_domain_glb = y_domain
629631
z_domain_glb = z_domain
630632
631-
call s_mpi_decompose_computational_domain()
633+
local_domains = (/x_domain, y_domain, z_domain/)
634+
call s_mpi_decompose_computational_domain(write_silo_ghost_offsets=.false., adjust_local_domains= .not. old_grid, &
635+
& local_domains=local_domains)
636+
x_domain = local_domains(1)
637+
y_domain = local_domains(2)
638+
z_domain = local_domains(3)
632639
633640
bc = bc_xyz_info(bc_x, bc_y, bc_z)
634641

src/simulation/m_start_up.fpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ contains
10181018

10191019
call s_initialize_parallel_io()
10201020

1021-
call s_mpi_decompose_computational_domain()
1021+
call s_mpi_decompose_computational_domain(write_silo_ghost_offsets=.false., adjust_local_domains=.false.)
10221022

10231023
bc = bc_xyz_info(bc_x, bc_y, bc_z)
10241024

0 commit comments

Comments
 (0)