Как записать / прочитать неровные массивы в файле HDF5 с помощью API C ++? - PullRequest
0 голосов
/ 03 марта 2020

У меня есть несколько std::vector разных размеров, содержащих поплавки. Я хотел бы записать / прочитать их все в виде зубчатого массива в файле HDF5 (в идеале один за другим, используя гиперсписки, так как я не могу держать все векторы в памяти одновременно). Я считаю, что мне следует использовать обычный массив, каждый из элементов которого имеет тип данных переменной длины, но все примеры, которые я нашел, были C примерами. Мой код выглядит следующим образом:

#include <vector>
#include "H5Cpp.h"

int main() {
  std::vector<float> v1 {0.1, 0.2, 0.3};
  std::vector<float> v2 {0.4, 0.5};

  H5::VarLenType array_type (H5::PredType::NATIVE_FLOAT);

  hsize_t dimensions[1] = {2};
  H5::DataSpace dataspace (1, dimensions);

  H5::H5File file ("jarray.h5", H5F_ACC_TRUNC);
  H5::DataSet dataset = file.createDataSet("jarray", array_type, dataspace);

  hsize_t size[1] = {1};
  hsize_t offset[1] = {0};
  dataspace.selectHyperslab(H5S_SELECT_SET, size, offset);

  dataset.write(v1.data(), array_type);

  return 0;
};

Если я пропускаю вызов функции write, код создает пустой файл со следующей структурой (как распечатано h5dump):

HDF5 "jarray.h5" {
GROUP "/" {
   DATASET "jarray" {
      DATATYPE  H5T_VLEN { H5T_IEEE_F32LE}
      DATASPACE  SIMPLE { ( 2 ) / ( 2 ) }
      DATA {
      (0): (), ()
      }
   }
}
}

Это заставляет меня верить, что набор данных имеет правильную структуру, но я не совсем правильно пишу.

Может кто-нибудь уточнить, как записать в такой массив? Как один go о чтении значений потом? Любая помощь будет высоко ценится.

1 Ответ

0 голосов
/ 03 марта 2020

Не уверен, как это сделать с HDF5 C ++ API, но вы можете попробовать HDFql , так как он избавляет вас от низкоуровневых деталей HDF5. Используя HDFql в C ++, вы можете сделать следующее для записи / чтения зубчатого массива HDF5:

// create HDF5 file 'jarray.h5'
HDFql::execute("CREATE FILE jarray.h5");

// use (i.e. open) file 'jarray.h5'
HDFql::execute("USE FILE jarray.h5");

// create HDF5 dataset 'jarray' of one dimension (size 2) as a variable-length float (i.e. jagged)
HDFql::execute("CREATE DATASET jarray AS VARFLOAT(2)");

// write 0.1, 0.2 and 0.3 in first row of dataset 'jarray', 0.4 and 0.5 in second row
HDFql::execute("INSERT INTO jarray VALUES((0.1, 0.2, 0.3), (0.4, 0.5))");

// read first row of dataset 'jarray' using an hyperslab and populate cursor with values
HDFql::execute("SELECT FROM jarray(0:::1)");

// display values of first row
while (HDFql::cursorNext() == HDFql::SUCCESS)
{
     std::cout << *HDFql::cursorGetFloat() << std::endl;
}

// read second row of dataset 'jarray' using an hyperslab and populate cursor with values
HDFql::execute("SELECT FROM jarray(1:::1)");

// display values of second row
while (HDFql::cursorNext() == HDFql::SUCCESS)
{
     std::cout << *HDFql::cursorGetFloat() << std::endl;
}

Это короткий пример, основанный на прямой записи значений. Если вам нужно писать / читать, используя пользовательскую память (т. Е. Переменную), пожалуйста, ознакомьтесь с справочным руководством и примерами , чтобы получить дополнительную информацию.

...