|
- /**
- * \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 <mpi.h>
-
- //#include "matrix.hpp"
- #include "config.h"
-
-
- template<typename TID = int>
- struct MPI_t {
- using ID_t = TID; // Export TID type (currently int defined by the standard)
-
- void init(int *argc, char ***argv) {
- // Initialize the MPI environment
- MPI_Init(argc, argv);
-
- // Get the number of processes
- int size_value, rank_value;
- size_ = static_cast<ID_t>(MPI_Comm_size(MPI_COMM_WORLD, &size_value));
- rank_ = static_cast<ID_t>(MPI_Comm_rank(MPI_COMM_WORLD, &rank_value));
-
- // Get the name of the processor
- char processor_name[MPI_MAX_PROCESSOR_NAME];
- int name_len;
- MPI_Get_processor_name(processor_name, &name_len);
- name_ = std::string (processor_name, name_len);
- }
-
- void finalize() {
- // Finalize the MPI environment.
- MPI_Finalize();
- }
-
- bool exchange(ID_t partner, const void *send_data, void *recv_data, int data_count, MPI_Datatype datatype) {
- bool ret = true;
- MPI_Status status;
- MPI_Sendrecv(
- send_data, data_count, datatype, partner, 0,
- recv_data, data_count, datatype, partner, 0,
- MPI_COMM_WORLD, &status
- );
- if (status.MPI_ERROR != MPI_SUCCESS)
- ret = false;
-
- return ret;
- }
-
- // Accessors
- [[nodiscard]] ID_t rank() const noexcept { return rank_; }
- [[nodiscard]] ID_t size() const noexcept { return size_; }
- [[nodiscard]] const std::string& name() const noexcept { return name_; }
-
- private:
- ID_t rank_{};
- ID_t size_{};
- std::string name_{};
- };
-
- extern MPI_t<> mpi;
- using mpi_id_t = MPI_t<>::ID_t;
-
- /*!
- * 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_;
- };
-
- #endif /* UTILS_HPP_ */
|