source: codes/icosagcm/devel/src/unstructured/transfer_unstructured.F90 @ 688

Last change on this file since 688 was 688, checked in by dubos, 6 years ago

devel/unstructured : select double or single precision for physical quantities

File size: 3.9 KB
Line 
1MODULE transfer_unstructured_mod
2  USE data_unstructured_mod
3  IMPLICIT NONE
4  SAVE
5  PRIVATE
6
7#include "unstructured.h90"
8
9  INCLUDE 'mpif.h'
10
11  LOGICAL :: transfer_initialized=.FALSE.
12  PUBLIC :: update_halo
13 
14CONTAINS
15
16  SUBROUTINE init_halo_transfer(halo, rank, num, cells)
17    TYPE(Halo_transfer) :: halo
18    INTEGER :: ranks, total, rank(:), num(:), cells(:)
19    ranks=SIZE(rank)
20    total=SIZE(cells)
21    IF(total /= SUM(num) ) STOP 'init_halo_transfer : SIZE(cells)<>SUM(num)'
22    halo%ranks = ranks
23    ALLOCATE(halo%rank(ranks))
24    ALLOCATE(halo%num(ranks))
25    ALLOCATE(halo%cells(total))
26    ALLOCATE(halo%buf2(llm+1,total))
27    halo%rank=rank
28    halo%num=num
29    halo%cells=cells
30  END SUBROUTINE init_halo_transfer
31
32  SUBROUTINE init_transfer(index, &
33       send_num, send_size, send_rank, send_len, send_list, &
34       recv_num, recv_size, recv_rank, recv_len, recv_list) &
35       BIND(C, name='dynamico_init_transfer')
36    INTEGER(C_INT), VALUE :: index, send_num, send_size, recv_num, recv_size
37    INTEGER(C_INT) :: send_rank(send_num), send_len(send_num), send_list(send_size), &
38         recv_rank(recv_num), recv_len(recv_num), recv_list(recv_size)
39    PRINT *, 'init_transfer', index, &
40       send_num, send_size, '/', send_rank, '/', send_len, '/', &
41       recv_num, recv_size, '/', recv_rank, '/', recv_len, '/' 
42    CALL init_halo_transfer(send_info(index), send_rank, send_len, send_list)
43    CALL init_halo_transfer(recv_info(index), recv_rank, recv_len, recv_list)
44    transfer_initialized=.TRUE.
45  END SUBROUTINE init_transfer
46
47  !-------------------------------------------------------------------------------------------------!
48 
49  SUBROUTINE copy_in(lldata, ndata, llbuf, nbuf, cells, data, buf)
50    INTEGER :: ndata, lldata, nbuf, llbuf, cells(nbuf), i
51    NUM :: data(lldata,ndata), buf(llbuf,nbuf)
52    !$OMP DO
53    DO i=1,nbuf
54       buf(1:lldata,i) = data(1:lldata, cells(i))
55    END DO
56    !$OMP END DO
57  END SUBROUTINE copy_in
58
59  SUBROUTINE copy_out(lldata, ndata, llbuf, nbuf, cells, data, buf)
60    INTEGER :: ndata, lldata, nbuf, llbuf, cells(nbuf), i
61    NUM :: data(lldata,ndata), buf(llbuf,nbuf)
62    !$OMP DO SCHEDULE(STATIC)
63    DO i=1,nbuf
64       data(1:lldata, cells(i)) = buf(1:lldata,i) 
65    END DO
66    !$OMP END DO
67  END SUBROUTINE copy_out
68
69  SUBROUTINE update_halo(index, data)
70    INTEGER :: index ! transfer_XXX, cf data_unstructured.F90
71    NUM :: data(:,:)   
72    TYPE(Halo_transfer), POINTER :: halo
73    NUM, POINTER :: buf(:,:)
74    INTEGER :: req(send_info(index)%ranks+recv_info(index)%ranks), &
75         status(MPI_STATUS_SIZE, send_info(index)%ranks+recv_info(index)%ranks)
76    INTEGER :: llbuf, num, i, istart, ireq, ierr
77    IF(.NOT. transfer_initialized) RETURN
78    halo => send_info(index)
79    buf => halo%buf2
80    llbuf = SIZE(buf,1)
81    CALL copy_in(SIZE(data,1), SIZE(data,2), llbuf, SIZE(buf,2), halo%cells, data, buf) 
82
83    !$OMP MASTER
84    ireq=0
85    istart=1
86    DO i = 1,halo%ranks
87       num = halo%num(i)
88       ireq = ireq+1
89       call MPI_ISEND(buf(1,istart), llbuf*num, MPI_NUM, halo%rank(i), &
90            42, MPI_COMM_WORLD, req(ireq), ierr)
91       istart = istart+num
92    END DO
93    !$OMP END MASTER
94    halo => recv_info(index)
95    buf => halo%buf2
96    llbuf = SIZE(buf,1)
97    !$OMP MASTER
98    istart=1
99    DO i = 1,halo%ranks
100       num = halo%num(i)
101       ireq = ireq+1
102       call MPI_IRECV(buf(1,istart), llbuf*num, MPI_NUM, halo%rank(i), &
103            42, MPI_COMM_WORLD, req(ireq), ierr)
104       istart = istart+num
105    END DO
106    CALL MPI_WAITALL(ireq, req, status, ierr)
107    !$OMP END MASTER
108    !$OMP BARRIER
109
110    CALL copy_out(SIZE(data,1), SIZE(data,2), SIZE(buf,1), SIZE(buf,2), halo%cells, data, buf)
111  END SUBROUTINE update_halo
112
113  SUBROUTINE update_halo_c(index, lldata, ndata, data) BIND(C, name='dynamico_update_halo')
114    INTEGER, VALUE :: index, lldata, ndata
115    NUM :: data(lldata, ndata)
116    CALL update_halo(index, data)
117  END SUBROUTINE update_halo_c
118 
119END MODULE transfer_unstructured_mod
Note: See TracBrowser for help on using the repository browser.