MPI-AMRVAC 3.2
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_load_balance.t
Go to the documentation of this file.
2 implicit none
3
4contains
5 !> reallocate blocks into processors for load balance
6 subroutine load_balance
7 use mod_forest
12
13 integer :: Morton_no, recv_igrid, recv_ipe, send_igrid, send_ipe, igrid, ipe
14 !> MPI recv send variables for AMR
15 integer :: itag, irecv, isend
16 integer, dimension(:), allocatable :: recvrequest, sendrequest
17 integer, dimension(:,:), allocatable :: recvstatus, sendstatus
18 !> MPI recv send variables for staggered-variable AMR
19 integer :: itag_stg
20 integer, dimension(:), allocatable :: recvrequest_stg, sendrequest_stg
21 integer, dimension(:,:), allocatable :: recvstatus_stg, sendstatus_stg
22
23
24 ! Cost-weighted partition (Athena-style EWMA) when lb_automatic is on
25 ! AND we have at least one cycle of measurement to act on. The
26 ! get_Morton_range_costed routine itself falls back to the equal-block
27 ! partition (cost_total == 0) on the very first call.
28 if (lb_automatic .and. it > it_init) then
30 else
31 call get_morton_range()
32 end if
33
34 if (npe==1) then
36 return
37 end if
38
39 irecv=0
40 isend=0
41 allocate(recvstatus(mpi_status_size,max_blocks),recvrequest(max_blocks), &
42 sendstatus(mpi_status_size,max_blocks),sendrequest(max_blocks))
43 recvrequest=mpi_request_null
44 sendrequest=mpi_request_null
45
46 if(stagger_grid) then
47 allocate(recvstatus_stg(mpi_status_size,max_blocks*^nd),recvrequest_stg(max_blocks*^nd), &
48 sendstatus_stg(mpi_status_size,max_blocks*^nd),sendrequest_stg(max_blocks*^nd))
49 recvrequest_stg=mpi_request_null
50 sendrequest_stg=mpi_request_null
51 end if
52
53 do ipe=0,npe-1; do morton_no=morton_start(ipe),morton_stop(ipe)
54 recv_ipe=ipe
55
56 send_igrid=sfc(1,morton_no)
57 send_ipe=sfc(2,morton_no)
58
59 if (recv_ipe/=send_ipe) then
60 ! get an igrid number for the new node in recv_ipe processor
61 recv_igrid=getnode(recv_ipe)
62 ! update node igrid and ipe on the tree
63 call change_ipe_tree_leaf(recv_igrid,recv_ipe,send_igrid,send_ipe)
64 ! receive physical data of the new node in recv_ipe processor
65 if (recv_ipe==mype) call lb_recv
66 ! send physical data of the old node in send_ipe processor
67 if (send_ipe==mype) call lb_send
68 end if
69 if (recv_ipe==mype) then
70 if (recv_ipe==send_ipe) then
71 sfc_to_igrid(morton_no)=send_igrid
72 else
73 sfc_to_igrid(morton_no)=recv_igrid
74 end if
75 end if
76 end do; end do
77
78 if (irecv>0) then
79 call mpi_waitall(irecv,recvrequest,recvstatus,ierrmpi)
80 if(stagger_grid) call mpi_waitall(irecv,recvrequest_stg,recvstatus_stg,ierrmpi)
81 end if
82 if (isend>0) then
83 call mpi_waitall(isend,sendrequest,sendstatus,ierrmpi)
84 if(stagger_grid) call mpi_waitall(isend,sendrequest_stg,sendstatus_stg,ierrmpi)
85 end if
86
87 deallocate(recvstatus,recvrequest,sendstatus,sendrequest)
88 if(stagger_grid) deallocate(recvstatus_stg,recvrequest_stg,sendstatus_stg,sendrequest_stg)
89
90 ! post processing
91 do ipe=0,npe-1; do morton_no=morton_start(ipe),morton_stop(ipe)
92 recv_ipe=ipe
93
94 send_igrid=sfc(1,morton_no)
95 send_ipe=sfc(2,morton_no)
96
97 if (recv_ipe/=send_ipe) then
98 !if (send_ipe==mype) call dealloc_node(send_igrid)
99 call putnode(send_igrid,send_ipe)
100 end if
101 end do; end do
102 {#IFDEF EVOLVINGBOUNDARY
103 ! mark physical-boundary blocks on space-filling curve
104 do morton_no=morton_start(mype),morton_stop(mype)
105 igrid=sfc_to_igrid(morton_no)
106 if (phyboundblock(igrid)) sfc_phybound(morton_no)=1
107 end do
108 call mpi_allreduce(mpi_in_place,sfc_phybound,nleafs,mpi_integer,&
109 mpi_sum,icomm,ierrmpi)
110 }
111
112 ! Update sfc array: igrid and ipe info in space filling curve
113 call amr_morton_order()
114
115 contains
116
117 subroutine lb_recv
119
120 call alloc_node(recv_igrid)
121
122 itag=recv_igrid
123 irecv=irecv+1
124 {#IFDEF EVOLVINGBOUNDARY
125 if (phyboundblock(recv_igrid)) then
126 call mpi_irecv(ps(recv_igrid)%w,1,type_block,send_ipe,itag, &
127 icomm,recvrequest(irecv),ierrmpi)
128 else
129 call mpi_irecv(ps(recv_igrid)%w,1,type_block_io,send_ipe,itag, &
130 icomm,recvrequest(irecv),ierrmpi)
131 end if
132 }{#IFNDEF EVOLVINGBOUNDARY
133 call mpi_irecv(ps(recv_igrid)%w,1,type_block_io,send_ipe,itag, &
134 icomm,recvrequest(irecv),ierrmpi)
135 }
136 if(stagger_grid) then
137 itag=recv_igrid+max_blocks
138 call mpi_irecv(ps(recv_igrid)%ws,1,type_block_io_stg,send_ipe,itag, &
139 icomm,recvrequest_stg(irecv),ierrmpi)
140 end if
141
142 end subroutine lb_recv
143
144 subroutine lb_send
145
146 itag=recv_igrid
147 isend=isend+1
148 {#IFDEF EVOLVINGBOUNDARY
149 if (phyboundblock(send_igrid)) then
150 call mpi_isend(ps(send_igrid)%w,1,type_block,recv_ipe,itag, &
151 icomm,sendrequest(isend),ierrmpi)
152 else
153 call mpi_isend(ps(send_igrid)%w,1,type_block_io,recv_ipe,itag, &
154 icomm,sendrequest(isend),ierrmpi)
155 end if
156 }{#IFNDEF EVOLVINGBOUNDARY
157 call mpi_isend(ps(send_igrid)%w,1,type_block_io,recv_ipe,itag, &
158 icomm,sendrequest(isend),ierrmpi)
159 }
160 if(stagger_grid) then
161 itag=recv_igrid+max_blocks
162 call mpi_isend(ps(send_igrid)%ws,1,type_block_io_stg,recv_ipe,itag, &
163 icomm,sendrequest_stg(isend),ierrmpi)
164 end if
165
166 end subroutine lb_send
167
168 end subroutine load_balance
169
170end module mod_load_balance
subroutine lb_recv
subroutine, public putnode(igrid, ipe)
subroutine, public alloc_node(igrid)
allocate arrays on igrid node
integer function, public getnode(ipe)
Get first available igrid on processor ipe.
Module with basic grid data structures.
Definition mod_forest.t:2
integer, dimension(:), allocatable, save sfc_to_igrid
Go from a Morton number to an igrid index (for a single processor)
Definition mod_forest.t:53
integer, dimension(:), allocatable, save morton_start
First Morton number per processor.
Definition mod_forest.t:62
integer, dimension(:), allocatable, save morton_stop
Last Morton number per processor.
Definition mod_forest.t:65
integer, dimension(:,:), allocatable, save sfc
Array to go from a Morton number to an igrid and processor index. Sfc(1:3, MN) contains [igrid,...
Definition mod_forest.t:43
subroutine, public change_ipe_tree_leaf(recv_igrid, recv_ipe, send_igrid, send_ipe)
This module contains definitions of global parameters and variables and some generic functions/subrou...
integer it
Number of time steps taken.
integer it_init
initial iteration count
logical stagger_grid
True for using stagger grid.
integer mype
The rank of the current MPI task.
integer npe
The number of MPI tasks.
logical lb_automatic
Cost-weighted automatic load balancer toggle (off by default). When .true., the SFC partitioner cuts ...
integer max_blocks
The maximum number of grid blocks in a processor.
subroutine load_balance
reallocate blocks into processors for load balance
subroutine get_morton_range_costed
Cost-weighted SFC partition. Reduces the per-rank block_cost array into a global Morton-indexed cost,...
subroutine get_morton_range
Set the Morton range for each processor.