Esempio n. 1
0
asynStatus NDFileHDF5Dataset::flushDataset()
{
  static const char *functionName = "flushDataset";
  // flushDataset is a no-op if the HDF version doesn't support it
  #if H5_VERSION_GE(1,9,178)

  herr_t hdfstatus;

  // Flush the dataset
  hdfstatus = H5Dflush(this->dataset_);
  if (hdfstatus){
    asynPrint(this->pAsynUser_, ASYN_TRACE_ERROR, 
              "%s::%s ERROR Unable to flush the dataset [%s]\n", 
              fileName, functionName, this->name_.c_str());
    return asynError;
  }
  #else
  // If this is called when we do not support SWMR then someone has done something
  // bad, so return an asynError
  asynPrint(this->pAsynUser_, ASYN_TRACE_ERROR,
            "%s::%s SWMR dataset flush attempted but the library compiled against doesn't support it.\n",
            fileName, functionName);
  return asynError;
  #endif

  return asynSuccess;  
}
Esempio n. 2
0
asynStatus NDFileHDF5AttributeDataset::flushDataset()
{
  asynStatus status = asynSuccess;

  // We cannot flush for SWMR if the HDF version doesn't support it
  #if H5_VERSION_GE(1,9,178)

  // Flush the dataset
  H5Dflush(dataset_);
  #else
  status = asynError;
  #endif

  return status;
}
Esempio n. 3
0
/*-------------------------------------------------------------------------
 * Function:    test_flush
 *
 * Purpose:     This function tests flushing individual objects' metadata
 *              from the metadata cache.
 *
 * Return:      0 on Success, 1 on Failure
 *
 * Programmer:  Mike McGreevy
 *              July 1, 2010
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t test_flush(void) 
{
    /**************************************************************************
     *
     * Test Description:
     *
     * This test will build an HDF5 file with several objects in a varying 
     * hierarchical layout. It will then attempt to flush the objects
     * in the file one by one, individually, using the four H5*flush
     * routines (D,G,T, and O). After each call to either create or flush an 
     * object, a series of verifications will occur on each object in the file.
     *
     * Each verification consists of spawning off a new process and determining
     * if the object can be opened and its information retreived in said 
     * alternate process. It reports the results, which are compared to an 
     * expected value (either that the object can be found on disk, or that it
     * cannot).
     *
     * Note that to spawn a verification, this program sends a signal (by creating
     * a file on disk) to the test script controlling it, indicating how to 
     * run the verification.
     * 
     * Implementation is funky, but basically, an example: 
     *
     * Step 1. Dataset is created.
     * Step 2. Verify that dataset can't be opened by separate process, as
     *         it should not have been flushed to disk yet.
     * Step 3. Group is created.
     * Step 4. Verify that group can't be opened by separate process.
     * Step 5. H5Gflush is called on the group.
     * Step 6. Verify that group CAN be opened, but dataset still has
     *         yet to hit disk, and CANNOT be opened. Success! Only the group 
     *         was flushed.
     *
     **************************************************************************/

    /**************************************************************************
      * Generated Test File will look like this:
      * 
      * GROUP "/"
      *   DATASET "Dataset1"
      *   GROUP "Group1" {
      *     DATASET "Dataset2"
      *     GROUP "Group2" {
      *       DATATYPE "CommittedDatatype3"
      *     }
      *   }
      *   GROUP "Group3" {
      *     DATASET "Dataset3"
      *     DATATYPE "CommittedDatatype2"
      *   }
      *   DATATYPE "CommittedDatatype1"
     **************************************************************************/

    /* Variables */
    hid_t fid,gid,gid2,gid3,sid,tid1,tid2,tid3,did,did2,did3,rid,fapl,status = 0;
    hsize_t dims[2] = {3,5};

    /* Testing Message */
    HDfprintf(stdout, "Testing individual object flush behavior:\n");

    /* Cleanup any old error or signal files */
    CLEANUP_FILES;
    
    /* ================ */
    /* CREATE TEST FILE */
    /* ================ */

    /* Create file, open root group - have to use latest file format for SWMR */
    if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) TEST_ERROR;
    if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) TEST_ERROR; 
    if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
    if ((rid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create data space and types */
    if ((sid = H5Screate_simple(2, dims, dims)) < 0) TEST_ERROR;
    if ((tid1 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
    if ((tid2 = H5Tcopy(H5T_NATIVE_CHAR)) < 0) TEST_ERROR;
    if ((tid3 = H5Tcopy(H5T_NATIVE_LONG)) < 0) TEST_ERROR;

    /* Create Group1 */
    if ((gid = H5Gcreate2(fid, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create Group2 */
    if ((gid2 = H5Gcreate2(gid, "Group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create Group3 */
    if ((gid3 = H5Gcreate2(fid, "Group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create Dataset1 */
    if ((did = H5Dcreate2(fid, "Dataset1", tid1, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create Dataset2 */
    if ((did2 = H5Dcreate2(gid, "Dataset2", tid3, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create Dataset3 */
    if ((did3 = H5Dcreate2(gid3, "Dataset3", tid2, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create CommittedDatatype1 */
    if ((status = H5Tcommit2(fid, "CommittedDatatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create CommittedDatatype2 */
    if ((status = H5Tcommit2(gid2, "CommittedDatatype2", tid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Create CommittedDatatype3 */
    if ((status = H5Tcommit2(gid3, "CommittedDatatype3", tid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;

    /* ============ */
    /* FLUSH GROUPS */
    /* ============ */

    /* Test */
    TESTING("to ensure H5Gflush correctly flushes single groups");

    /* First, let's verify that nothing is currently flushed. */
    if (run_flush_verification_process(RG, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    /* Then, flush the root group and verify it's the only thing on disk */
    if ((status = H5Gflush(rid)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    /* Flush Group1 and Verify it is recently flushed, and nothing 
     * else has changed. */
    if ((status = H5Gflush(gid)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    /* Flush Group2 and Verify it is recently flushed, and nothing 
     * else has changed. */
    if ((status = H5Gflush(gid2)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    PASSED();

    /* ============== */
    /* FLUSH DATASETS */
    /* ============== */

    /* Test */
    TESTING("to ensure H5Dflush correctly flushes single datasets");

    /* Flush Dataset1 and verify it's the only thing that hits disk. */
    if ((status = H5Dflush(did)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    /* Flush Dataset2 and verify it's the only thing that hits disk. */
    if ((status = H5Dflush(did2)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    PASSED();

    /* =============== */
    /* FLUSH DATATYPES */
    /* =============== */

    /* Test */
    TESTING("to ensure H5Tflush correctly flushes single datatypes");

    /* Flush Datatype 1 and verify it's the only thing that hits disk. */
    if ((status = H5Tflush(tid1)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    /* Flush Datatype 2 and verify it's the only thing that hits disk. */
    if ((status = H5Tflush(tid2)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    PASSED();
    
    /* ============= */
    /* FLUSH OBJECTS */
    /* ============= */

    /* Test */
    TESTING("to ensure H5Oflush correctly flushes single objects");

    /* Flush Group3 and verify it's the only thing that hits disk. */
    if ((status = H5Oflush(gid3)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    /* Flush Dataset3 and verify it's the only thing that hits disk. */
    if ((status = H5Oflush(did3)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR;

    /* Flush CommittedDatatype3 and verify it's the only thing that hits disk. */
    if ((status = H5Oflush(tid3)) < 0) TEST_ERROR;
    if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(G3, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(D3, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T2, FLUSHED) != 0) TEST_ERROR;
    if (run_flush_verification_process(T3, FLUSHED) != 0) TEST_ERROR;

    PASSED();

    /* ================== */
    /* Cleanup and Return */  
    /* ================== */
    if (H5Pclose(fapl) < 0) TEST_ERROR;
    if (H5Gclose(gid) < 0) TEST_ERROR;
    if (H5Gclose(gid2) < 0) TEST_ERROR;
    if (H5Dclose(did) < 0) TEST_ERROR;
    if (H5Dclose(did2) < 0) TEST_ERROR;
    if (H5Gclose(rid) < 0) TEST_ERROR;
    if (H5Fclose(fid) < 0) TEST_ERROR;

    /* Delete test file */
    HDremove(FILENAME);

    if (end_verification() < 0) TEST_ERROR;

    return SUCCEED;

error:
    return FAIL;

} /* end test_flush */
Esempio n. 4
0
/* 
 * Append planes, each of (1,2*chunksize,2*chunksize) to the dataset.
 * In other words, 4 chunks are appended to the dataset at a time.
 * Fill each plane with the plane number and then write it at the nth plane.
 * Increase the plane number and repeat till the end of dataset, when it
 * reaches chunksize long. End product is a (2*chunksize)^3 cube.
 *
 * Return: 0 succeed; -1 fail.
 */
static int 
write_file(void)
{
    hid_t	fid;          	/* File ID for new HDF5 file */
    hid_t	dsid;         	/* dataset ID */
    hid_t       fapl;         	/* File access property list */
    hid_t	dcpl;      	/* Dataset creation property list */
    char	*name;
    UC_CTYPE	*buffer, *bufptr;	/* data buffer */
    hsize_t	cz=chunksize_g;		/* Chunk size */
    hid_t	f_sid;	    	/* dataset file space id */
    hid_t	m_sid;	    	/* memory space id */
    int		rank;	    	/* rank */
    hsize_t 	chunk_dims[3];	/* Chunk dimensions */
    hsize_t	dims[3];    	/* Dataspace dimensions */
    hsize_t	memdims[3]; 	/* Memory space dimensions */
    hsize_t	start[3] = {0,0,0}, count[3];    /* Hyperslab selection values */
    hbool_t 	disabled;   	/* Object's disabled status */	
    hsize_t     i, j, k;

    name = filename_g;

    /* Open the file */
    if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
        return -1;
    if(use_swmr_g)
        if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
            return -1;
    if((fid = H5Fopen(name, H5F_ACC_RDWR | (use_swmr_g ? H5F_ACC_SWMR_WRITE : 0), fapl)) < 0){
	fprintf(stderr, "H5Fopen failed\n");
        return -1;
    }

    /* Open the dataset of the program name */
    if((dsid = H5Dopen2(fid, progname_g, H5P_DEFAULT)) < 0){
	fprintf(stderr, "H5Dopen2 failed\n");
	return -1;
    }

    /* Disabled mdc flushed for the dataset */
    if(H5Odisable_mdc_flushes(dsid) < 0) {
	fprintf(stderr, "H5Odisable_mdc_flushes failed\n");
	return -1;
    }

    /* Get mdc disabled status of the dataset */
    if(H5Oare_mdc_flushes_disabled(dsid, &disabled) < 0) {
	fprintf(stderr, "H5Oare_mdc_flushes_disabled failed\n");
	return -1;
    } else if(disabled)
	printf("Dataset has disabled mdc flushes.\n");
    else
	printf("Dataset should have disabled its mdc flushes.\n");

    /* Find chunksize used */
    if ((dcpl = H5Dget_create_plist(dsid)) < 0){
	fprintf(stderr, "H5Dget_create_plist failed\n");
	return -1;
    }
    if (H5D_CHUNKED != H5Pget_layout(dcpl)){
	fprintf(stderr, "storage layout is not chunked\n");
	return -1;
    }
    if ((rank = H5Pget_chunk(dcpl, 3, chunk_dims)) != 3){
	fprintf(stderr, "storage rank is not 3\n");
	return -1;
    }

    /* verify chunk_dims against set paramenters */
    if (chunk_dims[0]!= chunkdims_g[0] || chunk_dims[1] != cz || chunk_dims[2] != cz){
	fprintf(stderr, "chunk size is not as expected. Got dims=(%llu,%llu,%llu)\n",
	    (unsigned long long)chunk_dims[0], (unsigned long long)chunk_dims[1], 
            (unsigned long long)chunk_dims[2]);
	return -1;
    }

    /* allocate space for data buffer 1 X dims[1] X dims[2] of UC_CTYPE */
    memdims[0]=1;
    memdims[1] = dims_g[1];
    memdims[2] = dims_g[2];
    if ((buffer=(UC_CTYPE*)HDmalloc((size_t)memdims[1]*(size_t)memdims[2]*sizeof(UC_CTYPE)))==NULL) {
	fprintf(stderr, "malloc: failed\n");
	return -1;
    };

    /*
     * Get dataset rank and dimension.
     */
    f_sid = H5Dget_space(dsid);    /* Get filespace handle first. */
    rank  = H5Sget_simple_extent_ndims(f_sid);
    if (rank != UC_RANK){
	fprintf(stderr, "rank(%d) of dataset does not match\n", rank);
	return -1;
    }
    if (H5Sget_simple_extent_dims(f_sid, dims, NULL) < 0){
	fprintf(stderr, "H5Sget_simple_extent_dims got error\n");
	return -1;
    }
    printf("dataset rank %d, dimensions %llu x %llu x %llu\n",
	   rank, (unsigned long long)(dims[0]), (unsigned long long)(dims[1]), 
           (unsigned long long)(dims[2]));
    /* verify that file space dims are as expected and are consistent with memory space dims */
    if (dims[0] != 0 || dims[1] != memdims[1] || dims[2] != memdims[2]){
	fprintf(stderr, "dataset is not empty. Got dims=(%llu,%llu,%llu)\n",
	    (unsigned long long)dims[0], (unsigned long long)dims[1], 
            (unsigned long long)dims[2]);
	return -1;
    }
    
    /* setup mem-space for buffer */
    if ((m_sid=H5Screate_simple(rank, memdims, NULL))<0){
	fprintf(stderr, "H5Screate_simple for memory failed\n");
	return -1;
    };

    /* write planes */
    count[0]=1;
    count[1]=dims[1];
    count[2]=dims[2];
    for (i=0; i<nplanes_g; i++){
	/* fill buffer with value i+1 */
	bufptr = buffer;
	for (j=0; j<dims[1]; j++)
	    for (k=0; k<dims[2]; k++)
		*bufptr++ = i;

	/* extend the dataset by one for new plane */
	dims[0]=i+1;
        if(H5Dset_extent(dsid, dims) < 0){
	    fprintf(stderr, "H5Dset_extent failed\n");
            return -1;
	}

        /* Get the dataset's dataspace */
        if((f_sid = H5Dget_space(dsid)) < 0){
	    fprintf(stderr, "H5Dset_extent failed\n");
            return -1;
	}

	start[0]=i;
        /* Choose the next plane to write */
        if(H5Sselect_hyperslab(f_sid, H5S_SELECT_SET, start, NULL, count, NULL) < 0){
	    fprintf(stderr, "Failed H5Sselect_hyperslab\n");
            return -1;
	}

        /* Write plane to the dataset */
        if(H5Dwrite(dsid, UC_DATATYPE, m_sid, f_sid, H5P_DEFAULT, buffer) < 0){
	    fprintf(stderr, "Failed H5Dwrite\n");
            return -1;
	}

	/* Flush the dataset for every "chunkplanes_g" planes */
	if(!((i + 1) % (hsize_t)chunkplanes_g)) {
	    if(H5Dflush(dsid) < 0) {
		fprintf(stderr, "Failed to H5Dflush dataset\n");
		return -1;
	    }
	}
    }

    if(H5Dflush(dsid) < 0) {
	fprintf(stderr, "Failed to H5Dflush dataset\n");
	return -1;
    }

    /* Enable mdc flushes for the dataset */
    /* Closing the dataset later will enable mdc flushes automatically if this is not done */
    if(disabled)
	if(H5Oenable_mdc_flushes(dsid) < 0) {
	    fprintf(stderr, "Failed to H5Oenable_mdc_flushes\n");
	    return -1;
	}

    /* Done writing. Free/Close all resources including data file */
    HDfree(buffer);

    if(H5Dclose(dsid) < 0){
	fprintf(stderr, "Failed to close datasete\n");
	return -1;
    }
    if(H5Sclose(m_sid) < 0){
	fprintf(stderr, "Failed to close memory space\n");
	return -1;
    }
    if(H5Sclose(f_sid) < 0){
	fprintf(stderr, "Failed to close file space\n");
	return -1;
    }
    if(H5Pclose(fapl) < 0){
	fprintf(stderr, "Failed to property list\n");
	return -1;
    }
    if(H5Fclose(fid) < 0){
	fprintf(stderr, "Failed to close file id\n");
	return -1;
    }

    return 0;
} /* write_file() */
Esempio n. 5
0
/*-------------------------------------------------------------------------
 * Function:    H5DOappend()
 *
 * Purpose:     To append elements to a dataset.
 *
 *      axis:       the dataset dimension (zero-based) for the append
 *      extension:  the # of elements to append for the axis-th dimension
 *      memtype:    the datatype
 *      buf:        buffer with data for the append
 *
 * Return:      Non-negative on success/Negative on failure
 *
 * Programmer:  Vailin Choi; Jan 2014
 *
 * Note:
 * 	This routine is copied from the fast forward feature branch: features/hdf5_ff
 *	src/H5FF.c:H5DOappend() with the following modifications:
 * 	1) Remove and replace macro calls such as
 *		FUNC_ENTER_API, H5TRACE, HGOTO_ERROR 
 * 	   accordingly because hl does not have these macros
 *	2) Replace H5I_get_type() by H5Iget_type()
 *	3) Replace H5P_isa_class() by H5Pisa_class()
 *	4) Fix a bug in the following: replace extension by size[axis]
 *		if(extension < old_size) {
 *		  ret_value = FAIL;
 *		  goto done;
 *   		}
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, 
           hid_t memtype, const void *buf)
{
    hbool_t created_dxpl = FALSE;       /* Whether we created a DXPL */
    hsize_t size[H5S_MAX_RANK];		/* The new size (after extension */
    hsize_t old_size = 0; 		/* The size of the dimension to be extended */
    int sndims; 			/* Number of dimensions in dataspace (signed) */
    unsigned ndims; 			/* Number of dimensions in dataspace */
    hid_t space_id = FAIL; 		/* Old file space */
    hid_t new_space_id = FAIL; 		/* New file space (after extension) */
    hid_t mem_space_id = FAIL; 		/* Memory space for data buffer */
    hssize_t snelmts; 			/* Number of elements in selection (signed) */
    hsize_t nelmts; 			/* Number of elements in selection */
    hid_t dapl = FAIL;			/* Dataset access property list */

    hsize_t start[H5S_MAX_RANK];	/* H5Sselect_Hyperslab: starting offset */
    hsize_t count[H5S_MAX_RANK];	/* H5Sselect_hyperslab: # of blocks to select */
    hsize_t stride[H5S_MAX_RANK];	/* H5Sselect_hyperslab: # of elements to move when selecting */
    hsize_t block[H5S_MAX_RANK];	/* H5Sselect_hyperslab: # of elements in a block */

    hsize_t *boundary = NULL;		/* Boundary set in append flush property */
    H5D_append_cb_t append_cb;		/* Callback function set in append flush property */
    void *udata;			/* User data set in append flush property */
    hbool_t hit = FALSE;		/* Boundary is hit or not */
    hsize_t k;				/* Local index variable */
    unsigned u; 		        /* Local index variable */
    herr_t ret_value = FAIL;		/* Return value */

    /* check arguments */
    if(H5I_DATASET != H5Iget_type(dset_id))
        goto done;

    /* If the user passed in a default DXPL, create one to pass to H5Dwrite() */
    if(H5P_DEFAULT == dxpl_id) {
        if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
            goto done;
        created_dxpl = TRUE;
    } /* end if */
    else if(TRUE != H5Pisa_class(dxpl_id, H5P_DATASET_XFER))
        goto done;

    /* Get the dataspace of the dataset */
    if(FAIL == (space_id = H5Dget_space(dset_id)))
        goto done;

    /* Get the rank of this dataspace */
    if((sndims = H5Sget_simple_extent_ndims(space_id)) < 0)
        goto done;
    ndims = (unsigned)sndims;

    /* Verify correct axis */
    if(axis >= ndims)
        goto done;

    /* Get the dimensions sizes of the dataspace */
    if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0)
        goto done;

    /* Adjust the dimension size of the requested dimension, 
     * but first record the old dimension size
     */
    old_size = size[axis];
    size[axis] += extension;
    if(size[axis] < old_size)
        goto done;

    /* Set the extent of the dataset to the new dimension */
    if(H5Dset_extent(dset_id, size) < 0)
        goto done;

    /* Get the new dataspace of the dataset */
    if(FAIL == (new_space_id = H5Dget_space(dset_id)))
        goto done;

    /* Select a hyperslab corresponding to the append operation */
    for(u = 0 ; u < ndims ; u++) {
        start[u] = 0;
        stride[u] = 1;
        count[u] = size[u];
        block[u] = 1;
        if(u == axis) {
            count[u] = extension;
            start[u] = old_size;
        } /* end if */
    } /* end for */
    if(FAIL == H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, start, stride, count, block))
        goto done;

    /* The # of elemnts in the new extended dataspace */
    if((snelmts = H5Sget_select_npoints(new_space_id)) < 0)
        goto done;
    nelmts = (hsize_t)snelmts;

    /* create a memory space */
    if(FAIL == (mem_space_id = H5Screate_simple(1, &nelmts, NULL)))
        goto done;

    /* Write the data */
    if(H5Dwrite(dset_id, memtype, mem_space_id, new_space_id, dxpl_id, buf) < 0)
        goto done;

    /* Obtain the dataset's access property list */
    if((dapl = H5Dget_access_plist(dset_id)) < 0)
        goto done;

    /* Allocate the boundary array */
    boundary = (hsize_t *)HDmalloc(ndims * sizeof(hsize_t));

    /* Retrieve the append flush property */
    if(H5Pget_append_flush(dapl, ndims, boundary, &append_cb, &udata) < 0)
        goto done;

    /* No boundary for this axis */
    if(boundary[axis] != 0) {

        /* Determine whether a boundary is hit or not */
        for(k = start[axis]; k < size[axis]; k++)
            if(!((k + 1) % boundary[axis])) {
                hit = TRUE;
                break;
            }

        if(hit) { /* Hit the boundary */
            /* Invoke callback if there is one */
            if(append_cb && append_cb(dset_id, size, udata) < 0)
                goto done;

	        /* Do a dataset flush */
            if(H5Dflush(dset_id) < 0)
                goto done;
        } /* end if */
    } /* end if */

    /* Indicate success */
    ret_value = SUCCEED;

done:
    /* Close dxpl if we created it vs. one was passed in */
    if(created_dxpl) {
        if(H5Pclose(dxpl_id) < 0)
            ret_value = FAIL;
    } /* end if */

    /* Close old dataspace */
    if(space_id != FAIL && H5Sclose(space_id) < 0)
        ret_value = FAIL;

    /* Close new dataspace */
    if(new_space_id != FAIL && H5Sclose(new_space_id) < 0)
        ret_value = FAIL;

    /* Close memory dataspace */
    if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
        ret_value = FAIL;

    /* Close the dataset access property list */
    if(dapl != FAIL && H5Pclose(dapl) < 0)
        ret_value = FAIL;

    if(boundary)
        HDfree(boundary);

    return ret_value;
} /* H5DOappend() */