FMS  2026.01.01-dev
Flexible Modeling System
mpp_transmit.inc
1 ! -*-f90-*-
2 
3 !***********************************************************************
4 !* Apache License 2.0
5 !*
6 !* This file is part of the GFDL Flexible Modeling System (FMS).
7 !*
8 !* Licensed under the Apache License, Version 2.0 (the "License");
9 !* you may not use this file except in compliance with the License.
10 !* You may obtain a copy of the License at
11 !*
12 !* http://www.apache.org/licenses/LICENSE-2.0
13 !*
14 !* FMS is distributed in the hope that it will be useful, but WITHOUT
15 !* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied;
16 !* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
17 !* PARTICULAR PURPOSE. See the License for the specific language
18 !* governing permissions and limitations under the License.
19 !***********************************************************************
20 !> @file
21 !> @brief Routines for data transmission between PE's
22 
23 !> @addtogroup mpp_mod
24 !> @{
25 
26 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27 ! !
28 ! MPP_TRANSMIT !
29 ! !
30 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
31 
32  subroutine mpp_transmit_scalar_( put_data, to_pe, get_data, from_pe, plen, glen, block, tag, &
33  recv_request, send_request)
34  integer, intent(in) :: to_pe, from_pe
35  mpp_type_, intent(in) :: put_data
36  mpp_type_, intent(out) :: get_data
37  integer, optional, intent(in) :: plen, glen
38  logical, intent(in), optional :: block
39  integer, intent(in), optional :: tag
40  type(mpi_request), intent(out), optional :: recv_request, send_request
41  integer :: put_len, get_len
42  mpp_type_ :: put_data1d(1), get_data1d(1)
43  pointer( ptrp, put_data1d )
44  pointer( ptrg, get_data1d )
45 
46  get_data = mpp_type_init_value
47 
48  ptrp = loc(put_data)
49  ptrg = loc(get_data)
50  put_len=1; if(PRESENT(plen))put_len=plen
51  get_len=1; if(PRESENT(glen))get_len=glen
52  call mpp_transmit_ ( put_data1d, put_len, to_pe, get_data1d, get_len, from_pe, block, tag, &
53  recv_request=recv_request, send_request=send_request )
54 
55  return
56  end subroutine mpp_transmit_scalar_
57 
58  subroutine mpp_transmit_2d_( put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, &
59  recv_request, send_request )
60  integer, intent(in) :: put_len, to_pe, get_len, from_pe
61  mpp_type_, intent(in) :: put_data(:,:)
62  mpp_type_, intent(out) :: get_data(:,:)
63  logical, intent(in), optional :: block
64  integer, intent(in), optional :: tag
65  type(mpi_request), intent(out), optional :: recv_request, send_request
66  mpp_type_ :: put_data1d(put_len), get_data1d(get_len)
67 
68  pointer( ptrp, put_data1d )
69  pointer( ptrg, get_data1d )
70  get_data = mpp_type_init_value
71 
72  ptrp = loc(put_data)
73  ptrg = loc(get_data)
74  call mpp_transmit( put_data1d, put_len, to_pe, get_data1d, get_len, from_pe, block, tag, &
75  recv_request=recv_request, send_request=send_request )
76 
77  return
78  end subroutine mpp_transmit_2d_
79 
80  subroutine mpp_transmit_3d_( put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, &
81  recv_request, send_request )
82  integer, intent(in) :: put_len, to_pe, get_len, from_pe
83  mpp_type_, intent(in) :: put_data(:,:,:)
84  mpp_type_, intent(out) :: get_data(:,:,:)
85  logical, intent(in), optional :: block
86  integer, intent(in), optional :: tag
87  type(mpi_request), intent(out), optional :: recv_request, send_request
88  mpp_type_ :: put_data1d(put_len), get_data1d(get_len)
89 
90  pointer( ptrp, put_data1d )
91  pointer( ptrg, get_data1d )
92  get_data = mpp_type_init_value
93 
94  ptrp = loc(put_data)
95  ptrg = loc(get_data)
96  call mpp_transmit( put_data1d, put_len, to_pe, get_data1d, get_len, from_pe, block, tag, &
97  recv_request=recv_request, send_request=send_request )
98 
99  return
100  end subroutine mpp_transmit_3d_
101 
102  subroutine mpp_transmit_4d_( put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, &
103  recv_request, send_request )
104  integer, intent(in) :: put_len, to_pe, get_len, from_pe
105  mpp_type_, intent(in) :: put_data(:,:,:,:)
106  mpp_type_, intent(out) :: get_data(:,:,:,:)
107  logical, intent(in), optional :: block
108  integer, intent(in), optional :: tag
109  type(mpi_request), intent(out), optional :: recv_request, send_request
110  mpp_type_ :: put_data1d(put_len), get_data1d(get_len)
111 
112  pointer( ptrp, put_data1d )
113  pointer( ptrg, get_data1d )
114  get_data = mpp_type_init_value
115 
116  ptrp = loc(put_data)
117  ptrg = loc(get_data)
118  call mpp_transmit( put_data1d, put_len, to_pe, get_data1d, get_len, from_pe, block, tag, &
119  recv_request=recv_request, send_request=send_request )
120 
121  return
122  end subroutine mpp_transmit_4d_
123 
124  subroutine mpp_transmit_5d_( put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, &
125  recv_request, send_request )
126  integer, intent(in) :: put_len, to_pe, get_len, from_pe
127  mpp_type_, intent(in) :: put_data(:,:,:,:,:)
128  mpp_type_, intent(out) :: get_data(:,:,:,:,:)
129  logical, intent(in), optional :: block
130  integer, intent(in), optional :: tag
131  type(mpi_request), intent(out), optional :: recv_request, send_request
132  mpp_type_ :: put_data1d(put_len), get_data1d(get_len)
133 
134  pointer( ptrp, put_data1d )
135  pointer( ptrg, get_data1d )
136  get_data = mpp_type_init_value
137 
138  ptrp = loc(put_data)
139  ptrg = loc(get_data)
140  call mpp_transmit( put_data1d, put_len, to_pe, get_data1d, get_len, from_pe, block, tag, &
141  recv_request=recv_request, send_request=send_request )
142 
143  return
144  end subroutine mpp_transmit_5d_
145 
146 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
147 ! !
148 ! MPP_SEND and RECV !
149 ! !
150 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
151 
152  subroutine mpp_recv_( get_data, get_len, from_pe, block, tag, request )
153 !a mpp_transmit with null arguments on the put side
154  integer, intent(in) :: get_len, from_pe
155  mpp_type_, intent(out) :: get_data(*)
156  logical, intent(in), optional :: block
157  integer, intent(in), optional :: tag
158  type(mpi_request), intent(out), optional :: request
159 
160  mpp_type_ :: dummy(1)
161  call mpp_transmit( dummy, 1, null_pe, get_data, get_len, from_pe, block, tag, recv_request=request )
162  end subroutine mpp_recv_
163 
164  subroutine mpp_send_( put_data, put_len, to_pe, tag, request )
165 !a mpp_transmit with null arguments on the get side
166  integer, intent(in) :: put_len, to_pe
167  mpp_type_, intent(in) :: put_data(*)
168  integer, intent(in), optional :: tag
169  type(mpi_request), intent(out), optional :: request
170  mpp_type_ :: dummy(1)
171  call mpp_transmit( put_data, put_len, to_pe, dummy, 1, null_pe, tag=tag, send_request=request )
172  end subroutine mpp_send_
173 
174  subroutine mpp_recv_scalar_( get_data, from_pe, glen, block, tag, request, omp_offload )
175 !a mpp_transmit with null arguments on the put side
176  integer, intent(in) :: from_pe
177  mpp_type_, intent(out) :: get_data
178  logical, intent(in), optional :: block
179  integer, intent(in), optional :: tag
180  type(mpi_request), intent(out), optional :: request
181 
182  integer, optional, intent(in) :: glen
183  logical, optional, intent(in) :: omp_offload
184  integer :: get_len
185  mpp_type_ :: get_data1d(1)
186  mpp_type_ :: dummy(1)
187 
188  pointer( ptr, get_data1d )
189  get_data = mpp_type_init_value
190 
191  ptr = loc(get_data)
192  get_len=1; if(PRESENT(glen))get_len=glen
193  call mpp_transmit( dummy, 1, null_pe, get_data1d, get_len, from_pe, &
194  block, tag, recv_request=request, omp_offload=omp_offload )
195 
196  end subroutine mpp_recv_scalar_
197 
198  subroutine mpp_send_scalar_( put_data, to_pe, plen, tag, request, omp_offload)
199 !a mpp_transmit with null arguments on the get side
200  integer, intent(in) :: to_pe
201  mpp_type_, intent(in) :: put_data
202  integer, optional, intent(in) :: plen
203  integer, intent(in), optional :: tag
204  type(mpi_request), intent(out), optional :: request
205  logical, optional, intent(in) :: omp_offload
206  integer :: put_len
207  mpp_type_ :: put_data1d(1)
208  mpp_type_ :: dummy(1)
209 
210  pointer( ptr, put_data1d )
211  ptr = loc(put_data)
212  put_len=1; if(PRESENT(plen))put_len=plen
213  call mpp_transmit( put_data1d, put_len, to_pe, dummy, 1, null_pe, &
214  tag=tag, send_request=request, omp_offload=omp_offload )
215 
216  end subroutine mpp_send_scalar_
217 
218  subroutine mpp_recv_2d_( get_data, get_len, from_pe, block, tag, request )
219 !a mpp_transmit with null arguments on the put side
220  integer, intent(in) :: get_len, from_pe
221  mpp_type_, intent(out) :: get_data(:,:)
222  logical, intent(in), optional :: block
223  integer, intent(in), optional :: tag
224  type(mpi_request), intent(out), optional :: request
225 
226  mpp_type_ :: dummy(1,1)
227  call mpp_transmit( dummy, 1, null_pe, get_data, get_len, from_pe, &
228  block, tag, recv_request=request )
229  end subroutine mpp_recv_2d_
230 
231  subroutine mpp_send_2d_( put_data, put_len, to_pe, tag, request )
232 !a mpp_transmit with null arguments on the get side
233  integer, intent(in) :: put_len, to_pe
234  mpp_type_, intent(in) :: put_data(:,:)
235  integer, intent(in), optional :: tag
236  type(mpi_request), intent(out), optional :: request
237  mpp_type_ :: dummy(1,1)
238  call mpp_transmit( put_data, put_len, to_pe, dummy, 1, null_pe, tag = tag, send_request=request )
239  end subroutine mpp_send_2d_
240 
241  subroutine mpp_recv_3d_( get_data, get_len, from_pe, block, tag, request )
242 !a mpp_transmit with null arguments on the put side
243  integer, intent(in) :: get_len, from_pe
244  mpp_type_, intent(out) :: get_data(:,:,:)
245  logical, intent(in), optional :: block
246  integer, intent(in), optional :: tag
247  type(mpi_request), intent(out), optional :: request
248 
249  mpp_type_ :: dummy(1,1,1)
250  call mpp_transmit( dummy, 1, null_pe, get_data, get_len, from_pe, block, tag, recv_request=request )
251  end subroutine mpp_recv_3d_
252 
253  subroutine mpp_send_3d_( put_data, put_len, to_pe, tag, request )
254 !a mpp_transmit with null arguments on the get side
255  integer, intent(in) :: put_len, to_pe
256  mpp_type_, intent(in) :: put_data(:,:,:)
257  integer, intent(in), optional :: tag
258  type(mpi_request), intent(out), optional :: request
259  mpp_type_ :: dummy(1,1,1)
260  call mpp_transmit( put_data, put_len, to_pe, dummy, 1, null_pe, tag = tag, send_request=request )
261  end subroutine mpp_send_3d_
262 
263  subroutine mpp_recv_4d_( get_data, get_len, from_pe, block, tag, request )
264 !a mpp_transmit with null arguments on the put side
265  integer, intent(in) :: get_len, from_pe
266  mpp_type_, intent(out) :: get_data(:,:,:,:)
267  logical, intent(in), optional :: block
268  integer, intent(in), optional :: tag
269  type(mpi_request), intent(out), optional :: request
270 
271  mpp_type_ :: dummy(1,1,1,1)
272  call mpp_transmit( dummy, 1, null_pe, get_data, get_len, from_pe, block, tag, recv_request=request )
273  end subroutine mpp_recv_4d_
274 
275  subroutine mpp_send_4d_( put_data, put_len, to_pe, tag, request )
276 !a mpp_transmit with null arguments on the get side
277  integer, intent(in) :: put_len, to_pe
278  mpp_type_, intent(in) :: put_data(:,:,:,:)
279  integer, intent(in), optional :: tag
280  type(mpi_request), intent(out), optional :: request
281  mpp_type_ :: dummy(1,1,1,1)
282  call mpp_transmit( put_data, put_len, to_pe, dummy, 1, null_pe, tag = tag, send_request=request )
283  end subroutine mpp_send_4d_
284 
285  subroutine mpp_recv_5d_( get_data, get_len, from_pe, block, tag, request)
286 !a mpp_transmit with null arguments on the put side
287  integer, intent(in) :: get_len, from_pe
288  mpp_type_, intent(out) :: get_data(:,:,:,:,:)
289  logical, intent(in), optional :: block
290  integer, intent(in), optional :: tag
291  type(mpi_request), intent(out), optional :: request
292 
293  mpp_type_ :: dummy(1,1,1,1,1)
294  call mpp_transmit( dummy, 1, null_pe, get_data, get_len, from_pe, block, tag, recv_request=request )
295  end subroutine mpp_recv_5d_
296 
297  subroutine mpp_send_5d_( put_data, put_len, to_pe, tag, request )
298 !a mpp_transmit with null arguments on the get side
299  integer, intent(in) :: put_len, to_pe
300  mpp_type_, intent(in) :: put_data(:,:,:,:,:)
301  integer, intent(in), optional :: tag
302  type(mpi_request), intent(out), optional :: request
303  mpp_type_ :: dummy(1,1,1,1,1)
304  call mpp_transmit( put_data, put_len, to_pe, dummy, 1, null_pe, tag = tag, send_request=request )
305  end subroutine mpp_send_5d_
306 
307 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
308 ! !
309 ! MPP_BROADCAST !
310 ! !
311 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
312 
313  subroutine mpp_broadcast_scalar_( broadcast_data, from_pe, pelist )
314  mpp_type_, intent(inout) :: broadcast_data
315  integer, intent(in) :: from_pe
316  integer, intent(in), optional :: pelist(:)
317  mpp_type_ :: data1d(1)
318 
319  pointer( ptr, data1d )
320 
321  ptr = loc(broadcast_data)
322  call mpp_broadcast_( data1d, 1, from_pe, pelist )
323 
324  return
325  end subroutine mpp_broadcast_scalar_
326 
327  subroutine mpp_broadcast_2d_( broadcast_data, length, from_pe, pelist )
328 !this call was originally bundled in with mpp_transmit, but that doesn't allow
329 !broadcast to a subset of PEs. This version will, and mpp_transmit will remain
330 !backward compatible.
331  mpp_type_, intent(inout) :: broadcast_data(:,:)
332  integer, intent(in) :: length, from_pe
333  integer, intent(in), optional :: pelist(:)
334  mpp_type_ :: data1d(length)
335 
336  pointer( ptr, data1d )
337  ptr = loc(broadcast_data)
338  call mpp_broadcast( data1d, length, from_pe, pelist )
339 
340  return
341  end subroutine mpp_broadcast_2d_
342 
343  subroutine mpp_broadcast_3d_( broadcast_data, length, from_pe, pelist )
344 !this call was originally bundled in with mpp_transmit, but that doesn't allow
345 !broadcast to a subset of PEs. This version will, and mpp_transmit will remain
346 !backward compatible.
347  mpp_type_, intent(inout) :: broadcast_data(:,:,:)
348  integer, intent(in) :: length, from_pe
349  integer, intent(in), optional :: pelist(:)
350  mpp_type_ :: data1d(length)
351 
352  pointer( ptr, data1d )
353  ptr = loc(broadcast_data)
354  call mpp_broadcast( data1d, length, from_pe, pelist )
355 
356  return
357  end subroutine mpp_broadcast_3d_
358 
359  subroutine mpp_broadcast_4d_( broadcast_data, length, from_pe, pelist )
360 !this call was originally bundled in with mpp_transmit, but that doesn't allow
361 !broadcast to a subset of PEs. This version will, and mpp_transmit will remain
362 !backward compatible.
363  mpp_type_, intent(inout) :: broadcast_data(:,:,:,:)
364  integer, intent(in) :: length, from_pe
365  integer, intent(in), optional :: pelist(:)
366  mpp_type_ :: data1d(length)
367 
368  pointer( ptr, data1d )
369  ptr = loc(broadcast_data)
370  call mpp_broadcast( data1d, length, from_pe, pelist )
371 
372  return
373  end subroutine mpp_broadcast_4d_
374 
375  subroutine mpp_broadcast_5d_( broadcast_data, length, from_pe, pelist )
376 !this call was originally bundled in with mpp_transmit, but that doesn't allow
377 !broadcast to a subset of PEs. This version will, and mpp_transmit will remain
378 !backward compatible.
379  mpp_type_, intent(inout) :: broadcast_data(:,:,:,:,:)
380  integer, intent(in) :: length, from_pe
381  integer, intent(in), optional :: pelist(:)
382  mpp_type_ :: data1d(length)
383 
384  pointer( ptr, data1d )
385  ptr = loc(broadcast_data)
386  call mpp_broadcast( data1d, length, from_pe, pelist )
387 
388  return
389  end subroutine mpp_broadcast_5d_
390 !> @}