Last active
December 19, 2015 06:39
-
-
Save dstuebe/5912638 to your computer and use it in GitHub Desktop.
Example fortran code to create compressed dataset with compound data types.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*------------------------------------------------------------------------- | |
* Function: H5Z_can_apply_szip | |
* | |
* Purpose: Check the parameters for szip compression for validity and | |
* whether they fit a particular dataset. | |
* | |
* Note: This function currently range-checks for datatypes with | |
* 8-bit boundaries (8, 16, 24, etc.). It appears that the szip | |
* library can actually handle 1-24, 32 & 64 bit samples. If | |
* this becomes important, we should make the checks below more | |
* sophisticated and have them check for n-bit datatypes of the | |
* correct size, etc. - QAK | |
* | |
* Return: Success: Non-negative | |
* Failure: Negative | |
* | |
* Programmer: Quincey Koziol | |
* Monday, April 7, 2003 | |
* | |
* Modifications: | |
* | |
*------------------------------------------------------------------------- | |
*/ | |
static htri_t | |
H5Z_can_apply_szip(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id) | |
{ | |
const H5T_t *type; /* Datatype */ | |
unsigned dtype_size; /* Datatype's size (in bits) */ | |
H5T_order_t dtype_order; /* Datatype's endianness order */ | |
htri_t ret_value = TRUE; /* Return value */ | |
FUNC_ENTER_NOAPI(FAIL) | |
/* Get datatype */ | |
if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE))) | |
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") | |
/* Get datatype's size, for checking the "bits-per-pixel" */ | |
if((dtype_size = (8 * H5T_get_size(type))) == 0) | |
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad datatype size") | |
/* Range check datatype's size */ | |
if(dtype_size > 32 && dtype_size != 64) | |
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FALSE, "invalid datatype size") | |
/* Get datatype's endianness order */ | |
if((dtype_order = H5T_get_order(type)) == H5T_ORDER_ERROR) | |
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "can't retrieve datatype endianness order") | |
/* Range check datatype's endianness order */ | |
/* (Note: this may not handle non-atomic datatypes well) */ | |
if(dtype_order != H5T_ORDER_LE && dtype_order != H5T_ORDER_BE) | |
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FALSE, "invalid datatype endianness order") | |
done: | |
FUNC_LEAVE_NOAPI(ret_value) | |
} /* end H5Z_can_apply_szip() */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!************************************************************ | |
! | |
! This example shows how to read and write compound | |
! datatypes to a dataset. | |
! | |
! This file is intended for use with HDF5 Library version 1.8 | |
! with --enable-fortran2003 | |
! | |
! Compile: gfortran -I/usr/local/Cellar/hdf5/1.8.11/include -L/usr/local/Cellar/hdf5/1.8.11/lib -lhdf5_fortran -lhdf5hl_fortran -lhdf5 -lhdf5_hl hdfWriteParticleType.f90 -o hdfWriteParticleType | |
!************************************************************ | |
PROGRAM main | |
USE ISO_C_BINDING | |
USE HDF5 | |
IMPLICIT NONE | |
! This should map to REAL*8 on most modern processors | |
INTEGER, PARAMETER :: real_kind_15 = SELECTED_REAL_KIND(Fortran_REAL_8) | |
LOGICAL :: avail | |
INTEGER :: flags, filter_info, filter_info_both, filter_id | |
CHARACTER(LEN=18), PARAMETER :: filename = "hdfParticleType.h5" | |
CHARACTER(LEN=3) , PARAMETER :: dataset = "DS1" | |
INTEGER , PARAMETER :: ntsteps = 100 | |
INTEGER , PARAMETER :: nparticles = 100 | |
INTEGER , PARAMETER :: chunk0 = 10 | |
INTEGER , PARAMETER :: chunk1 = 10 | |
!INTEGER , PARAMETER :: maxstringlen = 80 | |
INTEGER , PARAMETER :: rank2 = 2 | |
INTEGER , PARAMETER :: rank1 = 1 | |
INTEGER , PARAMETER :: compression_level = 9 ! http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetDeflate | |
INTEGER , PARAMETER :: pixels_per_block = 12 ! http://www.hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_szip.htm | |
TYPE sensor_t ! Compound data type | |
INTEGER :: serial_no | |
!CHARACTER(LEN=maxstringlen) :: location | |
REAL(real_kind_15) :: temperature | |
REAL(real_kind_15) :: pressure | |
END TYPE sensor_t | |
TYPE(sensor_t), DIMENSION(1:nparticles), TARGET :: wdata ! Write buffer | |
TYPE(sensor_t), DIMENSION(1:nparticles), TARGET :: rdata ! Read buffer | |
INTEGER(HID_T) :: file, filetype, memtype, spaceParticles, spaceMemory, dset, strtype, dcplParticles ! Handles | |
INTEGER :: hdferr | |
INTEGER(HSIZE_T), DIMENSION(1:2) :: dimParticles = (/nparticles, ntsteps /), & | |
chunkParticles = (/chunk1, chunk0/) | |
INTEGER(HSIZE_T), DIMENSION(1:2) :: start2, stride2, count2, block2 | |
INTEGER(HSIZE_T), DIMENSION(1:1) :: start1, stride1, count1, block1 | |
INTEGER(HSIZE_T), Dimension(1:2) :: memSize2 | |
INTEGER(HSIZE_T), Dimension(1:1) :: memSize1 | |
TYPE(C_PTR) :: f_ptr | |
INTEGER :: i | |
real*4 :: tic, toc | |
! | |
! Initialize FORTRAN interface. | |
! | |
CALL h5open_f(hdferr) | |
! SZIP filter check | |
CALL h5zfilter_avail_f(H5Z_FILTER_SZIP_F, avail, hdferr) | |
IF (.NOT.avail) THEN | |
WRITE(*,'("szip filter not available.",/)') | |
STOP | |
ENDIF | |
CALL h5zget_filter_info_f(H5Z_FILTER_SZIP_F, filter_info, hdferr) | |
filter_info_both=IOR(H5Z_FILTER_ENCODE_ENABLED_F,H5Z_FILTER_DECODE_ENABLED_F) | |
IF (filter_info .NE. filter_info_both) THEN | |
WRITE(*,'("szip filter not available for encoding and decoding.",/)') | |
STOP | |
ENDIF | |
! GZIP filter check | |
CALL h5zfilter_avail_f(H5Z_FILTER_DEFLATE_F, avail, hdferr) | |
IF (.NOT.avail) THEN | |
WRITE(*,'("gzip filter not available.",/)') | |
STOP | |
ENDIF | |
CALL h5zget_filter_info_f(H5Z_FILTER_DEFLATE_F, filter_info, hdferr) | |
filter_info_both=IOR(H5Z_FILTER_ENCODE_ENABLED_F,H5Z_FILTER_DECODE_ENABLED_F) | |
IF (filter_info .NE. filter_info_both) THEN | |
WRITE(*,'("gzip filter not available for encoding and decoding.",/)') | |
STOP | |
ENDIF | |
! | |
! Initialize data. | |
! | |
call random_seed() | |
! Initialize data arrays with a value | |
call random_number(wdata%temperature) | |
call random_number(wdata%pressure) | |
wdata%serial_no = 0 | |
! | |
! Create a new file using the default properties. | |
! | |
CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file, hdferr) | |
! | |
! Create the compound datatype for memory. | |
! | |
CALL h5tcreate_f(H5T_COMPOUND_F, H5OFFSETOF(C_LOC(wdata(1)), C_LOC(wdata(2))), memtype, hdferr) | |
CALL h5tinsert_f(memtype, "Serial number", & | |
H5OFFSETOF(C_LOC(wdata(1)),C_LOC(wdata(1)%serial_no)), H5T_NATIVE_INTEGER, hdferr) | |
! | |
! Create datatype for the String attribute. | |
! | |
!CALL h5tcopy_f(H5T_NATIVE_CHARACTER, strtype, hdferr) | |
!CALL h5tset_size_f(strtype, INT(maxstringlen,size_t), hdferr) | |
! | |
!CALL h5tinsert_f(memtype, "Location", & | |
! H5OFFSETOF(C_LOC(wdata(1)),C_LOC(wdata(1)%location)), strtype, hdferr) | |
CALL h5tinsert_f(memtype, "Temperature (F)", & | |
H5OFFSETOF(C_LOC(wdata(1)),C_LOC(wdata(1)%temperature)), & | |
h5kind_to_type(real_kind_15,H5_REAL_KIND), hdferr) | |
CALL h5tinsert_f(memtype, "Pressure (inHg)", & | |
H5OFFSETOF(C_LOC(wdata(1)),C_LOC(wdata(1)%pressure)), & | |
h5kind_to_type(real_kind_15,H5_REAL_KIND), hdferr) | |
! | |
! Create the compound datatype for the file. Because the standard | |
! types we are using for the file may have different sizes than | |
! the corresponding native types, we must manually calculate the | |
! offset of each member. | |
! | |
!CALL h5tcreate_f(H5T_COMPOUND_F, INT(8 + maxstringlen + 8 + 8 , size_t), filetype, hdferr) | |
CALL h5tcreate_f(H5T_COMPOUND_F, INT(8 + 8 + 8 , size_t), filetype, hdferr) | |
CALL h5tinsert_f(filetype, "Serial number", 0_size_t, H5T_STD_I64BE, hdferr) | |
!CALL h5tinsert_f(filetype, "Location", 8_size_t, strtype, hdferr) | |
CALL h5tinsert_f(filetype, "Temperature (F)", INT(8,size_t), & | |
H5T_IEEE_F64BE, hdferr) | |
CALL h5tinsert_f(filetype, "Pressure (inHg)", INT(8 + 8, size_t), & | |
H5T_IEEE_F64BE, hdferr) | |
! | |
! Create dataspace. Set the size to be the current size. | |
! | |
CALL h5screate_simple_f(rank2, dimParticles, spaceParticles, hdferr) | |
count1 = (/nparticles/) | |
CALL h5screate_simple_f(rank1, count1, spaceMemory, hdferr) | |
!!!!! | |
! Create the dataset creation property list, and set the chunk size. | |
CALL h5pcreate_f(H5P_DATASET_CREATE_F, dcplParticles, hdferr) | |
!CALL h5pset_szip_f(dcplParticles, H5_SZIP_NN_OM_F, pixels_per_block, hdferr) | |
CALL h5pset_deflate_f(dcplParticles, compression_level, hdferr) | |
CALL h5pset_chunk_f(dcplParticles, rank2, chunkParticles, hdferr) | |
!!!! | |
! | |
! Create the dataset and write the compound data to it. | |
! | |
CALL h5dcreate_f(file, dataset, filetype, spaceParticles, dset, hdferr, dcplParticles) | |
!CALL h5dcreate_f(file, dataset, filetype, spaceParticles, dset, hdferr) | |
! | |
! Write the data to the dataset. | |
call cpu_time(tic) | |
DO i = 1,ntsteps | |
start2(1:2) = (/0,i-1/) | |
count2(1:2) = (/nParticles,1/) | |
CALL h5sselect_hyperslab_f (spaceParticles, H5S_SELECT_SET_F, start2, count2, hdferr) | |
wdata%serial_no = wdata%serial_no +1 | |
call random_number(wdata%temperature) | |
call random_number(wdata%pressure) | |
f_ptr = C_LOC(wdata(1)) | |
CALL h5dwrite_f(dset, memtype, f_ptr, hdferr, mem_space_id=spaceMemory, file_space_id=spaceParticles) | |
ENDDO | |
call cpu_time(toc) | |
print "('Completed dummy data output in ', f10.6,' Seconds')", toc - tic | |
! | |
! Close and release resources. | |
! | |
CALL h5dclose_f(dset, hdferr) | |
CALL h5sclose_f(spaceParticles, hdferr) | |
CALL h5sclose_f(spaceMemory, hdferr) | |
CALL h5tclose_f(filetype, hdferr) | |
CALL h5fclose_f(file, hdferr) | |
! | |
! Now we begin the read section of this example. | |
! | |
! | |
! Open file and dataset. | |
! | |
! CALL h5fopen_f(filename, H5F_ACC_RDONLY_F, file, hdferr) | |
! CALL h5dopen_f(file, dataset, dset, hdferr) | |
! | |
! Get dataspace. | |
! | |
! CALL h5dget_space_f(dset, space, hdferr) | |
! CALL h5sget_simple_extent_dims_f(space, dims, ndims, hdferr) | |
! | |
! Read the data. | |
! | |
! f_ptr = C_LOC(rdata(1)) | |
! CALL h5dread_f(dset, memtype, f_ptr, hdferr) | |
! | |
! Output the data to the screen. | |
! | |
! DO i = 1, ndims(1) | |
! WRITE(*,'(A,I1,":")') dataset, i | |
! WRITE(*,'("Serial number : ", I6)') rdata(i)%serial_no | |
! WRITE(*,'("Location : ", A)' ) TRIM(rdata(i)%location) | |
! WRITE(*,'("Temperature (F) : ", f8.2)') rdata(i)%temperature | |
! WRITE(*,'("Pressure (inHg) : ", f8.2)') rdata(i)%pressure | |
! END DO | |
! | |
! Close and release resources | |
! | |
! CALL h5dclose_f(dset, hdferr) | |
! CALL h5sclose_f(space, hdferr) | |
! CALL h5tclose_f(strtype, hdferr) | |
! CALL h5fclose_f(file, hdferr) | |
END PROGRAM main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment