!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! !! GNU General Public License !! !! !! !! This file is part of the Flexible Modeling System (FMS). !! !! !! !! FMS is free software; you can redistribute it and/or modify !! !! it and are expected to follow the terms of the GNU General Public !! !! License as published by the Free Software Foundation. !! !! !! !! FMS is distributed in the hope that it will be useful, !! !! but WITHOUT ANY WARRANTY; 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 General Public License !! !! along with FMS; if not, write to: !! !! Free Software Foundation, Inc. !! !! 59 Temple Place, Suite 330 !! !! Boston, MA 02111-1307 USA !! !! or see: !! !! http://www.gnu.org/licenses/gpl.txt !! !! !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Modified: Jun Wang ! Jun.Wang@noaa.gov module mpp_comm_mod #include #if defined(use_libSMA) && defined(sgi_mipspro) use shmem_interface #endif #if defined(use_libMPI) && defined(sgi_mipspro) use mpi #endif use mpp_parameter_mod, only : MPP_CLOCK_SYNC, MPP_DEBUG, MPP_VERBOSE, NOTE, FATAL use mpp_parameter_mod, only : MAX_EVENT_TYPES, EVENT_ALLREDUCE, NULL_PE, EVENT_SEND use mpp_parameter_mod, only : ALL_PES, ANY_PE, NULL_PE, EVENT_RECV, EVENT_WAIT use mpp_parameter_mod, only : EVENT_BROADCAST, MPP_READY, MPP_WAIT use mpp_parameter_mod, only : mpp_parameter_version=>version, mpp_parameter_tagname=>tagname use mpp_data_mod, only : peset, clocks, module_is_initialized=>mpp_is_initialized use mpp_data_mod, only : error, pe, npes, root_pe, current_peset_num,peset_num !-->cpl insertion peset_num <-- for mpp_init use mpp_data_mod, only : world_peset_num, clock_num, current_clock, start_tick use mpp_data_mod, only : tick,tick0, ticks_per_sec, max_ticks, tick_rate use mpp_data_mod, only : debug=>debug_mpp, request, etc_unit, log_unit, configfile use mpp_data_mod, only : stat, mpp_stack, ptr_stack, status, ptr_status, sync, ptr_sync use mpp_data_mod, only : mpp_from_pe, ptr_from, remote_data_loc, ptr_remote, etcfile use mpp_data_mod, only : first_call_system_clock_mpi, mpi_tick_rate, mpi_count0 use mpp_data_mod, only : mpp_data_version=>version, mpp_data_tagname=>tagname use mpp_data_mod, only : mpp_comm_private use mpp_util_mod, only : mpp_sync, mpp_error, mpp_npes, mpp_pe, stdlog, stdout, stderr use mpp_util_mod, only : get_peset, get_unit, increment_current_clock, dump_clock_summary use mpp_util_mod, only : sum_clock_data, mpp_clock_id, mpp_clock_begin, mpp_clock_end use mpp_util_mod, only : mpp_set_current_pelist, mpp_init_logfile use mpp_util_mod, only : mpp_util_version=>version, mpp_util_tagname=>tagname implicit none private #if defined(use_libSMA) || defined(use_GSM) #include #endif #if defined(use_libMPI) && !defined(sgi_mipspro) #include ! sgi_mipspro gets this from 'use mpi' #endif #ifdef use_libMPI #ifdef _CRAYT3E !BWA: mpif.h on t3e currently does not contain MPI_INTEGER8 datatype !(O2k and t90 do) !(t3e: fixed on 3.3 I believe) integer, parameter :: MPI_INTEGER8=MPI_INTEGER #endif #endif use_libMPI integer :: clock0 !measures total runtime from mpp_init to mpp_exit integer :: mpp_stack_size=0, mpp_stack_hwm=0 integer :: tag=1 logical :: verbose=.FALSE. #ifdef _CRAY integer(LONG_KIND) :: word(1) #endif #if defined(sgi_mipspro) || defined(__ia64) integer(INT_KIND) :: word(1) #endif character(len=128) :: version= & '$Id$' character(len=128) :: tagname= & '$Name$' public :: mpp_init, mpp_exit, mpp_min, mpp_max, mpp_sum, mpp_transmit, mpp_recv public :: mpp_send, mpp_broadcast, mpp_chksum, mpp_malloc, mpp_set_stack_size #ifdef use_MPI_GSM public :: mpp_gsm_malloc, mpp_gsm_free #endif #ifdef use_libSMA !currently SMA contains no generic shmem_wait for different integer kinds: !I have inserted one here interface shmem_integer_wait module procedure shmem_int4_wait_local module procedure shmem_int8_wait_local end interface #endif !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! ! ROUTINES TO INITIALIZE/FINALIZE MPP MODULE: mpp_init, mpp_exit ! ! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! ! Initialize mpp_mod. ! ! ! Called to initialize the mpp_mod package. It is recommended ! that this call be the first executed line in your program. It sets the ! number of PEs assigned to this run (acquired from the command line, or ! through the environment variable NPES), and associates an ID ! number to each PE. These can be accessed by calling mpp_npes and mpp_pe. ! ! ! ! flags can be set to MPP_VERBOSE to ! have mpp_mod keep you informed of what it's up to. ! ! ! ! ! Exit mpp_mod. ! ! ! Called at the end of the run, or to re-initialize mpp_mod, ! should you require that for some odd reason. ! ! This call implies synchronization across all PEs. ! ! ! !####################################################################### ! ! ! Symmetric memory allocation. ! ! ! This routine is used on SGI systems when mpp_mod is ! invoked in the SHMEM library. It ensures that dynamically allocated ! memory can be used with shmem_get and ! shmem_put. This is called symmetric ! allocation and is described in the ! intro_shmem man page. ptr is a Cray ! pointer (see the section on portability). The operation can be expensive ! (since it requires a global barrier). We therefore attempt to re-use ! existing allocation whenever possible. Therefore len ! and ptr must have the SAVE attribute ! in the calling routine, and retain the information about the last call ! to mpp_malloc. Additional memory is symmetrically ! allocated if and only if newlen exceeds ! len. ! ! This is never required on Cray PVP or MPP systems. While the T3E ! manpages do talk about symmetric allocation, mpp_mod ! is coded to remove this restriction. ! ! It is never required if mpp_mod is invoked in MPI. ! ! This call implies synchronization across all PEs. ! ! ! ! a cray pointer, points to a dummy argument in this routine. ! ! ! the required allocation length for the pointer ptr ! ! ! the current allocation (0 if unallocated). ! ! !##################################################################### ! ! ! Allocate module internal workspace. ! ! ! mpp_mod maintains a private internal array called ! mpp_stack for private workspace. This call sets the length, ! in words, of this array. ! ! The mpp_init call sets this ! workspace length to a default of 32768, and this call may be used if a ! longer workspace is needed. ! ! This call implies synchronization across all PEs. ! ! This workspace is symmetrically allocated, as required for ! efficient communication on SGI and Cray MPP systems. Since symmetric ! allocation must be performed by all PEs in a job, this call ! must also be called by all PEs, using the same value of ! n. Calling mpp_set_stack_size from a subset of PEs, ! or with unequal argument n, may cause the program to hang. ! ! If any MPP call using mpp_stack overflows the declared ! stack array, the program will abort with a message specifying the ! stack length that is required. Many users wonder why, if the required ! stack length can be computed, it cannot also be specified at that ! point. This cannot be automated because there is no way for the ! program to know if all PEs are present at that call, and with equal ! values of n. The program must be rerun by the user with the ! correct argument to mpp_set_stack_size, called at an ! appropriate point in the code where all PEs are known to be present. ! ! ! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! ! GLOBAL REDUCTION ROUTINES: mpp_max, mpp_sum, mpp_min ! ! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! ! Reduction operations. ! ! ! Find the max of scalar a the PEs in pelist ! result is also automatically broadcast to all PEs ! ! ! ! real or integer, of 4-byte of 8-byte kind. ! ! ! If pelist is omitted, the context is assumed to be the ! current pelist. This call implies synchronization across the PEs in ! pelist, or the current pelist if pelist is absent. ! ! interface mpp_max module procedure mpp_max_real8 #ifndef no_8byte_integers module procedure mpp_max_int8 #endif #ifndef no_4byte_reals module procedure mpp_max_real4 #endif module procedure mpp_max_int4 end interface interface mpp_min module procedure mpp_min_real8 #ifndef no_8byte_integers module procedure mpp_min_int8 #endif #ifndef no_4byte_reals module procedure mpp_min_real4 #endif module procedure mpp_min_int4 end interface ! ! ! Reduction operation. ! ! ! MPP_TYPE_ corresponds to any 4-byte and 8-byte variant of ! integer, real, complex variables, of rank 0 or 1. A ! contiguous block from a multi-dimensional array may be passed by its ! starting address and its length, as in f77. ! ! Library reduction operators are not required or guaranteed to be ! bit-reproducible. In any case, changing the processor count changes ! the data layout, and thus very likely the order of operations. For ! bit-reproducible sums of distributed arrays, consider using the ! mpp_global_sum routine provided by the mpp_domains module. ! ! The bit_reproducible flag provided in earlier versions of ! this routine has been removed. ! ! ! If pelist is omitted, the context is assumed to be the ! current pelist. This call implies synchronization across the PEs in ! pelist, or the current pelist if pelist is absent. ! ! ! ! ! ! interface mpp_sum #ifndef no_8byte_integers module procedure mpp_sum_int8 module procedure mpp_sum_int8_scalar module procedure mpp_sum_int8_2d module procedure mpp_sum_int8_3d module procedure mpp_sum_int8_4d module procedure mpp_sum_int8_5d #endif module procedure mpp_sum_real8 module procedure mpp_sum_real8_scalar module procedure mpp_sum_real8_2d module procedure mpp_sum_real8_3d module procedure mpp_sum_real8_4d module procedure mpp_sum_real8_5d module procedure mpp_sum_cmplx8 module procedure mpp_sum_cmplx8_scalar module procedure mpp_sum_cmplx8_2d module procedure mpp_sum_cmplx8_3d module procedure mpp_sum_cmplx8_4d module procedure mpp_sum_cmplx8_5d module procedure mpp_sum_int4 module procedure mpp_sum_int4_scalar module procedure mpp_sum_int4_2d module procedure mpp_sum_int4_3d module procedure mpp_sum_int4_4d module procedure mpp_sum_int4_5d #ifndef no_4byte_reals module procedure mpp_sum_real4 module procedure mpp_sum_real4_scalar module procedure mpp_sum_real4_2d module procedure mpp_sum_real4_3d module procedure mpp_sum_real4_4d module procedure mpp_sum_real4_5d module procedure mpp_sum_cmplx4 module procedure mpp_sum_cmplx4_scalar module procedure mpp_sum_cmplx4_2d module procedure mpp_sum_cmplx4_3d module procedure mpp_sum_cmplx4_4d module procedure mpp_sum_cmplx4_5d #endif end interface !##################################################################### ! ! ! Basic message-passing call. ! ! ! MPP_TYPE_ corresponds to any 4-byte and 8-byte variant of ! integer, real, complex, logical variables, of rank 0 or 1. A ! contiguous block from a multi-dimensional array may be passed by its ! starting address and its length, as in f77. ! ! mpp_transmit is currently implemented as asynchronous ! outward transmission and synchronous inward transmission. This follows ! the behaviour of shmem_put and shmem_get. In MPI, it ! is implemented as mpi_isend and mpi_recv. For most ! applications, transmissions occur in pairs, and are here accomplished ! in a single call. ! ! The special PE designations NULL_PE, ! ANY_PE and ALL_PES are provided by use ! association. ! ! NULL_PE: is used to disable one of the pair of ! transmissions.
! ANY_PE: is used for unspecific remote ! destination. (Please note that put_pe=ANY_PE has no meaning ! in the MPI context, though it is available in the SHMEM invocation. If ! portability is a concern, it is best avoided).
! ALL_PES: is used for broadcast operations. ! ! It is recommended that mpp_broadcast be used for ! broadcasts. ! ! The following example illustrates the use of ! NULL_PE and ALL_PES: ! !
  !    real, dimension(n) :: a
  !    if( pe.EQ.0 )then
  !        do p = 1,npes-1
  !           call mpp_transmit( a, n, p, a, n, NULL_PE )
  !        end do
  !    else
  !        call mpp_transmit( a, n, NULL_PE, a, n, 0 )
  !    end if
  !    
  !    call mpp_transmit( a, n, ALL_PES, a, n, 0 )
  !    
! ! The do loop and the broadcast operation above are equivalent. ! ! Two overloaded calls mpp_send and ! mpp_recv have also been ! provided. mpp_send calls mpp_transmit ! with get_pe=NULL_PE. mpp_recv calls ! mpp_transmit with put_pe=NULL_PE. Thus ! the do loop above could be written more succinctly: ! !
  !    if( pe.EQ.0 )then
  !        do p = 1,npes-1
  !           call mpp_send( a, n, p )
  !        end do
  !    else
  !        call mpp_recv( a, n, 0 )
  !    end if
  !    
!
! !
interface mpp_transmit module procedure mpp_transmit_real8 module procedure mpp_transmit_real8_scalar module procedure mpp_transmit_real8_2d module procedure mpp_transmit_real8_3d module procedure mpp_transmit_real8_4d module procedure mpp_transmit_real8_5d module procedure mpp_transmit_cmplx8 module procedure mpp_transmit_cmplx8_scalar module procedure mpp_transmit_cmplx8_2d module procedure mpp_transmit_cmplx8_3d module procedure mpp_transmit_cmplx8_4d module procedure mpp_transmit_cmplx8_5d #ifndef no_8byte_integers module procedure mpp_transmit_int8 module procedure mpp_transmit_int8_scalar module procedure mpp_transmit_int8_2d module procedure mpp_transmit_int8_3d module procedure mpp_transmit_int8_4d module procedure mpp_transmit_int8_5d module procedure mpp_transmit_logical8 module procedure mpp_transmit_logical8_scalar module procedure mpp_transmit_logical8_2d module procedure mpp_transmit_logical8_3d module procedure mpp_transmit_logical8_4d module procedure mpp_transmit_logical8_5d #endif #ifndef no_4byte_reals module procedure mpp_transmit_real4 module procedure mpp_transmit_real4_scalar module procedure mpp_transmit_real4_2d module procedure mpp_transmit_real4_3d module procedure mpp_transmit_real4_4d module procedure mpp_transmit_real4_5d module procedure mpp_transmit_cmplx4 module procedure mpp_transmit_cmplx4_scalar module procedure mpp_transmit_cmplx4_2d module procedure mpp_transmit_cmplx4_3d module procedure mpp_transmit_cmplx4_4d module procedure mpp_transmit_cmplx4_5d #endif module procedure mpp_transmit_int4 module procedure mpp_transmit_int4_scalar module procedure mpp_transmit_int4_2d module procedure mpp_transmit_int4_3d module procedure mpp_transmit_int4_4d module procedure mpp_transmit_int4_5d module procedure mpp_transmit_logical4 module procedure mpp_transmit_logical4_scalar module procedure mpp_transmit_logical4_2d module procedure mpp_transmit_logical4_3d module procedure mpp_transmit_logical4_4d module procedure mpp_transmit_logical4_5d end interface interface mpp_recv module procedure mpp_recv_real8 module procedure mpp_recv_real8_scalar module procedure mpp_recv_real8_2d module procedure mpp_recv_real8_3d module procedure mpp_recv_real8_4d module procedure mpp_recv_real8_5d module procedure mpp_recv_cmplx8 module procedure mpp_recv_cmplx8_scalar module procedure mpp_recv_cmplx8_2d module procedure mpp_recv_cmplx8_3d module procedure mpp_recv_cmplx8_4d module procedure mpp_recv_cmplx8_5d #ifndef no_8byte_integers module procedure mpp_recv_int8 module procedure mpp_recv_int8_scalar module procedure mpp_recv_int8_2d module procedure mpp_recv_int8_3d module procedure mpp_recv_int8_4d module procedure mpp_recv_int8_5d module procedure mpp_recv_logical8 module procedure mpp_recv_logical8_scalar module procedure mpp_recv_logical8_2d module procedure mpp_recv_logical8_3d module procedure mpp_recv_logical8_4d module procedure mpp_recv_logical8_5d #endif #ifndef no_4byte_reals module procedure mpp_recv_real4 module procedure mpp_recv_real4_scalar module procedure mpp_recv_real4_2d module procedure mpp_recv_real4_3d module procedure mpp_recv_real4_4d module procedure mpp_recv_real4_5d module procedure mpp_recv_cmplx4 module procedure mpp_recv_cmplx4_scalar module procedure mpp_recv_cmplx4_2d module procedure mpp_recv_cmplx4_3d module procedure mpp_recv_cmplx4_4d module procedure mpp_recv_cmplx4_5d #endif module procedure mpp_recv_int4 module procedure mpp_recv_int4_scalar module procedure mpp_recv_int4_2d module procedure mpp_recv_int4_3d module procedure mpp_recv_int4_4d module procedure mpp_recv_int4_5d module procedure mpp_recv_logical4 module procedure mpp_recv_logical4_scalar module procedure mpp_recv_logical4_2d module procedure mpp_recv_logical4_3d module procedure mpp_recv_logical4_4d module procedure mpp_recv_logical4_5d end interface interface mpp_send module procedure mpp_send_real8 module procedure mpp_send_real8_scalar module procedure mpp_send_real8_2d module procedure mpp_send_real8_3d module procedure mpp_send_real8_4d module procedure mpp_send_real8_5d module procedure mpp_send_cmplx8 module procedure mpp_send_cmplx8_scalar module procedure mpp_send_cmplx8_2d module procedure mpp_send_cmplx8_3d module procedure mpp_send_cmplx8_4d module procedure mpp_send_cmplx8_5d #ifndef no_8byte_integers module procedure mpp_send_int8 module procedure mpp_send_int8_scalar module procedure mpp_send_int8_2d module procedure mpp_send_int8_3d module procedure mpp_send_int8_4d module procedure mpp_send_int8_5d module procedure mpp_send_logical8 module procedure mpp_send_logical8_scalar module procedure mpp_send_logical8_2d module procedure mpp_send_logical8_3d module procedure mpp_send_logical8_4d module procedure mpp_send_logical8_5d #endif #ifndef no_4byte_reals module procedure mpp_send_real4 module procedure mpp_send_real4_scalar module procedure mpp_send_real4_2d module procedure mpp_send_real4_3d module procedure mpp_send_real4_4d module procedure mpp_send_real4_5d module procedure mpp_send_cmplx4 module procedure mpp_send_cmplx4_scalar module procedure mpp_send_cmplx4_2d module procedure mpp_send_cmplx4_3d module procedure mpp_send_cmplx4_4d module procedure mpp_send_cmplx4_5d #endif module procedure mpp_send_int4 module procedure mpp_send_int4_scalar module procedure mpp_send_int4_2d module procedure mpp_send_int4_3d module procedure mpp_send_int4_4d module procedure mpp_send_int4_5d module procedure mpp_send_logical4 module procedure mpp_send_logical4_scalar module procedure mpp_send_logical4_2d module procedure mpp_send_logical4_3d module procedure mpp_send_logical4_4d module procedure mpp_send_logical4_5d end interface ! ! ! Parallel broadcasts. ! ! ! The mpp_broadcast call has been added because the original ! syntax (using ALL_PES in mpp_transmit) did not ! support a broadcast across a pelist. ! ! MPP_TYPE_ corresponds to any 4-byte and 8-byte variant of ! integer, real, complex, logical variables, of rank 0 or 1. A ! contiguous block from a multi-dimensional array may be passed by its ! starting address and its length, as in f77. ! ! Global broadcasts through the ALL_PES argument to mpp_transmit are still provided for ! backward-compatibility. ! ! If pelist is omitted, the context is assumed to be the ! current pelist. from_pe must belong to the current ! pelist. This call implies synchronization across the PEs in ! pelist, or the current pelist if pelist is absent. ! ! ! ! ! ! ! interface mpp_broadcast module procedure mpp_broadcast_real8 module procedure mpp_broadcast_real8_scalar module procedure mpp_broadcast_real8_2d module procedure mpp_broadcast_real8_3d module procedure mpp_broadcast_real8_4d module procedure mpp_broadcast_real8_5d module procedure mpp_broadcast_cmplx8 module procedure mpp_broadcast_cmplx8_scalar module procedure mpp_broadcast_cmplx8_2d module procedure mpp_broadcast_cmplx8_3d module procedure mpp_broadcast_cmplx8_4d module procedure mpp_broadcast_cmplx8_5d #ifndef no_8byte_integers module procedure mpp_broadcast_int8 module procedure mpp_broadcast_int8_scalar module procedure mpp_broadcast_int8_2d module procedure mpp_broadcast_int8_3d module procedure mpp_broadcast_int8_4d module procedure mpp_broadcast_int8_5d module procedure mpp_broadcast_logical8 module procedure mpp_broadcast_logical8_scalar module procedure mpp_broadcast_logical8_2d module procedure mpp_broadcast_logical8_3d module procedure mpp_broadcast_logical8_4d module procedure mpp_broadcast_logical8_5d #endif #ifndef no_4byte_reals module procedure mpp_broadcast_real4 module procedure mpp_broadcast_real4_scalar module procedure mpp_broadcast_real4_2d module procedure mpp_broadcast_real4_3d module procedure mpp_broadcast_real4_4d module procedure mpp_broadcast_real4_5d module procedure mpp_broadcast_cmplx4 module procedure mpp_broadcast_cmplx4_scalar module procedure mpp_broadcast_cmplx4_2d module procedure mpp_broadcast_cmplx4_3d module procedure mpp_broadcast_cmplx4_4d module procedure mpp_broadcast_cmplx4_5d #endif module procedure mpp_broadcast_int4 module procedure mpp_broadcast_int4_scalar module procedure mpp_broadcast_int4_2d module procedure mpp_broadcast_int4_3d module procedure mpp_broadcast_int4_4d module procedure mpp_broadcast_int4_5d module procedure mpp_broadcast_logical4 module procedure mpp_broadcast_logical4_scalar module procedure mpp_broadcast_logical4_2d module procedure mpp_broadcast_logical4_3d module procedure mpp_broadcast_logical4_4d module procedure mpp_broadcast_logical4_5d end interface !##################################################################### ! ! ! Parallel checksums. ! ! ! mpp_chksum is a parallel checksum routine that returns an ! identical answer for the same array irrespective of how it has been ! partitioned across processors. LONG_KINDis the KIND ! parameter corresponding to long integers (see discussion on ! OS-dependent preprocessor directives) defined in ! the header file fms_platform.h. MPP_TYPE_ corresponds to any ! 4-byte and 8-byte variant of integer, real, complex, logical ! variables, of rank 0 to 5. ! ! Integer checksums on FP data use the F90 TRANSFER() ! intrinsic. ! ! The serial checksum module is superseded ! by this function, and is no longer being actively maintained. This ! provides identical results on a single-processor job, and to perform ! serial checksums on a single processor of a parallel job, you only ! need to use the optional pelist argument. !
  !     use mpp_mod
  !     integer :: pe, chksum
  !     real :: a(:)
  !     pe = mpp_pe()
  !     chksum = mpp_chksum( a, (/pe/) )
  !     
! ! The additional functionality of mpp_chksum over ! serial checksums is to compute the checksum across the PEs in ! pelist. The answer is guaranteed to be the same for ! the same distributed array irrespective of how it has been ! partitioned. ! ! If pelist is omitted, the context is assumed to be the ! current pelist. This call implies synchronization across the PEs in ! pelist, or the current pelist if pelist is absent. !
! ! ! !
interface mpp_chksum #ifndef no_8byte_integers module procedure mpp_chksum_i8_1d module procedure mpp_chksum_i8_2d module procedure mpp_chksum_i8_3d module procedure mpp_chksum_i8_4d #endif module procedure mpp_chksum_i4_1d module procedure mpp_chksum_i4_2d module procedure mpp_chksum_i4_3d module procedure mpp_chksum_i4_4d module procedure mpp_chksum_r8_0d module procedure mpp_chksum_r8_1d module procedure mpp_chksum_r8_2d module procedure mpp_chksum_r8_3d module procedure mpp_chksum_r8_4d module procedure mpp_chksum_r8_5d module procedure mpp_chksum_c8_0d module procedure mpp_chksum_c8_1d module procedure mpp_chksum_c8_2d module procedure mpp_chksum_c8_3d module procedure mpp_chksum_c8_4d module procedure mpp_chksum_c8_5d #ifndef no_4byte_reals module procedure mpp_chksum_r4_0d module procedure mpp_chksum_r4_1d module procedure mpp_chksum_r4_2d module procedure mpp_chksum_r4_3d module procedure mpp_chksum_r4_4d module procedure mpp_chksum_r4_5d module procedure mpp_chksum_c4_0d module procedure mpp_chksum_c4_1d module procedure mpp_chksum_c4_2d module procedure mpp_chksum_c4_3d module procedure mpp_chksum_c4_4d module procedure mpp_chksum_c4_5d #endif end interface contains #include #ifdef use_libSMA #include #elif defined(use_libMPI) #include #else #include #endif #ifndef no_8byte_integers #define MPP_CHKSUM_INT_ mpp_chksum_i8_1d #define MPP_TYPE_ integer(LONG_KIND) #define MPP_RANK_ (:) #include #define MPP_CHKSUM_INT_ mpp_chksum_i8_2d #define MPP_TYPE_ integer(LONG_KIND) #define MPP_RANK_ (:,:) #include #define MPP_CHKSUM_INT_ mpp_chksum_i8_3d #define MPP_TYPE_ integer(LONG_KIND) #define MPP_RANK_ (:,:,:) #include #define MPP_CHKSUM_INT_ mpp_chksum_i8_4d #define MPP_TYPE_ integer(LONG_KIND) #define MPP_RANK_ (:,:,:,:) #include #define MPP_CHKSUM_INT_ mpp_chksum_i8_5d #define MPP_TYPE_ integer(LONG_KIND) #define MPP_RANK_ (:,:,:,:,:) #include #endif #define MPP_CHKSUM_INT_ mpp_chksum_i4_1d #define MPP_TYPE_ integer(INT_KIND) #define MPP_RANK_ (:) #include #define MPP_CHKSUM_INT_ mpp_chksum_i4_2d #define MPP_TYPE_ integer(INT_KIND) #define MPP_RANK_ (:,:) #include #define MPP_CHKSUM_INT_ mpp_chksum_i4_3d #define MPP_TYPE_ integer(INT_KIND) #define MPP_RANK_ (:,:,:) #include #define MPP_CHKSUM_INT_ mpp_chksum_i4_4d #define MPP_TYPE_ integer(INT_KIND) #define MPP_RANK_ (:,:,:,:) #include #define MPP_CHKSUM_INT_ mpp_chksum_i4_5d #define MPP_TYPE_ integer(INT_KIND) #define MPP_RANK_ (:,:,:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_r8_0d #define MPP_TYPE_ real(DOUBLE_KIND) #define MPP_RANK_ ! #include #define MPP_CHKSUM_ mpp_chksum_r8_1d #define MPP_TYPE_ real(DOUBLE_KIND) #define MPP_RANK_ (:) #include #define MPP_CHKSUM_ mpp_chksum_r8_2d #define MPP_TYPE_ real(DOUBLE_KIND) #define MPP_RANK_ (:,:) #include #define MPP_CHKSUM_ mpp_chksum_r8_3d #define MPP_TYPE_ real(DOUBLE_KIND) #define MPP_RANK_ (:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_r8_4d #define MPP_TYPE_ real(DOUBLE_KIND) #define MPP_RANK_ (:,:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_r8_5d #define MPP_TYPE_ real(DOUBLE_KIND) #define MPP_RANK_ (:,:,:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_c8_0d #define MPP_TYPE_ complex(DOUBLE_KIND) #define MPP_RANK_ ! #include #define MPP_CHKSUM_ mpp_chksum_c8_1d #define MPP_TYPE_ complex(DOUBLE_KIND) #define MPP_RANK_ (:) #include #define MPP_CHKSUM_ mpp_chksum_c8_2d #define MPP_TYPE_ complex(DOUBLE_KIND) #define MPP_RANK_ (:,:) #include #define MPP_CHKSUM_ mpp_chksum_c8_3d #define MPP_TYPE_ complex(DOUBLE_KIND) #define MPP_RANK_ (:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_c8_4d #define MPP_TYPE_ complex(DOUBLE_KIND) #define MPP_RANK_ (:,:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_c8_5d #define MPP_TYPE_ complex(DOUBLE_KIND) #define MPP_RANK_ (:,:,:,:,:) #include #ifndef no_4byte_reals !CAUTION: the r4 versions of these may produce !unpredictable results: I'm not sure what the result !of the TRANSFER() to integer(8) is from an odd number of real(4)s? !However the complex(4) will work, since it is guaranteed even. #define MPP_CHKSUM_ mpp_chksum_r4_0d #define MPP_TYPE_ real(FLOAT_KIND) #define MPP_RANK_ ! #include #define MPP_CHKSUM_ mpp_chksum_r4_1d #define MPP_TYPE_ real(FLOAT_KIND) #define MPP_RANK_ (:) #include #define MPP_CHKSUM_ mpp_chksum_r4_2d #define MPP_TYPE_ real(FLOAT_KIND) #define MPP_RANK_ (:,:) #include #define MPP_CHKSUM_ mpp_chksum_r4_3d #define MPP_TYPE_ real(FLOAT_KIND) #define MPP_RANK_ (:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_r4_4d #define MPP_TYPE_ real(FLOAT_KIND) #define MPP_RANK_ (:,:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_r4_5d #define MPP_TYPE_ real(FLOAT_KIND) #define MPP_RANK_ (:,:,:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_c4_0d #define MPP_TYPE_ complex(FLOAT_KIND) #define MPP_RANK_ ! #include #define MPP_CHKSUM_ mpp_chksum_c4_1d #define MPP_TYPE_ complex(FLOAT_KIND) #define MPP_RANK_ (:) #include #define MPP_CHKSUM_ mpp_chksum_c4_2d #define MPP_TYPE_ complex(FLOAT_KIND) #define MPP_RANK_ (:,:) #include #define MPP_CHKSUM_ mpp_chksum_c4_3d #define MPP_TYPE_ complex(FLOAT_KIND) #define MPP_RANK_ (:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_c4_4d #define MPP_TYPE_ complex(FLOAT_KIND) #define MPP_RANK_ (:,:,:,:) #include #define MPP_CHKSUM_ mpp_chksum_c4_5d #define MPP_TYPE_ complex(FLOAT_KIND) #define MPP_RANK_ (:,:,:,:,:) #include #endif end module mpp_comm_mod