3 !***********************************************************************
4 !* GNU Lesser General Public License
6 !* This file
is part of the GFDL Flexible Modeling System (FMS).
8 !* FMS
is free software: you can redistribute it and/or modify it under
9 !* the terms of the GNU Lesser General Public License as published by
10 !* the Free Software Foundation, either
version 3 of the License, or (at
11 !* your option) any later
version.
13 !* FMS
is distributed in the hope that it
will be useful, but WITHOUT
14 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 !* You should have
received a copy of the GNU Lesser General Public
19 !* License along with FMS. If
not, see <http:
20 !***********************************************************************
24 #elif defined(use_libMPI) 30 #ifndef no_8byte_integers 31 #undef MPP_CHKSUM_INT_ 32 #define MPP_CHKSUM_INT_ mpp_chksum_i8_1d 33 #undef MPP_CHKSUM_INT_RMASK_ 34 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i8_1d_rmask 36 #define MPP_TYPE_ integer(LONG_KIND) 41 #undef MPP_CHKSUM_INT_ 42 #define MPP_CHKSUM_INT_ mpp_chksum_i8_2d 43 #undef MPP_CHKSUM_INT_RMASK_ 44 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i8_2d_rmask 46 #define MPP_TYPE_ integer(LONG_KIND) 48 #define MPP_RANK_ (:,:) 51 #undef MPP_CHKSUM_INT_ 52 #define MPP_CHKSUM_INT_ mpp_chksum_i8_3d 53 #undef MPP_CHKSUM_INT_RMASK_ 54 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i8_3d_rmask 56 #define MPP_TYPE_ integer(LONG_KIND) 58 #define MPP_RANK_ (:,:,:) 61 #undef MPP_CHKSUM_INT_ 62 #define MPP_CHKSUM_INT_ mpp_chksum_i8_4d 63 #undef MPP_CHKSUM_INT_RMASK_ 64 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i8_4d_rmask 66 #define MPP_TYPE_ integer(LONG_KIND) 68 #define MPP_RANK_ (:,:,:,:) 71 #undef MPP_CHKSUM_INT_ 72 #define MPP_CHKSUM_INT_ mpp_chksum_i8_5d 73 #undef MPP_CHKSUM_INT_RMASK_ 74 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i8_5d_rmask 76 #define MPP_TYPE_ integer(LONG_KIND) 78 #define MPP_RANK_ (:,:,:,:,:) 82 #undef MPP_CHKSUM_INT_ 83 #define MPP_CHKSUM_INT_ mpp_chksum_i4_1d 84 #undef MPP_CHKSUM_INT_RMASK_ 85 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i4_1d_rmask 87 #define MPP_TYPE_ integer(INT_KIND) 92 #undef MPP_CHKSUM_INT_ 93 #define MPP_CHKSUM_INT_ mpp_chksum_i4_2d 94 #undef MPP_CHKSUM_INT_RMASK_ 95 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i4_2d_rmask 97 #define MPP_TYPE_ integer(INT_KIND) 99 #define MPP_RANK_ (:,:) 102 #undef MPP_CHKSUM_INT_ 103 #define MPP_CHKSUM_INT_ mpp_chksum_i4_3d 104 #undef MPP_CHKSUM_INT_RMASK_ 105 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i4_3d_rmask 107 #define MPP_TYPE_ integer(INT_KIND) 109 #define MPP_RANK_ (:,:,:) 112 #undef MPP_CHKSUM_INT_ 113 #define MPP_CHKSUM_INT_ mpp_chksum_i4_4d 114 #undef MPP_CHKSUM_INT_RMASK_ 115 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i4_4d_rmask 117 #define MPP_TYPE_ integer(INT_KIND) 119 #define MPP_RANK_ (:,:,:,:) 122 #undef MPP_CHKSUM_INT_ 123 #define MPP_CHKSUM_INT_ mpp_chksum_i4_5d 124 #undef MPP_CHKSUM_INT_RMASK_ 125 #define MPP_CHKSUM_INT_RMASK_ mpp_chksum_i4_5d_rmask 127 #define MPP_TYPE_ integer(INT_KIND) 129 #define MPP_RANK_ (:,:,:,:,:) 133 #define MPP_CHKSUM_ mpp_chksum_r8_0d 135 #define MPP_TYPE_ real(DOUBLE_KIND) 141 #define MPP_CHKSUM_ mpp_chksum_r8_1d 143 #define MPP_TYPE_ real(DOUBLE_KIND) 145 #define MPP_RANK_ (:) 149 #define MPP_CHKSUM_ mpp_chksum_r8_2d 151 #define MPP_TYPE_ real(DOUBLE_KIND) 153 #define MPP_RANK_ (:,:) 157 #define MPP_CHKSUM_ mpp_chksum_r8_3d 159 #define MPP_TYPE_ real(DOUBLE_KIND) 161 #define MPP_RANK_ (:,:,:) 165 #define MPP_CHKSUM_ mpp_chksum_r8_4d 167 #define MPP_TYPE_ real(DOUBLE_KIND) 169 #define MPP_RANK_ (:,:,:,:) 173 #define MPP_CHKSUM_ mpp_chksum_r8_5d 175 #define MPP_TYPE_ real(DOUBLE_KIND) 177 #define MPP_RANK_ (:,:,:,:,:) 182 #define MPP_CHKSUM_ mpp_chksum_c8_0d 184 #define MPP_TYPE_ complex(DOUBLE_KIND) 190 #define MPP_CHKSUM_ mpp_chksum_c8_1d 192 #define MPP_TYPE_ complex(DOUBLE_KIND) 194 #define MPP_RANK_ (:) 198 #define MPP_CHKSUM_ mpp_chksum_c8_2d 200 #define MPP_TYPE_ complex(DOUBLE_KIND) 202 #define MPP_RANK_ (:,:) 206 #define MPP_CHKSUM_ mpp_chksum_c8_3d 208 #define MPP_TYPE_ complex(DOUBLE_KIND) 210 #define MPP_RANK_ (:,:,:) 214 #define MPP_CHKSUM_ mpp_chksum_c8_4d 216 #define MPP_TYPE_ complex(DOUBLE_KIND) 218 #define MPP_RANK_ (:,:,:,:) 222 #define MPP_CHKSUM_ mpp_chksum_c8_5d 224 #define MPP_TYPE_ complex(DOUBLE_KIND) 226 #define MPP_RANK_ (:,:,:,:,:) 232 #define MPP_CHKSUM_ mpp_chksum_r4_0d 234 #define MPP_TYPE_ real(FLOAT_KIND) 240 #define MPP_CHKSUM_ mpp_chksum_r4_1d 242 #define MPP_TYPE_ real(FLOAT_KIND) 244 #define MPP_RANK_ (:) 248 #define MPP_CHKSUM_ mpp_chksum_r4_2d 250 #define MPP_TYPE_ real(FLOAT_KIND) 252 #define MPP_RANK_ (:,:) 256 #define MPP_CHKSUM_ mpp_chksum_r4_3d 258 #define MPP_TYPE_ real(FLOAT_KIND) 260 #define MPP_RANK_ (:,:,:) 264 #define MPP_CHKSUM_ mpp_chksum_r4_4d 266 #define MPP_TYPE_ real(FLOAT_KIND) 268 #define MPP_RANK_ (:,:,:,:) 272 #define MPP_CHKSUM_ mpp_chksum_r4_5d 274 #define MPP_TYPE_ real(FLOAT_KIND) 276 #define MPP_RANK_ (:,:,:,:,:) 282 #define MPP_CHKSUM_ mpp_chksum_c4_0d 284 #define MPP_TYPE_ complex(FLOAT_KIND) 290 #define MPP_CHKSUM_ mpp_chksum_c4_1d 292 #define MPP_TYPE_ complex(FLOAT_KIND) 294 #define MPP_RANK_ (:) 298 #define MPP_CHKSUM_ mpp_chksum_c4_2d 300 #define MPP_TYPE_ complex(FLOAT_KIND) 302 #define MPP_RANK_ (:,:) 306 #define MPP_CHKSUM_ mpp_chksum_c4_3d 308 #define MPP_TYPE_ complex(FLOAT_KIND) 310 #define MPP_RANK_ (:,:,:) 314 #define MPP_CHKSUM_ mpp_chksum_c4_4d 316 #define MPP_TYPE_ complex(FLOAT_KIND) 318 #define MPP_RANK_ (:,:,:,:) 322 #define MPP_CHKSUM_ mpp_chksum_c4_5d 324 #define MPP_TYPE_ complex(FLOAT_KIND) 326 #define MPP_RANK_ (:,:,:,:,:) 330 !#################################################
331 #undef MPP_GATHER_1D_ 332 #undef MPP_GATHER_1DV_ 334 #define MPP_TYPE_ logical 335 #define MPP_GATHER_1D_ mpp_gather_logical_1d 336 #define MPP_GATHER_1DV_ mpp_gather_logical_1dv 337 #undef MPP_GATHER_PELIST_2D_ 338 #undef MPP_GATHER_PELIST_3D_ 339 #define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_logical_2d 340 #define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_logical_3d 343 #undef MPP_GATHER_1D_ 344 #undef MPP_GATHER_1DV_ 346 #define MPP_TYPE_ integer(INT_KIND) 347 #define MPP_GATHER_1D_ mpp_gather_int4_1d 348 #define MPP_GATHER_1DV_ mpp_gather_int4_1dv 349 #undef MPP_GATHER_PELIST_2D_ 350 #undef MPP_GATHER_PELIST_3D_ 351 #define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_int4_2d 352 #define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_int4_3d 355 #undef MPP_GATHER_1D_ 356 #undef MPP_GATHER_1DV_ 358 #define MPP_TYPE_ real(FLOAT_KIND) 359 #define MPP_GATHER_1D_ mpp_gather_real4_1d 360 #define MPP_GATHER_1DV_ mpp_gather_real4_1dv 361 #undef MPP_GATHER_PELIST_2D_ 362 #undef MPP_GATHER_PELIST_3D_ 363 #define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_real4_2d 364 #define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_real4_3d 367 #undef MPP_GATHER_1D_ 368 #undef MPP_GATHER_1DV_ 370 #define MPP_TYPE_ real(DOUBLE_KIND) 371 #define MPP_GATHER_1D_ mpp_gather_real8_1d 372 #define MPP_GATHER_1DV_ mpp_gather_real8_1dv 373 #undef MPP_GATHER_PELIST_2D_ 374 #undef MPP_GATHER_PELIST_3D_ 375 #define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_real8_2d 376 #define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_real8_3d 379 !#################################################
380 #undef MPP_SCATTER_PELIST_2D_ 381 #undef MPP_SCATTER_PELIST_3D_ 383 #define MPP_TYPE_ integer(INT_KIND) 384 #define MPP_SCATTER_PELIST_2D_ mpp_scatter_pelist_int4_2d 385 #define MPP_SCATTER_PELIST_3D_ mpp_scatter_pelist_int4_3d 388 #undef MPP_SCATTER_PELIST_2D_ 389 #undef MPP_SCATTER_PELIST_3D_ 391 #define MPP_TYPE_ real(FLOAT_KIND) 392 #define MPP_SCATTER_PELIST_2D_ mpp_scatter_pelist_real4_2d 393 #define MPP_SCATTER_PELIST_3D_ mpp_scatter_pelist_real4_3d 396 #undef MPP_SCATTER_PELIST_2D_ 397 #undef MPP_SCATTER_PELIST_3D_ 399 #define MPP_TYPE_ real(DOUBLE_KIND) 400 #define MPP_SCATTER_PELIST_2D_ mpp_scatter_pelist_real8_2d 401 #define MPP_SCATTER_PELIST_3D_ mpp_scatter_pelist_real8_3d ************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version will
subroutine, public copy(self, rhs)
character(len=128) version
l_size ! loop over number of fields ke do je do ie to is
logical function received(this, seqno)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) a
*f90 *************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If not