7 INTEGER,
PARAMETER :: halo_max=3
9 LOGICAL,
SAVE :: using_mpi
10 LOGICAL,
SAVE :: using_omp
12 integer,
save :: mpi_size
13 integer,
save :: mpi_rank
14 integer,
save :: jj_begin
15 integer,
save :: jj_end
16 integer,
save :: jj_nb
17 integer,
save :: ij_begin
18 integer,
save :: ij_end
19 logical,
save :: pole_nord
20 logical,
save :: pole_sud
24 integer,
save :: jjnb_u
27 integer,
save :: jjnb_v
31 integer,
save :: ijnb_u
35 integer,
save :: ijnb_v
38 integer,
allocatable,
save,
dimension(:) :: jj_begin_para
39 integer,
allocatable,
save,
dimension(:) :: jj_end_para
40 integer,
allocatable,
save,
dimension(:) :: jj_nb_para
41 integer,
save :: OMP_CHUNK
42 integer,
save :: omp_rank
43 integer,
save :: omp_size
69 integer,
pointer :: jj_begin_para(:) => NULL()
70 integer,
pointer :: jj_end_para(:) => NULL()
71 integer,
pointer :: jj_nb_para(:) => NULL()
74 INTERFACE assignment (=)
87 #include "dimensions.h"
94 integer,
dimension(3) :: blocklen,type
96 character(len=4) :: num
97 character(len=20) :: filename
100 INTEGER :: omp_get_num_threads
101 EXTERNAL omp_get_num_threads
102 INTEGER :: omp_get_thread_num
103 EXTERNAL omp_get_thread_num
123 call mpi_comm_size(comm_lmdz,mpi_size,ierr)
124 call mpi_comm_rank(comm_lmdz,mpi_rank,ierr)
134 WRITE(num,
'(I4.4)') mpi_rank
135 filename=
'lmdz.out_'//num
136 IF (mpi_rank .NE. 0)
THEN
137 OPEN(
unit=
lunout,file=trim(filename),action=
'write', &
138 status=
'unknown',form=
'formatted',iostat=ierr)
143 allocate(jj_begin_para(0:mpi_size-1))
144 allocate(jj_end_para(0:mpi_size-1))
145 allocate(jj_nb_para(0:mpi_size-1))
148 jj_nb_para(
i)=(jjm+1)/mpi_size
149 if (
i < mod((jjm+1),mpi_size) ) jj_nb_para(
i)=jj_nb_para(
i)+1
151 if (jj_nb_para(
i) <= 2 )
then
153 write(
lunout,*)
"Arret : le nombre de bande de lattitude par process est trop faible (<2)."
154 write(
lunout,*)
" ---> diminuez le nombre de CPU ou augmentez la taille en lattitude"
157 IF (using_mpi) call mpi_abort(comm_lmdz,-1, ierr)
173 jj_end_para(
i)=
j+jj_nb_para(
i)-1
178 jj_begin = jj_begin_para(mpi_rank)
179 jj_end = jj_end_para(mpi_rank)
180 jj_nb = jj_nb_para(mpi_rank)
182 ij_begin=(jj_begin-1)*iip1+1
185 if (mpi_rank.eq.0)
then
191 if (mpi_rank.eq.mpi_size-1)
then
197 write(
lunout,*)
"init_parallel: jj_begin",jj_begin
198 write(
lunout,*)
"init_parallel: jj_end",jj_end
199 write(
lunout,*)
"init_parallel: ij_begin",ij_begin
200 write(
lunout,*)
"init_parallel: ij_end",ij_end
201 jjb_u=max(jj_begin-halo_max,1)
202 jje_u=min(jj_end+halo_max,
jjp1)
205 jjb_v=max(jj_begin-halo_max,1)
206 jje_v=min(jj_end+halo_max,jjm)
209 ijb_u=max(ij_begin-halo_max*iip1,1)
210 ije_u=min(ij_end+halo_max*iip1,
ip1jmp1)
213 ijb_v=max(ij_begin-halo_max*iip1,1)
214 ije_v=min(ij_end+halo_max*iip1,
ip1jm)
221 omp_size=omp_get_num_threads()
223 omp_rank=omp_get_thread_num()
235 include
"dimensions.h"
238 INTEGER,
INTENT(IN) :: jj_nb_new(0:mpi_size-1)
239 TYPE(distrib),
INTENT(INOUT) :: d
242 IF (.NOT.
ASSOCIATED(d%jj_nb_para))
ALLOCATE(d%jj_nb_para(0:mpi_size-1))
243 IF (.NOT.
ASSOCIATED(d%jj_begin_para))
ALLOCATE(d%jj_begin_para(0:mpi_size-1))
244 IF (.NOT.
ASSOCIATED(d%jj_end_para))
ALLOCATE(d%jj_end_para(0:mpi_size-1))
246 d%jj_Nb_Para=jj_nb_new
249 d%jj_end_para(0)=d%jj_Nb_Para(0)
253 d%jj_begin_para(
i)=d%jj_end_para(
i-1)+1
254 d%jj_end_para(
i)=d%jj_begin_para(
i)+d%jj_Nb_para(
i)-1
258 d%jj_begin = d%jj_begin_para(mpi_rank)
259 d%jj_end = d%jj_end_para(mpi_rank)
260 d%jj_nb = d%jj_nb_para(mpi_rank)
262 d%ij_begin=(d%jj_begin-1)*iip1+1
263 d%ij_end=d%jj_end*iip1
265 d%jjb_u=max(d%jj_begin-halo_max,1)
266 d%jje_u=min(d%jj_end+halo_max,
jjp1)
267 d%jjnb_u=d%jje_u-d%jjb_u+1
269 d%jjb_v=max(d%jj_begin-halo_max,1)
270 d%jje_v=min(d%jj_end+halo_max,jjm)
271 d%jjnb_v=d%jje_v-d%jjb_v+1
273 d%ijb_u=max(d%ij_begin-halo_max*iip1,1)
274 d%ije_u=min(d%ij_end+halo_max*iip1,
ip1jmp1)
275 d%ijnb_u=d%ije_u-d%ijb_u+1
277 d%ijb_v=max(d%ij_begin-halo_max*iip1,1)
278 d%ije_v=min(d%ij_end+halo_max*iip1,
ip1jm)
279 d%ijnb_v=d%ije_v-d%ijb_v+1
287 include
"dimensions.h"
291 jj_begin = d%jj_begin
294 ij_begin = d%ij_begin
313 jj_begin_para(:) = d%jj_begin_para(:)
314 jj_end_para(:) = d%jj_end_para(:)
315 jj_nb_para(:) = d%jj_nb_para(:)
323 include
"dimensions.h"
325 TYPE(distrib),
INTENT(INOUT) :: dist
326 TYPE(distrib),
INTENT(IN) :: new_dist
328 dist%jj_begin = new_dist%jj_begin
329 dist%jj_end = new_dist%jj_end
330 dist%jj_nb = new_dist%jj_nb
331 dist%ij_begin = new_dist%ij_begin
332 dist%ij_end = new_dist%ij_end
334 dist%jjb_u = new_dist%jjb_u
335 dist%jje_u = new_dist%jje_u
336 dist%jjnb_u = new_dist%jjnb_u
337 dist%jjb_v = new_dist%jjb_v
338 dist%jje_v = new_dist%jje_v
339 dist%jjnb_v = new_dist%jjnb_v
341 dist%ijb_u = new_dist%ijb_u
342 dist%ije_u = new_dist%ije_u
343 dist%ijnb_u = new_dist%ijnb_u
345 dist%ijb_v = new_dist%ijb_v
346 dist%ije_v = new_dist%ije_v
347 dist%ijnb_v = new_dist%ijnb_v
350 dist%jj_begin_para(:) = new_dist%jj_begin_para(:)
351 dist%jj_end_para(:) = new_dist%jj_end_para(:)
352 dist%jj_nb_para(:) = new_dist%jj_nb_para(:)
360 include
"dimensions.h"
379 character(len=6),
parameter :: type_ocean=
"dummy"
383 include
"dimensions.h"
392 if (
allocated(jj_begin_para))
deallocate(jj_begin_para)
393 if (
allocated(jj_end_para))
deallocate(jj_end_para)
394 if (
allocated(jj_nb_para))
deallocate(jj_nb_para)
396 if (type_ocean ==
'couple')
then
398 call prism_terminate_proto(ierr)
399 IF (ierr .ne. prism_ok)
THEN
400 call
abort_gcm(
'Finalize_parallel',
' Probleme dans prism_terminate_proto ',1)
405 IF (using_mpi) call mpi_finalize(ierr)
414 #include "dimensions.h"
417 integer,
intent(in) ::
ij,
ll,row
418 real,
dimension(ij,ll),
intent(in) ::field
419 real,
dimension(ll*iip1*row),
intent(out) :: buffer
428 buffer(pos)=field(
i,
l)
437 #include "dimensions.h"
440 integer,
intent(in) ::
ij,
ll,row
441 real,
dimension(ij,ll),
intent(out) ::field
442 real,
dimension(ll*iip1*row),
intent(in) :: buffer
452 field(
i,
l)=buffer(pos)
468 IF (using_mpi) CALL mpi_barrier(comm_lmdz,ierr)
478 #include "dimensions.h"
484 REAL,
dimension(ij,ll) :: field
488 LOGICAL :: sendup,senddown
489 LOGICAL :: recvup,recvdown
490 INTEGER,
DIMENSION(4) ::
request
492 INTEGER,
DIMENSION(MPI_STATUS_SIZE,4) :: status
494 INTEGER,
DIMENSION(1,4) :: status
497 REAL,
dimension(:),
allocatable :: buffer_send_up,buffer_send_down
498 REAL,
dimension(:),
allocatable :: buffer_recv_up,buffer_recv_down
499 INTEGER :: buffer_size
535 nbrequest=nbrequest+1
536 buffer_size=down*iip1*
ll
537 allocate(buffer_send_up(buffer_size))
541 call mpi_issend(buffer_send_up,buffer_size,mpi_real8,mpi_rank-1,1, &
542 comm_lmdz,
request(nbrequest),ierr)
548 nbrequest=nbrequest+1
550 buffer_size=up*iip1*
ll
551 allocate(buffer_send_down(buffer_size))
552 call
pack_data(field(ij_end+1-up*iip1,1),
ij,
ll,up,buffer_send_down)
556 call mpi_issend(buffer_send_down,buffer_size,mpi_real8,mpi_rank+1,1, &
557 comm_lmdz,
request(nbrequest),ierr)
564 nbrequest=nbrequest+1
565 buffer_size=up*iip1*
ll
566 allocate(buffer_recv_up(buffer_size))
570 call mpi_irecv(buffer_recv_up,buffer_size,mpi_real8,mpi_rank-1,1, &
571 comm_lmdz,
request(nbrequest),ierr)
579 nbrequest=nbrequest+1
580 buffer_size=down*iip1*
ll
581 allocate(buffer_recv_down(buffer_size))
585 call mpi_irecv(buffer_recv_down,buffer_size,mpi_real8,mpi_rank+1,1, &
586 comm_lmdz,
request(nbrequest),ierr)
593 if (nbrequest > 0) call mpi_waitall(nbrequest,
request,status,ierr)
595 IF (recvup) call
unpack_data(field(ij_begin-up*iip1,1),
ij,
ll,up,buffer_recv_up)
596 IF (recvdown) call
unpack_data(field(ij_end+1,1),
ij,
ll,down,buffer_recv_down)
610 #include "dimensions.h"
612 #include "iniprint.h"
616 INTEGER ::
ij,
ll,rank
617 REAL,
dimension(ij,ll) :: field
618 REAL,
dimension(:),
allocatable :: buffer_send
619 REAL,
dimension(:),
allocatable :: buffer_recv
620 INTEGER,
dimension(0:MPI_Size-1) :: recv_count, displ
627 allocate(buffer_send(iip1*
ll*(jj_end-jj_begin+1)))
628 call
pack_data(field(ij_begin,1),
ij,
ll,jj_end-jj_begin+1,buffer_send)
630 allocate(buffer_send(iip1*
ll*(min(jj_end,jjm)-jj_begin+1)))
631 call
pack_data(field(ij_begin,1),
ij,
ll,min(jj_end,jjm)-jj_begin+1,buffer_send)
634 stop
'erreur dans Gather_Field'
637 if (mpi_rank==rank)
then
638 allocate(buffer_recv(
ij*
ll))
644 recv_count(
i)=(jj_end_para(
i)-jj_begin_para(
i)+1)*
ll*iip1
646 recv_count(
i)=(min(jj_end_para(
i),jjm)-jj_begin_para(
i)+1)*
ll*iip1
648 stop
'erreur dans Gather_Field'
654 displ(
i)=displ(
i-1)+recv_count(
i-1)
663 allocate(buffer_recv(1))
668 call mpi_gatherv(buffer_send,(min(ij_end,
ij)-ij_begin+1)*
ll,mpi_real8, &
669 buffer_recv,recv_count,displ,mpi_real8,rank,comm_lmdz,ierr)
673 if (mpi_rank==rank)
then
678 jj_end_para(
i)-jj_begin_para(
i)+1,buffer_recv(displ(
i)+1))
683 min(jj_end_para(
i),jjm)-jj_begin_para(
i)+1,buffer_recv(displ(
i)+1))
694 #include "dimensions.h"
700 REAL,
dimension(ij,ll) :: field
707 call mpi_bcast(field,
ij*
ll,mpi_real8,0,comm_lmdz,ierr)
716 #include "dimensions.h"
722 REAL,
dimension(ij,ll) :: field
730 call mpi_bcast(field,
ij*
ll,mpi_real8,rank,comm_lmdz,ierr)