[10335] | 1 | PROGRAM mpp_optimize |
---|
| 2 | !!====================================================================== |
---|
| 3 | !! *** PROGRAM mpp_optimize *** |
---|
| 4 | !!===================================================================== |
---|
| 5 | !! ** Purpose : Propose possible domain decompositions for a given |
---|
| 6 | !! bathymetric file, which is particularly intersting when |
---|
| 7 | !! we want to eliminate land-only domain. |
---|
| 8 | !! All solution are proposed and written to output file. |
---|
| 9 | !! The ratio between the effective number of computed |
---|
| 10 | !! point and the total number of points in the domain is |
---|
| 11 | !! given and is probably a major criteria for choosing a |
---|
| 12 | !! domain decomposition. |
---|
| 13 | !! |
---|
| 14 | !! ** Method : Use mpp_init like code for seting up the decomposition |
---|
| 15 | !! and evaluate the efficiency of the decomposition. |
---|
| 16 | !! History |
---|
| 17 | !! original : 95-12 (Imbard M) for OPA8.1, CLIPPER |
---|
| 18 | !! f90 : 03-06 (Molines JM), namelist as input |
---|
| 19 | !! : 05-05 (Molines JM), bathy in ncdf |
---|
| 20 | !! : 13-03 (Molines JM), Nemo-like coding and license. |
---|
| 21 | !! : 18-10 (Mathiot P), upgrade the NEMO 4.0 |
---|
| 22 | !!---------------------------------------------------------------------- |
---|
| 23 | !!---------------------------------------------------------------------- |
---|
| 24 | !! routines : description |
---|
| 25 | !!---------------------------------------------------------------------- |
---|
[2136] | 26 | |
---|
| 27 | |
---|
[10335] | 28 | !!---------------------------------------------------------------------- |
---|
| 29 | !! MPP-PREP, MEOM 2013 |
---|
| 30 | !! $Id$ |
---|
| 31 | !! Copyright (c) 2013, J.-M. Molines |
---|
| 32 | !! Software governed by the CeCILL licence (Licence/MPP-PREPCeCILL.txt) |
---|
| 33 | !!---------------------------------------------------------------------- |
---|
| 34 | USE netcdf |
---|
[2136] | 35 | |
---|
[10335] | 36 | IMPLICIT NONE |
---|
[2136] | 37 | |
---|
[10335] | 38 | INTEGER, PARAMETER :: jpreci=1 ,jprecj=1 !: overlap between processors |
---|
[2136] | 39 | |
---|
[10335] | 40 | ! Namelist declaration and definition |
---|
| 41 | ! ----------------------------------- |
---|
| 42 | INTEGER :: nn_procmax =250 !: maximum number of proc. (Read from namelist) |
---|
| 43 | INTEGER :: nn_procmin = 1 !: maximum number of proc. (Read from namelist) |
---|
| 44 | LOGICAL :: ln_memchk = .FALSE. ! add a memory constraint if true (obsolete) |
---|
| 45 | NAMELIST /namproc/ nn_procmax, nn_procmin, ln_memchk |
---|
| 46 | ! |
---|
| 47 | INTEGER :: nn_jpk = 46 !: vertical levels |
---|
| 48 | INTEGER :: nn_izoom = 1 !: I zoom indicator |
---|
| 49 | INTEGER :: nn_jzoom = 1 !: J zoom indicator |
---|
| 50 | NAMELIST /namspace/ nn_jpk, nn_izoom, nn_jzoom |
---|
| 51 | ! |
---|
| 52 | ! Following variables are used only if ln_memchk=.true. |
---|
| 53 | REAL(KIND=4) :: required_memory, rppmpt !: not in namelist working array |
---|
| 54 | REAL(KIND=4) :: rn_ppmcal = 225000000. !: maximum memory of one processor for a |
---|
| 55 | !: given machine (in 8 byte words) |
---|
| 56 | REAL(KIND=4) :: rn_ppmin = 0.4 !: minimum ratio to fill the memory |
---|
| 57 | REAL(KIND=4) :: rn_ppmax = 0.9 !: maximum ratio to fill the memory |
---|
| 58 | NAMELIST /namparam/ rn_ppmcal, rn_ppmin, rn_ppmax |
---|
| 59 | ! |
---|
| 60 | CHARACTER(LEN=80) :: cn_var='none' !: Variable name of the bathymetry |
---|
| 61 | CHARACTER(LEN=80) :: cn_x='x' !: X dimension name |
---|
| 62 | CHARACTER(LEN=80) :: cn_y='y' !: Y dimension name |
---|
| 63 | CHARACTER(LEN=80) :: cn_fbathy !: File name of the netcdf bathymetry (namelist) |
---|
| 64 | LOGICAL :: ln_zps=.FALSE. !: Logical flag for partial cells. |
---|
| 65 | NAMELIST /namfile/ cn_fbathy, cn_var, cn_x, cn_y, ln_zps |
---|
| 66 | ! |
---|
| 67 | CHARACTER(LEN=80) :: cn_fovdta !: root file name for keep output |
---|
| 68 | NAMELIST /namkeep/ cn_fovdta |
---|
| 69 | ! |
---|
| 70 | INTEGER :: numnam = 4 ! logical unit for namelist |
---|
| 71 | INTEGER :: numout = 10 ! logical unit for output |
---|
| 72 | INTEGER :: npiglo, npjglo ! domain size |
---|
| 73 | INTEGER :: npidta, npjdta ! domain size |
---|
[2136] | 74 | |
---|
[10335] | 75 | INTEGER :: ji, jj, jni, jnj ! dummy loop index |
---|
| 76 | INTEGER :: ii, ij, jjc ! dummy loop index |
---|
| 77 | INTEGER :: narg, iargc, ijarg ! browsing command line |
---|
[2136] | 78 | |
---|
[10335] | 79 | ! Decomposition related arrays (using same meaning than in NEMO) |
---|
| 80 | INTEGER, DIMENSION(:,:), ALLOCATABLE :: ilci, ilcj ,iimppt, ijmppt |
---|
| 81 | INTEGER, DIMENSION(:) , ALLOCATABLE :: nlei_ocea, nldi_ocea |
---|
| 82 | INTEGER, DIMENSION(:) , ALLOCATABLE :: nlej_ocea, nldj_ocea |
---|
| 83 | INTEGER, DIMENSION(:) , ALLOCATABLE :: nlei_land, nldi_land |
---|
| 84 | INTEGER, DIMENSION(:) , ALLOCATABLE :: nlej_land, nldj_land |
---|
| 85 | INTEGER :: nimpp, njmpp |
---|
| 86 | INTEGER :: nreci, nrecj |
---|
| 87 | INTEGER :: ili, ilj |
---|
| 88 | INTEGER :: jarea, iarea, iarea0 |
---|
| 89 | INTEGER :: iresti, irestj |
---|
| 90 | ! |
---|
| 91 | INTEGER :: ioce, isurf !: number of ocean points cumulated, per_proc |
---|
| 92 | INTEGER :: ioce_opt !: number of ocean points cumulated for optimal case |
---|
| 93 | INTEGER :: nland, nocea, nvalid !: number of land, ocean, memory_valid procs |
---|
| 94 | INTEGER :: nland_opt !: optimal number of land procs |
---|
| 95 | INTEGER :: ii1, ii2, ij1, ij2 !: limit of subdomain in global domain |
---|
| 96 | INTEGER :: jpimax, jpjmax !: size of sub domain |
---|
| 97 | INTEGER :: jpimax_opt, jpjmax_opt !: size of sub domain for optimal case |
---|
| 98 | INTEGER :: inf10, inf30, inf50 !: |
---|
| 99 | INTEGER :: inf10_opt, inf30_opt, inf50_opt !: in optimal case |
---|
| 100 | INTEGER :: npni_opt, npnj_opt !: optimal domain decomposition |
---|
[2136] | 101 | |
---|
[10335] | 102 | INTEGER :: iminproci, imaxproci !: limits of the processor loop |
---|
| 103 | INTEGER :: iminprocj, imaxprocj !: can be reduded to nkeepi, nkeepj |
---|
[2136] | 104 | |
---|
[10335] | 105 | ! Saving criteria |
---|
| 106 | REAL(KIND=4) :: ratio_min=99999. !: keep only decomposition with ration less than ratio_min |
---|
| 107 | INTEGER :: nocea_min = 1 !: minimum number of ocean procs for saving |
---|
| 108 | INTEGER :: nmodulo = 1 !: Only keep solution multiple of nmodulo |
---|
| 109 | LOGICAL :: ll_criteria=.TRUE. !: |
---|
| 110 | ! |
---|
| 111 | REAL(KIND=4) :: oce_cover |
---|
| 112 | REAL(KIND=4) :: oce_cover_min, oce_cover_max, ratio |
---|
| 113 | REAL(KIND=4) :: oce_cover_min_opt, oce_cover_max_opt, ratio_opt |
---|
| 114 | REAL(KIND=4), DIMENSION(:,:), ALLOCATABLE :: tmask ! npiglo x npjglo |
---|
| 115 | REAL(KIND=4), DIMENSION(:,:), ALLOCATABLE :: bathy ! npidta x npjdta |
---|
[2136] | 116 | |
---|
[10335] | 117 | ! CDF stuff |
---|
| 118 | INTEGER :: ncid, istatus, id |
---|
| 119 | LOGICAL :: ll_good = .FALSE. |
---|
[2136] | 120 | |
---|
[10335] | 121 | CHARACTER(LEN=80) :: cf_namlist='namelist' |
---|
| 122 | CHARACTER(LEN=80) :: cf_out='processor.layout' |
---|
| 123 | CHARACTER(LEN=80) :: cdum ! dummy character variable |
---|
| 124 | |
---|
| 125 | ! Keep stuff |
---|
| 126 | LOGICAL :: ll_keep = .FALSE. |
---|
| 127 | INTEGER :: nkeepi, nkeepj !: for option -keep : the retained decomposition |
---|
[2136] | 128 | ! |
---|
| 129 | |
---|
[10335] | 130 | !!---------------------------------------------------------------------- |
---|
| 131 | narg=iargc() |
---|
| 132 | ijarg=1 |
---|
| 133 | IF ( narg == 0 ) THEN |
---|
| 134 | PRINT *,' try mpp_optimize -h for instructions !' |
---|
| 135 | STOP |
---|
| 136 | ENDIF |
---|
| 137 | ! |
---|
| 138 | DO WHILE ( ijarg <= narg ) |
---|
| 139 | CALL getarg(ijarg,cdum) ; ijarg=ijarg+1 |
---|
| 140 | SELECT CASE ( cdum ) |
---|
| 141 | CASE ('-h') |
---|
| 142 | PRINT *,' usage : mpp_optimize [ -h ] [-keep jpni jpnj] [ -o file out ] ' |
---|
| 143 | PRINT *,' [ -modulo val ] [-r ratio] [-minocean procs] -n namelist' |
---|
| 144 | PRINT *,' ' |
---|
| 145 | PRINT *,' PURPOSE :' |
---|
| 146 | PRINT *,' This program is build to optimize the domain beakdown into' |
---|
| 147 | PRINT *,' subdomain for mpp computing.' |
---|
| 148 | PRINT *,' Once the grid size, and the land/sea mask is known, it looks' |
---|
| 149 | PRINT *,' for all the possibilities within a range of setting parameters' |
---|
| 150 | PRINT *,' and determine the optimal.' |
---|
| 151 | PRINT *,'' |
---|
| 152 | PRINT *,' Optimization is done with respect to the maximum number of' |
---|
| 153 | PRINT *,' sea processors and to the maximum numbers of procs (nn_procmax)' |
---|
| 154 | PRINT *,' ' |
---|
| 155 | PRINT *,' Optional optimization can be performed taking into account' |
---|
| 156 | PRINT *,' the maximum available processor memory rn_ppmcal. This is' |
---|
| 157 | PRINT *,' activated if ln_memchk is set true in the namelist' |
---|
| 158 | PRINT *,' ' |
---|
| 159 | PRINT *,' Additional criteria can be given on the command line to reduce' |
---|
| 160 | PRINT *,' the amount of possible choices.' |
---|
| 161 | PRINT *,' ' |
---|
| 162 | PRINT *,' ARGUMENTS :' |
---|
| 163 | PRINT *,' -n namelist : indicate the name of the namelist to use' |
---|
| 164 | PRINT *,' ' |
---|
| 165 | PRINT *,' OPTIONS :' |
---|
| 166 | PRINT *,' -h : print this help message' |
---|
| 167 | PRINT *,' -keep jpni jpnj : print a file suitable for plotting,' |
---|
| 168 | PRINT *,' corresponding to the given decomposition' |
---|
| 169 | PRINT *,' -o output file : give the name of the output file' |
---|
| 170 | PRINT *,' default is ',TRIM(cf_out) |
---|
| 171 | PRINT *,' -modulo val : only retain decomposition whose total number' |
---|
| 172 | PRINT *,' of util processors (sea) are a multiple of val' |
---|
| 173 | PRINT *,' -r ratio : only retain decomposition with a ratio computed/global' |
---|
| 174 | PRINT *,' less or equal to the given ratio' |
---|
| 175 | PRINT *,' -minocean procs : only retain decomposition with a number of ' |
---|
| 176 | PRINT *,' ocean procs greater of equal to procs' |
---|
| 177 | PRINT *,' ' |
---|
| 178 | PRINT *,' REQUIRED FILES :' |
---|
| 179 | PRINT *,' A bathymetric file and an ad-hoc namelist are required.' |
---|
| 180 | PRINT *,' The file name of the bathymetry is specified in the namelist' |
---|
| 181 | PRINT *,' ' |
---|
| 182 | PRINT *,' OUTPUT : ' |
---|
| 183 | PRINT *,' ',TRIM(cf_out),' : an ascii file with all found possibilities' |
---|
| 184 | PRINT *,' ' |
---|
| 185 | STOP |
---|
| 186 | CASE ('-n' ) |
---|
| 187 | CALL getarg(ijarg,cf_namlist) ; ijarg=ijarg+1 |
---|
| 188 | CASE ('-o' ) |
---|
| 189 | CALL getarg(ijarg,cf_out) ; ijarg=ijarg+1 |
---|
| 190 | CASE ('-keep' ) |
---|
| 191 | ll_keep=.TRUE. |
---|
| 192 | CALL getarg(ijarg,cdum) ; ijarg=ijarg+1 ; READ( cdum,*) nkeepi |
---|
| 193 | CALL getarg(ijarg,cdum) ; ijarg=ijarg+1 ; READ( cdum,*) nkeepj |
---|
| 194 | CASE ('-modulo' ) |
---|
| 195 | CALL getarg(ijarg,cdum) ; ijarg=ijarg+1 ; READ( cdum,*) nmodulo |
---|
| 196 | CASE ('-r' ) |
---|
| 197 | CALL getarg(ijarg,cdum) ; ijarg=ijarg+1 ; READ( cdum,*) ratio_min |
---|
| 198 | CASE ('-minocean' ) |
---|
| 199 | CALL getarg(ijarg,cdum) ; ijarg=ijarg+1 ; READ( cdum,*) nocea_min |
---|
| 200 | END SELECT |
---|
| 201 | ENDDO |
---|
| 202 | |
---|
| 203 | ! Open and read the namelist |
---|
| 204 | OPEN(numnam,FILE=cf_namlist) |
---|
| 205 | REWIND(numnam) |
---|
| 206 | READ(numnam,namspace) |
---|
| 207 | |
---|
| 208 | REWIND(numnam) |
---|
| 209 | READ(numnam,namfile) |
---|
| 210 | |
---|
| 211 | REWIND(numnam) |
---|
| 212 | READ(numnam,namparam) |
---|
| 213 | |
---|
| 214 | REWIND(numnam) |
---|
| 215 | READ(numnam,namproc) |
---|
| 216 | |
---|
| 217 | REWIND(numnam) |
---|
| 218 | READ(numnam,namkeep) ! only used for -keep option but still ... |
---|
| 219 | CLOSE(numnam) |
---|
| 220 | |
---|
| 221 | ! estimated code size expressed in number of 3D arrays (valid for OPA8.1) to be tuned for OPA9.0/Nemo |
---|
| 222 | rppmpt = 55.+73./nn_jpk |
---|
| 223 | |
---|
| 224 | ! Open bathy file an allocate required memory |
---|
| 225 | INQUIRE( FILE=cn_fbathy, EXIST=ll_good ) |
---|
| 226 | IF( ll_good ) THEN |
---|
| 227 | istatus = NF90_OPEN(cn_fbathy, NF90_NOWRITE, ncid) |
---|
| 228 | istatus = NF90_INQ_DIMID(ncid, cn_x, id) ; istatus = NF90_INQUIRE_DIMENSION(ncid, id, len=npiglo) |
---|
| 229 | istatus = NF90_INQ_DIMID(ncid, cn_y, id) ; istatus = NF90_INQUIRE_DIMENSION(ncid, id, len=npjglo) |
---|
| 230 | npidta = npiglo ; npjdta=npjglo |
---|
| 231 | ELSE |
---|
| 232 | PRINT *,' File missing : ', TRIM(cn_fbathy) |
---|
| 233 | STOP 42 |
---|
| 234 | ENDIF |
---|
| 235 | |
---|
| 236 | ALLOCATE (tmask(npiglo,npjglo), bathy(npidta,npjdta) ) |
---|
| 237 | ALLOCATE (ilci(nn_procmax,nn_procmax), ilcj(nn_procmax,nn_procmax) ) |
---|
| 238 | ALLOCATE (iimppt(nn_procmax,nn_procmax), ijmppt(nn_procmax,nn_procmax) ) |
---|
| 239 | |
---|
| 240 | ! Open output file for results |
---|
| 241 | IF ( ll_keep ) THEN |
---|
| 242 | nn_procmax = nkeepi*nkeepj ! reduce nn_procmax |
---|
| 243 | ! File will be open later |
---|
| 244 | ELSE |
---|
| 245 | OPEN(numout,FILE=cf_out) |
---|
| 246 | WRITE(numout,*) |
---|
| 247 | WRITE(numout,*) ' Domain decomposition optimization ' |
---|
| 248 | WRITE(numout,*) ' ----------------------------------' |
---|
| 249 | WRITE(numout,*) |
---|
| 250 | ENDIF |
---|
| 251 | ! |
---|
| 252 | ALLOCATE ( nlei_ocea(nn_procmax), nldi_ocea(nn_procmax), nlej_ocea(nn_procmax), nldj_ocea(nn_procmax) ) |
---|
| 253 | ALLOCATE ( nlei_land(nn_procmax), nldi_land(nn_procmax), nlej_land(nn_procmax), nldj_land(nn_procmax) ) |
---|
| 254 | ! |
---|
| 255 | ! Read cdf bathy file |
---|
| 256 | IF ( cn_var == 'none' ) THEN ! automatic detection of variable name according to partial step |
---|
| 257 | IF ( ln_zps ) THEN ! partial steps |
---|
| 258 | cn_var = 'Bathymetry' |
---|
| 259 | ELSE |
---|
| 260 | cn_var = 'Bathy_level' ! full steps |
---|
[2136] | 261 | ENDIF |
---|
[10335] | 262 | ENDIF |
---|
| 263 | PRINT *,'' |
---|
| 264 | PRINT *,' ocean/land file used is: ', TRIM(cn_fbathy) |
---|
| 265 | PRINT *,' variable used to find ocean domain is: ', TRIM(cn_var) |
---|
| 266 | PRINT *,' Dimensions (jpi x jpj) are: ',npiglo,'x',npjglo |
---|
| 267 | PRINT *,'' |
---|
[2136] | 268 | |
---|
[10335] | 269 | istatus = NF90_INQ_VARID (ncid, cn_var, id) |
---|
| 270 | istatus = NF90_GET_VAR (ncid, id, bathy) |
---|
| 271 | istatus = NF90_CLOSE (ncid) |
---|
| 272 | ! |
---|
| 273 | ! Building the mask ( eventually on a smaller domain than the bathy) |
---|
| 274 | tmask(:,:) = bathy(nn_izoom:nn_izoom+npiglo -1, nn_jzoom:nn_jzoom+npjglo -1) |
---|
[2136] | 275 | |
---|
[10335] | 276 | WHERE ( tmask > 0 ) |
---|
| 277 | tmask = 1. |
---|
| 278 | ELSEWHERE |
---|
| 279 | tmask = 0. |
---|
| 280 | ENDWHERE |
---|
[2136] | 281 | |
---|
[10335] | 282 | ! Main loop on processors |
---|
| 283 | ! ------------------------ |
---|
| 284 | ! initialization of working variables |
---|
| 285 | npni_opt=1 ; npnj_opt=1 |
---|
| 286 | jpimax_opt=npiglo ; jpjmax_opt=npjglo |
---|
| 287 | nland_opt=0 |
---|
| 288 | ioce_opt=0 |
---|
| 289 | oce_cover_min_opt=0. ; oce_cover_max_opt=0. |
---|
| 290 | inf10_opt=0 ; inf30_opt=0 ; inf50_opt=0 |
---|
| 291 | ratio_opt=1. |
---|
[6412] | 292 | |
---|
[10335] | 293 | nvalid=0 ! counter for valid case ( ln_memchk true ) |
---|
| 294 | IF ( ll_keep ) THEN |
---|
| 295 | iminproci = nkeepi ; imaxproci = iminproci |
---|
| 296 | iminprocj = nkeepj ; imaxprocj = iminprocj |
---|
| 297 | ELSE |
---|
| 298 | iminproci = 1 ; imaxproci = MIN( nn_procmax, npiglo ) |
---|
| 299 | iminprocj = 1 ; imaxprocj = MIN( nn_procmax, npjglo ) |
---|
| 300 | ENDIF |
---|
[6412] | 301 | |
---|
[10335] | 302 | ! loop on all decomposition a priori |
---|
| 303 | PRINT *, 'Loop over all the decomposition (can take a while) ...' |
---|
| 304 | PRINT *, '' |
---|
| 305 | DO jni=iminproci, imaxproci |
---|
| 306 | DO jnj=iminprocj, imaxprocj |
---|
| 307 | ! Limitation of the maxumun number of PE's |
---|
| 308 | IF ( jni*jnj <= nn_procmax .AND. jni*jnj >= nn_procmin ) THEN |
---|
| 309 | ! |
---|
| 310 | ! 1. Dimension arrays for subdomains |
---|
| 311 | ! ----------------------------------- |
---|
| 312 | ! |
---|
| 313 | ! Partition : size of sub-domain |
---|
| 314 | jpimax=(npiglo-2*jpreci + (jni-1))/jni + 2*jpreci |
---|
| 315 | jpjmax=(npjglo-2*jprecj + (jnj-1))/jnj + 2*jprecj |
---|
| 316 | ! |
---|
| 317 | ! Memory optimization ? |
---|
| 318 | IF ( ln_memchk ) THEN |
---|
| 319 | required_memory=rppmpt*jpimax*jpjmax*nn_jpk |
---|
| 320 | IF( required_memory > rn_ppmcal ) EXIT |
---|
| 321 | IF( required_memory > rn_ppmax*rn_ppmcal .OR. required_memory < rn_ppmin*rn_ppmcal) EXIT |
---|
| 322 | ENDIF |
---|
| 323 | nvalid=nvalid+1 |
---|
| 324 | ! |
---|
| 325 | ! Position of each sub domain (jni x jni in total ) |
---|
| 326 | nreci = 2*jpreci ; nrecj = 2*jprecj |
---|
| 327 | iresti = 1 + MOD ( npiglo - nreci - 1 , jni ) ; irestj = 1 + MOD ( npjglo - nrecj - 1 , jnj ) |
---|
| 328 | ! |
---|
| 329 | ! |
---|
| 330 | ilci( 1:iresti, 1:jnj) = jpimax |
---|
| 331 | ilci(iresti+1:jni , 1:jnj) = jpimax-1 |
---|
| 332 | |
---|
| 333 | ilcj(1:jni, 1:irestj) = jpjmax |
---|
| 334 | ilcj(1:jni,irestj+1:jnj ) = jpjmax-1 |
---|
| 335 | |
---|
| 336 | ! 2. Index arrays for subdomains |
---|
| 337 | ! ------------------------------- |
---|
| 338 | iimppt(1:jni, 1:jnj) = 1 |
---|
| 339 | ijmppt(1:jni, 1:jnj) = 1 |
---|
| 340 | IF( jni > 1 ) THEN |
---|
| 341 | DO jj=1,jnj |
---|
| 342 | DO ji=2,jni |
---|
| 343 | iimppt(ji,jj)= iimppt(ji-1,jj) + ilci(ji-1,jj) - nreci |
---|
| 344 | END DO |
---|
| 345 | END DO |
---|
| 346 | ENDIF |
---|
| 347 | |
---|
| 348 | IF( jnj > 1 ) THEN |
---|
| 349 | DO jj=2,jnj |
---|
| 350 | DO ji=1,jni |
---|
| 351 | ijmppt(ji,jj)= ijmppt(ji,jj-1) + ilcj(ji,jj-1) - nrecj |
---|
| 352 | END DO |
---|
| 353 | END DO |
---|
| 354 | ENDIF |
---|
| 355 | ! |
---|
| 356 | ! Loop on each subdomain to look for land proportion |
---|
| 357 | nland = 0 |
---|
| 358 | nocea = 0 |
---|
| 359 | ioce = 0 |
---|
| 360 | oce_cover_min = 1.e+20 |
---|
| 361 | oce_cover_max = -1.e+20 |
---|
| 362 | inf10=0 |
---|
| 363 | inf30=0 |
---|
| 364 | inf50=0 |
---|
| 365 | ! |
---|
| 366 | ! 3. Subdomain description in the Regular Case |
---|
| 367 | ! -------------------------------------------- |
---|
| 368 | ! |
---|
| 369 | DO jarea = 1, jni*jnj |
---|
| 370 | iarea0 = jarea - 1 |
---|
| 371 | ii = 1 + MOD(iarea0,jni) |
---|
| 372 | ij = 1 + iarea0/jni |
---|
| 373 | ili = ilci(ii,ij) |
---|
| 374 | ilj = ilcj(ii,ij) |
---|
| 375 | |
---|
| 376 | isurf = 0 |
---|
| 377 | ! loop on inner point of sub-domain |
---|
| 378 | DO jj=1, ilj |
---|
| 379 | DO ji=1, ili |
---|
| 380 | IF( tmask(ji + iimppt(ii,ij) - 1, jj + ijmppt(ii,ij) - 1) == 1 ) isurf=isurf+1 |
---|
| 381 | END DO |
---|
| 382 | END DO |
---|
| 383 | |
---|
| 384 | nimpp = iimppt(ii,ij) |
---|
| 385 | njmpp = ijmppt(ii,ij) |
---|
| 386 | ii1 = nimpp+jpreci ; ii2 = nimpp+ili-1 -jpreci |
---|
| 387 | ij1 = njmpp+jprecj ; ij2 = njmpp+ilj-1 -jprecj |
---|
| 388 | IF ( isurf == 0 ) THEN |
---|
| 389 | nland = nland+1 |
---|
| 390 | nldi_land(nland) = ii1 |
---|
| 391 | nlei_land(nland) = ii2 |
---|
| 392 | nldj_land(nland) = ij1 |
---|
| 393 | nlej_land(nland) = ij2 |
---|
| 394 | ELSE |
---|
| 395 | nocea = nocea+1 |
---|
| 396 | ioce = ioce + isurf |
---|
| 397 | nldi_ocea(nocea) = ii1 |
---|
| 398 | nlei_ocea(nocea) = ii2 |
---|
| 399 | nldj_ocea(nocea) = ij1 |
---|
| 400 | nlej_ocea(nocea) = ij2 |
---|
| 401 | ENDIF |
---|
| 402 | |
---|
| 403 | ! ratio of wet points over total number of point per proc. |
---|
| 404 | oce_cover = float(isurf)/float(jpimax*jpjmax) |
---|
| 405 | |
---|
| 406 | IF(oce_cover_min > oce_cover .AND. isurf /= 0) oce_cover_min=oce_cover |
---|
| 407 | IF(oce_cover_max < oce_cover .AND. isurf /= 0) oce_cover_max=oce_cover |
---|
| 408 | IF(oce_cover < 0.1 .AND. isurf /= 0) inf10=inf10+1 |
---|
| 409 | IF(oce_cover < 0.3 .AND. isurf /= 0) inf30=inf30+1 |
---|
| 410 | IF(oce_cover < 0.5 .AND. isurf /= 0) inf50=inf50+1 |
---|
| 411 | ! |
---|
| 412 | !END DO ! loop on processors |
---|
| 413 | END DO ! loop on processors |
---|
| 414 | ! |
---|
| 415 | ratio=float(nocea)*float(jpimax*jpjmax)/float(npiglo*npjglo) |
---|
| 416 | |
---|
| 417 | ! criteria for printing results |
---|
| 418 | ll_criteria = ( ( MOD ( nocea, nmodulo ) == 0 ) .AND. & |
---|
| 419 | & ( ratio <= ratio_min ) .AND. & |
---|
| 420 | & ( nocea >= nocea_min ) ) |
---|
| 421 | IF ( ll_keep ) THEN ! the loop in done only once ! |
---|
| 422 | WRITE(cdum,'(a,"-",i3.3,"x",i3.3,"_",i4.4)') TRIM(cn_fovdta), nkeepi, nkeepj, nocea |
---|
| 423 | OPEN(numout, file=cdum ) |
---|
| 424 | WRITE(numout,'("# ocean ",i5)') nocea |
---|
| 425 | DO jjc=1, nocea |
---|
| 426 | WRITE(numout,'("#",i5)') jjc |
---|
| 427 | WRITE(numout,'(2i5)') nldi_ocea(jjc)-1+nn_izoom-1, nldj_ocea(jjc)-1+nn_jzoom -1 |
---|
| 428 | WRITE(numout,'(2i5)') nlei_ocea(jjc)+1+nn_izoom-1, nldj_ocea(jjc)-1+nn_jzoom -1 |
---|
| 429 | WRITE(numout,'(2i5)') nlei_ocea(jjc)+1+nn_izoom-1, nlej_ocea(jjc)+1+nn_jzoom -1 |
---|
| 430 | WRITE(numout,'(2i5)') nldi_ocea(jjc)-1+nn_izoom-1, nlej_ocea(jjc)+1+nn_jzoom -1 |
---|
| 431 | WRITE(numout,'(2i5)') nldi_ocea(jjc)-1+nn_izoom-1, nldj_ocea(jjc)-1+nn_jzoom -1 |
---|
| 432 | WRITE(numout,'(2i5)') 9999, 9999 |
---|
| 433 | ENDDO |
---|
| 434 | ! |
---|
| 435 | WRITE(numout,'("# land ",i5)') nland |
---|
| 436 | DO jjc=1, nland |
---|
| 437 | WRITE(numout,'("# land ",i5)') jjc |
---|
| 438 | WRITE(numout,'(2i5)') nldi_land(jjc)-1+nn_izoom-1, nldj_land(jjc)-1+nn_jzoom -1 |
---|
| 439 | WRITE(numout,'(2i5)') nlei_land(jjc)+1+nn_izoom-1, nldj_land(jjc)-1+nn_jzoom -1 |
---|
| 440 | WRITE(numout,'(2i5)') nlei_land(jjc)+1+nn_izoom-1, nlej_land(jjc)+1+nn_jzoom -1 |
---|
| 441 | WRITE(numout,'(2i5)') nldi_land(jjc)-1+nn_izoom-1, nlej_land(jjc)+1+nn_jzoom -1 |
---|
| 442 | WRITE(numout,'(2i5)') nldi_land(jjc)-1+nn_izoom-1, nldj_land(jjc)-1+nn_jzoom -1 |
---|
| 443 | WRITE(numout,'(2i5)') nlei_land(jjc)+1+nn_izoom-1, nlej_land(jjc)+1+nn_jzoom -1 |
---|
| 444 | WRITE(numout,'(2i5)') nldi_land(jjc)-1+nn_izoom-1, nlej_land(jjc)+1+nn_jzoom -1 |
---|
| 445 | WRITE(numout,'(2i5)') nlei_land(jjc)+1+nn_izoom-1, nldj_land(jjc)-1+nn_jzoom -1 |
---|
| 446 | WRITE(numout,'(2i5)') 9999, 9999 |
---|
| 447 | ENDDO |
---|
| 448 | ! |
---|
| 449 | ELSE |
---|
| 450 | IF ( ll_criteria ) THEN |
---|
| 451 | WRITE(numout,*) ' iresti=',iresti,' irestj=',irestj |
---|
| 452 | WRITE(numout,*) '--> Total number of domains ',jni*jnj |
---|
| 453 | WRITE(numout,*) ' ' |
---|
| 454 | WRITE(numout,*) ' jpni=',jni ,' jpnj=',jnj |
---|
| 455 | WRITE(numout,*) ' jpi= ',jpimax ,' jpj= ',jpjmax |
---|
| 456 | WRITE(numout,*) ' Number of ocean processors ', nocea |
---|
| 457 | WRITE(numout,*) ' Number of land processors ', nland |
---|
| 458 | WRITE(numout,*) ' Mean ocean coverage per domain ', float(ioce)/float(nocea)/float(jpimax*jpjmax) |
---|
| 459 | WRITE(numout,*) ' Minimum ocean coverage ', oce_cover_min |
---|
| 460 | WRITE(numout,*) ' Maximum ocean coverage ', oce_cover_max |
---|
| 461 | WRITE(numout,*) ' nb of proc with coverage < 10 % ', inf10 |
---|
| 462 | WRITE(numout,*) ' nb of proc with coverage 10 < nb < 30 % ', inf30 - inf10 |
---|
| 463 | WRITE(numout,*) ' nb of proc with coverage 30 < nb < 50 % ', inf50 - inf30 |
---|
| 464 | WRITE(numout,*) ' Number of computed points ', nocea*jpimax*jpjmax |
---|
| 465 | WRITE(numout,*) ' Overhead of computed points ', nocea*jpimax*jpjmax-npiglo*npjglo |
---|
| 466 | WRITE(numout,*) ' % sup (computed / global) ', ratio |
---|
| 467 | WRITE(numout,*) |
---|
| 468 | ENDIF ! note that indication of optimum does not take modulo into account (for information) |
---|
| 469 | ! |
---|
| 470 | ! Look for optimum |
---|
| 471 | IF( nland > nland_opt ) THEN |
---|
| 472 | npni_opt = jni |
---|
| 473 | npnj_opt = jnj |
---|
| 474 | jpimax_opt = jpimax |
---|
| 475 | jpjmax_opt = jpjmax |
---|
| 476 | nland_opt = nland |
---|
| 477 | ioce_opt = ioce |
---|
| 478 | oce_cover_min_opt = oce_cover_min |
---|
| 479 | oce_cover_max_opt = oce_cover_max |
---|
| 480 | inf10_opt = inf10 |
---|
| 481 | inf30_opt = inf30 |
---|
| 482 | inf50_opt = inf50 |
---|
| 483 | ratio_opt = ratio |
---|
| 484 | ELSE IF( nland == nland_opt .AND. ratio_opt < ratio) THEN |
---|
| 485 | npni_opt = jni |
---|
| 486 | npnj_opt = jnj |
---|
| 487 | jpimax_opt = jpimax |
---|
| 488 | jpjmax_opt = jpjmax |
---|
| 489 | ioce_opt = ioce |
---|
| 490 | oce_cover_min_opt = oce_cover_min |
---|
| 491 | oce_cover_max_opt = oce_cover_max |
---|
| 492 | inf10_opt = inf10 |
---|
| 493 | inf30_opt = inf30 |
---|
| 494 | inf50_opt = inf50 |
---|
| 495 | ratio_opt = ratio |
---|
| 496 | ENDIF |
---|
| 497 | ENDIF |
---|
| 498 | ENDIF |
---|
| 499 | END DO |
---|
| 500 | END DO |
---|
| 501 | ! |
---|
| 502 | ! print optimal result |
---|
| 503 | IF ( .NOT. ll_keep ) THEN |
---|
| 504 | IF ( nvalid == 0 ) THEN |
---|
| 505 | WRITE(numout,*) ' no possible choice ...' |
---|
| 506 | WRITE(numout,*) |
---|
| 507 | WRITE(numout,*) 'insufficient number of processors for the available memory' |
---|
| 508 | STOP |
---|
| 509 | ENDIF |
---|
| 510 | |
---|
| 511 | WRITE(numout,*) ' Optimal choice' |
---|
| 512 | WRITE(numout,*) ' ==============' |
---|
| 513 | WRITE(numout,*) |
---|
| 514 | WRITE(numout,*) '--> Total number of domains ',npni_opt*npnj_opt |
---|
| 515 | WRITE(numout,*) ' ' |
---|
| 516 | WRITE(numout,*) ' jpni=',npni_opt ,' jpnj=',npnj_opt |
---|
| 517 | WRITE(numout,*) ' jpi= ',jpimax_opt ,' jpj= ',jpjmax_opt |
---|
| 518 | WRITE(numout,*) |
---|
| 519 | WRITE(numout,*) ' Number of ocean processors ', npni_opt*npnj_opt-nland_opt |
---|
| 520 | WRITE(numout,*) ' Number of land processors ', nland_opt |
---|
| 521 | WRITE(numout,*) ' Mean ocean coverage ', float(ioce_opt)/float(npni_opt*npnj_opt-nland_opt)/float(jpimax_opt*jpjmax_opt) |
---|
| 522 | WRITE(numout,*) ' Minimum ocean coverage ', oce_cover_min_opt |
---|
| 523 | WRITE(numout,*) ' Maximum ocean coverage ', oce_cover_max_opt |
---|
| 524 | WRITE(numout,*) ' nb of proc with coverage < 10 % ', inf10_opt |
---|
| 525 | WRITE(numout,*) ' nb of proc with coverage 10 < nb < 30 % ', inf30_opt - inf10_opt |
---|
| 526 | WRITE(numout,*) ' nb of proc with coverage 30 < nb < 50 % ', inf50_opt - inf30_opt |
---|
| 527 | WRITE(numout,*) ' Number of computed points ', (npni_opt*npnj_opt-nland_opt)*jpimax_opt*jpjmax_opt |
---|
| 528 | WRITE(numout,*) ' Overhead of computed points ', (npni_opt*npnj_opt-nland_opt)*jpimax_opt*jpjmax_opt-npiglo*npjglo |
---|
| 529 | WRITE(numout,*) ' % sup (computed / global) ', ratio_opt |
---|
| 530 | WRITE(numout,*) |
---|
| 531 | ENDIF |
---|
| 532 | CLOSE(numout) |
---|
| 533 | ! |
---|
| 534 | STOP |
---|
| 535 | END PROGRAM mpp_optimize |
---|