/*! * \file utils.h * \brief Utilities to handle matrix files, chrono, etc... * * \author * Christos Choutouridis AEM:8997 * */ #ifndef UTILS_H_ #define UTILS_H_ #include #include #include #include #include #include #include template struct buffer_t { buffer_t(size_t s) { p = new T[s]; } ~buffer_t() { delete[] p; } buffer_t() = default; buffer_t(buffer_t&&) = default; buffer_t& operator=(buffer_t&&) = default; buffer_t(const buffer_t&) = delete; buffer_t& operator=(const buffer_t&) = delete; T* allocate(size_t s) { return p = new T[s]; } T* operator() () { return p; } T& operator[] (size_t i){ return p[i]; } private: T* p{nullptr}; }; struct Mtx { template static void coo2csc(I *row, I *col, I const* row_coo, I const* col_coo, I nnz, I n, I isOneBased) { // ----- cannot assume that input is already 0! for (I l = 0; l < n+1; l++) col[l] = 0; // ----- find the correct column sizes for (I l = 0; l < nnz; l++) col[col_coo[l] - isOneBased]++; // ----- cumulative sum for (I i = 0, cumsum = 0; i < n; i++) { I temp = col[i]; col[i] = cumsum; cumsum += temp; } col[n] = nnz; // ----- copy the row indices to the correct place for (I l = 0; l < nnz; l++) { I col_l; col_l = col_coo[l] - isOneBased; I dst = col[col_l]; row[dst] = row_coo[l] - isOneBased; col[col_l]++; } // ----- revert the column pointers for (I i = 0, last = 0; i < n; i++) { I temp = col[i]; col[i] = last; last = temp; } } template static bool is_triangular (std::ifstream& file) { std::string line, token; enum state_en {HEADER, SIZE, DATA} state = HEADER; enum LU_t {Z, LOWER, UPPER} LU = Z; while (std::getline (file, line, '\n')) { std::stringstream ss(line); switch (state) { case HEADER: ss >> token; if (token != "%%MatrixMarket") return false; else state = SIZE; break; case SIZE: if (line[0] == '%') continue; else state = DATA; break; case DATA: if (line[0] == '%') continue; I i, j; ss >> i >> j; switch (LU) { case Z: LU = (i static bool load (SpMat& M, std::ifstream& file) { std::string line, token; enum state_en {HEADER, SIZE, DATA} state = HEADER; enum LU_t {Z, LOWER, UPPER} LU = Z; IndexT n1, n2, nnz; buffer_t col{}, row{}, coo_col{}, coo_row{}; IndexT cnt{}; while (std::getline (file, line, '\n')) { std::stringstream ss(line); switch (state) { case HEADER: ss >> token; if (token != "%%MatrixMarket") return false; else state = SIZE; break; case SIZE: if (line[0] == '%') continue; else { ss >> n1 >> n2 >> nnz; if (session.makeSymmetric) nnz *= 2; col.allocate(nnz); row.allocate(nnz); coo_col.allocate(nnz); coo_row.allocate(nnz); state = DATA; } break; case DATA: if (line[0] == '%') continue; IndexT i, j; ss >> i >> j; if (session.makeSymmetric) { if (LU == Z) { LU = (i(n1, cnt, &row[0], &col[0]); return true; } }; 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; Tpoint start () noexcept { return start_ = std::chrono::steady_clock::now(); } Tpoint stop () noexcept { return stop_ = std::chrono::steady_clock::now(); } auto dt () noexcept { return std::chrono::duration_cast(stop_ - start_).count(); } void print_dt () noexcept { auto t = stop_ - start_; if (std::chrono::duration_cast(t).count() < 10000) std::cout << "time: " << std::to_string(std::chrono::duration_cast(t).count()) << " [usec]\n"; else if (std::chrono::duration_cast(t).count() < 10000) std::cout << "time: " << std::to_string(std::chrono::duration_cast(t).count()) << " [msec]\n"; else std::cout << "time: " << std::to_string(std::chrono::duration_cast(t).count()) << " [sec]\n"; } private: Tpoint start_; Tpoint stop_; }; void init_ER_graph (matrix& A, double p); void print_ER_graph (matrix& A); #endif /* UTILS_H_ */