2023-05-03 03:52:39 +08:00
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
* 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. *
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parallel tests for file image operations
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "hdf5.h"
|
|
|
|
#include "testphdf5.h"
|
|
|
|
|
|
|
|
/* file_image_daisy_chain_test
|
|
|
|
*
|
|
|
|
* Process zero:
|
|
|
|
*
|
|
|
|
* 1) Creates a core file with an integer vector data set of
|
|
|
|
* length n (= mpi_size),
|
|
|
|
*
|
|
|
|
* 2) Initializes the vector to zero in * location 0, and to -1
|
|
|
|
* everywhere else.
|
|
|
|
*
|
|
|
|
* 3) Flushes the core file, and gets an image of it. Closes
|
|
|
|
* the core file.
|
|
|
|
*
|
|
|
|
* 4) Sends the image to process 1.
|
|
|
|
*
|
|
|
|
* 5) Awaits receipt on a file image from process n-1.
|
|
|
|
*
|
|
|
|
* 6) opens the image received from process n-1, verifies that
|
|
|
|
* it contains a vector of length equal to mpi_size, and
|
|
|
|
* that the vector contains (0, 1, 2, ... n-1)
|
|
|
|
*
|
|
|
|
* 7) closes the core file and exits.
|
|
|
|
*
|
|
|
|
* Process i (0 < i < n)
|
|
|
|
*
|
|
|
|
* 1) Await receipt of file image from process (i - 1).
|
|
|
|
*
|
|
|
|
* 2) Open the image with the core file driver, verify that i
|
|
|
|
* contains a vector v of length, and that v[j] = j for
|
|
|
|
* 0 <= j < i, and that v[j] == -1 for i <= j < n
|
|
|
|
*
|
|
|
|
* 3) Set v[i] = i in the core file.
|
|
|
|
*
|
|
|
|
* 4) Flush the core file and send it to process (i + 1) % n.
|
|
|
|
*
|
|
|
|
* 5) close the core file and exit.
|
|
|
|
*
|
|
|
|
* Test fails on a hang (if an image is not received), or on invalid data.
|
|
|
|
*
|
|
|
|
* JRM -- 11/28/11
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
file_image_daisy_chain_test(void)
|
|
|
|
{
|
|
|
|
char file_name[1024] = "\0";
|
|
|
|
int mpi_size, mpi_rank;
|
|
|
|
int mpi_result;
|
|
|
|
int i;
|
|
|
|
int space_ndims;
|
|
|
|
MPI_Status rcvstat;
|
|
|
|
int *vector_ptr = NULL;
|
|
|
|
hid_t fapl_id = -1;
|
|
|
|
hid_t file_id; /* file IDs */
|
|
|
|
hid_t dset_id = -1;
|
|
|
|
hid_t dset_type_id = -1;
|
|
|
|
hid_t space_id = -1;
|
|
|
|
herr_t err;
|
|
|
|
hsize_t dims[1];
|
|
|
|
void *image_ptr = NULL;
|
|
|
|
ssize_t bytes_read;
|
|
|
|
ssize_t image_len;
|
2023-09-06 02:49:37 +08:00
|
|
|
bool vector_ok = true;
|
2023-05-03 03:52:39 +08:00
|
|
|
htri_t tri_result;
|
|
|
|
|
|
|
|
/* set up MPI parameters */
|
|
|
|
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
|
|
|
|
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
|
|
|
|
|
2023-05-27 04:29:02 +08:00
|
|
|
/* Make sure the connector supports the API functions being tested */
|
|
|
|
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_MORE) ||
|
|
|
|
!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE) ||
|
|
|
|
!(vol_cap_flags_g & H5VL_CAP_FLAG_FLUSH_REFRESH)) {
|
|
|
|
if (MAINPROCESS) {
|
|
|
|
puts("SKIPPED");
|
|
|
|
printf(" API functions for basic file, dataset, or dataset more aren't supported with this "
|
|
|
|
"connector\n");
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-05-03 03:52:39 +08:00
|
|
|
/* setup file name */
|
2023-09-16 06:13:18 +08:00
|
|
|
snprintf(file_name, 1024, "file_image_daisy_chain_test_%05d.h5", (int)mpi_rank);
|
2023-05-03 03:52:39 +08:00
|
|
|
|
|
|
|
if (mpi_rank == 0) {
|
|
|
|
|
|
|
|
/* 1) Creates a core file with an integer vector data set
|
|
|
|
* of length mpi_size,
|
|
|
|
*/
|
|
|
|
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
|
|
|
|
VRFY((fapl_id >= 0), "creating fapl");
|
|
|
|
|
2023-09-06 02:49:37 +08:00
|
|
|
err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), false);
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY((err >= 0), "setting core file driver in fapl.");
|
|
|
|
|
|
|
|
file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl_id);
|
|
|
|
VRFY((file_id >= 0), "created core file");
|
|
|
|
|
|
|
|
dims[0] = (hsize_t)mpi_size;
|
|
|
|
space_id = H5Screate_simple(1, dims, dims);
|
|
|
|
VRFY((space_id >= 0), "created data space");
|
|
|
|
|
|
|
|
dset_id = H5Dcreate2(file_id, "v", H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
|
|
|
|
VRFY((dset_id >= 0), "created data set");
|
|
|
|
|
|
|
|
/* 2) Initialize the vector to zero in location 0, and
|
|
|
|
* to -1 everywhere else.
|
|
|
|
*/
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
vector_ptr = (int *)malloc((size_t)(mpi_size) * sizeof(int));
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY((vector_ptr != NULL), "allocated in memory representation of vector");
|
|
|
|
|
|
|
|
vector_ptr[0] = 0;
|
|
|
|
for (i = 1; i < mpi_size; i++)
|
|
|
|
vector_ptr[i] = -1;
|
|
|
|
|
|
|
|
err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)vector_ptr);
|
|
|
|
VRFY((err >= 0), "wrote initial data to vector.");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
free(vector_ptr);
|
2023-05-03 03:52:39 +08:00
|
|
|
vector_ptr = NULL;
|
|
|
|
|
|
|
|
/* 3) Flush the core file, and get an image of it. Close
|
|
|
|
* the core file.
|
|
|
|
*/
|
|
|
|
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
|
|
|
|
VRFY((err >= 0), "flushed core file.");
|
|
|
|
|
|
|
|
image_len = H5Fget_file_image(file_id, NULL, (size_t)0);
|
|
|
|
VRFY((image_len > 0), "got image file size");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
image_ptr = (void *)malloc((size_t)image_len);
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY(image_ptr != NULL, "allocated file image buffer.");
|
|
|
|
|
|
|
|
bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_len);
|
|
|
|
VRFY(bytes_read == image_len, "wrote file into image buffer");
|
|
|
|
|
|
|
|
err = H5Sclose(space_id);
|
|
|
|
VRFY((err >= 0), "closed data space.");
|
|
|
|
|
|
|
|
err = H5Dclose(dset_id);
|
|
|
|
VRFY((err >= 0), "closed data set.");
|
|
|
|
|
|
|
|
err = H5Fclose(file_id);
|
|
|
|
VRFY((err >= 0), "closed core file(1).");
|
|
|
|
|
|
|
|
err = H5Pclose(fapl_id);
|
|
|
|
VRFY((err >= 0), "closed fapl(1).");
|
|
|
|
|
|
|
|
/* 4) Send the image to process 1. */
|
|
|
|
|
|
|
|
mpi_result = MPI_Ssend((void *)(&image_len), (int)sizeof(ssize_t), MPI_BYTE, 1, 0, MPI_COMM_WORLD);
|
|
|
|
VRFY((mpi_result == MPI_SUCCESS), "sent image size to process 1");
|
|
|
|
|
|
|
|
mpi_result = MPI_Ssend((void *)image_ptr, (int)image_len, MPI_BYTE, 1, 0, MPI_COMM_WORLD);
|
|
|
|
VRFY((mpi_result == MPI_SUCCESS), "sent image to process 1");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
free(image_ptr);
|
2023-05-03 03:52:39 +08:00
|
|
|
image_ptr = NULL;
|
|
|
|
image_len = 0;
|
|
|
|
|
|
|
|
/* 5) Await receipt on a file image from process n-1. */
|
|
|
|
|
|
|
|
mpi_result = MPI_Recv((void *)(&image_len), (int)sizeof(ssize_t), MPI_BYTE, mpi_size - 1, 0,
|
|
|
|
MPI_COMM_WORLD, &rcvstat);
|
|
|
|
VRFY((mpi_result == MPI_SUCCESS), "received image len from process n-1");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
image_ptr = (void *)malloc((size_t)image_len);
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY(image_ptr != NULL, "allocated file image receive buffer.");
|
|
|
|
|
|
|
|
mpi_result =
|
|
|
|
MPI_Recv((void *)image_ptr, (int)image_len, MPI_BYTE, mpi_size - 1, 0, MPI_COMM_WORLD, &rcvstat);
|
|
|
|
VRFY((mpi_result == MPI_SUCCESS), "received file image from process n-1");
|
|
|
|
|
|
|
|
/* 6) open the image received from process n-1, verify that
|
|
|
|
* it contains a vector of length equal to mpi_size, and
|
|
|
|
* that the vector contains (0, 1, 2, ... n-1).
|
|
|
|
*/
|
|
|
|
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
|
|
|
|
VRFY((fapl_id >= 0), "creating fapl");
|
|
|
|
|
2023-09-06 02:49:37 +08:00
|
|
|
err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), false);
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY((err >= 0), "setting core file driver in fapl.");
|
|
|
|
|
|
|
|
err = H5Pset_file_image(fapl_id, image_ptr, (size_t)image_len);
|
|
|
|
VRFY((err >= 0), "set file image in fapl.");
|
|
|
|
|
|
|
|
file_id = H5Fopen(file_name, H5F_ACC_RDWR, fapl_id);
|
|
|
|
VRFY((file_id >= 0), "opened received file image file");
|
|
|
|
|
|
|
|
dset_id = H5Dopen2(file_id, "v", H5P_DEFAULT);
|
|
|
|
VRFY((dset_id >= 0), "opened data set");
|
|
|
|
|
|
|
|
dset_type_id = H5Dget_type(dset_id);
|
|
|
|
VRFY((dset_type_id >= 0), "obtained data set type");
|
|
|
|
|
|
|
|
tri_result = H5Tequal(dset_type_id, H5T_NATIVE_INT);
|
2023-09-06 02:49:37 +08:00
|
|
|
VRFY((tri_result == true), "verified data set type");
|
2023-05-03 03:52:39 +08:00
|
|
|
|
|
|
|
space_id = H5Dget_space(dset_id);
|
|
|
|
VRFY((space_id >= 0), "opened data space");
|
|
|
|
|
|
|
|
space_ndims = H5Sget_simple_extent_ndims(space_id);
|
|
|
|
VRFY((space_ndims == 1), "verified data space num dims(1)");
|
|
|
|
|
|
|
|
space_ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
|
|
|
|
VRFY((space_ndims == 1), "verified data space num dims(2)");
|
|
|
|
VRFY((dims[0] == (hsize_t)mpi_size), "verified data space dims");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
vector_ptr = (int *)malloc((size_t)(mpi_size) * sizeof(int));
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY((vector_ptr != NULL), "allocated in memory rep of vector");
|
|
|
|
|
|
|
|
err = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)vector_ptr);
|
|
|
|
VRFY((err >= 0), "read received vector.");
|
|
|
|
|
2023-09-06 02:49:37 +08:00
|
|
|
vector_ok = true;
|
2023-05-03 03:52:39 +08:00
|
|
|
for (i = 0; i < mpi_size; i++)
|
|
|
|
if (vector_ptr[i] != i)
|
2023-09-06 02:49:37 +08:00
|
|
|
vector_ok = false;
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY((vector_ok), "verified received vector.");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
free(vector_ptr);
|
2023-05-03 03:52:39 +08:00
|
|
|
vector_ptr = NULL;
|
|
|
|
|
|
|
|
/* 7) closes the core file and exit. */
|
|
|
|
|
|
|
|
err = H5Sclose(space_id);
|
|
|
|
VRFY((err >= 0), "closed data space.");
|
|
|
|
|
|
|
|
err = H5Dclose(dset_id);
|
|
|
|
VRFY((err >= 0), "closed data set.");
|
|
|
|
|
|
|
|
err = H5Fclose(file_id);
|
|
|
|
VRFY((err >= 0), "closed core file(1).");
|
|
|
|
|
|
|
|
err = H5Pclose(fapl_id);
|
|
|
|
VRFY((err >= 0), "closed fapl(1).");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
free(image_ptr);
|
2023-05-03 03:52:39 +08:00
|
|
|
image_ptr = NULL;
|
|
|
|
image_len = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* 1) Await receipt of file image from process (i - 1). */
|
|
|
|
|
|
|
|
mpi_result = MPI_Recv((void *)(&image_len), (int)sizeof(ssize_t), MPI_BYTE, mpi_rank - 1, 0,
|
|
|
|
MPI_COMM_WORLD, &rcvstat);
|
|
|
|
VRFY((mpi_result == MPI_SUCCESS), "received image size from process mpi_rank-1");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
image_ptr = (void *)malloc((size_t)image_len);
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY(image_ptr != NULL, "allocated file image receive buffer.");
|
|
|
|
|
|
|
|
mpi_result =
|
|
|
|
MPI_Recv((void *)image_ptr, (int)image_len, MPI_BYTE, mpi_rank - 1, 0, MPI_COMM_WORLD, &rcvstat);
|
|
|
|
VRFY((mpi_result == MPI_SUCCESS), "received file image from process mpi_rank-1");
|
|
|
|
|
|
|
|
/* 2) Open the image with the core file driver, verify that it
|
|
|
|
* contains a vector v of length, and that v[j] = j for
|
|
|
|
* 0 <= j < i, and that v[j] == -1 for i <= j < n
|
|
|
|
*/
|
|
|
|
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
|
|
|
|
VRFY((fapl_id >= 0), "creating fapl");
|
|
|
|
|
2023-09-06 02:49:37 +08:00
|
|
|
err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), false);
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY((err >= 0), "setting core file driver in fapl.");
|
|
|
|
|
|
|
|
err = H5Pset_file_image(fapl_id, image_ptr, (size_t)image_len);
|
|
|
|
VRFY((err >= 0), "set file image in fapl.");
|
|
|
|
|
|
|
|
file_id = H5Fopen(file_name, H5F_ACC_RDWR, fapl_id);
|
|
|
|
H5Eprint2(H5P_DEFAULT, stderr);
|
|
|
|
VRFY((file_id >= 0), "opened received file image file");
|
|
|
|
|
|
|
|
dset_id = H5Dopen2(file_id, "v", H5P_DEFAULT);
|
|
|
|
VRFY((dset_id >= 0), "opened data set");
|
|
|
|
|
|
|
|
dset_type_id = H5Dget_type(dset_id);
|
|
|
|
VRFY((dset_type_id >= 0), "obtained data set type");
|
|
|
|
|
|
|
|
tri_result = H5Tequal(dset_type_id, H5T_NATIVE_INT);
|
2023-09-06 02:49:37 +08:00
|
|
|
VRFY((tri_result == true), "verified data set type");
|
2023-05-03 03:52:39 +08:00
|
|
|
|
|
|
|
space_id = H5Dget_space(dset_id);
|
|
|
|
VRFY((space_id >= 0), "opened data space");
|
|
|
|
|
|
|
|
space_ndims = H5Sget_simple_extent_ndims(space_id);
|
|
|
|
VRFY((space_ndims == 1), "verified data space num dims(1)");
|
|
|
|
|
|
|
|
space_ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
|
|
|
|
VRFY((space_ndims == 1), "verified data space num dims(2)");
|
|
|
|
VRFY((dims[0] == (hsize_t)mpi_size), "verified data space dims");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
vector_ptr = (int *)malloc((size_t)(mpi_size) * sizeof(int));
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY((vector_ptr != NULL), "allocated in memory rep of vector");
|
|
|
|
|
|
|
|
err = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)vector_ptr);
|
|
|
|
VRFY((err >= 0), "read received vector.");
|
|
|
|
|
2023-09-06 02:49:37 +08:00
|
|
|
vector_ok = true;
|
2023-05-03 03:52:39 +08:00
|
|
|
for (i = 0; i < mpi_size; i++) {
|
|
|
|
if (i < mpi_rank) {
|
|
|
|
if (vector_ptr[i] != i)
|
2023-09-06 02:49:37 +08:00
|
|
|
vector_ok = false;
|
2023-05-03 03:52:39 +08:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (vector_ptr[i] != -1)
|
2023-09-06 02:49:37 +08:00
|
|
|
vector_ok = false;
|
2023-05-03 03:52:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
VRFY((vector_ok), "verified received vector.");
|
|
|
|
|
|
|
|
/* 3) Set v[i] = i in the core file. */
|
|
|
|
|
|
|
|
vector_ptr[mpi_rank] = mpi_rank;
|
|
|
|
|
|
|
|
err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)vector_ptr);
|
|
|
|
VRFY((err >= 0), "wrote modified data to vector.");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
free(vector_ptr);
|
2023-05-03 03:52:39 +08:00
|
|
|
vector_ptr = NULL;
|
|
|
|
|
|
|
|
/* 4) Flush the core file and send it to process (mpi_rank + 1) % n. */
|
|
|
|
|
|
|
|
err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
|
|
|
|
VRFY((err >= 0), "flushed core file.");
|
|
|
|
|
|
|
|
image_len = H5Fget_file_image(file_id, NULL, (size_t)0);
|
|
|
|
VRFY((image_len > 0), "got (possibly modified) image file len");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
image_ptr = (void *)realloc((void *)image_ptr, (size_t)image_len);
|
2023-05-03 03:52:39 +08:00
|
|
|
VRFY(image_ptr != NULL, "re-allocated file image buffer.");
|
|
|
|
|
|
|
|
bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_len);
|
|
|
|
VRFY(bytes_read == image_len, "wrote file into image buffer");
|
|
|
|
|
|
|
|
mpi_result = MPI_Ssend((void *)(&image_len), (int)sizeof(ssize_t), MPI_BYTE,
|
|
|
|
(mpi_rank + 1) % mpi_size, 0, MPI_COMM_WORLD);
|
|
|
|
VRFY((mpi_result == MPI_SUCCESS), "sent image size to process (mpi_rank + 1) % mpi_size");
|
|
|
|
|
|
|
|
mpi_result = MPI_Ssend((void *)image_ptr, (int)image_len, MPI_BYTE, (mpi_rank + 1) % mpi_size, 0,
|
|
|
|
MPI_COMM_WORLD);
|
|
|
|
VRFY((mpi_result == MPI_SUCCESS), "sent image to process (mpi_rank + 1) % mpi_size");
|
|
|
|
|
2023-06-29 06:48:12 +08:00
|
|
|
free(image_ptr);
|
2023-05-03 03:52:39 +08:00
|
|
|
image_ptr = NULL;
|
|
|
|
image_len = 0;
|
|
|
|
|
|
|
|
/* 5) close the core file and exit. */
|
|
|
|
|
|
|
|
err = H5Sclose(space_id);
|
|
|
|
VRFY((err >= 0), "closed data space.");
|
|
|
|
|
|
|
|
err = H5Dclose(dset_id);
|
|
|
|
VRFY((err >= 0), "closed data set.");
|
|
|
|
|
|
|
|
err = H5Fclose(file_id);
|
|
|
|
VRFY((err >= 0), "closed core file(1).");
|
|
|
|
|
|
|
|
err = H5Pclose(fapl_id);
|
|
|
|
VRFY((err >= 0), "closed fapl(1).");
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
} /* file_image_daisy_chain_test() */
|