SCALE-RM
scale_prc_cartesC.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
10 #include "scalelib.h"
12  !-----------------------------------------------------------------------------
13  !
14  !++ used modules
15  !
16  use mpi
17  use scale_precision
18  use scale_io
19  !-----------------------------------------------------------------------------
20  implicit none
21  private
22  !-----------------------------------------------------------------------------
23  !
24  !++ Public procedure
25  !
26  public :: prc_cartesc_setup
27 
28  !-----------------------------------------------------------------------------
29  !
30  !++ Public parameters & variables
31  !
32  integer, public, parameter :: prc_w = 1
33  integer, public, parameter :: prc_n = 2
34  integer, public, parameter :: prc_e = 3
35  integer, public, parameter :: prc_s = 4
36  integer, public, parameter :: prc_nw = 5
37  integer, public, parameter :: prc_ne = 6
38  integer, public, parameter :: prc_sw = 7
39  integer, public, parameter :: prc_se = 8
40 
41  integer, public :: prc_num_x = 1
42  integer, public :: prc_num_y = 1
43 
44  integer, public, allocatable :: prc_2drank(:,:)
45  integer, public :: prc_next(8) = -1
46 
47  logical, public :: prc_has_w
48  logical, public :: prc_has_n
49  logical, public :: prc_has_e
50  logical, public :: prc_has_s
51 
52  logical, public :: prc_periodic_x = .true.
53  logical, public :: prc_periodic_y = .true.
54 
55  !-----------------------------------------------------------------------------
56  !
57  !++ Private procedure
58  !
59  !-----------------------------------------------------------------------------
60  !
61  !++ Private parameters & variables
62  !
63  !-----------------------------------------------------------------------------
64 contains
65  !-----------------------------------------------------------------------------
67  subroutine prc_cartesc_setup
68  use scale_prc, only: &
69  prc_abort, &
71  prc_mpi_alive, &
82  prc_nprocs, &
83  prc_myrank, &
85  implicit none
86 
87  logical :: PRC_CART_REORDER = .false.
88 
89  namelist / param_prc_cartesc / &
90  prc_num_x, &
91  prc_num_y, &
94  prc_cart_reorder
95 
96  logical :: period (2)
97  integer :: divide (2)
98  integer :: coords_W (2)
99  integer :: coords_N (2)
100  integer :: coords_E (2)
101  integer :: coords_S (2)
102  integer :: next_coords(2)
103  integer :: iptbl
104  integer :: next(8)
105 
106  integer :: ierr
107  integer :: p
108  !---------------------------------------------------------------------------
109 
110  log_newline
111  log_info("PRC_CARTESC_setup",*) 'Setup'
112 
113  if ( io_l ) then
114  log_newline
115  log_progress(*) 'start MPI'
116  log_newline
117  log_info("PRC_CARTESC_setup",*) 'Process information '
118  log_info_cont('(1x,A,I12)') 'UNIVERSAL_COMM_WORLD : ', prc_universal_comm_world
119  log_info_cont('(1x,A,I12)') 'total process [UNIVERSAL] : ', prc_universal_nprocs
120  log_info_cont('(1x,A,I12)') 'my process ID [UNIVERSAL] : ', prc_universal_myrank
121  log_info_cont('(1x,A,L12)') 'master rank? [UNIVERSAL] : ', prc_universal_ismaster
122  log_info_cont('(1x,A,I12)') 'GLOBAL_COMM_WORLD : ', prc_global_comm_world
123  log_info_cont('(1x,A,I12)') 'total process [GLOBAL] : ', prc_global_nprocs
124  log_info_cont('(1x,A,I12)') 'my process ID [GLOBAL] : ', prc_global_myrank
125  log_info_cont('(1x,A,L12)') 'master rank? [GLOBAL] : ', prc_global_ismaster
126  log_info_cont('(1x,A,I12)') 'LOCAL_COMM_WORLD : ', prc_local_comm_world
127  log_info_cont('(1x,A,I12)') 'total process [LOCAL] : ', prc_nprocs
128  log_info_cont('(1x,A,I12)') 'my process ID [LOCAL] : ', prc_myrank
129  log_info_cont('(1x,A,L12)') 'master rank? [LOCAL] : ', prc_ismaster
130  log_info_cont('(1x,A,I12)') 'ABORT_COMM_WORLD : ', prc_abort_comm_world
131  log_info_cont('(1x,A,I12)') 'master rank ID [each world] : ', prc_masterrank
132  endif
133 
134  !--- read namelist
135  rewind(io_fid_conf)
136  read(io_fid_conf,nml=param_prc_cartesc,iostat=ierr)
137  if( ierr < 0 ) then !--- missing
138  log_info("PRC_CARTESC_setup",*) 'Not found namelist. Default used.'
139  elseif( ierr > 0 ) then !--- fatal error
140  log_error("PRC_CARTESC_setup",*) 'Not appropriate names in namelist PARAM_PRC_CARTESC. Check!'
141  call prc_abort
142  endif
143  if( io_nml ) write(io_fid_nml,nml=param_prc_cartesc)
144 
145  log_newline
146  log_info("PRC_CARTESC_setup",*) 'Process allocation '
147  log_info_cont(*) 'No. of Node :', prc_num_x," x ",prc_num_y
148 
149  if ( prc_num_x*prc_num_y /= prc_nprocs ) then
150  log_error("PRC_CARTESC_setup",*) 'total number of node does not match that requested. Check!'
151  call prc_abort
152  endif
153 
154  if ( mod(prc_nprocs,prc_num_x) /= 0 ) then
155  log_error("PRC_CARTESC_setup",*) 'number of requested node cannot devide to 2D. Check!'
156  call prc_abort
157  endif
158 
159  ! set communication topology
160  allocate( prc_2drank(-1:prc_nprocs-1,2) )
161  prc_2drank(:,:) = -1
162 
163  do p = 0, prc_nprocs-1
164  prc_2drank(p,1) = mod(p,prc_num_x)
165  prc_2drank(p,2) = (p-prc_2drank(p,1)) / prc_num_x
166  enddo
167 
168  divide(1) = prc_num_y
169  divide(2) = prc_num_x
170  period(1) = prc_periodic_y
171  period(2) = prc_periodic_x
172  if ( prc_mpi_alive ) then
173  call mpi_cart_create(prc_local_comm_world,2,divide,period,prc_cart_reorder,iptbl,ierr)
174  call mpi_cart_shift(iptbl,0,1,prc_next(prc_s),prc_next(prc_n),ierr) ! next rank search Down/Up
175  call mpi_cart_shift(iptbl,1,1,prc_next(prc_w),prc_next(prc_e),ierr) ! next rank search Left/Right
176 
177  ! get neighbor_coordinates
178  prc_has_w = prc_next(prc_w) /= mpi_proc_null
179  if( prc_has_w ) call mpi_cart_coords(iptbl,prc_next(prc_w),2,coords_w,ierr)
180  prc_has_n = prc_next(prc_n) /= mpi_proc_null
181  if( prc_has_n ) call mpi_cart_coords(iptbl,prc_next(prc_n),2,coords_n,ierr)
182  prc_has_e = prc_next(prc_e) /= mpi_proc_null
183  if( prc_has_e ) call mpi_cart_coords(iptbl,prc_next(prc_e),2,coords_e,ierr)
184  prc_has_s = prc_next(prc_s) /= mpi_proc_null
185  if( prc_has_s ) call mpi_cart_coords(iptbl,prc_next(prc_s),2,coords_s,ierr)
186  ! next rank search NorthWest
187  if ( .NOT. prc_has_n &
188  .OR. .NOT. prc_has_w ) then
189  prc_next(prc_nw) = mpi_proc_null
190  else
191  next_coords(1) = coords_n(1)
192  next_coords(2) = coords_w(2)
193  call mpi_cart_rank(iptbl, next_coords, prc_next(prc_nw), ierr)
194  endif
195  ! next rank search NorthEast
196  if ( .NOT. prc_has_n &
197  .OR. .NOT. prc_has_e ) then
198  prc_next(prc_ne) = mpi_proc_null
199  else
200  next_coords(1) = coords_n(1)
201  next_coords(2) = coords_e(2)
202  call mpi_cart_rank(iptbl, next_coords, prc_next(prc_ne), ierr)
203  endif
204  ! next rank search SouthWest
205  if ( .NOT. prc_has_s &
206  .OR. .NOT. prc_has_w ) then
207  prc_next(prc_sw) = mpi_proc_null
208  else
209  next_coords(1) = coords_s(1)
210  next_coords(2) = coords_w(2)
211  call mpi_cart_rank(iptbl, next_coords, prc_next(prc_sw), ierr)
212  endif
213  ! next rank search SouthEast
214  if ( .NOT. prc_has_s &
215  .OR. .NOT. prc_has_e ) then
216  prc_next(prc_se) = mpi_proc_null
217  else
218  next_coords(1) = coords_s(1)
219  next_coords(2) = coords_e(2)
220  call mpi_cart_rank(iptbl, next_coords, prc_next(prc_se), ierr)
221  endif
222  call mpi_comm_free(iptbl,ierr)
223  endif
224 
225  next(:) = max(prc_next(:),-1) ! avoid if MPI_PROC_NULL < -1
226 
227  log_info("PRC_CARTESC_setup",*) 'Node topology :'
228  log_info_cont('(1x,A,I5,A,I5,A,I5,A,A,I5,A,I5,A,I5,A,A,I5,A,I5,A,I5,A)') &
229  'NW(',next(prc_nw),',',prc_2drank(next(prc_nw),1),',',prc_2drank(next(prc_nw),2),')', &
230  ' - N(',next(prc_n) ,',',prc_2drank(next(prc_n) ,1),',',prc_2drank(next(prc_n) ,2),')', &
231  ' - NE(',next(prc_ne),',',prc_2drank(next(prc_ne),1),',',prc_2drank(next(prc_ne),2),')'
232  log_info_cont('(1x,A)') ' | | |'
233  log_info_cont('(1x,A,I5,A,I5,A,I5,A,A,I5,A,I5,A,I5,A,A,I5,A,I5,A,I5,A)') &
234  ' W(',next(prc_w),',',prc_2drank(next(prc_w),1),',',prc_2drank(next(prc_w),2),')', &
235  ' - P(',prc_myrank ,',',prc_2drank(prc_myrank, 1),',',prc_2drank(prc_myrank, 2),')', &
236  ' - E(',next(prc_e),',',prc_2drank(next(prc_e),1),',',prc_2drank(next(prc_e),2),')'
237  log_info_cont('(1x,A)') ' | | |'
238  log_info_cont('(1x,A,I5,A,I5,A,I5,A,A,I5,A,I5,A,I5,A,A,I5,A,I5,A,I5,A)') &
239  'SW(',next(prc_sw),',',prc_2drank(next(prc_sw),1),',',prc_2drank(next(prc_sw),2),')', &
240  ' - S(',next(prc_s) ,',',prc_2drank(next(prc_s) ,1),',',prc_2drank(next(prc_s) ,2),')', &
241  ' - SE(',next(prc_se),',',prc_2drank(next(prc_se),1),',',prc_2drank(next(prc_se),2),')'
242 
243  return
244  end subroutine prc_cartesc_setup
245 
246 end module scale_prc_cartesc
integer, public prc_universal_nprocs
process num in universal communicator
Definition: scale_prc.F90:72
integer, parameter, public prc_sw
[node direction] southwest
integer, dimension(8), public prc_next
node ID of 8 neighbour process
integer, parameter, public prc_n
[node direction] north
logical, public prc_global_ismaster
master process in global communicator?
Definition: scale_prc.F90:81
integer, public io_fid_nml
Log file ID (only for output namelist)
Definition: scale_io.F90:57
integer, public prc_global_myrank
myrank in global communicator
Definition: scale_prc.F90:79
subroutine, public prc_cartesc_setup
Setup Processor topology.
module process / cartesC
integer, public io_fid_conf
Config file ID.
Definition: scale_io.F90:55
logical, public prc_mpi_alive
MPI is alive?
Definition: scale_prc.F90:93
logical, public prc_has_s
integer, parameter, public prc_se
[node direction] southeast
logical, public prc_has_n
logical, public prc_has_e
logical, public prc_periodic_y
periodic condition or not (Y)?
integer, public prc_universal_comm_world
original communicator
Definition: scale_prc.F90:70
integer, public prc_nprocs
myrank in local communicator
Definition: scale_prc.F90:88
integer, public prc_universal_myrank
myrank in universal communicator
Definition: scale_prc.F90:71
logical, public prc_periodic_x
periodic condition or not (X)?
logical, public io_l
output log or not? (this process)
Definition: scale_io.F90:61
module PROCESS
Definition: scale_prc.F90:11
integer, parameter, public prc_w
[node direction] west
integer, parameter, public prc_masterrank
master process in each communicator
Definition: scale_prc.F90:65
integer, public prc_global_nprocs
process num in global communicator
Definition: scale_prc.F90:80
integer, public prc_myrank
process num in local communicator
Definition: scale_prc.F90:89
integer, dimension(:,:), allocatable, public prc_2drank
node index in 2D topology
subroutine, public prc_abort
Abort Process.
Definition: scale_prc.F90:338
integer, public prc_num_y
y length of 2D processor topology
integer, parameter, public prc_nw
[node direction] northwest
integer, parameter, public prc_e
[node direction] east
logical, public prc_ismaster
master process in local communicator?
Definition: scale_prc.F90:90
integer, public prc_global_comm_world
global communicator
Definition: scale_prc.F90:78
module PRECISION
integer, parameter, public prc_s
[node direction] south
logical, public prc_universal_ismaster
master process in universal communicator?
Definition: scale_prc.F90:73
integer, public prc_local_comm_world
local communicator
Definition: scale_prc.F90:87
integer, public prc_abort_comm_world
communicator for aborting
Definition: scale_prc.F90:95
logical, public io_nml
output log or not? (for namelist, this process)
Definition: scale_io.F90:62
module STDIO
Definition: scale_io.F90:10
integer, parameter, public prc_ne
[node direction] northeast
logical, public prc_has_w
integer, public prc_num_x
x length of 2D processor topology