EMPIRE DA  v1.9.1
Data assimilation codes using EMPIRE communication
 All Classes Files Functions Variables Pages
minimal_model_comms_v2.f90
Go to the documentation of this file.
1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2 ! minimal_model_comms just sets up communicators for empire for
3 ! testing purposes
4 !
5 !The MIT License (MIT)
6 !
7 !Copyright (c) 2015 Philip A. Browne
8 !
9 !Permission is hereby granted, free of charge, to any person obtaining a copy
10 !of this software and associated documentation files (the "Software"), to deal
11 !in the Software without restriction, including without limitation the rights
12 !to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 !copies of the Software, and to permit persons to whom the Software is
14 !furnished to do so, subject to the following conditions:
15 !
16 !The above copyright notice and this permission notice shall be included in all
17 !copies or substantial portions of the Software.
18 !
19 !THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 !IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 !FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 !AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 !LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 !OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 !SOFTWARE.
26 !
27 !Email: p.browne@reading.ac.uk
28 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
29 
31  implicit none
32 
33  include 'mpif.h'
34  integer :: mpi_err
35  integer :: world_rank
36  integer :: world_size
37  integer, parameter :: mdl_num_proc=5
38  integer :: mdl_mpi_comm
39  integer :: temp_mdls_comm
40  integer :: temp_mdls_rank
41  integer :: mdl_rank
42  integer :: da
43  integer, parameter :: rk = kind(1.0d0)
44  real(kind=rk), allocatable, dimension(:) :: state_vector
45  integer :: state_dim
46  integer :: i
47  integer :: cpl_root
48  integer :: particle_rank
49  integer :: nda
50  integer :: nens
51  integer :: temp_mdls_size
52  integer :: temp_cpl_comm
53  integer :: first_ptcl
54  integer :: final_ptcl
55  integer :: cpl_mpi_comm
56  integer :: null_mpi_comm
57 
58  call mpi_init(mpi_err)
59  if(mpi_err .eq. 0) then
60  print*,'mpi_init successful'
61  else
62  print*,'mpi_init unsuccessful'
63  end if
64 
65 
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
70  else
71  print*,'mpi_comm_rank unsuccessful'
72  end if
73 
74 
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
79  else
80  print*,'mpi_comm_size unsuccessful'
81  end if
82 
83 
84  cpl_root = world_size-1
85  print*,'rank = ',world_rank,' on mpi_comm_world which has size ',world_size
86  da = 0
87 
88 
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'
93  print*,'i = ',i
94  else
95  print*,'mpi_allreduce unsuccessful'
96  end if
97 
98 
99 
100  call mpi_comm_split(mpi_comm_world,da,world_rank,temp_mdls_comm&
101  &,mpi_err)
102  if(mpi_err .eq. 0) then
103  print*,'mpi_comm_split successful: temp_mdls_comm created'
104  else
105  print*,'mpi_comm_split unsuccessful: temp_mdls_comm not created'
106  end if
107 
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
112  else
113  print*,'mpi_comm_size unsuccessful'
114  end if
115 
116 
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 &
120  &model'
121  stop
122  end if
123 
124 
125  nda = world_size-temp_mdls_size
126  if(nda .lt. 1) then
127  print*,'MINIMAL MODEL COMMS v2 ERROR: nda is less than 1.'
128  print*,'Make sure you launch with a DA CODE'
129  stop
130  end if
131 
132 
133 
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
139  else
140  print*,'mpi_comm_rank unsuccessful'
141  end if
142 
143 
144  particle_rank = temp_mdls_rank/mdl_num_proc
145 
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'
150  else
151  print*,'mpi_comm_split unsuccessful: mdl_mpi_comm not created'
152  end if
153 
154 
155 
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
160  else
161  print*,'mpi_comm_rank unsuccessful'
162  end if
163 
164 
165  cpl_root = nda*particle_rank/nens
166  print*,'cpl_root = ',cpl_root
167 
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'
171  stop
172  end if
173 
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'
177  else
178  print*,'mpi_comm_split unsuccessful: temp_cpl_comm not created'
179  end if
180 
181 
182 
183 
184 
185 
186  first_ptcl = -((-cpl_root)*nens/nda)
187  final_ptcl = -((-cpl_root-1)*nens/nda)-1
188 
189  first_ptcl = ceiling(real(cpl_root)*real(nens)/real(nda))
190  final_ptcl = ceiling(real(cpl_root+1)*real(nens)/real(nda))-1
191 
192 
193  print*,'range of particles = ',first_ptcl,final_ptcl
194 
195 
196 
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'
203  else
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'
210  end if
211 
212 
213  end do
214 
215  cpl_root = mdl_num_proc
216 
217 
218 
219 
220 
221 
222 
223 
224  select case(mdl_rank)
225  case(0)
226  state_dim = 1
227  case(1)
228  state_dim = 3
229  case(2)
230  state_dim = 2
231  case(3)
232  state_dim = 5
233  case(4)
234  state_dim = 1
235  case default
236  print*,'it was at this point, model realised, he fucked up'
237  stop
238  end select
239  allocate(state_vector(state_dim))
240 
241 
242 
243 
244  state_vector = 10*mdl_rank + (/ (real(i,rk), i = 1,state_dim) /)
245 
246  print*,'state_vector = '
247  print*,state_vector
248 
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'
253 
254 
255 
256 
257  call mpi_finalize(mpi_err)
258  print*,'MINIMAL_MODEL_COMMS_v2 finished nicely'
259 end program minimal_model_comms_v2
program minimal_model_comms_v2