Skip to content

Commit 5b74f0f

Browse files
authored
Merge pull request #514 from E3SM-Project/dqwu/hdf5_type_refactoring
This PR completes the first phase of support for HDF5 IO type by adding error handling to all HDF5 API calls. It also utilizes some internal helper functions to improve code organization and readability. Additionally, minor fixes for HDF5 and ADIOS IO types have been implemented. The nightly test for HDF5 IO type has also been updated to enable it only when direct HDF5 support is available.
2 parents d701fd2 + e4df3e6 commit 5b74f0f

File tree

10 files changed

+1530
-587
lines changed

10 files changed

+1530
-587
lines changed

examples/c/CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ add_spio_executable(example1 TRUE "" example1.c)
7171
add_spio_executable(darray_no_async TRUE "" darray_no_async.c)
7272
add_spio_executable(darray_async TRUE "" darray_async.c)
7373
add_spio_executable(put_var TRUE "" put_var.c)
74-
add_spio_executable(test_hdf5 TRUE "" test_hdf5.c)
74+
if (WITH_HDF5)
75+
add_spio_executable(test_hdf5 TRUE "" test_hdf5.c)
76+
endif ()
7577

7678
if (PIO_ENABLE_FORTRAN)
7779
if (MPE_C_FOUND)
@@ -92,5 +94,7 @@ else ()
9294
add_mpi_test(put_var EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/put_var NUMPROCS 4 TIMEOUT 60)
9395
#add_mpi_test(darray_async EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/darray_async NUMPROCS 5 TIMEOUT 60)
9496
add_mpi_test(darray_no_async EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/darray_no_async NUMPROCS 4 TIMEOUT 60)
95-
add_mpi_test(test_hdf5 EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/test_hdf5 NUMPROCS 4 TIMEOUT 60)
97+
if (WITH_HDF5)
98+
add_mpi_test(test_hdf5 EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/test_hdf5 NUMPROCS 4 TIMEOUT 60)
99+
endif ()
96100
endif ()

examples/c/test_hdf5.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ int main(int argc, char* argv[])
168168
ret = PIOc_put_att(ncid, varid_lat, "long_name", PIO_CHAR, strlen("latitude"), "latitude"); ERR
169169
ret = PIOc_put_att(ncid, varid_lat, "units", PIO_CHAR, strlen("degrees_north"), "degrees_north"); ERR
170170
ret = PIOc_put_att(ncid, varid_P0, "long_name", PIO_CHAR, strlen("reference pressure"), "reference pressure"); ERR
171-
ret = PIOc_put_att(ncid, varid_P0, "units", PIO_CHAR, strlen("Pa"), "Pa"); ERR
171+
ret = PIOc_put_att(ncid, varid_P0, "units", PIO_CHAR, strlen("pA"), "pA"); ERR /* Wrong attribute value */
172+
ret = PIOc_put_att(ncid, varid_P0, "units", PIO_CHAR, strlen("Pa"), "Pa"); ERR /* Correction: overwrite an existing attribute */
172173
const int mdims_val = 1;
173174
ret = PIOc_put_att(ncid, varid_U, "mdims", PIO_INT, 1, &mdims_val); ERR
174175
ret = PIOc_put_att(ncid, varid_U, "units", PIO_CHAR, strlen("m/s"), "m/s"); ERR
@@ -569,6 +570,9 @@ int main(int argc, char* argv[])
569570

570571
#else
571572
printf("SCORPIO is not configured with HDF5 support.\n");
573+
574+
/* Make the test fail if HDF5 support is not enabled/available. */
575+
return -1;
572576
#endif
573577

574578
return 0;

src/clib/pio.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ extern "C" {
7878
#ifdef _HDF5
7979
#include <hdf5.h>
8080
#include <hdf5_hl.h>
81+
#include <unistd.h>
8182
#endif
8283

8384
/* PIO_OFFSET_C_TYPENAME is defined in pio_config.h */
@@ -1652,12 +1653,6 @@ extern "C" {
16521653
int end_adios2_step(file_desc_t *file, iosystem_desc_t *ios);
16531654
#endif
16541655

1655-
/* FIXME: Shouldn't these HDF5 functions be moved to pio_internal.h ? */
1656-
#ifdef _HDF5
1657-
hid_t nc_type_to_hdf5_type(nc_type xtype);
1658-
PIO_Offset hdf5_get_nc_type_size(nc_type xtype);
1659-
#endif
1660-
16611656
#if defined(__cplusplus)
16621657
}
16631658
#endif

src/clib/pio_darray_int.c

Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -441,13 +441,17 @@ int write_darray_multi_par(file_desc_t *file, int nvars, int fndims, const int *
441441
if (!(startlist[rrcnt] = calloc(fndims, sizeof(PIO_Offset))))
442442
{
443443
ierr = pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__,
444-
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using PIO_IOTYPE_HDF5 iotype failed. Out of memory allocating buffer (%lld bytes) for array to store starts of I/O regions written out to file", nvars, pio_get_fname_from_file(file), file->pio_ncid, (long long int) (fndims * sizeof(PIO_Offset)));
444+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
445+
"Out of memory allocating buffer (%lld bytes) for array to store starts of I/O regions written out to file",
446+
nvars, pio_get_fname_from_file(file), file->pio_ncid, (long long int) (fndims * sizeof(PIO_Offset)));
445447
break;
446448
}
447449
if (!(countlist[rrcnt] = calloc(fndims, sizeof(PIO_Offset))))
448450
{
449451
ierr = pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__,
450-
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using PIO_IOTYPE_HDF5 iotype failed. Out of memory allocating buffer (%lld bytes) for array to store counts of I/O regions written out to file", nvars, pio_get_fname_from_file(file), file->pio_ncid, (long long int) (fndims * sizeof(PIO_Offset)));
452+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
453+
"Out of memory allocating buffer (%lld bytes) for array to store counts of I/O regions written out to file",
454+
nvars, pio_get_fname_from_file(file), file->pio_ncid, (long long int) (fndims * sizeof(PIO_Offset)));
451455
break;
452456
}
453457

@@ -469,7 +473,15 @@ int write_darray_multi_par(file_desc_t *file, int nvars, int fndims, const int *
469473
for (int nv = 0; nv < nvars; nv++)
470474
{
471475
hid_t file_space_id = H5Dget_space(file->hdf5_vars[varids[nv]].hdf5_dataset_id);
472-
hid_t mem_space_id;
476+
if (file_space_id == H5I_INVALID_HID)
477+
{
478+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
479+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
480+
"The low level (HDF5) I/O library call failed to make a copy of the dataspace of the dataset associated with variable (%s, varid=%d)",
481+
nvars, pio_get_fname_from_file(file), file->pio_ncid, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
482+
}
483+
484+
hid_t mem_space_id = H5I_INVALID_HID;
473485

474486
if (dsize_all > 0)
475487
{
@@ -487,31 +499,86 @@ int write_darray_multi_par(file_desc_t *file, int nvars, int fndims, const int *
487499
for (int i = 0; i < rrcnt; i++)
488500
{
489501
/* Union hyperslabs of all regions */
490-
H5Sselect_hyperslab(file_space_id, op, (hsize_t*)startlist[i], NULL, (hsize_t*)countlist[i], NULL);
502+
if (H5Sselect_hyperslab(file_space_id, op, (hsize_t*)startlist[i], NULL, (hsize_t*)countlist[i], NULL) < 0)
503+
{
504+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
505+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
506+
"The low level (HDF5) I/O library call failed to select a hyperslab region for a dataspace copied from the dataset associated with variable (%s, varid=%d)",
507+
nvars, pio_get_fname_from_file(file), file->pio_ncid, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
508+
}
509+
491510
op = H5S_SELECT_OR;
492511
}
493512

494513
mem_space_id = H5Screate_simple(1, &dsize_all, NULL);
514+
if (mem_space_id == H5I_INVALID_HID)
515+
{
516+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
517+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
518+
"The low level (HDF5) I/O library call failed to create a new simple dataspace for variable (%s, varid=%d)",
519+
nvars, pio_get_fname_from_file(file), file->pio_ncid, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
520+
}
495521

496522
/* Get a pointer to the data. */
497523
bufptr = (void *)((char *)iobuf + nv * iodesc->mpitype_size * llen);
498524
}
499525
else
500526
{
501527
/* No data to write on this IO task. */
502-
H5Sselect_none(file_space_id);
528+
if (H5Sselect_none(file_space_id) < 0)
529+
{
530+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
531+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
532+
"The low level (HDF5) I/O library call failed to reset the selection region for a dataspace copied from the dataset associated with variable (%s, varid=%d)",
533+
nvars, pio_get_fname_from_file(file), file->pio_ncid, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
534+
}
503535

504536
mem_space_id = H5Screate(H5S_NULL);
537+
if (mem_space_id == H5I_INVALID_HID)
538+
{
539+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
540+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
541+
"The low level (HDF5) I/O library call failed to create a new NULL dataspace for variable (%s, varid=%d)",
542+
nvars, pio_get_fname_from_file(file), file->pio_ncid, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
543+
}
505544

506545
bufptr = NULL;
507546
}
508547

509548
/* Collective write */
510-
hid_t mem_type_id = nc_type_to_hdf5_type(iodesc->piotype);
511-
H5Dwrite(file->hdf5_vars[varids[nv]].hdf5_dataset_id, mem_type_id, mem_space_id, file_space_id, file->dxplid_coll, bufptr);
549+
hid_t mem_type_id = spio_nc_type_to_hdf5_type(iodesc->piotype);
550+
if (mem_type_id == H5I_INVALID_HID)
551+
{
552+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
553+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
554+
"Unsupported memory type (type=%x) for variable (%s, varid=%d)",
555+
nvars, pio_get_fname_from_file(file), file->pio_ncid, iodesc->piotype, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
556+
}
557+
558+
if (H5Dwrite(file->hdf5_vars[varids[nv]].hdf5_dataset_id, mem_type_id, mem_space_id, file_space_id,
559+
file->dxplid_coll, bufptr) < 0)
560+
{
561+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
562+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
563+
"The low level (HDF5) I/O library call failed to write the dataset associated with variable (%s, varid=%d)",
564+
nvars, pio_get_fname_from_file(file), file->pio_ncid, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
565+
}
512566

513-
H5Sclose(file_space_id);
514-
H5Sclose(mem_space_id);
567+
if (H5Sclose(file_space_id) < 0)
568+
{
569+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
570+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
571+
"The low level (HDF5) I/O library call failed to release a dataspace copied from the dataset associated with variable (%s, varid=%d)",
572+
nvars, pio_get_fname_from_file(file), file->pio_ncid, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
573+
}
574+
575+
if (H5Sclose(mem_space_id) < 0)
576+
{
577+
return pio_err(ios, file, PIO_EHDF5ERR, __FILE__, __LINE__,
578+
"Writing variables (number of variables = %d) to file (%s, ncid=%d) using HDF5 iotype failed. "
579+
"The low level (HDF5) I/O library call failed to release a simple (or NULL) dataspace for variable (%s, varid=%d)",
580+
nvars, pio_get_fname_from_file(file), file->pio_ncid, pio_get_vname_from_file(file, varids[nv]), varids[nv]);
581+
}
515582
}
516583

517584
/* Free resources. */

src/clib/pio_file.c

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -943,27 +943,7 @@ int PIOc_closefile(int ncid)
943943
#endif
944944
#ifdef _HDF5
945945
case PIO_IOTYPE_HDF5:
946-
ierr = PIO_NOERR;
947-
948-
H5Pclose(file->dxplid_coll);
949-
H5Pclose(file->dxplid_indep);
950-
951-
for (int i = 0; i < file->hdf5_num_dims; i++)
952-
{
953-
if (!file->hdf5_dims[i].has_coord_var)
954-
H5Dclose(file->hdf5_dims[i].hdf5_dataset_id);
955-
}
956-
957-
for (int i = 0; i < file->hdf5_num_vars; i++)
958-
{
959-
H5Dclose(file->hdf5_vars[i].hdf5_dataset_id);
960-
961-
if (file->hdf5_vars[i].nc_type == NC_CHAR)
962-
H5Tclose(file->hdf5_vars[i].hdf5_type);
963-
}
964-
965-
H5Fclose(file->hdf5_file_id);
966-
946+
ierr = spio_hdf5_close(ios, file);
967947
break;
968948
#endif
969949
default:

0 commit comments

Comments
 (0)