hdf5/testpar/t_pflush2.c
2023-10-31 06:05:25 -07:00

224 lines
6.6 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Purpose: This is the second half of a two-part test that makes sure
* that a file can be read after a parallel application crashes as long
* as the file was flushed first. We simulate a crash by
* calling _exit(0) since this doesn't flush HDF5 caches but
* still exits with success.
*/
#include "h5test.h"
static const char *FLUSH_FILENAME[] = {"flush", NULL};
static const char *NOFLUSH_FILENAME[] = {"noflush", NULL};
static int *data_g = NULL;
#define N_GROUPS 100
/*-------------------------------------------------------------------------
* Function: check_test_file
*
* Purpose: Part 2 of a two-part H5Fflush() test.
*
* Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
check_test_file(char *name, size_t name_length, hid_t fapl_id)
{
hid_t fid = H5I_INVALID_HID;
hid_t sid = H5I_INVALID_HID;
hid_t did = H5I_INVALID_HID;
hid_t top_level_gid = H5I_INVALID_HID;
hid_t gid = H5I_INVALID_HID;
hid_t dxpl_id = H5I_INVALID_HID;
hsize_t dims[2];
int val;
hsize_t i, j;
if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
goto error;
if (H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) < 0)
goto error;
if ((fid = H5Fopen(name, H5F_ACC_RDONLY, fapl_id)) < 0)
goto error;
/* Open the dataset */
if ((did = H5Dopen2(fid, "dset", H5P_DEFAULT)) < 0)
goto error;
if ((sid = H5Dget_space(did)) < 0)
goto error;
if (H5Sget_simple_extent_dims(sid, dims, NULL) < 0)
goto error;
assert(100 == dims[0] && 100 == dims[1]);
/* Read some data */
if (H5Dread(did, H5T_NATIVE_INT, sid, sid, dxpl_id, data_g) < 0)
goto error;
for (i = 0; i < dims[0]; i++) {
for (j = 0; j < dims[1]; j++) {
val = (int)(i + (i * j) + j);
if (data_g[(i * 100) + j] != val) {
H5_FAILED();
printf(" data_g[%lu][%lu] = %d\n", (unsigned long)i, (unsigned long)j,
data_g[(i * 100) + j]);
printf(" should be %d\n", val);
}
}
}
/* Open some groups */
if ((top_level_gid = H5Gopen2(fid, "some_groups", H5P_DEFAULT)) < 0)
goto error;
for (i = 0; i < N_GROUPS; i++) {
snprintf(name, name_length, "grp%02u", (unsigned)i);
if ((gid = H5Gopen2(top_level_gid, name, H5P_DEFAULT)) < 0)
goto error;
if (H5Gclose(gid) < 0)
goto error;
}
if (H5Gclose(top_level_gid) < 0)
goto error;
if (H5Dclose(did) < 0)
goto error;
if (H5Fclose(fid) < 0)
goto error;
if (H5Pclose(dxpl_id) < 0)
goto error;
if (H5Sclose(sid) < 0)
goto error;
return SUCCEED;
error:
H5E_BEGIN_TRY
{
H5Pclose(dxpl_id);
H5Gclose(top_level_gid);
H5Dclose(did);
H5Fclose(fid);
H5Sclose(sid);
H5Gclose(gid);
}
H5E_END_TRY
return FAIL;
} /* end check_test_file() */
/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Part 2 of a two-part H5Fflush() test.
*
* Return: EXIT_SUCCESS/EXIT_FAIL
*-------------------------------------------------------------------------
*/
int
main(int argc, char *argv[])
{
hid_t fapl_id1 = H5I_INVALID_HID;
hid_t fapl_id2 = H5I_INVALID_HID;
H5E_auto2_t func;
char name[1024];
const char *envval = NULL;
int mpi_size;
int mpi_rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
MPI_Init(&argc, &argv);
MPI_Comm_size(comm, &mpi_size);
MPI_Comm_rank(comm, &mpi_rank);
if (mpi_rank == 0)
TESTING("H5Fflush (part2 with flush)");
/* Don't run using the split VFD */
envval = getenv(HDF5_DRIVER);
if (envval == NULL)
envval = "nomatch";
if (!strcmp(envval, "split")) {
if (mpi_rank == 0) {
SKIPPED();
puts(" Test not compatible with current Virtual File Driver");
}
MPI_Finalize();
exit(EXIT_SUCCESS);
}
if (NULL == (data_g = malloc(100 * 100 * sizeof(*data_g))))
goto error;
if ((fapl_id1 = H5Pcreate(H5P_FILE_ACCESS)) < 0)
goto error;
if (H5Pset_fapl_mpio(fapl_id1, comm, info) < 0)
goto error;
if ((fapl_id2 = H5Pcreate(H5P_FILE_ACCESS)) < 0)
goto error;
if (H5Pset_fapl_mpio(fapl_id2, comm, info) < 0)
goto error;
/* Check the case where the file was flushed */
h5_fixname(FLUSH_FILENAME[0], fapl_id1, name, sizeof(name));
if (check_test_file(name, sizeof(name), fapl_id1)) {
H5_FAILED();
goto error;
}
else if (mpi_rank == 0) {
PASSED();
}
/* Check the case where the file was not flushed. This should give an error
* so we turn off the error stack temporarily.
*/
if (mpi_rank == 0)
TESTING("H5Fflush (part2 without flush)");
H5Eget_auto2(H5E_DEFAULT, &func, NULL);
H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
h5_fixname(NOFLUSH_FILENAME[0], fapl_id2, name, sizeof(name));
if (check_test_file(name, sizeof(name), fapl_id2)) {
if (mpi_rank == 0)
PASSED();
}
else {
H5_FAILED();
goto error;
}
H5Eset_auto2(H5E_DEFAULT, func, NULL);
h5_clean_files(FLUSH_FILENAME, fapl_id1);
h5_clean_files(NOFLUSH_FILENAME, fapl_id2);
if (data_g) {
free(data_g);
data_g = NULL;
}
MPI_Finalize();
exit(EXIT_SUCCESS);
error:
if (data_g)
free(data_g);
exit(EXIT_FAILURE);
} /* end main() */