/
NenNil
/
vmk2025-parallel-computing
Обзор
Документация
Войти
/
NenNil
/
vmk2025-parallel-computing
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
seq/main.cpp
212 строк
8 KB
Нил Ненахов
added seq and omp program
31 окт 2025, 20:17
31 окт 2025, 20:17
7c054ab
Код
Авторство
О чём код?
#include "generate.h" #include "solve.h" #include "matrix.h" #include "time.h" #include "scheme.h" #include <cstddef> #include <iostream> #include <mpi.h> #include <ostream> #include <vector> #include <string> #include <chrono> #include <cmath> #include <stdexcept> #include <fstream> using namespace std; double fun(double x, double y) { // if (y>-0.4) return -1; // return 1; return pow(x, 2)+4*pow(y, 2)-1; } double funx(double y, bool pos) { // return 0; if (pos) return sqrt(1-4*pow(y,2)); else return -sqrt(1-4*pow(y,2)); } double funy(double x, bool pos) { // return -0.4; if (pos) return sqrt((1-pow(x,2))/4); else return -sqrt((1-pow(x,2))/4); } double vectorNormL2(const std::vector<double>& vec) { if (vec.empty()) { throw std::invalid_argument("Vector is empty"); } double sumOfSquares = 0.0; for (double val : vec) { sumOfSquares += val * val; } return std::sqrt(sumOfSquares); } int main(int argc, char* argv[]) { // Проверка минимального количества аргументов if (argc < 3) { std::cout << "Usage: program x1 x2 [-n numThreads] [--variant numVarient]\n"; return 0; } // Обязательные параметры int x1 = std::atoi(argv[1]); int x2 = std::atoi(argv[2]); // Параметры по умолчанию int variant = 2; int p_size = 1, r_size = 1; // Парсинг дополнительных аргументов for (int i = 5; i < argc; ++i) { std::string arg = argv[i]; if ((arg == "--variant" || arg == "-v") && i + 1 < argc) { variant = std::atoi(argv[++i]); } else if (arg == "--help" || "-h") { std::cout << "./main x1 x2 [-n numThreads] [--variant|-v numVariant] [--openMP] [--MPI] [--openCL] [--help | -h]" << std::endl; std::cout << "--p_size количество процессов по горизонтали для openMP" << std::endl; std::cout << "--r_size количество процессов по вертикали для openMP" << std::endl; std::cout << "Внимание, количество запускаемых процессов (с помощью mpicc -np x) должно быть равно r_size*p_size" << std::endl; std::cout << "Внимание, флаг -np нужно прописывать дважды в mpicc -np и после названия исполняемого файла, если они не совпадают может случиться что-то плохое" << std::endl; std::cout << "-v or --variant устанавливает вариант построение матрицы смежности (пока реализованы 2 и 3 варианты)" << std::endl; std::cout << "--openMP позволяет использовать openMP везде где возможно" << std::endl; std::cout << "--MPI позволяет использовать MPI везде, где возможно, там где есть реализация MPI и openMP будет использовано MPI (пока реализовано только перемножение матриц)" << std::endl; // std::cout << "--openCL позволяет использовать openCL везде, где возможно, сильнее MPI и openMP (не реализовано)" << std::endl; std::cout << "--transposeTest прогоняет через тесты методы транспонирования матрицы" << std::endl; std::cout << "--adjacencyMatrixTest тестирует построение матриц смежности" << std::endl; std::cout << "--mutrixMultiplicationTest тестирует функциии перемножения матриц" << std::endl; std::cout << "--SpMVtest сравнивает выводы разных реализаций SpMV функций" << std::endl; std::cout << "--onlyTests останавливает исполнение после запуска тестов" << std::endl; return 0; } else { std::cerr << "Unknown argument: " << arg << "\n"; return 1; // Возвращаем ошибку при неизвестном аргументе } } std::chrono::time_point<std::chrono::high_resolution_clock> start, end; double duration; // Вывод результатов для проверки std::cout << "x1: " << x1 << ", x2: " << x2 << "\n"; double h1 = 2.0/x1; double h2 = 2.0/x2; cout << "h1: " << h1 << ", h2: " << h2 << endl; Coefa coef_a = Coefa(h1, h2, &fun, &funx, &funy, 0.00001); Coefb coef_b = Coefb(h1, h2, &fun, &funx, &funy, 0.00001); Matrix_coef matr_c = Matrix_coef(h1, h2, coef_a, coef_b); start = std::chrono::high_resolution_clock::now(); // Генерация матрицы auto A = fast_generate(x1, x2, matr_c); end = std::chrono::high_resolution_clock::now(); duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count(); duration = duration/1000000; std::cout << "Matrix_coef execution time: " << duration << " seconds\n"; if ((x1<10)&&(x2<10)) print_csr_matrix(A); BorderF bf(h1, h2, &fun, &funx, &funy); int vec_size = x1*x2; std::vector<double> f(vec_size); start = std::chrono::high_resolution_clock::now(); for (int x=0; x<x1; x++) for (int y=0; y<x2; y++) { f[y*x1+x] = bf.getcoef(x,y); // std::cout << "x: " << bf.countx(x) << ", y: " << bf.county(y) << " coef: " << f[x+y*y] << std::endl; // cout << "x: " << x << ", y: " << y << ", coef: " << f[x*x1+y] << ", count: " << x*x1+y << endl; } end = std::chrono::high_resolution_clock::now(); duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count(); duration = duration/1000000; std::cout << "vector B execution time: " << duration << " seconds\n"; /* for (int i=0; i<f.size()-1; i++) { cout << f[i] << ", "; } cout << f[f.size()-1] << ";" << endl; */ // Копирование диагонали из matrix в M auto M = new CSRMatrix(); copy_diag(M, A); std::vector<double> buf(vec_size); std::vector<double> z(vec_size); std::vector<double> x(vec_size); std::vector<double> p(vec_size); std::vector<double> q(vec_size); std::vector<double> r(vec_size); // Инициализация вектора x нулями //vfill(myOutput->x, x, 0.0); // Вектор r (остаток) инициализируется как b r = f; // Решение системы int iterations = 0; start = std::chrono::high_resolution_clock::now(); solve(A, f, 0.000001, 10000, x, &iterations, z, p, q, M); // Передаем вектор b end = std::chrono::high_resolution_clock::now(); duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count(); duration = duration/1000000; std::cout << "solve execution time: " << duration << " seconds\n"; // Вывод результата // std::cout << "res[0]=" << x[0] << '\n'; std::cout << "iterations=" << iterations << '\n'; // std::cout << "norm=" << vectorNormL2(x) << endl; // cout << "res: " << endl; /* for (int i=0; i<x.size()-1; i++) { cout << x[i] << ", "; } cout << x[x.size()-1] << ";" << endl; */ delete M; delete A; std::ofstream file("output.txt", std::ios::binary); size_t size = x.size(); // Перебираем элементы вектора и выводим их в файл for (const auto &item : x) { file << item << "\n"; // Каждое число в отдельной строке } file.close(); // Закрытие файла return 0; }