AUTH's THMMY "Parallel and distributed systems" course assignments.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

225 lignes
7.8 KiB

  1. /**
  2. * \file utils.hpp
  3. * \brief Utilities header
  4. *
  5. * \author
  6. * Christos Choutouridis AEM:8997
  7. * <cchoutou@ece.auth.gr>
  8. */
  9. #ifndef UTILS_HPP_
  10. #define UTILS_HPP_
  11. #include <iostream>
  12. #include <chrono>
  13. #include <unistd.h>
  14. #include <hdf5.h>
  15. #include "matrix.hpp"
  16. #include "config.h"
  17. /*!
  18. * A Logger for entire program.
  19. */
  20. struct Log {
  21. struct Endl {} endl; //!< a tag object to to use it as a new line request.
  22. //! We provide logging via << operator
  23. template<typename T>
  24. Log& operator<< (T&& t) {
  25. if (session.verbose) {
  26. if (line_) {
  27. std::cout << "[Log]: " << t;
  28. line_ = false;
  29. }
  30. else
  31. std::cout << t;
  32. }
  33. return *this;
  34. }
  35. // overload for special end line handling
  36. Log& operator<< (Endl e) { (void)e;
  37. if (session.verbose) {
  38. std::cout << '\n';
  39. line_ = true;
  40. }
  41. return *this;
  42. }
  43. private:
  44. bool line_ {true};
  45. };
  46. extern Log logger;
  47. /*!
  48. * A small timing utility based on chrono.
  49. */
  50. struct Timing{
  51. using Tpoint = std::chrono::steady_clock::time_point;
  52. using microseconds = std::chrono::microseconds;
  53. using milliseconds = std::chrono::milliseconds;
  54. using seconds = std::chrono::seconds;
  55. //! tool to mark the starting point
  56. Tpoint start () noexcept { return start_ = std::chrono::steady_clock::now(); }
  57. //! tool to mark the ending point
  58. Tpoint stop () noexcept { return stop_ = std::chrono::steady_clock::now(); }
  59. auto dt () noexcept {
  60. return std::chrono::duration_cast<std::chrono::microseconds>(stop_ - start_).count();
  61. }
  62. //! tool to print the time interval
  63. void print_dt (const char* what) noexcept {
  64. if (session.timing) {
  65. auto t = stop_ - start_;
  66. if (std::chrono::duration_cast<microseconds>(t).count() < 10000)
  67. std::cout << "[Timing]: " << what << ": " << std::to_string(std::chrono::duration_cast<microseconds>(t).count()) << " [usec]\n";
  68. else if (std::chrono::duration_cast<milliseconds>(t).count() < 10000)
  69. std::cout << "[Timing]: " << what << ": " << std::to_string(std::chrono::duration_cast<milliseconds>(t).count()) << " [msec]\n";
  70. else
  71. std::cout << "[Timing]: " << what << ": " << std::to_string(std::chrono::duration_cast<seconds>(t).count()) << " [sec]\n";
  72. }
  73. }
  74. private:
  75. Tpoint start_;
  76. Tpoint stop_;
  77. };
  78. struct Mtx {
  79. template<typename MatrixType, HDF5_type Type>
  80. static void load(const std::string& filename, const std::string& dataset, MatrixType& matrix) {
  81. hid_t file_id{}, dataset_id{}, dataspace_id{};
  82. herr_t read_st;
  83. do {
  84. // Open file
  85. logger << "Load HDF5 file: " << filename << " Dataset: " << dataset << "...";
  86. if ((file_id = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
  87. break;
  88. // Open dataset
  89. if ((dataset_id = H5Dopen2(file_id, dataset.c_str(), H5P_DEFAULT)) < 0)
  90. break;
  91. // Get dataspace and allocate memory for read buffer
  92. if ((dataspace_id = H5Dget_space(dataset_id)) < 0)
  93. break;
  94. hsize_t dims[2];
  95. H5Sget_simple_extent_dims(dataspace_id, dims, NULL);
  96. matrix.resize(dims[0], dims[1]);
  97. // Read the dataset
  98. // ToDo: Come up with a better way to do this
  99. if constexpr (Type == HDF5_type::DOUBLE) {
  100. if ((read_st = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) < 0)
  101. break;
  102. }
  103. else if (Type == HDF5_type::FLOAT) {
  104. if ((read_st = H5Dread(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) < 0)
  105. break;
  106. }
  107. else if (Type == HDF5_type::UINT) {
  108. if ((read_st = H5Dread(dataset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) < 0)
  109. break;
  110. }
  111. else if (Type == HDF5_type::INT) {
  112. if ((read_st = H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) < 0)
  113. break;
  114. }
  115. // Done
  116. H5Dclose(dataset_id);
  117. H5Sclose(dataspace_id);
  118. H5Fclose(file_id);
  119. logger << " Done" << logger.endl;
  120. return;
  121. } while (0);
  122. // Error: close everything (if possible) and return false
  123. H5Dclose(dataset_id);
  124. H5Sclose(dataspace_id);
  125. H5Fclose(file_id);
  126. throw std::runtime_error("Cannot store to " + filename + " dataset:" + dataset + '\n');
  127. }
  128. template<typename MatrixType, HDF5_type Type>
  129. static void store(const std::string& filename, const std::string& dataset, MatrixType& matrix) {
  130. hid_t file_id{}, dataset_id{}, dataspace_id{};
  131. herr_t write_st;
  132. do {
  133. // Try to open the file in read-write mode
  134. logger << "Store HDF5 file: " << filename << " Dataset: " << dataset << "...";
  135. if (access(session.outMtxFile.c_str(), F_OK) == 0){
  136. if ((file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
  137. break;
  138. }
  139. else {
  140. if ((file_id = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
  141. break;
  142. }
  143. // Create the dataspace for the dataset
  144. hsize_t dims[] = { matrix.rows(), matrix.columns() };
  145. if ((dataspace_id = H5Screate_simple(2, dims, NULL)) < 0)
  146. break;
  147. // ToDo: Come up with a better way to do this
  148. if constexpr (Type == HDF5_type::DOUBLE) {
  149. // Create the dataset with default properties
  150. if ((dataset_id = H5Dcreate2(
  151. file_id, dataset.c_str(), H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
  152. break;
  153. // Write the data to the dataset
  154. if ((write_st = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) <0 )
  155. break;
  156. }
  157. else if (Type == HDF5_type::FLOAT) {
  158. // Create the dataset with default properties
  159. if ((dataset_id = H5Dcreate2(
  160. file_id, dataset.c_str(), H5T_NATIVE_FLOAT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
  161. break;
  162. // Write the data to the dataset
  163. if ((write_st = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) <0 )
  164. break;
  165. }
  166. else if (Type == HDF5_type::UINT) {
  167. // Create the dataset with default properties
  168. if ((dataset_id = H5Dcreate2(
  169. file_id, dataset.c_str(), H5T_NATIVE_UINT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
  170. break;
  171. // Write the data to the dataset
  172. if ((write_st = H5Dwrite(dataset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) <0 )
  173. break;
  174. }
  175. else if (Type == HDF5_type::INT) {
  176. // Create the dataset with default properties
  177. if ((dataset_id = H5Dcreate2(
  178. file_id, dataset.c_str(), H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
  179. break;
  180. // Write the data to the dataset
  181. if ((write_st = H5Dwrite(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix.data())) <0 )
  182. break;
  183. }
  184. // Close the dataset, dataspace, and file
  185. H5Dclose(dataset_id);
  186. H5Sclose(dataspace_id);
  187. H5Fclose(file_id);
  188. logger << " Done" << logger.endl;
  189. return;
  190. } while (0);
  191. // Error: close everything (if possible) and return false
  192. H5Dclose(dataset_id);
  193. H5Sclose(dataspace_id);
  194. H5Fclose(file_id);
  195. throw std::runtime_error("Cannot store " + filename + " with dataset:" + dataset +'\n');
  196. }
  197. };
  198. #endif /* UTILS_HPP_ */