Тип соединения HDF5 Собственный по сравнению с IEEE

Я только собираю HDF5, и меня немного смущает разница между созданием данных для памяти и созданием данных для файла. Какая разница?

В этом примере создание данных составного типа требует, чтобы данные были созданы в памяти и помещены в файл:

 /*
 * Create the memory data type. 
 */
s1_tid = H5Tcreate (H5T_COMPOUND, sizeof(s1_t));
H5Tinsert(s1_tid, "a_name", HOFFSET(s1_t, a), H5T_NATIVE_INT);
H5Tinsert(s1_tid, "c_name", HOFFSET(s1_t, c), H5T_NATIVE_DOUBLE);
H5Tinsert(s1_tid, "b_name", HOFFSET(s1_t, b), H5T_NATIVE_FLOAT);

/* 
 * Create the dataset.
 */
dataset = H5Dcreate(file, DATASETNAME, s1_tid, space, H5P_DEFAULT);

/*
 * Wtite data to the dataset; 
 */
status = H5Dwrite(dataset, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s1);

Однако в другом примере здесь автор также создает для файла составные данные, в которых указывается другой тип данных. Например, при создании типа данных для памяти serial_no использовал тип H5T_NATIVE_INT, но при создании типа данных для файла serial_no использовал H5T_STD_I64BE. Почему он это делает?

    /*
 * Create the compound datatype for memory.
 */
memtype = H5Tcreate (H5T_COMPOUND, sizeof (sensor_t));
status = H5Tinsert (memtype, "Serial number",
            HOFFSET (sensor_t, serial_no), H5T_NATIVE_INT);
status = H5Tinsert (memtype, "Location", HOFFSET (sensor_t, location),
            strtype);
status = H5Tinsert (memtype, "Temperature (F)",
            HOFFSET (sensor_t, temperature), H5T_NATIVE_DOUBLE);
status = H5Tinsert (memtype, "Pressure (inHg)",
            HOFFSET (sensor_t, pressure), H5T_NATIVE_DOUBLE);

/*
 * Create the compound datatype for the file.  Because the standard
 * types we are using for the file may have different sizes than
 * the corresponding native types, we must manually calculate the
 * offset of each member.
 */
filetype = H5Tcreate (H5T_COMPOUND, 8 + sizeof (hvl_t) + 8 + 8);
status = H5Tinsert (filetype, "Serial number", 0, H5T_STD_I64BE);
status = H5Tinsert (filetype, "Location", 8, strtype);
status = H5Tinsert (filetype, "Temperature (F)", 8 + sizeof (hvl_t),
            H5T_IEEE_F64BE);
status = H5Tinsert (filetype, "Pressure (inHg)", 8 + sizeof (hvl_t) + 8,
            H5T_IEEE_F64BE);

/*
 * Create dataspace.  Setting maximum size to NULL sets the maximum
 * size to be the current size.
 */
space = H5Screate_simple (1, dims, NULL);

/*
 * Create the dataset and write the compound data to it.
 */
dset = H5Dcreate (file, DATASET, filetype, space, H5P_DEFAULT, H5P_DEFAULT,
            H5P_DEFAULT);
status = H5Dwrite (dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);

В чем разница между этими двумя методами?


person foboi1122    schedule 28.02.2013    source источник


Ответы (2)


Из http://www.hdfgroup.org/HDF5/doc/UG/UG_frame11Datatypes. HTML:

H5T_NATIVE_INT соответствует типу C int. На ПК на базе Intel этот тип аналогичен H5T_STD_I32LE, а в системе MIPS он будет эквивалентен H5T_STD_I32BE.

То есть H5T_NATIVE_INT имеет разную структуру памяти на разных типах процессоров. Если ваши данные используются только в памяти, что означает, что ваши данные не будут выходить за пределы этой машины, вы можете использовать H5T_NATIVE_INT для повышения производительности.

Но если ваши данные будут сохранены в файл и будут использоваться разными системами, вы должны указать определенный тип int, чтобы ваши данные могли быть правильно прочитаны, например. H5T_STD_I64BE или H5T_STD_I32LE. Если вы используете H5T_NATIVE_INT и создали файл данных на ПК с процессором Intel, номер будет сохранен как H5T_STD_I32LE. Когда этот файл используется системой MIPS, он будет считывать номер как H5T_STD_I32BE, что не ожидается.

person Chen    schedule 01.03.2013
comment
из моей интерпретации: нормально иметь тип файла с NATIVE_some_type; клиенты несут ответственность за сопоставление при считывании содержимого. другими словами: когда этот файл используется системой MIPS, он будет читать номер как H5T_STD_I32BE, что не ожидается. не правда; клиент должен прочитать тип файла обратно и создать соответствующий макет памяти. Клиент должен ожидать несоответствия порядка байтов и устранять их с помощью правильного сопоставления. Пример демонстрирует, что порядок байтов/макет файла не связан с порядком/макетом байтов хоста (памяти). - person Steven Varga; 22.08.2014
comment
@StevenVarga Если вы используете H5T_NATIVE_INT, вы не знаете, это прямой или прямой порядок байтов, если вы не поместите где-нибудь флаг, указывающий, каков порядок байтов. Даже если вы знаете фактический порядок байтов, преобразование всех данных после их загрузки не является тривиальной задачей. И обслуживание кода также сложно. Зачем беспокоиться? Почему бы не использовать явный порядок байтов при сохранении в файл? - person Chen; 26.08.2014

В другом ответе здесь отсутствуют некоторые ключевые идеи, из-за чего использование типов данных HDF5 кажется более сложным, чем оно есть на самом деле.

Начнем с того, что типы NATIVE — это просто псевдонимы того, на что сопоставляются типы C на этой платформе (это обнаруживается при сборке библиотеки HDF5). Если вы используете их в своем коде и посмотрите на файл, который вы создали с помощью инструмента h5dump, вы не увидите NATIVE тип данных, а вместо этого увидите реальный тип данных (H5T_STD_I32LE или что-то еще). Эти НАТИВНЫЕ типы, по общему признанию, немного сбивают с толку, но они удобны для отображения между типами C и типами данных HDF5 без необходимости знать порядок байтов системы, в которой вы находитесь.

Другое заблуждение, которое я хочу развеять, состоит в том, что библиотека будет преобразовывать типы за вас, когда это будет разумно. Если набор данных содержит значения H5T_STD_I32BE, и вы объявляете буфер ввода-вывода равным H5T_NATIVE_INT в системе с прямым порядком байтов, библиотека HDF5 преобразует целые числа набора данных с прямым порядком байтов в находящиеся в памяти целые числа с прямым порядком байтов. Вам не нужно выполнять замену байтов самостоятельно.

Вот простой способ подумать об этом:

  • Вы объявляете тип данных хранилища набора данных при вызове H5Dcreate().
  • Вы объявляете тип данных буфера ввода/вывода при вызове H5Dread() и H5Dwrite().

Опять же, если они различаются и преобразования типов разумны, данные будут преобразованы во время вызовов чтения/записи.

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

Пример: предположим, что у вас есть модуль записи BE и модуль чтения LE, и данные поступают медленно, но чтение должно быть максимально быстрым. в этом случае вы захотите явно создать свой набор данных для хранения данных H5T_STD_I32LE, чтобы преобразования типов данных происходили в модуле записи.

И последнее. Лучше использовать макрос HOFFSET(s,m) вместо вычисления смещений вручную при построении составных типов. Это проще в сопровождении, и ваш код будет выглядеть лучше.

Если вам нужна дополнительная информация о типах данных HDF5, ознакомьтесь с главой 6 руководства пользователя здесь: https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html

Вы также можете ознакомиться с документацией по H5T API в справочном руководстве здесь: https://support.hdfgroup.org/HDF5/doc/RM/RM_H5Front.html

person Dana Robinson    schedule 27.09.2017