追溯关闭使用 Fortran 创建的 NetCDF 文件
Retrospectively closing a NetCDF file created with Fortran
我是 运行 一个被剥离到最低限度的分布式模型:
integer, parameter :: &
nx = 1200,& ! Number of columns in grid
ny = 1200,& ! Number of rows in grid
nt = 6000 ! Number of timesteps
integer :: it ! Loop counter
real :: var1(nx,ny), var2(nx,ny), var3(nx,ny), etc(nx,ny)
! Create netcdf to write model output
call check( nf90_create(path="out.nc",cmode=nf90_clobber, ncid=nc_out_id) )
! Loop over time
do it = 1,nt
! Calculate a lot of variables
...
! Write some variables in out.nc at each timestep
CALL check( nf90_put_var(ncid=nc_out_id, varid=var1_varid, values=var1, &
start = (/ 1, 1, it /), count = (/ nx, ny, 1 /)) )
! Close the netcdf otherwise it is not readable:
if (it == nt) call check( nf90_close(nc_out_id) )
enddo
我正处于模型的开发阶段,所以它不可避免地会在意想不到的点崩溃(通常在 Calculate a lot of variables
阶段),这意味着,如果模型在时间步 it =3000
崩溃, 2999 timesteps将被写入netcdf输出文件,但我将无法读取该文件,因为该文件尚未关闭。尽管如此,数据已经写入:我目前有一个 2GB out.nc 的文件,我无法读取。当我 ncdump
文件时,它显示
netcdf out.nc {
dimensions:
x = 1400 ;
y = 1200 ;
time = UNLIMITED ; // (0 currently)
variables:
float var1 (time, y, x) ;
data:
}
我的问题是:(1) 有没有办法追溯关闭文件,即使在 Fortran 之外,也能读取已经写入的数据? (2) 或者,是否有另一种用 Fortran 编写文件的方法,即使不关闭文件也可以使文件可读?
当调用 nf90_close
时,缓冲输出被写入磁盘,文件 ID 被放弃,以便可以重复使用。问题很可能是由于程序因崩溃而终止时缓冲输出未写入磁盘,这意味着文件中仅存在您在 "define mode" 中所做的更改(如 ncdump 所示)。
因此您需要强制将数据更频繁地写入磁盘。有三种方法可以做到这一点(据我所知)。
nf90_sync
- 在调用时将缓冲数据同步到磁盘。这使您可以最大程度地控制何时输出数据(例如,每个循环步骤或每 n 个循环步骤),这可以让您优化速度与稳健性,但会为您引入更多的编程和检查开销。
- 感谢@RussF 的想法。 使用
nf90_share
标志创建或打开文件。如果 netCDF 文件打算同时由多个 readers/writers 使用,则这是推荐的方法。它与用于写入数据的 nf90_sync
的自动实现基本相同。它提供了更少的控制,但也减少了编程开销。注意:
This only applies to netCDF-3 classic or 64-bit offset files.
- 最后,我不推荐一个选项,但为了完整起见我将其包括在内(我想在某些情况下这是最好的选择,尽管要记住 none spring)-关闭并重新打开文件。我不推荐这样做,因为它会减慢你的程序,并增加导致错误的可能性。
我是 运行 一个被剥离到最低限度的分布式模型:
integer, parameter :: &
nx = 1200,& ! Number of columns in grid
ny = 1200,& ! Number of rows in grid
nt = 6000 ! Number of timesteps
integer :: it ! Loop counter
real :: var1(nx,ny), var2(nx,ny), var3(nx,ny), etc(nx,ny)
! Create netcdf to write model output
call check( nf90_create(path="out.nc",cmode=nf90_clobber, ncid=nc_out_id) )
! Loop over time
do it = 1,nt
! Calculate a lot of variables
...
! Write some variables in out.nc at each timestep
CALL check( nf90_put_var(ncid=nc_out_id, varid=var1_varid, values=var1, &
start = (/ 1, 1, it /), count = (/ nx, ny, 1 /)) )
! Close the netcdf otherwise it is not readable:
if (it == nt) call check( nf90_close(nc_out_id) )
enddo
我正处于模型的开发阶段,所以它不可避免地会在意想不到的点崩溃(通常在 Calculate a lot of variables
阶段),这意味着,如果模型在时间步 it =3000
崩溃, 2999 timesteps将被写入netcdf输出文件,但我将无法读取该文件,因为该文件尚未关闭。尽管如此,数据已经写入:我目前有一个 2GB out.nc 的文件,我无法读取。当我 ncdump
文件时,它显示
netcdf out.nc {
dimensions:
x = 1400 ;
y = 1200 ;
time = UNLIMITED ; // (0 currently)
variables:
float var1 (time, y, x) ;
data:
}
我的问题是:(1) 有没有办法追溯关闭文件,即使在 Fortran 之外,也能读取已经写入的数据? (2) 或者,是否有另一种用 Fortran 编写文件的方法,即使不关闭文件也可以使文件可读?
当调用 nf90_close
时,缓冲输出被写入磁盘,文件 ID 被放弃,以便可以重复使用。问题很可能是由于程序因崩溃而终止时缓冲输出未写入磁盘,这意味着文件中仅存在您在 "define mode" 中所做的更改(如 ncdump 所示)。
因此您需要强制将数据更频繁地写入磁盘。有三种方法可以做到这一点(据我所知)。
nf90_sync
- 在调用时将缓冲数据同步到磁盘。这使您可以最大程度地控制何时输出数据(例如,每个循环步骤或每 n 个循环步骤),这可以让您优化速度与稳健性,但会为您引入更多的编程和检查开销。- 感谢@RussF 的想法。 使用
nf90_share
标志创建或打开文件。如果 netCDF 文件打算同时由多个 readers/writers 使用,则这是推荐的方法。它与用于写入数据的nf90_sync
的自动实现基本相同。它提供了更少的控制,但也减少了编程开销。注意:This only applies to netCDF-3 classic or 64-bit offset files.
- 最后,我不推荐一个选项,但为了完整起见我将其包括在内(我想在某些情况下这是最好的选择,尽管要记住 none spring)-关闭并重新打开文件。我不推荐这样做,因为它会减慢你的程序,并增加导致错误的可能性。