diff options
Diffstat (limited to 'testpar')
-rw-r--r-- | testpar/CMakeLists.txt | 1 | ||||
-rw-r--r-- | testpar/Makefile.am | 7 | ||||
-rw-r--r-- | testpar/t_coll_chunk.c | 356 | ||||
-rw-r--r-- | testpar/t_dset.c | 231 | ||||
-rw-r--r-- | testpar/t_pmulti_dset.c | 651 | ||||
-rw-r--r-- | testpar/testphdf5.c | 20 | ||||
-rw-r--r-- | testpar/testphdf5.h | 10 |
7 files changed, 691 insertions, 585 deletions
diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt index 0c9f70e..ab04841 100644 --- a/testpar/CMakeLists.txt +++ b/testpar/CMakeLists.txt @@ -51,6 +51,7 @@ set (H5P_TESTS t_pshutdown t_prestart t_init_term + t_pmulti_dset t_shapesame t_filters_parallel ) diff --git a/testpar/Makefile.am b/testpar/Makefile.am index 1f15830..318f566 100644 --- a/testpar/Makefile.am +++ b/testpar/Makefile.am @@ -23,7 +23,10 @@ AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test # Test programs. These are our main targets. # -TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pflush1 t_pflush2 t_pread t_pshutdown t_prestart t_init_term t_shapesame t_filters_parallel +TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pflush1 t_pflush2 t_pread t_pshutdown t_prestart \ + t_init_term t_pmulti_dset t_shapesame + +## MSB FIX t_filters_parallel check_PROGRAMS = $(TEST_PROG_PARA) @@ -40,6 +43,6 @@ LDADD = $(LIBH5TEST) $(LIBHDF5) # shutdown.h5 is from t_pshutdown # after_mpi_fin.h5 is from t_init_term # go is used for debugging. See testphdf5.c. -CHECK_CLEANFILES+=MPItest.h5 Para*.h5 CacheTestDummy.h5 shutdown.h5 after_mpi_fin.h5 go +CHECK_CLEANFILES+=MPItest.h5 Para*.h5 CacheTestDummy.h5 shutdown.h5 pmulti_dset.h5 after_mpi_fin.h5 go include $(top_srcdir)/config/conclude.am diff --git a/testpar/t_coll_chunk.c b/testpar/t_coll_chunk.c index c6fa3d4..1e69750 100644 --- a/testpar/t_coll_chunk.c +++ b/testpar/t_coll_chunk.c @@ -299,268 +299,6 @@ coll_chunk5(void) coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_HARD, POINT, HYPER, IN_ORDER); } -/*------------------------------------------------------------------------- - * Function: coll_chunk6 - * - * Purpose: Test direct request for multi-chunk-io. - * Wrapper to test the collective chunk IO for regular JOINT - * selection with at least number of 2*mpi_size chunks - * Test for direct to Multi Chunk I/O. - * - * Return: Success: 0 - * - * Failure: -1 - * - * Programmer: Unknown - * July 12th, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ - -/* ------------------------------------------------------------------------ - * Descriptions for the selection: one singular selection accross many chunks - * Two dimensions, Num of chunks = 2* mpi_size - * - * dim1 = SPACE_DIM1*mpi_size - * dim2 = SPACE_DIM2 - * chunk_dim1 = dim1 - * chunk_dim2 = dim2 - * block = 1 for all dimensions - * stride = 1 for all dimensions - * count0 = SPACE_DIM1 - * count1 = SPACE_DIM2(3) - * start0 = mpi_rank*SPACE_DIM1 - * start1 = 0 - * - * ------------------------------------------------------------------------ - */ - -void -coll_chunk6(void) -{ - const char *filename = GetTestParameters(); - - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, HYPER, HYPER, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, HYPER, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, ALL, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, HYPER, OUT_OF_ORDER); - - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, ALL, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, POINT, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_HARD, POINT, HYPER, IN_ORDER); -} - -/*------------------------------------------------------------------------- - * Function: coll_chunk7 - * - * Purpose: Wrapper to test the collective chunk IO for regular JOINT - selection with at least number of 2*mpi_size chunks - * - * Return: Success: 0 - * - * Failure: -1 - * - * Programmer: Unknown - * July 12th, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ - -/* ------------------------------------------------------------------------ - * Descriptions for the selection: one singular selection accross many chunks - * Two dimensions, Num of chunks = 2* mpi_size - * - * dim1 = SPACE_DIM1*mpi_size - * dim2 = SPACE_DIM2 - * chunk_dim1 = dim1 - * chunk_dim2 = dim2 - * block = 1 for all dimensions - * stride = 1 for all dimensions - * count0 = SPACE_DIM1 - * count1 = SPACE_DIM2(3) - * start0 = mpi_rank*SPACE_DIM1 - * start1 = 0 - * - * ------------------------------------------------------------------------ - */ - -void -coll_chunk7(void) -{ - const char *filename = GetTestParameters(); - - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, HYPER, HYPER, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, HYPER, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, ALL, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, HYPER, OUT_OF_ORDER); - - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, ALL, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, POINT, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_TRUE, POINT, HYPER, IN_ORDER); -} - -/*------------------------------------------------------------------------- - * Function: coll_chunk8 - * - * Purpose: Wrapper to test the collective chunk IO for regular JOINT - selection with at least number of 2*mpi_size chunks - * - * Return: Success: 0 - * - * Failure: -1 - * - * Programmer: Unknown - * July 12th, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ - -/* ------------------------------------------------------------------------ - * Descriptions for the selection: one singular selection accross many chunks - * Two dimensions, Num of chunks = 2* mpi_size - * - * dim1 = SPACE_DIM1*mpi_size - * dim2 = SPACE_DIM2 - * chunk_dim1 = dim1 - * chunk_dim2 = dim2 - * block = 1 for all dimensions - * stride = 1 for all dimensions - * count0 = SPACE_DIM1 - * count1 = SPACE_DIM2(3) - * start0 = mpi_rank*SPACE_DIM1 - * start1 = 0 - * - * ------------------------------------------------------------------------ - */ - -void -coll_chunk8(void) -{ - const char *filename = GetTestParameters(); - - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, HYPER, HYPER, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, HYPER, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, ALL, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, HYPER, OUT_OF_ORDER); - - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, ALL, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, POINT, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_LINK_FALSE, POINT, HYPER, IN_ORDER); -} - -/*------------------------------------------------------------------------- - * Function: coll_chunk9 - * - * Purpose: Wrapper to test the collective chunk IO for regular JOINT - selection with at least number of 2*mpi_size chunks - * - * Return: Success: 0 - * - * Failure: -1 - * - * Programmer: Unknown - * July 12th, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ - -/* ------------------------------------------------------------------------ - * Descriptions for the selection: one singular selection accross many chunks - * Two dimensions, Num of chunks = 2* mpi_size - * - * dim1 = SPACE_DIM1*mpi_size - * dim2 = SPACE_DIM2 - * chunk_dim1 = dim1 - * chunk_dim2 = dim2 - * block = 1 for all dimensions - * stride = 1 for all dimensions - * count0 = SPACE_DIM1 - * count1 = SPACE_DIM2(3) - * start0 = mpi_rank*SPACE_DIM1 - * start1 = 0 - * - * ------------------------------------------------------------------------ - */ - -void -coll_chunk9(void) -{ - const char *filename = GetTestParameters(); - - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, HYPER, HYPER, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, HYPER, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, ALL, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, HYPER, OUT_OF_ORDER); - - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, ALL, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, POINT, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTUNBALANCE, API_MULTI_COLL, POINT, HYPER, IN_ORDER); -} - -/*------------------------------------------------------------------------- - * Function: coll_chunk10 - * - * Purpose: Wrapper to test the collective chunk IO for regular JOINT - selection with at least number of 2*mpi_size chunks - * - * Return: Success: 0 - * - * Failure: -1 - * - * Programmer: Unknown - * July 12th, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ - -/* ------------------------------------------------------------------------ - * Descriptions for the selection: one singular selection accross many chunks - * Two dimensions, Num of chunks = 2* mpi_size - * - * dim1 = SPACE_DIM1*mpi_size - * dim2 = SPACE_DIM2 - * chunk_dim1 = dim1 - * chunk_dim2 = dim2 - * block = 1 for all dimensions - * stride = 1 for all dimensions - * count0 = SPACE_DIM1 - * count1 = SPACE_DIM2(3) - * start0 = mpi_rank*SPACE_DIM1 - * start1 = 0 - * - * ------------------------------------------------------------------------ - */ - -void -coll_chunk10(void) -{ - const char *filename = GetTestParameters(); - - coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, HYPER, HYPER, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, HYPER, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, ALL, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, POINT, OUT_OF_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, HYPER, OUT_OF_ORDER); - - coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, ALL, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, POINT, IN_ORDER); - coll_chunktest(filename, 4, BYROW_SELECTINCHUNK, API_MULTI_IND, POINT, HYPER, IN_ORDER); -} - /*------------------------------------------------------------------------- * Function: coll_chunktest @@ -753,35 +491,6 @@ coll_chunktest(const char* filename, VRFY((status>= 0),"collective chunk optimization succeeded"); break; - case API_MULTI_HARD: - status = H5Pset_dxpl_mpio_chunk_opt(xfer_plist,H5FD_MPIO_CHUNK_MULTI_IO); - VRFY((status>= 0),"collective chunk optimization succeeded "); - break; - - case API_LINK_TRUE: - status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist,2); - VRFY((status>= 0),"collective chunk optimization set chunk number succeeded"); - break; - - case API_LINK_FALSE: - status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist,6); - VRFY((status>= 0),"collective chunk optimization set chunk number succeeded"); - break; - - case API_MULTI_COLL: - status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist,8);/* make sure it is using multi-chunk IO */ - VRFY((status>= 0),"collective chunk optimization set chunk number succeeded"); - status = H5Pset_dxpl_mpio_chunk_opt_ratio(xfer_plist,50); - VRFY((status>= 0),"collective chunk optimization set chunk ratio succeeded"); - break; - - case API_MULTI_IND: - status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist,8);/* make sure it is using multi-chunk IO */ - VRFY((status>= 0),"collective chunk optimization set chunk number succeeded"); - status = H5Pset_dxpl_mpio_chunk_opt_ratio(xfer_plist,100); - VRFY((status>= 0),"collective chunk optimization set chunk ratio succeeded"); - break; - default: ; } @@ -796,41 +505,6 @@ coll_chunktest(const char* filename, VRFY((status >= 0),"testing property list inserted succeeded"); break; - case API_MULTI_HARD: - prop_value = H5D_XFER_COLL_CHUNK_DEF; - status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value, - NULL, NULL, NULL, NULL, NULL, NULL); - VRFY((status >= 0),"testing property list inserted succeeded"); - break; - - case API_LINK_TRUE: - prop_value = H5D_XFER_COLL_CHUNK_DEF; - status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value, - NULL, NULL, NULL, NULL, NULL, NULL); - VRFY((status >= 0),"testing property list inserted succeeded"); - break; - - case API_LINK_FALSE: - prop_value = H5D_XFER_COLL_CHUNK_DEF; - status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value, - NULL, NULL, NULL, NULL, NULL, NULL); - VRFY((status >= 0),"testing property list inserted succeeded"); - break; - - case API_MULTI_COLL: - prop_value = H5D_XFER_COLL_CHUNK_DEF; - status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value, - NULL, NULL, NULL, NULL, NULL, NULL); - VRFY((status >= 0),"testing property list inserted succeeded"); - break; - - case API_MULTI_IND: - prop_value = H5D_XFER_COLL_CHUNK_DEF; - status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value, - NULL, NULL, NULL, NULL, NULL, NULL); - VRFY((status >= 0),"testing property list inserted succeeded"); - break; - default: ; } @@ -851,36 +525,6 @@ coll_chunktest(const char* filename, VRFY((prop_value == 0),"API to set LINK COLLECTIVE IO directly succeeded"); break; - case API_MULTI_HARD: - status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME,&prop_value); - VRFY((status >= 0),"testing property list get succeeded"); - VRFY((prop_value == 0),"API to set MULTI-CHUNK COLLECTIVE IO optimization succeeded"); - break; - - case API_LINK_TRUE: - status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME,&prop_value); - VRFY((status >= 0),"testing property list get succeeded"); - VRFY((prop_value == 0),"API to set LINK COLLECTIVE IO succeeded"); - break; - - case API_LINK_FALSE: - status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME,&prop_value); - VRFY((status >= 0),"testing property list get succeeded"); - VRFY((prop_value == 0),"API to set LINK IO transferring to multi-chunk IO succeeded"); - break; - - case API_MULTI_COLL: - status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME,&prop_value); - VRFY((status >= 0),"testing property list get succeeded"); - VRFY((prop_value == 0),"API to set MULTI-CHUNK COLLECTIVE IO with optimization succeeded"); - break; - - case API_MULTI_IND: - status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME,&prop_value); - VRFY((status >= 0),"testing property list get succeeded"); - VRFY((prop_value == 0),"API to set MULTI-CHUNK IO transferring to independent IO succeeded"); - break; - default: ; } diff --git a/testpar/t_dset.c b/testpar/t_dset.c index 65d1bb4..4d9d2b4 100644 --- a/testpar/t_dset.c +++ b/testpar/t_dset.c @@ -2204,10 +2204,10 @@ extend_writeAll(void) VRFY((ret>= 0),"set independent IO collectively succeeded"); } - /* write data collectively */ ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace, xfer_plist, data_array1); + H5Eprint2(H5E_DEFAULT, stderr); VRFY((ret >= 0), "H5Dwrite succeeded"); /* release resource */ @@ -2894,26 +2894,6 @@ none_selection_chunk(void) * as some dxpl flags to get collective I/O to break in different ways. * * The relevant I/O function and expected response for each mode: - * TEST_ACTUAL_IO_MULTI_CHUNK_IND: - * H5D_mpi_chunk_collective_io, each process reports independent I/O - * - * TEST_ACTUAL_IO_MULTI_CHUNK_COL: - * H5D_mpi_chunk_collective_io, each process reports collective I/O - * - * TEST_ACTUAL_IO_MULTI_CHUNK_MIX: - * H5D_mpi_chunk_collective_io, each process reports mixed I/O - * - * TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE: - * H5D_mpi_chunk_collective_io, processes disagree. The root reports - * collective, the rest report independent I/O - * - * TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND: - * Same test TEST_ACTUAL_IO_MULTI_CHUNK_IND. - * Set directly go to multi-chunk-io without num threshold calc. - * TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL: - * Same test TEST_ACTUAL_IO_MULTI_CHUNK_COL. - * Set directly go to multi-chunk-io without num threshold calc. - * * TEST_ACTUAL_IO_LINK_CHUNK: * H5D_link_chunk_collective_io, processes report linked chunk I/O * @@ -2927,9 +2907,8 @@ none_selection_chunk(void) * TEST_ACTUAL_IO_RESET: * Perfroms collective and then independent I/O wit hthe same dxpl to * make sure the peroperty is correctly reset to the default on each use. - * Specifically, this test runs TEST_ACTUAL_IO_MULTI_CHUNK_NO_OPT_MIX_DISAGREE - * (The most complex case that works on all builds) and then performs - * an independent read and write with the same dxpls. + * This test shares with TEST_ACTUAL_IO_LINK_CHUNK case + * and then performs an independent read and write with the same dxpls. * * Note: DIRECT_MULTI_CHUNK_MIX and DIRECT_MULTI_CHUNK_MIX_DISAGREE * is not needed as they are covered by DIRECT_CHUNK_MIX and @@ -2937,6 +2916,11 @@ none_selection_chunk(void) * path way to multi-chunk-io by H5FD_MPIO_CHUNK_MULTI_IO insted of num-threshold. * * Modification: + * - Work for HDFFV-8313. Removed multi-chunk-opt related cases + * - by decision to remove multi-chunk-opt feature. + * - Jonathan Kim (2013-09-19) + * + * Modification: * - Refctore to remove multi-chunk-without-opimization test and update for * testing direct to multi-chunk-io * Programmer: Jonathan Kim @@ -2956,8 +2940,6 @@ test_actual_io_mode(int selection_mode) { H5D_mpio_actual_io_mode_t actual_io_mode_expected = -1; const char * filename; const char * test_name; - hbool_t direct_multi_chunk_io; - hbool_t multi_chunk_io; hbool_t is_chunked; hbool_t is_collective; int mpi_size = -1; @@ -2986,21 +2968,6 @@ test_actual_io_mode(int selection_mode) { char message[256]; herr_t ret; - /* Set up some flags to make some future if statements slightly more readable */ - direct_multi_chunk_io = ( - selection_mode == TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND || - selection_mode == TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL ); - - /* Note: RESET performs the same tests as MULTI_CHUNK_MIX_DISAGREE and then - * tests independent I/O - */ - multi_chunk_io = ( - selection_mode == TEST_ACTUAL_IO_MULTI_CHUNK_IND || - selection_mode == TEST_ACTUAL_IO_MULTI_CHUNK_COL || - selection_mode == TEST_ACTUAL_IO_MULTI_CHUNK_MIX || - selection_mode == TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE || - selection_mode == TEST_ACTUAL_IO_RESET ); - is_chunked = ( selection_mode != TEST_ACTUAL_IO_CONTIGUOUS && selection_mode != TEST_ACTUAL_IO_NO_COLLECTIVE); @@ -3060,129 +3027,26 @@ test_actual_io_mode(int selection_mode) { /* Choose a selection method based on the type of I/O we want to occur, * and also set up some selection-dependeent test info. */ switch(selection_mode) { - - /* Independent I/O with optimization */ - case TEST_ACTUAL_IO_MULTI_CHUNK_IND: - case TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND: - /* Since the dataset is chunked by row and each process selects a row, - * each process writes to a different chunk. This forces all I/O to be - * independent. - */ - slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW); - - test_name = "Multi Chunk - Independent"; - actual_chunk_opt_mode_expected = H5D_MPIO_MULTI_CHUNK; - actual_io_mode_expected = H5D_MPIO_CHUNK_INDEPENDENT; - break; - - /* Collective I/O with optimization */ - case TEST_ACTUAL_IO_MULTI_CHUNK_COL: - case TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL: - /* The dataset is chunked by rows, so each process takes a column which - * spans all chunks. Since the processes write non-overlapping regular - * selections to each chunk, the operation is purely collective. - */ - slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL); - - test_name = "Multi Chunk - Collective"; - actual_chunk_opt_mode_expected = H5D_MPIO_MULTI_CHUNK; - if(mpi_size > 1) - actual_io_mode_expected = H5D_MPIO_CHUNK_COLLECTIVE; - else - actual_io_mode_expected = H5D_MPIO_CHUNK_INDEPENDENT; - break; - - /* Mixed I/O with optimization */ - case TEST_ACTUAL_IO_MULTI_CHUNK_MIX: - /* A chunk will be assigned collective I/O only if it is selected by each - * process. To get mixed I/O, have the root select all chunks and each - * subsequent process select the first and nth chunk. The first chunk, - * accessed by all, will be assigned collective I/O while each other chunk - * will be accessed only by the root and the nth procecess and will be - * assigned independent I/O. Each process will access one chunk collectively - * and at least one chunk independently, reporting mixed I/O. - */ - - if(mpi_rank == 0) { - /* Select the first column */ - slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL); - } else { - /* Select the first and the nth chunk in the nth column */ - block[0] = dim0 / mpi_size; - block[1] = dim1 / mpi_size; - count[0] = 2; - count[1] = 1; - stride[0] = mpi_rank * block[0]; - stride[1] = 1; - start[0] = 0; - start[1] = mpi_rank*block[1]; - } - - test_name = "Multi Chunk - Mixed"; - actual_chunk_opt_mode_expected = H5D_MPIO_MULTI_CHUNK; - actual_io_mode_expected = H5D_MPIO_CHUNK_MIXED; - break; - - /* RESET tests that the properties are properly reset to defaults each time I/O is - * performed. To acheive this, we have RESET perform collective I/O (which would change - * the values from the defaults) followed by independent I/O (which should report the - * default values). RESET doesn't need to have a unique selection, so we reuse - * MULTI_CHUMK_MIX_DISAGREE, which was chosen because it is a complex case that works - * on all builds. The independent section of RESET can be found at the end of this function. + /* RESET tests that the properties are properly reset to defaults each + * time I/O is performed. To acheive this, we have RESET perform + * collective I/O (which would change the values from the defaults) + * followed by independent I/O (which should report the default + * values). RESET doesn't need to have a unique selection, so we just + * reuse LINK_CHUNK, The independent section of RESET can be found at + * the end of this function. */ case TEST_ACTUAL_IO_RESET: - /* Mixed I/O with optimization and internal disagreement */ - case TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE: - /* A chunk will be assigned collective I/O only if it is selected by each - * process. To get mixed I/O with disagreement, assign process n to the - * first chunk and the nth chunk. The first chunk, selected by all, is - * assgigned collective I/O, while each other process gets independent I/O. - * Since the root process with only access the first chunk, it will report - * collective I/O. The subsequent processes will access the first chunk - * collectively, and their other chunk indpendently, reporting mixed I/O. - */ - - if(mpi_rank == 0) { - /* Select the first chunk in the first column */ - slab_set(mpi_rank, mpi_size, start, count, stride, block, BYCOL); - block[0] = block[0] / mpi_size; - } else { - /* Select the first and the nth chunk in the nth column */ - block[0] = dim0 / mpi_size; - block[1] = dim1 / mpi_size; - count[0] = 2; - count[1] = 1; - stride[0] = mpi_rank * block[0]; - stride[1] = 1; - start[0] = 0; - start[1] = mpi_rank*block[1]; - } - - /* If the testname was not already set by the RESET case */ - if (selection_mode == TEST_ACTUAL_IO_RESET) - test_name = "RESET"; - else - test_name = "Multi Chunk - Mixed (Disagreement)"; - - actual_chunk_opt_mode_expected = H5D_MPIO_MULTI_CHUNK; - if(mpi_size > 1) { - if(mpi_rank == 0) - actual_io_mode_expected = H5D_MPIO_CHUNK_COLLECTIVE; - else - actual_io_mode_expected = H5D_MPIO_CHUNK_MIXED; - } - else - actual_io_mode_expected = H5D_MPIO_CHUNK_INDEPENDENT; - - break; - /* Linked Chunk I/O */ case TEST_ACTUAL_IO_LINK_CHUNK: /* Nothing special; link chunk I/O is forced in the dxpl settings. */ slab_set(mpi_rank, mpi_size, start, count, stride, block, BYROW); - test_name = "Link Chunk"; + /* If the testname was not already set by the RESET case */ + if (selection_mode == TEST_ACTUAL_IO_RESET) + test_name = "RESET"; + else + test_name = "Link Chunk"; actual_chunk_opt_mode_expected = H5D_MPIO_LINK_CHUNK; actual_io_mode_expected = H5D_MPIO_CHUNK_COLLECTIVE; break; @@ -3243,29 +3107,6 @@ test_actual_io_mode(int selection_mode) { /* Request collective I/O */ ret = H5Pset_dxpl_mpio(dxpl_write, H5FD_MPIO_COLLECTIVE); VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded"); - - /* Set the threshold number of processes per chunk to twice mpi_size. - * This will prevent the threshold from ever being met, thus forcing - * multi chunk io instead of link chunk io. - * This is via deault. - */ - if(multi_chunk_io) { - /* force multi-chunk-io by threshold */ - ret = H5Pset_dxpl_mpio_chunk_opt_num(dxpl_write, (unsigned) mpi_size*2); - VRFY((ret >= 0), "H5Pset_dxpl_mpio_chunk_opt_num succeeded"); - - /* set this to manipulate testing senario about allocating processes - * to chunks */ - ret = H5Pset_dxpl_mpio_chunk_opt_ratio(dxpl_write, (unsigned) 99); - VRFY((ret >= 0), "H5Pset_dxpl_mpio_chunk_opt_ratio succeeded"); - } - - /* Set directly go to multi-chunk-io without threshold calc. */ - if(direct_multi_chunk_io) { - /* set for multi chunk io by property*/ - ret = H5Pset_dxpl_mpio_chunk_opt(dxpl_write, H5FD_MPIO_CHUNK_MULTI_IO); - VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded"); - } } /* Make a copy of the dxpl to test the read operation */ @@ -3315,6 +3156,9 @@ test_actual_io_mode(int selection_mode) { /* To test that the property is succesfully reset to the default, we perform some * independent I/O after the collective I/O + * For the above collective I/O actual_chunk_opt_mode for read/write was + * expected as H5D_MPIO_LINK_CHUNK, but they are expected as + * H5D_MPIO_NO_CHUNK_OPTIMIZATION for independent I/O here. */ if (selection_mode == TEST_ACTUAL_IO_RESET) { if (mpi_rank == 0) { @@ -3375,6 +3219,11 @@ test_actual_io_mode(int selection_mode) { * * Purpose: Tests all possible cases of the actual_io_mode property. * + * Modification: + * - Work base for HDFFV-8313. Removed multi-chunk-opt related cases + * - by decision to remove multi-chunk-opt feature. + * - Jonathan Kim (2013-09-19) + * * Programmer: Jacob Gruber * Date: 2011-04-06 */ @@ -3384,32 +3233,12 @@ actual_io_mode_tests(void) { int mpi_rank = -1; MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); MPI_Comm_size(MPI_COMM_WORLD, &mpi_rank); - - test_actual_io_mode(TEST_ACTUAL_IO_NO_COLLECTIVE); - - /* - * Test multi-chunk-io via proc_num threshold - */ - test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_IND); - test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_COL); - - /* The Multi Chunk Mixed test requires atleast three processes. */ - if (mpi_size > 2) - test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_MIX); - else - HDfprintf(stdout, "Multi Chunk Mixed test requires 3 proceses minimum\n"); - - test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE); - /* - * Test multi-chunk-io via setting direct property - */ - test_actual_io_mode(TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND); - test_actual_io_mode(TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL); + test_actual_io_mode(TEST_ACTUAL_IO_NO_COLLECTIVE); test_actual_io_mode(TEST_ACTUAL_IO_LINK_CHUNK); test_actual_io_mode(TEST_ACTUAL_IO_CONTIGUOUS); - + test_actual_io_mode(TEST_ACTUAL_IO_RESET); return; } diff --git a/testpar/t_pmulti_dset.c b/testpar/t_pmulti_dset.c new file mode 100644 index 0000000..f098ced --- /dev/null +++ b/testpar/t_pmulti_dset.c @@ -0,0 +1,651 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Neil Fortner + * March 10, 2014 + * + * Purpose: Test H5Dwrite_multi() and H5Dread_multi using randomized + * parameters in parallel. Also tests H5Dwrite() and H5Dread() + * using a similar method. + * + * Note that this test currently relies on all processes generating + * the same sequence of random numbers after using a shared seed + * value, therefore it may not work across multiple machines. + */ + +#include "h5test.h" +#include "testpar.h" + +#define T_PMD_ERROR \ + {nerrors++; H5_FAILED(); AT(); printf("seed = %u\n", seed);} + +#define FILENAME "pmulti_dset.h5" +#define MAX_DSETS 5 +#define MAX_DSET_X 15 +#define MAX_DSET_Y 10 +#define MAX_CHUNK_X 8 +#define MAX_CHUNK_Y 6 +#define MAX_HS_X 4 +#define MAX_HS_Y 2 +#define MAX_HS 2 +#define MAX_POINTS 6 +#define MAX_SEL_RETRIES 10 +#define OPS_PER_FILE 25 +#define DSET_MAX_NAME_LEN 8 + +/* Option flags */ +#define MDSET_FLAG_CHUNK 0x01u +#define MDSET_FLAG_SHAPESAME 0x02u +#define MDSET_FLAG_MDSET 0x04u +#define MDSET_FLAG_COLLECTIVE 0x08u +#define MDSET_ALL_FLAGS (MDSET_FLAG_CHUNK | MDSET_FLAG_SHAPESAME \ + | MDSET_FLAG_MDSET | MDSET_FLAG_COLLECTIVE) + +/* MPI variables */ +int mpi_size; +int mpi_rank; + +/* Names for datasets */ +char dset_name[MAX_DSETS][DSET_MAX_NAME_LEN]; + +/* Random number seed */ +unsigned seed; + +/* Number of errors */ +int nerrors = 0; + + +/*------------------------------------------------------------------------- + * Function: test_pmdset + * + * Purpose: Test randomized I/O using one or more datasets. Creates a + * file, runs OPS_PER_FILE read or write operations verifying + * that reads return the expected data, then closes the file. + * Runs the test with a new file niter times. + * + * The operations can use either hyperslab or point + * selections. Options are available for chunked or + * contiguous layout, use of multiple datasets and H5D*_multi + * calls, and use of the "shapesame" algorithm code path. To + * avoid the shapesame path when that option is not set, this + * function simply adds a dimension to the memory buffer in a + * way that the shapesame code is not designed to handle. + * + * Return: Number of errors + * + * Programmer: Neil Fortner + * Monday, March 10, 2014 + * + *------------------------------------------------------------------------- + */ +static void +test_pmdset(size_t niter, unsigned flags) +{ + H5D_rw_multi_t multi_info[MAX_DSETS]; + size_t max_dsets; + size_t buf_size; + size_t ndsets; + hid_t file_id = -1; + hid_t fapl_id = -1; + hid_t dcpl_id = -1; + hid_t dxpl_id = -1; + hsize_t dset_dims[MAX_DSETS][3]; + hsize_t chunk_dims[2]; + hsize_t max_dims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; + unsigned *rbuf = NULL; + unsigned *rbufi[MAX_DSETS][MAX_DSET_X]; + unsigned *erbuf = NULL; + unsigned *erbufi[MAX_DSETS][MAX_DSET_X]; + unsigned *wbuf = NULL; + unsigned *wbufi[MAX_DSETS][MAX_DSET_X]; + unsigned *efbuf = NULL; + unsigned *efbufi[MAX_DSETS][MAX_DSET_X]; + unsigned char *dset_usage; + unsigned char *dset_usagei[MAX_DSETS][MAX_DSET_X]; + hbool_t do_read; + hbool_t last_read; + hbool_t overlap; + hsize_t start[MAX_HS][3]; + hsize_t count[MAX_HS][3]; + hsize_t points[3 * MAX_POINTS]; + int rank_data_diff; + unsigned op_data_incr; + size_t i, j, k, l, m, n, o, p; + + if(mpi_rank == 0) + TESTING("random I/O"); + + /* Calculate maximum number of datasets */ + max_dsets = (flags & MDSET_FLAG_MDSET) ? MAX_DSETS : 1; + + /* Calculate data increment per write operation */ + op_data_incr = (unsigned)max_dsets * MAX_DSET_X * MAX_DSET_Y * (unsigned)mpi_size; + + /* Calculate buffer size */ + buf_size = max_dsets * MAX_DSET_X * MAX_DSET_Y * sizeof(unsigned); + + /* Allocate buffers */ + if(NULL == (rbuf = (unsigned *)HDmalloc(buf_size))) + T_PMD_ERROR + if(NULL == (erbuf = (unsigned *)HDmalloc(buf_size))) + T_PMD_ERROR + if(NULL == (wbuf = (unsigned *)HDmalloc(buf_size))) + T_PMD_ERROR + if(NULL == (efbuf = (unsigned *)HDmalloc(buf_size))) + T_PMD_ERROR + if(NULL == (dset_usage = (unsigned char *)HDmalloc(max_dsets * MAX_DSET_X * MAX_DSET_Y))) + T_PMD_ERROR + + /* Initialize buffer indices */ + for(i = 0; i < max_dsets; i++) + for(j = 0; j < MAX_DSET_X; j++) { + rbufi[i][j] = rbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y); + erbufi[i][j] = erbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y); + wbufi[i][j] = wbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y); + efbufi[i][j] = efbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y); + dset_usagei[i][j] = dset_usage + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y); + } /* end for */ + + /* Initialize 3rd dimension information (for tricking library into using + * non-"shapesame" code */ + for(i = 0; i < max_dsets; i++) + dset_dims[i][2] = 1; + for(i = 0; i < MAX_HS; i++) { + start[i][2] = 0; + count[i][2] = 1; + } /* end for */ + + /* Initialize multi_info */ + for(i = 0; i < max_dsets; i++) { + multi_info[i].dset_id = -1; + multi_info[i].dset_space_id = -1; + multi_info[i].mem_type_id = H5T_NATIVE_UINT; + multi_info[i].mem_space_id = -1; + } /* end for */ + + /* Generate memory dataspace */ + dset_dims[0][0] = MAX_DSET_X; + dset_dims[0][1] = MAX_DSET_Y; + if((multi_info[0].mem_space_id = H5Screate_simple((flags & MDSET_FLAG_SHAPESAME) ? 2 : 3, dset_dims[0], NULL)) < 0) + T_PMD_ERROR + for(i = 1; i < max_dsets; i++) + if((multi_info[i].mem_space_id = H5Scopy(multi_info[0].mem_space_id)) < 0) + T_PMD_ERROR + + /* Create fapl */ + if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + T_PMD_ERROR + + /* Set MPIO file driver */ + if((H5Pset_fapl_mpio(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL)) < 0) + T_PMD_ERROR + + /* Create dcpl */ + if((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) + T_PMD_ERROR + + /* Set fill time to alloc, and alloc time to early (so we always know + * what's in the file) */ + if(H5Pset_fill_time(dcpl_id, H5D_FILL_TIME_ALLOC) < 0) + T_PMD_ERROR + if(H5Pset_alloc_time(dcpl_id, H5D_ALLOC_TIME_EARLY) < 0) + T_PMD_ERROR + + /* Create dxpl */ + if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) + T_PMD_ERROR + + /* Set collective or independent I/O */ + if(flags & MDSET_FLAG_COLLECTIVE) { + if(H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) < 0) + T_PMD_ERROR + } /* end if */ + else + if(H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_INDEPENDENT) < 0) + T_PMD_ERROR + + for(i = 0; i < niter; i++) { + /* Determine number of datasets */ + ndsets = (flags & MDSET_FLAG_MDSET) + ? (size_t)((size_t)HDrandom() % max_dsets) + 1 : 1; + + /* Create file */ + if((file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) + T_PMD_ERROR + + /* Create datasets */ + for(j = 0; j < ndsets; j++) { + /* Generate file dataspace */ + dset_dims[j][0] = (hsize_t)((HDrandom() % MAX_DSET_X) + 1); + dset_dims[j][1] = (hsize_t)((HDrandom() % MAX_DSET_Y) + 1); + if((multi_info[j].dset_space_id = H5Screate_simple(2, dset_dims[j], (flags & MDSET_FLAG_CHUNK) ? max_dims : NULL)) < 0) + T_PMD_ERROR + + /* Generate chunk (if requested) */ + if(flags & MDSET_FLAG_CHUNK) { + chunk_dims[0] = (hsize_t)((HDrandom() % MAX_CHUNK_X) + 1); + chunk_dims[1] = (hsize_t)((HDrandom() % MAX_CHUNK_Y) + 1); + if(H5Pset_chunk(dcpl_id, 2, chunk_dims) < 0) + T_PMD_ERROR + } /* end if */ + + /* Create dataset */ + if((multi_info[j].dset_id = H5Dcreate2(file_id, dset_name[j], H5T_NATIVE_UINT, multi_info[j].dset_space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0) + T_PMD_ERROR + } /* end for */ + + /* Initialize read buffer and expected read buffer */ + (void)HDmemset(rbuf, 0, buf_size); + (void)HDmemset(erbuf, 0, buf_size); + + /* Initialize write buffer */ + for(j = 0; j < max_dsets; j++) + for(k = 0; k < MAX_DSET_X; k++) + for(l = 0; l < MAX_DSET_Y; l++) + wbufi[j][k][l] = (unsigned)(((unsigned)mpi_rank * max_dsets * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_X * MAX_DSET_Y) + (k * MAX_DSET_Y) + l); + + /* Initialize expected file buffer */ + (void)HDmemset(efbuf, 0, buf_size); + + /* Set last_read to TRUE so we don't reopen the file on the first + * iteration */ + last_read = TRUE; + + /* Perform read/write operations */ + for(j = 0; j < OPS_PER_FILE; j++) { + /* Decide whether to read or write */ + do_read = (hbool_t)(HDrandom() % 2); + + /* Barrier to ensure processes have finished the previous operation + */ + MPI_Barrier(MPI_COMM_WORLD); + + /* If the last operation was a write we must close and reopen the + * file to ensure consistency */ + /* Possibly change to MPI_FILE_SYNC at some point? -NAF */ + if(!last_read) { + /* Close datasets */ + for(k = 0; k < ndsets; k++) { + if(H5Dclose(multi_info[k].dset_id) < 0) + T_PMD_ERROR + multi_info[k].dset_id = -1; + } /* end for */ + + /* Close file */ + if(H5Fclose(file_id) < 0) + T_PMD_ERROR + file_id = -1; + + /* Barrier */ + MPI_Barrier(MPI_COMM_WORLD); + + /* Reopen file */ + if((file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl_id)) < 0) + T_PMD_ERROR + + /* Reopen datasets */ + for(k = 0; k < ndsets; k++) { + if((multi_info[k].dset_id = H5Dopen2(file_id, dset_name[k], H5P_DEFAULT)) < 0) + T_PMD_ERROR + } /* end for */ + + /* Barrier */ + MPI_Barrier(MPI_COMM_WORLD); + } /* end if */ + + /* Keep track of whether the last operation was a read */ + last_read = do_read; + + /* Loop over datasets */ + for(k = 0; k < ndsets; k++) { + /* Reset selection */ + if(H5Sselect_none(multi_info[k].mem_space_id) < 0) + T_PMD_ERROR + if(H5Sselect_none(multi_info[k].dset_space_id) < 0) + T_PMD_ERROR + + /* Reset dataset usage array, if writing */ + if(!do_read) + HDmemset(dset_usage, 0, max_dsets * MAX_DSET_X * MAX_DSET_Y); + + /* Iterate over processes */ + for(l = 0; l < (size_t)mpi_size; l++) { + /* Calculate difference between data in process being + * iterated over and that in this process */ + rank_data_diff = (int)((unsigned)max_dsets * MAX_DSET_X * MAX_DSET_Y) * ((int)l - (int)mpi_rank); + + /* Decide whether to do a hyperslab or point selection */ + if(HDrandom() % 2) { + /* Hyperslab */ + size_t nhs = (size_t)((HDrandom() % MAX_HS) + 1); /* Number of hyperslabs */ + size_t max_hs_x = (MAX_HS_X <= dset_dims[k][0]) ? MAX_HS_X : dset_dims[k][0]; /* Determine maximum hyperslab size in X */ + size_t max_hs_y = (MAX_HS_Y <= dset_dims[k][1]) ? MAX_HS_Y : dset_dims[k][1]; /* Determine maximum hyperslab size in Y */ + + for(m = 0; m < nhs; m++) { + overlap = TRUE; + for(n = 0; overlap && (n < MAX_SEL_RETRIES); n++) { + /* Generate hyperslab */ + count[m][0] = (hsize_t)(((hsize_t)HDrandom() % max_hs_x) + 1); + count[m][1] = (hsize_t)(((hsize_t)HDrandom() % max_hs_y) + 1); + start[m][0] = (count[m][0] == dset_dims[k][0]) ? 0 + : (hsize_t)HDrandom() % (dset_dims[k][0] - count[m][0] + 1); + start[m][1] = (count[m][1] == dset_dims[k][1]) ? 0 + : (hsize_t)HDrandom() % (dset_dims[k][1] - count[m][1] + 1); + + /* If writing, check for overlap with other processes */ + overlap = FALSE; + if(!do_read) + for(o = start[m][0]; + (o < (start[m][0] + count[m][0])) && !overlap; + o++) + for(p = start[m][1]; + (p < (start[m][1] + count[m][1])) && !overlap; + p++) + if(dset_usagei[k][o][p]) + overlap = TRUE; + } /* end for */ + + /* If we did not find a non-overlapping hyperslab + * quit trying to generate new ones */ + if(overlap) { + nhs = m; + break; + } /* end if */ + + /* Select hyperslab if this is the current process + */ + if(l == (size_t)mpi_rank) { + if(H5Sselect_hyperslab(multi_info[k].mem_space_id, H5S_SELECT_OR, start[m], NULL, count[m], NULL) < 0) + T_PMD_ERROR + if(H5Sselect_hyperslab(multi_info[k].dset_space_id, H5S_SELECT_OR, start[m], NULL, count[m], NULL) < 0) + T_PMD_ERROR + } /* end if */ + + /* Update expected buffers */ + if(do_read) { + if(l == (size_t)mpi_rank) + for(n = start[m][0]; n < (start[m][0] + count[m][0]); n++) + for(o = start[m][1]; o < (start[m][1] + count[m][1]); o++) + erbufi[k][n][o] = efbufi[k][n][o]; + } /* end if */ + else + for(n = start[m][0]; n < (start[m][0] + count[m][0]); n++) + for(o = start[m][1]; o < (start[m][1] + count[m][1]); o++) + efbufi[k][n][o] = (unsigned)((int)wbufi[k][n][o] + rank_data_diff); + } /* end for */ + + /* Update dataset usage array if writing */ + if(!do_read) + for(m = 0; m < nhs; m++) + for(n = start[m][0]; n < (start[m][0] + count[m][0]); n++) + for(o = start[m][1]; o < (start[m][1] + count[m][1]); o++) + dset_usagei[k][n][o] = (unsigned char)1; + } /* end if */ + else { + /* Point selection */ + size_t npoints = (size_t)(((size_t)HDrandom() % MAX_POINTS) + 1); /* Number of points */ + + /* Generate points */ + for(m = 0; m < npoints; m++) { + overlap = TRUE; + for(n = 0; overlap && (n < MAX_SEL_RETRIES); n++) { + /* Generate point */ + points[2 * m] = (unsigned)((hsize_t)HDrandom() % dset_dims[k][0]); + points[(2 * m) + 1] = (unsigned)((hsize_t)HDrandom() % dset_dims[k][1]); + + /* If writing, check for overlap with other + * processes */ + overlap = FALSE; + if(!do_read) + if(dset_usagei[k][points[2 * m]][points[(2 * m) + 1]]) + overlap = TRUE; + } /* end for */ + + /* If we did not find a non-overlapping point quit + * trying to generate new ones */ + if(overlap) { + npoints = m; + break; + } /* end if */ + } /* end for */ + + /* Update dataset usage array if writing */ + if(!do_read) + for(m = 0; m < npoints; m++) + dset_usagei[k][points[2 * m]][points[(2 * m) + 1]] = (unsigned char)1; + + /* Select points in file if this is the current process + */ + if((l == (size_t)mpi_rank) && (npoints > 0)) + if(H5Sselect_elements(multi_info[k].dset_space_id, H5S_SELECT_APPEND, npoints, points) < 0) + T_PMD_ERROR + + /* Update expected buffers */ + if(do_read) { + if(l == (size_t)mpi_rank) + for(m = 0; m < npoints; m++) + erbufi[k][points[2 * m]][points[(2 * m) + 1]] = efbufi[k][points[2 * m]][points[(2 * m) + 1]]; + } /* end if */ + else + for(m = 0; m < npoints; m++) + efbufi[k][points[2 * m]][points[(2 * m) + 1]] = (unsigned)((int)wbufi[k][points[2 * m]][points[(2 * m) + 1]] + rank_data_diff); + + /* Select points in memory if this is the current + * process */ + if((l == (size_t)mpi_rank) && (npoints > 0)) { + /* Convert to 3D for memory selection, if not using + * "shapesame" */ + if(!(flags & MDSET_FLAG_SHAPESAME)) { + for(m = npoints - 1; m > 0; m--) { + points[(3 * m) + 2] = 0; + points[(3 * m) + 1] = points[(2 * m) + 1]; + points[3 * m] = points[2 * m]; + } /* end for */ + points[2] = 0; + } /* end if */ + + /* Select elements */ + if(H5Sselect_elements(multi_info[k].mem_space_id, H5S_SELECT_APPEND, npoints, points) < 0) + T_PMD_ERROR + } /* end if */ + } /* end else */ + } /* end for */ + } /* end for */ + + /* Perform I/O */ + if(do_read) { + if(flags & MDSET_FLAG_MDSET) { + /* Set buffers */ + for(k = 0; k < ndsets; k++) + multi_info[k].u.rbuf = rbufi[k][0]; + + /* Read datasets */ + if(H5Dread_multi(dxpl_id, ndsets, multi_info) < 0) + T_PMD_ERROR + } /* end if */ + else + /* Read */ + if(H5Dread(multi_info[0].dset_id, multi_info[0].mem_type_id, multi_info[0].mem_space_id, multi_info[0].dset_space_id, dxpl_id, rbuf) < 0) + T_PMD_ERROR + + /* Verify data */ + if(0 != memcmp(rbuf, erbuf, buf_size)) + T_PMD_ERROR + } /* end if */ + else { + if(flags & MDSET_FLAG_MDSET) { + /* Set buffers */ + for(k = 0; k < ndsets; k++) + multi_info[k].u.wbuf = wbufi[k][0]; + + /* Write datasets */ + if(H5Dwrite_multi(dxpl_id, ndsets, multi_info) < 0) + T_PMD_ERROR + } /* end if */ + else + /* Write */ + if(H5Dwrite(multi_info[0].dset_id, multi_info[0].mem_type_id, multi_info[0].mem_space_id, multi_info[0].dset_space_id, dxpl_id, wbuf) < 0) + T_PMD_ERROR + + /* Update wbuf */ + for(l = 0; l < max_dsets; l++) + for(m = 0; m < MAX_DSET_X; m++) + for(n = 0; n < MAX_DSET_Y; n++) + wbufi[l][m][n] += op_data_incr; + } /* end else */ + } /* end for */ + + /* Close */ + for(j = 0; j < ndsets; j++) { + if(H5Dclose(multi_info[j].dset_id) < 0) + T_PMD_ERROR + multi_info[j].dset_id = -1; + if(H5Sclose(multi_info[j].dset_space_id) < 0) + T_PMD_ERROR + multi_info[j].dset_space_id = -1; + } /* end for */ + if(H5Fclose(file_id) < 0) + T_PMD_ERROR + file_id = -1; + } /* end for */ + + /* Close */ + for(i = 0; i < max_dsets; i++) { + if(H5Sclose(multi_info[i].mem_space_id) < 0) + T_PMD_ERROR + multi_info[i].mem_space_id = -1; + } /* end for */ + if(H5Pclose(dxpl_id) < 0) + T_PMD_ERROR + dxpl_id = -1; + if(H5Pclose(dcpl_id) < 0) + T_PMD_ERROR + dcpl_id = -1; + if(H5Pclose(fapl_id) < 0) + T_PMD_ERROR + fapl_id = -1; + free(rbuf); + rbuf = NULL; + free(erbuf); + erbuf = NULL; + free(wbuf); + wbuf = NULL; + free(efbuf); + efbuf = NULL; + free(dset_usage); + dset_usage = NULL; + + if(mpi_rank == 0) + PASSED(); + + return; +} /* end test_mdset() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Runs all tests with all combinations of configuration + * flags. + * + * Return: Success: 0 + * Failue: 1 + * + * Programmer: Neil Fortner + * Monday, March 10, 2014 + * + *------------------------------------------------------------------------- + */ +int +main(int argc, char *argv[]) +{ + unsigned i; + int ret; + + h5_reset(); + + /* Initialize MPI */ + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + /* Generate random number seed, if rank 0 */ + if(MAINPROCESS) + seed = (unsigned)HDtime(NULL); + + /* Broadcast seed from rank 0 (other ranks will receive rank 0's seed) */ + if(MPI_SUCCESS != MPI_Bcast(&seed, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD)) + T_PMD_ERROR + + /* Seed random number generator with shared seed (so all ranks generate the + * same sequence) */ + HDsrandom(seed); + + /* Fill dset_name array */ + for(i = 0; i < MAX_DSETS; i++) { + if((ret = snprintf(dset_name[i], DSET_MAX_NAME_LEN, "dset%u", i)) < 0) + T_PMD_ERROR + if(ret >= DSET_MAX_NAME_LEN) + T_PMD_ERROR + } /* end for */ + + for(i = 0; i <= MDSET_ALL_FLAGS; i++) { + /* Print flag configuration */ + if(MAINPROCESS) { + puts("\nConfiguration:"); + printf(" Layout: %s\n", (i & MDSET_FLAG_CHUNK) ? "Chunked" : "Contiguous"); + printf(" Shape same: %s\n", (i & MDSET_FLAG_SHAPESAME) ? "Yes" : "No"); + printf(" I/O type: %s\n", (i & MDSET_FLAG_MDSET) ? "Multi" : "Single"); + printf(" MPI I/O type: %s\n", (i & MDSET_FLAG_COLLECTIVE) ? "Collective" : "Independent"); + } /* end if */ + + test_pmdset(10, i); + } /* end for */ + + /* Barrier to make sure all ranks are done before deleting the file, and + * also to clean up output (make sure PASSED is printed before any of the + * following messages) */ + if(MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD)) + T_PMD_ERROR + + /* Delete file */ + if(mpi_rank == 0) + if(MPI_SUCCESS != MPI_File_delete(FILENAME, MPI_INFO_NULL)) + T_PMD_ERROR + + /* Gather errors from all processes */ + MPI_Allreduce(&nerrors, &ret, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); + nerrors = ret; + + if(MAINPROCESS) { + printf("===================================\n"); + if (nerrors) + printf("***Parallel multi dataset tests detected %d errors***\n", nerrors); + else + printf("Parallel multi dataset tests finished with no errors\n"); + printf("===================================\n"); + } /* end if */ + + /* close HDF5 library */ + H5close(); + + /* MPI_Finalize must be called AFTER H5close which may use MPI calls */ + MPI_Finalize(); + + /* cannot just return (nerrors) because exit code is limited to 1 byte */ + return(nerrors != 0); +} /* end main() */ + diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index 87d9056..abd09ea 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -383,11 +383,12 @@ int main(int argc, char **argv) "parallel extend Chunked allocation on serial file", PARATESTFILE); AddTest("fltread", test_filter_read, NULL, "parallel read of dataset written serially with filters", PARATESTFILE); - +#if 0 //MSB FIX #ifdef H5_HAVE_FILTER_DEFLATE AddTest("cmpdsetr", compress_readAll, NULL, "compressed dataset collective read", PARATESTFILE); #endif /* H5_HAVE_FILTER_DEFLATE */ +#endif AddTest("zerodsetr", zero_dim_dset, NULL, "zero dim dset", PARATESTFILE); @@ -439,23 +440,6 @@ int main(int argc, char **argv) AddTest((mpi_size <3)? "-cchunk5":"cchunk5" , coll_chunk5,NULL, "linked chunk collective IO without optimization",PARATESTFILE); - AddTest((mpi_size < 3)? "-cchunk6" : "cchunk6", - coll_chunk6,NULL, - "multi-chunk collective IO with direct request",PARATESTFILE); - AddTest((mpi_size < 3)? "-cchunk7" : "cchunk7", - coll_chunk7,NULL, - "linked chunk collective IO with optimization",PARATESTFILE); - AddTest((mpi_size < 3)? "-cchunk8" : "cchunk8", - coll_chunk8,NULL, - "linked chunk collective IO transferring to multi-chunk",PARATESTFILE); - AddTest((mpi_size < 3)? "-cchunk9" : "cchunk9", - coll_chunk9,NULL, - "multiple chunk collective IO with optimization",PARATESTFILE); - AddTest((mpi_size < 3)? "-cchunk10" : "cchunk10", - coll_chunk10,NULL, - "multiple chunk collective IO transferring to independent IO",PARATESTFILE); - - /* irregular collective IO tests*/ AddTest("ccontw", diff --git a/testpar/testphdf5.h b/testpar/testphdf5.h index 322cb9b..ec61c58 100644 --- a/testpar/testphdf5.h +++ b/testpar/testphdf5.h @@ -168,14 +168,8 @@ enum H5TEST_COLL_CHUNK_API {API_NONE=0,API_LINK_HARD, /* Definitions of the selection mode for the test_actual_io_function. */ #define TEST_ACTUAL_IO_NO_COLLECTIVE 0 #define TEST_ACTUAL_IO_RESET 1 -#define TEST_ACTUAL_IO_MULTI_CHUNK_IND 2 -#define TEST_ACTUAL_IO_MULTI_CHUNK_COL 3 -#define TEST_ACTUAL_IO_MULTI_CHUNK_MIX 4 -#define TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE 5 -#define TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND 6 -#define TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL 7 -#define TEST_ACTUAL_IO_LINK_CHUNK 8 -#define TEST_ACTUAL_IO_CONTIGUOUS 9 +#define TEST_ACTUAL_IO_LINK_CHUNK 2 +#define TEST_ACTUAL_IO_CONTIGUOUS 3 /* Definitions of the selection mode for the no_collective_cause_tests function. */ #define TEST_COLLECTIVE 0x001 |