|
- /**
- * \file utils.hpp
- * \brief Utilities header
- *
- * \author
- * Christos Choutouridis AEM:8997
- * <cchoutou@ece.auth.gr>
- */
- #ifndef UTILS_HPP_
- #define UTILS_HPP_
-
- #include <iostream>
- #include <chrono>
- #include <unistd.h>
- #include <hdf5.h>
-
- #include <matrix.hpp>
- #include <config.h>
-
- /*!
- * A Logger for entire program.
- */
- struct Log {
- struct Endl {} endl; //!< a tag object to to use it as a new line request.
-
- //! We provide logging via << operator
- template<typename T>
- Log& operator<< (T&& t) {
- if (session.verbose) {
- if (line_) {
- std::cout << "[Log]: " << t;
- line_ = false;
- }
- else
- std::cout << t;
- }
- return *this;
- }
- // overload for special end line handling
- Log& operator<< (Endl e) { (void)e;
- if (session.verbose) {
- std::cout << '\n';
- line_ = true;
- }
- return *this;
- }
- private:
- bool line_ {true};
- };
-
- extern Log logger;
-
- /*!
- * A small timing utility based on chrono.
- */
- struct Timing{
- using Tpoint = std::chrono::steady_clock::time_point;
- using microseconds = std::chrono::microseconds;
- using milliseconds = std::chrono::milliseconds;
- using seconds = std::chrono::seconds;
-
- //! tool to mark the starting point
- Tpoint start () noexcept { return start_ = std::chrono::steady_clock::now(); }
- //! tool to mark the ending point
- Tpoint stop () noexcept { return stop_ = std::chrono::steady_clock::now(); }
-
- auto dt () noexcept {
- return std::chrono::duration_cast<std::chrono::microseconds>(stop_ - start_).count();
- }
- //! tool to print the time interval
- void print_dt (const char* what) noexcept {
- if (session.timing) {
- auto t = stop_ - start_;
- if (std::chrono::duration_cast<microseconds>(t).count() < 10000)
- std::cout << "[Timing]: " << what << ": " << std::to_string(std::chrono::duration_cast<microseconds>(t).count()) << " [usec]\n";
- else if (std::chrono::duration_cast<milliseconds>(t).count() < 10000)
- std::cout << "[Timing]: " << what << ": " << std::to_string(std::chrono::duration_cast<milliseconds>(t).count()) << " [msec]\n";
- else
- std::cout << "[Timing]: " << what << ": " << std::to_string(std::chrono::duration_cast<seconds>(t).count()) << " [sec]\n";
- }
- }
- private:
- Tpoint start_;
- Tpoint stop_;
- };
-
-
-
- struct Mtx {
-
- template<typename MatrixType, HDF5_type Type>
- static void load(const std::string& filename, const std::string& dataset, MatrixType& matrix) {
-
- hid_t file_id{}, dataset_id{}, dataspace_id{};
- herr_t read_st;
- do {
- // Open file
- logger << "Load HDF5 file: " << filename << " Dataset: " << dataset << "...";
- if ((file_id = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
- break;
-
- // Open dataset
- if ((dataset_id = H5Dopen2(file_id, dataset.c_str(), H5P_DEFAULT)) < 0)
- break;
-
- // Get dataspace and allocate memory for read buffer
- if ((dataspace_id = H5Dget_space(dataset_id)) < 0)
- break;
- hsize_t dims[2];
- H5Sget_simple_extent_dims(dataspace_id, dims, NULL);
- matrix.resize(dims[0], dims[1]);
-
- // Read the dataset
- // ToDo: Come up with a better way to do this
- if constexpr (Type == HDF5_type::DOUBLE) {
- if ((read_st = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) < 0)
- break;
- }
- else if (Type == HDF5_type::FLOAT) {
- if ((read_st = H5Dread(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) < 0)
- break;
- }
- else if (Type == HDF5_type::UINT) {
- if ((read_st = H5Dread(dataset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) < 0)
- break;
- }
- else if (Type == HDF5_type::INT) {
- if ((read_st = H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) < 0)
- break;
- }
- // Done
- H5Dclose(dataset_id);
- H5Sclose(dataspace_id);
- H5Fclose(file_id);
- logger << " Done" << logger.endl;
- return;
- } while (0);
-
- // Error: close everything (if possible) and return false
- H5Dclose(dataset_id);
- H5Sclose(dataspace_id);
- H5Fclose(file_id);
- throw std::runtime_error("Cannot store to " + filename + " dataset:" + dataset + '\n');
- }
-
-
- template<typename MatrixType, HDF5_type Type>
- static void store(const std::string& filename, const std::string& dataset, MatrixType& matrix) {
-
- hid_t file_id{}, dataset_id{}, dataspace_id{};
- herr_t write_st;
- do {
- // Try to open the file in read-write mode
- logger << "Store HDF5 file: " << filename << " Dataset: " << dataset << "...";
- if (access(session.outMtxFile.c_str(), F_OK) == 0){
- if ((file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
- break;
- }
- else {
- if ((file_id = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
- break;
- }
-
- // Create the dataspace for the dataset
- hsize_t dims[] = { matrix.rows(), matrix.columns() };
- if ((dataspace_id = H5Screate_simple(2, dims, NULL)) < 0)
- break;
-
- // ToDo: Come up with a better way to do this
- if constexpr (Type == HDF5_type::DOUBLE) {
- // Create the dataset with default properties
- if ((dataset_id = H5Dcreate2(
- file_id, dataset.c_str(), H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
- break;
- // Write the data to the dataset
- if ((write_st = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) <0 )
- break;
- }
- else if (Type == HDF5_type::FLOAT) {
- // Create the dataset with default properties
- if ((dataset_id = H5Dcreate2(
- file_id, dataset.c_str(), H5T_NATIVE_FLOAT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
- break;
- // Write the data to the dataset
- if ((write_st = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) <0 )
- break;
- }
- else if (Type == HDF5_type::UINT) {
- // Create the dataset with default properties
- if ((dataset_id = H5Dcreate2(
- file_id, dataset.c_str(), H5T_NATIVE_UINT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
- break;
- // Write the data to the dataset
- if ((write_st = H5Dwrite(dataset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) <0 )
- break;
- }
- else if (Type == HDF5_type::INT) {
- // Create the dataset with default properties
- if ((dataset_id = H5Dcreate2(
- file_id, dataset.c_str(), H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
- break;
- // Write the data to the dataset
- if ((write_st = H5Dwrite(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) <0 )
- break;
- }
- // Close the dataset, dataspace, and file
- H5Dclose(dataset_id);
- H5Sclose(dataspace_id);
- H5Fclose(file_id);
- logger << " Done" << logger.endl;
- return;
- } while (0);
-
- // Error: close everything (if possible) and return false
- H5Dclose(dataset_id);
- H5Sclose(dataspace_id);
- H5Fclose(file_id);
- throw std::runtime_error("Cannot store " + filename + " with dataset:" + dataset +'\n');
- }
- };
-
-
-
- #endif /* UTILS_HPP_ */
|