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; }
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; }
/*------------------------------------------------------------------------- * 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 */
/* * 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() */
/*------------------------------------------------------------------------- * 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() */