/*------------------------------------------------------------------------- * Function: test_direct * * Purpose: Tests the file handle interface for DIRECT I/O driver * * Return: Success: 0 * Failure: -1 * * Programmer: Raymond Lu * Wednesday, 20 September 2006 * *------------------------------------------------------------------------- */ static herr_t test_direct(void) { #ifdef H5_HAVE_DIRECT hid_t file=(-1), fapl, access_fapl = -1; hid_t dset1=-1, dset2=-1, space1=-1, space2=-1; char filename[1024]; int *fhandle=NULL; hsize_t file_size; hsize_t dims1[2], dims2[1]; size_t mbound; size_t fbsize; size_t cbsize; int *points, *check, *p1, *p2; int wdata2[DSET2_DIM] = {11,12,13,14}; int rdata2[DSET2_DIM]; int i, j, n; #endif /*H5_HAVE_DIRECT*/ TESTING("Direct I/O file driver"); #ifndef H5_HAVE_DIRECT SKIPPED(); return 0; #else /*H5_HAVE_DIRECT*/ /* Set property list and file name for Direct driver. Set memory alignment boundary * and file block size to 512 which is the minimum for Linux 2.6. */ fapl = h5_fileaccess(); if(H5Pset_fapl_direct(fapl, MBOUNDARY, FBSIZE, CBSIZE) < 0) TEST_ERROR; h5_fixname(FILENAME[5], fapl, filename, sizeof filename); /* Verify the file access properties */ if(H5Pget_fapl_direct(fapl, &mbound, &fbsize, &cbsize) < 0) TEST_ERROR; if(mbound != MBOUNDARY || fbsize != FBSIZE || cbsize != CBSIZE) TEST_ERROR; if(H5Pset_alignment(fapl, (hsize_t)THRESHOLD, (hsize_t)FBSIZE) < 0) TEST_ERROR; H5E_BEGIN_TRY { file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); } H5E_END_TRY; if(file<0) { H5Pclose (fapl); SKIPPED(); printf(" Probably the file system doesn't support Direct I/O\n"); return 0; } /* Retrieve the access property list... */ if ((access_fapl = H5Fget_access_plist(file)) < 0) TEST_ERROR; /* ...and close the property list */ if (H5Pclose(access_fapl) < 0) TEST_ERROR; /* Check file handle API */ if(H5Fget_vfd_handle(file, H5P_DEFAULT, (void **)&fhandle) < 0) TEST_ERROR; if(*fhandle<0) TEST_ERROR; /* Check file size API */ if(H5Fget_filesize(file, &file_size) < 0) TEST_ERROR; /* There is no guarantee of the number of metadata allocations, but it's * 4 currently and the size of the file should be between 3 & 4 file buffer * sizes.. */ if(file_size < (FBSIZE * 3) || file_size >= (FBSIZE * 4)) TEST_ERROR; /* Allocate aligned memory for data set 1. For data set 1, everything is aligned including * memory address, size of data, and file address. */ if(posix_memalign(&points, (size_t)FBSIZE, (size_t)(DSET1_DIM1*DSET1_DIM2*sizeof(int)))!=0) TEST_ERROR; if(posix_memalign(&check, (size_t)FBSIZE, (size_t)(DSET1_DIM1*DSET1_DIM2*sizeof(int)))!=0) TEST_ERROR; /* Initialize the dset1 */ p1 = points; for(i = n = 0; i < DSET1_DIM1; i++) for(j = 0; j < DSET1_DIM2; j++) *p1++ = n++; /* Create the data space1 */ dims1[0] = DSET1_DIM1; dims1[1] = DSET1_DIM2; if((space1 = H5Screate_simple(2, dims1, NULL)) < 0) TEST_ERROR; /* Create the dset1 */ if((dset1 = H5Dcreate2(file, DSET1_NAME, H5T_NATIVE_INT, space1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Write the data to the dset1 */ if(H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, points) < 0) TEST_ERROR; if(H5Dclose(dset1) < 0) TEST_ERROR; if((dset1 = H5Dopen2(file, DSET1_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; /* Read the data back from dset1 */ if(H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, check) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ p1 = points; p2 = check; for(i = 0; i < DSET1_DIM1; i++) for(j = 0; j < DSET1_DIM2; j++) if(*p1++ != *p2++) { H5_FAILED(); printf(" Read different values than written in data set 1.\n"); printf(" At index %d,%d\n", i, j); TEST_ERROR; } /* end if */ /* Create the data space2. For data set 2, memory address and data size are not aligned. */ dims2[0] = DSET2_DIM; if((space2 = H5Screate_simple(1, dims2, NULL)) < 0) TEST_ERROR; /* Create the dset2 */ if((dset2 = H5Dcreate2(file, DSET2_NAME, H5T_NATIVE_INT, space2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Write the data to the dset1 */ if(H5Dwrite(dset2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata2) < 0) TEST_ERROR; if(H5Dclose(dset2) < 0) TEST_ERROR; if((dset2 = H5Dopen2(file, DSET2_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; /* Read the data back from dset1 */ if(H5Dread(dset2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata2) < 0) TEST_ERROR; /* Check that the values read are the same as the values written */ for(i = 0; i < DSET2_DIM; i++) if(wdata2[i] != rdata2[i]) { H5_FAILED(); printf(" Read different values than written in data set 2.\n"); printf(" At index %d\n", i); TEST_ERROR; } /* end if */ if(H5Sclose(space1) < 0) TEST_ERROR; if(H5Dclose(dset1) < 0) TEST_ERROR; if(H5Sclose(space2) < 0) TEST_ERROR; if(H5Dclose(dset2) < 0) TEST_ERROR; if(H5Fclose(file) < 0) TEST_ERROR; if(points) free(points); if(check) free(check); h5_cleanup(FILENAME, fapl); PASSED(); return 0; error: H5E_BEGIN_TRY { H5Pclose (fapl); H5Sclose(space1); H5Dclose(dset1); H5Sclose(space2); H5Dclose(dset2); H5Fclose(file); } H5E_END_TRY; return -1; #endif /*H5_HAVE_DIRECT*/ }
herr_t pt_H5Pset_fapl_direct(hid_t fapl_id, size_t alignment, size_t block_size, size_t cbuf_size) { return H5Pset_fapl_direct(fapl_id, alignment, block_size, cbuf_size); }
/*------------------------------------------------------------------------- * Function: h5_fileaccess * * Purpose: Returns a file access template which is the default template * but with a file driver set according to the constant or * environment variable HDF5_DRIVER * * Return: Success: A file access property list * * Failure: -1 * * Programmer: Robb Matzke * Thursday, November 19, 1998 * * Modifications: * *------------------------------------------------------------------------- */ hid_t h5_fileaccess(void) { const char *val = NULL; const char *name; char s[1024]; hid_t fapl = -1; /* First use the environment variable, then the constant */ val = HDgetenv("HDF5_DRIVER"); #ifdef HDF5_DRIVER if (!val) val = HDF5_DRIVER; #endif if ((fapl=H5Pcreate(H5P_FILE_ACCESS))<0) return -1; if (!val || !*val) return fapl; /*use default*/ HDstrncpy(s, val, sizeof s); s[sizeof(s)-1] = '\0'; if (NULL==(name=HDstrtok(s, " \t\n\r"))) return fapl; if (!HDstrcmp(name, "sec2")) { /* Unix read() and write() system calls */ if (H5Pset_fapl_sec2(fapl)<0) return -1; } else if (!HDstrcmp(name, "stdio")) { /* Standard C fread() and fwrite() system calls */ if (H5Pset_fapl_stdio(fapl)<0) return -1; } else if (!HDstrcmp(name, "core")) { /* In-memory driver settings (backing store on, 1 MB increment) */ if (H5Pset_fapl_core(fapl, (size_t)1, TRUE)<0) return -1; } else if (!HDstrcmp(name, "core_paged")) { /* In-memory driver with write tracking and paging on */ if (H5Pset_fapl_core(fapl, (size_t)1, TRUE)<0) return -1; if (H5Pset_core_write_tracking(fapl, TRUE, (size_t)4096)<0) return -1; } else if (!HDstrcmp(name, "split")) { /* Split meta data and raw data each using default driver */ if (H5Pset_fapl_split(fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT)<0) return -1; } else if (!HDstrcmp(name, "multi")) { /* Multi-file driver, general case of the split driver */ H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; hid_t memb_fapl[H5FD_MEM_NTYPES]; const char *memb_name[H5FD_MEM_NTYPES]; char sv[H5FD_MEM_NTYPES][1024]; haddr_t memb_addr[H5FD_MEM_NTYPES]; H5FD_mem_t mt; HDmemset(memb_map, 0, sizeof memb_map); HDmemset(memb_fapl, 0, sizeof memb_fapl); HDmemset(memb_name, 0, sizeof memb_name); HDmemset(memb_addr, 0, sizeof memb_addr); HDassert(HDstrlen(multi_letters)==H5FD_MEM_NTYPES); for(mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, mt)) { memb_fapl[mt] = H5P_DEFAULT; sprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); memb_name[mt] = sv[mt]; memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10); } /* end for */ if (H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE)<0) { return -1; } } else if (!HDstrcmp(name, "family")) { hsize_t fam_size = 100*1024*1024; /*100 MB*/ /* Family of files, each 1MB and using the default driver */ if ((val=HDstrtok(NULL, " \t\n\r"))) fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024); if (H5Pset_fapl_family(fapl, fam_size, H5P_DEFAULT)<0) return -1; } else if (!HDstrcmp(name, "log")) { unsigned log_flags = H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC; /* Log file access */ if ((val = HDstrtok(NULL, " \t\n\r"))) log_flags = (unsigned)HDstrtol(val, NULL, 0); if (H5Pset_fapl_log(fapl, NULL, log_flags, (size_t)0) < 0) return -1; } else if (!HDstrcmp(name, "direct")) { #ifdef H5_HAVE_DIRECT /* Linux direct read() and write() system calls. Set memory boundary, file block size, * and copy buffer size to the default values. */ if (H5Pset_fapl_direct(fapl, 1024, 4096, 8*4096)<0) return -1; #endif } else if(!HDstrcmp(name, "latest")) { /* use the latest format */ if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) return -1; } else { /* Unknown driver */ return -1; } return fapl; }
hid_t set_vfd(parameters *param) { hid_t my_fapl = -1; vfdtype vfd; vfd = param->vfd; if ((my_fapl=H5Pcreate(H5P_FILE_ACCESS))<0) return -1; if (vfd == sec2) { /* Unix read() and write() system calls */ if (H5Pset_fapl_sec2(my_fapl)<0) return -1; } else if (vfd == stdio) { /* Standard C fread() and fwrite() system calls */ if (H5Pset_fapl_stdio(my_fapl)<0) return -1; } else if (vfd == core) { /* In-core temporary file with 1MB increment */ if (H5Pset_fapl_core(my_fapl, (size_t)1024*1024, TRUE)<0) return -1; } else if (vfd == split) { /* Split meta data and raw data each using default driver */ if (H5Pset_fapl_split(my_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT)<0) return -1; } else if (vfd == multi) { /* Multi-file driver, general case of the split driver */ H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; hid_t memb_fapl[H5FD_MEM_NTYPES]; const char *memb_name[H5FD_MEM_NTYPES]; char sv[H5FD_MEM_NTYPES][1024]; haddr_t memb_addr[H5FD_MEM_NTYPES]; H5FD_mem_t mt; HDmemset(memb_map, 0, sizeof memb_map); HDmemset(memb_fapl, 0, sizeof memb_fapl); HDmemset(memb_name, 0, sizeof memb_name); HDmemset(memb_addr, 0, sizeof memb_addr); HDassert(HDstrlen(multi_letters)==H5FD_MEM_NTYPES); for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,mt)) { memb_fapl[mt] = H5P_DEFAULT; sprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); memb_name[mt] = sv[mt]; memb_addr[mt] = (haddr_t)MAX(mt - 1,0) * (HADDR_MAX / 10); } if (H5Pset_fapl_multi(my_fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE)<0) { return -1; } } else if (vfd == family) { hsize_t fam_size = 1*1024*1024; /*100 MB*/ /* Family of files, each 1MB and using the default driver */ /* if ((val=HDstrtok(NULL, " \t\n\r"))) fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024); */ if (H5Pset_fapl_family(my_fapl, fam_size, H5P_DEFAULT)<0) return -1; } else if (vfd == direct) { #ifdef H5_HAVE_DIRECT /* Linux direct read() and write() system calls. Set memory boundary, file block size, * and copy buffer size to the default values. */ if (H5Pset_fapl_direct(my_fapl, 1024, 4096, 8*4096)<0) return -1; #endif } else { /* Unknown driver */ return -1; } return my_fapl; }