/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 "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; hbool_t vector_ok = TRUE; htri_t tri_result; /* set up MPI parameters */ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); /* setup file name */ HDsnprintf(file_name, 1024, "file_image_daisy_chain_test_%05d.h5", (int)mpi_rank); 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"); err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), FALSE); 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. */ vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int)); 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."); HDfree(vector_ptr); 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"); image_ptr = (void *)HDmalloc((size_t)image_len); 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"); HDfree(image_ptr); 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"); image_ptr = (void *)HDmalloc((size_t)image_len); 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"); err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), FALSE); 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); VRFY((tri_result == TRUE), "verified data set type"); 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"); vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int)); 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."); vector_ok = TRUE; for (i = 0; i < mpi_size; i++) if (vector_ptr[i] != i) vector_ok = FALSE; VRFY((vector_ok), "verified received vector."); HDfree(vector_ptr); 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)."); HDfree(image_ptr); 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"); image_ptr = (void *)HDmalloc((size_t)image_len); 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"); err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), FALSE); 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); VRFY((tri_result == TRUE), "verified data set type"); 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"); vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int)); 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."); vector_ok = TRUE; for (i = 0; i < mpi_size; i++) { if (i < mpi_rank) { if (vector_ptr[i] != i) vector_ok = FALSE; } else { if (vector_ptr[i] != -1) vector_ok = FALSE; } } 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."); HDfree(vector_ptr); 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"); image_ptr = (void *)HDrealloc((void *)image_ptr, (size_t)image_len); 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"); HDfree(image_ptr); 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() */