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 2304 – NEMO

Changeset 2304


Ignore:
Timestamp:
2010-10-22T17:56:39+02:00 (13 years ago)
Author:
rblod
Message:

Choose one option for mpp reproducibility, see ticket #743

Location:
branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/DOM/dom_oce.F90

    r2287 r2304  
    214214   !! mpp reproducibility 
    215215   !!---------------------------------------------------------------------- 
    216 #if defined key_mpp_rep1 || defined key_mpp_re2 
     216#if defined key_mpp_rep 
    217217   LOGICAL, PUBLIC, PARAMETER ::   lk_mpp_rep = .TRUE.    !: agrif flag 
    218218#else 
  • branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/lib_fortran.F90

    r2287 r2304  
    2525 
    2626   INTERFACE glob_sum 
    27 #if defined key_mpp_rep1 
    28       MODULE PROCEDURE mpp_sum_indep 
    29 #elif defined key_mpp_rep2       
     27#if defined key_mpp_rep 
    3028      MODULE PROCEDURE mpp_sum_cmpx 
    3129#else 
     
    116114   END FUNCTION glob_sum_3d_a 
    117115 
    118 #if defined key_mpp_rep2   
     116#if defined key_mpp_rep   
    119117   FUNCTION mpp_sum_cmpx( pval ) 
    120118      !!---------------------------------------------------------------------- 
     
    182180#endif 
    183181 
    184 #if defined key_mpp_rep1 
    185    FUNCTION mpp_sum_indep( pval ) 
    186       !!---------------------------------------------------------------------- 
    187       !!               ***  ROUTINE mpp_sum_indep *** 
    188       !!           
    189       !! ** Purpose : Sum all elements in the pval array in 
    190       !!              an accurate order-independent way. 
    191       !! 
    192       !! ** Method  : The code iterates the compensated summation until the  
    193       !!              result is guaranteed to be within 4*eps of the true sum. 
    194       !!              It then rounds the result to the nearest floating-point  
    195       !!              number whose last three bits are zero, thereby  
    196       !!              guaranteeing an order-independent result. 
    197       !! 
    198       !! ** Action  : This does only work for MPI.  
    199       !!              It does not work for SHMEM.      !! 
    200       !! References : M. Fisher (ECMWF): IFS code + personal communication 
    201       !!              The algorithm is based on Ogita et al. (2005)  
    202       !!              SIAM J. Sci. Computing, Vol.26, No.6, pp1955-1988.  
    203       !!              This is based in turn on an algorithm 
    204       !!              by Knuth (1969, seminumerical algorithms). 
    205       !! 
    206       !! History : 
    207       !!        !  07-07  (K. Mogensen)  Original code heavily based on IFS. 
    208       !!---------------------------------------------------------------------- 
    209       REAL(wp) mpp_sum_indep 
    210       REAL(wp), DIMENSION(jpi,jpj), INTENT(IN) :: pval 
    211       !   
    212       REAL(wp), DIMENSION(3) :: zbuffl 
    213       REAL(wp), DIMENSION(:), ALLOCATABLE :: zpsums, zperrs, zpcors, zbuffg, zp 
    214       REAL(wp) :: zcorr, zerr,  zolderr, zbeta, zres 
    215       INTEGER, DIMENSION(:), allocatable :: irecv, istart 
    216       INTEGER :: ikn, jj 
    217  
    218       ! initialise to avoid uninitialised variables trapping of some compilers to complain. 
    219       zres = 0.0_wp ; zerr = 0.0_wp ; zbuffl(:) = 0.0_wp 
    220       ! Get global number of elements 
    221       ikn = SIZE(pval) 
    222 # ifdef key_mpp 
    223       CALL mpp_sum( ikn ) 
    224 # endif 
    225       ! Check that the the algorithm can work  
    226        
    227       IF ( ( REAL( 2 * ikn ) * EPSILON( zres ) ) >= 1.0 ) THEN 
    228          CALL ctl_stop('mpp_sum_indep:', & 
    229             &          'size of array is too large to guarantee error bounds') 
    230       ENDIF 
    231        
    232       ALLOCATE( & 
    233          & zp(MAX(ikn,1)),                &  
    234          & zbuffg(jpnij*SIZE(zbuffl)), & 
    235          & zpsums(jpnij),              & 
    236          & zperrs(jpnij),              & 
    237          & zpcors(jpnij)               & 
    238          & ) 
    239  
    240       zolderr = HUGE(zerr) 
    241  
    242       ! Copy the input array. This avoids some tricky indexing, at the 
    243       ! expense of some inefficency. 
    244  
    245       IF ( ikn > 0 ) THEN 
    246          zp(:) = RESHAPE(pval, (/ jpi * jpj /) ) 
    247       ELSE 
    248          zp(1) = 0.0_wp 
    249       ENDIF 
    250        
    251       k_loop: DO 
    252  
    253          ! Transform local arrays 
    254           
    255          IF ( ikn > 0 ) THEN 
    256             CALL comp_sum ( zp, ikn, zcorr, zerr ) 
    257          ENDIF 
    258  
    259          ! Gather partial sums and error bounds to all processors 
    260  
    261          zbuffl(1) = zp(MAX(ikn,1)) 
    262           
    263          IF ( ikn > 0 ) THEN 
    264             zbuffl(2) = zerr 
    265             zbuffl(3) = zcorr 
    266          ELSE            
    267             zbuffl(2) = 0.0_wp 
    268             zbuffl(3) = 0.0_wp 
    269          ENDIF 
    270           
    271          IF ( jpnij > 1 ) THEN 
    272             ALLOCATE( & 
    273                & irecv(jpnij), & 
    274                & istart(jpnij) & 
    275                & ) 
    276             CALL mpp_allgatherv( zbuffl, SIZE(zbuffl), & 
    277                & zbuffg, jpnij * SIZE(zbuffl), irecv, istart ) 
    278             DEALLOCATE( & 
    279                & irecv, & 
    280                & istart & 
    281                & ) 
    282              
    283             DO jj = 1, jpnij 
    284                zpsums(jj) = zbuffg(1+(jj-1)*SIZE(zbuffl)) 
    285                zperrs(jj) = zbuffg(2+(jj-1)*SIZE(zbuffl)) 
    286                zpcors(jj) = zbuffg(3+(jj-1)*SIZE(zbuffl)) 
    287             END DO 
    288  
    289          ELSE 
    290             zpsums(1) = zbuffl(1) 
    291             zperrs(1) = zbuffl(2) 
    292             zpcors(1) = zbuffl(3) 
    293          ENDIF 
    294  
    295          ! Transform partial sums 
    296          CALL comp_sum( zpsums, jpnij, zcorr, zerr ) 
    297          zerr  = zerr  + SUM(zperrs) 
    298          zcorr = zcorr + SUM(zpcors) 
    299           
    300          ! Calculate final result          
    301          zres = zpsums(jpnij) + zcorr 
    302  
    303          ! Calculate error bound. This is corollary 4.7 from Ogita et al.  
    304          ! (2005)          
    305          zbeta = zerr *(  REAL( 2*ikn, wp ) * EPSILON(zres) ) & 
    306             &  /(1.0_wp - REAL( 2*ikn, wp ) * EPSILON(zres) ) 
    307  
    308          zerr = EPSILON(zres) * ABS(zres) & 
    309             & +(zbeta + ( 2.0_wp * EPSILON(zres) * EPSILON(zres) * ABS(zres) & 
    310             &            +3.0_wp * TINY(zres) ) ) 
    311  
    312          ! Update the last element of the local array 
    313          zp(MAX(ikn,1)) = zpsums(nproc+1) 
    314  
    315          ! Exit if the global error is small enough 
    316          IF ( zerr < 4.0_wp * SPACING(zres) ) EXIT k_loop 
    317           
    318          ! Take appropriate action if ZRES cannot be sufficiently refined.          
    319          IF (zerr >= zolderr) THEN 
    320             CALL ctl_stop('Failed to refine sum', & 
    321                &          'Warning: Possiblity of non-reproducible results') 
    322          ENDIF 
    323  
    324          zolderr = zerr 
    325           
    326       ENDDO k_loop 
    327  
    328       ! At this stage, we have guaranteed that ZRES less than 4*EPS 
    329       ! away from the exact sum. There are only four floating point 
    330       ! numbers in this range. So, if we find the nearest number that 
    331       ! has its last three bits zero, then we have a reproducible result. 
    332  
    333       mpp_sum_indep = fround(zres) 
    334  
    335       DEALLOCATE( & 
    336          & zpcors, & 
    337          & zperrs, & 
    338          & zpsums, & 
    339          & zbuffg, & 
    340          & zp      & 
    341          & ) 
    342  
    343    END FUNCTION mpp_sum_indep 
    344  
    345    SUBROUTINE comp_sum( pval, kn, pcorr, perr ) 
    346       !!---------------------------------------------------------------------- 
    347       !!               ***  ROUTINE comp_sum *** 
    348       !!           
    349       !! ** Purpose : To perform compensated (i.e. accurate) summation. 
    350       !! 
    351       !! ** Method  : These routines transform the elements of the array P,  
    352       !!              such that: 
    353       !!              1)  pval(kn)         contains sum(pval) 
    354       !!              2)  pval(1)...pval(kn-1) contain the rounding errors  
    355       !!                  that were made in calculating sum(pval). 
    356       !!              3)  The exact sum of the elements of pval is unmodified. 
    357       !!              On return, pcorr contains the sum of the rounding errors, 
    358       !!              perr contains the sum of their absolute values. 
    359       !!              After calling this routine, an accurate sum of the  
    360       !!              elements of pval can be calculated as res=pval(n)+pcorr. 
    361       !! 
    362       !! ** Action  :  
    363       !! 
    364       !! References : M. Fisher (ECMWF) IFS code + personal communications 
    365       !! 
    366       !! History : 
    367       !!        !  07-07  (K. Mogensen)  Original code heavily based on IFS  
    368       !!-------------------------------------------------------------------- 
    369       INTEGER, INTENT(IN) :: kn         ! Number of elements in input array 
    370       REAL(wp), DIMENSION(kn), INTENT(INOUT) :: pval    ! Input array to be sum on input 
    371                                                         ! pval(kn) = sum (pval) on output 
    372                                                         ! pval(1)...pval(kn-1) = rounding errors on output 
    373       REAL(wp) :: pcorr   ! Sum of rounding errors 
    374       REAL(wp) :: perr       ! Sum of absolute rounding errors 
    375       !! * Local declarations 
    376       REAL(wp) :: zx, zz, zpsum 
    377       INTEGER :: jj 
    378  
    379       pcorr = 0.0_wp 
    380       perr  = 0.0_wp 
    381        
    382       zpsum = pval(1) 
    383        
    384       DO jj = 2, kn 
    385  
    386          ! It is vital that these 4 lines are not optimized in any way that 
    387          ! changes the results. 
    388          zx         = pval(jj) + zpsum 
    389          zz         = zx - pval(jj) 
    390          pval(jj-1) = ( pval(jj) - ( zx - zz ) ) + ( zpsum - zz )  
    391          zpsum      = zx 
    392  
    393          ! Accumulate the correction and the error          
    394          pcorr      = pcorr + pval(jj-1) 
    395          perr       = perr + ABS( pval(jj-1) ) 
    396  
    397       END DO 
    398  
    399       pval(kn) = zpsum 
    400        
    401    END SUBROUTINE comp_sum 
    402  
    403    FUNCTION fround(pres) 
    404       !!---------------------------------------------------------------------- 
    405       !!               ***  ROUTINE fround *** 
    406       !!           
    407       !! ** Purpose : Rounding of floating-point number 
    408       !! 
    409       !! ** Method  : Returns the value of PRES rounded to the nearest  
    410       !!              floating-point number that has its last three bits zero 
    411       !!              This works on big-endian and little-endian machines. 
    412       !! 
    413       !! ** Action  :  
    414       !! 
    415       !! References : M. Fisher (ECMWF) IFS code + personal communication 
    416       !! 
    417       !! History : 
    418       !!        !  07-07  (K. Mogensen)  Original code heavily based on IFS. 
    419       !!---------------------------------------------------------------------- 
    420       REAL(wp) fround 
    421       REAL(wp), INTENT(IN) :: pres      ! Value to be rounded 
    422       ! 
    423       REAL(wp) :: zz(2), zup, zdown 
    424       INTEGER  :: ii(2), iequiv(8), ints_per_real, i_low_word 
    425       INTEGER  :: jj 
    426  
    427       ii(:) = 1 
    428       zz(:) = 1.0_wp 
    429  
    430       ! Warning: If wp = 64 bits (or 32 bits for key_sp) this will not work. 
    431  
    432 #if defined key_sp 
    433       ints_per_real = 32 / BIT_SIZE(ii) 
    434 #else 
    435       ints_per_real = 64 / BIT_SIZE(ii) 
    436 #endif 
    437  
    438       ! Test whether big-endian or little-endian 
    439        
    440       zup = -1.0_wp 
    441       iequiv(1:ints_per_real) = TRANSFER(zup,iequiv(1:ints_per_real)) 
    442        
    443       IF ( iequiv(1) == 0 ) THEN 
    444          i_low_word = 1                ! Little-endian 
    445       ELSE 
    446          i_low_word = ints_per_real    ! Big-endian 
    447       ENDIF 
    448  
    449       ! Find the nearest number with all 3 lowest-order bits zeroed 
    450        
    451       iequiv(1:ints_per_real) = transfer(pres,iequiv(1:ints_per_real)) 
    452       zup    = pres 
    453       zdown  = pres 
    454  
    455       IF (IBITS(iequiv(i_low_word),0,3)/=0) THEN 
    456  
    457          DO jj = 1, 4 
    458  
    459             zup = NEAREST( zup, 1.0_wp ) 
    460             iequiv(1:ints_per_real) = TRANSFER( zup, iequiv(1:ints_per_real) ) 
    461             IF ( IBITS( iequiv(i_low_word), 0, 3 ) == 0 ) EXIT 
    462  
    463             zdown = NEAREST( zdown, -1.0 ) 
    464             iequiv(1:ints_per_real) = TRANSFER( zdown, iequiv(1:ints_per_real)) 
    465             IF ( IBITS( iequiv(i_low_word),0,3) == 0 ) EXIT 
    466  
    467          END DO 
    468  
    469          IF ( IBITS( iequiv( i_low_word ), 0, 3) /= 0 ) THEN 
    470             CALL ctl_stop('Fround:','This is not possible') 
    471          ENDIF 
    472           
    473       ENDIF 
    474        
    475       fround = TRANSFER( iequiv(1:ints_per_real), pres ) 
    476        
    477    END FUNCTION fround 
    478 #endif 
    479  
    480  
    481182#if defined key_nosignedzero 
    482183   FUNCTION SIGN_SCALAR(pa,pb) 
  • branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/lib_mpp.F90

    r2287 r2304  
    7373   PUBLIC   mppsize, mpprank 
    7474 
    75 # if defined key_mpp_rep1 
    76    PUBLIC mpp_allgatherv 
    77 # endif 
    78  
    7975   !! * Interfaces 
    8076   !! define generic interface for these routine as they are called sometimes 
     
    8884   END INTERFACE 
    8985   INTERFACE mpp_sum 
    90 # if defined key_mpp_rep2 
     86# if defined key_mpp_rep 
    9187      MODULE PROCEDURE mppsum_a_int, mppsum_int, mppsum_a_real, mppsum_real, & 
    9288                       mppsum_realdd, mppsum_a_realdd 
     
    105101   END INTERFACE 
    106102    
    107 # if defined key_mpp_rep1 
    108    INTERFACE mpp_allgatherv 
    109       MODULE PROCEDURE mpp_allgatherv_real, mpp_allgatherv_int 
    110    END INTERFACE 
    111 # endif 
    112  
    113103   !! ========================= !! 
    114104   !!  MPI  variable definition !! 
     
    289279      mynode = mpprank 
    290280      ! 
    291 #if defined key_mpp_rep2 
     281#if defined key_mpp_rep 
    292282      CALL MPI_OP_CREATE(DDPDD_MPI, .TRUE., MPI_SUMDD, ierr) 
    293283#endif 
     
    14301420   END SUBROUTINE mppsum_real 
    14311421 
    1432 # if defined key_mpp_rep2 
     1422# if defined key_mpp_rep 
    14331423   SUBROUTINE mppsum_realdd( ytab, kcom ) 
    14341424      !!---------------------------------------------------------------------- 
     
    23522342   END SUBROUTINE mpi_init_opa 
    23532343 
    2354 #if defined key_mpp_rep1 
    2355    SUBROUTINE mpp_allgatherv_real( pvalsin, knoin, pvalsout, ksizeout, & 
    2356       &                            knoout, kstartout ) 
    2357       !!---------------------------------------------------------------------- 
    2358       !!               ***  ROUTINE mpp_allgatherv_real *** 
    2359       !!           
    2360       !! ** Purpose : Gather a real array on all processors 
    2361       !! 
    2362       !! ** Method  : MPI all gatherv 
    2363       !! 
    2364       !! ** Action  : This does only work for MPI.  
    2365       !!              It does not work for SHMEM. 
    2366       !! 
    2367       !! References : http://www.mpi-forum.org 
    2368       !! 
    2369       !! History : 
    2370       !!        !  08-08  (K. Mogensen)  Original code 
    2371       !!---------------------------------------------------------------------- 
    2372  
    2373       !! * Arguments 
    2374       INTEGER, INTENT(IN) :: & 
    2375          & knoin,     & 
    2376          & ksizeout 
    2377       REAL(wp), DIMENSION(knoin), INTENT(IN) :: & 
    2378          & pvalsin 
    2379       REAL(wp), DIMENSION(ksizeout), INTENT(OUT) :: & 
    2380          & pvalsout 
    2381       INTEGER, DIMENSION(jpnij), INTENT(OUT) :: & 
    2382          & kstartout, & 
    2383          & knoout 
    2384        
    2385       !! * Local declarations 
    2386       INTEGER :: & 
    2387          & ierr 
    2388       INTEGER :: & 
    2389          & ji 
    2390       !----------------------------------------------------------------------- 
    2391       ! Call the MPI library to get number of data per processor 
    2392       !----------------------------------------------------------------------- 
    2393       CALL mpi_allgather( knoin,  1, mpi_integer, & 
    2394          &                knoout, 1, mpi_integer, & 
    2395          &                mpi_comm_opa, ierr ) 
    2396       !----------------------------------------------------------------------- 
    2397       ! Compute starts of each processors contribution 
    2398       !----------------------------------------------------------------------- 
    2399       kstartout(1) = 0 
    2400       DO ji = 2, jpnij 
    2401          kstartout(ji) = kstartout(ji-1) + knoout(ji-1)  
    2402       ENDDO 
    2403       !----------------------------------------------------------------------- 
    2404       ! Call the MPI library to do the gathering of the data 
    2405       !----------------------------------------------------------------------- 
    2406       CALL mpi_allgatherv( pvalsin,  knoin,  MPI_DOUBLE_PRECISION,            & 
    2407          &                 pvalsout, knoout, kstartout, MPI_DOUBLE_PRECISION, & 
    2408          &                 mpi_comm_opa, ierr ) 
    2409       
    2410    END SUBROUTINE mpp_allgatherv_real 
    2411  
    2412    SUBROUTINE mpp_allgatherv_int( kvalsin, knoin, kvalsout, ksizeout, & 
    2413       &                               knoout, kstartout ) 
    2414       !!---------------------------------------------------------------------- 
    2415       !!               ***  ROUTINE mpp_allgatherv *** 
    2416       !!           
    2417       !! ** Purpose : Gather an integer array on all processors 
    2418       !! 
    2419       !! ** Method  : MPI all gatherv 
    2420       !! 
    2421       !! ** Action  : This does only work for MPI.  
    2422       !!              It does not work for SHMEM. 
    2423       !! 
    2424       !! References : http://www.mpi-forum.org 
    2425       !! 
    2426       !! History : 
    2427       !!        !  06-07  (K. Mogensen)  Original code 
    2428       !!---------------------------------------------------------------------- 
    2429  
    2430       !! * Arguments 
    2431       INTEGER, INTENT(IN) :: & 
    2432          & knoin,     & 
    2433          & ksizeout 
    2434       INTEGER, DIMENSION(knoin), INTENT(IN) :: & 
    2435          & kvalsin 
    2436       INTEGER, DIMENSION(ksizeout), INTENT(OUT) :: & 
    2437          & kvalsout 
    2438       INTEGER, DIMENSION(jpnij), INTENT(OUT) :: & 
    2439          & kstartout, & 
    2440          & knoout 
    2441        
    2442       !! * Local declarations 
    2443       INTEGER :: & 
    2444          & ierr 
    2445       INTEGER :: & 
    2446          & ji 
    2447       !----------------------------------------------------------------------- 
    2448       ! Call the MPI library to get number of data per processor 
    2449       !----------------------------------------------------------------------- 
    2450       CALL mpi_allgather( knoin,  1, mpi_integer, & 
    2451          &                knoout, 1, mpi_integer, & 
    2452          &                mpi_comm_opa, ierr ) 
    2453       !----------------------------------------------------------------------- 
    2454       ! Compute starts of each processors contribution 
    2455       !----------------------------------------------------------------------- 
    2456       kstartout(1) = 0 
    2457       DO ji = 2, jpnij 
    2458          kstartout(ji) = kstartout(ji-1) + knoout(ji-1) 
    2459       ENDDO 
    2460       !----------------------------------------------------------------------- 
    2461       ! Call the MPI library to do the gathering of the data 
    2462       !----------------------------------------------------------------------- 
    2463       CALL mpi_allgatherv( kvalsin,  knoin,  mpi_integer,            & 
    2464          &                 kvalsout, knoout, kstartout, mpi_integer, & 
    2465          &                 mpi_comm_opa, ierr ) 
    2466        
    2467    END SUBROUTINE mpp_allgatherv_int 
    2468 #endif 
    2469  
    2470 #if defined key_mpp_rep2 
     2344#if defined key_mpp_rep 
    24712345   SUBROUTINE DDPDD_MPI (ydda, yddb, ilen, itype) 
    24722346      !!--------------------------------------------------------------------- 
     
    25032377   !!   Default case:            Dummy module        share memory computing 
    25042378   !!---------------------------------------------------------------------- 
    2505 # if defined key_mpp_rep1 
    2506    USE par_kind 
    2507    USE par_oce 
    2508  
    2509    PUBLIC mpp_allgatherv 
    2510 # endif 
    25112379 
    25122380   INTERFACE mpp_sum 
     
    25302398   END INTERFACE 
    25312399 
    2532 # if defined key_mpp_rep1 
    2533    INTERFACE mpp_allgatherv 
    2534       MODULE PROCEDURE mpp_allgatherv_real, mpp_allgatherv_int 
    2535    END INTERFACE 
    2536 # endif 
    2537  
    2538  
    25392400   LOGICAL, PUBLIC, PARAMETER ::   lk_mpp = .FALSE.      !: mpp flag 
    25402401   INTEGER :: ncomm_ice 
     
    27192580      WRITE(*,*) 'mpp_comm_free: You should not have seen this print! error?', kcom 
    27202581   END SUBROUTINE mpp_comm_free 
    2721  
    2722 # if defined key_mpp_rep1  
    2723    SUBROUTINE mpp_allgatherv_real( pvalsin, knoin, pvalsout, ksizeout, & 
    2724       &                            knoout, kstartout ) 
    2725       INTEGER, INTENT(IN) :: & 
    2726          & knoin,     & 
    2727          & ksizeout 
    2728       REAL(wp), DIMENSION(knoin), INTENT(IN) :: & 
    2729          & pvalsin 
    2730       REAL(wp), DIMENSION(ksizeout), INTENT(OUT) :: & 
    2731          & pvalsout 
    2732       INTEGER, DIMENSION(jpnij), INTENT(OUT) :: & 
    2733          & kstartout, & 
    2734          & knoout 
    2735       pvalsout(1:knoin) = pvalsin(1:knoin) 
    2736       kstartout(1) = 0 
    2737       knoout(1) = knoin           
    2738    END SUBROUTINE mpp_allgatherv_real 
    2739  
    2740    SUBROUTINE mpp_allgatherv_int( kvalsin, knoin, kvalsout, ksizeout, & 
    2741       &                               knoout, kstartout ) 
    2742       INTEGER, INTENT(IN) :: & 
    2743          & knoin,     & 
    2744          & ksizeout 
    2745       INTEGER, DIMENSION(knoin), INTENT(IN) :: & 
    2746          & kvalsin 
    2747       INTEGER, DIMENSION(ksizeout), INTENT(OUT) :: & 
    2748          & kvalsout 
    2749       INTEGER, DIMENSION(jpnij), INTENT(OUT) :: & 
    2750          & kstartout, & 
    2751          & knoout 
    2752        
    2753       kvalsout(1:knoin) = kvalsin(1:knoin) 
    2754       kstartout(1) = 0 
    2755       knoout(1) = knoin             
    2756    END SUBROUTINE mpp_allgatherv_int 
    2757 # endif 
    2758  
    27592582#endif 
    27602583   !!---------------------------------------------------------------------- 
Note: See TracChangeset for help on using the changeset viewer.