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