【问题标题】:How to set cache settings while using h5py high level interface?使用 h5py 高级接口时如何设置缓存设置?
【发布时间】:2021-04-30 22:05:59
【问题描述】:

我正在尝试增加 HDF5 文件的缓存大小,但它似乎不起作用。 这就是我所拥有的:

import h5py

with h5py.File("test.h5", 'w') as fid:
        # cache settings of file
        cacheSettings = list(fid.id.get_access_plist().get_cache())
        print cacheSettings
        # increase cache
        cacheSettings[2] = int(5 * cacheSettings[2])
        print cacheSettings
        # read cache settings from file
        fid.id.get_access_plist().set_cache(*cacheSettings)
        print fid.id.get_access_plist().get_cache()

这是输出:

[0, 521, 1048576, 0.75]
[0, 521, 5242880, 0.75]
(0, 521, 1048576, 0.75)

知道为什么阅读有效,但设置无效吗?
关闭并重新打开文件似乎也无济于事。

【问题讨论】:

    标签: python h5py


    【解决方案1】:

    如果您使用的是 h5py 2.9.0 或更高版本,请参阅Mike's answer


    根据the docsget_access_plist() 返回文件访问属性列表的副本。所以修改副本不影响原件也就不足为奇了。

    似乎高级界面不提供更改缓存设置的方法。

    这是使用低级接口的方法。

    propfaid = h5py.h5p.create(h5py.h5p.FILE_ACCESS)
    settings = list(propfaid.get_cache())
    print(settings)
    # [0, 521, 1048576, 0.75]
    
    settings[2] *= 5
    propfaid.set_cache(*settings)
    settings = propfaid.get_cache()
    print(settings)
    # (0, 521, 5242880, 0.75)
    

    上面创建了一个PropFAID。然后我们可以通过这种方式打开文件并获得FileID

    import contextlib
    with contextlib.closing(h5py.h5f.open(
                            filename, flags=h5py.h5f.ACC_RDWR, fapl=propfaid)) as fid:
        # <h5py.h5f.FileID object at 0x9abc694>
        settings = list(fid.get_access_plist().get_cache())
        print(settings)
        # [0, 521, 5242880, 0.75]
    

    我们可以使用fid通过将fid传递给h5py.File来使用高级接口打开文件:

        f = h5py.File(fid)
        print(f.id.get_access_plist().get_cache())
        # (0, 521, 5242880, 0.75)
    

    因此,您仍然可以使用高级界面,但需要一些时间 摆弄着到达那里。另一方面,如果您将其提炼成基本要素,也许还不错:

    import h5py
    import contextlib
    
    filename = '/tmp/foo.hdf5'
    propfaid = h5py.h5p.create(h5py.h5p.FILE_ACCESS)
    settings = list(propfaid.get_cache())
    settings[2] *= 5
    propfaid.set_cache(*settings)
    with contextlib.closing(h5py.h5f.open(filename, fapl=propfaid)) as fid:
        f = h5py.File(fid)
    

    【讨论】:

    • 那么在这行之后:f = h5py.File(fid)我可以使用高级API来创建数据集吗?:dset = f.create_dataset("zipped_max", (100, 100), compression="gzip", compression_opts=9)
    • 是的;这就是物体的美。一旦你有了对象,它就拥有了该类的所有方法,无论对象是如何创建的。
    • 太棒了!我一直在使用高级 API,但我刚刚意识到我需要退后一步通过低级 API 增加缓存大小。感谢您的回复。
    • 我在确保文件已关闭时遇到问题。我已经发布了一个相关的问题:How to close an HDF5 using low level Python API?
    • 请注意,从 h5py 版本 2.9.0 开始,可以通过 h5py.File 的参数直接操作缓存参数。这个答案(+1)实际上是我用来在 h5py 中编写的代码,但用户不再需要这样做。看我的回答。
    【解决方案2】:

    从 h5py 版本 2.9.0 开始,此行为现在可以直接通过主 h5py.File 界面使用。控制“原始数据块缓存”的三个参数 — rdcc_nbytesrdcc_w0rdcc_nslots — 记录在 here。 OP 试图调整 rdcc_nbytes 设置,现在可以简单地完成

    import h5py
    
    with h5py.File("test.h5", "w", rdcc_nbytes=5242880) as f:
        f.create_dataset(...)
    

    在这种情况下,我假设您知道您实际需要多少空间,而不是像 OP 想要的那样仅仅乘以 5。当前默认值与找到的 OP 相同。当然,如果您真的想以编程方式执行此操作,您可以只打开一次,获取缓存,关闭它,然后使用所需的参数重新打开。

    【讨论】:

      【解决方案3】:

      h5py-cache 项目可能会有所帮助,虽然我没有使用过:

      import h5py_cache
      with h5py_cache.File('test.h5', chunk_cache_mem_size=1024**3, 'a') as f:
          f.create_dataset(...)
      

      【讨论】:

      • 请注意,此模块已合并到 h5py 本身,因此 h5py_cache 项目 [我是作者] 现在已弃用。请参阅我的答案以了解如何使用它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 2016-02-07
      • 1970-01-01
      • 2011-12-27
      • 2012-06-25
      • 2015-05-04
      • 2012-08-14
      相关资源
      最近更新 更多