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

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

devel/unstructured : local mesh setup + halo exchange

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