Я обрабатываю количество файлов, каждая обработка файла будет выводить несколько тысяч массивов float, и я буду хранить данные всех файлов в одном огромном наборе данных в одном hdf5 для дальнейшей обработки,
В настоящее время я смущен тем, как добавить свои данные в файл hdf5. (комментарий в коде выше). В 2 для циклов выше, как вы можете видеть, я хочу добавить одномерный массив float в hdf5 за раз, а не как все это. Мои данные находятся в терабайтах, и мы можем добавлять эти данные только в файл.
Есть несколько вопросов:
- Как добавить данные в этом случае? Какую функцию я должен использовать?
- Прямо сейчас, у меня есть fdim [0] = 928347543, я попытался установить флаг бесконечности HDF5, но выполнение выполнения жалуется. Есть ли способ сделать это? Я не хочу вычислять данные, которые я имею каждый раз; есть ли способ просто продолжать добавлять данные, не заботясь о значении fdim?
Или это невозможно?
EDIT:
Я слежу за предложением Саймона, и в настоящее время здесь есть мой обновленный код:
hid_t desFi5;
hid_t fid1;
hid_t propList;
hsize_t fdim[2];
desFi5 = H5Fcreate(saveFilePath, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
fdim[0] = 3;
fdim[1] = 1;//H5S_UNLIMITED;
fid1 = H5Screate_simple(2, fdim, NULL);
cout << "----------------------------------Space done\n";
propList = H5Pcreate( H5P_DATASET_CREATE);
H5Pset_layout( propList, H5D_CHUNKED );
int ndims = 2;
hsize_t chunk_dims[2];
chunk_dims[0] = 3;
chunk_dims[1] = 1;
H5Pset_chunk( propList, ndims, chunk_dims );
cout << "----------------------------------Property done\n";
hid_t dataset1 = H5Dcreate( desFi5, "des", H5T_NATIVE_FLOAT, fid1, H5P_DEFAULT, propList, H5P_DEFAULT);
cout << "----------------------------------Dataset done\n";
bufi = new float*[1];
bufi[0] = new float[3];
bufi[0][0] = 0;
bufi[0][1] = 1;
bufi[0][2] = 2;
//hyperslab
hsize_t start[2] = {0,0};
hsize_t stride[2] = {1,1};
hsize_t count[2] = {1,1};
hsize_t block[2] = {1,3};
H5Sselect_hyperslab( fid1, H5S_SELECT_OR, start, stride, count, block);
cout << "----------------------------------hyperslab done\n";
H5Dwrite(dataset1, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, *bufi);
fdim[0] = 3;
fdim[1] = H5S_UNLIMITED; // COMPLAINS HERE
H5Dset_extent( dataset1, fdim );
cout << "----------------------------------extent done\n";
//hyperslab2
hsize_t start2[2] = {1,0};
hsize_t stride2[2] = {1,1};
hsize_t count2[2] = {1,1};
hsize_t block2[2] = {1,3};
H5Sselect_hyperslab( fid1, H5S_SELECT_OR, start2, stride2, count2, block2);
cout << "----------------------------------hyperslab2 done\n";
H5Dwrite(dataset1, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, *bufi);
cout << "----------------------------------H5Dwrite done\n";
H5Dclose(dataset1);
cout << "----------------------------------dataset closed\n";
H5Pclose( propList );
cout << "----------------------------------property list closed\n";
H5Sclose(fid1);
cout << "----------------------------------dataspace fid1 closed\n";
H5Fclose(desFi5);
cout << "----------------------------------desFi5 closed\n";
Мой текущий выход:
bash-3.2$ ./hdf5AppendTest.out
----------------------------------Space done
----------------------------------Property done
----------------------------------Dataset done
----------------------------------hyperslab done
HDF5-DIAG: Error detected in HDF5 (1.8.10) thread 0:
#000: /home/hdftest/snapshots-bin-hdf5_1_8_10/current/src/H5D.c line 1103 in H5Dset_extent(): unable to set extend dataset
major: Dataset
minor: Unable to initialize object
#001: /home/hdftest/snapshots-bin-hdf5_1_8_10/current/src/H5Dint.c line 2179 in H5D__set_extent(): unable to modify size of data space
major: Dataset
minor: Unable to initialize object
#002: /home/hdftest/snapshots-bin-hdf5_1_8_10/current/src/H5S.c line 1874 in H5S_set_extent(): dimension cannot exceed the existing maximal size (new: 18446744073709551615 max: 1)
major: Dataspace
minor: Bad value
----------------------------------extent done
----------------------------------hyperslab2 done
----------------------------------H5Dwrite done
----------------------------------dataset closed
----------------------------------property list closed
----------------------------------dataspace fid1 closed
----------------------------------desFi5 closed
В настоящее время я вижу, что установка элементов без ограничений с помощью H5Dset_extent все еще вызывает проблемы во время выполнения. (проблемная функция отмечена //COMPLAINS HERE
в коде выше). Я уже получил данные chunk, как указано Саймоном, так что проблема здесь?
С другой стороны, без H5Dset_extent я могу просто написать тестовый массив из [0, 1, 2], но как мы можем сделать код выше вывода тестового массива в файл следующим образом:
[0, 1, 2]
[0, 1, 2]
[0, 1, 2]
[0, 1, 2]
...
...
Вспомните: это всего лишь тестовый массив, реальные данные больше, и я не могу удержать все это в ОЗУ, поэтому я должен поместить данные частично по первой части за раз.
ИЗМЕНИТЬ 2:
Я следовал за Саймоном. Вот критическая часть:
hsize_t n = 3, p = 1;
float *bufi_data = new float[n * p];
float ** bufi = new float*[n];
for (hsize_t i = 0; i < n; ++i){
bufi[i] = &bufi_data[i * n];
}
bufi[0][0] = 0.1;
bufi[0][1] = 0.2;
bufi[0][2] = 0.3;
//hyperslab
hsize_t start[2] = {0,0};
hsize_t count[2] = {3,1};
H5Sselect_hyperslab( fid1, H5S_SELECT_SET, start, NULL, count, NULL);
cout << "----------------------------------hyperslab done\n";
H5Dwrite(dataset1, H5T_NATIVE_FLOAT, H5S_ALL, fid1, H5P_DEFAULT, *bufi);
bufi[0][0] = 0.4;
bufi[0][1] = 0.5;
bufi[0][2] = 0.6;
hsize_t fdimNew[2];
fdimNew[0] = 3;
fdimNew[1] = 2;
H5Dset_extent( dataset1, fdimNew );
cout << "----------------------------------extent done\n";
//hyperslab2
hsize_t start2[2] = {0,0}; //PROBLEM
hsize_t count2[2] = {3,1};
H5Sselect_hyperslab( fid1, H5S_SELECT_SET, start2, NULL, count2, NULL);
cout << "----------------------------------hyperslab2 done\n";
H5Dwrite(dataset1, H5T_NATIVE_FLOAT, H5S_ALL, fid1, H5P_DEFAULT, *bufi);
Из вышесказанного я получил следующий вывод для hdf5:
0.4 0.5 0.6
0 0 0
После дополнительного эксперимента с start2
и count2
, я вижу, что эти переменные влияют только на начальный индекс и индекс инкремента для bufi
. Он вообще не перемещает позицию индекса записи моего набора данных.
Напомним: окончательный результат должен быть:
0.1 0.2 0.3
0.4 0.5 0.6
Кроме того, он должен быть bufi
вместо *bufi
для H5Dwrite
, Simon, потому что bufi
дает мне полностью случайные числа.
ОБНОВЛЕНИЕ 3:
Для части выбора, предложенной Саймоном:
hsize_t start[2] = {0, 0};
hsize_t count[2] = {1, 3};
hsize_t start[2] = {1, 0};
hsize_t count[2] = {1, 3};
Они выдадут следующую ошибку:
HDF5-DIAG: Error detected in HDF5 (1.8.10) thread 0:
#000: /home/hdftest/snapshots-bin-hdf5_1_8_10/current/src/H5Dio.c line 245 in H5Dwrite(): file selection+offset not within extent
major: Dataspace
minor: Out of range
count[2]
должен быть {3,1}
, а не {1,3}
, я полагаю? И для start[2]
, если я не устанавливаю его как {0,0}
, он всегда будет выкрикивать ошибку выше.
Вы уверены, что это правильно?