Chris@49: // Copyright (C) 2012 Ryan Curtin Chris@49: // Copyright (C) 2012 Conrad Sanderson Chris@49: // Copyright (C) 2013 Szabolcs Horvat Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: //! \addtogroup hdf5_misc Chris@49: //! @{ Chris@49: Chris@49: Chris@49: #if defined(ARMA_USE_HDF5) Chris@49: namespace hdf5_misc Chris@49: { Chris@49: Chris@49: Chris@49: //! Given a certain type, find the corresponding HDF5 datatype. This can't be Chris@49: //! done entirely at compile time, unfortunately, because the H5T_* macros Chris@49: //! depend on function calls. Chris@49: template< typename eT > Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type() Chris@49: { Chris@49: return -1; // Return invalid. Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! Specializations for each valid element type Chris@49: //! (taken from all the possible typedefs of {u8, s8, ..., u64, s64} and the other native types. Chris@49: //! We can't use the actual u8/s8 typedefs because their relations to the H5T_... types are unclear. Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< unsigned char >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_UCHAR); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< char >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_CHAR); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< short >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_SHORT); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< unsigned short >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_USHORT); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< int >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_INT); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< unsigned int >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_UINT); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< long >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_LONG); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< unsigned long >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_ULONG); Chris@49: } Chris@49: Chris@49: Chris@49: #if defined(ARMA_USE_U64S64) && defined(ULLONG_MAX) Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< long long >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_LLONG); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< unsigned long long >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_ULLONG); Chris@49: } Chris@49: #endif Chris@49: Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< float >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_FLOAT); Chris@49: } Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< double >() Chris@49: { Chris@49: return H5Tcopy(H5T_NATIVE_DOUBLE); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! Utility hid_t since HOFFSET() won't work with std::complex. Chris@49: template Chris@49: struct hdf5_complex_t Chris@49: { Chris@49: eT real; Chris@49: eT imag; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< std::complex >() Chris@49: { Chris@49: hid_t type = H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t)); Chris@49: Chris@49: H5Tinsert(type, "real", HOFFSET(hdf5_complex_t, real), H5T_NATIVE_FLOAT); Chris@49: H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t, imag), H5T_NATIVE_FLOAT); Chris@49: Chris@49: return type; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template<> Chris@49: inline Chris@49: hid_t Chris@49: get_hdf5_type< std::complex >() Chris@49: { Chris@49: hid_t type = H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t)); Chris@49: Chris@49: H5Tinsert(type, "real", HOFFSET(hdf5_complex_t, real), H5T_NATIVE_DOUBLE); Chris@49: H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t, imag), H5T_NATIVE_DOUBLE); Chris@49: Chris@49: return type; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: // Compare datatype against all supported types. Chris@49: inline Chris@49: bool Chris@49: is_supported_arma_hdf5_type(hid_t datatype) Chris@49: { Chris@49: hid_t search_type; Chris@49: Chris@49: bool is_equal; Chris@49: Chris@49: Chris@49: // start with most likely used types: double, complex, float, complex Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type< std::complex >(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type< std::complex >(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: Chris@49: // remaining supported types: u8, s8, u16, s16, u32, s32, u64, s64, ulng_t, slng_t Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: #if defined(ARMA_USE_U64S64) Chris@49: { Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: } Chris@49: #endif Chris@49: Chris@49: #if defined(ARMA_ALLOW_LONG) Chris@49: { Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = ( H5Tequal(datatype, search_type) > 0 ); Chris@49: H5Tclose(search_type); Chris@49: if (is_equal) { return true; } Chris@49: } Chris@49: #endif Chris@49: Chris@49: return false; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! Auxiliary functions and structs for search_hdf5_file. Chris@49: struct hdf5_search_info Chris@49: { Chris@49: const std::vector& names; Chris@49: int num_dims; Chris@49: bool exact; Chris@49: hid_t best_match; Chris@49: size_t best_match_position; // Position of best match in names vector. Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: inline Chris@49: herr_t Chris@49: hdf5_search_callback Chris@49: ( Chris@49: hid_t loc_id, Chris@49: const char* name, Chris@49: const H5O_info_t* info, Chris@49: void* operator_data // hdf5_search_info Chris@49: ) Chris@49: { Chris@49: hdf5_search_info* search_info = (hdf5_search_info*) operator_data; Chris@49: Chris@49: // We are looking for datasets. Chris@49: if (info->type == H5O_TYPE_DATASET) Chris@49: { Chris@49: // Check type of dataset to see if we could even load it. Chris@49: hid_t dataset = H5Dopen(loc_id, name, H5P_DEFAULT); Chris@49: hid_t datatype = H5Dget_type(dataset); Chris@49: Chris@49: const bool is_supported = is_supported_arma_hdf5_type(datatype); Chris@49: Chris@49: H5Tclose(datatype); Chris@49: H5Dclose(dataset); Chris@49: Chris@49: if(is_supported == false) Chris@49: { Chris@49: // Forget about it and move on. Chris@49: return 0; Chris@49: } Chris@49: Chris@49: // Now we have to check against our set of names. Chris@49: // Only check names which could be better. Chris@49: for (size_t string_pos = 0; string_pos < search_info->best_match_position; ++string_pos) Chris@49: { Chris@49: // name is the full path (/path/to/dataset); names[string_pos] may be Chris@49: // "dataset", "/to/dataset", or "/path/to/dataset". Chris@49: // So if we count the number of forward slashes in names[string_pos], Chris@49: // and then simply take the last substring of name containing that number of slashes, Chris@49: // we can do the comparison. Chris@49: Chris@49: // Count the number of forward slashes in names[string_pos]. Chris@49: uword count = 0; Chris@49: for (uword i = 0; i < search_info->names[string_pos].length(); ++i) Chris@49: { Chris@49: if ((search_info->names[string_pos])[i] == '/') { ++count; } Chris@49: } Chris@49: Chris@49: // Count the number of forward slashes in the full name. Chris@49: uword name_count = 0; Chris@49: const std::string str = std::string(name); Chris@49: for (uword i = 0; i < str.length(); ++i) Chris@49: { Chris@49: if (str[i] == '/') { ++count; } Chris@49: } Chris@49: Chris@49: // If we are asking for more slashes than we have, this can't be a match. Chris@49: // Skip to below, where we decide whether or not to keep it anyway based Chris@49: // on the exactness condition of the search. Chris@49: if (count <= name_count) Chris@49: { Chris@49: size_t start_pos = (count == 0) ? 0 : std::string::npos; Chris@49: while (count > 0) Chris@49: { Chris@49: // Move pointer to previous slash. Chris@49: start_pos = str.rfind('/', start_pos); Chris@49: Chris@49: // Break if we've run out of slashes. Chris@49: if (start_pos == std::string::npos) { break; } Chris@49: Chris@49: --count; Chris@49: } Chris@49: Chris@49: // Now take the substring (this may end up being the full string). Chris@49: const std::string substring = str.substr(start_pos); Chris@49: Chris@49: // Are they the same? Chris@49: if (substring == search_info->names[string_pos]) Chris@49: { Chris@49: // We have found the object; it must be better than our existing match. Chris@49: hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT); Chris@49: Chris@49: Chris@49: // arma_check(match_candidate < 0, "Mat::load(): cannot open an HDF5 dataset"); Chris@49: if(match_candidate < 0) Chris@49: { Chris@49: return -1; Chris@49: } Chris@49: Chris@49: Chris@49: // Ensure that the dataset is valid and of the correct dimensionality. Chris@49: hid_t filespace = H5Dget_space(match_candidate); Chris@49: int num_dims = H5Sget_simple_extent_ndims(filespace); Chris@49: Chris@49: if (num_dims <= search_info->num_dims) Chris@49: { Chris@49: // Valid dataset -- we'll keep it. Chris@49: // If we already have an existing match we have to close it. Chris@49: if (search_info->best_match != -1) Chris@49: { Chris@49: H5Dclose(search_info->best_match); Chris@49: } Chris@49: Chris@49: search_info->best_match_position = string_pos; Chris@49: search_info->best_match = match_candidate; Chris@49: } Chris@49: Chris@49: H5Sclose(filespace); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: // If they are not the same, but we have not found anything and we don't need an exact match, take this. Chris@49: if ((search_info->exact == false) && (search_info->best_match == -1)) Chris@49: { Chris@49: hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT); Chris@49: Chris@49: // arma_check(match_candidate < 0, "Mat::load(): cannot open an HDF5 dataset"); Chris@49: if(match_candidate < 0) Chris@49: { Chris@49: return -1; Chris@49: } Chris@49: Chris@49: hid_t filespace = H5Dget_space(match_candidate); Chris@49: int num_dims = H5Sget_simple_extent_ndims(filespace); Chris@49: Chris@49: if (num_dims <= search_info->num_dims) Chris@49: { Chris@49: // Valid dataset -- we'll keep it. Chris@49: search_info->best_match = H5Dopen(loc_id, name, H5P_DEFAULT); Chris@49: } Chris@49: Chris@49: H5Sclose(filespace); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: return 0; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! Search an HDF5 file for the given dataset names. Chris@49: //! If 'exact' is true, failure to find a dataset in the list of names means that -1 is returned. Chris@49: //! If 'exact' is false and no datasets are found, -1 is returned. Chris@49: //! The number of dimensions is used to help prune down invalid datasets; Chris@49: //! 2 dimensions is a matrix, 1 dimension is a vector, and 3 dimensions is a cube. Chris@49: //! If the number of dimensions in a dataset is less than or equal to num_dims, Chris@49: //! it will be considered -- for instance, a one-dimensional HDF5 vector can be loaded as a single-column matrix. Chris@49: inline Chris@49: hid_t Chris@49: search_hdf5_file Chris@49: ( Chris@49: const std::vector& names, Chris@49: hid_t hdf5_file, Chris@49: int num_dims = 2, Chris@49: bool exact = false Chris@49: ) Chris@49: { Chris@49: hdf5_search_info search_info = { names, num_dims, exact, -1, names.size() }; Chris@49: Chris@49: // We'll use the H5Ovisit to track potential entries. Chris@49: herr_t status = H5Ovisit(hdf5_file, H5_INDEX_NAME, H5_ITER_NATIVE, hdf5_search_callback, void_ptr(&search_info)); Chris@49: Chris@49: // Return the best match; it will be -1 if there was a problem. Chris@49: return (status < 0) ? -1 : search_info.best_match; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! Load an HDF5 matrix into an array of type specified by datatype, Chris@49: //! then convert that into the desired array 'dest'. Chris@49: //! This should only be called when eT is not the datatype. Chris@49: template Chris@49: inline Chris@49: hid_t Chris@49: load_and_convert_hdf5 Chris@49: ( Chris@49: eT *dest, Chris@49: hid_t dataset, Chris@49: hid_t datatype, Chris@49: uword n_elem Chris@49: ) Chris@49: { Chris@49: Chris@49: // We can't use nice template specializations here Chris@49: // as the determination of the type of 'datatype' must be done at runtime. Chris@49: // So we end up with this ugliness... Chris@49: hid_t search_type; Chris@49: Chris@49: bool is_equal; Chris@49: Chris@49: Chris@49: // u8 Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // s8 Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // u16 Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // s16 Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // u32 Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // s32 Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: #if defined(ARMA_USE_U64S64) Chris@49: { Chris@49: // u64 Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // s64 Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: } Chris@49: #endif Chris@49: Chris@49: Chris@49: #if defined(ARMA_ALLOW_LONG) Chris@49: { Chris@49: // ulng_t Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // slng_t Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: } Chris@49: #endif Chris@49: Chris@49: Chris@49: // float Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // double Chris@49: search_type = get_hdf5_type(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: Col v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // complex float Chris@49: search_type = get_hdf5_type< std::complex >(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: if(is_complex::value == false) Chris@49: { Chris@49: return -1; // can't read complex data into non-complex matrix/cube Chris@49: } Chris@49: Chris@49: Col< std::complex > v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert_cx(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: // complex double Chris@49: search_type = get_hdf5_type< std::complex >(); Chris@49: is_equal = (H5Tequal(datatype, search_type) > 0); Chris@49: H5Tclose(search_type); Chris@49: Chris@49: if(is_equal) Chris@49: { Chris@49: if(is_complex::value == false) Chris@49: { Chris@49: return -1; // can't read complex data into non-complex matrix/cube Chris@49: } Chris@49: Chris@49: Col< std::complex > v(n_elem); Chris@49: hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); Chris@49: arrayops::convert_cx(dest, v.memptr(), n_elem); Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: return -1; // Failure. Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: } // namespace hdf5_misc Chris@49: #endif // #if defined(ARMA_USE_HDF5) Chris@49: Chris@49: Chris@49: Chris@49: //! @}