HDF5 запись не удается даже в критическом разделе OpenMP - PullRequest
0 голосов
/ 29 января 2019

Я хотел написать большой 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 () с ошибкой сегментации, но существует множество способов его сбоя, я бы сказал, что проблема более общая, чем эта.

...