Ignore:
Timestamp:
May 16, 2019, 4:38:11 PM (5 years ago)
Author:
yann meurdesoif
Message:

Solve 2 problems when writing restartphy files at high resolution :

  • large memory consumption that can lead to crash with an oom kill
  • very very long tile due to usage of NF_ENDDEF/NF_REDEF for each saved field. Now the first pass will create the nectdf header and the second pass will write the fields.

YM

File:
1 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/trunk/libf/phylmd/iostart.F90

    r3465 r3506  
    2525
    2626    PUBLIC get_field,get_var,put_field,put_var
    27     PUBLIC Open_startphy,close_startphy,open_restartphy,close_restartphy
     27    PUBLIC Open_startphy,close_startphy,open_restartphy,close_restartphy, enddef_restartphy
    2828   
    2929CONTAINS
     
    326326      ierr = NF90_DEF_DIM (nid_restart, "horizon_klevp1", klon_glo*klevp1, idim4)
    327327
    328       ierr = NF90_ENDDEF(nid_restart)
     328!      ierr = NF90_ENDDEF(nid_restart)
    329329    ENDIF
    330330
    331331  END SUBROUTINE open_restartphy
    332332 
     333  SUBROUTINE enddef_restartphy
     334  USE netcdf
     335  USE mod_phys_lmdz_para
     336  IMPLICIT NONE
     337    INTEGER          :: ierr
     338
     339    IF (is_master) ierr = NF90_ENDDEF(nid_restart)
     340 
     341  END SUBROUTINE enddef_restartphy
     342
    333343  SUBROUTINE close_restartphy
    334344  USE netcdf
     
    337347    INTEGER          :: ierr
    338348
    339     IF (is_mpi_root .AND. is_omp_root) THEN
    340       ierr = NF90_CLOSE (nid_restart)
    341     ENDIF
     349    IF (is_master) ierr = NF90_CLOSE (nid_restart)
    342350 
    343351  END SUBROUTINE close_restartphy
    344352
    345353 
    346   SUBROUTINE put_field_r1(field_name,title,field)
    347   IMPLICIT NONE
     354  SUBROUTINE put_field_r1(pass, field_name,title,field)
     355  IMPLICIT NONE
     356  INTEGER, INTENT(IN)            :: pass
    348357  CHARACTER(LEN=*),INTENT(IN)    :: field_name
    349358  CHARACTER(LEN=*),INTENT(IN)    :: title
    350359  REAL,INTENT(IN)                :: field(:)
    351  
    352     CALL put_field_rgen(field_name,title,field,1)
     360    CALL put_field_rgen(pass, field_name,title,field,1)
    353361 
    354362  END SUBROUTINE put_field_r1
    355363
    356   SUBROUTINE put_field_r2(field_name,title,field)
    357   IMPLICIT NONE
     364  SUBROUTINE put_field_r2(pass, field_name,title,field)
     365  IMPLICIT NONE
     366  INTEGER, INTENT(IN)            :: pass
    358367  CHARACTER(LEN=*),INTENT(IN)    :: field_name
    359368  CHARACTER(LEN=*),INTENT(IN)    :: title
    360369  REAL,INTENT(IN)                :: field(:,:)
    361370 
    362     CALL put_field_rgen(field_name,title,field,size(field,2))
     371    CALL put_field_rgen(pass, field_name,title,field,size(field,2))
    363372 
    364373  END SUBROUTINE put_field_r2
    365374
    366   SUBROUTINE put_field_r3(field_name,title,field)
    367   IMPLICIT NONE
     375  SUBROUTINE put_field_r3(pass, field_name,title,field)
     376  IMPLICIT NONE
     377  INTEGER, INTENT(IN)            :: pass
    368378  CHARACTER(LEN=*),INTENT(IN)    :: field_name
    369379  CHARACTER(LEN=*),INTENT(IN)    :: title
    370380  REAL,INTENT(IN)                :: field(:,:,:)
    371381 
    372     CALL put_field_rgen(field_name,title,field,size(field,2)*size(field,3))
     382    CALL put_field_rgen(pass, field_name,title,field,size(field,2)*size(field,3))
    373383 
    374384  END SUBROUTINE put_field_r3
    375385 
    376   SUBROUTINE put_field_rgen(field_name,title,field,field_size)
     386  SUBROUTINE put_field_rgen(pass, field_name,title,field,field_size)
    377387  USE netcdf
    378388  USE dimphy
     
    381391  USE mod_phys_lmdz_para
    382392  IMPLICIT NONE
     393  INTEGER, INTENT(IN)            :: pass
    383394  CHARACTER(LEN=*),INTENT(IN)    :: field_name
    384395  CHARACTER(LEN=*),INTENT(IN)    :: title
     
    386397  REAL,INTENT(IN)                :: field(klon,field_size)
    387398 
    388   REAL                           :: field_glo(klon_glo,field_size)
    389   REAL                           :: field_glo_tmp(klon_glo,field_size)
    390 !  INTEGER,ALLOCATABLE            :: ind_cell_glo_glo(:)
    391   INTEGER                        :: ind_cell_glo_glo(klon_glo)
     399!  REAL                           :: field_glo(klon_glo,field_size)
     400!  REAL                           :: field_glo_tmp(klon_glo,field_size)
     401  REAL ,ALLOCATABLE              :: field_glo(:,:)
     402  REAL ,ALLOCATABLE              :: field_glo_tmp(:,:)
     403  INTEGER,ALLOCATABLE            :: ind_cell_glo_glo(:)
     404!  INTEGER                        :: ind_cell_glo_glo(klon_glo)
    392405  INTEGER                        :: ierr,i
    393406  INTEGER                        :: nvarid
    394407  INTEGER                        :: idim
    395408   
    396    
    397 !    IF (is_master) ALLOCATE(ind_cell_glo_glo(klon_glo))
    398     CALL gather(ind_cell_glo,ind_cell_glo_glo)
    399 
    400     CALL gather(field,field_glo_tmp)
     409! first pass : definition   
     410  IF (pass==1) THEN
    401411   
    402412    IF (is_master) THEN
    403 
    404       DO i=1,klon_glo
    405        field_glo(ind_cell_glo_glo(i),:)=field_glo_tmp(i,:)
    406       ENDDO
    407 
    408413
    409414      IF (field_size==1) THEN
     
    418423      ENDIF
    419424         
    420       ierr = NF90_REDEF (nid_restart)
     425!      ierr = NF90_REDEF (nid_restart)
    421426#ifdef NC_DOUBLE
    422427      ierr = NF90_DEF_VAR (nid_restart, field_name, NF90_DOUBLE,(/ idim /),nvarid)
     
    425430#endif
    426431      IF (LEN_TRIM(title) > 0) ierr = NF90_PUT_ATT (nid_restart,nvarid,"title", title)
    427       ierr = NF90_ENDDEF(nid_restart)
    428       ierr = NF90_PUT_VAR(nid_restart,nvarid,RESHAPE(field_glo,(/klon_glo*field_size/)))
    429     ENDIF
    430    
    431    END SUBROUTINE put_field_rgen 
    432  
    433    SUBROUTINE put_var_r0(var_name,title,var)
     432!      ierr = NF90_ENDDEF(nid_restart)
     433     ENDIF
     434
     435! second pass : write     
     436   ELSE IF (pass==2) THEN
     437   
     438     IF (is_master) THEN
     439       ALLOCATE(ind_cell_glo_glo(klon_glo))
     440       ALLOCATE(field_glo(klon_glo,field_size))
     441       ALLOCATE(field_glo_tmp(klon_glo,field_size))
     442     ELSE
     443       ALLOCATE(ind_cell_glo_glo(0))
     444       ALLOCATE(field_glo(0,0))
     445     ENDIF
     446     
     447     CALL gather(ind_cell_glo,ind_cell_glo_glo)
     448
     449     CALL gather(field,field_glo_tmp)
     450   
     451     IF (is_master) THEN
     452
     453       DO i=1,klon_glo
     454         field_glo(ind_cell_glo_glo(i),:)=field_glo_tmp(i,:)
     455       ENDDO
     456
     457       ierr = NF90_INQ_VARID(nid_restart, field_name, nvarid)
     458       ierr = NF90_PUT_VAR(nid_restart,nvarid,RESHAPE(field_glo,(/klon_glo*field_size/)))
     459      ENDIF
     460   ENDIF
     461   
     462 END SUBROUTINE put_field_rgen 
     463 
     464
     465 SUBROUTINE put_var_r0(pass, var_name,title,var)
    434466   IMPLICIT NONE
     467     INTEGER, INTENT(IN)            :: pass
    435468     CHARACTER(LEN=*),INTENT(IN) :: var_name
    436469     CHARACTER(LEN=*),INTENT(IN) :: title
     
    440473     varin(1)=var
    441474     
    442      CALL put_var_rgen(var_name,title,varin,size(varin))
     475     CALL put_var_rgen(pass, var_name,title,varin,size(varin))
    443476
    444477  END SUBROUTINE put_var_r0
    445478
    446479
    447    SUBROUTINE put_var_r1(var_name,title,var)
     480   SUBROUTINE put_var_r1(pass, var_name,title,var)
    448481   IMPLICIT NONE
     482     INTEGER, INTENT(IN)            :: pass
    449483     CHARACTER(LEN=*),INTENT(IN) :: var_name
    450484     CHARACTER(LEN=*),INTENT(IN) :: title
    451485     REAL,INTENT(IN)             :: var(:)
    452486     
    453      CALL put_var_rgen(var_name,title,var,size(var))
     487     CALL put_var_rgen(pass, var_name,title,var,size(var))
    454488
    455489  END SUBROUTINE put_var_r1
    456490 
    457   SUBROUTINE put_var_r2(var_name,title,var)
     491  SUBROUTINE put_var_r2(pass, var_name,title,var)
    458492   IMPLICIT NONE
     493     INTEGER, INTENT(IN)            :: pass
    459494     CHARACTER(LEN=*),INTENT(IN) :: var_name
    460495     CHARACTER(LEN=*),INTENT(IN) :: title
    461496     REAL,INTENT(IN)             :: var(:,:)
    462497     
    463      CALL put_var_rgen(var_name,title,var,size(var))
     498     CALL put_var_rgen(pass, var_name,title,var,size(var))
    464499
    465500  END SUBROUTINE put_var_r2     
    466501 
    467   SUBROUTINE put_var_r3(var_name,title,var)
     502  SUBROUTINE put_var_r3(pass, var_name,title,var)
    468503   IMPLICIT NONE
     504     INTEGER, INTENT(IN)            :: pass
    469505     CHARACTER(LEN=*),INTENT(IN) :: var_name
    470506     CHARACTER(LEN=*),INTENT(IN) :: title
    471507     REAL,INTENT(IN)             :: var(:,:,:)
    472508     
    473      CALL put_var_rgen(var_name,title,var,size(var))
     509     CALL put_var_rgen(pass, var_name,title,var,size(var))
    474510
    475511  END SUBROUTINE put_var_r3
    476512
    477   SUBROUTINE put_var_rgen(var_name,title,var,var_size)
     513  SUBROUTINE put_var_rgen(pass, var_name,title,var,var_size)
    478514  USE netcdf
    479515  USE dimphy
    480516  USE mod_phys_lmdz_para
    481517  IMPLICIT NONE
    482      CHARACTER(LEN=*),INTENT(IN) :: var_name
    483      CHARACTER(LEN=*),INTENT(IN) :: title
    484      INTEGER,INTENT(IN)          :: var_size
    485      REAL,INTENT(IN)             :: var(var_size)
    486      
    487      INTEGER :: ierr
    488      INTEGER :: nvarid
     518    INTEGER, INTENT(IN)         :: pass
     519    CHARACTER(LEN=*),INTENT(IN) :: var_name
     520    CHARACTER(LEN=*),INTENT(IN) :: title
     521    INTEGER,INTENT(IN)          :: var_size
     522    REAL,INTENT(IN)             :: var(var_size)
     523   
     524    INTEGER :: ierr
     525    INTEGER :: nvarid
    489526         
    490     IF (is_mpi_root .AND. is_omp_root) THEN
     527    IF (is_master) THEN
    491528
    492529      IF (var_size/=length) THEN
     
    494531        call abort_physic("", "", 1)
    495532      ENDIF
    496      
    497       ierr = NF90_REDEF (nid_restart)
     533
     534     ! first pass : definition   
     535      IF (pass==1) THEN
     536       
     537!      ierr = NF90_REDEF (nid_restart)
    498538
    499539#ifdef NC_DOUBLE
    500       ierr = NF90_DEF_VAR (nid_restart, var_name, NF90_DOUBLE,(/ idim1 /),nvarid)
     540        ierr = NF90_DEF_VAR (nid_restart, var_name, NF90_DOUBLE,(/ idim1 /),nvarid)
    501541#else
    502       ierr = NF90_DEF_VAR (nid_restart, var_name, NF90_FLOAT,(/ idim1 /),nvarid)
     542        ierr = NF90_DEF_VAR (nid_restart, var_name, NF90_FLOAT,(/ idim1 /),nvarid)
    503543#endif
    504       IF (LEN_TRIM(title)>0) ierr = NF90_PUT_ATT (nid_restart,nvarid,"title", title)
    505       ierr = NF90_ENDDEF(nid_restart)
    506      
    507       ierr = NF90_PUT_VAR(nid_restart,nvarid,var)
    508 
     544        IF (LEN_TRIM(title)>0) ierr = NF90_PUT_ATT (nid_restart,nvarid,"title", title)
     545!      ierr = NF90_ENDDEF(nid_restart)
     546
     547    ! second pass : write     
     548      ELSE IF (pass==2) THEN
     549        ierr = NF90_INQ_VARID(nid_restart, var_name, nvarid)
     550        ierr = NF90_PUT_VAR(nid_restart,nvarid,var)
     551      ENDIF
    509552    ENDIF
    510553   
Note: See TracChangeset for help on using the changeset viewer.