diff --git a/README b/README index 4ab73f5..c872354 100644 --- a/README +++ b/README @@ -34,12 +34,16 @@ Note that only few of the HDF5 datatypes are supported by each of the functions hdf5oct at the moment, typically one or several of double, integer and string. +# REQUIREMENTS ######################### + +The wrapper h5c++ provided by the HDF5 library must be available. + # INSTALLATION ######################### -To install, just use +To compile this package, use make - + This will produce a package file named "hdf5oct-*.tar.gz" . Then you may either install the package with @@ -50,7 +54,7 @@ the correct file name) with the command pkg install hdf5oct-0.2.0.tar.gz -This will put the *.oct files somewhere where Octave will find them. +Both will put the *.oct files somewhere where Octave will find them. You can try running make test @@ -62,6 +66,10 @@ To uninstall the package you may want to use make uninstall +or on the GNU Octave prompt + + pkg uninstall hdf5oct + # TODO ################################# - write h5info, h5disp diff --git a/h5read.cc b/h5read.cc index f346fd5..26304a2 100644 --- a/h5read.cc +++ b/h5read.cc @@ -58,7 +58,7 @@ using namespace std; bool any_int_leq_zero (const Matrix& mat) { - for (int i = 0; i < mat.length (); i++) + for (int i = 0; i < mat.numel (); i++) { if (mat(i) < 0.5) return true; @@ -76,7 +76,7 @@ check_vec (const octave_value& val, Matrix& mat/*out*/, if (error_state) return 0; - if (! mat.is_vector ()) + if (! mat.isvector ()) { error ("%s must be a vector", name); return 0; @@ -85,7 +85,7 @@ check_vec (const octave_value& val, Matrix& mat/*out*/, double mind, maxd; if (allow_zeros) { - for (int i = 0; i < mat.nelem (); i++) + for (int i = 0; i < mat.numel (); i++) { if (mat(i) == octave_Inf) mat(i) = 0; @@ -148,31 +148,31 @@ the appropriate size for the given HDF5 type.\n\ @end deftypefn") { #if ! (defined (HAVE_HDF5) && defined (HAVE_HDF5_18)) - gripe_disabled_feature ("h5read", "HDF5 IO"); - return octave_value_list (); + err_disabled_feature ("h5read", "HDF5 IO"); + return octave_value (); #else int nargin = args.length (); if (nargin < 2 || nargin == 3 || nargin > 6 || nargout > 1) { print_usage (); - return octave_value_list (); + return octave_value (); } if (! (args(0).is_string () && args (1).is_string ())) { print_usage (); - return octave_value_list (); + return octave_value (); } string filename = args(0).string_value (); string dsetname = args(1).string_value (); if (error_state) - return octave_value_list (); + return octave_value (); //open the hdf5 file - H5File file (filename.c_str (), false); + H5File file (filename.c_str (), false, false); if (error_state) - return octave_value_list (); + return octave_value (); if (nargin < 4) { @@ -200,7 +200,7 @@ the appropriate size for the given HDF5 type.\n\ err = err || ! check_vec (args(5), block, "BLOCK", false); if (err) - return octave_value_list (); + return octave_value (); return file.read_dset_hyperslab (dsetname.c_str (), start, count, stride, block, nargin-2); @@ -222,8 +222,8 @@ is to read.\n\ { octave_value retval; #if ! (defined (HAVE_HDF5) && defined (HAVE_HDF5_18)) - gripe_disabled_feature ("h5readatt", "HDF5 IO"); - return octave_value_list (); + err_disabled_feature ("h5readatt", "HDF5 IO"); + return octave_value (); #else int nargin = args.length (); if (nargin != 3) @@ -241,12 +241,12 @@ is to read.\n\ string objname = args(1).string_value (); string attname = args(2).string_value (); if (error_state) - return octave_value_list (); + return octave_value (); //open the hdf5 file - H5File file (filename.c_str (), false); + H5File file (filename.c_str (), false, false); if (error_state) - return octave_value_list (); + return octave_value (); retval = file.read_att (objname.c_str (), attname.c_str ()); return retval; @@ -293,43 +293,43 @@ the appropriate size for the given Octave type.\n\ @end deftypefn") { #if ! (defined (HAVE_HDF5) && defined (HAVE_HDF5_18)) - gripe_disabled_feature ("h5write", "HDF5 IO"); - return octave_value_list (); + err_disabled_feature ("h5write", "HDF5 IO"); + return octave_value (); #else int nargin = args.length (); if (! (nargin == 3 || nargin == 5 || nargin == 6 || nargin == 7) || nargout != 0) { print_usage (); - return octave_value_list (); + return octave_value (); } if (! (args(0).is_string () && args(1).is_string ())) { print_usage (); - return octave_value_list (); + return octave_value (); } string filename = args(0).string_value (); string location = args(1).string_value (); if (error_state) - return octave_value_list (); + return octave_value (); if (nargin == 3) { //open the hdf5 file, create it if it does not exist - H5File file (filename.c_str (), true); + H5File file (filename.c_str (), true, true); if (error_state) - return octave_value_list (); + return octave_value (); file.write_dset (location.c_str (), args(2)); } else { //open the hdf5 file, complain if it does not exist - H5File file (filename.c_str (), false); + H5File file (filename.c_str (), false, true); if (error_state) - return octave_value_list (); + return octave_value (); Matrix start, count, stride, block; int err = 0; @@ -350,14 +350,14 @@ the appropriate size for the given Octave type.\n\ err = err || ! check_vec (args(6), block, "BLOCK", false); if (err) - return octave_value_list (); + return octave_value (); file.write_dset_hyperslab (location.c_str (), args(2), start, count, stride, block, nargin-3); } - return octave_value_list (); + return octave_value (); #endif } @@ -373,20 +373,20 @@ the object named @var{objectname} in the HDF5 file specified by @var{filename}.\ @end deftypefn") { #if ! (defined (HAVE_HDF5) && defined (HAVE_HDF5_18)) - gripe_disabled_feature ("h5writeatt", "HDF5 IO"); - return octave_value_list (); + err_disabled_feature ("h5writeatt", "HDF5 IO"); + return octave_value (); #else int nargin = args.length (); if (nargin != 4 || nargout != 0) { print_usage (); - return octave_value_list (); + return octave_value (); } if (! (args(0).is_string () && args(1).is_string () && args(2).is_string ())) { print_usage (); - return octave_value_list (); + return octave_value (); } string filename = args(0).string_value (); @@ -394,17 +394,17 @@ the object named @var{objectname} in the HDF5 file specified by @var{filename}.\ string attname = args(2).string_value (); if (error_state) - return octave_value_list (); + return octave_value (); //open the hdf5 file - H5File file (filename.c_str (), false); + H5File file (filename.c_str (), false, true); if (error_state) - return octave_value_list (); + return octave_value (); file.write_att (location.c_str (), attname.c_str (), args(3)); - return octave_value_list (); + return octave_value (); #endif } @@ -414,7 +414,8 @@ DEFUN_DLD (h5create, args, nargout, @deftypefn {Loadable Function} h5create (@var{filename}, @var{dsetname}, @var{size}, @var{key}, @var{val},...)\n\ \n\ Create a dataset with name @var{dsetname} and size @var{size} \n\ -in the HDF5 file specified by @var{filename}.\n\ +in the HDF5 file specified by @var{filename}. Intermediate groups\n\ +are created as necessary.\n\ \n\ The vector @var{size} may contain one or several Inf (or \n\ equivalently: zero) values.\n\ @@ -442,35 +443,35 @@ setting is not @sc{matlab} compatible.\n\ @end deftypefn") { #if ! (defined (HAVE_HDF5) && defined (HAVE_HDF5_18)) - gripe_disabled_feature("h5create", "HDF5 IO"); - return octave_value_list (); + err_disabled_feature("h5create", "HDF5 IO"); + return octave_value (); #else int nargin = args.length (); if (! (nargin == 3 || nargin == 5 || nargin == 7) || nargout != 0) { print_usage (); - return octave_value_list (); + return octave_value (); } if (! (args(0).is_string () && args(1).is_string ())) { print_usage (); - return octave_value_list (); + return octave_value (); } if ((nargin == 5 && ! args(3).is_string ()) || (nargin == 7 && ! args(5).is_string ())) { print_usage (); - return octave_value_list (); + return octave_value (); } string filename = args(0).string_value (); string location = args(1).string_value (); if (error_state) - return octave_value_list (); + return octave_value (); Matrix size; if (! check_vec (args(2), size, "SIZE", true)) - return octave_value_list (); + return octave_value (); // loop over the key-value pairs and see what is given @@ -484,7 +485,7 @@ setting is not @sc{matlab} compatible.\n\ if (error_state) { error ("Datatype argument must be a string"); - return octave_value_list (); + return octave_value (); } } else if (args(i).string_value () == "ChunkSize") @@ -494,31 +495,31 @@ setting is not @sc{matlab} compatible.\n\ if(args(i+1).string_value () != "auto") { error ("ChunkSize argument must be either a vector, or the string 'auto'."); - return octave_value_list (); + return octave_value (); } chunksize = args(2).matrix_value (); chunksize(0) = 0; } else if (! check_vec (args(i+1), chunksize, "ChunkSize", false)) - return octave_value_list (); + return octave_value (); } else { error ("unknown parameter name %s", args(i).string_value ().c_str ()); - return octave_value_list (); + return octave_value (); } } //open the hdf5 file - H5File file (filename.c_str (), true); + H5File file (filename.c_str (), true, true); if (error_state) - return octave_value_list (); + return octave_value (); file.create_dset (location.c_str (), size, datatype.c_str (), chunksize); - return octave_value_list (); + return octave_value (); #endif } @@ -529,7 +530,10 @@ DEFUN_DLD (h5delete, args, nargout, @deftypefnx {Loadable Function} h5delete (@var{filename}, @var{objname}, @var{attname})\n\ \n\ In the first form, delete a dataset or group with name @var{objname}\n\ -in the HDF5 file specified by @var{filename}.\n\ +in the HDF5 file specified by @var{filename}. Note that hdf5 is like a\n\ +filesystem: the library does not free the used space when a dataset is\n\ +deleted. One can use the tool h5repack afterwards to actually reduce the \n\ +filesize.\n \ \n\ In the second form, delete an attribute with name @var{attname} associated\n\ to a dataset or group with name @var{objname}\n\ @@ -541,36 +545,36 @@ Note that this function is not @sc{matlab} compliant.\n\ @end deftypefn") { #if ! (defined (HAVE_HDF5) && defined (HAVE_HDF5_18)) - gripe_disabled_feature("h5delete", "HDF5 IO"); - return octave_value_list (); + err_disabled_feature("h5delete", "HDF5 IO"); + return octave_value (); #else int nargin = args.length (); if (! (nargin == 2 || nargin == 3) || nargout != 0) { print_usage (); - return octave_value_list (); + return octave_value (); } if (! (args(0).is_string () && args(1).is_string ())) { print_usage (); - return octave_value_list (); + return octave_value (); } if (nargin == 3 && ! args(2).is_string ()) { print_usage (); - return octave_value_list (); + return octave_value (); } string filename = args(0).string_value (); string location = args(1).string_value (); if (error_state) - return octave_value_list (); + return octave_value (); //open the hdf5 file - H5File file (filename.c_str (), true); + H5File file (filename.c_str (), true, true); if (error_state) - return octave_value_list (); + return octave_value (); if (nargin == 2) file.delete_link (location.c_str ()); else if (nargin == 3) @@ -580,13 +584,14 @@ Note that this function is not @sc{matlab} compliant.\n\ file.delete_att (location.c_str (), attname.c_str ()); } - return octave_value_list (); + return octave_value (); #endif } #if defined (HAVE_HDF5) && defined (HAVE_HDF5_18) -H5File::H5File (const char *filename, const bool create_if_nonexisting) +H5File::H5File (const char *filename, const bool create_if_nonexisting, + const bool write_access) { H5E_auto_t oef; void *olderr; @@ -594,7 +599,7 @@ H5File::H5File (const char *filename, const bool create_if_nonexisting) //suppress hdf5 error output H5Eset_auto (H5E_DEFAULT,0,0); - file_stat fs (filename); + octave::sys::file_stat fs (filename); if (! fs.exists () && create_if_nonexisting) file = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); else if (! fs.exists () && ! create_if_nonexisting) @@ -606,7 +611,9 @@ H5File::H5File (const char *filename, const bool create_if_nonexisting) error ("The file is not in the HDF5 format, %s: %s", filename, strerror (errno)); else { - file = H5Fopen (filename, H5F_ACC_RDWR, H5P_DEFAULT); + file = H5Fopen (filename, + write_access ? H5F_ACC_RDWR : H5F_ACC_RDONLY, + H5P_DEFAULT); if (file < 0) error ("Opening the file failed, %s: %s", filename, strerror (errno)); } @@ -659,7 +666,7 @@ template hsize_t* H5File::alloc_hsize (const T& dim, const int mode, const bool reverse) { - int rank = dim.length (); + int rank = dim.numel (); hsize_t *hsize = (hsize_t*)malloc (rank * sizeof (hsize_t)); for (int i = 0; i < rank; i++) { @@ -719,10 +726,10 @@ octave_value H5File::read_dset_complete (const char *dsetname) { if (open_dset (dsetname) < 0) - return octave_value_list (); + return octave_value (); mat_dims.resize (max (rank, 2)); - // .resize(1) still leaves mat_dims with a length of 2 for some reason, so + // .resize(1) still leaves mat_dims with a length of 2, so // we need at least 2 filled mat_dims(0) = mat_dims(1) = 1; for (int i = 0; i < rank; i++) @@ -732,7 +739,7 @@ H5File::read_dset_complete (const char *dsetname) if (H5Sselect_all (dspace_id) < 0) { error ("Error selecting complete dataset %s", dsetname); - return octave_value_list (); + return octave_value (); } octave_value retval = read_dset (); @@ -746,44 +753,44 @@ H5File::read_dset_hyperslab (const char *dsetname, int nargin) { if (open_dset (dsetname) < 0) - return octave_value_list (); + return octave_value (); - if (rank == 0 && ! (start.is_empty () && count.is_empty () - && stride.is_empty () && block.is_empty ())) + if (rank == 0 && ! (start.isempty () && count.isempty () + && stride.isempty () && block.isempty ())) { error ("Cannot specify hyperslab for scalar datasets (rank 0)"); - return octave_value_list (); + return octave_value (); } - if (start.nelem () != rank) + if (start.numel () != rank) { error ("start must be a vector of length %d, the dataset rank", rank); - return octave_value_list (); + return octave_value (); } - if (count.nelem () != rank) + if (count.numel () != rank) { error ("count must be a vector of length %d, the dataset rank", rank); - return octave_value_list (); + return octave_value (); } Matrix _stride = stride; if (nargin < 3) _stride = Matrix (dim_vector(1, rank), 1); - if (_stride.nelem () != rank) + if (_stride.numel () != rank) { error ("stride must be a vector of length %d, the dataset rank", rank); - return octave_value_list (); + return octave_value (); } Matrix _block = block; if (nargin < 4) _block = Matrix (dim_vector(1, rank), 1); - if (_block.nelem () != rank) + if (_block.numel () != rank) { error ("block must be a vector of length %d, the dataset rank", rank); - return octave_value_list (); + return octave_value (); } - - // .resize(1) still leaves mat_dims with a length of 2 for some reason, so + + // .resize(1) still leaves mat_dims with a length of 2, so // we need at least 2 filled mat_dims.resize (max (rank, 2)); mat_dims(0) = mat_dims(1) = 1; @@ -795,7 +802,7 @@ H5File::read_dset_hyperslab (const char *dsetname, { error ("In dimension %d, requested stride %d smaller than block size %d", i+1, (int)_stride(i), (int)_block(i)); - return octave_value_list (); + return octave_value (); } if (_count(i) == 0) { @@ -810,29 +817,50 @@ H5File::read_dset_hyperslab (const char *dsetname, error ("In dimension %d, dataset only has %d elements, but at least %d" " are required for requested hyperslab", i+1, (int)h5_dims[rank-i-1], end); - return octave_value_list (); + return octave_value (); } } hsize_t *hstart = alloc_hsize (start, ALLOC_HSIZE_DEFAULT, true); + if(hstart == NULL) + { + error ("error when allocating hstart array, for %s", dsetname); + return octave_value (); + } hsize_t *hstride = alloc_hsize (_stride, ALLOC_HSIZE_DEFAULT, true); + if(hstride == NULL) + { + error ("error when allocating hstride array, for %s", dsetname); + return octave_value (); + } hsize_t *hcount = alloc_hsize (_count, ALLOC_HSIZE_DEFAULT, true); + if(hcount == NULL) + { + error ("error when allocating hcount array, for %s", dsetname); + return octave_value (); + } hsize_t *hblock = alloc_hsize (_block, ALLOC_HSIZE_DEFAULT, true); - // TODO check these (and hmem) for NULLs - + if(hblock == NULL) + { + error ("error when allocating hblock array, for %s", dsetname); + return octave_value (); + } + herr_t sel_result = H5Sselect_hyperslab (dspace_id, H5S_SELECT_SET, hstart, hstride, hcount, hblock); - free (hstart); free (hstride); free (hcount); free (hblock); - if (sel_result < 0) - return octave_value_list (); - + { + error ("error when selecting the hyperslab of dataset %s to read from", dsetname); + return octave_value (); + } + octave_value retval = read_dset (); return retval; + } octave_value @@ -841,12 +869,23 @@ H5File::read_dset () bool is_cmplx = false; type_id = H5Dget_type (dset_id); hid_t complex_type_id = hdf5_make_complex_type (H5T_NATIVE_DOUBLE); + + hsize_t *hmem = alloc_hsize (mat_dims, ALLOC_HSIZE_DEFAULT, false); + hid_t memspace_id = H5Screate_simple (rank, hmem, hmem); + free (hmem); + if (memspace_id < 0) + { + return octave_value (); + } - // hsize_t *hmem = alloc_hsize (mat_dims, ALLOC_HSIZE_DEFAULT, false); - // hid_t memspace_id = H5Screate_simple (rank, hmem, hmem); - // free (hmem); + if (H5Sselect_valid (dspace_id) <= 0) + { + error ("selected dataspace is not valid"); + return octave_value (); + } octave_value retval; + herr_t read_result; if (H5Tget_class (type_id) == H5T_COMPOUND && H5Tget_class (complex_type_id) == H5T_COMPOUND && hdf5_types_compatible (type_id, complex_type_id) > 0) @@ -854,31 +893,14 @@ H5File::read_dset () ComplexNDArray ret (mat_dims); // macro begin #define HDF5_READ_DATA(type) \ - if (H5Sselect_valid (dspace_id) <= 0) \ - { \ - error ("selected dataspace is not valid"); \ - return octave_value_list (); \ - } \ - \ - int mdc_nelem = -1; \ - size_t rdcc_nelem = -1; \ - size_t rdcc_nbytes = -1; \ - double rdcc_w0 = -1; \ - if (H5Pget_cache (H5Fget_access_plist (file), &mdc_nelem, \ - &rdcc_nelem, &rdcc_nbytes, &rdcc_w0 ) < 0) \ - { \ - error ("could not determine raw data chunk cache parameters."); \ - return octave_value_list (); \ - } \ - /*cout << "cache params:" << rdcc_nelem << "," << rdcc_nbytes << endl;*/ \ - herr_t read_result = H5Dread (dset_id, \ - type, \ - H5S_ALL, dspace_id, \ - H5P_DEFAULT, ret.fortran_vec ()); \ + read_result = H5Dread (dset_id, \ + type, \ + memspace_id, dspace_id, \ + H5P_DEFAULT, ret.fortran_vec ()); \ if (read_result < 0) \ { \ error ("error when reading dataset"); \ - return octave_value_list (); \ + return octave_value (); \ } \ retval = octave_value (ret) // macro end @@ -967,7 +989,7 @@ void H5File::write_dset (const char *dsetname, const octave_value ov_data) { - int rank = ov_data.dims ().length (); + int rank = ov_data.dims ().numel (); hsize_t *dims = alloc_hsize (ov_data.dims(), ALLOC_HSIZE_DEFAULT, true); dspace_id = H5Screate_simple (rank, dims, NULL); @@ -997,7 +1019,7 @@ H5File::write_dset (const char *dsetname, herr_t status; // find the right type - if (ov_data.is_complex_type ()) + if (ov_data.iscomplex ()) { //check if the data set already exists. if it does, open it, //otherwise, create it. Furthermore check if the datatype is @@ -1023,7 +1045,7 @@ H5File::write_dset (const char *dsetname, ComplexNDArray data = ov_data.complex_array_value (); OPEN_AND_WRITE; } - else if (ov_data.is_integer_type ()) + else if (ov_data.isinteger ()) { if (ov_data.is_uint64_type ()) { @@ -1115,19 +1137,19 @@ H5File::write_dset_hyperslab (const char *dsetname, return; // check if the given hyperslab settings are reasonable - if (rank == 0 && ! (start.is_empty () && count.is_empty () - && stride.is_empty () && block.is_empty ())) + if (rank == 0 && ! (start.isempty () && count.isempty () + && stride.isempty () && block.isempty ())) { error ("Cannot specify hyperslab for scalar datasets (rank 0)"); return; } - if (start.nelem () != rank) + if (start.numel () != rank) { error ("start must be a vector of length %d, the dataset rank", rank); return; } - if (count.nelem () != rank) + if (count.numel () != rank) { error ("count must be a vector of length %d, the dataset rank", rank); return; @@ -1135,7 +1157,7 @@ H5File::write_dset_hyperslab (const char *dsetname, Matrix _stride = stride; if (nargin < 3) _stride = Matrix (dim_vector(1, rank), 1); - if (_stride.nelem () != rank) + if (_stride.numel () != rank) { error ("stride must be a vector of length %d, the dataset rank", rank); return; @@ -1143,7 +1165,7 @@ H5File::write_dset_hyperslab (const char *dsetname, Matrix _block = block; if (nargin < 4) _block = Matrix (dim_vector(1, rank), 1); - if (_block.nelem () != rank) + if (_block.numel () != rank) { error ("block must be a vector of length %d, the dataset rank", rank); return; @@ -1178,10 +1200,29 @@ H5File::write_dset_hyperslab (const char *dsetname, h5_dims[rank-i-1] = end; } hsize_t *hstart = alloc_hsize (start, ALLOC_HSIZE_DEFAULT, true); + if(hstart == NULL) + { + error ("error when allocating hstart array, for %s", dsetname); + return; + } hsize_t *hstride = alloc_hsize (_stride, ALLOC_HSIZE_DEFAULT, true); + if(hstride == NULL) + { + error ("error when allocating hstride array, for %s", dsetname); + return; + } hsize_t *hcount = alloc_hsize (count, ALLOC_HSIZE_DEFAULT, true); + if(hcount == NULL) + { + error ("error when allocating hcount array, for %s", dsetname); + return; + } hsize_t *hblock = alloc_hsize (_block, ALLOC_HSIZE_DEFAULT, true); - // TODO check these (and hmem) for NULLs + if(hblock == NULL) + { + error ("error when allocating hblock array, for %s", dsetname); + return; + } // make the current size of the dataset bigger H5Sclose (dspace_id); @@ -1211,6 +1252,11 @@ H5File::write_dset_hyperslab (const char *dsetname, } hsize_t *hmem = alloc_hsize (data.dims (), ALLOC_HSIZE_DEFAULT, false); + if(hmem == NULL) + { + error ("error when allocating hmem array, for %s", dsetname); + return; + } hid_t memspace_id = H5Screate_simple (rank, hmem, hmem); if (memspace_id < 0) { @@ -1365,7 +1411,7 @@ H5File::write_att (const char *location, const char *attname, error ("matrix type attributes are not yet supported."); return; // dims = alloc_hsize (attvalue.dims (), ALLOC_HSIZE_DEFAULT, true); - // dspace_id = H5Screate_simple (attvalue.dims ().length (), dims, NULL); + // dspace_id = H5Screate_simple (attvalue.dims ().numel (), dims, NULL); // free (dims); } else @@ -1417,7 +1463,7 @@ H5File::write_att (const char *location, const char *attname, buf = (void *) attvalue.string_value ().c_str (); } - else if (attvalue.is_integer_type ()) + else if (attvalue.isinteger ()) { //type_id = H5Tcopy (H5T_STD_I64LE); //cannot read this back in then, don't know why type_id = H5Tcopy (H5T_NATIVE_INT); @@ -1425,14 +1471,14 @@ H5File::write_att (const char *location, const char *attname, attval_int = attvalue.int_value (); buf = (void *) &attval_int; } - else if (attvalue.is_real_type ()) + else if (attvalue.isreal ()) { type_id = H5Tcopy (H5T_NATIVE_DOUBLE); mem_type_id = H5Tcopy (H5T_NATIVE_DOUBLE); attval_double = attvalue.double_value (); buf = (void *) &attval_double; } - else if (attvalue.is_complex_type ()) + else if (attvalue.iscomplex ()) { error ("complex values are not supported by the HDF5 format. \ You have to save real and imag part separately."); @@ -1525,18 +1571,18 @@ H5File::create_dset (const char *location, const Matrix& size, hsize_t *dims = alloc_hsize (size, ALLOC_HSIZE_INF_TO_ZERO, true); // and produce unlimited maximum extent for.. hsize_t *maxdims = alloc_hsize (size, ALLOC_HSIZE_INFZERO_TO_UNLIMITED, true); - dspace_id = H5Screate_simple (size.nelem (), dims, maxdims); + dspace_id = H5Screate_simple (size.numel (), dims, maxdims); free (dims); free (maxdims); - if (any_int_leq_zero (size) && chunksize.is_empty ()) + if (any_int_leq_zero (size) && chunksize.isempty ()) { error ("If the size argument contains an Inf or zero element, then ChunkSize must be specified."); return; } // get a dataset creation property list hid_t crp_list = H5Pcreate (H5P_DATASET_CREATE); - if (! chunksize.is_empty ()) + if (! chunksize.isempty ()) { // a dataset with an unlimited dimension must be chunked. if (chunksize(0) == 0) @@ -1548,22 +1594,26 @@ H5File::create_dset (const char *location, const Matrix& size, error ("Could not set chunked layout of %s", location); return; } - if (H5Pset_chunk (crp_list, size.nelem (), dims_chunk) < 0) + if (H5Pset_chunk (crp_list, size.numel (), dims_chunk) < 0) { error ("Could not set chunk size of %s", location); return; } free (dims_chunk); } - + + // create non-existent intermediate groups. + hid_t lcpl_list = H5Pcreate (H5P_LINK_CREATE); + H5Pset_create_intermediate_group (lcpl_list, 1); dset_id = H5Dcreate (file, location, type_id, dspace_id, - H5P_DEFAULT, crp_list, H5P_DEFAULT); + lcpl_list, crp_list, H5P_DEFAULT); if (dset_id < 0) { error ("Could not create dataset %s", location); return; } H5Pclose (crp_list); + H5Pclose (lcpl_list); } @@ -1605,7 +1655,7 @@ H5File::get_auto_chunksize(const Matrix& dset_shape, int typesize) const int CHUNK_MAX = 1024*1024; // Hard upper limit (1M) Matrix chunksize = dset_shape; - int ndims = chunksize.length (); + int ndims = chunksize.numel (); for (int i = 0; i < ndims; i++) { //For unlimited dimensions we have to guess 1024 diff --git a/h5read.h b/h5read.h index ba5361d..813ba4d 100644 --- a/h5read.h +++ b/h5read.h @@ -39,7 +39,8 @@ class H5File public: - H5File (const char *filename, const bool create_if_nonexisting); + H5File (const char *filename, const bool create_if_nonexisting, + const bool write_access); ~H5File (); diff --git a/increment_version.sh b/increment_version.sh new file mode 100755 index 0000000..6c05e51 --- /dev/null +++ b/increment_version.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +echo -n "Enter new version: " +read vers +sed -i "s/VERSION=.*/VERSION=$vers/" makefile +sed -i "s/Version:.*/Version: $vers/" package/DESCRIPTION diff --git a/makefile b/makefile index 7d3cd8b..6d617b3 100644 --- a/makefile +++ b/makefile @@ -3,9 +3,13 @@ src= h5read.cc headers=h5read.h octs=$(src:.cc=.oct) objs=$(src:.cc=.o) -MKOCTFILE=CXX=$(CXX) mkoctfile -g -VERSION=0.4.0 +H5FLAGS=$(shell octave --eval 'exit(__octave_config_info__ ("build_features").HDF5 != 1)' &> /dev/null && echo "-DHAVE_HDF5") \ +$(shell octave --eval 'exit(__octave_config_info__ ("build_features").HDF5_18 != 1)' &> /dev/null && echo "-DHAVE_HDF5_18") + +MKOCTFILE=CXX="$(CXX)" CXXFLAGS="-ansi" mkoctfile -v -std=c++11 $(H5FLAGS) + +VERSION=0.5.0 PACKAGEFILE=hdf5oct-$(VERSION).tar.gz .PHONY: test clean install uninstall package @@ -13,6 +17,7 @@ PACKAGEFILE=hdf5oct-$(VERSION).tar.gz all: $(octs) package %.oct: $(objs) + echo $(MKOCTFILE) -o $@ $(objs) $(MKOCTFILE) -o $@ $(objs) %.o: %.cc $(headers) diff --git a/package/DESCRIPTION b/package/DESCRIPTION index b27cc8b..3f311ff 100644 --- a/package/DESCRIPTION +++ b/package/DESCRIPTION @@ -1,5 +1,5 @@ Name: hdf5oct -Version: 0.2.0 +Version: 0.5.0 Date: 2015-10-02 Author: Tom Mullins, Anton Starikov, Thorsten Liebig, Stefan Großhauser Maintainer: Stefan Großhauser diff --git a/test/h5test.m b/test/h5test.m index 5338634..b614546 100644 --- a/test/h5test.m +++ b/test/h5test.m @@ -110,6 +110,9 @@ function read_write_chunk_at(filename, dsetname, chunk, start) %%%%%%%% h5create("test.h5","created_dset_inf23",[ 2 3 4],'Datatype','int8', 'ChunkSize', [2 3 2]) +%%%%%%%% +h5create("test.h5","/nonexistent/groups/created_dset_single",[1],'Datatype','single') + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% disp("Test h5write and h5read...")