37 integer,
parameter :: mdl_num_proc=5
38 integer :: mdl_mpi_comm
39 integer :: temp_mdls_comm
40 integer :: temp_mdls_rank
43 integer,
parameter :: rk = kind(1.0d0)
44 real(kind=rk),
allocatable,
dimension(:) :: state_vector
48 integer :: particle_rank
51 integer :: temp_mdls_size
52 integer :: temp_cpl_comm
55 integer :: cpl_mpi_comm
56 integer :: null_mpi_comm
58 call mpi_init(mpi_err)
59 if(mpi_err .eq. 0)
then
60 print*,
'mpi_init successful'
62 print*,
'mpi_init unsuccessful'
66 call mpi_comm_rank(mpi_comm_world,world_rank,mpi_err)
67 if(mpi_err .eq. 0)
then
68 print*,
'mpi_comm_rank successful'
69 print*,
'world_rank = ',world_rank
71 print*,
'mpi_comm_rank unsuccessful'
75 call mpi_comm_size(mpi_comm_world,world_size,mpi_err)
76 if(mpi_err .eq. 0)
then
77 print*,
'mpi_comm_size successful'
78 print*,
'world_size = ',world_size
80 print*,
'mpi_comm_size unsuccessful'
84 cpl_root = world_size-1
85 print*,
'rank = ',world_rank,
' on mpi_comm_world which has size ',world_size
89 call mpi_allreduce(mdl_num_proc,i,1,mpi_integer,mpi_max&
90 &,mpi_comm_world,mpi_err)
91 if(mpi_err .eq. 0)
then
92 print*,
'mpi_allreduce successful'
95 print*,
'mpi_allreduce unsuccessful'
100 call mpi_comm_split(mpi_comm_world,da,world_rank,temp_mdls_comm&
102 if(mpi_err .eq. 0)
then
103 print*,
'mpi_comm_split successful: temp_mdls_comm created'
105 print*,
'mpi_comm_split unsuccessful: temp_mdls_comm not created'
108 call mpi_comm_size(temp_mdls_comm,temp_mdls_size,mpi_err)
109 if(mpi_err .eq. 0)
then
110 print*,
'mpi_comm_size successful'
111 print*,
'temp_mdls_size = ',temp_mdls_size
113 print*,
'mpi_comm_size unsuccessful'
117 if(mod(temp_mdls_size,mdl_num_proc) .ne. 0)
then
118 print*,
'MINIMAL MODEL LAUNCH ERROR.'
119 print*,
'MUST LAUNCH A MULTIPLE OF ',mdl_num_proc,
' copies of the &
125 nda = world_size-temp_mdls_size
127 print*,
'MINIMAL MODEL COMMS v2 ERROR: nda is less than 1.'
128 print*,
'Make sure you launch with a DA CODE'
134 nens = temp_mdls_size/mdl_num_proc
135 call mpi_comm_rank(temp_mdls_comm,temp_mdls_rank,mpi_err)
136 if(mpi_err .eq. 0)
then
137 print*,
'mpi_comm_rank successful'
138 print*,
'temp_mdls_rank = ',temp_mdls_rank
140 print*,
'mpi_comm_rank unsuccessful'
144 particle_rank = temp_mdls_rank/mdl_num_proc
146 call mpi_comm_split(temp_mdls_comm,particle_rank,temp_mdls_rank&
147 &,mdl_mpi_comm,mpi_err)
148 if(mpi_err .eq. 0)
then
149 print*,
'mpi_comm_split successful: mdl_mpi_comm created'
151 print*,
'mpi_comm_split unsuccessful: mdl_mpi_comm not created'
156 call mpi_comm_rank(mdl_mpi_comm,mdl_rank,mpi_err)
157 if(mpi_err .eq. 0)
then
158 print*,
'mpi_comm_rank successful'
159 print*,
'mdl_rank = ',mdl_rank
161 print*,
'mpi_comm_rank unsuccessful'
165 cpl_root = nda*particle_rank/nens
166 print*,
'cpl_root = ',cpl_root
168 if(cpl_root .lt. 0)
then
169 print*,
'MINIMAL MODEL COMMS v2 ERROR: cpl_root is less than 0.'
170 print*,
'Make sure you launch with a DA CODE'
174 call mpi_comm_split(mpi_comm_world,cpl_root,temp_mdls_rank,temp_cpl_comm,mpi_err)
175 if(mpi_err .eq. 0)
then
176 print*,
'mpi_comm_split successful: temp_cpl_comm created'
178 print*,
'mpi_comm_split unsuccessful: temp_cpl_comm not created'
186 first_ptcl = -((-cpl_root)*nens/nda)
187 final_ptcl = -((-cpl_root-1)*nens/nda)-1
189 first_ptcl = ceiling(
real(cpl_root)*
real(nens)/
real(nda))
190 final_ptcl = ceiling(
real(cpl_root+1)*
real(nens)/
real(nda))-1
193 print*,
'range of particles = ',first_ptcl,final_ptcl
197 do i = first_ptcl,final_ptcl
198 print*,
'i = ',i,
' particle_rank = ',particle_rank
199 if(i .eq. particle_rank)
then
200 call mpi_comm_split(temp_cpl_comm,1,temp_mdls_rank&
201 &,cpl_mpi_comm,mpi_err)
202 print*,
'created cpl_mpi_comm'
204 print*,
'doing null splitting'
205 call mpi_comm_split(temp_cpl_comm,0,temp_mdls_rank&
206 &,null_mpi_comm,mpi_err)
207 print*,
'created mpi_comm_null'
208 call mpi_comm_free(null_mpi_comm,mpi_err)
209 print*,
'freed up null_mpi_comm'
215 cpl_root = mdl_num_proc
224 select case(mdl_rank)
236 print*,
'it was at this point, model realised, he fucked up'
239 allocate(state_vector(state_dim))
244 state_vector = 10*mdl_rank + (/ (
real(i,rk), i = 1,state_dim) /)
246 print*,
'state_vector = '
249 print*,
'doing a gather on cpl_mpi_comm'
250 call mpi_gather(state_dim,1,mpi_integer,state_dim&
251 &,1,mpi_integer,cpl_root,cpl_mpi_comm,mpi_err)
252 print*,
'finished the gather on cpl_mpi_comm'
257 call mpi_finalize(mpi_err)
258 print*,
'MINIMAL_MODEL_COMMS_v2 finished nicely'
program minimal_model_comms_v2