如何在使用h5py高级接口时设置缓存配置?

5 投票
3 回答
4959 浏览
提问于 2025-04-17 14:28

我正在尝试增加我的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)

有没有人知道为什么读取是可以的,但设置却不行呢?
关闭文件再重新打开似乎也没有帮助。

3 个回答

1

这个h5py-cache项目可能会对你有帮助,虽然我自己没有使用过:

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

从h5py版本2.9.0开始,这种功能可以直接通过主要的h5py.File接口来使用。有三个参数可以控制“原始数据块缓存”——rdcc_nbytesrdcc_w0rdcc_nslots——详细信息可以在这里找到。提问者想调整rdcc_nbytes这个设置,现在可以简单地这样做:

import h5py

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

在这种情况下,我假设你知道自己实际需要多少空间,而不是像提问者那样随便乘以5。当前的默认值和提问者找到的一样。当然,如果你真的想通过编程来实现这个功能,你可以先打开一次文件,获取缓存,关闭它,然后再用想要的参数重新打开。

8

如果你使用的是h5py版本2.9.0或更新的版本,可以参考Mike的回答


根据文档get_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)

撰写回答