Я хотел написать большой 4-мерный файл HDF5, где значения вычисляются параллельно и записываются во взаимном исключении.
Это минимальный рабочий пример моей проблемы.
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <omp.h>
#include "H5Cpp.h"
using namespace H5;
int main(int argc, char *argv[])
{
H5File file("out.h5", H5F_ACC_TRUNC);
const uint F_RANK = 4;
const uint M_RANK = 3;
const uint D = 8;
const uint MD = 2;
std::vector<hsize_t> fdim = {D, D, 6, 1024};
std::vector<hsize_t> count = {1, 1, 6, 1024};
std::vector<hsize_t> mdim = {MD, 6, 1024};
float fillvalue = -1.0;
DSetCreatPropList plist;
plist.setFillValue(PredType::NATIVE_FLOAT, &fillvalue);
DataSpace fspace(F_RANK, fdim.data());
DataSet dataset = file.createDataSet("data", PredType::NATIVE_FLOAT, fspace, plist);
#pragma omp parallel
{
uint id = omp_get_thread_num();
std::vector<hsize_t> start(F_RANK, 0);
DataSpace private_fspace = dataset.getSpace();
DataSpace private_mspace(M_RANK, mdim.data());
private_mspace.selectAll();
std::cout << "THREAD " << id << " STARTS" << std::endl;
#pragma omp for ordered schedule(static)
for (uint b = 0; b < D*D / MD; b++)
{
// Assume this is an expensive computation
std::vector<float> data(MD*6*1024, b);
#pragma omp critical
{
private_fspace.selectNone();
std::cout << "THREAD " << id << " SELECTED NONE" << std::endl;
// Store batch
for (uint p = 0; p < MD; p++)
{
start[0] = b / (D*D) + p;
start[1] = p;
private_fspace.selectHyperslab(H5S_SELECT_OR, count.data(), start.data());
std::cout << "THREAD " << id << " SELECTED " << start[0] << ' ' << start[1] << std::endl;
}
std::cout << "ABOUT TO WRITE " << private_fspace.getSelectNpoints() << std::endl;
dataset.write(data.data(), PredType::NATIVE_FLOAT, private_mspace, private_fspace);
private_fspace.selectNone();
}
std::cout << "WRITTEN" << std::endl;
}
}
}
Я компилирую его, используя h5c++ example.cpp -fopenmp
.
Во время работы может произойти много возможных ошибок, некоторые - ошибки сегментации, другие - прерывания и даже ошибки шины.Есть даже некоторые ошибки библиотеки HDF5, подобные этим
HDF5: infinite loop closing library
L,T_top,P,P,Z,FD,E,SL,FL,FL,.....
Иногда происходит сбой перед записью чего-либо, иногда он завершается без ошибок.Конечно, это происходит только тогда, когда для OMP_NUM_THREADS
установлено значение больше 1, поэтому проблема заключается в параллелизме.Тем не менее, я установил все релевантные переменные как частные для каждого процесса, и все происходит в критической секции, поэтому я не вижу, как это происходит.
Отладка на GDB показывает, что HDF5 может не работатьDataSet :: getSpace () с ошибкой сегментации, но существует множество способов его сбоя, я бы сказал, что проблема более общая, чем эта.