Calling fortran HDF5 function h5dwrite_f from C++

Hello,

I’ve currently the need to write some data buffers in column major order in the HDF5 file (the C++ HDF5 library write them in row major order).

As a first solution, I’m trying to call the fortran HDF5 function h5dwrite_f from my C++ code (indeed, I’m expecting this function to write buffers naturally in column major order). However I have an issue at runtime. Here is a simpler code to reproduce the issue (I’ve just patched an example provided by the HDF group, declaring the h5dwrite_f_c_ function and replacing the call to H5Dwrite by a call to h5dwrite_f_c_):

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

  • Copyright by The HDF Group. *
  • Copyright by the Board of Trustees of the University of Illinois. *
  • All rights reserved. *
  •                                                                       *
    

#include “hdf5.h”

#define H5FILE_NAME “SDS.h5”
#define DATASETNAME “IntArray”
#define NX 5 /* dataset dimensions */
#define NY 6
#define RANK 2

extern “C” {
void h5dwrite_f_c_(hid_t *dset_id, hid_t mem_type_id, const void * buf, hsize_t[], int hdferr, hid_t *mem_space_id, hid_t *file_space_id, hid_t *xfer_prp);
}

int
main (void)
{
hid_t file, dataset; /* file and dataset handles /
hid_t datatype, dataspace; /
handles /
hsize_t dimsf[2]; /
dataset dimensions /
herr_t status;
int data[NX][NY]; /
data to write */
int i, j;

/*
 * Data  and output buffer initialization.
 */
for(j = 0; j < NX; j++)
for(i = 0; i < NY; i++)
    data[j][i] = i + j;
/*
 * 0 1 2 3 4 5
 * 1 2 3 4 5 6
 * 2 3 4 5 6 7
 * 3 4 5 6 7 8
 * 4 5 6 7 8 9
 */

/*
 * Create a new file using H5F_ACC_TRUNC access,
 * default file creation properties, and default file
 * access properties.
 */
file = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

/*
 * Describe the size of the array and create the data space for fixed
 * size dataset.
 */
dimsf[0] = NX;
dimsf[1] = NY;
dataspace = H5Screate_simple(RANK, dimsf, NULL);

/*
 * Define datatype for the data in the file.
 * We will store little endian INT numbers.
 */
datatype = H5Tcopy(H5T_NATIVE_INT);
status = H5Tset_order(datatype, H5T_ORDER_LE);

/*
 * Create a new dataset within the file using defined dataspace and
 * datatype and default dataset creation properties.
 */
dataset = H5Dcreate2(file, DATASETNAME, datatype, dataspace,
		H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

/*
 * Write the data to the dataset using default transfer properties.
 */
//status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
hid_t xfer_prp = H5P_DEFAULT;
hid_t memspace = H5Screate_simple(RANK, dimsf, NULL);

h5dwrite_f_c_(&dataset, &datatype, data, dimsf, &status, &memspace, &dataspace, &xfer_prp);

/*
 * Close/release resources.
 */
H5Sclose(dataspace);
H5Tclose(datatype);
H5Dclose(dataset);
H5Fclose(file);

return 0;

}

At runtime, I’m getting the following output:

[fleuryl@hpc-login02 examples_HDF5]$ ./h5_write.exe
HDF5-DIAG: Error detected in HDF5 (1.8.12) thread 0:
#000: …/…/src/H5Dio.c line 231 in H5Dwrite(): can’t prepare for writing data
major: Dataset
minor: Write failed
#001: …/…/src/H5Dio.c line 344 in H5D__pre_write(): not a data space
major: Invalid arguments to routine
minor: Inappropriate type

I’m using GCC/6.4.0-2.28 and the HD5 library with version 1.8.12.

Thank you very much for your help.

To use the Fortran APIs, you need to call h5open_f, which populates the Fortran parameters from the C HDF5 library. At least I think that is one of the issues, I’ve not heard of anyone calling the Fortran APIs from non-Fortran applications, so this is uncharted territory.