#ifdef RS6K
@PROCESS NOCHECK
#endif
MODULE MPL_GATHERV_MOD

!**** MPL_GATHERV Gather data to specific processor

!     Purpose.
!     --------
!     Gather data to specific processor
!     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_GATHERV

!        Input required arguments :
!        -------------------------
!           PSENDBUF -  buffer containing message
!                       (can be type REAL*4, REAL*8 or INTEGER)
!           PRECVBUF -  buffer containing message (required from kroot)
!                       (can be type REAL*4, REAL*8 or INTEGER)
!           KRECVCOUNTS-number of elements received from each process
!                       (required from kroot processor)

!        Input optional arguments :
!        -------------------------
!           KROOT    -  rank of receiveing processor (default 1) 
!           KCOMM    -  Communicator number if different from MPI_COMM_WORLD 
!                       or from that established as the default 
!                       by an MPL communicator routine
!           KRECVDISPL -displacements in PRECVBUF at which to place 
!                       the incoming data
!           CDSTRING -  Character string for ABORT messages
!                       used when KERROR is not provided

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

!        Output optional arguments :
!        -------------------------
!           KERROR   -  return error code.     If not supplied, 
!                       MPL_GATHERV aborts when an error is detected.
!     Author.
!     -------
!        D.Dent, M.Hamrud     ECMWF

!     Modifications.
!     --------------
!        Original: 2000-11-23

! --- *NOT* THREAD SAFE YET ---

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

USE PARKIND1  ,ONLY : JPIM     ,JPRB     ,JPRM

USE MPL_MPIF
USE MPL_DATA_MODULE
USE MPL_MESSAGE_MOD
USE MPL_SEND_MOD
USE MPL_RECV_MOD
USE MPL_MYRANK_MOD

IMPLICIT NONE

PRIVATE


!INTEGER(KIND=JPIM) :: ISENDCOUNT,IRECVBUFSIZE
INTEGER(KIND=JPIM),PARAMETER :: ITAG=22222

LOGICAL   :: LLABORT=.TRUE.
REAL(KIND=JPRB)    :: ZDUM_JPRB
REAL(KIND=JPRM)    :: ZDUM_JPRM
INTEGER(KIND=JPIM)    :: ZDUM_INT

INTERFACE MPL_GATHERV
MODULE PROCEDURE MPL_GATHERV_REAL8,MPL_GATHERV_REAL4,MPL_GATHERV_INT,&
               & MPL_GATHERV_INT_SCALAR
END INTERFACE

PUBLIC MPL_GATHERV

CONTAINS

SUBROUTINE MPL_GATHERV_PREAMB1(IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT, &
     & KCOMM,KROOT)


#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_COMM_SIZE => MPI_COMM_SIZE8
#endif



INTEGER(KIND=JPIM),INTENT(OUT) :: IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KROOT
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
INTEGER(KIND=JPIM) :: ITID
ITID = OML_MY_THREAD()
IERROR = 0

IF(MPL_NUMPROC < 1) CALL MPL_MESSAGE( &
  & CDMESSAGE='MPL_GATHERV: MPL NOT INITIALISED ',LDABORT=LLABORT) 

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

IF(ICOMM == MPL_COMM_OML(ITID)) THEN
  IPL_NUMPROC = MPL_NUMPROC
  IPL_MYRANK  = MPL_RANK
ELSE
  CALL MPI_COMM_SIZE(ICOMM,IPL_NUMPROC,IERROR)
  IPL_MYRANK  = MPL_MYRANK(ICOMM)
ENDIF

IF(PRESENT(KROOT)) THEN
  IROOT=KROOT
ELSE
  IROOT=1
ENDIF


END SUBROUTINE MPL_GATHERV_PREAMB1

SUBROUTINE MPL_GATHERV_PREAMB2(IPL_NUMPROC,IPL_MYRANK,IRECVBUFSIZE,ISENDCOUNT,&
     & KRECVCOUNTS,KIRECVDISPL,KRECVDISPL,CDSTRING)

INTEGER(KIND=JPIM),INTENT(IN) :: IPL_NUMPROC,IPL_MYRANK,IRECVBUFSIZE,ISENDCOUNT
INTEGER(KIND=JPIM),INTENT(IN)  :: KRECVCOUNTS(:)
INTEGER(KIND=JPIM),INTENT(OUT) :: KIRECVDISPL(:) 
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:)
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
INTEGER(KIND=JPIM) :: IR


IF(SIZE(KRECVCOUNTS)  < IPL_NUMPROC) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_GATHERV: ERROR KRECVCOUNTS DIMENSION=',&
   & SIZE(KRECVCOUNTS)
  CALL MPL_MESSAGE(CDMESSAGE=&
   & 'MPL_GATHERV: ERROR KRECVCOUNTS DIMENSION IS WRONG',LDABORT=LLABORT)
ENDIF
IF(ISENDCOUNT /= KRECVCOUNTS(IPL_MYRANK)) THEN
  WRITE(MPL_ERRUNIT,*)'MPL_GATHERV: ERROR KRECVCOUNTS INCONSISTENCY ',&
   & ISENDCOUNT,KRECVCOUNTS(IPL_MYRANK)
  CALL MPL_MESSAGE(CDMESSAGE=&
   & 'MPL_GATHERV: ERROR ISENDCOUNT /= KRECVCOUNTS(MPL_RANK) ',LDABORT=LLABORT)
ENDIF

IF(PRESENT(KRECVDISPL)) THEN
  KIRECVDISPL(1:IPL_NUMPROC) = KRECVDISPL(1:IPL_NUMPROC)
ELSE
  KIRECVDISPL(1:IPL_NUMPROC) = 0
  DO IR=2, IPL_NUMPROC
    KIRECVDISPL(IR) = KIRECVDISPL(IR-1) + KRECVCOUNTS(IR-1)
  ENDDO
ENDIF
DO IR=1, IPL_NUMPROC
  IF(KIRECVDISPL(IR)+KRECVCOUNTS(IR) > IRECVBUFSIZE) THEN
    WRITE(MPL_ERRUNIT,'(A,4I10)')'MPL_GATHERV:RECV BUFFER TOO SMALL  ', &
     & IR,KIRECVDISPL(IR),KRECVCOUNTS(IR),IRECVBUFSIZE
    CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV',CDSTRING=CDSTRING,LDABORT=LLABORT)
  ENDIF
ENDDO

END SUBROUTINE MPL_GATHERV_PREAMB2

SUBROUTINE MPL_GATHERV_REAL4(PSENDBUF,KROOT,PRECVBUF,KRECVCOUNTS,KRECVDISPL, &
                            & KCOMM,KERROR,CDSTRING)


#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_GATHERV => MPI_GATHERV8
#endif



REAL(KIND=JPRM),INTENT(IN) :: PSENDBUF(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KROOT
REAL(KIND=JPRM),INTENT(OUT),OPTIONAL  :: PRECVBUF(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVCOUNTS(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: IRECVDISPL(MPL_NUMPROC)
INTEGER(KIND=JPIM) :: IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT
INTEGER(KIND=JPIM) :: IRECVBUFSIZE,ISENDCOUNT


ISENDCOUNT = SIZE(PSENDBUF)
#ifndef NAG
IF( (LOC(PSENDBUF(UBOUND(PSENDBUF,1))) - LOC(PSENDBUF(LBOUND(PSENDBUF,1)))) /= 4*(ISENDCOUNT - 1) .AND. &
  & ISENDCOUNT > 0 ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV: SENDBUF NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF
#endif

CALL MPL_GATHERV_PREAMB1(IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT,KCOMM,KROOT)

IF(IPL_MYRANK == IROOT) THEN
  IF( .NOT. PRESENT(PRECVBUF)) CALL MPL_MESSAGE(&
   & CDMESSAGE='MPL_GATHERV:RECVBUF MISSING',CDSTRING=CDSTRING,LDABORT=LLABORT)

  IRECVBUFSIZE = SIZE(PRECVBUF)
#ifndef NAG
  IF( (LOC(PRECVBUF(UBOUND(PRECVBUF,1))) - LOC(PRECVBUF(LBOUND(PRECVBUF,1)))) /= 4*(IRECVBUFSIZE - 1) .AND. &
    & IRECVBUFSIZE > 0 ) THEN
    CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV: RECVBUF NOT CONTIGUOUS ',LDABORT=LLABORT)
  ENDIF
#endif

  CALL MPL_GATHERV_PREAMB2(IPL_NUMPROC,IPL_MYRANK,IRECVBUFSIZE,ISENDCOUNT,&
       & KRECVCOUNTS,IRECVDISPL,KRECVDISPL,CDSTRING)
  CALL MPI_GATHERV(PSENDBUF(1),ISENDCOUNT,INT(MPI_REAL4),PRECVBUF(1),KRECVCOUNTS, &
   &  IRECVDISPL,INT(MPI_REAL4),IROOT-1,ICOMM,IERROR)
ELSE
  CALL MPI_GATHERV(PSENDBUF(1),ISENDCOUNT,INT(MPI_REAL4),ZDUM_JPRM,1, &
   &  1,INT(MPI_REAL4),IROOT-1,ICOMM,IERROR)
ENDIF

IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_GATHERV',&
   & CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_GATHERV_REAL4

SUBROUTINE MPL_GATHERV_REAL8(PSENDBUF,KROOT,PRECVBUF,KRECVCOUNTS,KRECVDISPL, &
                            & KCOMM,KERROR,CDSTRING)


#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_GATHERV => MPI_GATHERV8
#endif



REAL(KIND=JPRB)            :: PSENDBUF(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVCOUNTS(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KROOT
REAL(KIND=JPRB),OPTIONAL   :: PRECVBUF(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: IRECVDISPL(MPL_NUMPROC)
INTEGER(KIND=JPIM) :: IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT
INTEGER(KIND=JPIM) :: IRECVBUFSIZE,ISENDCOUNT
INTEGER(KIND=JPIM) :: IDUM,IST,IEND,JK


ISENDCOUNT = SIZE(PSENDBUF)
#ifndef NAG
IF( (LOC(PSENDBUF(UBOUND(PSENDBUF,1))) - LOC(PSENDBUF(LBOUND(PSENDBUF,1)))) /= 8*(ISENDCOUNT - 1) .AND. &
  & ISENDCOUNT > 0 ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV: SENDBUF NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF
#endif

CALL MPL_GATHERV_PREAMB1(IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT,KCOMM,KROOT)

IF(IPL_MYRANK == IROOT) THEN
  IF( .NOT. PRESENT(PRECVBUF)) CALL MPL_MESSAGE(&
   & CDMESSAGE='MPL_GATHERV:RECVBUF MISSING',CDSTRING=CDSTRING,LDABORT=LLABORT)
  IRECVBUFSIZE = SIZE(PRECVBUF)
#ifndef NAG
  IF( (LOC(PRECVBUF(UBOUND(PRECVBUF,1))) - LOC(PRECVBUF(LBOUND(PRECVBUF,1)))) /= 8*(IRECVBUFSIZE - 1) .AND. &
    & IRECVBUFSIZE > 0 ) THEN
    CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV: RECVBUF NOT CONTIGUOUS ',LDABORT=LLABORT)
  ENDIF
#endif
  CALL MPL_GATHERV_PREAMB2(IPL_NUMPROC,IPL_MYRANK,IRECVBUFSIZE,ISENDCOUNT,&
       & KRECVCOUNTS,IRECVDISPL,KRECVDISPL,CDSTRING)
  IF(LUSEHLMPI .OR. ICOMM /= MPL_COMM)THEN
    CALL MPI_GATHERV(PSENDBUF(1),ISENDCOUNT,INT(MPI_REAL8),PRECVBUF(1),KRECVCOUNTS,&
     &  IRECVDISPL,INT(MPI_REAL8),IROOT-1,ICOMM,IERROR)
  ELSE
    DO JK=1,IPL_NUMPROC
      IST = IRECVDISPL(JK)+1
      IEND = IST+KRECVCOUNTS(JK)-1
      IF(JK /= MPL_RANK) THEN
        CALL MPL_SEND(MPL_RANK,KTAG=ITAG,KDEST=JK)
        CALL MPL_RECV(PRECVBUF(IST:IEND),KTAG=ITAG,KSOURCE=JK)
      ELSE
        PRECVBUF(IST:IEND) = PSENDBUF(1:ISENDCOUNT)
      ENDIF
    ENDDO
  ENDIF
ELSE
  IF(LUSEHLMPI .OR. ICOMM /= MPL_COMM)THEN
    CALL MPI_GATHERV(PSENDBUF(1),ISENDCOUNT,INT(MPI_REAL8),ZDUM_JPRB,1, &
     &  1,INT(MPI_REAL8),IROOT-1,ICOMM,IERROR)
  ELSE
    CALL MPL_RECV(IDUM,KTAG=ITAG,KSOURCE=IROOT)
    CALL MPL_SEND(PSENDBUF(1:ISENDCOUNT),KTAG=ITAG,KDEST=IROOT)
  ENDIF
ENDIF

IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_GATHERV',CDSTRING,&
   & LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_GATHERV_REAL8

SUBROUTINE MPL_GATHERV_INT(KSENDBUF,KROOT,KRECVBUF,KRECVCOUNTS,KRECVDISPL, &
                            & KCOMM,KERROR,CDSTRING)


#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_GATHERV => MPI_GATHERV8
#endif



INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KROOT
INTEGER(KIND=JPIM),INTENT(IN)         :: KSENDBUF(:)
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KRECVBUF(:)
INTEGER(KIND=JPIM),INTENT(IN) :: KRECVCOUNTS(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: IRECVDISPL(MPL_NUMPROC)
INTEGER(KIND=JPIM) :: IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT
INTEGER(KIND=JPIM) :: IRECVBUFSIZE,ISENDCOUNT

ISENDCOUNT = SIZE(KSENDBUF)
#ifndef NAG
IF( (LOC(KSENDBUF(UBOUND(KSENDBUF,1))) - LOC(KSENDBUF(LBOUND(KSENDBUF,1)))) /= 4*(ISENDCOUNT - 1) .AND. &
  & ISENDCOUNT > 0 ) THEN
  CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV: SENDBUF NOT CONTIGUOUS ',LDABORT=LLABORT)
ENDIF
#endif

CALL MPL_GATHERV_PREAMB1(IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT,KCOMM,KROOT)

IF(IPL_MYRANK == IROOT) THEN
  IF( .NOT. PRESENT(KRECVBUF)) CALL MPL_MESSAGE(&
   & CDMESSAGE='MPL_GATHERV:RECVBUF MISSING',CDSTRING=CDSTRING,LDABORT=LLABORT)

  IRECVBUFSIZE = SIZE(KRECVBUF)
#ifndef NAG
  IF( (LOC(KRECVBUF(UBOUND(KRECVBUF,1))) - LOC(KRECVBUF(LBOUND(KRECVBUF,1)))) /= 4*(IRECVBUFSIZE - 1) .AND. &
    & IRECVBUFSIZE > 0 ) THEN
    CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV: RECVBUF NOT CONTIGUOUS ',LDABORT=LLABORT)
  ENDIF
#endif

  CALL MPL_GATHERV_PREAMB2(IPL_NUMPROC,IPL_MYRANK,IRECVBUFSIZE,ISENDCOUNT,&
       & KRECVCOUNTS,IRECVDISPL,KRECVDISPL,CDSTRING)
  CALL MPI_GATHERV(KSENDBUF(1),ISENDCOUNT,INT(MPI_INTEGER),KRECVBUF(1),&
   & KRECVCOUNTS,IRECVDISPL,INT(MPI_INTEGER),IROOT-1,ICOMM,IERROR)
ELSE
  CALL MPI_GATHERV(KSENDBUF(1),ISENDCOUNT,INT(MPI_INTEGER),ZDUM_INT,1, &
   &  1,INT(MPI_INTEGER),IROOT-1,ICOMM,IERROR)
ENDIF

IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_GATHERV',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_GATHERV_INT

SUBROUTINE MPL_GATHERV_INT_SCALAR(KSENDBUF,KROOT,KRECVBUF,KRECVCOUNTS,&
 & KRECVDISPL,KCOMM,KERROR,CDSTRING)


#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_GATHERV => MPI_GATHERV8, MPI_GATHER => MPI_GATHER8
#endif



INTEGER(KIND=JPIM),INTENT(IN) :: KSENDBUF
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KROOT
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KRECVBUF(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVCOUNTS(:) ! Not used; for compatibility only
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: IRECVDISPL(MPL_NUMPROC),IRECVCOUNTS(MPL_NUMPROC)
INTEGER(KIND=JPIM) :: IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT
INTEGER(KIND=JPIM) :: IRECVBUFSIZE,ISENDCOUNT

ISENDCOUNT = 1
CALL MPL_GATHERV_PREAMB1(IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT,KCOMM,KROOT)

IF(IPL_MYRANK == IROOT) THEN
  IF( .NOT. PRESENT(KRECVBUF)) CALL MPL_MESSAGE(&
   & CDMESSAGE='MPL_GATHERV:RECVBUF MISSING',CDSTRING=CDSTRING,LDABORT=LLABORT)
  IRECVBUFSIZE = SIZE(KRECVBUF)
  IF(PRESENT(KRECVDISPL)) THEN
    IRECVCOUNTS(:) = 1
    CALL MPL_GATHERV_PREAMB2(IPL_NUMPROC,IPL_MYRANK,IRECVBUFSIZE,ISENDCOUNT,&
         & IRECVCOUNTS,IRECVDISPL,KRECVDISPL,CDSTRING)
    CALL MPI_GATHERV(KSENDBUF,ISENDCOUNT,INT(MPI_INTEGER),KRECVBUF(1),&
     & IRECVCOUNTS,IRECVDISPL,INT(MPI_INTEGER),IROOT-1,ICOMM,IERROR)
  ELSE
    IF(IRECVBUFSIZE < IPL_NUMPROC) THEN
      CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV:IRECVBUFSIZE < IPL_NUMPROC',&
       & CDSTRING=CDSTRING,LDABORT=LLABORT)
    ENDIF
    CALL MPI_GATHER(KSENDBUF,ISENDCOUNT,INT(MPI_INTEGER),KRECVBUF(1),&
     & ISENDCOUNT,INT(MPI_INTEGER),IROOT-1,ICOMM,IERROR)
  ENDIF
ELSE
  IF(PRESENT(KRECVDISPL)) THEN
    CALL MPI_GATHERV(KSENDBUF,ISENDCOUNT,INT(MPI_INTEGER),ZDUM_INT,1, &
     &  1,INT(MPI_INTEGER),IROOT-1,ICOMM,IERROR)
  ELSE
    CALL MPI_GATHER(KSENDBUF,ISENDCOUNT,INT(MPI_INTEGER),ZDUM_INT,&
     & 1,INT(MPI_INTEGER),IROOT-1,ICOMM,IERROR)
  ENDIF
ENDIF

IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_GATHERV',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_GATHERV_INT_SCALAR

SUBROUTINE MPL_GATHERV_REAL8_SCALAR(PSENDBUF,KROOT,PRECVBUF,KRECVCOUNTS,&
 & KRECVDISPL,KCOMM,KERROR,CDSTRING)


#ifdef USE_8_BYTE_WORDS
  Use mpi4to8, Only : &
    MPI_GATHERV => MPI_GATHERV8, MPI_GATHER => MPI_GATHER8
#endif



REAL(KIND=JPRB),INTENT(IN) :: PSENDBUF
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KROOT
REAL(KIND=JPRB),INTENT(OUT),OPTIONAL :: PRECVBUF(:)
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVCOUNTS(:) ! Not used; for compatibility only
INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM
INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING

INTEGER(KIND=JPIM) :: IRECVDISPL(MPL_NUMPROC),IRECVCOUNTS(MPL_NUMPROC)
INTEGER(KIND=JPIM) :: IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT
INTEGER(KIND=JPIM) :: IRECVBUFSIZE,ISENDCOUNT

ISENDCOUNT = 1
CALL MPL_GATHERV_PREAMB1(IERROR,IPL_NUMPROC,IPL_MYRANK,ICOMM,IROOT,KCOMM,KROOT)

IF(IPL_MYRANK == IROOT) THEN
  IF( .NOT. PRESENT(PRECVBUF)) CALL MPL_MESSAGE(&
   & CDMESSAGE='MPL_GATHERV:RECVBUF MISSING',CDSTRING=CDSTRING,LDABORT=LLABORT)
  IRECVBUFSIZE = SIZE(PRECVBUF)
  IF(PRESENT(KRECVDISPL)) THEN
    IRECVCOUNTS(:) = 1
    CALL MPL_GATHERV_PREAMB2(IPL_NUMPROC,IPL_MYRANK,IRECVBUFSIZE,ISENDCOUNT,&
         & IRECVCOUNTS,IRECVDISPL,KRECVDISPL,CDSTRING)
    CALL MPI_GATHERV(PSENDBUF,ISENDCOUNT,INT(MPI_REAL8),PRECVBUF(1),&
     & IRECVCOUNTS,IRECVDISPL,INT(MPI_REAL8),IROOT-1,ICOMM,IERROR)
  ELSE
    IF(IRECVBUFSIZE < IPL_NUMPROC) THEN
      CALL MPL_MESSAGE(CDMESSAGE='MPL_GATHERV:IRECVBUFSIZE < IPL_NUMPROC',&
       & CDSTRING=CDSTRING,LDABORT=LLABORT)
    ENDIF
    CALL MPI_GATHER(PSENDBUF,ISENDCOUNT,INT(MPI_REAL8),PRECVBUF(1),&
     & ISENDCOUNT,INT(MPI_REAL8),IROOT-1,ICOMM,IERROR)
  ENDIF
ELSE
  IF(PRESENT(KRECVDISPL)) THEN
    CALL MPI_GATHERV(PSENDBUF,ISENDCOUNT,INT(MPI_REAL8),ZDUM_JPRB,1, &
     &  1,INT(MPI_REAL8),IROOT-1,ICOMM,IERROR)
  ELSE
    CALL MPI_GATHER(PSENDBUF,ISENDCOUNT,INT(MPI_REAL8),ZDUM_JPRB,&
     & 1,INT(MPI_REAL8),IROOT-1,ICOMM,IERROR)
  ENDIF
ENDIF

IF(PRESENT(KERROR)) THEN
  KERROR=IERROR
ELSE
  IF(IERROR /= 0 ) CALL MPL_MESSAGE(IERROR,'MPL_GATHERV',CDSTRING,LDABORT=LLABORT)
ENDIF

END SUBROUTINE MPL_GATHERV_REAL8_SCALAR

END MODULE MPL_GATHERV_MOD
