Совет (лучшие практики) по работе с большим количеством больших 2D-массивов в файлах HDF5

Я использую программу Python для записи массива 4000x4000 в файл hdf5. Затем я читаю данные c-программой, где они мне нужны в качестве входных данных для моделирования. Мне нужно примерно 1000 из этих массивов 4000x4000 (то есть я выполняю 1000 запусков моделирования).

Теперь у меня следующий вопрос: какой способ «лучше»: 1000 отдельных файлов hdf5 или один большой файл hdf5 с 1000 различными наборами данных (с именем «dataset_% 04d»)?

Мы очень ценим любые советы или передовые методы поведения для такого рода проблем (так как я не слишком знаком с hdf5).


В случае, если это интересно, вот код Python, который я использую для записи файла hdf5:

import h5py
h5f = h5py.File( 'data_0001.h5', 'w' )
h5f.create_dataset( 'dataset_1', data=myData )
h5f.close

person Alf    schedule 04.11.2015    source источник
comment
Почему бы Вам просто не протестировать и не рассказать нам;) Я не уверен, что есть правильный ответ. HDF5 не имеет ограничений на размер файла, поэтому, если ваш вариант использования требует быстрого доступа к наборам данных, то их размещение в одном файле может быть преимуществом, таким образом можно избежать времени, затрачиваемого на открытие файлов (и в файловых системах HPD, по крайней мере, на этот раз может быть значительным).   -  person kakk11    schedule 05.11.2015
comment
вроде того, что я делаю в данный момент. Я решил попробовать подход с одним большим файлом, который должен привести к размеру файла ~ 40 ГБ. Мой вопрос был нацелен на то, чтобы узнать, как опытный пользователь hdf5 справится с этим. Из того, что я читал в Интернете, у меня сложилось впечатление, что это будет подход с одним файлом. Спасибо за подтверждение моего предположения об ограничении размера файла.   -  person Alf    schedule 05.11.2015


Ответы (2)


Это действительно интересно, поскольку сейчас я сталкиваюсь с аналогичной проблемой.

Performace

Чтобы исследовать проблему более подробно, я создал следующий файл

import h5py
import numpy as np

def one_file(shape=(4000, 4000), n=1000):
    h5f = h5py.File('data.h5', 'w')

    for i in xrange(n):
        dataset = np.random.random(shape)
        dataset_name = 'dataset_{:08d}'.format(i)
        h5f.create_dataset(dataset_name, data=dataset)
        print i

    h5f.close()


def more_files(shape=(4000, 4000), n=1000):

    for i in xrange(n):
        file_name = 'data_{:08d}'.format(i)
        h5f = h5py.File(file_name, 'w')
        dataset = np.random.random(shape)
        h5f.create_dataset('dataset', data=dataset)
        h5f.close()
        print i

Затем в IPython

>>> from testing import one_file, more_files
>>> %timeit one_file(n=25) # with n=25, the resulting file is 3.0GB
1 loops, best of 3: 42.5 s per loop
>>> %timeit more_files(n=25)
1 loops, best of 3: 41.7 s per loop

>>> %timeit one_file(n=250)
1 loops, best of 3: 7min 29s per loop
>>> %timeit more_files(n=250)
1 loops, best of 3: 8min 10s per loop

Разница для меня весьма удивительна, поскольку n=25 иметь больше файлов быстрее, однако это уже не правда для большего количества наборов данных.

Опыт

Как отмечали другие в комментариях, вероятно, нет правильного ответа, поскольку это очень специфическая проблема. Я использую файлы hdf5 для своих исследований в области физики плазмы. Не знаю, поможет ли это вам, но могу поделиться своим опытом с hdf5.

Я запускаю множество симуляций и выводю данные для данной симуляции, которые используются для перехода к одному файлу hdf5. Когда симуляция закончилась, она выгружала свое состояние в этот файл hdf5, так что позже я смог взять это состояние и расширить симуляцию с этой точки (я мог бы также изменить некоторые параметры, и мне не нужно начинать с нуля). Результат этого моделирования снова попал в тот же файл. Это было здорово - у меня был только один файл для одной симуляции. Однако у этого подхода есть определенные недостатки:

  1. Когда симуляция дает сбой, вы получаете неполный файл - вы не можете начать новую симуляцию из этого файла.
  2. Нет простого способа, как безопасно заглянуть в файл hdf5, когда другой процесс записывает в этот файл. Если случится так, что вы пытаетесь читать из, а другой процесс выполняет запись, вы получаете поврежденный файл, и все ваши данные теряются!
  3. Я не знаю простого способа, как вы можете удалить группы из файла (я кто-нибудь знает способ, дайте мне знать). Итак, если мне нужно реструктурировать файл, мне нужно создать из него новый (h5copy, h5repack, ...).

Итак, я пришел к такому подходу, который работает намного лучше:

  1. Я периодически сбрасываю состояние из симуляции и после этого записываю в новый файл. Если симуляция дает сбой, мне нужно удалить только последний файл, и я не теряю много времени процессора.
  2. В настоящее время я рисую только данные из всех файлов, кроме последнего. Обратите внимание, что есть другой способ: см. здесь, но мой подход определенно проще и Я согласен с этим.
  3. Намного лучше обрабатывать больше маленьких файлов, чем один огромный файл - вы видите прогресс и так далее.

Надеюсь это поможет.

person ziky    schedule 08.11.2015
comment
Спасибо за ответ @ziky. На самом деле, вы не единственный физик-плазменник, работающий здесь с файлами hdf5;) Я решил сделать следующее: для ввода симуляций (в основном сетки) я использую один большой файл hdf5 (тот же файл для всех симуляций). В настоящий момент они выполняются последовательно (одна симуляция, затем другая и так далее), поэтому параллельного доступа к этому файлу нет - хотя я планирую это изменить, давайте посмотрим, работает ли он по-прежнему. Поскольку я также хочу иметь доступ к результатам во время моделирования, я решил использовать один выходной файл для каждого прогона (по тем же причинам, что и ваша). - person Alf; 10.11.2015
comment
Мне нравится, @Alf. Я также использую параллельный доступ к файлу h5, поскольку моя симуляция написана на Fortran + MPI. Я использую Python только для обработки результатов. И я думаю, вам нужно использовать mpi для параллельного доступа к файлу (но я могу ошибаться). Я потратил довольно много времени на параллельные процедуры ввода-вывода. Довольно сложно иметь возможность записывать в файл только из одного процесса или из всех сразу. Если вам интересно, дайте мне знать, и я могу поделиться опытом. - person ziky; 10.11.2015

Я знаю, что немного опоздал на вечеринку, но я подумал, что поделюсь своим опытом. Мои размеры данных меньше, но с точки зрения простоты анализа я предпочитаю один большой (1000, 4000, 4000) набор данных. В вашем случае похоже, что вам нужно использовать свойство maxshape, чтобы сделать его расширяемым при создании новых результатов. Сохранение нескольких отдельных наборов данных затрудняет просмотр тенденций в наборах данных, так как вам придется разрезать их все по отдельности. С одним набором данных вы могли бы сделать, например. data[:, 5, 20], чтобы посмотреть через 3-ю ось. Кроме того, для решения проблемы повреждения я настоятельно рекомендую использовать h5py.File в качестве диспетчера контекста:

with h5py.File('myfilename') as f:
    f.create_dataset('mydata', data=data, maxshape=(1000, 4000, 4000))

Это автоматически закрывает файл, даже если есть исключение. Раньше я постоянно ругался из-за поврежденных данных, а потом начал это делать, и с тех пор у меня не было проблем.

person m3wolf    schedule 06.08.2016