Loading include/dca/io/hdf5/hdf5_writer.hpp +8 −17 Original line number Diff line number Diff line Loading @@ -39,7 +39,9 @@ public: public: // In: verbose. If true, the writer outputs a short log whenever it is executed. HDF5Writer(bool verbose = true) : file_id(-1), my_paths(0), verbose_(verbose) {} HDF5Writer(bool verbose = true) : verbose_(verbose) { H5::Exception::dontPrint(); } ~HDF5Writer(); Loading @@ -50,7 +52,7 @@ public: return true; } H5::H5File& open_file(std::string file_name_ref, bool overwrite = true); void open_file(std::string file_name_ref, bool overwrite = true); void close_file(); void open_group(std::string new_path); Loading @@ -58,11 +60,6 @@ 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 @@ -133,11 +130,6 @@ public: return execute(name, static_cast<io::Buffer::Container>(buffer)); } 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 @@ -153,17 +145,16 @@ public: private: bool fexists(const char* filename); bool exists(const std::string& name); 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; 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; std::vector<std::string> my_paths_; bool verbose_; Loading src/io/hdf5/hdf5_writer.cpp +77 −32 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ bool HDF5Writer::fexists(const char* filename) { return bool(ifile); } H5::H5File& HDF5Writer::open_file(std::string file_name, bool overwrite) { void HDF5Writer::open_file(std::string file_name, bool overwrite) { if (file_) throw std::logic_error(__FUNCTION__); Loading @@ -43,41 +43,34 @@ H5::H5File& HDF5Writer::open_file(std::string file_name, bool overwrite) { file_ = std::make_unique<H5::H5File>(file_name.c_str(), H5F_ACC_EXCL); } file_id = file_->getId(); if (file_id < 0) throw std::runtime_error("Cannot open file : " + file_name); return (*file_); file_id_ = file_->getId(); } void HDF5Writer::close_file() { datasets_.clear(); groups_.clear(); file_->close(); file_.release(); } void HDF5Writer::open_group(std::string name) { my_paths.push_back(name); my_paths_.push_back(name); const std::string path = get_path(); if (!groupExists(path)) { groups_[path] = std::make_unique<H5::Group>(file_->createGroup(path.c_str())); if (!exists(path)) { file_->createGroup(path.c_str()); } } void HDF5Writer::close_group() { my_paths.pop_back(); my_paths_.pop_back(); } std::string HDF5Writer::get_path() { std::string path = "/"; for (size_t i = 0; i < my_paths.size(); i++) { path += my_paths[i]; for (size_t i = 0; i < my_paths_.size(); i++) { path += my_paths_[i]; if (i < my_paths.size() - 1) if (i < my_paths_.size() - 1) path += "/"; } Loading @@ -87,45 +80,97 @@ std::string HDF5Writer::get_path() { void HDF5Writer::execute(const std::string& name, const std::string& value) //, H5File& file, std::string path) { std::string full_name = get_path() + '/' + name; 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); write(full_name, std::vector<hsize_t>{value.size()}, HDF5_TYPE<char>::get_PredType(), value.data()); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<char>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<char>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value[0]); } delete dataset; delete dataspace; } } void HDF5Writer::execute(const std::string& name, const std::vector<std::string>& value) //, H5File& file, std::string path) { if (value.size() > 0) { H5::H5File& file = (*file_); open_group(name); execute("size", value.size()); execute("size", value.size()); //, file, new_path); open_group("data"); const auto path = get_path(); hsize_t dims[1]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; for (int i = 0; i < value.size(); ++i) { execute(get_path() + "/" + std::to_string(i), value[i]); 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<char>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<char>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &(value[l][0])); } close_group(); delete dataset; delete dataspace; close_group(); } } 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)); if (exists(name)) { H5::DataSet dataset = file_->openDataSet(name.c_str()); H5::DataSpace dataspace = dataset.getSpace(); #ifndef NDEBUG // Check for a size match. std::vector<hsize_t> size_check(dims.size()); dataspace.getSimpleExtentDims(size_check.data(), nullptr); assert(dims == size_check); #endif dataset.write(data, type, dataspace, H5P_DEFAULT); } else { H5::DataSpace dataspace(dims.size(), dims.data()); H5::DataSet dataset(file_->createDataSet(name.c_str(), type, dataspace)); dataset.write(data, type, dataspace, H5P_DEFAULT); } } // TODO: check pre-existing size datasets_[name].first->write(data, type, *datasets_[name].second, H5P_DEFAULT); bool HDF5Writer::exists(const std::string& name) { auto code = H5Gget_objinfo(file_id_, name.c_str(), 0, NULL); return code == 0; } } // namespace io Loading test/unit/io/hdf5_reader_writer_test.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -239,9 +239,8 @@ TEST(HDF5ReaderWriterTest, Overwrite) { writer.execute("a", 1); writer.execute("a", 2); writer.flush(); H5::Exception::dontPrint(); EXPECT_THROW(writer.execute("a", 3), H5::Exception); // Try to write with different size. EXPECT_DEBUG_DEATH(writer.execute("a", std::pair<int, int>(1, 1)), ""); writer.close_file(); Loading Loading
include/dca/io/hdf5/hdf5_writer.hpp +8 −17 Original line number Diff line number Diff line Loading @@ -39,7 +39,9 @@ public: public: // In: verbose. If true, the writer outputs a short log whenever it is executed. HDF5Writer(bool verbose = true) : file_id(-1), my_paths(0), verbose_(verbose) {} HDF5Writer(bool verbose = true) : verbose_(verbose) { H5::Exception::dontPrint(); } ~HDF5Writer(); Loading @@ -50,7 +52,7 @@ public: return true; } H5::H5File& open_file(std::string file_name_ref, bool overwrite = true); void open_file(std::string file_name_ref, bool overwrite = true); void close_file(); void open_group(std::string new_path); Loading @@ -58,11 +60,6 @@ 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 @@ -133,11 +130,6 @@ public: return execute(name, static_cast<io::Buffer::Container>(buffer)); } 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 @@ -153,17 +145,16 @@ public: private: bool fexists(const char* filename); bool exists(const std::string& name); 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; 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; std::vector<std::string> my_paths_; bool verbose_; Loading
src/io/hdf5/hdf5_writer.cpp +77 −32 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ bool HDF5Writer::fexists(const char* filename) { return bool(ifile); } H5::H5File& HDF5Writer::open_file(std::string file_name, bool overwrite) { void HDF5Writer::open_file(std::string file_name, bool overwrite) { if (file_) throw std::logic_error(__FUNCTION__); Loading @@ -43,41 +43,34 @@ H5::H5File& HDF5Writer::open_file(std::string file_name, bool overwrite) { file_ = std::make_unique<H5::H5File>(file_name.c_str(), H5F_ACC_EXCL); } file_id = file_->getId(); if (file_id < 0) throw std::runtime_error("Cannot open file : " + file_name); return (*file_); file_id_ = file_->getId(); } void HDF5Writer::close_file() { datasets_.clear(); groups_.clear(); file_->close(); file_.release(); } void HDF5Writer::open_group(std::string name) { my_paths.push_back(name); my_paths_.push_back(name); const std::string path = get_path(); if (!groupExists(path)) { groups_[path] = std::make_unique<H5::Group>(file_->createGroup(path.c_str())); if (!exists(path)) { file_->createGroup(path.c_str()); } } void HDF5Writer::close_group() { my_paths.pop_back(); my_paths_.pop_back(); } std::string HDF5Writer::get_path() { std::string path = "/"; for (size_t i = 0; i < my_paths.size(); i++) { path += my_paths[i]; for (size_t i = 0; i < my_paths_.size(); i++) { path += my_paths_[i]; if (i < my_paths.size() - 1) if (i < my_paths_.size() - 1) path += "/"; } Loading @@ -87,45 +80,97 @@ std::string HDF5Writer::get_path() { void HDF5Writer::execute(const std::string& name, const std::string& value) //, H5File& file, std::string path) { std::string full_name = get_path() + '/' + name; 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); write(full_name, std::vector<hsize_t>{value.size()}, HDF5_TYPE<char>::get_PredType(), value.data()); std::string full_name = path + "/" + name; dataset = new H5::DataSet( file.createDataSet(full_name.c_str(), HDF5_TYPE<char>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<char>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &value[0]); } delete dataset; delete dataspace; } } void HDF5Writer::execute(const std::string& name, const std::vector<std::string>& value) //, H5File& file, std::string path) { if (value.size() > 0) { H5::H5File& file = (*file_); open_group(name); execute("size", value.size()); execute("size", value.size()); //, file, new_path); open_group("data"); const auto path = get_path(); hsize_t dims[1]; H5::DataSet* dataset = NULL; H5::DataSpace* dataspace = NULL; for (int i = 0; i < value.size(); ++i) { execute(get_path() + "/" + std::to_string(i), value[i]); 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<char>::get_PredType(), *dataspace)); H5Dwrite(dataset->getId(), HDF5_TYPE<char>::get(), dataspace->getId(), H5S_ALL, H5P_DEFAULT, &(value[l][0])); } close_group(); delete dataset; delete dataspace; close_group(); } } 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)); if (exists(name)) { H5::DataSet dataset = file_->openDataSet(name.c_str()); H5::DataSpace dataspace = dataset.getSpace(); #ifndef NDEBUG // Check for a size match. std::vector<hsize_t> size_check(dims.size()); dataspace.getSimpleExtentDims(size_check.data(), nullptr); assert(dims == size_check); #endif dataset.write(data, type, dataspace, H5P_DEFAULT); } else { H5::DataSpace dataspace(dims.size(), dims.data()); H5::DataSet dataset(file_->createDataSet(name.c_str(), type, dataspace)); dataset.write(data, type, dataspace, H5P_DEFAULT); } } // TODO: check pre-existing size datasets_[name].first->write(data, type, *datasets_[name].second, H5P_DEFAULT); bool HDF5Writer::exists(const std::string& name) { auto code = H5Gget_objinfo(file_id_, name.c_str(), 0, NULL); return code == 0; } } // namespace io Loading
test/unit/io/hdf5_reader_writer_test.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -239,9 +239,8 @@ TEST(HDF5ReaderWriterTest, Overwrite) { writer.execute("a", 1); writer.execute("a", 2); writer.flush(); H5::Exception::dontPrint(); EXPECT_THROW(writer.execute("a", 3), H5::Exception); // Try to write with different size. EXPECT_DEBUG_DEATH(writer.execute("a", std::pair<int, int>(1, 1)), ""); writer.close_file(); Loading