예제 #1
0
/*----------------------------------------------------------------------------
 * Name:        h5pget_fapl_mpio_c
 * Purpose:     Call H5Pget_fapl_mpio to retrieve communicator and info object
 * Inputs:      prp_id - property list identifier
 *              comm   - buffer to return MPI communicator
 *              info   - buffer to return MPI info object
 * Returns:     0 on success, -1 on failure
 * Programmer:  Elena Pourmal
 *              Thursday, October 26, 2000
 * Modifications:
 *---------------------------------------------------------------------------*/
int_f
nh5pget_fapl_mpio_c(hid_t_f *prp_id, int_f* comm, int_f* info)
{
     int ret_value = -1;
     hid_t c_prp_id;
     herr_t ret;
     MPI_Comm c_comm;
     MPI_Info c_info;

     /*
      * Call H5Pget_mpi function.
      */
     c_prp_id = *prp_id;
     ret = H5Pget_fapl_mpio(c_prp_id, &c_comm, &c_info);
     if (ret < 0) return ret_value;
     *comm = (int_f) MPI_Comm_c2f(c_comm);
     *info = (int_f) MPI_Info_c2f(c_info);
     ret_value = 0;
     return ret_value;
}
/*-------------------------------------------------------------------------
 * Function:    test_fapl_mpio_dup
 *
 * Purpose:     Test if fapl_mpio property list keeps a duplicate of the
 * 		communicator and INFO objects given when set; and returns
 * 		duplicates of its components when H5Pget_fapl_mpio is called.
 *
 * Return:      Success:        None
 *
 *              Failure:        Abort
 *
 * Programmer:  Albert Cheng
 *              January 9, 2003
 *
 * Modifications:
 *-------------------------------------------------------------------------
 */
void
test_fapl_mpio_dup(void)
{
    int mpi_size, mpi_rank;
    MPI_Comm comm, comm_tmp;
    int mpi_size_old, mpi_rank_old;
    int mpi_size_tmp, mpi_rank_tmp;
    MPI_Info info = MPI_INFO_NULL;
    MPI_Info info_tmp = MPI_INFO_NULL;
    int mrc;			/* MPI return value */
    hid_t acc_pl;		/* File access properties */
    herr_t ret;			/* hdf5 return value */
    int nkeys, nkeys_tmp;

    if (VERBOSE_MED)
	printf("Verify fapl_mpio duplicates communicator and INFO objects\n");

    /* set up MPI parameters */
    MPI_Comm_size(MPI_COMM_WORLD,&mpi_size);
    MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
    if (VERBOSE_MED)
	printf("rank/size of MPI_COMM_WORLD are %d/%d\n", mpi_rank, mpi_size);

    /* Create a new communicator that has the same processes as MPI_COMM_WORLD.
     * Use MPI_Comm_split because it is simplier than MPI_Comm_create
     */
    mrc = MPI_Comm_split(MPI_COMM_WORLD, 0, 0, &comm);
    VRFY((mrc==MPI_SUCCESS), "MPI_Comm_split");
    MPI_Comm_size(comm,&mpi_size_old);
    MPI_Comm_rank(comm,&mpi_rank_old);
    if (VERBOSE_MED)
	printf("rank/size of comm are %d/%d\n", mpi_rank_old, mpi_size_old);

    /* create a new INFO object with some trivial information. */
    mrc = MPI_Info_create(&info);
    VRFY((mrc==MPI_SUCCESS), "MPI_Info_create");
    mrc = MPI_Info_set(info, "hdf_info_name", "XYZ");
    VRFY((mrc==MPI_SUCCESS), "MPI_Info_set");
    if (MPI_INFO_NULL != info){
	mrc=MPI_Info_get_nkeys(info, &nkeys);
	VRFY((mrc==MPI_SUCCESS), "MPI_Info_get_nkeys");
    }
    if (VERBOSE_MED)
	h5_dump_info_object(info);

    acc_pl = H5Pcreate (H5P_FILE_ACCESS);
    VRFY((acc_pl >= 0), "H5P_FILE_ACCESS");

    ret = H5Pset_fapl_mpio(acc_pl, comm, info);
    VRFY((ret >= 0), "");

    /* Case 1:
     * Free the created communicator and INFO object.
     * Check if the access property list is still valid and can return
     * valid communicator and INFO object.
     */
    mrc = MPI_Comm_free(&comm);
    VRFY((mrc==MPI_SUCCESS), "MPI_Comm_free");
    if (MPI_INFO_NULL!=info){
	mrc = MPI_Info_free(&info);
	VRFY((mrc==MPI_SUCCESS), "MPI_Info_free");
    }

    ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, &info_tmp);
    VRFY((ret >= 0), "H5Pget_fapl_mpio");
    MPI_Comm_size(comm_tmp,&mpi_size_tmp);
    MPI_Comm_rank(comm_tmp,&mpi_rank_tmp);
    if (VERBOSE_MED)
	printf("After H5Pget_fapl_mpio: rank/size of comm are %d/%d\n",
	mpi_rank_tmp, mpi_size_tmp);
    VRFY((mpi_size_tmp==mpi_size), "MPI_Comm_size");
    VRFY((mpi_rank_tmp==mpi_rank), "MPI_Comm_rank");
    if (MPI_INFO_NULL != info_tmp){
	mrc=MPI_Info_get_nkeys(info_tmp, &nkeys_tmp);
	VRFY((mrc==MPI_SUCCESS), "MPI_Info_get_nkeys");
	VRFY((nkeys_tmp==nkeys), "new and old nkeys equal");
    }
    if (VERBOSE_MED)
	h5_dump_info_object(info_tmp);

    /* Case 2:
     * Free the retrieved communicator and INFO object.
     * Check if the access property list is still valid and can return
     * valid communicator and INFO object.
     * Also verify the NULL argument option.
     */
    mrc = MPI_Comm_free(&comm_tmp);
    VRFY((mrc==MPI_SUCCESS), "MPI_Comm_free");
    if (MPI_INFO_NULL!=info_tmp){
	mrc = MPI_Info_free(&info_tmp);
	VRFY((mrc==MPI_SUCCESS), "MPI_Info_free");
    }

    /* check NULL argument options. */
    ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, NULL);
    VRFY((ret >= 0), "H5Pget_fapl_mpio Comm only");
    mrc = MPI_Comm_free(&comm_tmp);
    VRFY((mrc==MPI_SUCCESS), "MPI_Comm_free");

    ret = H5Pget_fapl_mpio(acc_pl, NULL, &info_tmp);
    VRFY((ret >= 0), "H5Pget_fapl_mpio Info only");
    if (MPI_INFO_NULL!=info_tmp){
	mrc = MPI_Info_free(&info_tmp);
	VRFY((mrc==MPI_SUCCESS), "MPI_Info_free");
    }

    ret = H5Pget_fapl_mpio(acc_pl, NULL, NULL);
    VRFY((ret >= 0), "H5Pget_fapl_mpio neither");

    /* now get both and check validity too. */
    /* Donot free the returned objects which are used in the next case. */
    ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, &info_tmp);
    VRFY((ret >= 0), "H5Pget_fapl_mpio");
    MPI_Comm_size(comm_tmp,&mpi_size_tmp);
    MPI_Comm_rank(comm_tmp,&mpi_rank_tmp);
    if (VERBOSE_MED)
	printf("After second H5Pget_fapl_mpio: rank/size of comm are %d/%d\n",
	mpi_rank_tmp, mpi_size_tmp);
    VRFY((mpi_size_tmp==mpi_size), "MPI_Comm_size");
    VRFY((mpi_rank_tmp==mpi_rank), "MPI_Comm_rank");
    if (MPI_INFO_NULL != info_tmp){
	mrc=MPI_Info_get_nkeys(info_tmp, &nkeys_tmp);
	VRFY((mrc==MPI_SUCCESS), "MPI_Info_get_nkeys");
	VRFY((nkeys_tmp==nkeys), "new and old nkeys equal");
    }
    if (VERBOSE_MED)
	h5_dump_info_object(info_tmp);

    /* Case 3:
     * Close the property list and verify the retrieved communicator and INFO
     * object are still valid.
     */
    H5Pclose(acc_pl);
    MPI_Comm_size(comm_tmp,&mpi_size_tmp);
    MPI_Comm_rank(comm_tmp,&mpi_rank_tmp);
    if (VERBOSE_MED)
	printf("After Property list closed: rank/size of comm are %d/%d\n",
	mpi_rank_tmp, mpi_size_tmp);
    if (MPI_INFO_NULL != info_tmp){
	mrc=MPI_Info_get_nkeys(info_tmp, &nkeys_tmp);
	VRFY((mrc==MPI_SUCCESS), "MPI_Info_get_nkeys");
    }
    if (VERBOSE_MED)
	h5_dump_info_object(info_tmp);

    /* clean up */
    mrc = MPI_Comm_free(&comm_tmp);
    VRFY((mrc==MPI_SUCCESS), "MPI_Comm_free");
    if (MPI_INFO_NULL!=info_tmp){
	mrc = MPI_Info_free(&info_tmp);
	VRFY((mrc==MPI_SUCCESS), "MPI_Info_free");
    }
}
예제 #3
0
/*
 * Open a file through the HDF5 interface.
 */
static void *HDF5_Open(char *testFileName, IOR_param_t * param)
{
        hid_t accessPropList, createPropList;
        hsize_t memStart[NUM_DIMS],
            dataSetDims[NUM_DIMS],
            memStride[NUM_DIMS],
            memCount[NUM_DIMS], memBlock[NUM_DIMS], memDataSpaceDims[NUM_DIMS];
        int tasksPerDataSet;
        unsigned fd_mode = (unsigned)0;
        hid_t *fd;
        MPI_Comm comm;
        MPI_Info mpiHints = MPI_INFO_NULL;

        fd = (hid_t *) malloc(sizeof(hid_t));
        if (fd == NULL)
                ERR("malloc() failed");
        /*
         * HDF5 uses different flags than those for POSIX/MPIIO
         */
        if (param->open == WRITE) {     /* WRITE flags */
                param->openFlags = IOR_TRUNC;
        } else {                /* READ or check WRITE/READ flags */
                param->openFlags = IOR_RDONLY;
        }

        /* set IOR file flags to HDF5 flags */
        /* -- file open flags -- */
        if (param->openFlags & IOR_RDONLY) {
                fd_mode |= H5F_ACC_RDONLY;
        }
        if (param->openFlags & IOR_WRONLY) {
                fprintf(stdout, "File write only not implemented in HDF5\n");
        }
        if (param->openFlags & IOR_RDWR) {
                fd_mode |= H5F_ACC_RDWR;
        }
        if (param->openFlags & IOR_APPEND) {
                fprintf(stdout, "File append not implemented in HDF5\n");
        }
        if (param->openFlags & IOR_CREAT) {
                fd_mode |= H5F_ACC_CREAT;
        }
        if (param->openFlags & IOR_EXCL) {
                fd_mode |= H5F_ACC_EXCL;
        }
        if (param->openFlags & IOR_TRUNC) {
                fd_mode |= H5F_ACC_TRUNC;
        }
        if (param->openFlags & IOR_DIRECT) {
                fprintf(stdout, "O_DIRECT not implemented in HDF5\n");
        }

        /* set up file creation property list */
        createPropList = H5Pcreate(H5P_FILE_CREATE);
        HDF5_CHECK(createPropList, "cannot create file creation property list");
        /* set size of offset and length used to address HDF5 objects */
        HDF5_CHECK(H5Pset_sizes
                   (createPropList, sizeof(hsize_t), sizeof(hsize_t)),
                   "cannot set property list properly");

        /* set up file access property list */
        accessPropList = H5Pcreate(H5P_FILE_ACCESS);
        HDF5_CHECK(accessPropList, "cannot create file access property list");

        /*
         * someday HDF5 implementation will allow subsets of MPI_COMM_WORLD
         */
        /* store MPI communicator info for the file access property list */
        if (param->filePerProc) {
                comm = MPI_COMM_SELF;
        } else {
                comm = testComm;
        }

        SetHints(&mpiHints, param->hintsFileName);
        /*
         * note that with MP_HINTS_FILTERED=no, all key/value pairs will
         * be in the info object.  The info object that is attached to
         * the file during MPI_File_open() will only contain those pairs
         * deemed valid by the implementation.
         */
        /* show hints passed to file */
        if (rank == 0 && param->showHints) {
                fprintf(stdout, "\nhints passed to access property list {\n");
                ShowHints(&mpiHints);
                fprintf(stdout, "}\n");
        }
        HDF5_CHECK(H5Pset_fapl_mpio(accessPropList, comm, mpiHints),
                   "cannot set file access property list");

        /* set alignment */
        HDF5_CHECK(H5Pset_alignment(accessPropList, param->setAlignment,
                                    param->setAlignment),
                   "cannot set alignment");

        /* open file */
        if (param->open == WRITE) {     /* WRITE */
                *fd = H5Fcreate(testFileName, fd_mode,
                                createPropList, accessPropList);
                HDF5_CHECK(*fd, "cannot create file");
        } else {                /* READ or CHECK */
                *fd = H5Fopen(testFileName, fd_mode, accessPropList);
                HDF5_CHECK(*fd, "cannot open file");
        }

        /* show hints actually attached to file handle */
        if (param->showHints || (1) /* WEL - this needs fixing */ ) {
                if (rank == 0
                    && (param->showHints) /* WEL - this needs fixing */ ) {
                        WARN("showHints not working for HDF5");
                }
        } else {
                MPI_Info mpiHintsCheck = MPI_INFO_NULL;
                hid_t apl;
                apl = H5Fget_access_plist(*fd);
                HDF5_CHECK(H5Pget_fapl_mpio(apl, &comm, &mpiHintsCheck),
                           "cannot get info object through HDF5");
                if (rank == 0) {
                        fprintf(stdout,
                                "\nhints returned from opened file (HDF5) {\n");
                        ShowHints(&mpiHintsCheck);
                        fprintf(stdout, "}\n");
                        if (1 == 1) {   /* request the MPIIO file handle and its hints */
                                MPI_File *fd_mpiio;
                                HDF5_CHECK(H5Fget_vfd_handle
                                           (*fd, apl, (void **)&fd_mpiio),
                                           "cannot get MPIIO file handle");
                                MPI_CHECK(MPI_File_get_info
                                          (*fd_mpiio, &mpiHintsCheck),
                                          "cannot get info object through MPIIO");
                                fprintf(stdout,
                                        "\nhints returned from opened file (MPIIO) {\n");
                                ShowHints(&mpiHintsCheck);
                                fprintf(stdout, "}\n");
                        }
                }
                MPI_CHECK(MPI_Barrier(testComm), "barrier error");
        }

        /* this is necessary for resetting various parameters
           needed for reopening and checking the file */
        newlyOpenedFile = TRUE;

        HDF5_CHECK(H5Pclose(createPropList),
                   "cannot close creation property list");
        HDF5_CHECK(H5Pclose(accessPropList),
                   "cannot close access property list");

        /* create property list for serial/parallel access */
        xferPropList = H5Pcreate(H5P_DATASET_XFER);
        HDF5_CHECK(xferPropList, "cannot create transfer property list");

        /* set data transfer mode */
        if (param->collective) {
                HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_COLLECTIVE),
                           "cannot set collective data transfer mode");
        } else {
                HDF5_CHECK(H5Pset_dxpl_mpio
                           (xferPropList, H5FD_MPIO_INDEPENDENT),
                           "cannot set independent data transfer mode");
        }

        /* set up memory data space for transfer */
        memStart[0] = (hsize_t) 0;
        memCount[0] = (hsize_t) 1;
        memStride[0] = (hsize_t) (param->transferSize / sizeof(IOR_size_t));
        memBlock[0] = (hsize_t) (param->transferSize / sizeof(IOR_size_t));
        memDataSpaceDims[0] = (hsize_t) param->transferSize;
        memDataSpace = H5Screate_simple(NUM_DIMS, memDataSpaceDims, NULL);
        HDF5_CHECK(memDataSpace, "cannot create simple memory data space");

        /* define hyperslab for memory data space */
        HDF5_CHECK(H5Sselect_hyperslab(memDataSpace, H5S_SELECT_SET,
                                       memStart, memStride, memCount,
                                       memBlock), "cannot create hyperslab");

        /* set up parameters for fpp or different dataset count */
        if (param->filePerProc) {
                tasksPerDataSet = 1;
        } else {
                if (param->individualDataSets) {
                        /* each task in segment has single data set */
                        tasksPerDataSet = 1;
                } else {
                        /* share single data set across all tasks in segment */
                        tasksPerDataSet = param->numTasks;
                }
        }
        dataSetDims[0] = (hsize_t) ((param->blockSize / sizeof(IOR_size_t))
                                    * tasksPerDataSet);

        /* create a simple data space containing information on size
           and shape of data set, and open it for access */
        dataSpace = H5Screate_simple(NUM_DIMS, dataSetDims, NULL);
        HDF5_CHECK(dataSpace, "cannot create simple data space");

        return (fd);
}
예제 #4
0
파일: file.c 프로젝트: chrismullins/moab
mhdf_FileHandle
mhdf_openFileWithOpt( const char* filename, 
                      int writable, 
                      unsigned long* max_id_out,
                      hid_t id_type,
                      hid_t access_prop,
                      mhdf_Status* status )
{
  FileHandle* file_ptr;
  unsigned int flags;
  hid_t group_id;
  int check_is_hdf5 = 1;
#ifdef HDF5_PARALLEL
  herr_t err;
  MPI_Comm comm;
  MPI_Info info;
#endif
  API_BEGIN;
  
    /* Check if file is HDF5 */
  /* Don't do this because it can't handle MPI-IO driver code that
     passes options via prefixes on the file name. */
#ifdef HDF5_PARALLEL
  if (access_prop != H5P_DEFAULT) {
    err = H5Pget_fapl_mpio( access_prop, &comm, &info );
    if (err >= 0) {
      check_is_hdf5 = 0;
      /* MPI Documentation is inconsistent with regards to whether
         or not the above call dup's these, but my testing with 1.8.3
         indicates that at least for that version they are not.
      MPI_Comm_free(&comm);
      MPI_Info_free(&info); */
    }
  }
#endif
  if (check_is_hdf5 && H5Fis_hdf5( filename ) <= 0) {
    mhdf_setFail( status, "%s: File is not HDF5", filename );
    return NULL;
  }
  
    /* Create struct to hold working data */
  file_ptr = mhdf_alloc_FileHandle( 0, id_type, status );
  if (!file_ptr) {
    mhdf_setFail( status, "Memory allocation failed" );
    return NULL;
  }  

    /* Create the file */
  flags = writable ? H5F_ACC_RDWR : H5F_ACC_RDONLY;
  file_ptr->hdf_handle = H5Fopen( filename, flags, access_prop );
  if (file_ptr->hdf_handle < 0)
  {
    mhdf_setFail( status, "Failed to open file \"%s\"", filename );
    free( file_ptr );
    return NULL;
  }
  
    /* Check for TSTT data in file */
#if defined(H5Gopen_vers) && H5Gopen_vers > 1  
  group_id = H5Gopen2( file_ptr->hdf_handle, ROOT_GROUP, H5P_DEFAULT );
#else
  group_id = H5Gopen( file_ptr->hdf_handle, ROOT_GROUP );
#endif
  if (group_id < 0)
  {
    mhdf_setFail( status, "Invalid file \"%s\"\n", filename );
    H5Fclose( file_ptr->hdf_handle );
    free( file_ptr );
    return NULL;
  }
  H5Gclose( group_id );
  
    /* Get max id */
  if (!scan_for_max_id( file_ptr, status ))
  {
    H5Fclose( file_ptr->hdf_handle );
    mhdf_setFail( status, "Internal error reading file" );
    free( file_ptr );
    return NULL;
  }
  
  if (max_id_out)
    *max_id_out = file_ptr->max_id;
    
  mhdf_setOkay( status );
  API_END_H(1);
  return file_ptr;
}
예제 #5
0
void
phdf5writeAll(char *filename)
{
    hid_t fid1;			/* HDF5 file IDs */
    hid_t acc_tpl1;		/* File access templates */
    hid_t xfer_plist;		/* Dataset transfer properties list */
    hid_t sid1;   		/* Dataspace ID */
    hid_t file_dataspace;	/* File dataspace ID */
    hid_t mem_dataspace;	/* memory dataspace ID */
    hid_t dataset1, dataset2;	/* Dataset ID */
    hsize_t dims1[SPACE1_RANK] =
	{SPACE1_DIM1,SPACE1_DIM2};	/* dataspace dim sizes */
    DATATYPE data_array1[SPACE1_DIM1][SPACE1_DIM2];	/* data buffer */

    hsize_t start[SPACE1_RANK];			/* for hyperslab setting */
    hsize_t count[SPACE1_RANK], stride[SPACE1_RANK];	/* for hyperslab setting */

    herr_t ret;         	/* Generic return value */

    MPI_Comm comm = MPI_COMM_WORLD;
    MPI_Info info = MPI_INFO_NULL;


		/* in support of H5Tuner Test */
		MPI_Comm comm_test = MPI_COMM_WORLD;
		MPI_Info info_test ;
		int i_test, nkeys_test, flag_test;
		char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL+1];
		char *libtuner_file = getenv("LD_PRELOAD");
		/* in support of H5Tuner Test */

    if (verbose)
			printf("Collective write test on file %s\n", filename);

    /* -------------------
     * START AN HDF5 FILE
     * -------------------*/
    /* setup file access template with parallel IO access. */
    acc_tpl1 = H5Pcreate (H5P_FILE_ACCESS);
    assert(acc_tpl1 != FAIL);
    MESG("H5Pcreate access succeed");
    /* set Parallel access with communicator */
    ret = H5Pset_fapl_mpio(acc_tpl1, comm, info);
    assert(ret != FAIL);
    MESG("H5Pset_fapl_mpio succeed");

    /* create the file collectively */
    fid1=H5Fcreate(filename,H5F_ACC_TRUNC,H5P_DEFAULT,acc_tpl1);
    assert(fid1 != FAIL);
    MESG("H5Fcreate succeed");

// ------------------------------------------------
// H5Tuner tests
// ------------------------------------------------

// Retrieve MPI parameters set via the H5Tuner
printf("\n\n--------------------------------------------------\n");
if ( (libtuner_file != NULL) && (strlen(libtuner_file) > 1) ){
	printf("Version of the H5Tuner loaded: \n%s\n", libtuner_file);
}
else {
	printf("No H5Tuner currently loaded.\n");
}
printf("--------------------------------------------------\n");


// Retrieve HDF5 Threshold and Alignment
hsize_t alignment[2];
size_t sieve_buf_size;
alignment[0]= 0; // threshold value
alignment[1]= 0; // alignment value
int ierr = H5Pget_alignment(acc_tpl1, &alignment[0], &alignment[1]);
printf("\n\n--------------------------------------------------\n");
printf("Testing values for Threshold and Alignment\n");
printf("--------------------------------------------------\n");
printf("Test value set to:88 \nRetrieved Threshold=%lu\n", alignment[0]);
printf("Test value set to:44 \nRetrieved Alignment=%lu\n", alignment[1]);
// Check Threshold
if ( alignment[0] == 88 ) {
	printf("PASSED: Threshold Test\n");
}
else {
	printf("FAILED: Threshold Test\n");
}
// Check Alignment
if ( alignment[1] == 44 ) {
	printf("PASSED: Alignment Test\n");
}
else {
	printf("FAILED: Alignment Test\n");
}
printf("--------------------------------------------------\n\n");

// Retrieve HDF5 sieve buffer size
ierr = H5Pget_sieve_buf_size(acc_tpl1, &sieve_buf_size);
printf("\n\n--------------------------------------------------\n");
printf("Testing values for Sieve Buffer Size\n");
printf("--------------------------------------------------\n");
printf("Test value set to:77 \nRetrieved Sieve Buffer Size=%lu\n", sieve_buf_size);
// Check sieve buffer size
if ( (int) sieve_buf_size == 77 ) {
	printf("PASSED: Sieve Buffer Size Test\n");
}
else {
	printf("FAILED: Sieve Buffer Size Test\n");
}
printf("--------------------------------------------------\n\n");

// Retrieve MPI parameters set via the H5Tuner
MPI_Info_create(&info_test);

ret = H5Pget_fapl_mpio(acc_tpl1, &comm_test, &info_test);
assert(ret != FAIL);
MESG("H5Pget_fapl_mpio succeed");


printf("-------------------------------------------------\n" );
printf("Testing parameters values via MPI_Info\n" );
printf("-------------------------------------------------\n" );
if(info_test == MPI_INFO_NULL) {
				printf("MPI info object is null. No keys are available.\n");
}
else {
	MPI_Info_get_nkeys(info_test, &nkeys_test);
	//printf("MPI info has %d keys\n", nkeys_test);
	if (nkeys_test <= 0) {
		printf("MPI info has no keys\n");
	}
	else {
		printf("MPI info has %d keys\n", nkeys_test);
		for ( i_test=0; i_test < nkeys_test; i_test++) {
			MPI_Info_get_nthkey( info_test, i_test, key );
			MPI_Info_get( info_test, key, MPI_MAX_INFO_VAL, value, &flag_test );
			printf( "Retrieved value for key %s is %s\n", key, value );
			//fflush(stdout);
		}
	}
	printf("-------------------------------------------------\n" );
	MPI_Info_free(&info_test);
}
// end of H5Tuner tests
// ---------------------------------------


    /* Release file-access template */
    ret=H5Pclose(acc_tpl1);
    assert(ret != FAIL);


    /* --------------------------
     * Define the dimensions of the overall datasets
     * and create the dataset
     * ------------------------- */
    /* setup dimensionality object */
    sid1 = H5Screate_simple (SPACE1_RANK, dims1, NULL);
    assert (sid1 != FAIL);
    MESG("H5Screate_simple succeed");


    /* create a dataset collectively */
    dataset1 = H5Dcreate2(fid1, DATASETNAME1, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    assert(dataset1 != FAIL);
    MESG("H5Dcreate2 succeed");

    /* create another dataset collectively */
    dataset2 = H5Dcreate2(fid1, DATASETNAME2, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    assert(dataset2 != FAIL);
    MESG("H5Dcreate2 2 succeed");

    /*
     * Set up dimensions of the slab this process accesses.
     */

    /* Dataset1: each process takes a block of rows. */
    slab_set(start, count, stride, BYROW);
		if (verbose)
    	printf("start[]=(%lu,%lu), count[]=(%lu,%lu), total datapoints=%lu\n",
				(unsigned long)start[0], (unsigned long)start[1],
        (unsigned long)count[0], (unsigned long)count[1],
        (unsigned long)(count[0]*count[1]));

    /* create a file dataspace independently */
    file_dataspace = H5Dget_space (dataset1);
    assert(file_dataspace != FAIL);
    MESG("H5Dget_space succeed");
    ret=H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride,
	    count, NULL);
    assert(ret != FAIL);
    MESG("H5Sset_hyperslab succeed");

    /* create a memory dataspace independently */
    mem_dataspace = H5Screate_simple (SPACE1_RANK, count, NULL);
    assert (mem_dataspace != FAIL);

    /* fill the local slab with some trivial data */
    dataset_fill(start, count, stride, &data_array1[0][0]);
    MESG("data_array initialized");
    if (verbose){
			MESG("data_array created");
			dataset_print(start, count, stride, &data_array1[0][0]);
    }

    /* set up the collective transfer properties list */
    xfer_plist = H5Pcreate (H5P_DATASET_XFER);
    assert(xfer_plist != FAIL);
    ret=H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
    assert(ret != FAIL);
    MESG("H5Pcreate xfer succeed");

    /* write data collectively */
    ret = H5Dwrite(dataset1, H5T_NATIVE_INT, mem_dataspace, file_dataspace,
	    xfer_plist, data_array1);
    assert(ret != FAIL);
    MESG("H5Dwrite succeed");

    /* release all temporary handles. */
    /* Could have used them for dataset2 but it is cleaner */
    /* to create them again.*/
    H5Sclose(file_dataspace);
    H5Sclose(mem_dataspace);
    H5Pclose(xfer_plist);

    /* Dataset2: each process takes a block of columns. */
    slab_set(start, count, stride, BYCOL);
		if (verbose)
    	printf("start[]=(%lu,%lu), count[]=(%lu,%lu), total datapoints=%lu\n",
				(unsigned long)start[0], (unsigned long)start[1],
        (unsigned long)count[0], (unsigned long)count[1],
        (unsigned long)(count[0]*count[1]));

    /* put some trivial data in the data_array */
    dataset_fill(start, count, stride, &data_array1[0][0]);
    MESG("data_array initialized");
    if (verbose){
			MESG("data_array created");
			dataset_print(start, count, stride, &data_array1[0][0]);
    }

    /* create a file dataspace independently */
    file_dataspace = H5Dget_space (dataset1);
    assert(file_dataspace != FAIL);
    MESG("H5Dget_space succeed");
    ret=H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride,
	    count, NULL);
    assert(ret != FAIL);
    MESG("H5Sset_hyperslab succeed");

    /* create a memory dataspace independently */
    mem_dataspace = H5Screate_simple (SPACE1_RANK, count, NULL);
    assert (mem_dataspace != FAIL);

    /* fill the local slab with some trivial data */
    dataset_fill(start, count, stride, &data_array1[0][0]);
    MESG("data_array initialized");
    if (verbose){
			MESG("data_array created");
			dataset_print(start, count, stride, &data_array1[0][0]);
    }

    /* set up the collective transfer properties list */
    xfer_plist = H5Pcreate (H5P_DATASET_XFER);
    assert(xfer_plist != FAIL);
    ret=H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
    assert(ret != FAIL);
    MESG("H5Pcreate xfer succeed");

    /* write data independently */
    ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace,
	    xfer_plist, data_array1);
    assert(ret != FAIL);
    MESG("H5Dwrite succeed");

    /* release all temporary handles. */
    H5Sclose(file_dataspace);
    H5Sclose(mem_dataspace);
    H5Pclose(xfer_plist);


    /*
     * All writes completed.  Close datasets collectively
     */
    ret=H5Dclose(dataset1);
    assert(ret != FAIL);
    MESG("H5Dclose1 succeed");
    ret=H5Dclose(dataset2);
    assert(ret != FAIL);
    MESG("H5Dclose2 succeed");

    /* release all IDs created */
    H5Sclose(sid1);

    /* close the file collectively */
    H5Fclose(fid1);
}