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