【问题标题】:Retrospectively closing a NetCDF file created with Fortran追溯关闭使用 Fortran 创建的 NetCDF 文件
【发布时间】:2017-03-22 23:12:44
【问题描述】:

我正在运行一个分布式模型,在下面被剥离到最低限度:

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个时间步到 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_sync,这应该将缓冲数据写入文件并可能解决您的一些问题。不知道是否可以追溯关闭文件。
  • 调用nf90_sync 应该可以。另一种选择是使用NF90_SHARE 标志创建文件。它可能比一直显式同步文件要简单。
  • 您实际上可以在 fortran 中创建 MWE,我认为这里没有问题。这会很好,因为它实际上可能在程序崩溃的地方很重要。但是,正如之前的 cmets 建议的那样,同步应该可以解决问题,如果没有,还有一个选项可以在每个步骤中关闭/打开文件(有一些开销,因此不建议解决方案)或编写更多更小的文件,然后将它们合并到 HDF5 逻辑组中。
  • @SteveES 谢谢,nf90_sync 为我正在创建的新文件工作。
  • @SteveES 我已经按照你的建议编辑了这个问题。

标签: fortran netcdf


【解决方案1】:

nf90_close 被调用时,缓冲的输出被写入磁盘并且文件ID 被放弃以便它可以被重用。问题很可能是由于程序因崩溃而终止时没有将缓冲输出写入磁盘,这意味着文件中仅存在您在“定义模式”中所做的更改(如 ncdump 所示)。

因此,您需要更频繁地将数据写入磁盘。有三种方法可以做到这一点(据我所知)。

  • nf90_sync - 调用时将缓冲数据同步到磁盘。这使您可以最大程度地控制何时输出数据(例如,每个循环步骤或每 n 个循环步骤),这可以让您针对速度与稳健性进行优化,但会为您带来更多的编程和检查开销。
  • 感谢@RussF 提出这个想法。 使用nf90_share 标志创建或打开文件。如果 netCDF 文件打算由多个读取器/写入器同时使用,这是推荐的方法。它本质上与nf90_sync 用于写入数据的自动实现相同。它提供了更少的控制,但也减少了编程开销。注意:

    这仅适用于 netCDF-3 经典或 64 位偏移文件。

  • 最后,我不推荐一个选项,但为了完整性(我猜在某些情况下这是最好的选项,虽然没有想到) - 关闭并重新打开文件。我不建议这样做,因为它会减慢您的程序,并增加导致错误的可能性。

【讨论】:

  • 我还会添加一个选项,将文件拆分成更小的部分。我普遍同意在每次迭代时关闭和打开文件在性能方面并不好,但为什么会导致更多错误尚不清楚。
  • @kakk11,公平点,我将把它作为另一个建议添加,除非你更愿意建议编辑,或者自己提供作为答案?
  • @kakk11 至于导致错误,我想这更像是“迷信”而不是事实,但我的推理是基于导致错误的小风险(例如连接到磁盘时/试图打开时) /close a file) - 每次都不太可能失败,但是调用这些函数的次数越多,总体上出现错误的可能性就越大。每次打开和关闭都涉及更多这些潜在的错误,因此更容易出错。 (现在我等着被击落……)
猜你喜欢
  • 1970-01-01
  • 2017-06-27
  • 2020-08-07
  • 2020-04-17
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
  • 2016-04-27
  • 2020-03-13
相关资源
最近更新 更多