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
57 integer :: total_timesteps
58 integer :: tmp_colour_2
59 integer :: tmp_cpl_comm2
60 integer :: tmp_cpl_rank
61 integer :: status(mpi_status_size)
63 print*,
'RUNNING MINIMAL_MODEL_V3'
65 call mpi_init(mpi_err)
66 if(mpi_err .eq. 0)
then
67 print*,
'mpi_init successful'
69 print*,
'mpi_init unsuccessful'
73 call mpi_comm_rank(mpi_comm_world,world_rank,mpi_err)
74 if(mpi_err .eq. 0)
then
75 print*,
'mpi_comm_rank successful'
76 print*,
'world_rank = ',world_rank
78 print*,
'mpi_comm_rank unsuccessful'
82 call mpi_comm_size(mpi_comm_world,world_size,mpi_err)
83 if(mpi_err .eq. 0)
then
84 print*,
'mpi_comm_size successful'
85 print*,
'world_size = ',world_size
87 print*,
'mpi_comm_size unsuccessful'
91 cpl_root = world_size-1
92 print*,
'rank = ',world_rank,
' on mpi_comm_world which has size '&
97 call mpi_allreduce(mdl_num_proc,i,1,mpi_integer,mpi_max&
98 &,mpi_comm_world,mpi_err)
99 if(mpi_err .eq. 0)
then
100 print*,
'mpi_allreduce successful'
103 print*,
'mpi_allreduce unsuccessful'
110 call mpi_comm_split(mpi_comm_world,da,world_rank,temp_mdls_comm&
112 if(mpi_err .eq. 0)
then
113 print*,
'mpi_comm_split successful: temp_mdls_comm created'
115 print*,
'mpi_comm_split unsuccessful: temp_mdls_comm not created'
118 call mpi_comm_size(temp_mdls_comm,temp_mdls_size,mpi_err)
119 if(mpi_err .eq. 0)
then
120 print*,
'mpi_comm_size successful'
121 print*,
'temp_mdls_size = ',temp_mdls_size
123 print*,
'mpi_comm_size unsuccessful'
127 if(mod(temp_mdls_size,mdl_num_proc) .ne. 0)
then
128 print*,
'MINIMAL MODEL LAUNCH ERROR.'
129 print*,
'MUST LAUNCH A MULTIPLE OF ',mdl_num_proc,
' copies of the &
135 nda = (world_size-temp_mdls_size)/mdl_num_proc
137 print*,
'MINIMAL MODEL COMMS v3 ERROR: nda is less than 1.'
138 print*,
'Make sure you launch with a DA CODE'
147 nens = temp_mdls_size/mdl_num_proc
148 call mpi_comm_rank(temp_mdls_comm,temp_mdls_rank,mpi_err)
149 if(mpi_err .eq. 0)
then
150 print*,
'mpi_comm_rank successful'
151 print*,
'temp_mdls_rank = ',temp_mdls_rank
153 print*,
'mpi_comm_rank unsuccessful'
157 particle_rank = temp_mdls_rank/mdl_num_proc
159 call mpi_comm_split(temp_mdls_comm,particle_rank,temp_mdls_rank&
160 &,mdl_mpi_comm,mpi_err)
161 if(mpi_err .eq. 0)
then
162 print*,
'mpi_comm_split successful: mdl_mpi_comm created'
164 print*,
'mpi_comm_split unsuccessful: mdl_mpi_comm not created'
169 call mpi_comm_rank(mdl_mpi_comm,mdl_rank,mpi_err)
170 if(mpi_err .eq. 0)
then
171 print*,
'mpi_comm_rank successful'
172 print*,
'mdl_rank = ',mdl_rank
174 print*,
'mpi_comm_rank unsuccessful'
183 cpl_root = nda*particle_rank/nens
184 print*,
'cpl_root = ',cpl_root
186 if(cpl_root .lt. 0)
then
187 print*,
'MINIMAL MODEL COMMS v3 ERROR: cpl_root is less than 0.'
188 print*,
'Make sure you launch with a DA CODE'
192 call mpi_comm_split(mpi_comm_world,cpl_root,temp_mdls_rank&
193 &,temp_cpl_comm,mpi_err)
194 if(mpi_err .eq. 0)
then
195 print*,
'mpi_comm_split successful: temp_cpl_comm created'
197 print*,
'mpi_comm_split unsuccessful: temp_cpl_comm not created'
204 call mpi_comm_rank(temp_cpl_comm,tmp_cpl_rank,mpi_err)
205 if(mpi_err .eq. 0)
then
206 print*,
'mpi_comm_rank successful: tmp_cpl_rank = ',tmp_cpl_rank
208 print*,
'mpl_comm_rank unsuccessful: tmp_cpl_rank not detected'
211 tmp_colour_2 = mod(tmp_cpl_rank,mdl_num_proc)
212 print*,
'tmp_colour_2 = ',tmp_colour_2
213 call mpi_comm_split(temp_cpl_comm,tmp_colour_2,tmp_cpl_rank&
214 &,tmp_cpl_comm2,mpi_err)
215 if(mpi_err .eq. 0)
then
216 print*,
'mpi_comm_split successful: tmp_cpl_comm2 created'
218 print*,
'mpi_comm_split unsuccessful: tmp_cpl_comm2 not created'
226 first_ptcl = -((-cpl_root)*nens/nda)
227 final_ptcl = -((-cpl_root-1)*nens/nda)-1
229 first_ptcl = ceiling(
real(cpl_root)*
real(nens)/
real(nda))
230 final_ptcl = ceiling(
real(cpl_root+1)*
real(nens)/
real(nda))-1
233 print*,
'range of particles = ',first_ptcl,final_ptcl
237 do i = first_ptcl,final_ptcl
238 print*,
'i = ',i,
' particle_rank = ',particle_rank
239 if(i .eq. particle_rank)
then
240 call mpi_comm_split(tmp_cpl_comm2,1,temp_mdls_rank&
241 &,cpl_mpi_comm,mpi_err)
242 print*,
'created cpl_mpi_comm',cpl_mpi_comm
244 print*,
'doing null splitting'
245 call mpi_comm_split(tmp_cpl_comm2,0,temp_mdls_rank&
246 &,null_mpi_comm,mpi_err)
247 print*,
'created mpi_comm_null'
248 call mpi_comm_free(null_mpi_comm,mpi_err)
249 print*,
'freed up null_mpi_comm'
263 call mpi_comm_free(temp_cpl_comm ,mpi_err)
264 call mpi_comm_free(tmp_cpl_comm2,mpi_err)
268 select case(mdl_rank)
280 print*,
'it was at this point, model realised, he fucked up'
283 allocate(state_vector(state_dim))
288 state_vector = 10*mdl_rank + (/ (
real(i,rk), i = 1,state_dim) /)
290 print*,
'state_vector = '
293 print*,
'doing a send on cpl_mpi_comm'
295 call mpi_send(state_dim,1,mpi_integer,cpl_root,1,cpl_mpi_comm&
297 print*,
'finished the send on cpl_mpi_comm'
317 print*,
'Reading total_timesteps from file timesteps: '
318 open(11,file=
'timesteps',action=
'read',status=
'old')
319 read(11,*) total_timesteps
323 call mpi_send(state_vector,state_dim,mpi_double_precision,1,1&
324 &,cpl_mpi_comm,mpi_err)
328 call mpi_recv(state_vector,state_dim,mpi_double_precision,1&
329 &,mpi_any_tag,cpl_mpi_comm,status,mpi_err)
330 print*,
'Received tag = ',status(mpi_tag)
333 do i = 1,total_timesteps
334 print*,
'Timestep = ',i
337 call mpi_send(state_vector,state_dim,mpi_double_precision,1,1&
338 &,cpl_mpi_comm,mpi_err)
341 call mpi_recv(state_vector,state_dim,mpi_double_precision,1&
342 &,mpi_any_tag,cpl_mpi_comm,status,mpi_err)
343 print*,
'Received tag = ',status(mpi_tag)
364 call mpi_finalize(mpi_err)
365 print*,
'MINIMAL_MODEL_COMMS_v3 finished nicely'