#ifdef RS6K
@PROCESS NOCHECK
#endif
MODULE MPL_SEND_MOD

!**** MPL_SEND Send a message

!     Purpose.
!     --------
!     Send a message to a named source from a buffer.
!     The data may be REAL*4, REAL*8,or INTEGER, one dimensional array
!                     REAL*4,or REAL*8, two dimensional array
!                  or INTEGER scalar

!**   Interface.
!     ----------
!        CALL MPL_SEND

!        Input required arguments :
!        -------------------------
!           PBUF     -  buffer containing message
!                       (can be type REAL*4, REAL*8 or INTEGER)
!           KTAG     -  message tag
!           KDEST    -  rank of process to receive the message

!        Input optional arguments :
!        -------------------------
!           KCOMM    -  Communicator number if different from MPI_COMM_WORLD 
!                       or from that established as the default 
!                       by an MPL communicator routine
!           KMP_TYPE -  buffering type (see MPL_BUFFER_METHOD)
!                       overrides value provided to MPL_BUFFER_METHOD
!           CDSTRING -  Character string for ABORT messages
!                       used when KERROR is not provided

!        Output required arguments :
!        -------------------------
!           none

!        Output optional arguments :
!        -------------------------
!           KREQUEST -  Communication request
!                       required when buffering type is non-blocking
!           KERROR   -  return error code.     If not supplied, 
!                       MPL_SEND aborts when an error is detected.
!     Author.
!     -------
!        D.Dent, M.Hamrud     ECMWF

!     Modifications.
!     --------------
!        Original: 2000-09-01

!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB     ,JPRM

USE MPL_MPIF
USE MPL_DATA_MODULE
USE MPL_MESSAGE_MOD

IMPLICIT NONE

PRIVATE

!---Moved into subroutines to keep threadsafe----
! INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
! LOGICAL :: LLABORT=.TRUE.

INTERFACE MPL_SEND
MODULE PROCEDURE MPL_SEND_REAL4, MPL_SEND_REAL8,&
               & MPL_SEND_INT,   MPL_SEND_REAL42, &
               & MPL_SEND_REAL82,MPL_SEND_INT_SCALAR, &
               & MPL_SEND_INT2,  MPL_SEND_CHAR_SCALAR, &
               & MPL_SEND_REAL8_SCALAR
END INTERFACE

PUBLIC MPL_SEND

CONTAINS

SUBROUTINE MPL_SEND_REAL4(PBUF,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)


#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif


! real_m,intent(in) :: PBUF(:)
REAL(KIND=JPRM)            :: PBUF(:)
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF
  
IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = SIZE(PBUF)

IF( (LOC(PBUF(UBOUND(PBUF,1))) - LOC(PBUF(LBOUND(PBUF,1)))) /= 4*(ICOUNT - 1) ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND: BUFFER NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(PBUF(1),ICOUNT,INT(MPI_REAL4),KDEST-1,KTAG,ICOMM,IERROR)
ELSE IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(PBUF(1),ICOUNT,INT(MPI_REAL4),KDEST-1,KTAG,ICOMM,IERROR)
ELSE IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(PBUF(1),ICOUNT,INT(MPI_REAL4),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ELSE
  IF(PRESENT(KERROR)) THEN
    KERROR=1
  ELSE
    CALL MPL_MESSAGE(KERROR,'MPL_SEND',' INVALID METHOD',LDABORT=LLABORT)
  ENDIF
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_REAL4  

SUBROUTINE MPL_SEND_REAL8(PBUF,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)

#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif

! real_b,intent(in) :: PBUF(:)
REAL(KIND=JPRB)            :: PBUF(:)
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING


INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = SIZE(PBUF)

IF( (LOC(PBUF(UBOUND(PBUF,1))) - LOC(PBUF(LBOUND(PBUF,1)))) /= 8*(ICOUNT - 1) ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND: BUFFER NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(PBUF(1),ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(PBUF(1),ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(PBUF(1),ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_REAL8

SUBROUTINE MPL_SEND_INT(KBUF,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)

#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif

INTEGER(KIND=JPIM)           :: KBUF(:)
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = SIZE(KBUF)

IF( (LOC(KBUF(UBOUND(KBUF,1)))-LOC(KBUF(LBOUND(KBUF,1)))) /= 4*(ICOUNT - 1) ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND: BUFFER NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(KBUF(1),ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(KBUF(1),ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(KBUF(1),ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_INT

SUBROUTINE MPL_SEND_INT2(KBUF,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)

#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif

INTEGER(KIND=JPIM)           :: KBUF(:,:)
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = SIZE(KBUF)

IF( (LOC(KBUF(UBOUND(KBUF,1),UBOUND(KBUF,2))) - &
   & LOC(KBUF(LBOUND(KBUF,1),LBOUND(KBUF,2)))) /= 4*(ICOUNT - 1) ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND: BUFFER NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(KBUF(1,1),ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(KBUF(1,1),ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(KBUF(1,1),ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_INT2

SUBROUTINE MPL_SEND_INT_SCALAR(KINT,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)

#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif

INTEGER(KIND=JPIM)           :: KINT     
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = 1

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(KINT,ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(KINT,ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(KINT,ICOUNT,INT(MPI_INTEGER),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_INT_SCALAR

SUBROUTINE MPL_SEND_REAL42(PBUF,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)

#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif

! real_m,intent(in) :: PBUF(:,:)
REAL(KIND=JPRM)            :: PBUF(:,:)
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = SIZE(PBUF)

IF( (LOC(PBUF(UBOUND(PBUF,1),UBOUND(PBUF,2))) - &
   & LOC(PBUF(LBOUND(PBUF,1),LBOUND(PBUF,2)))) /= 4*(ICOUNT - 1) ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND: BUFFER NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(PBUF(1,1),ICOUNT,INT(MPI_REAL4),KDEST-1,KTAG,ICOMM,IERROR)
ELSE IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(PBUF(1,1),ICOUNT,INT(MPI_REAL4),KDEST-1,KTAG,ICOMM,IERROR)
ELSE IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(PBUF(1,1),ICOUNT,INT(MPI_REAL4),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ELSE
  IF(PRESENT(KERROR)) THEN
    KERROR=1
  ELSE
    CALL MPL_MESSAGE(KERROR,'MPL_SEND',' INVALID METHOD',LDABORT=LLABORT)
  ENDIF
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_REAL42  

SUBROUTINE MPL_SEND_REAL82(PBUF,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)

#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif

! real_b,intent(in) :: PBUF(:,:)
REAL(KIND=JPRB)            :: PBUF(:,:)
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = SIZE(PBUF)

IF( (LOC(PBUF(UBOUND(PBUF,1),UBOUND(PBUF,2))) - &
   & LOC(PBUF(LBOUND(PBUF,1),LBOUND(PBUF,2)))) /= 8*(ICOUNT - 1) ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND: BUFFER NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(PBUF(1,1),ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(PBUF(1,1),ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(PBUF(1,1),ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_REAL82

SUBROUTINE MPL_SEND_CHAR_SCALAR(CDCHAR,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)

#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif

CHARACTER*(*) :: CDCHAR
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = LEN(CDCHAR)

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(CDCHAR,ICOUNT,INT(MPI_BYTE),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(CDCHAR,ICOUNT,INT(MPI_BYTE),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(CDCHAR,ICOUNT,INT(MPI_BYTE),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_CHAR_SCALAR

SUBROUTINE MPL_SEND_REAL8_SCALAR(PBUF,KDEST,KTAG,KCOMM,KMP_TYPE,KERROR,KREQUEST,CDSTRING)

#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_SEND => MPI_SEND8, MPI_BSEND => MPI_BSEND8, MPI_ISEND => MPI_ISEND8
#endif

REAL(KIND=JPRB)              :: PBUF
INTEGER(KIND=JPIM),INTENT(IN) :: KDEST,KTAG
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: ICOUNT,IMP_TYPE,ICOMM,IERROR
LOGICAL :: LLABORT=.TRUE.
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_SEND: MPL NOT INITIALISED ',LDABORT=LLABORT) 
IF(KDEST < 1 .OR. KDEST >MPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_SEND: ERROR KDEST=',KDEST
  CALL MPL_MESSAGE(CDMESSAGE='MPL_SEND:ILLEGAL KDEST ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KMP_TYPE)) THEN
  IMP_TYPE=KMP_TYPE
ELSE
  IMP_TYPE=MPL_METHOD
ENDIF
IF(PRESENT(KCOMM)) THEN
  ICOMM=KCOMM
ELSE
  ICOMM=MPL_COMM_OML(ITID)
ENDIF

ICOUNT = 1

IF(IMP_TYPE == JP_BLOCKING_STANDARD) THEN
  CALL MPI_SEND(PBUF,ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_BLOCKING_BUFFERED) THEN
  CALL MPI_BSEND(PBUF,ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM,IERROR)
ENDIF
IF(IMP_TYPE == JP_NON_BLOCKING_STANDARD) THEN
  CALL MPI_ISEND(PBUF,ICOUNT,INT(MPI_REAL8),KDEST-1,KTAG,ICOMM, &
    & KREQUEST,IERROR)
ENDIF
IF(MPL_OUTPUT > 1 )THEN
  WRITE(MPL_UNIT,'(A,5I8)') ' MPL_SEND ',ICOUNT,IMP_TYPE,KDEST,KTAG,ICOMM
ENDIF
IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_SEND',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_SEND_REAL8_SCALAR

END MODULE MPL_SEND_MOD
