|
| 1 | +# h5fortran-MPI API |
| 2 | + |
| 3 | +This document provides a listing of h5fortran-mpi `public` scoped user-facing procedures and methods with a summary of their parameters. |
| 4 | + |
| 5 | +All examples assume: |
| 6 | + |
| 7 | +```fortran |
| 8 | +use h5mpi, only: hdf5_file, HSIZE_T, HID_T |
| 9 | +
|
| 10 | +type(hdf5_file) :: h |
| 11 | +``` |
| 12 | + |
| 13 | +Query HDF5 library version: |
| 14 | + |
| 15 | +```fortran |
| 16 | +use h5mpi, only : hdf5version |
| 17 | +
|
| 18 | +print *, hdf5version() |
| 19 | +``` |
| 20 | + |
| 21 | +## Open / close HDF5 file reference |
| 22 | + |
| 23 | +More than one HDF5 file can be open in a program, by declaring unique file handle (variable) like: |
| 24 | + |
| 25 | +```fortran |
| 26 | +type(hdf5_file) :: h1, h2, h3 |
| 27 | +``` |
| 28 | + |
| 29 | +```fortran |
| 30 | +call h%open(filename, action, mpi, comp_lvl) |
| 31 | +!! Opens hdf5 file |
| 32 | +
|
| 33 | +character(*), intent(in) :: filename |
| 34 | +character(*), intent(in), optional :: action !< 'r', 'w', 'rw', 'r+' |
| 35 | +logical, intent(in) :: mpi !< .true.: use HDF5-MPI .false.: use serial HDF5 |
| 36 | +integer, intent(in), optional :: comp_lvl !< 0: no compression. 1-9: ZLIB compression, higher is more compressior |
| 37 | +``` |
| 38 | + |
| 39 | +```fortran |
| 40 | +call h%close(close_hdf5_interface) |
| 41 | +!! This must be called on each HDF5 file to flush buffers to disk |
| 42 | +!! data loss can occur if program terminates before this procedure |
| 43 | +!! |
| 44 | +!! close_hdf5_interface is when you know you have exactly one HDF5 file in your |
| 45 | +!! application, if true it closes ALL files, even those invoked directly from HDF5. |
| 46 | +
|
| 47 | +logical, intent(in), optional :: close_hdf5_interface |
| 48 | +``` |
| 49 | + |
| 50 | +To avoid memory leaks or corrupted files, always "close()" all hDF5 files before STOPping the Fortran program. |
| 51 | + |
| 52 | +```fortran |
| 53 | +call h%flush() |
| 54 | +!! request operating system flush data to disk. |
| 55 | +``` |
| 56 | + |
| 57 | +## Disk variable (dataset) inquiry |
| 58 | + |
| 59 | +To allocate variables before reading data, inquire about dataset characteristics with these procedures. |
| 60 | + |
| 61 | +```fortran |
| 62 | +rank = h%ndim(dataset_name) |
| 63 | +
|
| 64 | +character(*), intent(in) :: dataset_name |
| 65 | +``` |
| 66 | + |
| 67 | +Get disk dataset shape (1D vector) |
| 68 | + |
| 69 | +```fortran |
| 70 | +call h%shape(dataset_name, dims) |
| 71 | +character(*), intent(in) :: dataset_name |
| 72 | +integer(HSIZE_T), intent(out), allocatable :: dims(:) |
| 73 | +``` |
| 74 | + |
| 75 | +Dataset "dname" data class (i.e. integer, float, string, ...) |
| 76 | + |
| 77 | +```fortran |
| 78 | +integer :: class |
| 79 | +!! H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F |
| 80 | +class = h%class(dname) |
| 81 | +character(*), intent(in) :: dname |
| 82 | +``` |
| 83 | + |
| 84 | +Dataset "dname" datatype |
| 85 | + |
| 86 | +```fortran |
| 87 | +integer(HID_T) :: dtype |
| 88 | +!! H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_INTEGER, H5T_NATIVE_CHARACTER, H5T_STD_I64LE |
| 89 | +dtype = h%dtype(dname) |
| 90 | +character(*), intent(in) :: dname |
| 91 | +``` |
| 92 | + |
| 93 | +Does dataset "dname" exist in this HDF5 file? |
| 94 | + |
| 95 | +```fortran |
| 96 | +exists = h%exist(dname) |
| 97 | +character(*), intent(in) :: dname |
| 98 | +``` |
| 99 | + |
| 100 | +Is dataset "dname" contiguous on disk? |
| 101 | + |
| 102 | +```fortran |
| 103 | +tf = h%is_contig(dname) |
| 104 | +!! is dataset contiguous |
| 105 | +character(*), intent(in) :: dname |
| 106 | +``` |
| 107 | + |
| 108 | +Is dataset compact (< 64K) |
| 109 | + |
| 110 | +```fortran |
| 111 | +tf = h%is_compact(dname) |
| 112 | +!! is dataset compact layout |
| 113 | +character(*), intent(in) :: dname |
| 114 | +``` |
| 115 | + |
| 116 | +Is dataset chunked? |
| 117 | + |
| 118 | +```fortran |
| 119 | +tf = h%is_chunked(dname) |
| 120 | +!! is dataset chunked |
| 121 | +character(*), intent(in) :: dname |
| 122 | +``` |
| 123 | + |
| 124 | +Is this an HDF5 file? |
| 125 | + |
| 126 | +```fortran |
| 127 | +use h5mpi, only: is_hdf5 |
| 128 | +
|
| 129 | +tf = is_hdf5('myfile.txt') !< probably false |
| 130 | +tf = is_hdf5('myfile.h5') !< true if a valid HDF5 file |
| 131 | +``` |
| 132 | + |
| 133 | +These are more advanced inquiries into the memory layout of the dataset, for advanced users: |
| 134 | + |
| 135 | +```fortran |
| 136 | +Layout = h%layout(dname) |
| 137 | +!! integer :: H5D_CONTIGUOUS_F, H5D_CHUNKED_F, H5D_VIRTUAL_F, H5D_COMPACT_F |
| 138 | +character(*), intent(in) :: dname |
| 139 | +``` |
| 140 | + |
| 141 | +```fortran |
| 142 | +call h%chunks(dname, chunk_size) |
| 143 | +character(*), intent(in) :: dname |
| 144 | +integer, intent(out) :: chunk_size(:) |
| 145 | +``` |
| 146 | + |
| 147 | +## create dataset softlink |
| 148 | + |
| 149 | +HDF5 can create dataset softlinks within an HDF5 file: |
| 150 | + |
| 151 | +```fortran |
| 152 | +call h%softlink(tgt, link) |
| 153 | +
|
| 154 | +character(*), intent(in) :: tgt, & !< target path to link dataset |
| 155 | + link !< soft link path to create |
| 156 | +``` |
| 157 | + |
| 158 | +## file write operations |
| 159 | + |
| 160 | +Write data from memory to disk HDF5 dataset: |
| 161 | +When file has been opened for MPI collective read via: `%open(..., mpi=.true.)` the data is distributed |
| 162 | +via MPI to the workers. |
| 163 | +If overall dataset dimensions "dset_dims" is present, data is collectively gathered from the workers as per HDF5-MPI docs. |
| 164 | +Otherwise, h5fortran-mpi assumes that root has all the data to be written and ignores the workers. |
| 165 | + |
| 166 | +```fortran |
| 167 | +call h%write(dname, value, dset_dims, istart, iend, chunk_size, compact) |
| 168 | +!! write 0d..7d dataset |
| 169 | +character(*), intent(in) :: dname |
| 170 | +class(*), intent(in) :: value(..) !< array to write |
| 171 | +integer, intent(in), dimension(rank(value)), optional :: dset_dims |
| 172 | +integer, intent(in), optional, dimension(rank(value)) :: istart, iend !< array slicing for hyperslab |
| 173 | +integer, intent(in), optional :: chunk_size(rank(value)) !< override auto-chunking |
| 174 | +logical, intent(in), optional :: compact !< faster I/O for sub-64 kB datasets |
| 175 | +``` |
| 176 | + |
| 177 | +Write dataset attribute (e.g. units or instrument): |
| 178 | + |
| 179 | +```fortran |
| 180 | +call h%writeattr(dname, attr, attrval) |
| 181 | +character(*), intent(in) :: dname, attr !< dataset name, attribute name |
| 182 | +class(*), intent(in) :: attrval(:) !< character, real, integer |
| 183 | +``` |
| 184 | + |
| 185 | +## file read operations |
| 186 | + |
| 187 | +Read data from disk to memory: |
| 188 | +When file has been opened for MPI collective read via: `%open(..., mpi=.true.)` the data is distributed |
| 189 | +via MPI to the workers. |
| 190 | +For example, if no slicing is specified, the whole dataset is read by root and broadcast to the workers. |
| 191 | +If slicing is specified, the data is read and distributed among the workers as per HDF5-MPI docs. |
| 192 | + |
| 193 | +```fortran |
| 194 | +call h%read(dname, value, istart, iend) |
| 195 | +character(*), intent(in) :: dname |
| 196 | +class(*), intent(inout) :: value(..) !< read array to this ALLOCATED variable of rank 0d..7d |
| 197 | +integer, intent(in), optional, dimension(rank(value)) :: istart, iend !< array slicing |
| 198 | +``` |
| 199 | + |
| 200 | +Read dataset attribute into memory: |
| 201 | + |
| 202 | +```fortran |
| 203 | +call h%readattr(dname, attr, attrval) |
| 204 | +character(*), intent(in) :: dname, attr !< dataset name, attribute name |
| 205 | +class(*), intent(inout) :: attrval(:) !< character scalar; real vector, integer vector |
| 206 | +``` |
0 commit comments