Index: NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbc_lnk_neicoll_generic.h90
===================================================================
--- NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbc_lnk_neicoll_generic.h90	(revision 14366)
+++ NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbc_lnk_neicoll_generic.h90	(revision 14367)
@@ -17,5 +17,5 @@
       INTEGER  ::   ip0j, ip1j, im0j, im1j
       INTEGER  ::   ishti, ishtj, ishti2, ishtj2
-      INTEGER  ::   iszs, iszr
+      INTEGER  ::   iszS, iszR
       INTEGER  ::   ierr
       INTEGER  ::   ihls, idx
@@ -26,10 +26,9 @@
       INTEGER, DIMENSION(8)  ::   isizej, ishtSj, ishtRj, ishtPj
       INTEGER, DIMENSION(8)  ::   ifill, iszall
-      INTEGER, DIMENSION(:), ALLOCATABLE  ::   icounts, icountr    ! number of elements to be sent/received
-      INTEGER, DIMENSION(:), ALLOCATABLE  ::   idispls, idisplr    ! displacement in halos arrays
+      INTEGER, DIMENSION(:), ALLOCATABLE  ::   iScnt, iRcnt    ! number of elements to be sent/received
+      INTEGER, DIMENSION(:), ALLOCATABLE  ::   iSdpl, iRdpl    ! displacement in halos arrays
       LOGICAL, DIMENSION(8)  ::   llsend, llrecv
       REAL(PRECISION) ::   zland
-      REAL(PRECISION), DIMENSION(:), ALLOCATABLE  ::   zsnd, zrcv          ! halos arrays
-      LOGICAL  ::   ll4only                                        ! default: 8 neighbourgs
+      LOGICAL  ::   ll4only                                    ! default: 8 neighbourgs
       LOGICAL  ::   ll_IdoNFold
       !!----------------------------------------------------------------------
@@ -140,20 +139,30 @@
       !
       ! Allocate local temporary arrays to be sent/received.
-      iszs = COUNT( llsend )
-      iszr = COUNT( llrecv )
-      ALLOCATE( icounts(iszs), icountr(iszr), idispls(iszs), idisplr(iszr) )   ! ok if iszs = 0 or iszr = 0
+      iszS = COUNT( llsend )
+      iszR = COUNT( llrecv )
+      ALLOCATE( iScnt(iszS), iRcnt(iszR), iSdpl(iszS), iRdpl(iszR) )   ! ok if iszS = 0 or iszR = 0
       iszall(:) = isizei(:) * isizej(:) * ipk * ipl * ipf
-      icounts(:) = PACK( iszall, mask = llsend )                                       ! ok if mask = .false.
-      icountr(:) = PACK( iszall, mask = llrecv )
-      idispls(1) = 0
-      DO jn = 2,iszs
-         idispls(jn) = idispls(jn-1) + icounts(jn-1)   ! with _alltoallv: in units of sendtype
-      END DO
-      idisplr(1) = 0
-      DO jn = 2,iszr
-         idisplr(jn) = idisplr(jn-1) + icountr(jn-1)   ! with _alltoallv: in units of sendtype
+      iScnt(:) = PACK( iszall, mask = llsend )                                       ! ok if mask = .false.
+      iRcnt(:) = PACK( iszall, mask = llrecv )
+      iSdpl(1) = 0
+      DO jn = 2,iszS
+         iSdpl(jn) = iSdpl(jn-1) + iScnt(jn-1)   ! with _alltoallv: in units of sendtype
+      END DO
+      iRdpl(1) = 0
+      DO jn = 2,iszR
+         iRdpl(jn) = iRdpl(jn-1) + iRcnt(jn-1)   ! with _alltoallv: in units of sendtype
       END DO
       
-      ALLOCATE( zsnd(SUM(icounts)), zrcv(SUM(icountr)) )
+      ! Allocate buffer arrays to be sent/received if needed
+      iszS = SUM(iszall, mask = llsend)                             ! send buffer size
+      IF( ALLOCATED(BUFFSND) ) THEN
+         IF( SIZE(BUFFSND) < iszS )    DEALLOCATE(BUFFSND)          ! send buffer is too small
+      ENDIF
+      IF( .NOT. ALLOCATED(BUFFSND) )   ALLOCATE( BUFFSND(iszS) )
+      iszR = SUM(iszall, mask = llrecv)                             ! recv buffer size
+      IF( ALLOCATED(BUFFRCV) ) THEN
+         IF( SIZE(BUFFRCV) < iszR )    DEALLOCATE(BUFFRCV)          ! recv buffer is too small
+      ENDIF
+      IF( .NOT. ALLOCATED(BUFFRCV) )   ALLOCATE( BUFFRCV(iszR) )
 
       ! fill sending buffer with ptab(jf)%pt4d
@@ -164,5 +173,5 @@
             ishtj = ishtSj(jn)
             DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
-               zsnd(idx) = ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl)
+               BUFFSND(idx) = ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl)
                idx = idx + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
@@ -175,5 +184,5 @@
       !
       IF( ln_timing ) CALL tic_tac(.TRUE.)
-      CALL mpi_neighbor_alltoallv (zsnd, icounts, idispls, MPI_TYPE, zrcv, icountr, idisplr, MPI_TYPE, impi_nc, ierr)
+      CALL mpi_neighbor_alltoallv (BUFFSND, iScnt, iSdpl, MPI_TYPE, BUFFRCV, iRcnt, iRdpl, MPI_TYPE, impi_nc, ierr)
       IF( ln_timing ) CALL tic_tac(.FALSE.)
       !
@@ -190,5 +199,5 @@
          CASE ( jpfillmpi   )                 ! fill with data received by MPI
             DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
-               ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = zrcv(idx)
+               ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = BUFFRCV(idx)
                idx = idx + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
@@ -212,5 +221,7 @@
       END DO
 
-      DEALLOCATE( icounts, icountr, idispls, idisplr, zsnd, zrcv )
+      DEALLOCATE( iScnt, iRcnt, iSdpl, iRdpl )
+      IF( iszS > jpi*jpj )   DEALLOCATE(BUFFSND)                    ! blocking Send -> can directly deallocate
+      IF( iszR > jpi*jpj )   DEALLOCATE(BUFFRCV)                    ! blocking Recv -> can directly deallocate
 
       ! potential "indirect self-periodicity" for the corners
Index: NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbc_lnk_pt2pt_generic.h90
===================================================================
--- NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbc_lnk_pt2pt_generic.h90	(revision 14366)
+++ NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbc_lnk_pt2pt_generic.h90	(revision 14367)
@@ -1,3 +1,3 @@
-
+  
    SUBROUTINE lbc_lnk_pt2pt_/**/PRECISION( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval, khls, lsend, lrecv, ld4only )
       CHARACTER(len=*)              , INTENT(in   ) ::   cdname      ! name of the calling subroutine
@@ -18,5 +18,5 @@
       INTEGER  ::   ishti, ishtj, ishti2, ishtj2
       INTEGER  ::   ifill_nfd, icomm, ierr
-      INTEGER  ::   ihls, idxs, idxr
+      INTEGER  ::   ihls, idxs, idxr, iszS, iszR
       INTEGER, DIMENSION(4)  ::   iwewe, issnn
       INTEGER, DIMENSION(8)  ::   isizei, ishtSi, ishtRi, ishtPi
@@ -26,5 +26,4 @@
       INTEGER, DIMENSION(8)  ::   iStag, iRtag     ! Send and Recv mpi_tag id
       REAL(PRECISION) ::   zland
-      REAL(PRECISION), DIMENSION(:), ALLOCATABLE  ::   zsnd, zrcv          ! halos arrays
       LOGICAL, DIMENSION(8)  ::   llsend, llrecv
       LOGICAL  ::   ll4only                                        ! default: 8 neighbourgs
@@ -137,5 +136,4 @@
       ! -------------------------------- !
       !
-      ireq(:) = MPI_REQUEST_NULL             ! default definition when no communication is done. understood by mpi_waitall
       iStag = (/ 1, 2, 3, 4, 5, 6, 7, 8 /)   ! any value but each one must be different
       ! define iRtag with the corresponding iStag, e.g. data received at west where sent at east.
@@ -153,6 +151,19 @@
       END DO
 
-      ! Allocate local temporary arrays to be sent/received.
-      ALLOCATE( zsnd( SUM(iszall, mask = llsend) ), zrcv( SUM(iszall, mask = llrecv) ) )
+      ! Allocate buffer arrays to be sent/received if needed
+      iszS = SUM(iszall, mask = llsend)                             ! send buffer size
+      IF( ALLOCATED(BUFFSND) ) THEN
+         CALL mpi_waitall(8, nreq_p2p, MPI_STATUSES_IGNORE, ierr)   ! wait for Isend from the PREVIOUS call
+         IF( SIZE(BUFFSND) < iszS )    DEALLOCATE(BUFFSND)          ! send buffer is too small
+      ENDIF
+      IF( .NOT. ALLOCATED(BUFFSND) )   ALLOCATE( BUFFSND(iszS) )
+      iszR = SUM(iszall, mask = llrecv)                             ! recv buffer size
+      IF( ALLOCATED(BUFFRCV) ) THEN
+         IF( SIZE(BUFFRCV) < iszR )    DEALLOCATE(BUFFRCV)          ! recv buffer is too small
+      ENDIF
+      IF( .NOT. ALLOCATED(BUFFRCV) )   ALLOCATE( BUFFRCV(iszR) )
+      !
+      ! default definition when no communication is done. understood by mpi_waitall
+      nreq_p2p(:) = MPI_REQUEST_NULL   ! WARNING: Must be done after the call to mpi_waitall just above
       !
       ! ----------------------------------------------- !
@@ -165,5 +176,5 @@
             ishtj = ishtSj(jn)
             DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
-               zsnd(idxs) = ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl)
+               BUFFSND(idxs) = ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl)
                idxs = idxs + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
@@ -171,5 +182,5 @@
             IF( ln_timing ) CALL tic_tac(.TRUE.)
             ! non-blocking send of the west/east side using local buffer
-            CALL MPI_ISEND( zsnd(ishtS(jn)+1), iszall(jn), MPI_TYPE, mpiSnei(ihls,jn), iStag(jn), icomm, ireq(jn), ierr )
+            CALL MPI_ISEND( BUFFSND(ishtS(jn)+1), iszall(jn), MPI_TYPE, mpiSnei(ihls,jn), iStag(jn), icomm, nreq_p2p(jn), ierr )
             IF( ln_timing ) CALL tic_tac(.FALSE.)
 #endif
@@ -190,9 +201,9 @@
             IF( ln_timing ) CALL tic_tac(.TRUE.)
             !                                 ! blocking receive of the west/east halo in local temporary arrays
-            CALL MPI_RECV(  zrcv(ishtR(jn)+1), iszall(jn), MPI_TYPE, mpiRnei(ihls,jn), iRtag(jn), icomm, MPI_STATUS_IGNORE, ierr )
-            IF( ln_timing ) CALL tic_tac(.FALSE.)
-#endif
-            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
-               ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = zrcv(idxr)
+            CALL MPI_RECV( BUFFRCV(ishtR(jn)+1), iszall(jn), MPI_TYPE, mpiRnei(ihls,jn), iRtag(jn), icomm, MPI_STATUS_IGNORE, ierr )
+            IF( ln_timing ) CALL tic_tac(.FALSE.)
+#endif
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
+               ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = BUFFRCV(idxr)
                idxr = idxr + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
@@ -237,5 +248,5 @@
             ishtj = ishtSj(jn)
             DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
-               zsnd(idxs) = ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl)
+               BUFFSND(idxs) = ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl)
                idxs = idxs + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
@@ -243,5 +254,5 @@
             IF( ln_timing ) CALL tic_tac(.TRUE.)
             ! non-blocking send of the south/north side using local buffer
-            CALL MPI_ISEND( zsnd(ishtS(jn)+1), iszall(jn), MPI_TYPE, mpiSnei(ihls,jn), iStag(jn), icomm, ireq(jn), ierr )
+            CALL MPI_ISEND( BUFFSND(ishtS(jn)+1), iszall(jn), MPI_TYPE, mpiSnei(ihls,jn), iStag(jn), icomm, nreq_p2p(jn), ierr )
             IF( ln_timing ) CALL tic_tac(.FALSE.)
 #endif
@@ -262,9 +273,9 @@
             IF( ln_timing ) CALL tic_tac(.TRUE.)
             !                                 ! blocking receive of the south/north halo in local temporary arrays
-            CALL MPI_RECV(  zrcv(ishtR(jn)+1), iszall(jn), MPI_TYPE, mpiRnei(ihls,jn), iRtag(jn), icomm, MPI_STATUS_IGNORE, ierr )
-            IF( ln_timing ) CALL tic_tac(.FALSE.)
-#endif
-            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
-               ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = zrcv(idxr)
+            CALL MPI_RECV( BUFFRCV(ishtR(jn)+1), iszall(jn), MPI_TYPE, mpiRnei(ihls,jn), iRtag(jn), icomm, MPI_STATUS_IGNORE, ierr )
+            IF( ln_timing ) CALL tic_tac(.FALSE.)
+#endif
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
+               ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = BUFFRCV(idxr)
                idxr = idxr + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
@@ -298,5 +309,5 @@
             ishtj = ishtSj(jn)
             DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
-               zsnd(idxs) = ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl)
+               BUFFSND(idxs) = ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl)
                idxs = idxs + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
@@ -304,5 +315,5 @@
             IF( ln_timing ) CALL tic_tac(.TRUE.)
             ! non-blocking send of the corners using local buffer
-            CALL MPI_ISEND( zsnd(ishtS(jn)+1), iszall(jn), MPI_TYPE, mpiSnei(ihls,jn), iStag(jn), icomm, ireq(jn), ierr )
+            CALL MPI_ISEND( BUFFSND(ishtS(jn)+1), iszall(jn), MPI_TYPE, mpiSnei(ihls,jn), iStag(jn), icomm, nreq_p2p(jn), ierr )
             IF( ln_timing ) CALL tic_tac(.FALSE.)
 #endif
@@ -314,5 +325,5 @@
             IF( ln_timing ) CALL tic_tac(.TRUE.)
             ! blocking receive of the corner halo in local temporary arrays
-            CALL MPI_RECV(  zrcv(ishtR(jn)+1), iszall(jn), MPI_TYPE, mpiRnei(ihls,jn), iRtag(jn), icomm, MPI_STATUS_IGNORE, ierr )
+            CALL MPI_RECV( BUFFRCV(ishtR(jn)+1), iszall(jn), MPI_TYPE, mpiRnei(ihls,jn), iRtag(jn), icomm, MPI_STATUS_IGNORE, ierr )
             IF( ln_timing ) CALL tic_tac(.FALSE.)
 #endif
@@ -320,5 +331,5 @@
             ishtj = ishtRj(jn)
             DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
-               ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = zrcv(idxr)
+               ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = BUFFRCV(idxr)
                idxr = idxr + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
@@ -328,8 +339,12 @@
       ! -------------------------------------------- !
       !     9. deallocate local temporary arrays     !
+      !        if they areg larger than jpi*jpj      !  <- arbitrary max size...
       ! -------------------------------------------- !
       !
-      CALL mpi_waitall(8, ireq, MPI_STATUSES_IGNORE, ierr)
-      DEALLOCATE( zsnd, zrcv )
+      IF( iszR > jpi*jpj )   DEALLOCATE(BUFFRCV)                    ! blocking receive -> can directly deallocate
+      IF( iszS > jpi*jpj ) THEN
+         CALL mpi_waitall(8, nreq_p2p, MPI_STATUSES_IGNORE, ierr)   ! must wait before deallocate send buffer
+         DEALLOCATE(BUFFSND)
+      ENDIF
       !
    END SUBROUTINE lbc_lnk_pt2pt_/**/PRECISION
Index: NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbclnk.F90
===================================================================
--- NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbclnk.F90	(revision 14366)
+++ NEMO/branches/2021/dev_r14312_MPI_Interface/src/OCE/LBC/lbclnk.F90	(revision 14367)
@@ -50,4 +50,8 @@
    PUBLIC   lbc_lnk_icb        ! iceberg lateral boundary conditions
 
+   REAL(dp), DIMENSION(:), ALLOCATABLE ::   buffsnd_dp, buffrcv_dp   ! MPI send/recv buffers
+   REAL(sp), DIMENSION(:), ALLOCATABLE ::   buffsnd_sp, buffrcv_sp   ! 
+   INTEGER,  DIMENSION(8)              ::   nreq_p2p                 ! request id for MPI_Isend in point-2-point communication
+   
    !! * Substitutions
    !!#  include "do_loop_substitute.h90"
@@ -126,7 +130,11 @@
 #define PRECISION sp
 #  define MPI_TYPE MPI_REAL
+#  define BUFFSND buffsnd_sp
+#  define BUFFRCV buffrcv_sp
 #  include "lbc_lnk_pt2pt_generic.h90"
 #  include "lbc_lnk_neicoll_generic.h90"
 #  undef MPI_TYPE
+#  undef BUFFSND
+#  undef BUFFRCV
 #undef PRECISION
    !!
@@ -135,7 +143,11 @@
 #define PRECISION dp
 #  define MPI_TYPE MPI_DOUBLE_PRECISION
+#  define BUFFSND buffsnd_dp
+#  define BUFFRCV buffrcv_dp
 #  include "lbc_lnk_pt2pt_generic.h90"
 #  include "lbc_lnk_neicoll_generic.h90"
 #  undef MPI_TYPE
+#  undef BUFFSND
+#  undef BUFFRCV
 #undef PRECISION
 
