Advertisement
EWTD

OpenMP Lab3

Dec 2nd, 2022 (edited)
965
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.71 KB | None | 0 0
  1. #include <vector>
  2. #include <iostream>
  3. #include <omp.h>
  4. #include <algorithm>
  5. #include <chrono>
  6.  
  7. #define eps 0.00001
  8.  
  9. long double __denumerator_squared_st_diviation = 0;
  10.  
  11. typedef std::vector<std::vector<double>> Matrix;
  12. typedef std::vector<double> Vector;
  13.  
  14. Vector vector_subtraction(const Vector& lhs, const Vector& rhs){
  15.     if (lhs.size() != rhs.size()) throw std::invalid_argument("can't subtract vector and vector");
  16.     Vector result(lhs.size());
  17. #pragma omp parallel for default(none) shared(lhs, rhs, result)
  18.     for (uint64_t idx = 0; idx < lhs.size(); idx++)
  19.         result[idx] = lhs[idx] - rhs[idx];
  20.     return result;
  21. }
  22. Vector matrix_multiply(const Matrix& lhs, const Vector& rhs){
  23.     if (lhs[0].size() != rhs.size()) throw std::invalid_argument("can't multiply matrix and vector");
  24.     Vector result(lhs.size(), 0);
  25. #pragma omp parallel for default(none) shared(lhs, rhs, result)
  26.     for (std::uint64_t i = 0; i < result.size(); i++)
  27.         for (std::uint64_t j = 0; j < lhs[i].size(); j++)
  28.             result[i] += lhs[i][j] * rhs[j];
  29.  
  30.     return result;
  31. }
  32.  
  33. void initialize_SLE(Matrix& mt, Vector& rhs, Vector& solution){
  34.     const auto N = mt.size();
  35.     for(std::uint64_t i = 0; i < mt.size(); i++)
  36.         for(std::uint64_t j = 0; j < mt[i].size(); j++)
  37.             mt[i][j] = (i == j) ? 2 : 1;
  38.     for(auto& elem: rhs)
  39.         elem = N + 1;
  40.     __denumerator_squared_st_diviation = rhs.size()*(N+1)*(N+1);
  41. }
  42.  
  43. long double count_metric(Matrix& mt, Vector& rhs, Vector& solution){
  44.     long double numerator_squared_st_diviation = 0;
  45.     const auto numerator = vector_subtraction(matrix_multiply(mt, solution), rhs);
  46. #pragma omp parallel for reduction(+:numerator_squared_st_diviation) shared(numerator) default(none)
  47.     for(std::uint64_t i = 0; i < numerator.size(); i++)
  48.         numerator_squared_st_diviation += numerator[i] * numerator[i];
  49.     return numerator_squared_st_diviation/__denumerator_squared_st_diviation;
  50. }
  51.  
  52. void evaluate_iteration(Matrix& mt, Vector& rhs, Vector& solution){
  53.     const double lambda = (1.f/(10.f * static_cast<float>(mt.size())));
  54.     auto vec = vector_subtraction(matrix_multiply(mt, solution), rhs);
  55. #pragma omp parallel for default(none) shared(lambda, vec)
  56.     for(std::uint64_t i = 0; i < vec.size(); i++)
  57.         vec[i] *= lambda;
  58. #pragma omp parallel for default(none) shared(lambda, vec, solution)
  59.     for(std::uint64_t i = 0; i < solution.size(); i++)
  60.         solution[i] -= vec[i];
  61. }
  62.  
  63. int main(int argc, char** argv){
  64.     std::uint64_t N = 0;
  65.     std::int32_t threads = 0;
  66.     if(argc == 3){
  67.         N = std::stoul(argv[1]);
  68.         threads = std::stoi(argv[2]);
  69.     }else{
  70.         std::cerr << "Invalid number of arguments: [matrix size] [thread number]";
  71.         exit(1);
  72.     }
  73.     omp_set_num_threads(threads);
  74.     Matrix SLE_coef(N, Vector(N, 0));
  75.     Vector SLE_rhs(N, 0), SLE_sol(N, 0);
  76.     initialize_SLE(SLE_coef, SLE_rhs, SLE_sol);
  77.     long double metric = count_metric(SLE_coef, SLE_rhs, SLE_sol);
  78.     //std::cout << "Iteration #0. metric: " << metric << ", duration: 0s\n";
  79.     uint32_t idx = 1;
  80.     const auto start = std::chrono::system_clock::now();
  81.     while(metric >= eps){
  82.         evaluate_iteration(SLE_coef, SLE_rhs, SLE_sol);
  83.         metric = count_metric(SLE_coef, SLE_rhs, SLE_sol);
  84.         //std::cout << "Iteration #" << (idx++) << ". metric: " << metric << "ms\n";
  85.     }
  86.     const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start);
  87.     std::cout << "Elapsed Time: " << duration.count() << "ms. Solution: {\n";
  88.     std::for_each(SLE_sol.begin(), SLE_sol.end(), [](const double value) { std::cout << value << ", "; });
  89.     std::cout << "\n}\n";
  90.     return 0;
  91. }
Tags: C++ OpenMp
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement