2015-12-16 2 views
2

Я пытаюсь написать трехмерные данные (Nx x Ny x Nz), которые хранятся в памяти как линейный массив (k + Nz * j + Nz * Ny * i), в файл HDF5 с использованием гиперспиров. Смотрите мой код:Запись 3D-данных в файл HDF5 в C

#include <stdio.h> 
#include <math.h> 
#include <string.h> 
#include <stdlib.h> 
#include <float.h> 

#include "hdf5.h" 

int main(int argc, char *argv[]) 
{ 
    int i, j, k; 
    int count = 0; 
    int Nx = 180; 
    int Ny = 128; 
    int Nz = 128; 

    double *data = (double *)malloc(Nx * Ny * Nz * sizeof(double)); 

    for (i = 0; i < Nx; i++) 
    { 
     for (j = 0; j < Ny; j++) 
     { 
      for (k = 0; k < Nz; k++) 
      { 
       data[k + Nz * j + Nz * Ny * i] = (double)count; 
       count++; 
      } 
     } 
    } 

    hid_t err; 
    hid_t dataspace, memspace, dataset; 
    hid_t file_identifier; 
    int rank; 
    hsize_t dimens_3d[3]; 
    hsize_t start_3d[3]; 
    hsize_t stride_3d[3]; 
    hsize_t count_3d[3]; 

    char *file_name = "data.h5"; 

    file_identifier = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); 

    rank = 3; 

    dimens_3d[0] = Nz; 
    dimens_3d[1] = Ny; 
    dimens_3d[2] = Nx; 

    dataspace = H5Screate_simple(rank, dimens_3d, NULL); 

    start_3d[0] = 0; 
    start_3d[1] = 0; 
    start_3d[2] = 0; 

    stride_3d[0] = 1; 
    stride_3d[1] = 1; 
    stride_3d[1] = 1; 

    count_3d[0] = Nz; 
    count_3d[1] = Ny; 
    count_3d[2] = Nx; 

    err = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start_3d, stride_3d, count_3d, NULL); 

    dimens_3d[0] = Nz; 
    dimens_3d[1] = Ny; 
    dimens_3d[2] = Nx; 

    memspace = H5Screate_simple(rank, dimens_3d, NULL); 

    start_3d[0] = 0; 
    start_3d[1] = 0; 
    start_3d[2] = 0; 

    stride_3d[0] = 1; 
    stride_3d[1] = 1; 
    stride_3d[1] = 1; 

    count_3d[0] = Nz; 
    count_3d[1] = Ny; 
    count_3d[2] = Nx; 

    err = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start_3d, stride_3d, count_3d, NULL); 

    dataset = H5Dcreate(file_identifier, "data", H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); 

    err = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, memspace, dataspace, H5P_DEFAULT, &(data[0])); 

    H5Sclose(memspace); 
    H5Sclose(dataspace); 
    H5Dclose(dataset); 

    H5Fclose(file_identifier); 

    free(data); 

    return 0; 
} 

Этот пример не помещает никаких данных в файл, и я не могу понять, почему. Файл создается, но когда я выгружаю его в XML-файл с помощью утилиты h5dump (h5dump -u data.h5> data.xml), нет значений для массива data. Если я комментирую строки с H5Sselect_hyperslab, значения функции появляются в файле.

Я понимаю, что здесь использование функции H5Sselect_hyperslab не является обязательным, но следующим шагом для меня будет запись HDF5 параллельно, где будет необходимо использовать гиперслои.

+0

Пожалуйста, предоставьте полный компилируемый пример. –

+0

Как вы узнали, что все открылось? Существует ли файл? Он содержит что-нибудь? Где ваши данные отладки? Этот вопрос безнадежен: (( –

+0

Я обновил код и расширил описание проблемы. Еще раз создаем файл, и я вижу содержимое файла с помощью утилиты h5dump. – kpa

ответ

3

Вы сделали опечатку в stride_3d: вы установите stride_3d[1] дважды и никогда не установлен stride_3d[2] поэтому начальное значение stride_3d[2] не определено (а.к.а. мусор) и вызов H5Sselect_hyperslab терпит неудачу. Что подводит нас к моему второму пункту ...

Проверьте свои ошибки! После каждого вызова API вы должны проверить значение err.

+0

Большое спасибо за помощь, это был глупая ошибка. Теперь я проверяю коды ошибок. – kpa