Loading include/dca/io/hdf5/hdf5_reader.hpp +68 −17 Original line number Diff line number Diff line Loading @@ -96,6 +96,12 @@ public: template <typename scalar_type> bool execute(std::string name, dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A); template <typename scalar_type> bool execute(std::string name, dca::linalg::Matrix<std::complex<scalar_type>, dca::linalg::CPU>& A); template <typename scalar_type> bool execute(dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A); bool execute(std::string name, io::Buffer& buff) { return execute(name, static_cast<io::Buffer::Container&>(buff)); } Loading Loading @@ -215,11 +221,10 @@ bool HDF5Reader::execute(std::string name, func::function<scalartype, domain_typ template <typename scalar_type> bool HDF5Reader::execute(std::string name, dca::linalg::Vector<scalar_type, dca::linalg::CPU>& V) { open_group(name); bool success = true; try { std::string full_name = get_path() + "/data"; std::string full_name = get_path() + "/" + name; H5::DataSet dataset = my_file->openDataSet(full_name.c_str()); Loading @@ -229,24 +234,24 @@ bool HDF5Reader::execute(std::string name, dca::linalg::Vector<scalar_type, dca: H5Dread(dataset.getId(), HDF5_TYPE<scalar_type>::get(), dataspace.getId(), H5S_ALL, H5P_DEFAULT, &V[0]); V.set_name(name); } catch (const H5::FileIException& err) { std::cout << "\n\n\t the vector (" + name + ") does not exist in path : " + get_path() + "\n\n"; success = false; } close_group(); return success; } template <typename scalar_type> bool HDF5Reader::execute(std::string name, dca::linalg::Vector<std::complex<scalar_type>, dca::linalg::CPU>& V) { open_group(name); bool success = true; try { std::string full_name = get_path() + "/data"; std::string full_name = get_path() + "/" + name; H5::DataSet dataset = my_file->openDataSet(full_name.c_str()); Loading @@ -256,37 +261,79 @@ bool HDF5Reader::execute(std::string name, H5Dread(dataset.getId(), HDF5_TYPE<scalar_type>::get(), dataspace.getId(), H5S_ALL, H5P_DEFAULT, &V[0]); V.set_name(name); } catch (const H5::FileIException& err) { std::cout << "\n\n\t the vector (" + name + ") does not exist in path : " + get_path() + "\n\n"; success = false; } close_group(); return success; } template <typename scalar_type> bool HDF5Reader::execute(std::string name, dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A) { open_group(name); bool success = true; try { std::string full_name = get_path() + "/data"; std::string full_name = get_path() + "/" + name; H5::DataSet dataset = my_file->openDataSet(full_name.c_str()); H5::DataSpace dataspace = dataset.getSpace(); std::array<hsize_t, 2> dims; dataspace.getSimpleExtentDims(dims.data(), nullptr); std::vector<scalar_type> linearized(dims[0] * dims[1]); dataset.read(linearized.data(), HDF5_TYPE<scalar_type>::get_PredType(), dataspace); // HDF5 is column major, while Matrix is not major. A.resizeNoCopy(std::make_pair(dims[0], dims[1])); unsigned linindex = 0; for (int i = 0; i < A.nrRows(); ++i) { for (int j = 0; j < A.nrCols(); ++j) A(i, j) = linearized[linindex++]; } A.set_name(name); } catch (const H5::FileIException& err) { std::cout << "\n\n\t the function (" + name + ") does not exist in path : " + get_path() + "\n\n"; success = false; } return success; } template <typename scalar_type> bool HDF5Reader::execute(std::string name, dca::linalg::Matrix<std::complex<scalar_type>, dca::linalg::CPU>& A) { bool success = true; try { std::string full_name = get_path() + "/" + name; H5::DataSet dataset = my_file->openDataSet(full_name.c_str()); H5::DataSpace dataspace = dataset.getSpace(); // These 2 lines fix the bug of reading into a matrix which has been resized to a smaller size // hsize_t global_size[2] = {A.nrCols(), A.nrRows()}; // HDF5 use row // major data distribution // hsize_t global_size[2] = {A.capacity().second, A.capacity().first}; // HDF5 use // row major data distribution // dataspace.setExtentSimple(2, &global_size[0], NULL); std::array<hsize_t, 3> dims; dataspace.getSimpleExtentDims(dims.data(), nullptr); H5Dread(dataset.getId(), HDF5_TYPE<scalar_type>::get(), dataspace.getId(), H5S_ALL, H5P_DEFAULT, &A(0, 0)); A.resizeNoCopy(std::make_pair(dims[1], dims[2])); std::vector<std::complex<scalar_type>> linearized(A.nrRows() * A.nrCols()); dataset.read(linearized.data(), HDF5_TYPE<scalar_type>::get_PredType(), dataspace); // HDF5 is column major, while Matrix is not major. unsigned linindex = 0; for (int i = 0; i < A.nrRows(); ++i) for (int j = 0; j < A.nrCols(); ++j) { A(i, j) = linearized[linindex++]; } A.set_name(name); } catch (const H5::FileIException& err) { std::cout << "\n\n\t the function (" + name + ") does not exist in path : " + get_path() + Loading @@ -294,10 +341,14 @@ bool HDF5Reader::execute(std::string name, dca::linalg::Matrix<scalar_type, dca: success = false; } close_group(); return success; } template <typename scalar_type> bool HDF5Reader::execute(dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A) { return execute(A.get_name(), A); } } // namespace io } // namespace dca Loading include/dca/io/hdf5/hdf5_writer.hpp +97 −368 Original line number Diff line number Diff line Loading @@ -43,10 +43,10 @@ public: ~HDF5Writer(); bool is_reader() { constexpr bool is_reader() { return false; } bool is_writer() { constexpr bool is_writer() { return true; } Loading @@ -58,6 +58,11 @@ public: std::string get_path(); // Closes all open datasets. Overwriting them will no longer be possible. void flush() { datasets_.clear(); } template <typename arbitrary_struct_t> static void to_file(const arbitrary_struct_t& arbitrary_struct, const std::string& file_name); Loading Loading @@ -128,7 +133,10 @@ public: return execute(name, static_cast<io::Buffer::Container>(buffer)); } bool pathExists(const std::string& path) const; bool groupExists(const std::string& path) const; // Returns -1 if datasets does not exist. std::array<hsize_t, 2> datasetId(const std::string& path); operator bool() const { return static_cast<bool>(file_); Loading @@ -145,11 +153,16 @@ public: private: bool fexists(const char* filename); void write(const std::string& name, const std::vector<hsize_t>& size, H5::PredType type, const void* data); std::unique_ptr<H5::H5File> file_; hid_t file_id; std::unordered_map<std::string, std::unique_ptr<H5::Group>> groups_; std::unordered_map<std::string, std::pair<std::unique_ptr<H5::DataSet>, std::unique_ptr<H5::DataSpace>>> datasets_; std::vector<std::string> my_paths; bool verbose_; Loading @@ -167,54 +180,18 @@ void HDF5Writer::to_file(const arbitrary_struct_t& arbitrary_struct, const std:: template <typename scalar_type> void HDF5Writer::execute(const std::string& name, scalar_type value) { H5::H5File& file = (*file_); std::string path = get_path(); const std::string full_name = get_path() + "/" + name; std::vector<hsize_t> dims{1}; hsize_t dims[1]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dims[0] = 1; dataspace = new H5::DataSpace(1, dims); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value); } delete dataset; delete dataspace; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), &value); } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const std::pair<scalar_type, scalar_type>& value) { H5::H5File& file = (*file_); std::string path = get_path(); hsize_t dims[1]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dims[0] = 2; dataspace = new H5::DataSpace(1, dims); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &(value.first)); } std::string full_name = get_path() + "/" + name; std::vector<hsize_t> dims{2}; delete dataset; delete dataspace; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), &value.first); } template <typename scalar_type> Loading @@ -222,149 +199,57 @@ void HDF5Writer::execute(const std::string& name, const std::vector<scalar_type>& value) //, H5File& file, std::string path) { if (value.size() > 0) { H5::H5File& file = (*file_); std::string path = get_path(); hsize_t dims[1]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dims[0] = value.size(); dataspace = new H5::DataSpace(1, dims); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value[0]); } delete dataset; delete dataspace; std::string full_name = get_path() + "/" + name; std::vector<hsize_t> dims{value.size()}; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), value.data()); } } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const std::vector<std::complex<scalar_type>>& value) { H5::H5File& file = (*file_); std::string path = get_path(); hsize_t dims[2]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dims[0] = 2; dims[1] = value.size(); dataspace = new H5::DataSpace(2, dims); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value[0]); if (value.size() > 0) { std::string full_name = get_path() + "/" + name; std::vector<hsize_t> dims{2, value.size()}; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), value.data()); } delete dataset; delete dataspace; } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const std::vector<std::vector<scalar_type>>& value) { if (value.size() > 0) { H5::H5File& file = (*file_); std::string full_name = get_path() + "/" + name; bool all_the_same_size = true; std::vector<size_t> dim(2, 0); { dim[0] = value.size(); dim[1] = value[0].size(); for (size_t l = 0; l < dim[0]; l++) if (dim[1] != value[l].size()) const std::size_t cols = value[0].size(); for (auto& v : value) { if (v.size() != cols) { all_the_same_size = false; break; } } open_group(name); execute("equal-size", all_the_same_size); H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; if (all_the_same_size) { execute("size", dim); hsize_t dims[2]; std::vector<hsize_t> dims{value.size(), cols}; std::vector<scalar_type> linearized(dims[0] * dims[1]); { dims[0] = value.size(); dims[1] = value[0].size(); dataspace = new H5::DataSpace(2, dims); std::size_t linindex = 0; for (std::size_t i = 0; i < value.size(); ++i) for (std::size_t j = 0; j < cols; ++j, ++linindex) linearized[linindex] = value[i][j]; std::string full_name = get_path() + "/data"; dataset = new H5::DataSet(file.createDataSet( full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); scalar_type* tmp = new scalar_type[dims[0] * dims[1]]; /* for(int i=0; i<dims[0]; i++) for(int j=0; j<dims[1]; j++) tmp[i+j*dims[0]] = value[i][j]; */ // hdf5 has row-major ordering! for (hsize_t i = 0; i < dims[0]; i++) for (hsize_t j = 0; j < dims[1]; j++) tmp[i * dims[1] + j] = value[i][j]; H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, tmp); delete[] tmp; } write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), value.data()); } else { execute("size_i", dim[0]); dim.resize(0); for (size_t l = 0; l < value.size(); l++) dim.push_back(value[l].size()); execute("size_j", dim); hsize_t dims[1]; open_group("data"); for (size_t l = 0; l < value.size(); l++) { dims[0] = value[l].size(); dataspace = new H5::DataSpace(1, dims); std::stringstream ss; ss << get_path() << "/" << l; dataset = new H5::DataSet(file.createDataSet( ss.str().c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value[l]); open_group(full_name); std::vector<hsize_t> dims(1); for (std::size_t i = 0; i < value.size(); ++i) { const std::string new_name = full_name + "/row_" + std::to_string(i); dims[0] = value[i].size(); write(new_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), value[i].data()); } close_group(); } delete dataset; delete dataspace; close_group(); } } Loading Loading @@ -437,54 +322,27 @@ void HDF5Writer::execute(const std::string& name, const func::function<scalar_ty if (f.size() == 0) return; H5::H5File& file = (*file_); open_group(name); std::string new_path = get_path(); { execute("name", f.get_name()); { std::vector<int> vec(0); std::vector<hsize_t> dims(0); for (int l = 0; l < f.signature(); l++) vec.push_back(f[l]); int n_dims = f.signature(); for (int l = 0; l < n_dims; l++) dims.push_back(f[l]); execute("domain-sizes", vec); } { int N_dmns = f.signature(); std::vector<hsize_t> dims(N_dmns); // hsize_t dims[N_dmns]; // for(int l=0; l<N_dmns; l++) // dims[l] = f[l]; execute("domain-sizes", dims); // be carefull --> HDF5 is by default row-major, while the function-class is column-major ! for (int l = 0; l < N_dmns; l++) dims[N_dmns - 1 - l] = f[l]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dataspace = new H5::DataSpace(N_dmns, &dims[0]); for (int l = 0; l < n_dims; l++) dims[n_dims - 1 - l] = f[l]; std::string full_name = new_path + "/data"; dataset = new H5::DataSet(file.createDataSet( full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &f(0)); } delete dataset; delete dataspace; } } write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), f.values()); close_group(); } Loading @@ -495,50 +353,29 @@ void HDF5Writer::execute(const std::string& name, if (f.size() == 0) return; H5::H5File& file = (*file_); open_group(name); { std::string new_path = get_path(); execute("name", f.get_name()); { std::vector<int> vec(0); std::vector<hsize_t> dims(0); for (int l = 0; l < f.signature(); l++) vec.push_back(f[l]); int n_dims = f.signature(); for (int l = 0; l < n_dims; l++) dims.push_back(f[l]); execute("domain-sizes", vec); } { int N_dmns = f.signature(); std::vector<hsize_t> dims(N_dmns + 1); execute("domain-sizes", dims); dims.resize(n_dims + 1); // be carefull --> HDF5 is by default row-major, while the function-class is column-major ! dims[N_dmns] = 2; for (int l = 0; l < N_dmns; l++) dims[N_dmns - 1 - l] = f[l]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; for (int l = 0; l < n_dims; l++) dims[n_dims - l] = f[l]; { dataspace = new H5::DataSpace(N_dmns + 1, &dims[0]); dims[0] = 2; std::string full_name = get_path() + "/data"; dataset = new H5::DataSet(file.createDataSet( full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &f(0)); } delete dataset; delete dataspace; } } write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), f.values()); close_group(); } Loading @@ -546,156 +383,48 @@ void HDF5Writer::execute(const std::string& name, template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const dca::linalg::Vector<scalar_type, dca::linalg::CPU>& V) { H5::H5File& file = (*file_); open_group(name); execute("name", V.get_name()); execute("size", V.get_size()); hsize_t dims[1]; dims[0] = V.size(); H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dataspace = new H5::DataSpace(1, dims); std::string full_name = get_path() + "/data"; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &V[0]); } delete dataset; delete dataspace; close_group(); std::string full_name = get_path() + "/" + name; write(full_name, std::vector<hsize_t>{V.size()}, HDF5_TYPE<scalar_type>::get_PredType(), V.ptr()); } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const dca::linalg::Vector<std::complex<scalar_type>, dca::linalg::CPU>& V) { H5::H5File& file = (*file_); open_group(name); execute("name", V.get_name()); execute("size", V.size()); hsize_t dims[2]; dims[0] = 2; dims[1] = V.size(); H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dataspace = new H5::DataSpace(2, dims); std::string full_name = get_path() + "/data"; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &V[0]); } delete dataset; delete dataspace; close_group(); std::string full_name = get_path() + "/" + name; write(full_name, std::vector<hsize_t>{2, V.size()}, HDF5_TYPE<scalar_type>::get_PredType(), V.ptr()); } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A) { H5::H5File& file = (*file_); open_group(name); { execute("name", A.get_name()); execute("current-size", A.size()); execute("global-size", A.capacity()); } std::vector<hsize_t> dims{hsize_t(A.nrRows()), hsize_t(A.nrCols())}; std::vector<scalar_type> linearized(dims[0] * dims[1]); hsize_t dims[2]; dims[0] = A.capacity().first; dims[1] = A.capacity().second; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dataspace = new H5::DataSpace(2, dims); std::string full_name = get_path() + "/data"; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &A(0, 0)); } delete dataset; delete dataspace; int linindex = 0; // Note: Matrices are row major, while HDF5 is column major for (int i = 0; i < A.nrRows(); ++i) for (int j = 0; j < A.nrCols(); ++j) linearized[linindex++] = A(i, j); close_group(); std::string full_name = get_path() + "/" + name; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), linearized.data()); } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const dca::linalg::Matrix<std::complex<scalar_type>, dca::linalg::CPU>& A) { H5::H5File& file = (*file_); open_group(name); { execute("name", A.get_name()); std::vector<int> vec(2, 0); vec[0] = A.size().first; vec[1] = A.size().second; execute("current-size", vec); vec[0] = A.capacity().first; vec[1] = A.capacity().second; execute("global-size", vec); } hsize_t dims[3]; dims[0] = 2; dims[1] = A.capacity().first; dims[2] = A.capacity().second; std::vector<hsize_t> dims{hsize_t(2), hsize_t(A.nrRows()), hsize_t(A.nrCols())}; std::vector<std::complex<scalar_type>> linearized(A.nrRows() * A.nrCols()); H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; int linindex = 0; // Note: Matrices are row major, while HDF5 is column major for (int i = 0; i < A.nrRows(); ++i) for (int j = 0; j < A.nrCols(); ++j) linearized[linindex++] = A(i, j); { dataspace = new H5::DataSpace(3, dims); std::string full_name = get_path() + "/data"; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &A(0, 0)); } delete dataset; delete dataspace; close_group(); std::string full_name = get_path() + "/" + name; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), linearized.data()); } template <class T> Loading src/io/hdf5/hdf5_reader.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ void HDF5Reader::open_file(std::string file_name) { } void HDF5Reader::close_file() { my_file->close(); delete my_file; my_file = NULL; } Loading src/io/hdf5/hdf5_writer.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -52,7 +52,9 @@ H5::H5File& HDF5Writer::open_file(std::string file_name, bool overwrite) { } void HDF5Writer::close_file() { datasets_.clear(); groups_.clear(); file_->close(); file_.release(); } Loading @@ -60,7 +62,7 @@ void HDF5Writer::open_group(std::string name) { my_paths.push_back(name); const std::string path = get_path(); if (!pathExists(path)) { if (!groupExists(path)) { groups_[path] = std::make_unique<H5::Group>(file_->createGroup(path.c_str())); } } Loading Loading @@ -151,9 +153,21 @@ void HDF5Writer::execute(const std::string& name, } } bool HDF5Writer::pathExists(const std::string& path) const { bool HDF5Writer::groupExists(const std::string& path) const { return groups_.count(path); } void HDF5Writer::write(const std::string& name, const std::vector<hsize_t>& dims, H5::PredType type, const void* data) { if (datasets_.count(name) == 0) { datasets_[name].second = std::make_unique<H5::DataSpace>(dims.size(), dims.data()); datasets_[name].first = std::make_unique<H5::DataSet>( file_->createDataSet(name.c_str(), type, *datasets_[name].second)); } // TODO: check pre-existing size datasets_[name].first->write(data, type, *datasets_[name].second, H5P_DEFAULT); } } // namespace io } // namespace dca test/unit/io/hdf5_reader_writer_test.cpp +89 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
include/dca/io/hdf5/hdf5_reader.hpp +68 −17 Original line number Diff line number Diff line Loading @@ -96,6 +96,12 @@ public: template <typename scalar_type> bool execute(std::string name, dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A); template <typename scalar_type> bool execute(std::string name, dca::linalg::Matrix<std::complex<scalar_type>, dca::linalg::CPU>& A); template <typename scalar_type> bool execute(dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A); bool execute(std::string name, io::Buffer& buff) { return execute(name, static_cast<io::Buffer::Container&>(buff)); } Loading Loading @@ -215,11 +221,10 @@ bool HDF5Reader::execute(std::string name, func::function<scalartype, domain_typ template <typename scalar_type> bool HDF5Reader::execute(std::string name, dca::linalg::Vector<scalar_type, dca::linalg::CPU>& V) { open_group(name); bool success = true; try { std::string full_name = get_path() + "/data"; std::string full_name = get_path() + "/" + name; H5::DataSet dataset = my_file->openDataSet(full_name.c_str()); Loading @@ -229,24 +234,24 @@ bool HDF5Reader::execute(std::string name, dca::linalg::Vector<scalar_type, dca: H5Dread(dataset.getId(), HDF5_TYPE<scalar_type>::get(), dataspace.getId(), H5S_ALL, H5P_DEFAULT, &V[0]); V.set_name(name); } catch (const H5::FileIException& err) { std::cout << "\n\n\t the vector (" + name + ") does not exist in path : " + get_path() + "\n\n"; success = false; } close_group(); return success; } template <typename scalar_type> bool HDF5Reader::execute(std::string name, dca::linalg::Vector<std::complex<scalar_type>, dca::linalg::CPU>& V) { open_group(name); bool success = true; try { std::string full_name = get_path() + "/data"; std::string full_name = get_path() + "/" + name; H5::DataSet dataset = my_file->openDataSet(full_name.c_str()); Loading @@ -256,37 +261,79 @@ bool HDF5Reader::execute(std::string name, H5Dread(dataset.getId(), HDF5_TYPE<scalar_type>::get(), dataspace.getId(), H5S_ALL, H5P_DEFAULT, &V[0]); V.set_name(name); } catch (const H5::FileIException& err) { std::cout << "\n\n\t the vector (" + name + ") does not exist in path : " + get_path() + "\n\n"; success = false; } close_group(); return success; } template <typename scalar_type> bool HDF5Reader::execute(std::string name, dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A) { open_group(name); bool success = true; try { std::string full_name = get_path() + "/data"; std::string full_name = get_path() + "/" + name; H5::DataSet dataset = my_file->openDataSet(full_name.c_str()); H5::DataSpace dataspace = dataset.getSpace(); std::array<hsize_t, 2> dims; dataspace.getSimpleExtentDims(dims.data(), nullptr); std::vector<scalar_type> linearized(dims[0] * dims[1]); dataset.read(linearized.data(), HDF5_TYPE<scalar_type>::get_PredType(), dataspace); // HDF5 is column major, while Matrix is not major. A.resizeNoCopy(std::make_pair(dims[0], dims[1])); unsigned linindex = 0; for (int i = 0; i < A.nrRows(); ++i) { for (int j = 0; j < A.nrCols(); ++j) A(i, j) = linearized[linindex++]; } A.set_name(name); } catch (const H5::FileIException& err) { std::cout << "\n\n\t the function (" + name + ") does not exist in path : " + get_path() + "\n\n"; success = false; } return success; } template <typename scalar_type> bool HDF5Reader::execute(std::string name, dca::linalg::Matrix<std::complex<scalar_type>, dca::linalg::CPU>& A) { bool success = true; try { std::string full_name = get_path() + "/" + name; H5::DataSet dataset = my_file->openDataSet(full_name.c_str()); H5::DataSpace dataspace = dataset.getSpace(); // These 2 lines fix the bug of reading into a matrix which has been resized to a smaller size // hsize_t global_size[2] = {A.nrCols(), A.nrRows()}; // HDF5 use row // major data distribution // hsize_t global_size[2] = {A.capacity().second, A.capacity().first}; // HDF5 use // row major data distribution // dataspace.setExtentSimple(2, &global_size[0], NULL); std::array<hsize_t, 3> dims; dataspace.getSimpleExtentDims(dims.data(), nullptr); H5Dread(dataset.getId(), HDF5_TYPE<scalar_type>::get(), dataspace.getId(), H5S_ALL, H5P_DEFAULT, &A(0, 0)); A.resizeNoCopy(std::make_pair(dims[1], dims[2])); std::vector<std::complex<scalar_type>> linearized(A.nrRows() * A.nrCols()); dataset.read(linearized.data(), HDF5_TYPE<scalar_type>::get_PredType(), dataspace); // HDF5 is column major, while Matrix is not major. unsigned linindex = 0; for (int i = 0; i < A.nrRows(); ++i) for (int j = 0; j < A.nrCols(); ++j) { A(i, j) = linearized[linindex++]; } A.set_name(name); } catch (const H5::FileIException& err) { std::cout << "\n\n\t the function (" + name + ") does not exist in path : " + get_path() + Loading @@ -294,10 +341,14 @@ bool HDF5Reader::execute(std::string name, dca::linalg::Matrix<scalar_type, dca: success = false; } close_group(); return success; } template <typename scalar_type> bool HDF5Reader::execute(dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A) { return execute(A.get_name(), A); } } // namespace io } // namespace dca Loading
include/dca/io/hdf5/hdf5_writer.hpp +97 −368 Original line number Diff line number Diff line Loading @@ -43,10 +43,10 @@ public: ~HDF5Writer(); bool is_reader() { constexpr bool is_reader() { return false; } bool is_writer() { constexpr bool is_writer() { return true; } Loading @@ -58,6 +58,11 @@ public: std::string get_path(); // Closes all open datasets. Overwriting them will no longer be possible. void flush() { datasets_.clear(); } template <typename arbitrary_struct_t> static void to_file(const arbitrary_struct_t& arbitrary_struct, const std::string& file_name); Loading Loading @@ -128,7 +133,10 @@ public: return execute(name, static_cast<io::Buffer::Container>(buffer)); } bool pathExists(const std::string& path) const; bool groupExists(const std::string& path) const; // Returns -1 if datasets does not exist. std::array<hsize_t, 2> datasetId(const std::string& path); operator bool() const { return static_cast<bool>(file_); Loading @@ -145,11 +153,16 @@ public: private: bool fexists(const char* filename); void write(const std::string& name, const std::vector<hsize_t>& size, H5::PredType type, const void* data); std::unique_ptr<H5::H5File> file_; hid_t file_id; std::unordered_map<std::string, std::unique_ptr<H5::Group>> groups_; std::unordered_map<std::string, std::pair<std::unique_ptr<H5::DataSet>, std::unique_ptr<H5::DataSpace>>> datasets_; std::vector<std::string> my_paths; bool verbose_; Loading @@ -167,54 +180,18 @@ void HDF5Writer::to_file(const arbitrary_struct_t& arbitrary_struct, const std:: template <typename scalar_type> void HDF5Writer::execute(const std::string& name, scalar_type value) { H5::H5File& file = (*file_); std::string path = get_path(); const std::string full_name = get_path() + "/" + name; std::vector<hsize_t> dims{1}; hsize_t dims[1]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dims[0] = 1; dataspace = new H5::DataSpace(1, dims); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value); } delete dataset; delete dataspace; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), &value); } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const std::pair<scalar_type, scalar_type>& value) { H5::H5File& file = (*file_); std::string path = get_path(); hsize_t dims[1]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dims[0] = 2; dataspace = new H5::DataSpace(1, dims); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &(value.first)); } std::string full_name = get_path() + "/" + name; std::vector<hsize_t> dims{2}; delete dataset; delete dataspace; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), &value.first); } template <typename scalar_type> Loading @@ -222,149 +199,57 @@ void HDF5Writer::execute(const std::string& name, const std::vector<scalar_type>& value) //, H5File& file, std::string path) { if (value.size() > 0) { H5::H5File& file = (*file_); std::string path = get_path(); hsize_t dims[1]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dims[0] = value.size(); dataspace = new H5::DataSpace(1, dims); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value[0]); } delete dataset; delete dataspace; std::string full_name = get_path() + "/" + name; std::vector<hsize_t> dims{value.size()}; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), value.data()); } } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const std::vector<std::complex<scalar_type>>& value) { H5::H5File& file = (*file_); std::string path = get_path(); hsize_t dims[2]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dims[0] = 2; dims[1] = value.size(); dataspace = new H5::DataSpace(2, dims); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value[0]); if (value.size() > 0) { std::string full_name = get_path() + "/" + name; std::vector<hsize_t> dims{2, value.size()}; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), value.data()); } delete dataset; delete dataspace; } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const std::vector<std::vector<scalar_type>>& value) { if (value.size() > 0) { H5::H5File& file = (*file_); std::string full_name = get_path() + "/" + name; bool all_the_same_size = true; std::vector<size_t> dim(2, 0); { dim[0] = value.size(); dim[1] = value[0].size(); for (size_t l = 0; l < dim[0]; l++) if (dim[1] != value[l].size()) const std::size_t cols = value[0].size(); for (auto& v : value) { if (v.size() != cols) { all_the_same_size = false; break; } } open_group(name); execute("equal-size", all_the_same_size); H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; if (all_the_same_size) { execute("size", dim); hsize_t dims[2]; std::vector<hsize_t> dims{value.size(), cols}; std::vector<scalar_type> linearized(dims[0] * dims[1]); { dims[0] = value.size(); dims[1] = value[0].size(); dataspace = new H5::DataSpace(2, dims); std::size_t linindex = 0; for (std::size_t i = 0; i < value.size(); ++i) for (std::size_t j = 0; j < cols; ++j, ++linindex) linearized[linindex] = value[i][j]; std::string full_name = get_path() + "/data"; dataset = new H5::DataSet(file.createDataSet( full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); scalar_type* tmp = new scalar_type[dims[0] * dims[1]]; /* for(int i=0; i<dims[0]; i++) for(int j=0; j<dims[1]; j++) tmp[i+j*dims[0]] = value[i][j]; */ // hdf5 has row-major ordering! for (hsize_t i = 0; i < dims[0]; i++) for (hsize_t j = 0; j < dims[1]; j++) tmp[i * dims[1] + j] = value[i][j]; H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, tmp); delete[] tmp; } write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), value.data()); } else { execute("size_i", dim[0]); dim.resize(0); for (size_t l = 0; l < value.size(); l++) dim.push_back(value[l].size()); execute("size_j", dim); hsize_t dims[1]; open_group("data"); for (size_t l = 0; l < value.size(); l++) { dims[0] = value[l].size(); dataspace = new H5::DataSpace(1, dims); std::stringstream ss; ss << get_path() << "/" << l; dataset = new H5::DataSet(file.createDataSet( ss.str().c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value[l]); open_group(full_name); std::vector<hsize_t> dims(1); for (std::size_t i = 0; i < value.size(); ++i) { const std::string new_name = full_name + "/row_" + std::to_string(i); dims[0] = value[i].size(); write(new_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), value[i].data()); } close_group(); } delete dataset; delete dataspace; close_group(); } } Loading Loading @@ -437,54 +322,27 @@ void HDF5Writer::execute(const std::string& name, const func::function<scalar_ty if (f.size() == 0) return; H5::H5File& file = (*file_); open_group(name); std::string new_path = get_path(); { execute("name", f.get_name()); { std::vector<int> vec(0); std::vector<hsize_t> dims(0); for (int l = 0; l < f.signature(); l++) vec.push_back(f[l]); int n_dims = f.signature(); for (int l = 0; l < n_dims; l++) dims.push_back(f[l]); execute("domain-sizes", vec); } { int N_dmns = f.signature(); std::vector<hsize_t> dims(N_dmns); // hsize_t dims[N_dmns]; // for(int l=0; l<N_dmns; l++) // dims[l] = f[l]; execute("domain-sizes", dims); // be carefull --> HDF5 is by default row-major, while the function-class is column-major ! for (int l = 0; l < N_dmns; l++) dims[N_dmns - 1 - l] = f[l]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dataspace = new H5::DataSpace(N_dmns, &dims[0]); for (int l = 0; l < n_dims; l++) dims[n_dims - 1 - l] = f[l]; std::string full_name = new_path + "/data"; dataset = new H5::DataSet(file.createDataSet( full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &f(0)); } delete dataset; delete dataspace; } } write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), f.values()); close_group(); } Loading @@ -495,50 +353,29 @@ void HDF5Writer::execute(const std::string& name, if (f.size() == 0) return; H5::H5File& file = (*file_); open_group(name); { std::string new_path = get_path(); execute("name", f.get_name()); { std::vector<int> vec(0); std::vector<hsize_t> dims(0); for (int l = 0; l < f.signature(); l++) vec.push_back(f[l]); int n_dims = f.signature(); for (int l = 0; l < n_dims; l++) dims.push_back(f[l]); execute("domain-sizes", vec); } { int N_dmns = f.signature(); std::vector<hsize_t> dims(N_dmns + 1); execute("domain-sizes", dims); dims.resize(n_dims + 1); // be carefull --> HDF5 is by default row-major, while the function-class is column-major ! dims[N_dmns] = 2; for (int l = 0; l < N_dmns; l++) dims[N_dmns - 1 - l] = f[l]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; for (int l = 0; l < n_dims; l++) dims[n_dims - l] = f[l]; { dataspace = new H5::DataSpace(N_dmns + 1, &dims[0]); dims[0] = 2; std::string full_name = get_path() + "/data"; dataset = new H5::DataSet(file.createDataSet( full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &f(0)); } delete dataset; delete dataspace; } } write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), f.values()); close_group(); } Loading @@ -546,156 +383,48 @@ void HDF5Writer::execute(const std::string& name, template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const dca::linalg::Vector<scalar_type, dca::linalg::CPU>& V) { H5::H5File& file = (*file_); open_group(name); execute("name", V.get_name()); execute("size", V.get_size()); hsize_t dims[1]; dims[0] = V.size(); H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dataspace = new H5::DataSpace(1, dims); std::string full_name = get_path() + "/data"; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &V[0]); } delete dataset; delete dataspace; close_group(); std::string full_name = get_path() + "/" + name; write(full_name, std::vector<hsize_t>{V.size()}, HDF5_TYPE<scalar_type>::get_PredType(), V.ptr()); } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const dca::linalg::Vector<std::complex<scalar_type>, dca::linalg::CPU>& V) { H5::H5File& file = (*file_); open_group(name); execute("name", V.get_name()); execute("size", V.size()); hsize_t dims[2]; dims[0] = 2; dims[1] = V.size(); H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dataspace = new H5::DataSpace(2, dims); std::string full_name = get_path() + "/data"; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &V[0]); } delete dataset; delete dataspace; close_group(); std::string full_name = get_path() + "/" + name; write(full_name, std::vector<hsize_t>{2, V.size()}, HDF5_TYPE<scalar_type>::get_PredType(), V.ptr()); } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const dca::linalg::Matrix<scalar_type, dca::linalg::CPU>& A) { H5::H5File& file = (*file_); open_group(name); { execute("name", A.get_name()); execute("current-size", A.size()); execute("global-size", A.capacity()); } std::vector<hsize_t> dims{hsize_t(A.nrRows()), hsize_t(A.nrCols())}; std::vector<scalar_type> linearized(dims[0] * dims[1]); hsize_t dims[2]; dims[0] = A.capacity().first; dims[1] = A.capacity().second; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; { dataspace = new H5::DataSpace(2, dims); std::string full_name = get_path() + "/data"; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &A(0, 0)); } delete dataset; delete dataspace; int linindex = 0; // Note: Matrices are row major, while HDF5 is column major for (int i = 0; i < A.nrRows(); ++i) for (int j = 0; j < A.nrCols(); ++j) linearized[linindex++] = A(i, j); close_group(); std::string full_name = get_path() + "/" + name; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), linearized.data()); } template <typename scalar_type> void HDF5Writer::execute(const std::string& name, const dca::linalg::Matrix<std::complex<scalar_type>, dca::linalg::CPU>& A) { H5::H5File& file = (*file_); open_group(name); { execute("name", A.get_name()); std::vector<int> vec(2, 0); vec[0] = A.size().first; vec[1] = A.size().second; execute("current-size", vec); vec[0] = A.capacity().first; vec[1] = A.capacity().second; execute("global-size", vec); } hsize_t dims[3]; dims[0] = 2; dims[1] = A.capacity().first; dims[2] = A.capacity().second; std::vector<hsize_t> dims{hsize_t(2), hsize_t(A.nrRows()), hsize_t(A.nrCols())}; std::vector<std::complex<scalar_type>> linearized(A.nrRows() * A.nrCols()); H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; int linindex = 0; // Note: Matrices are row major, while HDF5 is column major for (int i = 0; i < A.nrRows(); ++i) for (int j = 0; j < A.nrCols(); ++j) linearized[linindex++] = A(i, j); { dataspace = new H5::DataSpace(3, dims); std::string full_name = get_path() + "/data"; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<scalar_type>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<scalar_type>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &A(0, 0)); } delete dataset; delete dataspace; close_group(); std::string full_name = get_path() + "/" + name; write(full_name, dims, HDF5_TYPE<scalar_type>::get_PredType(), linearized.data()); } template <class T> Loading
src/io/hdf5/hdf5_reader.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ void HDF5Reader::open_file(std::string file_name) { } void HDF5Reader::close_file() { my_file->close(); delete my_file; my_file = NULL; } Loading
src/io/hdf5/hdf5_writer.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -52,7 +52,9 @@ H5::H5File& HDF5Writer::open_file(std::string file_name, bool overwrite) { } void HDF5Writer::close_file() { datasets_.clear(); groups_.clear(); file_->close(); file_.release(); } Loading @@ -60,7 +62,7 @@ void HDF5Writer::open_group(std::string name) { my_paths.push_back(name); const std::string path = get_path(); if (!pathExists(path)) { if (!groupExists(path)) { groups_[path] = std::make_unique<H5::Group>(file_->createGroup(path.c_str())); } } Loading Loading @@ -151,9 +153,21 @@ void HDF5Writer::execute(const std::string& name, } } bool HDF5Writer::pathExists(const std::string& path) const { bool HDF5Writer::groupExists(const std::string& path) const { return groups_.count(path); } void HDF5Writer::write(const std::string& name, const std::vector<hsize_t>& dims, H5::PredType type, const void* data) { if (datasets_.count(name) == 0) { datasets_[name].second = std::make_unique<H5::DataSpace>(dims.size(), dims.data()); datasets_[name].first = std::make_unique<H5::DataSet>( file_->createDataSet(name.c_str(), type, *datasets_[name].second)); } // TODO: check pre-existing size datasets_[name].first->write(data, type, *datasets_[name].second, H5P_DEFAULT); } } // namespace io } // namespace dca
test/unit/io/hdf5_reader_writer_test.cpp +89 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes