Changeset 11192 for NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lib_mpp.F90
- Timestamp:
- 2019-06-27T12:40:32+02:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lib_mpp.F90
r11067 r11192 34 34 !! get_unit : give the index of an unused logical unit 35 35 !!---------------------------------------------------------------------- 36 #if defined key_mpp_mpi 37 !!---------------------------------------------------------------------- 38 !! 'key_mpp_mpi' MPI massively parallel processing library 39 !!---------------------------------------------------------------------- 40 !! lib_mpp_alloc : allocate mpp arrays 36 !!---------------------------------------------------------------------- 41 37 !! mynode : indentify the processor unit 42 38 !! mpp_lnk : interface (defined in lbclnk) for message passing of 2d or 3d arrays (mpp_lnk_2d, mpp_lnk_3d) … … 57 53 !!---------------------------------------------------------------------- 58 54 USE dom_oce ! ocean space and time domain 59 USE lbcnfd ! north fold treatment60 55 USE in_out_manager ! I/O manager 61 56 62 57 IMPLICIT NONE 63 58 PRIVATE 64 65 INTERFACE mpp_nfd66 MODULE PROCEDURE mpp_nfd_2d , mpp_nfd_3d , mpp_nfd_4d67 MODULE PROCEDURE mpp_nfd_2d_ptr, mpp_nfd_3d_ptr, mpp_nfd_4d_ptr68 END INTERFACE69 70 ! Interface associated to the mpp_lnk_... routines is defined in lbclnk71 PUBLIC mpp_lnk_2d , mpp_lnk_3d , mpp_lnk_4d72 PUBLIC mpp_lnk_2d_ptr , mpp_lnk_3d_ptr , mpp_lnk_4d_ptr73 PUBLIC mpp_lnk_bdy_2d , mpp_lnk_bdy_3d , mpp_lnk_bdy_4d74 PUBLIC mpp_lnk_bdy_2d_ptr, mpp_lnk_bdy_3d_ptr, mpp_lnk_bdy_4d_ptr75 !76 !!gm this should be useless77 PUBLIC mpp_nfd_2d , mpp_nfd_3d , mpp_nfd_4d78 PUBLIC mpp_nfd_2d_ptr, mpp_nfd_3d_ptr, mpp_nfd_4d_ptr79 !!gm end80 59 ! 81 60 PUBLIC ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam 82 61 PUBLIC mynode, mppstop, mppsync, mpp_comm_free 83 62 PUBLIC mpp_ini_north 84 PUBLIC mpp_lnk_2d_icb85 PUBLIC mpp_lbc_north_icb86 63 PUBLIC mpp_min, mpp_max, mpp_sum, mpp_minloc, mpp_maxloc 87 64 PUBLIC mpp_delay_max, mpp_delay_sum, mpp_delay_rcv … … 89 66 PUBLIC mpp_ini_znl 90 67 PUBLIC mppsend, mpprecv ! needed by TAM and ICB routines 68 PUBLIC mpp_report 69 PUBLIC tic_tac 91 70 92 71 !! * Interfaces … … 114 93 !! MPI variable definition !! 115 94 !! ========================= !! 95 #if defined key_mpp_mpi 116 96 !$AGRIF_DO_NOT_TREAT 117 97 INCLUDE 'mpif.h' 118 98 !$AGRIF_END_DO_NOT_TREAT 119 120 99 LOGICAL, PUBLIC, PARAMETER :: lk_mpp = .TRUE. !: mpp flag 100 #else 101 INTEGER, PUBLIC, PARAMETER :: MPI_STATUS_SIZE = 1 102 INTEGER, PUBLIC, PARAMETER :: MPI_DOUBLE_PRECISION = 8 103 LOGICAL, PUBLIC, PARAMETER :: lk_mpp = .FALSE. !: mpp flag 104 #endif 121 105 122 106 INTEGER, PARAMETER :: nprocmax = 2**10 ! maximun dimension (required to be a power of 2) … … 189 173 LOGICAL, PUBLIC :: l_north_nogather = .FALSE. !: internal control of northfold comms 190 174 175 INTEGER, PUBLIC, PARAMETER :: jpfillnothing = 1 176 INTEGER, PUBLIC, PARAMETER :: jpfillcst = 2 177 INTEGER, PUBLIC, PARAMETER :: jpfillcopy = 3 178 INTEGER, PUBLIC, PARAMETER :: jpfillperio = 4 179 INTEGER, PUBLIC, PARAMETER :: jpfillmpi = 5 180 191 181 !!---------------------------------------------------------------------- 192 182 !! NEMO/OCE 4.0 , NEMO Consortium (2018) … … 215 205 NAMELIST/nammpp/ cn_mpi_send, nn_buffer, jpni, jpnj, ln_nnogather 216 206 !!---------------------------------------------------------------------- 207 #if defined key_mpp_mpi 217 208 ! 218 209 ii = 1 … … 311 302 ENDIF 312 303 313 # if defined key_agrif304 # if defined key_agrif 314 305 IF( Agrif_Root() ) THEN 315 306 CALL Agrif_MPI_Init(mpi_comm_oce) … … 317 308 CALL Agrif_MPI_set_grid_comm(mpi_comm_oce) 318 309 ENDIF 319 # endif310 # endif 320 311 321 312 CALL mpi_comm_rank( mpi_comm_oce, mpprank, ierr ) … … 330 321 CALL MPI_OP_CREATE(DDPDD_MPI, .TRUE., MPI_SUMDD, ierr) 331 322 ! 323 #else 324 IF( PRESENT( localComm ) ) mpi_comm_oce = localComm 325 mynode = 0 326 CALL ctl_opn( kumond, TRIM(ldname), 'UNKNOWN', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. , 1 ) 327 #endif 332 328 END FUNCTION mynode 333 334 !!----------------------------------------------------------------------335 !! *** routine mpp_lnk_(2,3,4)d ***336 !!337 !! * Argument : dummy argument use in mpp_lnk_... routines338 !! ptab : array or pointer of arrays on which the boundary condition is applied339 !! cd_nat : nature of array grid-points340 !! psgn : sign used across the north fold boundary341 !! kfld : optional, number of pt3d arrays342 !! cd_mpp : optional, fill the overlap area only343 !! pval : optional, background value (used at closed boundaries)344 !!----------------------------------------------------------------------345 !346 ! !== 2D array and array of 2D pointer ==!347 !348 # define DIM_2d349 # define ROUTINE_LNK mpp_lnk_2d350 # include "mpp_lnk_generic.h90"351 # undef ROUTINE_LNK352 # define MULTI353 # define ROUTINE_LNK mpp_lnk_2d_ptr354 # include "mpp_lnk_generic.h90"355 # undef ROUTINE_LNK356 # undef MULTI357 # undef DIM_2d358 !359 ! !== 3D array and array of 3D pointer ==!360 !361 # define DIM_3d362 # define ROUTINE_LNK mpp_lnk_3d363 # include "mpp_lnk_generic.h90"364 # undef ROUTINE_LNK365 # define MULTI366 # define ROUTINE_LNK mpp_lnk_3d_ptr367 # include "mpp_lnk_generic.h90"368 # undef ROUTINE_LNK369 # undef MULTI370 # undef DIM_3d371 !372 ! !== 4D array and array of 4D pointer ==!373 !374 # define DIM_4d375 # define ROUTINE_LNK mpp_lnk_4d376 # include "mpp_lnk_generic.h90"377 # undef ROUTINE_LNK378 # define MULTI379 # define ROUTINE_LNK mpp_lnk_4d_ptr380 # include "mpp_lnk_generic.h90"381 # undef ROUTINE_LNK382 # undef MULTI383 # undef DIM_4d384 385 !!----------------------------------------------------------------------386 !! *** routine mpp_nfd_(2,3,4)d ***387 !!388 !! * Argument : dummy argument use in mpp_nfd_... routines389 !! ptab : array or pointer of arrays on which the boundary condition is applied390 !! cd_nat : nature of array grid-points391 !! psgn : sign used across the north fold boundary392 !! kfld : optional, number of pt3d arrays393 !! cd_mpp : optional, fill the overlap area only394 !! pval : optional, background value (used at closed boundaries)395 !!----------------------------------------------------------------------396 !397 ! !== 2D array and array of 2D pointer ==!398 !399 # define DIM_2d400 # define ROUTINE_NFD mpp_nfd_2d401 # include "mpp_nfd_generic.h90"402 # undef ROUTINE_NFD403 # define MULTI404 # define ROUTINE_NFD mpp_nfd_2d_ptr405 # include "mpp_nfd_generic.h90"406 # undef ROUTINE_NFD407 # undef MULTI408 # undef DIM_2d409 !410 ! !== 3D array and array of 3D pointer ==!411 !412 # define DIM_3d413 # define ROUTINE_NFD mpp_nfd_3d414 # include "mpp_nfd_generic.h90"415 # undef ROUTINE_NFD416 # define MULTI417 # define ROUTINE_NFD mpp_nfd_3d_ptr418 # include "mpp_nfd_generic.h90"419 # undef ROUTINE_NFD420 # undef MULTI421 # undef DIM_3d422 !423 ! !== 4D array and array of 4D pointer ==!424 !425 # define DIM_4d426 # define ROUTINE_NFD mpp_nfd_4d427 # include "mpp_nfd_generic.h90"428 # undef ROUTINE_NFD429 # define MULTI430 # define ROUTINE_NFD mpp_nfd_4d_ptr431 # include "mpp_nfd_generic.h90"432 # undef ROUTINE_NFD433 # undef MULTI434 # undef DIM_4d435 436 437 !!----------------------------------------------------------------------438 !! *** routine mpp_lnk_bdy_(2,3,4)d ***439 !!440 !! * Argument : dummy argument use in mpp_lnk_... routines441 !! ptab : array or pointer of arrays on which the boundary condition is applied442 !! cd_nat : nature of array grid-points443 !! psgn : sign used across the north fold boundary444 !! kb_bdy : BDY boundary set445 !! kfld : optional, number of pt3d arrays446 !!----------------------------------------------------------------------447 !448 ! !== 2D array and array of 2D pointer ==!449 !450 # define DIM_2d451 # define ROUTINE_BDY mpp_lnk_bdy_2d452 # include "mpp_bdy_generic.h90"453 # undef ROUTINE_BDY454 # define MULTI455 # define ROUTINE_BDY mpp_lnk_bdy_2d_ptr456 # include "mpp_bdy_generic.h90"457 # undef ROUTINE_BDY458 # undef MULTI459 # undef DIM_2d460 !461 ! !== 3D array and array of 3D pointer ==!462 !463 # define DIM_3d464 # define ROUTINE_BDY mpp_lnk_bdy_3d465 # include "mpp_bdy_generic.h90"466 # undef ROUTINE_BDY467 # define MULTI468 # define ROUTINE_BDY mpp_lnk_bdy_3d_ptr469 # include "mpp_bdy_generic.h90"470 # undef ROUTINE_BDY471 # undef MULTI472 # undef DIM_3d473 !474 ! !== 4D array and array of 4D pointer ==!475 !476 # define DIM_4d477 # define ROUTINE_BDY mpp_lnk_bdy_4d478 # include "mpp_bdy_generic.h90"479 # undef ROUTINE_BDY480 # define MULTI481 # define ROUTINE_BDY mpp_lnk_bdy_4d_ptr482 # include "mpp_bdy_generic.h90"483 # undef ROUTINE_BDY484 # undef MULTI485 # undef DIM_4d486 487 !!----------------------------------------------------------------------488 !!489 !! load_array & mpp_lnk_2d_9 à generaliser a 3D et 4D490 491 492 !! mpp_lnk_sum_2d et 3D ====>>>>>> à virer du code !!!!493 494 495 !!----------------------------------------------------------------------496 497 329 498 330 … … 513 345 !!---------------------------------------------------------------------- 514 346 ! 347 #if defined key_mpp_mpi 515 348 SELECT CASE ( cn_mpi_send ) 516 349 CASE ( 'S' ) ! Standard mpi send (blocking) … … 522 355 CALL mpi_isend( pmess, kbytes, mpi_double_precision, kdest , ktyp, mpi_comm_oce, md_req, iflag ) 523 356 END SELECT 357 #endif 524 358 ! 525 359 END SUBROUTINE mppsend … … 543 377 !!---------------------------------------------------------------------- 544 378 ! 379 #if defined key_mpp_mpi 545 380 ! If a specific process number has been passed to the receive call, 546 381 ! use that one. Default is to use mpi_any_source … … 549 384 ! 550 385 CALL mpi_recv( pmess, kbytes, mpi_double_precision, use_source, ktyp, mpi_comm_oce, istatus, iflag ) 386 #endif 551 387 ! 552 388 END SUBROUTINE mpprecv … … 569 405 ! 570 406 itaille = jpi * jpj 407 #if defined key_mpp_mpi 571 408 CALL mpi_gather( ptab, itaille, mpi_double_precision, pio, itaille , & 572 409 & mpi_double_precision, kp , mpi_comm_oce, ierror ) 410 #else 411 pio(:,:,1) = ptab(:,:) 412 #endif 573 413 ! 574 414 END SUBROUTINE mppgather … … 592 432 itaille = jpi * jpj 593 433 ! 434 #if defined key_mpp_mpi 594 435 CALL mpi_scatter( pio, itaille, mpi_double_precision, ptab, itaille , & 595 436 & mpi_double_precision, kp , mpi_comm_oce, ierror ) 437 #else 438 ptab(:,:) = pio(:,:,1) 439 #endif 596 440 ! 597 441 END SUBROUTINE mppscatter … … 617 461 COMPLEX(wp), ALLOCATABLE, DIMENSION(:) :: ytmp 618 462 !!---------------------------------------------------------------------- 463 #if defined key_mpp_mpi 619 464 ilocalcomm = mpi_comm_oce 620 465 IF( PRESENT(kcom) ) ilocalcomm = kcom … … 655 500 656 501 ! send y_in into todelay(idvar)%y1d with a non-blocking communication 657 # if defined key_mpi2502 # if defined key_mpi2 658 503 IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 659 504 CALL mpi_allreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr ) 660 505 IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 506 # else 507 CALL mpi_iallreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr ) 508 # endif 661 509 #else 662 CALL mpi_iallreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr)510 pout(:) = REAL(y_in(:), wp) 663 511 #endif 664 512 … … 684 532 INTEGER :: ierr, ilocalcomm 685 533 !!---------------------------------------------------------------------- 534 #if defined key_mpp_mpi 686 535 ilocalcomm = mpi_comm_oce 687 536 IF( PRESENT(kcom) ) ilocalcomm = kcom … … 718 567 719 568 ! send p_in into todelay(idvar)%z1d with a non-blocking communication 720 # if defined key_mpi2569 # if defined key_mpi2 721 570 IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.) 722 571 CALL mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr ) 723 572 IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.) 573 # else 574 CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr ) 575 # endif 724 576 #else 725 CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr)577 pout(:) = p_in(:) 726 578 #endif 727 579 … … 739 591 INTEGER :: ierr 740 592 !!---------------------------------------------------------------------- 593 #if defined key_mpp_mpi 741 594 IF( ndelayid(kid) /= -2 ) THEN 742 595 #if ! defined key_mpi2 … … 748 601 ndelayid(kid) = -2 ! add flag to know that mpi_wait was already called on kid 749 602 ENDIF 603 #endif 750 604 END SUBROUTINE mpp_delay_rcv 751 605 … … 906 760 !!----------------------------------------------------------------------- 907 761 ! 762 #if defined key_mpp_mpi 908 763 CALL mpi_barrier( mpi_comm_oce, ierror ) 764 #endif 909 765 ! 910 766 END SUBROUTINE mppsync … … 928 784 IF( PRESENT(ld_force_abort) ) ll_force_abort = ld_force_abort 929 785 ! 786 #if defined key_mpp_mpi 930 787 IF(ll_force_abort) THEN 931 788 CALL mpi_abort( MPI_COMM_WORLD ) … … 934 791 CALL mpi_finalize( info ) 935 792 ENDIF 793 #endif 936 794 IF( .NOT. llfinal ) STOP 123 937 795 ! … … 946 804 !!---------------------------------------------------------------------- 947 805 ! 806 #if defined key_mpp_mpi 948 807 CALL MPI_COMM_FREE(kcom, ierr) 808 #endif 949 809 ! 950 810 END SUBROUTINE mpp_comm_free … … 976 836 INTEGER, ALLOCATABLE, DIMENSION(:) :: kwork 977 837 !!---------------------------------------------------------------------- 838 #if defined key_mpp_mpi 978 839 !-$$ WRITE (numout,*) 'mpp_ini_znl ', nproc, ' - ngrp_world : ', ngrp_world 979 840 !-$$ WRITE (numout,*) 'mpp_ini_znl ', nproc, ' - mpi_comm_world : ', mpi_comm_world … … 1047 908 1048 909 DEALLOCATE(kwork) 910 #endif 1049 911 1050 912 END SUBROUTINE mpp_ini_znl … … 1078 940 !!---------------------------------------------------------------------- 1079 941 ! 942 #if defined key_mpp_mpi 1080 943 njmppmax = MAXVAL( njmppt ) 1081 944 ! … … 1109 972 CALL MPI_COMM_CREATE( mpi_comm_oce, ngrp_north, ncomm_north, ierr ) 1110 973 ! 974 #endif 1111 975 END SUBROUTINE mpp_ini_north 1112 976 … … 1130 994 LOGICAL :: mpi_was_called 1131 995 !!--------------------------------------------------------------------- 996 #if defined key_mpp_mpi 1132 997 ! 1133 998 CALL mpi_initialized( mpi_was_called, code ) ! MPI initialization … … 1169 1034 ENDIF 1170 1035 ! 1036 #endif 1171 1037 END SUBROUTINE mpi_init_oce 1172 1038 … … 1203 1069 1204 1070 1205 SUBROUTINE mpp_lbc_north_icb( pt2d, cd_type, psgn, kextj)1206 !!---------------------------------------------------------------------1207 !! *** routine mpp_lbc_north_icb ***1208 !!1209 !! ** Purpose : Ensure proper north fold horizontal bondary condition1210 !! in mpp configuration in case of jpn1 > 1 and for 2d1211 !! array with outer extra halo1212 !!1213 !! ** Method : North fold condition and mpp with more than one proc1214 !! in i-direction require a specific treatment. We gather1215 !! the 4+kextj northern lines of the global domain on 11216 !! processor and apply lbc north-fold on this sub array.1217 !! Then we scatter the north fold array back to the processors.1218 !! This routine accounts for an extra halo with icebergs1219 !! and assumes ghost rows and columns have been suppressed.1220 !!1221 !!----------------------------------------------------------------------1222 REAL(wp), DIMENSION(:,:), INTENT(inout) :: pt2d ! 2D array with extra halo1223 CHARACTER(len=1) , INTENT(in ) :: cd_type ! nature of pt3d grid-points1224 ! ! = T , U , V , F or W -points1225 REAL(wp) , INTENT(in ) :: psgn ! = -1. the sign change across the1226 !! ! north fold, = 1. otherwise1227 INTEGER , INTENT(in ) :: kextj ! Extra halo width at north fold1228 !1229 INTEGER :: ji, jj, jr1230 INTEGER :: ierr, itaille, ildi, ilei, iilb1231 INTEGER :: ipj, ij, iproc1232 !1233 REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: ztab_e, znorthloc_e1234 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: znorthgloio_e1235 !!----------------------------------------------------------------------1236 !1237 ipj=41238 ALLOCATE( ztab_e(jpiglo, 1-kextj:ipj+kextj) , &1239 & znorthloc_e(jpimax, 1-kextj:ipj+kextj) , &1240 & znorthgloio_e(jpimax, 1-kextj:ipj+kextj,jpni) )1241 !1242 ztab_e(:,:) = 0._wp1243 znorthloc_e(:,:) = 0._wp1244 !1245 ij = 1 - kextj1246 ! put the last ipj+2*kextj lines of pt2d into znorthloc_e1247 DO jj = jpj - ipj + 1 - kextj , jpj + kextj1248 znorthloc_e(1:jpi,ij)=pt2d(1:jpi,jj)1249 ij = ij + 11250 END DO1251 !1252 itaille = jpimax * ( ipj + 2*kextj )1253 !1254 IF( ln_timing ) CALL tic_tac(.TRUE.)1255 CALL MPI_ALLGATHER( znorthloc_e(1,1-kextj) , itaille, MPI_DOUBLE_PRECISION, &1256 & znorthgloio_e(1,1-kextj,1), itaille, MPI_DOUBLE_PRECISION, &1257 & ncomm_north, ierr )1258 !1259 IF( ln_timing ) CALL tic_tac(.FALSE.)1260 !1261 DO jr = 1, ndim_rank_north ! recover the global north array1262 iproc = nrank_north(jr) + 11263 ildi = nldit (iproc)1264 ilei = nleit (iproc)1265 iilb = nimppt(iproc)1266 DO jj = 1-kextj, ipj+kextj1267 DO ji = ildi, ilei1268 ztab_e(ji+iilb-1,jj) = znorthgloio_e(ji,jj,jr)1269 END DO1270 END DO1271 END DO1272 1273 ! 2. North-Fold boundary conditions1274 ! ----------------------------------1275 CALL lbc_nfd( ztab_e(:,1-kextj:ipj+kextj), cd_type, psgn, kextj )1276 1277 ij = 1 - kextj1278 !! Scatter back to pt2d1279 DO jj = jpj - ipj + 1 - kextj , jpj + kextj1280 DO ji= 1, jpi1281 pt2d(ji,jj) = ztab_e(ji+nimpp-1,ij)1282 END DO1283 ij = ij +11284 END DO1285 !1286 DEALLOCATE( ztab_e, znorthloc_e, znorthgloio_e )1287 !1288 END SUBROUTINE mpp_lbc_north_icb1289 1290 1291 SUBROUTINE mpp_lnk_2d_icb( cdname, pt2d, cd_type, psgn, kexti, kextj )1292 !!----------------------------------------------------------------------1293 !! *** routine mpp_lnk_2d_icb ***1294 !!1295 !! ** Purpose : Message passing management for 2d array (with extra halo for icebergs)1296 !! This routine receives a (1-kexti:jpi+kexti,1-kexti:jpj+kextj)1297 !! array (usually (0:jpi+1, 0:jpj+1)) from lbc_lnk_icb calls.1298 !!1299 !! ** Method : Use mppsend and mpprecv function for passing mask1300 !! between processors following neighboring subdomains.1301 !! domain parameters1302 !! jpi : first dimension of the local subdomain1303 !! jpj : second dimension of the local subdomain1304 !! kexti : number of columns for extra outer halo1305 !! kextj : number of rows for extra outer halo1306 !! nbondi : mark for "east-west local boundary"1307 !! nbondj : mark for "north-south local boundary"1308 !! noea : number for local neighboring processors1309 !! nowe : number for local neighboring processors1310 !! noso : number for local neighboring processors1311 !! nono : number for local neighboring processors1312 !!----------------------------------------------------------------------1313 CHARACTER(len=*) , INTENT(in ) :: cdname ! name of the calling subroutine1314 REAL(wp), DIMENSION(1-kexti:jpi+kexti,1-kextj:jpj+kextj), INTENT(inout) :: pt2d ! 2D array with extra halo1315 CHARACTER(len=1) , INTENT(in ) :: cd_type ! nature of ptab array grid-points1316 REAL(wp) , INTENT(in ) :: psgn ! sign used across the north fold1317 INTEGER , INTENT(in ) :: kexti ! extra i-halo width1318 INTEGER , INTENT(in ) :: kextj ! extra j-halo width1319 !1320 INTEGER :: jl ! dummy loop indices1321 INTEGER :: imigr, iihom, ijhom ! local integers1322 INTEGER :: ipreci, iprecj ! - -1323 INTEGER :: ml_req1, ml_req2, ml_err ! for key_mpi_isend1324 INTEGER, DIMENSION(MPI_STATUS_SIZE) :: ml_stat ! for key_mpi_isend1325 !!1326 REAL(wp), DIMENSION(1-kexti:jpi+kexti,nn_hls+kextj,2) :: r2dns, r2dsn1327 REAL(wp), DIMENSION(1-kextj:jpj+kextj,nn_hls+kexti,2) :: r2dwe, r2dew1328 !!----------------------------------------------------------------------1329 1330 ipreci = nn_hls + kexti ! take into account outer extra 2D overlap area1331 iprecj = nn_hls + kextj1332 1333 IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, 1, 1, 1, ld_lbc = .TRUE. )1334 1335 ! 1. standard boundary treatment1336 ! ------------------------------1337 ! Order matters Here !!!!1338 !1339 ! ! East-West boundaries1340 ! !* Cyclic east-west1341 IF( l_Iperio ) THEN1342 pt2d(1-kexti: 1 ,:) = pt2d(jpim1-kexti: jpim1 ,:) ! east1343 pt2d( jpi :jpi+kexti,:) = pt2d( 2 :2+kexti,:) ! west1344 !1345 ELSE !* closed1346 IF( .NOT. cd_type == 'F' ) pt2d( 1-kexti :nn_hls ,:) = 0._wp ! east except at F-point1347 pt2d(jpi-nn_hls+1:jpi+kexti,:) = 0._wp ! west1348 ENDIF1349 ! ! North-South boundaries1350 IF( l_Jperio ) THEN !* cyclic (only with no mpp j-split)1351 pt2d(:,1-kextj: 1 ) = pt2d(:,jpjm1-kextj: jpjm1) ! north1352 pt2d(:, jpj :jpj+kextj) = pt2d(:, 2 :2+kextj) ! south1353 ELSE !* closed1354 IF( .NOT. cd_type == 'F' ) pt2d(:, 1-kextj :nn_hls ) = 0._wp ! north except at F-point1355 pt2d(:,jpj-nn_hls+1:jpj+kextj) = 0._wp ! south1356 ENDIF1357 !1358 1359 ! north fold treatment1360 ! -----------------------1361 IF( npolj /= 0 ) THEN1362 !1363 SELECT CASE ( jpni )1364 CASE ( 1 ) ; CALL lbc_nfd ( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj )1365 CASE DEFAULT ; CALL mpp_lbc_north_icb( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj )1366 END SELECT1367 !1368 ENDIF1369 1370 ! 2. East and west directions exchange1371 ! ------------------------------------1372 ! we play with the neigbours AND the row number because of the periodicity1373 !1374 SELECT CASE ( nbondi ) ! Read Dirichlet lateral conditions1375 CASE ( -1, 0, 1 ) ! all exept 2 (i.e. close case)1376 iihom = jpi-nreci-kexti1377 DO jl = 1, ipreci1378 r2dew(:,jl,1) = pt2d(nn_hls+jl,:)1379 r2dwe(:,jl,1) = pt2d(iihom +jl,:)1380 END DO1381 END SELECT1382 !1383 ! ! Migrations1384 imigr = ipreci * ( jpj + 2*kextj )1385 !1386 IF( ln_timing ) CALL tic_tac(.TRUE.)1387 !1388 SELECT CASE ( nbondi )1389 CASE ( -1 )1390 CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req1 )1391 CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea )1392 IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)1393 CASE ( 0 )1394 CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 )1395 CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req2 )1396 CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea )1397 CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe )1398 IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)1399 IF(l_isend) CALL mpi_wait(ml_req2,ml_stat,ml_err)1400 CASE ( 1 )1401 CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 )1402 CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe )1403 IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)1404 END SELECT1405 !1406 IF( ln_timing ) CALL tic_tac(.FALSE.)1407 !1408 ! ! Write Dirichlet lateral conditions1409 iihom = jpi - nn_hls1410 !1411 SELECT CASE ( nbondi )1412 CASE ( -1 )1413 DO jl = 1, ipreci1414 pt2d(iihom+jl,:) = r2dew(:,jl,2)1415 END DO1416 CASE ( 0 )1417 DO jl = 1, ipreci1418 pt2d(jl-kexti,:) = r2dwe(:,jl,2)1419 pt2d(iihom+jl,:) = r2dew(:,jl,2)1420 END DO1421 CASE ( 1 )1422 DO jl = 1, ipreci1423 pt2d(jl-kexti,:) = r2dwe(:,jl,2)1424 END DO1425 END SELECT1426 1427 1428 ! 3. North and south directions1429 ! -----------------------------1430 ! always closed : we play only with the neigbours1431 !1432 IF( nbondj /= 2 ) THEN ! Read Dirichlet lateral conditions1433 ijhom = jpj-nrecj-kextj1434 DO jl = 1, iprecj1435 r2dsn(:,jl,1) = pt2d(:,ijhom +jl)1436 r2dns(:,jl,1) = pt2d(:,nn_hls+jl)1437 END DO1438 ENDIF1439 !1440 ! ! Migrations1441 imigr = iprecj * ( jpi + 2*kexti )1442 !1443 IF( ln_timing ) CALL tic_tac(.TRUE.)1444 !1445 SELECT CASE ( nbondj )1446 CASE ( -1 )1447 CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req1 )1448 CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono )1449 IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)1450 CASE ( 0 )1451 CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 )1452 CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req2 )1453 CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono )1454 CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso )1455 IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)1456 IF(l_isend) CALL mpi_wait(ml_req2,ml_stat,ml_err)1457 CASE ( 1 )1458 CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 )1459 CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso )1460 IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)1461 END SELECT1462 !1463 IF( ln_timing ) CALL tic_tac(.FALSE.)1464 !1465 ! ! Write Dirichlet lateral conditions1466 ijhom = jpj - nn_hls1467 !1468 SELECT CASE ( nbondj )1469 CASE ( -1 )1470 DO jl = 1, iprecj1471 pt2d(:,ijhom+jl) = r2dns(:,jl,2)1472 END DO1473 CASE ( 0 )1474 DO jl = 1, iprecj1475 pt2d(:,jl-kextj) = r2dsn(:,jl,2)1476 pt2d(:,ijhom+jl) = r2dns(:,jl,2)1477 END DO1478 CASE ( 1 )1479 DO jl = 1, iprecj1480 pt2d(:,jl-kextj) = r2dsn(:,jl,2)1481 END DO1482 END SELECT1483 !1484 END SUBROUTINE mpp_lnk_2d_icb1485 1486 1487 1071 SUBROUTINE mpp_report( cdname, kpk, kpl, kpf, ld_lbc, ld_glb, ld_dlg ) 1488 1072 !!---------------------------------------------------------------------- … … 1500 1084 INTEGER :: ji, jj, jk, jh, jf, jcount ! dummy loop indices 1501 1085 !!---------------------------------------------------------------------- 1086 #if defined key_mpp_mpi 1502 1087 ! 1503 1088 ll_lbc = .FALSE. … … 1610 1195 DEALLOCATE(crname_lbc) 1611 1196 ENDIF 1197 #endif 1612 1198 END SUBROUTINE mpp_report 1613 1199 … … 1620 1206 REAL(wp), SAVE :: tic_ct = 0._wp 1621 1207 INTEGER :: ii 1208 #if defined key_mpp_mpi 1622 1209 1623 1210 IF( ncom_stp <= nit000 ) RETURN … … 1635 1222 tic_ct = MPI_Wtime() ! start count tac->tic (waiting time) 1636 1223 ENDIF 1224 #endif 1637 1225 1638 1226 END SUBROUTINE tic_tac 1639 1227 1640 1641 #else 1642 !!---------------------------------------------------------------------- 1643 !! Default case: Dummy module share memory computing 1644 !!---------------------------------------------------------------------- 1645 USE in_out_manager 1646 1647 INTERFACE mpp_sum 1648 MODULE PROCEDURE mppsum_int, mppsum_a_int, mppsum_real, mppsum_a_real, mppsum_realdd, mppsum_a_realdd 1649 END INTERFACE 1650 INTERFACE mpp_max 1651 MODULE PROCEDURE mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real 1652 END INTERFACE 1653 INTERFACE mpp_min 1654 MODULE PROCEDURE mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real 1655 END INTERFACE 1656 INTERFACE mpp_minloc 1657 MODULE PROCEDURE mpp_minloc2d ,mpp_minloc3d 1658 END INTERFACE 1659 INTERFACE mpp_maxloc 1660 MODULE PROCEDURE mpp_maxloc2d ,mpp_maxloc3d 1661 END INTERFACE 1662 1663 LOGICAL, PUBLIC, PARAMETER :: lk_mpp = .FALSE. !: mpp flag 1664 LOGICAL, PUBLIC :: ln_nnogather !: namelist control of northfold comms (needed here in case "key_mpp_mpi" is not used) 1665 INTEGER, PUBLIC :: mpi_comm_oce ! opa local communicator 1666 1667 INTEGER, PARAMETER, PUBLIC :: nbdelay = 0 ! make sure we don't enter loops: DO ji = 1, nbdelay 1668 CHARACTER(len=32), DIMENSION(1), PUBLIC :: c_delaylist = 'empty' 1669 CHARACTER(len=32), DIMENSION(1), PUBLIC :: c_delaycpnt = 'empty' 1670 LOGICAL, PUBLIC :: l_full_nf_update = .TRUE. 1671 TYPE :: DELAYARR 1672 REAL( wp), POINTER, DIMENSION(:) :: z1d => NULL() 1673 COMPLEX(wp), POINTER, DIMENSION(:) :: y1d => NULL() 1674 END TYPE DELAYARR 1675 TYPE( DELAYARR ), DIMENSION(1), PUBLIC :: todelay 1676 INTEGER, PUBLIC, DIMENSION(1) :: ndelayid = -1 1677 !!---------------------------------------------------------------------- 1678 CONTAINS 1679 1680 INTEGER FUNCTION lib_mpp_alloc(kumout) ! Dummy function 1681 INTEGER, INTENT(in) :: kumout 1682 lib_mpp_alloc = 0 1683 END FUNCTION lib_mpp_alloc 1684 1685 FUNCTION mynode( ldtxt, ldname, kumnam_ref, knumnam_cfg, kumond , kstop, localComm ) RESULT (function_value) 1686 INTEGER, OPTIONAL , INTENT(in ) :: localComm 1687 CHARACTER(len=*),DIMENSION(:) :: ldtxt 1688 CHARACTER(len=*) :: ldname 1689 INTEGER :: kumnam_ref, knumnam_cfg , kumond , kstop 1690 IF( PRESENT( localComm ) ) mpi_comm_oce = localComm 1691 function_value = 0 1692 IF( .FALSE. ) ldtxt(:) = 'never done' 1693 CALL ctl_opn( kumond, TRIM(ldname), 'UNKNOWN', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. , 1 ) 1694 END FUNCTION mynode 1695 1696 SUBROUTINE mppsync ! Dummy routine 1697 END SUBROUTINE mppsync 1698 1699 !!---------------------------------------------------------------------- 1700 !! *** mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real *** 1701 !! 1702 !!---------------------------------------------------------------------- 1703 !! 1704 # define OPERATION_MAX 1705 # define INTEGER_TYPE 1706 # define DIM_0d 1707 # define ROUTINE_ALLREDUCE mppmax_int 1708 # include "mpp_allreduce_generic.h90" 1709 # undef ROUTINE_ALLREDUCE 1710 # undef DIM_0d 1711 # define DIM_1d 1712 # define ROUTINE_ALLREDUCE mppmax_a_int 1713 # include "mpp_allreduce_generic.h90" 1714 # undef ROUTINE_ALLREDUCE 1715 # undef DIM_1d 1716 # undef INTEGER_TYPE 1717 ! 1718 # define REAL_TYPE 1719 # define DIM_0d 1720 # define ROUTINE_ALLREDUCE mppmax_real 1721 # include "mpp_allreduce_generic.h90" 1722 # undef ROUTINE_ALLREDUCE 1723 # undef DIM_0d 1724 # define DIM_1d 1725 # define ROUTINE_ALLREDUCE mppmax_a_real 1726 # include "mpp_allreduce_generic.h90" 1727 # undef ROUTINE_ALLREDUCE 1728 # undef DIM_1d 1729 # undef REAL_TYPE 1730 # undef OPERATION_MAX 1731 !!---------------------------------------------------------------------- 1732 !! *** mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real *** 1733 !! 1734 !!---------------------------------------------------------------------- 1735 !! 1736 # define OPERATION_MIN 1737 # define INTEGER_TYPE 1738 # define DIM_0d 1739 # define ROUTINE_ALLREDUCE mppmin_int 1740 # include "mpp_allreduce_generic.h90" 1741 # undef ROUTINE_ALLREDUCE 1742 # undef DIM_0d 1743 # define DIM_1d 1744 # define ROUTINE_ALLREDUCE mppmin_a_int 1745 # include "mpp_allreduce_generic.h90" 1746 # undef ROUTINE_ALLREDUCE 1747 # undef DIM_1d 1748 # undef INTEGER_TYPE 1749 ! 1750 # define REAL_TYPE 1751 # define DIM_0d 1752 # define ROUTINE_ALLREDUCE mppmin_real 1753 # include "mpp_allreduce_generic.h90" 1754 # undef ROUTINE_ALLREDUCE 1755 # undef DIM_0d 1756 # define DIM_1d 1757 # define ROUTINE_ALLREDUCE mppmin_a_real 1758 # include "mpp_allreduce_generic.h90" 1759 # undef ROUTINE_ALLREDUCE 1760 # undef DIM_1d 1761 # undef REAL_TYPE 1762 # undef OPERATION_MIN 1763 1764 !!---------------------------------------------------------------------- 1765 !! *** mppsum_a_int, mppsum_int, mppsum_a_real, mppsum_real *** 1766 !! 1767 !! Global sum of 1D array or a variable (integer, real or complex) 1768 !!---------------------------------------------------------------------- 1769 !! 1770 # define OPERATION_SUM 1771 # define INTEGER_TYPE 1772 # define DIM_0d 1773 # define ROUTINE_ALLREDUCE mppsum_int 1774 # include "mpp_allreduce_generic.h90" 1775 # undef ROUTINE_ALLREDUCE 1776 # undef DIM_0d 1777 # define DIM_1d 1778 # define ROUTINE_ALLREDUCE mppsum_a_int 1779 # include "mpp_allreduce_generic.h90" 1780 # undef ROUTINE_ALLREDUCE 1781 # undef DIM_1d 1782 # undef INTEGER_TYPE 1783 ! 1784 # define REAL_TYPE 1785 # define DIM_0d 1786 # define ROUTINE_ALLREDUCE mppsum_real 1787 # include "mpp_allreduce_generic.h90" 1788 # undef ROUTINE_ALLREDUCE 1789 # undef DIM_0d 1790 # define DIM_1d 1791 # define ROUTINE_ALLREDUCE mppsum_a_real 1792 # include "mpp_allreduce_generic.h90" 1793 # undef ROUTINE_ALLREDUCE 1794 # undef DIM_1d 1795 # undef REAL_TYPE 1796 # undef OPERATION_SUM 1797 1798 # define OPERATION_SUM_DD 1799 # define COMPLEX_TYPE 1800 # define DIM_0d 1801 # define ROUTINE_ALLREDUCE mppsum_realdd 1802 # include "mpp_allreduce_generic.h90" 1803 # undef ROUTINE_ALLREDUCE 1804 # undef DIM_0d 1805 # define DIM_1d 1806 # define ROUTINE_ALLREDUCE mppsum_a_realdd 1807 # include "mpp_allreduce_generic.h90" 1808 # undef ROUTINE_ALLREDUCE 1809 # undef DIM_1d 1810 # undef COMPLEX_TYPE 1811 # undef OPERATION_SUM_DD 1812 1813 !!---------------------------------------------------------------------- 1814 !! *** mpp_minloc2d, mpp_minloc3d, mpp_maxloc2d, mpp_maxloc3d 1815 !! 1816 !!---------------------------------------------------------------------- 1817 !! 1818 # define OPERATION_MINLOC 1819 # define DIM_2d 1820 # define ROUTINE_LOC mpp_minloc2d 1821 # include "mpp_loc_generic.h90" 1822 # undef ROUTINE_LOC 1823 # undef DIM_2d 1824 # define DIM_3d 1825 # define ROUTINE_LOC mpp_minloc3d 1826 # include "mpp_loc_generic.h90" 1827 # undef ROUTINE_LOC 1828 # undef DIM_3d 1829 # undef OPERATION_MINLOC 1830 1831 # define OPERATION_MAXLOC 1832 # define DIM_2d 1833 # define ROUTINE_LOC mpp_maxloc2d 1834 # include "mpp_loc_generic.h90" 1835 # undef ROUTINE_LOC 1836 # undef DIM_2d 1837 # define DIM_3d 1838 # define ROUTINE_LOC mpp_maxloc3d 1839 # include "mpp_loc_generic.h90" 1840 # undef ROUTINE_LOC 1841 # undef DIM_3d 1842 # undef OPERATION_MAXLOC 1843 1844 SUBROUTINE mpp_delay_sum( cdname, cdelay, y_in, pout, ldlast, kcom ) 1845 CHARACTER(len=*), INTENT(in ) :: cdname ! name of the calling subroutine 1846 CHARACTER(len=*), INTENT(in ) :: cdelay ! name (used as id) of the delayed operation 1847 COMPLEX(wp), INTENT(in ), DIMENSION(:) :: y_in 1848 REAL(wp), INTENT( out), DIMENSION(:) :: pout 1849 LOGICAL, INTENT(in ) :: ldlast ! true if this is the last time we call this routine 1850 INTEGER, INTENT(in ), OPTIONAL :: kcom 1851 ! 1852 pout(:) = REAL(y_in(:), wp) 1853 END SUBROUTINE mpp_delay_sum 1854 1855 SUBROUTINE mpp_delay_max( cdname, cdelay, p_in, pout, ldlast, kcom ) 1856 CHARACTER(len=*), INTENT(in ) :: cdname ! name of the calling subroutine 1857 CHARACTER(len=*), INTENT(in ) :: cdelay ! name (used as id) of the delayed operation 1858 REAL(wp), INTENT(in ), DIMENSION(:) :: p_in 1859 REAL(wp), INTENT( out), DIMENSION(:) :: pout 1860 LOGICAL, INTENT(in ) :: ldlast ! true if this is the last time we call this routine 1861 INTEGER, INTENT(in ), OPTIONAL :: kcom 1862 ! 1863 pout(:) = p_in(:) 1864 END SUBROUTINE mpp_delay_max 1865 1866 SUBROUTINE mpp_delay_rcv( kid ) 1867 INTEGER,INTENT(in ) :: kid 1868 WRITE(*,*) 'mpp_delay_rcv: You should not have seen this print! error?', kid 1869 END SUBROUTINE mpp_delay_rcv 1870 1871 SUBROUTINE mppstop( ldfinal, ld_force_abort ) 1872 LOGICAL, OPTIONAL, INTENT(in) :: ldfinal ! source process number 1873 LOGICAL, OPTIONAL, INTENT(in) :: ld_force_abort ! source process number 1874 STOP ! non MPP case, just stop the run 1875 END SUBROUTINE mppstop 1876 1877 SUBROUTINE mpp_ini_znl( knum ) 1878 INTEGER :: knum 1879 WRITE(*,*) 'mpp_ini_znl: You should not have seen this print! error?', knum 1880 END SUBROUTINE mpp_ini_znl 1881 1882 SUBROUTINE mpp_comm_free( kcom ) 1883 INTEGER :: kcom 1884 WRITE(*,*) 'mpp_comm_free: You should not have seen this print! error?', kcom 1885 END SUBROUTINE mpp_comm_free 1886 1887 #endif 1888 1889 !!---------------------------------------------------------------------- 1890 !! All cases: ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam routines 1228 #if ! defined key_mpp_mpi 1229 SUBROUTINE mpi_wait(request, status, ierror) 1230 INTEGER , INTENT(in ) :: request 1231 INTEGER, DIMENSION(MPI_STATUS_SIZE), INTENT( out) :: status 1232 INTEGER , INTENT( out) :: ierror 1233 END SUBROUTINE mpi_wait 1234 #endif 1235 1236 !!---------------------------------------------------------------------- 1237 !! ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam routines 1891 1238 !!---------------------------------------------------------------------- 1892 1239
Note: See TracChangeset
for help on using the changeset viewer.