| diskio_meat.hpp | | diskio_meat.hpp | |
| | | | |
| skipping to change at line 1244 | | skipping to change at line 1244 | |
| bool | | bool | |
| diskio::save_hdf5_binary(const Mat<eT>& x, const std::string& final_name) | | diskio::save_hdf5_binary(const Mat<eT>& x, const std::string& final_name) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| #if defined(ARMA_USE_HDF5) | | #if defined(ARMA_USE_HDF5) | |
| { | | { | |
| #if !defined(ARMA_PRINT_HDF5_ERRORS) | | #if !defined(ARMA_PRINT_HDF5_ERRORS) | |
| { | | { | |
| // Disable annoying HDF5 error messages. | | // Disable annoying HDF5 error messages. | |
|
| H5Eset_auto(H5E_DEFAULT, NULL, NULL); | | arma_H5Eset_auto(H5E_DEFAULT, NULL, NULL); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| bool save_okay = false; | | bool save_okay = false; | |
| | | | |
| const std::string tmp_name = diskio::gen_tmp_name(final_name); | | const std::string tmp_name = diskio::gen_tmp_name(final_name); | |
| | | | |
| // Set up the file according to HDF5's preferences | | // Set up the file according to HDF5's preferences | |
|
| hid_t file = H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5
P_DEFAULT); | | hid_t file = arma_H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAUL
T, H5P_DEFAULT); | |
| | | | |
| // We need to create a dataset, datatype, and dataspace | | // We need to create a dataset, datatype, and dataspace | |
| hsize_t dims[2]; | | hsize_t dims[2]; | |
| dims[1] = x.n_rows; | | dims[1] = x.n_rows; | |
| dims[0] = x.n_cols; | | dims[0] = x.n_cols; | |
| | | | |
|
| hid_t dataspace = H5Screate_simple(2, dims, NULL); // treat the matri
x as a 2d array dataspace | | hid_t dataspace = arma_H5Screate_simple(2, dims, NULL); // treat the
matrix as a 2d array dataspace | |
| hid_t datatype = hdf5_misc::get_hdf5_type<eT>(); | | hid_t datatype = hdf5_misc::get_hdf5_type<eT>(); | |
| | | | |
| // If this returned something invalid, well, it's time to crash. | | // If this returned something invalid, well, it's time to crash. | |
| arma_check(datatype == -1, "Mat::save(): unknown datatype for HDF5"); | | arma_check(datatype == -1, "Mat::save(): unknown datatype for HDF5"); | |
| | | | |
| // MATLAB forces the users to specify a name at save time for HDF5; Oct
ave | | // MATLAB forces the users to specify a name at save time for HDF5; Oct
ave | |
| // will use the default of 'dataset' unless otherwise specified, so we
will | | // will use the default of 'dataset' unless otherwise specified, so we
will | |
| // use that. | | // use that. | |
|
| hid_t dataset = H5Dcreate(file, "dataset", datatype, dataspace, H5P_DEF
AULT, H5P_DEFAULT, H5P_DEFAULT); | | hid_t dataset = arma_H5Dcreate(file, "dataset", datatype, dataspace, H5
P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
| | | | |
| // H5Dwrite does not make a distinction between row-major and column-ma
jor; | | // H5Dwrite does not make a distinction between row-major and column-ma
jor; | |
| // it just writes the memory. MATLAB and Octave store HDF5 matrices as | | // it just writes the memory. MATLAB and Octave store HDF5 matrices as | |
| // column-major, though, so we can save ours like that too and not need
to | | // column-major, though, so we can save ours like that too and not need
to | |
| // transpose. | | // transpose. | |
|
| herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAU
LT, x.mem); | | herr_t status = arma_H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_
DEFAULT, x.mem); | |
| save_okay = (status >= 0); | | save_okay = (status >= 0); | |
| | | | |
|
| H5Dclose(dataset); | | arma_H5Dclose(dataset); | |
| H5Tclose(datatype); | | arma_H5Tclose(datatype); | |
| H5Sclose(dataspace); | | arma_H5Sclose(dataspace); | |
| H5Fclose(file); | | arma_H5Fclose(file); | |
| | | | |
| if(save_okay == true) { save_okay = diskio::safe_rename(tmp_name, final
_name); } | | if(save_okay == true) { save_okay = diskio::safe_rename(tmp_name, final
_name); } | |
| | | | |
| return save_okay; | | return save_okay; | |
| } | | } | |
| #else | | #else | |
| { | | { | |
| arma_ignore(x); | | arma_ignore(x); | |
| arma_ignore(final_name); | | arma_ignore(final_name); | |
| | | | |
| | | | |
| skipping to change at line 1943 | | skipping to change at line 1943 | |
| #if defined(ARMA_USE_HDF5) | | #if defined(ARMA_USE_HDF5) | |
| { | | { | |
| | | | |
| // These may be necessary to store the error handler (if we need to). | | // These may be necessary to store the error handler (if we need to). | |
| herr_t (*old_func)(hid_t, void*); | | herr_t (*old_func)(hid_t, void*); | |
| void *old_client_data; | | void *old_client_data; | |
| | | | |
| #if !defined(ARMA_PRINT_HDF5_ERRORS) | | #if !defined(ARMA_PRINT_HDF5_ERRORS) | |
| { | | { | |
| // Save old error handler. | | // Save old error handler. | |
|
| H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data); | | arma_H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data); | |
| | | | |
| // Disable annoying HDF5 error messages. | | // Disable annoying HDF5 error messages. | |
|
| H5Eset_auto(H5E_DEFAULT, NULL, NULL); | | arma_H5Eset_auto(H5E_DEFAULT, NULL, NULL); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| bool load_okay = false; | | bool load_okay = false; | |
| | | | |
|
| hid_t fid = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); | | hid_t fid = arma_H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); | |
| | | | |
| if(fid >= 0) | | if(fid >= 0) | |
| { | | { | |
| // MATLAB HDF5 dataset names are user-specified; | | // MATLAB HDF5 dataset names are user-specified; | |
| // Octave tends to store the datasets in a group, with the actual dat
aset being referred to as "value". | | // Octave tends to store the datasets in a group, with the actual dat
aset being referred to as "value". | |
| // So we will search for "dataset" and "value", and if those are not
found we will take the first dataset we do find. | | // So we will search for "dataset" and "value", and if those are not
found we will take the first dataset we do find. | |
| std::vector<std::string> searchNames; | | std::vector<std::string> searchNames; | |
| searchNames.push_back("dataset"); | | searchNames.push_back("dataset"); | |
| searchNames.push_back("value"); | | searchNames.push_back("value"); | |
| | | | |
| hid_t dataset = hdf5_misc::search_hdf5_file(searchNames, fid, 2, fals
e); | | hid_t dataset = hdf5_misc::search_hdf5_file(searchNames, fid, 2, fals
e); | |
| | | | |
| if(dataset >= 0) | | if(dataset >= 0) | |
| { | | { | |
|
| hid_t filespace = H5Dget_space(dataset); | | hid_t filespace = arma_H5Dget_space(dataset); | |
| | | | |
| // This must be <= 2 due to our search rules. | | // This must be <= 2 due to our search rules. | |
|
| const int ndims = H5Sget_simple_extent_ndims(filespace); | | const int ndims = arma_H5Sget_simple_extent_ndims(filespace); | |
| | | | |
| hsize_t dims[2]; | | hsize_t dims[2]; | |
|
| const herr_t query_status = H5Sget_simple_extent_dims(filespace, di
ms, NULL); | | const herr_t query_status = arma_H5Sget_simple_extent_dims(filespac
e, dims, NULL); | |
| | | | |
| // arma_check(query_status < 0, "Mat::load(): cannot get size of HD
F5 dataset"); | | // arma_check(query_status < 0, "Mat::load(): cannot get size of HD
F5 dataset"); | |
| if(query_status < 0) | | if(query_status < 0) | |
| { | | { | |
| err_msg = "cannot get size of HDF5 dataset in "; | | err_msg = "cannot get size of HDF5 dataset in "; | |
| | | | |
|
| H5Sclose(filespace); | | arma_H5Sclose(filespace); | |
| H5Dclose(dataset); | | arma_H5Dclose(dataset); | |
| H5Fclose(fid); | | arma_H5Fclose(fid); | |
| | | | |
| #if !defined(ARMA_PRINT_HDF5_ERRORS) | | #if !defined(ARMA_PRINT_HDF5_ERRORS) | |
| { | | { | |
| // Restore HDF5 error handler. | | // Restore HDF5 error handler. | |
|
| H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); | | arma_H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| if(ndims == 1) { dims[1] = 1; } // Vector case; fake second dimens
ion (one column). | | if(ndims == 1) { dims[1] = 1; } // Vector case; fake second dimens
ion (one column). | |
| | | | |
| x.set_size(dims[1], dims[0]); | | x.set_size(dims[1], dims[0]); | |
| | | | |
| // Now we have to see what type is stored to figure out how to load
it. | | // Now we have to see what type is stored to figure out how to load
it. | |
|
| hid_t datatype = H5Dget_type(dataset); | | hid_t datatype = arma_H5Dget_type(dataset); | |
| hid_t mat_type = hdf5_misc::get_hdf5_type<eT>(); | | hid_t mat_type = hdf5_misc::get_hdf5_type<eT>(); | |
| | | | |
| // If these are the same type, it is simple. | | // If these are the same type, it is simple. | |
|
| if(H5Tequal(datatype, mat_type) > 0) | | if(arma_H5Tequal(datatype, mat_type) > 0) | |
| { | | { | |
| // Load directly; H5S_ALL used so that we load the entire dataset
. | | // Load directly; H5S_ALL used so that we load the entire dataset
. | |
|
| hid_t read_status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL,
H5P_DEFAULT, void_ptr(x.memptr())); | | hid_t read_status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_
ALL, H5P_DEFAULT, void_ptr(x.memptr())); | |
| | | | |
| if(read_status >= 0) { load_okay = true; } | | if(read_status >= 0) { load_okay = true; } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // Load into another array and convert its type accordingly. | | // Load into another array and convert its type accordingly. | |
| hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(),
dataset, datatype, x.n_elem); | | hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(),
dataset, datatype, x.n_elem); | |
| | | | |
| if(read_status >= 0) { load_okay = true; } | | if(read_status >= 0) { load_okay = true; } | |
| } | | } | |
| | | | |
| // Now clean up. | | // Now clean up. | |
|
| H5Tclose(datatype); | | arma_H5Tclose(datatype); | |
| H5Tclose(mat_type); | | arma_H5Tclose(mat_type); | |
| H5Sclose(filespace); | | arma_H5Sclose(filespace); | |
| } | | } | |
| | | | |
|
| H5Dclose(dataset); | | arma_H5Dclose(dataset); | |
| | | | |
|
| H5Fclose(fid); | | arma_H5Fclose(fid); | |
| | | | |
| if(load_okay == false) | | if(load_okay == false) | |
| { | | { | |
| err_msg = "unsupported or incorrect HDF5 data in "; | | err_msg = "unsupported or incorrect HDF5 data in "; | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| err_msg = "cannot open file "; | | err_msg = "cannot open file "; | |
| } | | } | |
| | | | |
| #if !defined(ARMA_PRINT_HDF5_ERRORS) | | #if !defined(ARMA_PRINT_HDF5_ERRORS) | |
| { | | { | |
| // Restore HDF5 error handler. | | // Restore HDF5 error handler. | |
|
| H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); | | arma_H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| return load_okay; | | return load_okay; | |
| } | | } | |
| #else | | #else | |
| { | | { | |
| arma_ignore(x); | | arma_ignore(x); | |
| arma_ignore(name); | | arma_ignore(name); | |
| arma_ignore(err_msg); | | arma_ignore(err_msg); | |
| | | | |
| skipping to change at line 2070 | | skipping to change at line 2070 | |
| //! Try to load a matrix by automatically determining its type | | //! Try to load a matrix by automatically determining its type | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| bool | | bool | |
| diskio::load_auto_detect(Mat<eT>& x, const std::string& name, std::string&
err_msg) | | diskio::load_auto_detect(Mat<eT>& x, const std::string& name, std::string&
err_msg) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| #if defined(ARMA_USE_HDF5) | | #if defined(ARMA_USE_HDF5) | |
| // We're currently using the C bindings for the HDF5 library, which don
't support C++ streams | | // We're currently using the C bindings for the HDF5 library, which don
't support C++ streams | |
|
| if( H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name, err_m
sg); } | | if( arma_H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name,
err_msg); } | |
| #endif | | #endif | |
| | | | |
| std::fstream f; | | std::fstream f; | |
| f.open(name.c_str(), std::fstream::in | std::fstream::binary); | | f.open(name.c_str(), std::fstream::in | std::fstream::binary); | |
| | | | |
| bool load_okay = f.is_open(); | | bool load_okay = f.is_open(); | |
| | | | |
| if(load_okay == true) | | if(load_okay == true) | |
| { | | { | |
| load_okay = diskio::load_auto_detect(x, f, err_msg); | | load_okay = diskio::load_auto_detect(x, f, err_msg); | |
| | | | |
| skipping to change at line 3176 | | skipping to change at line 3176 | |
| bool | | bool | |
| diskio::save_hdf5_binary(const Cube<eT>& x, const std::string& final_name) | | diskio::save_hdf5_binary(const Cube<eT>& x, const std::string& final_name) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| #if defined(ARMA_USE_HDF5) | | #if defined(ARMA_USE_HDF5) | |
| { | | { | |
| #if !defined(ARMA_PRINT_HDF5_ERRORS) | | #if !defined(ARMA_PRINT_HDF5_ERRORS) | |
| { | | { | |
| // Disable annoying HDF5 error messages. | | // Disable annoying HDF5 error messages. | |
|
| H5Eset_auto(H5E_DEFAULT, NULL, NULL); | | arma_H5Eset_auto(H5E_DEFAULT, NULL, NULL); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| bool save_okay = false; | | bool save_okay = false; | |
| | | | |
| const std::string tmp_name = diskio::gen_tmp_name(final_name); | | const std::string tmp_name = diskio::gen_tmp_name(final_name); | |
| | | | |
| // Set up the file according to HDF5's preferences | | // Set up the file according to HDF5's preferences | |
|
| hid_t file = H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5
P_DEFAULT); | | hid_t file = arma_H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAUL
T, H5P_DEFAULT); | |
| | | | |
| // We need to create a dataset, datatype, and dataspace | | // We need to create a dataset, datatype, and dataspace | |
| hsize_t dims[3]; | | hsize_t dims[3]; | |
| dims[2] = x.n_rows; | | dims[2] = x.n_rows; | |
| dims[1] = x.n_cols; | | dims[1] = x.n_cols; | |
| dims[0] = x.n_slices; | | dims[0] = x.n_slices; | |
| | | | |
|
| hid_t dataspace = H5Screate_simple(3, dims, NULL); // treat the cube
as a 3d array dataspace | | hid_t dataspace = arma_H5Screate_simple(3, dims, NULL); // treat the
cube as a 3d array dataspace | |
| hid_t datatype = hdf5_misc::get_hdf5_type<eT>(); | | hid_t datatype = hdf5_misc::get_hdf5_type<eT>(); | |
| | | | |
| // If this returned something invalid, well, it's time to crash. | | // If this returned something invalid, well, it's time to crash. | |
| arma_check(datatype == -1, "Cube::save(): unknown datatype for HDF5"); | | arma_check(datatype == -1, "Cube::save(): unknown datatype for HDF5"); | |
| | | | |
| // MATLAB forces the users to specify a name at save time for HDF5; Oct
ave | | // MATLAB forces the users to specify a name at save time for HDF5; Oct
ave | |
| // will use the default of 'dataset' unless otherwise specified, so we
will | | // will use the default of 'dataset' unless otherwise specified, so we
will | |
| // use that. | | // use that. | |
|
| hid_t dataset = H5Dcreate(file, "dataset", datatype, dataspace, H5P_DEF
AULT, H5P_DEFAULT, H5P_DEFAULT); | | hid_t dataset = arma_H5Dcreate(file, "dataset", datatype, dataspace, H5
P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
| | | | |
|
| herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAU
LT, x.mem); | | herr_t status = arma_H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_
DEFAULT, x.mem); | |
| save_okay = (status >= 0); | | save_okay = (status >= 0); | |
| | | | |
|
| H5Dclose(dataset); | | arma_H5Dclose(dataset); | |
| H5Tclose(datatype); | | arma_H5Tclose(datatype); | |
| H5Sclose(dataspace); | | arma_H5Sclose(dataspace); | |
| H5Fclose(file); | | arma_H5Fclose(file); | |
| | | | |
| if(save_okay == true) { save_okay = diskio::safe_rename(tmp_name, final
_name); } | | if(save_okay == true) { save_okay = diskio::safe_rename(tmp_name, final
_name); } | |
| | | | |
| return save_okay; | | return save_okay; | |
| } | | } | |
| #else | | #else | |
| { | | { | |
| arma_ignore(x); | | arma_ignore(x); | |
| arma_ignore(final_name); | | arma_ignore(final_name); | |
| | | | |
| | | | |
| skipping to change at line 3488 | | skipping to change at line 3488 | |
| #if defined(ARMA_USE_HDF5) | | #if defined(ARMA_USE_HDF5) | |
| { | | { | |
| | | | |
| // These may be necessary to store the error handler (if we need to). | | // These may be necessary to store the error handler (if we need to). | |
| herr_t (*old_func)(hid_t, void*); | | herr_t (*old_func)(hid_t, void*); | |
| void *old_client_data; | | void *old_client_data; | |
| | | | |
| #if !defined(ARMA_PRINT_HDF5_ERRORS) | | #if !defined(ARMA_PRINT_HDF5_ERRORS) | |
| { | | { | |
| // Save old error handler. | | // Save old error handler. | |
|
| H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data); | | arma_H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data); | |
| | | | |
| // Disable annoying HDF5 error messages. | | // Disable annoying HDF5 error messages. | |
|
| H5Eset_auto(H5E_DEFAULT, NULL, NULL); | | arma_H5Eset_auto(H5E_DEFAULT, NULL, NULL); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| bool load_okay = false; | | bool load_okay = false; | |
| | | | |
|
| hid_t fid = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); | | hid_t fid = arma_H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); | |
| | | | |
| if(fid >= 0) | | if(fid >= 0) | |
| { | | { | |
| // MATLAB HDF5 dataset names are user-specified; | | // MATLAB HDF5 dataset names are user-specified; | |
| // Octave tends to store the datasets in a group, with the actual dat
aset being referred to as "value". | | // Octave tends to store the datasets in a group, with the actual dat
aset being referred to as "value". | |
| // So we will search for "dataset" and "value", and if those are not
found we will take the first dataset we do find. | | // So we will search for "dataset" and "value", and if those are not
found we will take the first dataset we do find. | |
| std::vector<std::string> searchNames; | | std::vector<std::string> searchNames; | |
| searchNames.push_back("dataset"); | | searchNames.push_back("dataset"); | |
| searchNames.push_back("value"); | | searchNames.push_back("value"); | |
| | | | |
| hid_t dataset = hdf5_misc::search_hdf5_file(searchNames, fid, 3, fals
e); | | hid_t dataset = hdf5_misc::search_hdf5_file(searchNames, fid, 3, fals
e); | |
| | | | |
| if(dataset >= 0) | | if(dataset >= 0) | |
| { | | { | |
| hid_t filespace = H5Dget_space(dataset); | | hid_t filespace = H5Dget_space(dataset); | |
| | | | |
| // This must be <= 3 due to our search rules. | | // This must be <= 3 due to our search rules. | |
|
| const int ndims = H5Sget_simple_extent_ndims(filespace); | | const int ndims = arma_H5Sget_simple_extent_ndims(filespace); | |
| | | | |
| hsize_t dims[3]; | | hsize_t dims[3]; | |
|
| const herr_t query_status = H5Sget_simple_extent_dims(filespace, di
ms, NULL); | | const herr_t query_status = arma_H5Sget_simple_extent_dims(filespac
e, dims, NULL); | |
| | | | |
| // arma_check(query_status < 0, "Cube::load(): cannot get size of H
DF5 dataset"); | | // arma_check(query_status < 0, "Cube::load(): cannot get size of H
DF5 dataset"); | |
| if(query_status < 0) | | if(query_status < 0) | |
| { | | { | |
| err_msg = "cannot get size of HDF5 dataset in "; | | err_msg = "cannot get size of HDF5 dataset in "; | |
| | | | |
|
| H5Sclose(filespace); | | arma_H5Sclose(filespace); | |
| H5Dclose(dataset); | | arma_H5Dclose(dataset); | |
| H5Fclose(fid); | | arma_H5Fclose(fid); | |
| | | | |
| #if !defined(ARMA_PRINT_HDF5_ERRORS) | | #if !defined(ARMA_PRINT_HDF5_ERRORS) | |
| { | | { | |
| // Restore HDF5 error handler. | | // Restore HDF5 error handler. | |
|
| H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); | | arma_H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| if (ndims == 1) { dims[1] = 1; dims[2] = 1; } // Vector case; one
row/colum, several slices | | if (ndims == 1) { dims[1] = 1; dims[2] = 1; } // Vector case; one
row/colum, several slices | |
| if (ndims == 2) { dims[2] = 1; } // Matrix case; one column, severa
l rows/slices | | if (ndims == 2) { dims[2] = 1; } // Matrix case; one column, severa
l rows/slices | |
| | | | |
| x.set_size(dims[2], dims[1], dims[0]); | | x.set_size(dims[2], dims[1], dims[0]); | |
| | | | |
| // Now we have to see what type is stored to figure out how to load
it. | | // Now we have to see what type is stored to figure out how to load
it. | |
|
| hid_t datatype = H5Dget_type(dataset); | | hid_t datatype = arma_H5Dget_type(dataset); | |
| hid_t mat_type = hdf5_misc::get_hdf5_type<eT>(); | | hid_t mat_type = hdf5_misc::get_hdf5_type<eT>(); | |
| | | | |
| // If these are the same type, it is simple. | | // If these are the same type, it is simple. | |
|
| if(H5Tequal(datatype, mat_type) > 0) | | if(arma_H5Tequal(datatype, mat_type) > 0) | |
| { | | { | |
| // Load directly; H5S_ALL used so that we load the entire dataset
. | | // Load directly; H5S_ALL used so that we load the entire dataset
. | |
|
| hid_t read_status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL,
H5P_DEFAULT, void_ptr(x.memptr())); | | hid_t read_status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_
ALL, H5P_DEFAULT, void_ptr(x.memptr())); | |
| | | | |
| if(read_status >= 0) { load_okay = true; } | | if(read_status >= 0) { load_okay = true; } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // Load into another array and convert its type accordingly. | | // Load into another array and convert its type accordingly. | |
| hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(),
dataset, datatype, x.n_elem); | | hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(),
dataset, datatype, x.n_elem); | |
| | | | |
| if(read_status >= 0) { load_okay = true; } | | if(read_status >= 0) { load_okay = true; } | |
| } | | } | |
| | | | |
| // Now clean up. | | // Now clean up. | |
|
| H5Tclose(datatype); | | arma_H5Tclose(datatype); | |
| H5Tclose(mat_type); | | arma_H5Tclose(mat_type); | |
| H5Sclose(filespace); | | arma_H5Sclose(filespace); | |
| } | | } | |
| | | | |
|
| H5Dclose(dataset); | | arma_H5Dclose(dataset); | |
| | | | |
|
| H5Fclose(fid); | | arma_H5Fclose(fid); | |
| | | | |
| if(load_okay == false) | | if(load_okay == false) | |
| { | | { | |
| err_msg = "unsupported or incorrect HDF5 data in "; | | err_msg = "unsupported or incorrect HDF5 data in "; | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| err_msg = "cannot open file "; | | err_msg = "cannot open file "; | |
| } | | } | |
| | | | |
| #if !defined(ARMA_PRINT_HDF5_ERRORS) | | #if !defined(ARMA_PRINT_HDF5_ERRORS) | |
| { | | { | |
| // Restore HDF5 error handler. | | // Restore HDF5 error handler. | |
|
| H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); | | arma_H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| return load_okay; | | return load_okay; | |
| } | | } | |
| #else | | #else | |
| { | | { | |
| arma_ignore(x); | | arma_ignore(x); | |
| arma_ignore(name); | | arma_ignore(name); | |
| arma_ignore(err_msg); | | arma_ignore(err_msg); | |
| | | | |
| skipping to change at line 3616 | | skipping to change at line 3616 | |
| //! Try to load a cube by automatically determining its type | | //! Try to load a cube by automatically determining its type | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| bool | | bool | |
| diskio::load_auto_detect(Cube<eT>& x, const std::string& name, std::string&
err_msg) | | diskio::load_auto_detect(Cube<eT>& x, const std::string& name, std::string&
err_msg) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| #if defined(ARMA_USE_HDF5) | | #if defined(ARMA_USE_HDF5) | |
| // We're currently using the C bindings for the HDF5 library, which don
't support C++ streams | | // We're currently using the C bindings for the HDF5 library, which don
't support C++ streams | |
|
| if( H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name, err_m
sg); } | | if( arma_H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name,
err_msg); } | |
| #endif | | #endif | |
| | | | |
| std::fstream f; | | std::fstream f; | |
| f.open(name.c_str(), std::fstream::in | std::fstream::binary); | | f.open(name.c_str(), std::fstream::in | std::fstream::binary); | |
| | | | |
| bool load_okay = f.is_open(); | | bool load_okay = f.is_open(); | |
| | | | |
| if(load_okay == true) | | if(load_okay == true) | |
| { | | { | |
| load_okay = diskio::load_auto_detect(x, f, err_msg); | | load_okay = diskio::load_auto_detect(x, f, err_msg); | |
| | | | |
End of changes. 43 change blocks. |
| 57 lines changed or deleted | | 57 lines changed or added | |
|
| glue_times_meat.hpp | | glue_times_meat.hpp | |
| // Copyright (C) 2008-2014 Conrad Sanderson | | // Copyright (C) 2008-2014 Conrad Sanderson | |
| // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | | // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup glue_times | | //! \addtogroup glue_times | |
| //! @{ | | //! @{ | |
| | | | |
|
| template<bool is_eT_blas_type> | | template<bool do_inv_detect> | |
| template<typename T1, typename T2> | | template<typename T1, typename T2> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| void | | void | |
|
| glue_times_redirect2_helper<is_eT_blas_type>::apply(Mat<typename T1::elem_t
ype>& out, const Glue<T1,T2,glue_times>& X) | | glue_times_redirect2_helper<do_inv_detect>::apply(Mat<typename T1::elem_typ
e>& out, const Glue<T1,T2,glue_times>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | | |
| const partial_unwrap<T1> tmp1(X.A); | | const partial_unwrap<T1> tmp1(X.A); | |
| const partial_unwrap<T2> tmp2(X.B); | | const partial_unwrap<T2> tmp2(X.B); | |
| | | | |
| const typename partial_unwrap<T1>::stored_type& A = tmp1.M; | | const typename partial_unwrap<T1>::stored_type& A = tmp1.M; | |
| const typename partial_unwrap<T2>::stored_type& B = tmp2.M; | | const typename partial_unwrap<T2>::stored_type& B = tmp2.M; | |
| | | | |
| skipping to change at line 71 | | skipping to change at line 71 | |
| template<typename T1, typename T2> | | template<typename T1, typename T2> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| void | | void | |
| glue_times_redirect2_helper<true>::apply(Mat<typename T1::elem_type>& out,
const Glue<T1,T2,glue_times>& X) | | glue_times_redirect2_helper<true>::apply(Mat<typename T1::elem_type>& out,
const Glue<T1,T2,glue_times>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | | |
|
| if(strip_inv<T1>::do_inv == false) | | if(strip_inv<T1>::do_inv == true) | |
| { | | | |
| const partial_unwrap<T1> tmp1(X.A); | | | |
| const partial_unwrap<T2> tmp2(X.B); | | | |
| | | | |
| const typename partial_unwrap<T1>::stored_type& A = tmp1.M; | | | |
| const typename partial_unwrap<T2>::stored_type& B = tmp2.M; | | | |
| | | | |
| const bool use_alpha = partial_unwrap<T1>::do_times || partial_unwrap<T | | | |
| 2>::do_times; | | | |
| const eT alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val()) : | | | |
| eT(0); | | | |
| | | | |
| const bool alias = tmp1.is_alias(out) || tmp2.is_alias(out); | | | |
| | | | |
| if(alias == false) | | | |
| { | | | |
| glue_times::apply | | | |
| < | | | |
| eT, | | | |
| partial_unwrap<T1>::do_trans, | | | |
| partial_unwrap<T2>::do_trans, | | | |
| (partial_unwrap<T1>::do_times || partial_unwrap<T2>::do_times) | | | |
| > | | | |
| (out, A, B, alpha); | | | |
| } | | | |
| else | | | |
| { | | | |
| Mat<eT> tmp; | | | |
| | | | |
| glue_times::apply | | | |
| < | | | |
| eT, | | | |
| partial_unwrap<T1>::do_trans, | | | |
| partial_unwrap<T2>::do_trans, | | | |
| (partial_unwrap<T1>::do_times || partial_unwrap<T2>::do_times) | | | |
| > | | | |
| (tmp, A, B, alpha); | | | |
| | | | |
| out.steal_mem(tmp); | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
| arma_extra_debug_print("glue_times_redirect<2>::apply(): detected inv(A
)*B"); | | arma_extra_debug_print("glue_times_redirect<2>::apply(): detected inv(A
)*B"); | |
| | | | |
| const strip_inv<T1> A_strip(X.A); | | const strip_inv<T1> A_strip(X.A); | |
| | | | |
| Mat<eT> A = A_strip.M; | | Mat<eT> A = A_strip.M; | |
| | | | |
| arma_debug_check( (A.is_square() == false), "inv(): given matrix is not
square" ); | | arma_debug_check( (A.is_square() == false), "inv(): given matrix is not
square" ); | |
| | | | |
| const unwrap_check<T2> B_tmp(X.B, out); | | const unwrap_check<T2> B_tmp(X.B, out); | |
| const Mat<eT>& B = B_tmp.M; | | const Mat<eT>& B = B_tmp.M; | |
| | | | |
|
| | | arma_debug_assert_mul_size(A, B, "matrix multiplication"); | |
| | | | |
| glue_solve::solve_direct( out, A, B, A_strip.slow ); | | glue_solve::solve_direct( out, A, B, A_strip.slow ); | |
|
| | | | |
| | | return; | |
| } | | } | |
|
| | | | |
| | | glue_times_redirect2_helper<false>::apply(out, X); | |
| } | | } | |
| | | | |
|
| template<bool is_eT_blas_type> | | template<bool do_inv_detect> | |
| template<typename T1, typename T2, typename T3> | | template<typename T1, typename T2, typename T3> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| void | | void | |
|
| glue_times_redirect3_helper<is_eT_blas_type>::apply(Mat<typename T1::elem_t
ype>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X) | | glue_times_redirect3_helper<do_inv_detect>::apply(Mat<typename T1::elem_typ
e>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | | |
| // we have exactly 3 objects | | // we have exactly 3 objects | |
| // hence we can safely expand X as X.A.A, X.A.B and X.B | | // hence we can safely expand X as X.A.A, X.A.B and X.B | |
| | | | |
| const partial_unwrap<T1> tmp1(X.A.A); | | const partial_unwrap<T1> tmp1(X.A.A); | |
| const partial_unwrap<T2> tmp2(X.A.B); | | const partial_unwrap<T2> tmp2(X.A.B); | |
| | | | |
| skipping to change at line 193 | | skipping to change at line 159 | |
| } | | } | |
| | | | |
| template<typename T1, typename T2, typename T3> | | template<typename T1, typename T2, typename T3> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| void | | void | |
| glue_times_redirect3_helper<true>::apply(Mat<typename T1::elem_type>& out,
const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X) | | glue_times_redirect3_helper<true>::apply(Mat<typename T1::elem_type>& out,
const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| // TODO: investigate detecting inv(A)*B*C and replacing with solve(A,B)*C | | | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | | |
|
| if(strip_inv<T2>::do_inv == false) | | if(strip_inv<T1>::do_inv == true) | |
| { | | { | |
|
| // we have exactly 3 objects | | // replace inv(A)*B*C with solve(A,B*C); | |
| // hence we can safely expand X as X.A.A, X.A.B and X.B | | | |
| | | arma_extra_debug_print("glue_times_redirect<3>::apply(): detected inv(A | |
| | | )*B*C"); | |
| | | | |
| | | const strip_inv<T1> A_strip(X.A.A); | |
| | | | |
| | | Mat<eT> A = A_strip.M; | |
| | | | |
| | | arma_debug_check( (A.is_square() == false), "inv(): given matrix is not | |
| | | square" ); | |
| | | | |
|
| const partial_unwrap<T1> tmp1(X.A.A); | | | |
| const partial_unwrap<T2> tmp2(X.A.B); | | const partial_unwrap<T2> tmp2(X.A.B); | |
| const partial_unwrap<T3> tmp3(X.B ); | | const partial_unwrap<T3> tmp3(X.B ); | |
| | | | |
|
| const typename partial_unwrap<T1>::stored_type& A = tmp1.M; | | | |
| const typename partial_unwrap<T2>::stored_type& B = tmp2.M; | | const typename partial_unwrap<T2>::stored_type& B = tmp2.M; | |
| const typename partial_unwrap<T3>::stored_type& C = tmp3.M; | | const typename partial_unwrap<T3>::stored_type& C = tmp3.M; | |
| | | | |
|
| const bool use_alpha = partial_unwrap<T1>::do_times || partial_unwrap<T | | const bool use_alpha = partial_unwrap<T2>::do_times || partial_unwrap<T | |
| 2>::do_times || partial_unwrap<T3>::do_times; | | 3>::do_times; | |
| const eT alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val() * t | | const eT alpha = use_alpha ? (tmp2.get_val() * tmp3.get_val()) : | |
| mp3.get_val()) : eT(0); | | eT(0); | |
| | | | |
| | | Mat<eT> BC; | |
| | | | |
| | | glue_times::apply | |
| | | < | |
| | | eT, | |
| | | partial_unwrap<T2>::do_trans, | |
| | | partial_unwrap<T3>::do_trans, | |
| | | (partial_unwrap<T2>::do_times || partial_unwrap<T3>::do_times) | |
| | | > | |
| | | (BC, B, C, alpha); | |
| | | | |
|
| const bool alias = tmp1.is_alias(out) || tmp2.is_alias(out) || tmp3.is_
alias(out); | | arma_debug_assert_mul_size(A, BC, "matrix multiplication"); | |
| | | | |
|
| if(alias == false) | | glue_solve::solve_direct( out, A, BC, A_strip.slow ); | |
| { | | | |
| glue_times::apply | | | |
| < | | | |
| eT, | | | |
| partial_unwrap<T1>::do_trans, | | | |
| partial_unwrap<T2>::do_trans, | | | |
| partial_unwrap<T3>::do_trans, | | | |
| (partial_unwrap<T1>::do_times || partial_unwrap<T2>::do_times || pa | | | |
| rtial_unwrap<T3>::do_times) | | | |
| > | | | |
| (out, A, B, C, alpha); | | | |
| } | | | |
| else | | | |
| { | | | |
| Mat<eT> tmp; | | | |
| | | | |
| glue_times::apply | | | |
| < | | | |
| eT, | | | |
| partial_unwrap<T1>::do_trans, | | | |
| partial_unwrap<T2>::do_trans, | | | |
| partial_unwrap<T3>::do_trans, | | | |
| (partial_unwrap<T1>::do_times || partial_unwrap<T2>::do_times || pa | | | |
| rtial_unwrap<T3>::do_times) | | | |
| > | | | |
| (tmp, A, B, C, alpha); | | | |
| | | | |
|
| out.steal_mem(tmp); | | return; | |
| } | | | |
| } | | } | |
|
| else | | | |
| | | if(strip_inv<T2>::do_inv == true) | |
| { | | { | |
| // replace A*inv(B)*C with A*solve(B,C) | | // replace A*inv(B)*C with A*solve(B,C) | |
| | | | |
| arma_extra_debug_print("glue_times_redirect<3>::apply(): detected A*inv
(B)*C"); | | arma_extra_debug_print("glue_times_redirect<3>::apply(): detected A*inv
(B)*C"); | |
| | | | |
| const strip_inv<T2> B_strip(X.A.B); | | const strip_inv<T2> B_strip(X.A.B); | |
| | | | |
| Mat<eT> B = B_strip.M; | | Mat<eT> B = B_strip.M; | |
| | | | |
| arma_debug_check( (B.is_square() == false), "inv(): given matrix is not
square" ); | | arma_debug_check( (B.is_square() == false), "inv(): given matrix is not
square" ); | |
| | | | |
| const unwrap<T3> C_tmp(X.B); | | const unwrap<T3> C_tmp(X.B); | |
| const Mat<eT>& C = C_tmp.M; | | const Mat<eT>& C = C_tmp.M; | |
| | | | |
|
| | | arma_debug_assert_mul_size(B, C, "matrix multiplication"); | |
| | | | |
| Mat<eT> solve_result; | | Mat<eT> solve_result; | |
| | | | |
| glue_solve::solve_direct( solve_result, B, C, B_strip.slow ); | | glue_solve::solve_direct( solve_result, B, C, B_strip.slow ); | |
| | | | |
| const partial_unwrap_check<T1> tmp1(X.A.A, out); | | const partial_unwrap_check<T1> tmp1(X.A.A, out); | |
| | | | |
| const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M; | | const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M; | |
| | | | |
| const bool use_alpha = partial_unwrap_check<T1>::do_times; | | const bool use_alpha = partial_unwrap_check<T1>::do_times; | |
| const eT alpha = use_alpha ? tmp1.get_val() : eT(0); | | const eT alpha = use_alpha ? tmp1.get_val() : eT(0); | |
| | | | |
| glue_times::apply | | glue_times::apply | |
| < | | < | |
| eT, | | eT, | |
| partial_unwrap_check<T1>::do_trans, | | partial_unwrap_check<T1>::do_trans, | |
| false, | | false, | |
| partial_unwrap_check<T1>::do_times | | partial_unwrap_check<T1>::do_times | |
| > | | > | |
| (out, A, solve_result, alpha); | | (out, A, solve_result, alpha); | |
|
| | | | |
| | | return; | |
| } | | } | |
|
| | | | |
| | | glue_times_redirect3_helper<false>::apply(out, X); | |
| } | | } | |
| | | | |
| template<uword N> | | template<uword N> | |
| template<typename T1, typename T2> | | template<typename T1, typename T2> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| void | | void | |
| glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<
T1,T2,glue_times>& X) | | glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<
T1,T2,glue_times>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
End of changes. 21 change blocks. |
| 89 lines changed or deleted | | 49 lines changed or added | |
|
| hdf5_misc.hpp | | hdf5_misc.hpp | |
| | | | |
| skipping to change at line 35 | | skipping to change at line 35 | |
| } | | } | |
| | | | |
| //! Specializations for each valid element type | | //! Specializations for each valid element type | |
| //! (taken from all the possible typedefs of {u8, s8, ..., u64, s64} and th
e other native types. | | //! (taken from all the possible typedefs of {u8, s8, ..., u64, s64} and th
e other native types. | |
| //! We can't use the actual u8/s8 typedefs because their relations to the H
5T_... types are unclear. | | //! We can't use the actual u8/s8 typedefs because their relations to the H
5T_... types are unclear. | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< unsigned char >() | | get_hdf5_type< unsigned char >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_UCHAR); | | return arma_H5Tcopy(arma_H5T_NATIVE_UCHAR); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< char >() | | get_hdf5_type< char >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_CHAR); | | return arma_H5Tcopy(arma_H5T_NATIVE_CHAR); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< short >() | | get_hdf5_type< short >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_SHORT); | | return arma_H5Tcopy(arma_H5T_NATIVE_SHORT); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< unsigned short >() | | get_hdf5_type< unsigned short >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_USHORT); | | return arma_H5Tcopy(arma_H5T_NATIVE_USHORT); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< int >() | | get_hdf5_type< int >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_INT); | | return arma_H5Tcopy(arma_H5T_NATIVE_INT); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< unsigned int >() | | get_hdf5_type< unsigned int >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_UINT); | | return arma_H5Tcopy(arma_H5T_NATIVE_UINT); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< long >() | | get_hdf5_type< long >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_LONG); | | return arma_H5Tcopy(arma_H5T_NATIVE_LONG); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< unsigned long >() | | get_hdf5_type< unsigned long >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_ULONG); | | return arma_H5Tcopy(arma_H5T_NATIVE_ULONG); | |
| } | | } | |
| | | | |
| #if defined(ARMA_USE_U64S64) && defined(ULLONG_MAX) | | #if defined(ARMA_USE_U64S64) && defined(ULLONG_MAX) | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< long long >() | | get_hdf5_type< long long >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_LLONG); | | return arma_H5Tcopy(arma_H5T_NATIVE_LLONG); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< unsigned long long >() | | get_hdf5_type< unsigned long long >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_ULLONG); | | return arma_H5Tcopy(arma_H5T_NATIVE_ULLONG); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< float >() | | get_hdf5_type< float >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_FLOAT); | | return arma_H5Tcopy(arma_H5T_NATIVE_FLOAT); | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< double >() | | get_hdf5_type< double >() | |
| { | | { | |
|
| return H5Tcopy(H5T_NATIVE_DOUBLE); | | return arma_H5Tcopy(arma_H5T_NATIVE_DOUBLE); | |
| } | | } | |
| | | | |
| //! Utility hid_t since HOFFSET() won't work with std::complex. | | //! Utility hid_t since HOFFSET() won't work with std::complex. | |
| template<typename eT> | | template<typename eT> | |
| struct hdf5_complex_t | | struct hdf5_complex_t | |
| { | | { | |
| eT real; | | eT real; | |
| eT imag; | | eT imag; | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< std::complex<float> >() | | get_hdf5_type< std::complex<float> >() | |
| { | | { | |
|
| hid_t type = H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t<float>)); | | hid_t type = arma_H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t<float>)); | |
| | | | |
|
| H5Tinsert(type, "real", HOFFSET(hdf5_complex_t<float>, real), H5T_NATIVE_ | | arma_H5Tinsert(type, "real", HOFFSET(hdf5_complex_t<float>, real), arma_H | |
| FLOAT); | | 5T_NATIVE_FLOAT); | |
| H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t<float>, imag), H5T_NATIVE_ | | arma_H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t<float>, imag), arma_H | |
| FLOAT); | | 5T_NATIVE_FLOAT); | |
| | | | |
| return type; | | return type; | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| inline | | inline | |
| hid_t | | hid_t | |
| get_hdf5_type< std::complex<double> >() | | get_hdf5_type< std::complex<double> >() | |
| { | | { | |
|
| hid_t type = H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t<double>)); | | hid_t type = arma_H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t<double>))
; | |
| | | | |
|
| H5Tinsert(type, "real", HOFFSET(hdf5_complex_t<double>, real), H5T_NATIVE | | arma_H5Tinsert(type, "real", HOFFSET(hdf5_complex_t<double>, real), arma_ | |
| _DOUBLE); | | H5T_NATIVE_DOUBLE); | |
| H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t<double>, imag), H5T_NATIVE | | arma_H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t<double>, imag), arma_ | |
| _DOUBLE); | | H5T_NATIVE_DOUBLE); | |
| | | | |
| return type; | | return type; | |
| } | | } | |
| | | | |
| // Compare datatype against all supported types. | | // Compare datatype against all supported types. | |
| inline | | inline | |
| bool | | bool | |
| is_supported_arma_hdf5_type(hid_t datatype) | | is_supported_arma_hdf5_type(hid_t datatype) | |
| { | | { | |
| hid_t search_type; | | hid_t search_type; | |
| | | | |
| bool is_equal; | | bool is_equal; | |
| | | | |
| // start with most likely used types: double, complex<double>, float, com
plex<float> | | // start with most likely used types: double, complex<double>, float, com
plex<float> | |
| | | | |
| search_type = get_hdf5_type<double>(); | | search_type = get_hdf5_type<double>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type< std::complex<double> >(); | | search_type = get_hdf5_type< std::complex<double> >(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type<float>(); | | search_type = get_hdf5_type<float>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type< std::complex<float> >(); | | search_type = get_hdf5_type< std::complex<float> >(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| // remaining supported types: u8, s8, u16, s16, u32, s32, u64, s64, ulng_
t, slng_t | | // remaining supported types: u8, s8, u16, s16, u32, s32, u64, s64, ulng_
t, slng_t | |
| | | | |
| search_type = get_hdf5_type<u8>(); | | search_type = get_hdf5_type<u8>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type<s8>(); | | search_type = get_hdf5_type<s8>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type<u16>(); | | search_type = get_hdf5_type<u16>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type<s16>(); | | search_type = get_hdf5_type<s16>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type<u32>(); | | search_type = get_hdf5_type<u32>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type<s32>(); | | search_type = get_hdf5_type<s32>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| #if defined(ARMA_USE_U64S64) | | #if defined(ARMA_USE_U64S64) | |
| { | | { | |
| search_type = get_hdf5_type<u64>(); | | search_type = get_hdf5_type<u64>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type<s64>(); | | search_type = get_hdf5_type<s64>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #if defined(ARMA_ALLOW_LONG) | | #if defined(ARMA_ALLOW_LONG) | |
| { | | { | |
| search_type = get_hdf5_type<ulng_t>(); | | search_type = get_hdf5_type<ulng_t>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| | | | |
| search_type = get_hdf5_type<slng_t>(); | | search_type = get_hdf5_type<slng_t>(); | |
|
| is_equal = ( H5Tequal(datatype, search_type) > 0 ); | | is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| if (is_equal) { return true; } | | if (is_equal) { return true; } | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| //! Auxiliary functions and structs for search_hdf5_file. | | //! Auxiliary functions and structs for search_hdf5_file. | |
| struct hdf5_search_info | | struct hdf5_search_info | |
| { | | { | |
| | | | |
| skipping to change at line 282 | | skipping to change at line 282 | |
| const H5O_info_t* info, | | const H5O_info_t* info, | |
| void* operator_data // hdf5_search_info | | void* operator_data // hdf5_search_info | |
| ) | | ) | |
| { | | { | |
| hdf5_search_info* search_info = (hdf5_search_info*) operator_data; | | hdf5_search_info* search_info = (hdf5_search_info*) operator_data; | |
| | | | |
| // We are looking for datasets. | | // We are looking for datasets. | |
| if (info->type == H5O_TYPE_DATASET) | | if (info->type == H5O_TYPE_DATASET) | |
| { | | { | |
| // Check type of dataset to see if we could even load it. | | // Check type of dataset to see if we could even load it. | |
|
| hid_t dataset = H5Dopen(loc_id, name, H5P_DEFAULT); | | hid_t dataset = arma_H5Dopen(loc_id, name, H5P_DEFAULT); | |
| hid_t datatype = H5Dget_type(dataset); | | hid_t datatype = arma_H5Dget_type(dataset); | |
| | | | |
| const bool is_supported = is_supported_arma_hdf5_type(datatype); | | const bool is_supported = is_supported_arma_hdf5_type(datatype); | |
| | | | |
|
| H5Tclose(datatype); | | arma_H5Tclose(datatype); | |
| H5Dclose(dataset); | | arma_H5Dclose(dataset); | |
| | | | |
| if(is_supported == false) | | if(is_supported == false) | |
| { | | { | |
| // Forget about it and move on. | | // Forget about it and move on. | |
| return 0; | | return 0; | |
| } | | } | |
| | | | |
| // Now we have to check against our set of names. | | // Now we have to check against our set of names. | |
| // Only check names which could be better. | | // Only check names which could be better. | |
| for (size_t string_pos = 0; string_pos < search_info->best_match_positi
on; ++string_pos) | | for (size_t string_pos = 0; string_pos < search_info->best_match_positi
on; ++string_pos) | |
| | | | |
| skipping to change at line 345 | | skipping to change at line 345 | |
| --count; | | --count; | |
| } | | } | |
| | | | |
| // Now take the substring (this may end up being the full string). | | // Now take the substring (this may end up being the full string). | |
| const std::string substring = str.substr(start_pos); | | const std::string substring = str.substr(start_pos); | |
| | | | |
| // Are they the same? | | // Are they the same? | |
| if (substring == search_info->names[string_pos]) | | if (substring == search_info->names[string_pos]) | |
| { | | { | |
| // We have found the object; it must be better than our existing
match. | | // We have found the object; it must be better than our existing
match. | |
|
| hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT); | | hid_t match_candidate = arma_H5Dopen(loc_id, name, H5P_DEFAULT); | |
| | | | |
| // arma_check(match_candidate < 0, "Mat::load(): cannot open an H
DF5 dataset"); | | // arma_check(match_candidate < 0, "Mat::load(): cannot open an H
DF5 dataset"); | |
| if(match_candidate < 0) | | if(match_candidate < 0) | |
| { | | { | |
| return -1; | | return -1; | |
| } | | } | |
| | | | |
| // Ensure that the dataset is valid and of the correct dimensiona
lity. | | // Ensure that the dataset is valid and of the correct dimensiona
lity. | |
|
| hid_t filespace = H5Dget_space(match_candidate); | | hid_t filespace = arma_H5Dget_space(match_candidate); | |
| int num_dims = H5Sget_simple_extent_ndims(filespace); | | int num_dims = arma_H5Sget_simple_extent_ndims(filespace); | |
| | | | |
| if (num_dims <= search_info->num_dims) | | if (num_dims <= search_info->num_dims) | |
| { | | { | |
| // Valid dataset -- we'll keep it. | | // Valid dataset -- we'll keep it. | |
| // If we already have an existing match we have to close it. | | // If we already have an existing match we have to close it. | |
| if (search_info->best_match != -1) | | if (search_info->best_match != -1) | |
| { | | { | |
|
| H5Dclose(search_info->best_match); | | arma_H5Dclose(search_info->best_match); | |
| } | | } | |
| | | | |
| search_info->best_match_position = string_pos; | | search_info->best_match_position = string_pos; | |
| search_info->best_match = match_candidate; | | search_info->best_match = match_candidate; | |
| } | | } | |
| | | | |
|
| H5Sclose(filespace); | | arma_H5Sclose(filespace); | |
| } | | } | |
| } | | } | |
| | | | |
| // If they are not the same, but we have not found anything and we do
n't need an exact match, take this. | | // If they are not the same, but we have not found anything and we do
n't need an exact match, take this. | |
| if ((search_info->exact == false) && (search_info->best_match == -1)) | | if ((search_info->exact == false) && (search_info->best_match == -1)) | |
| { | | { | |
|
| hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT); | | hid_t match_candidate = arma_H5Dopen(loc_id, name, H5P_DEFAULT); | |
| | | | |
| // arma_check(match_candidate < 0, "Mat::load(): cannot open an HDF
5 dataset"); | | // arma_check(match_candidate < 0, "Mat::load(): cannot open an HDF
5 dataset"); | |
| if(match_candidate < 0) | | if(match_candidate < 0) | |
| { | | { | |
| return -1; | | return -1; | |
| } | | } | |
| | | | |
|
| hid_t filespace = H5Dget_space(match_candidate); | | hid_t filespace = arma_H5Dget_space(match_candidate); | |
| int num_dims = H5Sget_simple_extent_ndims(filespace); | | int num_dims = arma_H5Sget_simple_extent_ndims(filespace); | |
| | | | |
| if (num_dims <= search_info->num_dims) | | if (num_dims <= search_info->num_dims) | |
| { | | { | |
| // Valid dataset -- we'll keep it. | | // Valid dataset -- we'll keep it. | |
|
| search_info->best_match = H5Dopen(loc_id, name, H5P_DEFAULT); | | search_info->best_match = arma_H5Dopen(loc_id, name, H5P_DEFAULT)
; | |
| } | | } | |
| | | | |
|
| H5Sclose(filespace); | | arma_H5Sclose(filespace); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| return 0; | | return 0; | |
| } | | } | |
| | | | |
| //! Search an HDF5 file for the given dataset names. | | //! Search an HDF5 file for the given dataset names. | |
| //! If 'exact' is true, failure to find a dataset in the list of names mean
s that -1 is returned. | | //! If 'exact' is true, failure to find a dataset in the list of names mean
s that -1 is returned. | |
| //! If 'exact' is false and no datasets are found, -1 is returned. | | //! If 'exact' is false and no datasets are found, -1 is returned. | |
| | | | |
| skipping to change at line 422 | | skipping to change at line 422 | |
| ( | | ( | |
| const std::vector<std::string>& names, | | const std::vector<std::string>& names, | |
| hid_t hdf5_file, | | hid_t hdf5_file, | |
| int num_dims = 2, | | int num_dims = 2, | |
| bool exact = false | | bool exact = false | |
| ) | | ) | |
| { | | { | |
| hdf5_search_info search_info = { names, num_dims, exact, -1, names.size()
}; | | hdf5_search_info search_info = { names, num_dims, exact, -1, names.size()
}; | |
| | | | |
| // We'll use the H5Ovisit to track potential entries. | | // We'll use the H5Ovisit to track potential entries. | |
|
| herr_t status = H5Ovisit(hdf5_file, H5_INDEX_NAME, H5_ITER_NATIVE, hdf5_s
earch_callback, void_ptr(&search_info)); | | herr_t status = arma_H5Ovisit(hdf5_file, H5_INDEX_NAME, H5_ITER_NATIVE, h
df5_search_callback, void_ptr(&search_info)); | |
| | | | |
| // Return the best match; it will be -1 if there was a problem. | | // Return the best match; it will be -1 if there was a problem. | |
| return (status < 0) ? -1 : search_info.best_match; | | return (status < 0) ? -1 : search_info.best_match; | |
| } | | } | |
| | | | |
| //! Load an HDF5 matrix into an array of type specified by datatype, | | //! Load an HDF5 matrix into an array of type specified by datatype, | |
| //! then convert that into the desired array 'dest'. | | //! then convert that into the desired array 'dest'. | |
| //! This should only be called when eT is not the datatype. | | //! This should only be called when eT is not the datatype. | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| | | | |
| skipping to change at line 452 | | skipping to change at line 452 | |
| | | | |
| // We can't use nice template specializations here | | // We can't use nice template specializations here | |
| // as the determination of the type of 'datatype' must be done at runtime
. | | // as the determination of the type of 'datatype' must be done at runtime
. | |
| // So we end up with this ugliness... | | // So we end up with this ugliness... | |
| hid_t search_type; | | hid_t search_type; | |
| | | | |
| bool is_equal; | | bool is_equal; | |
| | | | |
| // u8 | | // u8 | |
| search_type = get_hdf5_type<u8>(); | | search_type = get_hdf5_type<u8>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<u8> v(n_elem); | | Col<u8> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // s8 | | // s8 | |
| search_type = get_hdf5_type<s8>(); | | search_type = get_hdf5_type<s8>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<s8> v(n_elem); | | Col<s8> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // u16 | | // u16 | |
| search_type = get_hdf5_type<u16>(); | | search_type = get_hdf5_type<u16>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<u16> v(n_elem); | | Col<u16> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // s16 | | // s16 | |
| search_type = get_hdf5_type<s16>(); | | search_type = get_hdf5_type<s16>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<s16> v(n_elem); | | Col<s16> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // u32 | | // u32 | |
| search_type = get_hdf5_type<u32>(); | | search_type = get_hdf5_type<u32>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<u32> v(n_elem); | | Col<u32> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // s32 | | // s32 | |
| search_type = get_hdf5_type<s32>(); | | search_type = get_hdf5_type<s32>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<s32> v(n_elem); | | Col<s32> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| #if defined(ARMA_USE_U64S64) | | #if defined(ARMA_USE_U64S64) | |
| { | | { | |
| // u64 | | // u64 | |
| search_type = get_hdf5_type<u64>(); | | search_type = get_hdf5_type<u64>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<u64> v(n_elem); | | Col<u64> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAU
LT, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_
DEFAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // s64 | | // s64 | |
| search_type = get_hdf5_type<s64>(); | | search_type = get_hdf5_type<s64>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<s64> v(n_elem); | | Col<s64> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAU
LT, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_
DEFAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #if defined(ARMA_ALLOW_LONG) | | #if defined(ARMA_ALLOW_LONG) | |
| { | | { | |
| // ulng_t | | // ulng_t | |
| search_type = get_hdf5_type<ulng_t>(); | | search_type = get_hdf5_type<ulng_t>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<ulng_t> v(n_elem); | | Col<ulng_t> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAU
LT, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_
DEFAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // slng_t | | // slng_t | |
| search_type = get_hdf5_type<slng_t>(); | | search_type = get_hdf5_type<slng_t>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<slng_t> v(n_elem); | | Col<slng_t> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAU
LT, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_
DEFAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| // float | | // float | |
| search_type = get_hdf5_type<float>(); | | search_type = get_hdf5_type<float>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<float> v(n_elem); | | Col<float> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // double | | // double | |
| search_type = get_hdf5_type<double>(); | | search_type = get_hdf5_type<double>(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| Col<double> v(n_elem); | | Col<double> v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert(dest, v.memptr(), n_elem); | | arrayops::convert(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // complex float | | // complex float | |
| search_type = get_hdf5_type< std::complex<float> >(); | | search_type = get_hdf5_type< std::complex<float> >(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| if(is_complex<eT>::value == false) | | if(is_complex<eT>::value == false) | |
| { | | { | |
| return -1; // can't read complex data into non-complex matrix/cube | | return -1; // can't read complex data into non-complex matrix/cube | |
| } | | } | |
| | | | |
| Col< std::complex<float> > v(n_elem); | | Col< std::complex<float> > v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert_cx(dest, v.memptr(), n_elem); | | arrayops::convert_cx(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| // complex double | | // complex double | |
| search_type = get_hdf5_type< std::complex<double> >(); | | search_type = get_hdf5_type< std::complex<double> >(); | |
|
| is_equal = (H5Tequal(datatype, search_type) > 0); | | is_equal = (arma_H5Tequal(datatype, search_type) > 0); | |
| H5Tclose(search_type); | | arma_H5Tclose(search_type); | |
| | | | |
| if(is_equal) | | if(is_equal) | |
| { | | { | |
| if(is_complex<eT>::value == false) | | if(is_complex<eT>::value == false) | |
| { | | { | |
| return -1; // can't read complex data into non-complex matrix/cube | | return -1; // can't read complex data into non-complex matrix/cube | |
| } | | } | |
| | | | |
| Col< std::complex<double> > v(n_elem); | | Col< std::complex<double> > v(n_elem); | |
|
| hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT
, void_ptr(v.memptr())); | | hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DE
FAULT, void_ptr(v.memptr())); | |
| arrayops::convert_cx(dest, v.memptr(), n_elem); | | arrayops::convert_cx(dest, v.memptr(), n_elem); | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| return -1; // Failure. | | return -1; // Failure. | |
| } | | } | |
| | | | |
| } // namespace hdf5_misc | | } // namespace hdf5_misc | |
| #endif // #if defined(ARMA_USE_HDF5) | | #endif // #if defined(ARMA_USE_HDF5) | |
| | | | |
End of changes. 69 change blocks. |
| 107 lines changed or deleted | | 107 lines changed or added | |
|
| op_find_meat.hpp | | op_find_meat.hpp | |
| | | | |
| skipping to change at line 217 | | skipping to change at line 217 | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
| ea_type PA = A.get_ea(); | | ea_type PA = A.get_ea(); | |
| const uword n_elem = A.get_n_elem(); | | const uword n_elem = A.get_n_elem(); | |
| | | | |
| indices.set_size(n_elem, 1); | | indices.set_size(n_elem, 1); | |
| | | | |
| uword* indices_mem = indices.memptr(); | | uword* indices_mem = indices.memptr(); | |
| uword n_nz = 0; | | uword n_nz = 0; | |
| | | | |
|
| for(uword i=0; i<n_elem; ++i) | | if(Proxy<T1>::prefer_at_accessor == false) | |
| { | | { | |
|
| const eT tmp = PA[i]; | | for(uword i=0; i<n_elem; ++i) | |
| | | { | |
| | | const eT tmp = PA[i]; | |
| | | | |
|
| bool not_zero; | | bool not_zero; | |
| | | | |
|
| if(is_same_type<op_type, op_rel_eq >::yes) { not_zero = (tmp == | | if(is_same_type<op_type, op_rel_eq >::yes) { not_zero = (tmp | |
| val); } | | == val); } | |
| else if(is_same_type<op_type, op_rel_noteq>::yes) { not_zero = (tmp != | | else if(is_same_type<op_type, op_rel_noteq>::yes) { not_zero = (tmp | |
| val); } | | != val); } | |
| else not_zero = false; | | else not_zero = false; | |
| | | | |
| | | if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | const uword n_rows = A.get_n_rows(); | |
| | | const uword n_cols = A.get_n_cols(); | |
| | | | |
| | | uword i = 0; | |
| | | | |
| | | for(uword col=0; col<n_cols; ++col) | |
| | | for(uword row=0; row<n_rows; ++row) | |
| | | { | |
| | | const eT tmp = A.at(row,col); | |
| | | | |
|
| if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | | bool not_zero; | |
| | | | |
| | | if(is_same_type<op_type, op_rel_eq >::yes) { not_zero = (tmp | |
| | | == val); } | |
| | | else if(is_same_type<op_type, op_rel_noteq>::yes) { not_zero = (tmp | |
| | | != val); } | |
| | | else not_zero = false; | |
| | | | |
| | | if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | |
| | | | |
| | | i++; | |
| | | } | |
| } | | } | |
| | | | |
| return n_nz; | | return n_nz; | |
| } | | } | |
| | | | |
| template<typename T1, typename T2, typename glue_type> | | template<typename T1, typename T2, typename glue_type> | |
| inline | | inline | |
| uword | | uword | |
| op_find::helper | | op_find::helper | |
| ( | | ( | |
| | | | |
| skipping to change at line 329 | | skipping to change at line 355 | |
| ea_type1 PA = A.get_ea(); | | ea_type1 PA = A.get_ea(); | |
| ea_type2 PB = B.get_ea(); | | ea_type2 PB = B.get_ea(); | |
| | | | |
| const uword n_elem = B.get_n_elem(); | | const uword n_elem = B.get_n_elem(); | |
| | | | |
| indices.set_size(n_elem, 1); | | indices.set_size(n_elem, 1); | |
| | | | |
| uword* indices_mem = indices.memptr(); | | uword* indices_mem = indices.memptr(); | |
| uword n_nz = 0; | | uword n_nz = 0; | |
| | | | |
|
| for(uword i=0; i<n_elem; ++i) | | if(Proxy<T1>::prefer_at_accessor == false) | |
| { | | { | |
|
| bool not_zero; | | for(uword i=0; i<n_elem; ++i) | |
| | | { | |
| | | bool not_zero; | |
| | | | |
|
| if(is_same_type<glue_type, glue_rel_eq >::yes) { not_zero = (P | | if(is_same_type<glue_type, glue_rel_eq >::yes) { not_zero = | |
| A[i] == PB[i]); } | | (PA[i] == PB[i]); } | |
| else if(is_same_type<glue_type, glue_rel_noteq >::yes) { not_zero = (P | | else if(is_same_type<glue_type, glue_rel_noteq >::yes) { not_zero = | |
| A[i] != PB[i]); } | | (PA[i] != PB[i]); } | |
| else not_zero = false; | | else not_zero = false; | |
| | | | |
|
| if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | | if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | |
| | | } | |
| } | | } | |
|
| | | else | |
| | | { | |
| | | const uword n_rows = A.get_n_rows(); | |
| | | const uword n_cols = A.get_n_cols(); | |
| | | | |
| | | uword i = 0; | |
| | | | |
| | | for(uword col=0; col<n_cols; ++col) | |
| | | for(uword row=0; row<n_rows; ++row) | |
| | | { | |
| | | bool not_zero; | |
| | | | |
| | | if(is_same_type<glue_type, glue_rel_eq >::yes) { not_zero = | |
| | | (A.at(row,col) == B.at(row,col)); } | |
| | | else if(is_same_type<glue_type, glue_rel_noteq >::yes) { not_zero = | |
| | | (A.at(row,col) != B.at(row,col)); } | |
| | | else not_zero = false; | |
| | | | |
| | | if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | |
| | | | |
| | | i++; | |
| | | } | |
| | | } | |
| | | | |
| return n_nz; | | return n_nz; | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X) | | op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| skipping to change at line 373 | | skipping to change at line 423 | |
| { | | { | |
| out = (k > 0 && k <= n_nz) ? indices.rows(n_nz-k, n_nz-1) : indices.r
ows(0, n_nz-1); | | out = (k > 0 && k <= n_nz) ? indices.rows(n_nz-k, n_nz-1) : indices.r
ows(0, n_nz-1); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| out.set_size(0,1); // empty column vector | | out.set_size(0,1); // empty column vector | |
| } | | } | |
| } | | } | |
| | | | |
|
| | | // | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| | | void | |
| | | op_find_simple::apply(Mat<uword>& out, const mtOp<uword, T1, op_find_simple | |
| | | >& X) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | Mat<uword> indices; | |
| | | const uword n_nz = op_find::helper(indices, X.m); | |
| | | | |
| | | if(n_nz > 0) | |
| | | { | |
| | | if(n_nz == indices.n_elem) | |
| | | { | |
| | | out.steal_mem(indices); | |
| | | } | |
| | | else | |
| | | { | |
| | | out.set_size(n_nz, 1); | |
| | | arrayops::copy( out.memptr(), indices.memptr(), n_nz ); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | out.set_size(0,1); | |
| | | } | |
| | | } | |
| | | | |
| | | // | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| | | void | |
| | | op_find_finite::apply(Mat<uword>& out, const mtOp<uword, T1, op_find_finite | |
| | | >& X) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | const Proxy<T1> P(X.m); | |
| | | | |
| | | const uword n_elem = P.get_n_elem(); | |
| | | | |
| | | Mat<uword> indices(n_elem,1); | |
| | | | |
| | | uword* indices_mem = indices.memptr(); | |
| | | uword count = 0; | |
| | | | |
| | | if(Proxy<T1>::prefer_at_accessor == false) | |
| | | { | |
| | | const typename Proxy<T1>::ea_type Pea = P.get_ea(); | |
| | | | |
| | | for(uword i=0; i<n_elem; ++i) | |
| | | { | |
| | | if( arma_isfinite(Pea[i]) ) { indices_mem[count] = i; count++; } | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | const uword n_rows = P.get_n_rows(); | |
| | | const uword n_cols = P.get_n_cols(); | |
| | | | |
| | | uword i = 0; | |
| | | | |
| | | for(uword col=0; col<n_cols; ++col) | |
| | | for(uword row=0; row<n_rows; ++row) | |
| | | { | |
| | | if( arma_isfinite(P.at(row,col)) ) { indices_mem[count] = i; count++ | |
| | | ; } | |
| | | | |
| | | i++; | |
| | | } | |
| | | } | |
| | | | |
| | | if(count > 0) | |
| | | { | |
| | | if(count == n_elem) | |
| | | { | |
| | | out.steal_mem(indices); | |
| | | } | |
| | | else | |
| | | { | |
| | | out.set_size(count,1); | |
| | | arrayops::copy( out.memptr(), indices.memptr(), count ); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | out.set_size(0,1); | |
| | | } | |
| | | } | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| | | void | |
| | | op_find_nonfinite::apply(Mat<uword>& out, const mtOp<uword, T1, op_find_non | |
| | | finite>& X) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | const Proxy<T1> P(X.m); | |
| | | | |
| | | const uword n_elem = P.get_n_elem(); | |
| | | | |
| | | Mat<uword> indices(n_elem,1); | |
| | | | |
| | | uword* indices_mem = indices.memptr(); | |
| | | uword count = 0; | |
| | | | |
| | | if(Proxy<T1>::prefer_at_accessor == false) | |
| | | { | |
| | | const typename Proxy<T1>::ea_type Pea = P.get_ea(); | |
| | | | |
| | | for(uword i=0; i<n_elem; ++i) | |
| | | { | |
| | | if( arma_isfinite(Pea[i]) == false ) { indices_mem[count] = i; count | |
| | | ++; } | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | const uword n_rows = P.get_n_rows(); | |
| | | const uword n_cols = P.get_n_cols(); | |
| | | | |
| | | uword i = 0; | |
| | | | |
| | | for(uword col=0; col<n_cols; ++col) | |
| | | for(uword row=0; row<n_rows; ++row) | |
| | | { | |
| | | if( arma_isfinite(P.at(row,col)) == false ) { indices_mem[count] = i | |
| | | ; count++; } | |
| | | | |
| | | i++; | |
| | | } | |
| | | } | |
| | | | |
| | | if(count > 0) | |
| | | { | |
| | | if(count == n_elem) | |
| | | { | |
| | | out.steal_mem(indices); | |
| | | } | |
| | | else | |
| | | { | |
| | | out.set_size(count,1); | |
| | | arrayops::copy( out.memptr(), indices.memptr(), count ); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | out.set_size(0,1); | |
| | | } | |
| | | } | |
| | | | |
| //! @} | | //! @} | |
| | | | |
End of changes. 11 change blocks. |
| 17 lines changed or deleted | | 227 lines changed or added | |
|