追溯关闭使用 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)-关闭并重新打开文件。我不推荐这样做,因为它会减慢你的程序,并增加导致错误的可能性。