New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
Changeset 4230 for branches/2013/dev_LOCEAN_CMCC_INGV_2013/NEMOGCM/NEMO/OPA_SRC/LBC/lib_mpp.F90 – NEMO

Ignore:
Timestamp:
2013-11-18T12:57:11+01:00 (10 years ago)
Author:
cetlod
Message:

dev_LOCEAN_CMCC_INGV_2013 : merge LOCEAN & CMCC_INGV branches, see ticket #1182

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2013/dev_LOCEAN_CMCC_INGV_2013/NEMOGCM/NEMO/OPA_SRC/LBC/lib_mpp.F90

    r4162 r4230  
    2222   !!                          'mpp_lnk_bdy_2d' and 'mpp_lnk_obc_2d' routines and update 
    2323   !!                          the mppobc routine to optimize the BDY and OBC communications 
    24    !!            3.6  !  2013  ( C. Ethe, G. Madec ) message passing arrays as local variables  
     24   !!            3.5  !  2013  ( C. Ethe, G. Madec ) message passing arrays as local variables  
     25   !!            3.5  !  2013 (S.Mocavero, I.Epicoco - CMCC) north fold optimizations 
    2526   !!---------------------------------------------------------------------- 
    2627 
     
    151152   REAL(wp), DIMENSION(:), ALLOCATABLE, SAVE :: tampon  ! buffer in case of bsend 
    152153 
    153    ! North fold arrays used to minimise the use of allgather operations. Set in nemo_northcomms (nemogcm) so need to be public 
    154    INTEGER, PUBLIC,  PARAMETER :: jpmaxngh = 8                 ! Assumed maximum number of active neighbours 
    155    INTEGER, PUBLIC,  PARAMETER :: jptyps   = 5                 ! Number of different neighbour lists to be used for northfold exchanges 
    156    INTEGER, PUBLIC,  DIMENSION (jpmaxngh,jptyps)    ::   isendto 
    157    INTEGER, PUBLIC,  DIMENSION (jptyps)             ::   nsndto 
    158    LOGICAL, PUBLIC                                  ::   ln_nnogather     = .FALSE.  ! namelist control of northfold comms 
     154   LOGICAL, PUBLIC                                  ::   ln_nnogather       ! namelist control of northfold comms 
    159155   LOGICAL, PUBLIC                                  ::   l_north_nogather = .FALSE.  ! internal control of northfold comms 
    160156   INTEGER, PUBLIC                                  ::   ityp 
     
    25922588      CHARACTER(len=1)                , INTENT(in   ) ::   cd_type   ! nature of pt3d grid-points 
    25932589      !                                                              !   = T ,  U , V , F or W  gridpoints 
    2594       REAL(wp)                        , INTENT(in   ) ::   psgn      ! = -1. the sign change across the north fold 
     2590      REAL(wp)                        , INTENT(in   ) ::   psgn      ! = -1. the sign change across the north fold  
    25952591      !!                                                             ! =  1. , the sign is kept 
    2596       INTEGER ::   ji, jj, jr 
     2592      INTEGER ::   ji, jj, jr, jk 
    25972593      INTEGER ::   ierr, itaille, ildi, ilei, iilb 
    25982594      INTEGER ::   ijpj, ijpjm1, ij, iproc 
    2599       INTEGER, DIMENSION (jpmaxngh)          ::   ml_req_nf          ! for mpi_isend when avoiding mpi_allgather 
     2595      INTEGER, DIMENSION (jpmaxngh)          ::   ml_req_nf          !for mpi_isend when avoiding mpi_allgather 
    26002596      INTEGER                                ::   ml_err             ! for mpi_isend when avoiding mpi_allgather 
    26012597      INTEGER, DIMENSION(MPI_STATUS_SIZE)    ::   ml_stat            ! for mpi_isend when avoiding mpi_allgather 
     
    26042600      REAL(wp), DIMENSION(:,:,:)  , ALLOCATABLE   :: znorthloc, zfoldwk       
    26052601      REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE   :: znorthgloio 
    2606  
    2607       !!---------------------------------------------------------------------- 
    2608       ! 
    2609       ALLOCATE( ztab(jpiglo,4,jpk), znorthloc(jpi,4,jpk), zfoldwk(jpi,4,jpk), znorthgloio(jpi,4,jpk,jpni) ) 
     2602      REAL(wp), DIMENSION(:,:,:)  , ALLOCATABLE   :: ztabl, ztabr 
     2603 
     2604      INTEGER :: istatus(mpi_status_size) 
     2605      INTEGER :: iflag 
     2606      !!---------------------------------------------------------------------- 
     2607      ! 
     2608      ALLOCATE( ztab(jpiglo,4,jpk) , znorthloc(jpi,4,jpk), zfoldwk(jpi,4,jpk), znorthgloio(jpi,4,jpk,jpni) ) 
     2609      ALLOCATE( ztabl(jpi,4,jpk), ztabr(jpi*jpmaxngh, 4, jpk) )  
    26102610 
    26112611      ijpj   = 4 
    2612       ityp = -1 
    26132612      ijpjm1 = 3 
    2614       ztab(:,:,:) = 0.e0 
    2615       ! 
    2616       DO jj = nlcj - ijpj +1, nlcj          ! put in znorthloc the last 4 jlines of pt3d 
    2617          ij = jj - nlcj + ijpj 
    2618          znorthloc(:,ij,:) = pt3d(:,jj,:) 
     2613      ! 
     2614      DO jk = 1, jpk 
     2615         DO jj = nlcj - ijpj +1, nlcj          ! put in xnorthloc the last 4 jlines of pt3d 
     2616            ij = jj - nlcj + ijpj 
     2617            znorthloc(:,ij,jk) = pt3d(:,jj,jk) 
     2618         END DO 
    26192619      END DO 
    26202620      ! 
    26212621      !                                     ! Build in procs of ncomm_north the znorthgloio 
    26222622      itaille = jpi * jpk * ijpj 
     2623 
     2624 
    26232625      IF ( l_north_nogather ) THEN 
    26242626         ! 
    2625          ! Avoid the use of mpi_allgather by exchanging only with the processes already identified 
    2626          ! (in nemo_northcomms) as being  involved in this process' northern boundary exchange 
    2627          ! 
    2628          DO jj = nlcj-ijpj+1, nlcj          ! First put local values into the global array 
    2629             ij = jj - nlcj + ijpj 
    2630             DO ji = 1, nlci 
    2631                ztab(ji+nimpp-1,ij,:) = pt3d(ji,jj,:) 
     2627        ztabr(:,:,:) = 0 
     2628        DO jk = 1, jpk 
     2629           DO jj = nlcj-ijpj+1, nlcj          ! First put local values into the global array 
     2630              ij = jj - nlcj + ijpj 
     2631              DO ji = 1, nlci 
     2632                 ztabl(ji,ij,jk) = pt3d(ji,jj,jk) 
     2633              END DO 
     2634           END DO 
     2635        END DO 
     2636 
     2637         DO jr = 1,nsndto 
     2638            IF (isendto(jr) .ne. narea) CALL mppsend( 5, znorthloc, itaille, isendto(jr)-1, ml_req_nf(jr) ) 
     2639         END DO 
     2640         DO jr = 1,nsndto 
     2641            iproc = isendto(jr) 
     2642            ildi = nldit (iproc) 
     2643            ilei = nleit (iproc) 
     2644            iilb = nimppt(isendto(jr)) - nimppt(isendto(1)) 
     2645            IF(isendto(jr) .ne. narea) THEN 
     2646              CALL mpprecv(5, zfoldwk, itaille, isendto(jr)-1) 
     2647              DO jk = 1, jpk 
     2648                 DO jj = 1, ijpj 
     2649                    DO ji = 1, ilei 
     2650                       ztabr(iilb+ji,jj,jk) = zfoldwk(ji,jj,jk) 
     2651                    END DO 
     2652                 END DO 
     2653              END DO 
     2654           ELSE 
     2655              DO jk = 1, jpk 
     2656                 DO jj = 1, ijpj 
     2657                    DO ji = 1, ilei 
     2658                       ztabr(iilb+ji,jj,jk) = pt3d(ji,nlcj-ijpj+jj,jk) 
     2659                    END DO 
     2660                 END DO 
     2661              END DO 
     2662           ENDIF 
     2663         END DO 
     2664         IF (l_isend) THEN 
     2665            DO jr = 1,nsndto 
     2666               IF (isendto(jr) .ne. narea) CALL mpi_wait(ml_req_nf(jr), ml_stat, ml_err) 
    26322667            END DO 
    2633          END DO 
    2634  
    2635          ! 
    2636          ! Set the exchange type in order to access the correct list of active neighbours 
    2637          ! 
    2638          SELECT CASE ( cd_type ) 
    2639             CASE ( 'T' , 'W' ) 
    2640                ityp = 1 
    2641             CASE ( 'U' ) 
    2642                ityp = 2 
    2643             CASE ( 'V' ) 
    2644                ityp = 3 
    2645             CASE ( 'F' ) 
    2646                ityp = 4 
    2647             CASE ( 'I' ) 
    2648                ityp = 5 
    2649             CASE DEFAULT 
    2650                ityp = -1                    ! Set a default value for unsupported types which 
    2651                                             ! will cause a fallback to the mpi_allgather method 
    2652          END SELECT 
    2653          IF ( ityp .gt. 0 ) THEN 
    2654  
    2655             DO jr = 1,nsndto(ityp) 
    2656                CALL mppsend(5, znorthloc, itaille, isendto(jr,ityp), ml_req_nf(jr) ) 
    2657             END DO 
    2658             DO jr = 1,nsndto(ityp) 
    2659                CALL mpprecv(5, zfoldwk, itaille, isendto(jr,ityp)) 
    2660                iproc = isendto(jr,ityp) + 1 
    2661                ildi = nldit (iproc) 
    2662                ilei = nleit (iproc) 
    2663                iilb = nimppt(iproc) 
    2664                DO jj = 1, ijpj 
    2665                   DO ji = ildi, ilei 
    2666                      ztab(ji+iilb-1,jj,:) = zfoldwk(ji,jj,:) 
    2667                   END DO 
     2668         ENDIF 
     2669         CALL mpp_lbc_nfd( ztabl, ztabr_3d, cd_type, psgn )   ! North fold boundary condition 
     2670         ! 
     2671         DO jk = 1, jpk 
     2672            DO jj = nlcj-ijpj+1, nlcj             ! Scatter back to pt3d 
     2673               ij = jj - nlcj + ijpj 
     2674               DO ji= 1, nlci 
     2675                  pt3d(ji,jj,jk) = ztabl(ji,ij,jk) 
    26682676               END DO 
    26692677            END DO 
    2670             IF (l_isend) THEN 
    2671                DO jr = 1,nsndto(ityp) 
    2672                   CALL mpi_wait(ml_req_nf(jr), ml_stat, ml_err) 
    2673                END DO 
    2674             ENDIF 
    2675  
    2676          ENDIF 
    2677  
    2678       ENDIF 
    2679  
    2680       IF ( ityp .lt. 0 ) THEN 
     2678         END DO 
     2679         ! 
     2680 
     2681      ELSE 
    26812682         CALL MPI_ALLGATHER( znorthloc  , itaille, MPI_DOUBLE_PRECISION,                & 
    26822683            &                znorthgloio, itaille, MPI_DOUBLE_PRECISION, ncomm_north, ierr ) 
    26832684         ! 
     2685         ztab(:,:,:) = 0.e0 
    26842686         DO jr = 1, ndim_rank_north         ! recover the global north array 
    26852687            iproc = nrank_north(jr) + 1 
     
    26872689            ilei  = nleit (iproc) 
    26882690            iilb  = nimppt(iproc) 
    2689             DO jj = 1, ijpj 
    2690                DO ji = ildi, ilei 
    2691                   ztab(ji+iilb-1,jj,:) = znorthgloio(ji,jj,:,jr) 
     2691            DO jk = 1, jpk 
     2692               DO jj = 1, ijpj 
     2693                  DO ji = ildi, ilei 
     2694                    ztab(ji+iilb-1,jj,jk) = znorthgloio(ji,jj,jk,jr) 
     2695                  END DO 
    26922696               END DO 
    26932697            END DO 
    26942698         END DO 
     2699         CALL lbc_nfd( ztab, cd_type, psgn )   ! North fold boundary condition 
     2700         ! 
     2701         DO jk = 1, jpk 
     2702            DO jj = nlcj-ijpj+1, nlcj             ! Scatter back to pt3d 
     2703               ij = jj - nlcj + ijpj 
     2704               DO ji= 1, nlci 
     2705                  pt3d(ji,jj,jk) = ztab(ji+nimpp-1,ij,jk) 
     2706               END DO 
     2707            END DO 
     2708         END DO 
     2709         ! 
    26952710      ENDIF 
    26962711      ! 
     
    27042719      CALL lbc_nfd( ztab, cd_type, psgn )   ! North fold boundary condition 
    27052720      ! 
    2706       DO jj = nlcj-ijpj+1, nlcj             ! Scatter back to pt3d 
    2707          ij = jj - nlcj + ijpj 
    2708          DO ji= 1, nlci 
    2709             pt3d(ji,jj,:) = ztab(ji+nimpp-1,ij,:) 
    2710          END DO 
     2721      DO jk = 1, jpk 
     2722         DO jj = nlcj-ijpj+1, nlcj             ! Scatter back to pt3d 
     2723            ij = jj - nlcj + ijpj 
     2724            DO ji= 1, nlci 
     2725               pt3d(ji,jj,jk) = ztab(ji+nimpp-1,ij,jk) 
     2726            END DO 
     2727        END DO 
    27112728      END DO 
    27122729      ! 
    27132730      DEALLOCATE( ztab, znorthloc, zfoldwk, znorthgloio ) 
     2731      DEALLOCATE( ztabl, ztabr )  
    27142732      ! 
    27152733   END SUBROUTINE mpp_lbc_north_3d 
     
    27302748      !! 
    27312749      !!---------------------------------------------------------------------- 
    2732       REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) ::   pt2d      ! 3D array on which the b.c. is applied 
    2733       CHARACTER(len=1)            , INTENT(in   ) ::   cd_type   ! nature of pt3d grid-points 
     2750      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) ::   pt2d      ! 2D array on which the b.c. is applied 
     2751      CHARACTER(len=1)            , INTENT(in   ) ::   cd_type   ! nature of pt2d grid-points 
    27342752      !                                                          !   = T ,  U , V , F or W  gridpoints 
    2735       REAL(wp)                    , INTENT(in   ) ::   psgn      ! = -1. the sign change across the north fold 
     2753      REAL(wp)                    , INTENT(in   ) ::   psgn      ! = -1. the sign change across the north fold  
    27362754      !!                                                             ! =  1. , the sign is kept 
    27372755      INTEGER ::   ji, jj, jr 
    27382756      INTEGER ::   ierr, itaille, ildi, ilei, iilb 
    27392757      INTEGER ::   ijpj, ijpjm1, ij, iproc 
    2740       INTEGER, DIMENSION (jpmaxngh)      ::   ml_req_nf          ! for mpi_isend when avoiding mpi_allgather 
     2758      INTEGER, DIMENSION (jpmaxngh)      ::   ml_req_nf          !for mpi_isend when avoiding mpi_allgather 
    27412759      INTEGER                            ::   ml_err             ! for mpi_isend when avoiding mpi_allgather 
    27422760      INTEGER, DIMENSION(MPI_STATUS_SIZE)::   ml_stat            ! for mpi_isend when avoiding mpi_allgather 
     
    27452763      REAL(wp), DIMENSION(:,:)  , ALLOCATABLE   :: znorthloc, zfoldwk       
    27462764      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE   :: znorthgloio 
     2765      REAL(wp), DIMENSION(:,:)  , ALLOCATABLE   :: ztabl, ztabr 
     2766      INTEGER :: istatus(mpi_status_size) 
     2767      INTEGER :: iflag 
    27472768      !!---------------------------------------------------------------------- 
    27482769      ! 
    27492770      ALLOCATE( ztab(jpiglo,4), znorthloc(jpi,4), zfoldwk(jpi,4), znorthgloio(jpi,4,jpni) ) 
     2771      ALLOCATE( ztabl(jpi,4), ztabr(jpi*jpmaxngh, 4) )  
    27502772      ! 
    27512773      ijpj   = 4 
    2752       ityp = -1 
    27532774      ijpjm1 = 3 
    2754       ztab(:,:) = 0.e0 
    27552775      ! 
    27562776      DO jj = nlcj-ijpj+1, nlcj             ! put in znorthloc the last 4 jlines of pt2d 
     
    27632783      IF ( l_north_nogather ) THEN 
    27642784         ! 
    2765          ! Avoid the use of mpi_allgather by exchanging only with the processes already identified 
     2785         ! Avoid the use of mpi_allgather by exchanging only with the processes already identified  
    27662786         ! (in nemo_northcomms) as being  involved in this process' northern boundary exchange 
    27672787         ! 
     2788         ztabr(:,:) = 0 
    27682789         DO jj = nlcj-ijpj+1, nlcj          ! First put local values into the global array 
    27692790            ij = jj - nlcj + ijpj 
    27702791            DO ji = 1, nlci 
    2771                ztab(ji+nimpp-1,ij) = pt2d(ji,jj) 
     2792               ztabl(ji,ij) = pt2d(ji,jj) 
    27722793            END DO 
    27732794         END DO 
    27742795 
    2775          ! 
    2776          ! Set the exchange type in order to access the correct list of active neighbours 
    2777          ! 
    2778          SELECT CASE ( cd_type ) 
    2779             CASE ( 'T' , 'W' ) 
    2780                ityp = 1 
    2781             CASE ( 'U' ) 
    2782                ityp = 2 
    2783             CASE ( 'V' ) 
    2784                ityp = 3 
    2785             CASE ( 'F' ) 
    2786                ityp = 4 
    2787             CASE ( 'I' ) 
    2788                ityp = 5 
    2789             CASE DEFAULT 
    2790                ityp = -1                    ! Set a default value for unsupported types which 
    2791                                             ! will cause a fallback to the mpi_allgather method 
    2792          END SELECT 
    2793  
    2794          IF ( ityp .gt. 0 ) THEN 
    2795  
    2796             DO jr = 1,nsndto(ityp) 
    2797                CALL mppsend(5, znorthloc, itaille, isendto(jr,ityp), ml_req_nf(jr) ) 
     2796         DO jr = 1,nsndto 
     2797            IF (isendto(jr) .ne. narea) CALL mppsend(5, znorthloc, itaille, isendto(jr)-1, ml_req_nf(jr)) 
     2798         END DO 
     2799         DO jr = 1,nsndto 
     2800            iproc = isendto(jr) 
     2801            ildi = nldit (iproc) 
     2802            ilei = nleit (iproc) 
     2803            iilb = nimppt(isendto(jr)) - nimppt(isendto(1)) 
     2804            IF(isendto(jr) .ne. narea) THEN 
     2805              CALL mpprecv(5, zfoldwk, itaille, isendto(jr)-1) 
     2806              DO jj = 1, ijpj 
     2807                 DO ji = 1, ilei 
     2808                    ztabr(iilb+ji,jj) = zfoldwk(ji,jj) 
     2809                 END DO 
     2810              END DO 
     2811            ELSE 
     2812              DO jj = 1, ijpj 
     2813                 DO ji = 1, ilei 
     2814                    ztabr(iilb+ji,jj) = pt2d(ji,nlcj-ijpj+jj) 
     2815                 END DO 
     2816              END DO 
     2817            ENDIF 
     2818         END DO 
     2819         IF (l_isend) THEN 
     2820            DO jr = 1,nsndto 
     2821               IF (isendto(jr) .ne. narea) CALL mpi_wait(ml_req_nf(jr), ml_stat, ml_err) 
    27982822            END DO 
    2799             DO jr = 1,nsndto(ityp) 
    2800                CALL mpprecv(5, zfoldwk, itaille, isendto(jr,ityp)) 
    2801                iproc = isendto(jr,ityp) + 1 
    2802                ildi = nldit (iproc) 
    2803                ilei = nleit (iproc) 
    2804                iilb = nimppt(iproc) 
    2805                DO jj = 1, ijpj 
    2806                   DO ji = ildi, ilei 
    2807                      ztab(ji+iilb-1,jj) = zfoldwk(ji,jj) 
    2808                   END DO 
    2809                END DO 
     2823         ENDIF 
     2824         CALL mpp_lbc_nfd( ztabl, ztabr, cd_type, psgn )   ! North fold boundary condition 
     2825         ! 
     2826         DO jj = nlcj-ijpj+1, nlcj             ! Scatter back to pt2d 
     2827            ij = jj - nlcj + ijpj 
     2828            DO ji = 1, nlci 
     2829               pt2d(ji,jj) = ztabl(ji,ij) 
    28102830            END DO 
    2811             IF (l_isend) THEN 
    2812                DO jr = 1,nsndto(ityp) 
    2813                   CALL mpi_wait(ml_req_nf(jr), ml_stat, ml_err) 
    2814                END DO 
    2815             ENDIF 
    2816  
    2817          ENDIF 
    2818  
    2819       ENDIF 
    2820  
    2821       IF ( ityp .lt. 0 ) THEN 
     2831         END DO 
     2832         ! 
     2833      ELSE 
    28222834         CALL MPI_ALLGATHER( znorthloc  , itaille, MPI_DOUBLE_PRECISION,        & 
    28232835            &                znorthgloio, itaille, MPI_DOUBLE_PRECISION, ncomm_north, ierr ) 
    28242836         ! 
     2837         ztab(:,:) = 0.e0 
    28252838         DO jr = 1, ndim_rank_north            ! recover the global north array 
    28262839            iproc = nrank_north(jr) + 1 
     
    28342847            END DO 
    28352848         END DO 
    2836       ENDIF 
    2837       ! 
    2838       ! The ztab array has been either: 
    2839       !  a. Fully populated by the mpi_allgather operation or 
    2840       !  b. Had the active points for this domain and northern neighbours populated 
    2841       !     by peer to peer exchanges 
    2842       ! Either way the array may be folded by lbc_nfd and the result for the span of 
    2843       ! this domain will be identical. 
    2844       ! 
    2845       CALL lbc_nfd( ztab, cd_type, psgn )   ! North fold boundary condition 
    2846       ! 
    2847       ! 
    2848       DO jj = nlcj-ijpj+1, nlcj             ! Scatter back to pt2d 
    2849          ij = jj - nlcj + ijpj 
    2850          DO ji = 1, nlci 
    2851             pt2d(ji,jj) = ztab(ji+nimpp-1,ij) 
    2852          END DO 
    2853       END DO 
    2854       ! 
     2849         CALL lbc_nfd( ztab, cd_type, psgn )   ! North fold boundary condition 
     2850         ! 
     2851         DO jj = nlcj-ijpj+1, nlcj             ! Scatter back to pt2d 
     2852            ij = jj - nlcj + ijpj 
     2853            DO ji = 1, nlci 
     2854               pt2d(ji,jj) = ztab(ji+nimpp-1,ij) 
     2855            END DO 
     2856         END DO 
     2857         ! 
     2858      ENDIF 
    28552859      DEALLOCATE( ztab, znorthloc, zfoldwk, znorthgloio ) 
     2860      DEALLOCATE( ztabl, ztabr )  
    28562861      ! 
    28572862   END SUBROUTINE mpp_lbc_north_2d 
Note: See TracChangeset for help on using the changeset viewer.