以并行HDF5创建可扩展数据集

时间:2015-08-19 16:44:21

标签: c++ boost parallel-processing mpi hdf5

我正在尝试将数据并行写入hdf5文件。每个节点都有自己的数据集,这是唯一的(虽然它们的大小相同)。我试图将它们全部写入hdf5文件中的单独数据集中。问题是后来我可能想用不同大小的数据集覆盖它们(与原始数据集集相比大小不同---每个处理器上的数据集大小相同)。有谁知道怎么做?

(代码依赖于boost和Eigen)

我有代码首先打开文件:

boost::mpi::environment env(argc, argv);

// set up the info for HDF5 and MPI
MPI_Comm comm = MPI_COMM_SELF;
MPI_Info info = MPI_INFO_NULL;

// Set up file access property list with parallel I/O access
hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS);
H5Pset_fapl_mpio(plist_id, comm, info);

// declare the file ID
std::string filename = "test.h5";

// create a file
hid_t fileID = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, plist_id);

// close the property list
H5Pclose(plist_id);

然后创建和编写数据集:

// get the mpi communicator
unique_ptr<mpi::communicator> worldComm(new mpi::communicator);

const Eigen::VectorXd dataset = worldComm->rank() * Eigen::VectorXd::Ones(3);
const std::string name = "/vector";

// sleep for a bit so the processors are doing something different
sleep(worldComm->rank() * 2.0);

// the sizes of the data set
const hsize_t dimsf[2] = {(hsize_t)dataset.rows(), (hsize_t)dataset.cols()};

// set the maximum size of the data set to be unlimited
const hsize_t maxdim[2] = {H5S_UNLIMITED, H5S_UNLIMITED};

// the size of each chuck --- is there a better way to choose these numbers!?!?!?!
const hsize_t chunkDims[2] = {2, 5};

// create the dataspace for the dataset.
const hid_t filespace = H5Screate_simple(2, dimsf, maxdim); 
assert(filespace>0);

// modify data set creation properties --- enable chunking
const hid_t prop = H5Pcreate(H5P_DATASET_CREATE);
const hid_t status = H5Pset_chunk(prop, 2, chunkDims);

// create the dataset with default properties for each process
std::vector<hid_t> dsetVec(worldComm->size());
for( int i=0; i<worldComm->size(); ++i ) {
  const std::string datasetName = name+"_rank_"+std::to_string(i);

  dsetVec[i] = H5Dcreate2(fileID, datasetName.c_str(), H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT, prop, H5P_DEFAULT);
}

// Create property list for dataset write.
const hid_t plistID = H5Pcreate(H5P_DATASET_XFER);

// write the data to file
H5Dwrite(dsetVec[worldComm->rank()], H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, plistID, dataset.data());

// close the filespace 
H5Sclose(filespace);

// close the datasets
for( int i=0; i<worldComm->size(); ++i ) {
  H5Dclose(dsetVec[i]);
}

// close the file
H5Fclose(fileID);

我期望的是四个名为&#34; / vector_rank_i&#34;的数据集。 (i = 0,1,2,3)每个大小为3且值为[0,0,0],[1,1,1],[2,2,2]和[3,3,3],分别。但是,正在生成的是名为&#34; / vector_rank_i&#34;的四个数据集。 (i = 0,1,2,3)每个大小为3但值为[0,0,0],[0,0,0],[0,0,0]和[3,3,3] ]。

如果我不使用分块,这个确切的代码可以正常工作。但是,由于我以后需要能够扩展数据集,因此这不太理想。有谁知道一个好的工作?

1 个答案:

答案 0 :(得分:0)

在回答您的特定代码之前,我想了解更多关于为什么“每个进程一个数据集”是您选择分解问题的原因。如果你要扩展到少数几个过程之外,这似乎是一团糟。

您正在对数据集执行并行I / O,并且您已启用MPI-IO但未启用集体访问。这不太可能在规模上产生非常好的表现。

你的大块暗淡对我来说似乎很小。我会让它们变大,但“有多大”取决于很多因素。那么,看看这些值的性能如何。如果你打开集体I / O,也许它不会那么糟糕?

除了最初的印象之外,也许您只是希望尝试使用HDF5。我不知道为什么打开分块会使一些数据集为空...除非你写的是NFS。如果你正在写NFS,那么,祝你好运,伙计,但它没有希望。