From 237ae8988546e413f330d5db3ea4bb328943b8d7 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sun, 14 Sep 2025 01:49:30 +0300 Subject: [PATCH 01/15] add: matrix class and method for load matrix form file --- .../ParallelMatrixMultiplication.sln | 25 +++++++ .../ParallelMatrixMultiplication/Matrix.cs | 71 +++++++++++++++++++ .../ParallelMatrixMultiplication.csproj | 17 +++++ .../ParallelMatrixMultiplication/Program.cs | 1 + 4 files changed, 114 insertions(+) create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.sln create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/ParallelMatrixMultiplication.csproj create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.sln b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.sln new file mode 100644 index 0000000..90584c4 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.13.35806.99 d17.13 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParallelMatrixMultiplication", "ParallelMatrixMultiplication\ParallelMatrixMultiplication.csproj", "{96DCD91F-9CF3-4519-8929-C0C38523DBB7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {96DCD91F-9CF3-4519-8929-C0C38523DBB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96DCD91F-9CF3-4519-8929-C0C38523DBB7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96DCD91F-9CF3-4519-8929-C0C38523DBB7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96DCD91F-9CF3-4519-8929-C0C38523DBB7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {902A2F58-AB9C-49FA-AD02-157B0D718B30} + EndGlobalSection +EndGlobal diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs new file mode 100644 index 0000000..266d180 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ParallelMatrixMultiplication +{ + class Matrix + { + public int Rows { get; private set; } + public int Columns { get; private set; } + private readonly int[,] numbers; + + public Matrix(int rows, int columns) + { + this.numbers = new int[rows, columns]; + } + + public int this[int rows, int columns] + { + get => numbers[rows, columns]; + set => numbers[rows, columns] = value; + } + + public static Matrix LoadFromFile(string filePath) + { + if (!File.Exists(filePath)) + { + throw new FileNotFoundException("Файл не найден"); + } + + List lines = new List(); + using (StreamReader reader = new StreamReader(filePath)) + { + string line = string.Empty; + while ((line = reader.ReadLine()) != null) + { + lines.Add(line); + } + } + + if (lines.Count == 0) + { + throw new InvalidDataException("Файл пуст"); + } + + int rows = lines.Count; + string[] firstRowValues = lines[0].Split(' '); + int columnsSize = firstRowValues.Length; + + Matrix matrix = new Matrix(rows, columnsSize); + + for (int i = 0; i < rows; i++) + { + string[] values = lines[i].Split(' '); + if (values.Length != columnsSize) + { + throw new InvalidDataException("Срока имеет некорректное количество столбцов"); + } + + for (int j = 0; j < columnsSize; j++) + { + matrix[i, j] = int.Parse(values[j]); + } + } + + return matrix; + } + } +} diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ParallelMatrixMultiplication.csproj b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ParallelMatrixMultiplication.csproj new file mode 100644 index 0000000..90dd746 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ParallelMatrixMultiplication.csproj @@ -0,0 +1,17 @@ + + + + Exe + net9.0 + enable + enable + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs new file mode 100644 index 0000000..1bc52a6 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs @@ -0,0 +1 @@ +Console.WriteLine("Hello, World!"); From 6e4caea7a0780ff81b11dd1b678adb7789752be4 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sun, 14 Sep 2025 21:47:40 +0300 Subject: [PATCH 02/15] add: files with the main logic of the program --- .../ParallelMatrixMultiplication/Matrix.cs | 77 ++++++++--- .../MatrixMultiplier.cs | 79 +++++++++++ .../ParallelMatrixMultiplication/Program.cs | 55 +++++++- .../UserInterface.cs | 125 ++++++++++++++++++ .../ParallelMatrixMultiplication/matrixA.txt | 3 + .../ParallelMatrixMultiplication/matrixB.txt | 4 + 6 files changed, 321 insertions(+), 22 deletions(-) create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/UserInterface.cs create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixA.txt create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixB.txt diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs index 266d180..2c041de 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs @@ -1,26 +1,31 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; namespace ParallelMatrixMultiplication { - class Matrix + public class Matrix { public int Rows { get; private set; } + public int Columns { get; private set; } + private readonly int[,] numbers; public Matrix(int rows, int columns) { + this.Rows = rows; + this.Columns = columns; this.numbers = new int[rows, columns]; } public int this[int rows, int columns] { - get => numbers[rows, columns]; - set => numbers[rows, columns] = value; + get => this.numbers[rows, columns]; + set => this.numbers[rows, columns] = value; } public static Matrix LoadFromFile(string filePath) @@ -30,42 +35,72 @@ public static Matrix LoadFromFile(string filePath) throw new FileNotFoundException("Файл не найден"); } - List lines = new List(); - using (StreamReader reader = new StreamReader(filePath)) - { - string line = string.Empty; - while ((line = reader.ReadLine()) != null) - { - lines.Add(line); - } - } + string[] lines = File.ReadAllLines(filePath); - if (lines.Count == 0) + if (lines.Length == 0) { throw new InvalidDataException("Файл пуст"); } - int rows = lines.Count; - string[] firstRowValues = lines[0].Split(' '); + int rows = lines.Length; + + string[] firstRowValues = lines[0].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int columnsSize = firstRowValues.Length; Matrix matrix = new Matrix(rows, columnsSize); - for (int i = 0; i < rows; i++) + for (int i = 0; i < rows; ++i) { - string[] values = lines[i].Split(' '); + string[] values = lines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + if (values.Length != columnsSize) { - throw new InvalidDataException("Срока имеет некорректное количество столбцов"); + throw new InvalidDataException("Строка имеет некорректное значение стобцов"); + } + + for (int j = 0; j < columnsSize; ++j) + { + if (!int.TryParse(values[j], out int parsedValue)) + { + throw new FormatException("Неверный формат числа в строке"); + } + + matrix[i, j] = parsedValue; + } + } + + return matrix; + } + + public void SaveToFile(string filePath) + { + using (StreamWriter writer = new StreamWriter(filePath)) + { + for (int i = 0; i < this.Rows; i++) + { + for (int j = 0; j < this.Columns; j++) + { + writer.Write(this.numbers[i, j] + (j == this.Columns - 1 ? string.Empty : " ")); + } + + writer.WriteLine(); } + } + } - for (int j = 0; j < columnsSize; j++) + public static Matrix GenerateRandomMatrix(int rows, int columns) + { + Random random = new Random(); + Matrix matrix = new Matrix(rows, columns); + for (int i = 0; i < rows; i++) + { + for (int j = 0; j < columns; ++j) { - matrix[i, j] = int.Parse(values[j]); + matrix[i, j] = random.Next(1, 74); } } return matrix; } } -} +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs new file mode 100644 index 0000000..4980f1d --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ParallelMatrixMultiplication +{ + public class MatrixMultiplier + { + public static Matrix SequentialMultiplication(Matrix a, Matrix b) + { + if (a.Columns != b.Rows) + { + throw new InvalidDataException("Умножение невозможно(количество столбцов первой матрицы не равно количеству строк второй)"); + } + + Matrix result = new Matrix(a.Rows, b.Columns); + for (int i = 0; i < a.Rows; ++i) + { + for (int j = 0; j < b.Columns; j++) + { + int sum = 0; + for (int k = 0; k < a.Columns; k++) + { + sum += a[i, k] * b[k, j]; + } + result[i, j] = sum; + } + } + + return result; + } + + public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) + { + if (a.Columns != b.Rows) + { + throw new InvalidDataException("Умножение невозможно(количество столбцов первой матрицы не равно количеству строк второй)"); + } + + Matrix result = new Matrix(a.Rows, b.Columns); + + Thread[] threads = new Thread[numThreads]; + int rowsForThread = a.Rows / numThreads; + + for (int i = 0; i < numThreads; ++i) + { + int startRow = i * rowsForThread; + int endRow = (i == numThreads - 1) ? a.Rows : (i + 1) * rowsForThread; + + threads[i] = new Thread(() => + { + for (int row = startRow; row < endRow; row++) + { + for (int columns = 0; columns < b.Columns; columns++) + { + int sum = 0; + for (int k = 0; k < a.Columns; ++k) + { + sum += a[row, k] * b[k, columns]; + } + + result[row, columns] = sum; + } + } + }); + threads[i].Start(); + } + foreach (var thread in threads) + { + thread.Join(); + } + + return result; + } + } +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs index 1bc52a6..8c7d200 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs @@ -1 +1,54 @@ -Console.WriteLine("Hello, World!"); +using ParallelMatrixMultiplication; +using System.Linq.Expressions; + +string? choice; + +while (true) +{ + + if (args.Length == 0) + { + Console.WriteLine("Выберите способ получения матриц:"); + Console.WriteLine("1. Загрузить из файлов"); + Console.WriteLine("2. Рандомная генерация + тесты"); + Console.WriteLine("3. Выйти"); + Console.WriteLine("Выбор: "); + choice = Console.ReadLine(); + } + else + { + choice = args[0]; + } + + if (string.IsNullOrWhiteSpace(choice)) + { + Console.WriteLine("Выбор не указан"); + return; + } + + try + { + switch (choice) + { + case "1": + MatrixUserInterface.LoadFromFileAndMultiply(); + break; + + case "2": + MatrixUserInterface.UsersMatrixTests(); + break; + + case "3": + Console.WriteLine("Выход..."); + return; + + default: + Console.WriteLine("\nНеизвестный ввод\n"); + break; + } + } + catch (Exception ex) + { + Console.WriteLine($"Произошла ошибка: {ex.Message}"); + } +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/UserInterface.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/UserInterface.cs new file mode 100644 index 0000000..3c6c819 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/UserInterface.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ParallelMatrixMultiplication +{ + public class MatrixUserInterface + { + public static void LoadFromFileAndMultiply() + { + Console.WriteLine("\nВведите путь к файлу с первой матрицей: "); + string pathA = Console.ReadLine(); + Console.WriteLine("\nВведите путь к файлу со второй матрицей: "); + string pathB = Console.ReadLine(); + + if (string.IsNullOrEmpty(pathA) || string.IsNullOrEmpty(pathB)) + { + Console.WriteLine("Пути к файлам не могут быть пустыми"); + return; + } + + Matrix first = Matrix.LoadFromFile(pathA); + Matrix second = Matrix.LoadFromFile(pathB); + + Stopwatch stopwatch = Stopwatch.StartNew(); + Matrix sequentialResult = MatrixMultiplier.SequentialMultiplication(first, second); + stopwatch.Stop(); + Console.WriteLine($"\nПоследовательное умножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); + + Console.WriteLine("\nВведите путь для сохранения результата последовательного умножения: "); + string sequentialSavePath = Console.ReadLine(); + sequentialResult.SaveToFile(sequentialSavePath); + + int numOfThreads = Environment.ProcessorCount; + Console.WriteLine("\nПараллельное умножение:"); + stopwatch.Restart(); + Matrix parallelResult = MatrixMultiplier.ParallelMultiplication(first, second, numOfThreads); + stopwatch.Stop(); + Console.WriteLine($"\nПараллельное уммножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); + + Console.WriteLine("\nВведите путь для сохранения результата параллельного умножения: "); + string parallelSavePath = Console.ReadLine(); + parallelResult.SaveToFile(parallelSavePath); + } + + public static void UsersMatrixTests() + { + Console.WriteLine("Введите количество запусков для каждого теста: "); + if (!int.TryParse(Console.ReadLine(), out int n) || n <= 0) + { + Console.WriteLine("Неверное количество запусков."); + return; + } + + var testCases = new List<(int RowsA, int ColumnsA, int RowsB, int ColumnsB)>() + { + (100, 100, 100, 100), + (200, 200, 200, 200), + (300,300,300,300), + (400,400,400,400), + (500,500,500,500), + }; + + Console.WriteLine($"Проведение тестирования с {n} запусками"); + Console.WriteLine("\nРазмеры матриц | Матожидание(последовательное) | СКО(последовательное) | Матожидание(параллельное) | СКО(параллельное) \n"); + + foreach (var testCase in testCases) + { + int rowsA = testCase.RowsA; + int columnsA = testCase.ColumnsA; + int rowsB = testCase.RowsB; + int columnsB = testCase.ColumnsB; + + Matrix matrixA = Matrix.GenerateRandomMatrix(rowsA, columnsA); + Matrix matrixB = Matrix.GenerateRandomMatrix(rowsB, columnsB); + + var sequentialTimes = new List(); + var parallelTimes = new List(); + + int numOfThreads = Environment.ProcessorCount; + + for (int i = 0; i < n; ++i) + { + Stopwatch stopwatch = Stopwatch.StartNew(); + MatrixMultiplier.SequentialMultiplication(matrixA, matrixB); + stopwatch.Stop(); + sequentialTimes.Add(stopwatch.Elapsed.TotalMilliseconds); + + stopwatch.Restart(); + MatrixMultiplier.ParallelMultiplication(matrixA, matrixB, numOfThreads); + stopwatch.Stop(); + parallelTimes.Add(stopwatch.Elapsed.TotalMilliseconds); + } + + double sequentialExpectation = CalculateMathematicalExpectation(sequentialTimes); + double parallelExpectation = CalculateMathematicalExpectation(parallelTimes); + + double sequentialStandardDeviation = CalculateStandardDeviation(sequentialTimes, sequentialExpectation); + double parallelStandardDeviation = CalculateStandardDeviation(parallelTimes, parallelExpectation); + + Console.WriteLine($"{rowsA}x{columnsA} * {rowsB}x{columnsB} | {sequentialExpectation:F2} мс | {sequentialStandardDeviation:F2} | {parallelExpectation:F2} | {parallelStandardDeviation:F2}\n"); + } + } + + private static double CalculateMathematicalExpectation(List values) + { + return values.Sum() / values.Count; + } + + private static double CalculateStandardDeviation(List values, double expectation) + { + double sumOfSquares = 0; + foreach (double value in values) + { + sumOfSquares += (value - expectation) * (value - expectation); + } + + return Math.Sqrt(sumOfSquares / values.Count); + } + } +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixA.txt b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixA.txt new file mode 100644 index 0000000..217c474 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixA.txt @@ -0,0 +1,3 @@ +1 2 3 4 +5 -6 7 8 +9 -10 -11 -12 \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixB.txt b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixB.txt new file mode 100644 index 0000000..15c198b --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixB.txt @@ -0,0 +1,4 @@ +1 2 +-3 4 +5 6 +7 -8 \ No newline at end of file From aed04bb3e409f7c0981c13d8df7b699173a0e900 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Tue, 16 Sep 2025 02:03:04 +0300 Subject: [PATCH 03/15] docs: added comments --- .../ParallelMatrixMultiplication.sln | 8 +- .../ParallelMatrixMultiplication/Matrix.cs | 101 ++++++++++++------ .../MatrixMultiplier.cs | 33 ++++-- ...serInterface.cs => MatrixUserInterface.cs} | 54 ++++++---- .../ParallelMatrixMultiplication.csproj | 10 +- .../ParallelMatrixMultiplication/Program.cs | 8 +- 6 files changed, 147 insertions(+), 67 deletions(-) rename ParallelMatrixMultiplication/ParallelMatrixMultiplication/{UserInterface.cs => MatrixUserInterface.cs} (74%) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.sln b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.sln index 90584c4..aec2fc3 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.sln +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.sln @@ -1,10 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.13.35806.99 d17.13 +VisualStudioVersion = 17.13.35806.99 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParallelMatrixMultiplication", "ParallelMatrixMultiplication\ParallelMatrixMultiplication.csproj", "{96DCD91F-9CF3-4519-8929-C0C38523DBB7}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParallelMatrixMultiplication.Test", "ParallelMatrixMultiplication.Test\ParallelMatrixMultiplication.Test.csproj", "{217B9ADC-8DBB-4227-BE0F-6DF9674FF67A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {96DCD91F-9CF3-4519-8929-C0C38523DBB7}.Debug|Any CPU.Build.0 = Debug|Any CPU {96DCD91F-9CF3-4519-8929-C0C38523DBB7}.Release|Any CPU.ActiveCfg = Release|Any CPU {96DCD91F-9CF3-4519-8929-C0C38523DBB7}.Release|Any CPU.Build.0 = Release|Any CPU + {217B9ADC-8DBB-4227-BE0F-6DF9674FF67A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {217B9ADC-8DBB-4227-BE0F-6DF9674FF67A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {217B9ADC-8DBB-4227-BE0F-6DF9674FF67A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {217B9ADC-8DBB-4227-BE0F-6DF9674FF67A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs index 2c041de..4b61206 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs @@ -1,33 +1,75 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// namespace ParallelMatrixMultiplication { - public class Matrix + /// + /// A class representing a matrix and operations for working with it. + /// + /// + /// Initializes a new instance of the class. + /// + /// The number of specified rows. + /// The number of specified columns. + public class Matrix(int rows, int columns) { - public int Rows { get; private set; } - - public int Columns { get; private set; } - - private readonly int[,] numbers; - - public Matrix(int rows, int columns) - { - this.Rows = rows; - this.Columns = columns; - this.numbers = new int[rows, columns]; - } - + /// + /// An array for storing matrix elements. + /// + private readonly int[,] numbers = new int[rows, columns]; + + /// + /// Gets number of rows in the matrix. + /// + public int Rows { get; private set; } = rows; + + /// + /// Gets number of columns in the matrix. + /// + public int Columns { get; private set; } = columns; + + /// + /// Indexer for accessing matrix elements. + /// + /// Row index. + /// Column index. + /// The value of the element. public int this[int rows, int columns] { get => this.numbers[rows, columns]; set => this.numbers[rows, columns] = value; } + /// + /// A method for generating a matrix with random values. + /// + /// Number of lines. + /// Number of columns. + /// Matrix with random values. + public static Matrix GenerateRandomMatrix(int rows, int columns) + { + Random random = new Random(); + Matrix matrix = new Matrix(rows, columns); + for (int i = 0; i < rows; i++) + { + for (int j = 0; j < columns; ++j) + { + matrix[i, j] = random.Next(1, 74); + } + } + + return matrix; + } + + /// + /// A method for loading a matrix from a file. + /// + /// The path to the matrix file. + /// The matrix from the file. + /// It is thrown if the file is not found. + /// It is thrown if the file is empty or contains incorrect data. + /// It is thrown if the numbers in the file have an incorrect format. public static Matrix LoadFromFile(string filePath) { if (!File.Exists(filePath)) @@ -72,6 +114,10 @@ public static Matrix LoadFromFile(string filePath) return matrix; } + /// + /// A method for saving a matrix to a file. + /// + /// The path to save the file. public void SaveToFile(string filePath) { using (StreamWriter writer = new StreamWriter(filePath)) @@ -87,20 +133,5 @@ public void SaveToFile(string filePath) } } } - - public static Matrix GenerateRandomMatrix(int rows, int columns) - { - Random random = new Random(); - Matrix matrix = new Matrix(rows, columns); - for (int i = 0; i < rows; i++) - { - for (int j = 0; j < columns; ++j) - { - matrix[i, j] = random.Next(1, 74); - } - } - - return matrix; - } } } \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs index 4980f1d..6206c39 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs @@ -1,14 +1,23 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// namespace ParallelMatrixMultiplication { + /// + /// A class for performing matrix multiplication in sequential and parallel ways. + /// public class MatrixMultiplier { + /// + /// Performs sequential multiplication of two matrices(AxB). + /// + /// The first matrix. + /// The second matrix. + /// The resulting matrix. + /// It is thrown if the number of columns of the first + /// matrix is not equal to the number of rows of the second. + /// public static Matrix SequentialMultiplication(Matrix a, Matrix b) { if (a.Columns != b.Rows) @@ -26,6 +35,7 @@ public static Matrix SequentialMultiplication(Matrix a, Matrix b) { sum += a[i, k] * b[k, j]; } + result[i, j] = sum; } } @@ -33,6 +43,16 @@ public static Matrix SequentialMultiplication(Matrix a, Matrix b) return result; } + /// + /// Performs parallel multiplication of two matrices(AxB). + /// + /// The first matrix. + /// The second matrix. + /// Number of threads. + /// The resulting matrix. + /// It is thrown if the number of columns of the first + /// matrix is not equal to the number of rows of the second. + /// public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) { if (a.Columns != b.Rows) @@ -68,6 +88,7 @@ public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) }); threads[i].Start(); } + foreach (var thread in threads) { thread.Join(); diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/UserInterface.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs similarity index 74% rename from ParallelMatrixMultiplication/ParallelMatrixMultiplication/UserInterface.cs rename to ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs index 3c6c819..88936fc 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/UserInterface.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs @@ -1,27 +1,29 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// namespace ParallelMatrixMultiplication { + using System.Diagnostics; + + /// + /// A user interface class for working with matrix multiplication. + /// public class MatrixUserInterface { + /// + /// Loads matrices from files, performs sequential and parallel multiplication, + /// and saves the results to files, as well as additionally measures execution time. + /// public static void LoadFromFileAndMultiply() { Console.WriteLine("\nВведите путь к файлу с первой матрицей: "); - string pathA = Console.ReadLine(); - Console.WriteLine("\nВведите путь к файлу со второй матрицей: "); - string pathB = Console.ReadLine(); + string? pathA = Console.ReadLine(); + ArgumentNullException.ThrowIfNullOrEmpty(pathA); - if (string.IsNullOrEmpty(pathA) || string.IsNullOrEmpty(pathB)) - { - Console.WriteLine("Пути к файлам не могут быть пустыми"); - return; - } + Console.WriteLine("\nВведите путь к файлу со второй матрицей: "); + string? pathB = Console.ReadLine(); + ArgumentNullException.ThrowIfNullOrEmpty(pathB); Matrix first = Matrix.LoadFromFile(pathA); Matrix second = Matrix.LoadFromFile(pathB); @@ -32,7 +34,8 @@ public static void LoadFromFileAndMultiply() Console.WriteLine($"\nПоследовательное умножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); Console.WriteLine("\nВведите путь для сохранения результата последовательного умножения: "); - string sequentialSavePath = Console.ReadLine(); + string? sequentialSavePath = Console.ReadLine(); + ArgumentNullException.ThrowIfNullOrEmpty(sequentialSavePath); sequentialResult.SaveToFile(sequentialSavePath); int numOfThreads = Environment.ProcessorCount; @@ -43,10 +46,15 @@ public static void LoadFromFileAndMultiply() Console.WriteLine($"\nПараллельное уммножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); Console.WriteLine("\nВведите путь для сохранения результата параллельного умножения: "); - string parallelSavePath = Console.ReadLine(); + string? parallelSavePath = Console.ReadLine(); + ArgumentNullException.ThrowIfNullOrEmpty(parallelSavePath); parallelResult.SaveToFile(parallelSavePath); } + /// + /// Performs performance testing of sequential and parallel matrix multiplication + /// for various matrix sizes with a set number of runs. + /// public static void UsersMatrixTests() { Console.WriteLine("Введите количество запусков для каждого теста: "); @@ -60,13 +68,17 @@ public static void UsersMatrixTests() { (100, 100, 100, 100), (200, 200, 200, 200), - (300,300,300,300), - (400,400,400,400), - (500,500,500,500), + (300, 300, 300, 300), + (400, 400, 400, 400), + (500, 500, 500, 500), }; Console.WriteLine($"Проведение тестирования с {n} запусками"); - Console.WriteLine("\nРазмеры матриц | Матожидание(последовательное) | СКО(последовательное) | Матожидание(параллельное) | СКО(параллельное) \n"); + Console.WriteLine("\nРазмеры матриц | " + + "Матожидание(последовательное) | " + + "СКО(последовательное) | " + + "Матожидание(параллельное) | " + + "СКО(параллельное) \n"); foreach (var testCase in testCases) { diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ParallelMatrixMultiplication.csproj b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ParallelMatrixMultiplication.csproj index 90dd746..81e1be1 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ParallelMatrixMultiplication.csproj +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ParallelMatrixMultiplication.csproj @@ -7,7 +7,15 @@ enable - + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs index 8c7d200..53996f1 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs @@ -1,11 +1,13 @@ -using ParallelMatrixMultiplication; -using System.Linq.Expressions; +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// + +using ParallelMatrixMultiplication; string? choice; while (true) { - if (args.Length == 0) { Console.WriteLine("Выберите способ получения матриц:"); From dc077a5a6a240a0cd9b5a957277c2a2b554b91b9 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Tue, 16 Sep 2025 02:37:37 +0300 Subject: [PATCH 04/15] refactor: in method "LoadFromFile" removed an unnecessary array of delimiters --- .../ParallelMatrixMultiplication/Matrix.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs index 4b61206..c2e7dc2 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs @@ -86,14 +86,14 @@ public static Matrix LoadFromFile(string filePath) int rows = lines.Length; - string[] firstRowValues = lines[0].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + string[] firstRowValues = lines[0].Split(' ', StringSplitOptions.RemoveEmptyEntries); int columnsSize = firstRowValues.Length; Matrix matrix = new Matrix(rows, columnsSize); for (int i = 0; i < rows; ++i) { - string[] values = lines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + string[] values = lines[i].Split(' ', StringSplitOptions.RemoveEmptyEntries); if (values.Length != columnsSize) { From badd149ac27a19c038fece3024106211ddae46f0 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Tue, 16 Sep 2025 03:20:48 +0300 Subject: [PATCH 05/15] refactor: now, in the "SaveToFile", an empty row is not added for the last row of the matrix --- .../ParallelMatrixMultiplication/Matrix.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs index c2e7dc2..b5c1aa7 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs @@ -129,7 +129,10 @@ public void SaveToFile(string filePath) writer.Write(this.numbers[i, j] + (j == this.Columns - 1 ? string.Empty : " ")); } - writer.WriteLine(); + if (i < this.Rows - 1) + { + writer.WriteLine(); + } } } } From 0401e367b7686d48c3d9f5e98cf5a19b9a60ce1c Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Tue, 16 Sep 2025 03:59:42 +0300 Subject: [PATCH 06/15] add: tests --- .../.editorconfig | 125 ++++++++++++++++++ .../ParallelMatrixMultiplication.Test.csproj | 58 ++++++++ .../TestLoadFromFile.cs | 65 +++++++++ .../TestSaveToFile.cs | 54 ++++++++ .../TestsBothMethodsAreSimilar.cs | 33 +++++ .../TestsParallelMultiply.cs | 88 ++++++++++++ .../TestsSequentialMultiply.cs | 88 ++++++++++++ .../expectedForSaveToFileTest.txt | 3 + .../firstTestFileForRead.txt | 3 + .../secondTestFileForRead.txt | 2 + .../stylecop.json | 15 +++ .../MatrixMultiplier.cs | 6 +- .../stylecop.json | 15 +++ 13 files changed, 554 insertions(+), 1 deletion(-) create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/.editorconfig create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/ParallelMatrixMultiplication.Test.csproj create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsBothMethodsAreSimilar.cs create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/expectedForSaveToFileTest.txt create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/firstTestFileForRead.txt create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/secondTestFileForRead.txt create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/stylecop.json create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/stylecop.json diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/.editorconfig b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/.editorconfig new file mode 100644 index 0000000..51a0b79 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/.editorconfig @@ -0,0 +1,125 @@ +[*.cs] + +# SA1600: Elements should be documented +dotnet_diagnostic.SA1600.severity = none + +[*.cs] +#### Стили именования #### + +# Правила именования + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Спецификации символов + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Стили именования + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case +csharp_style_throw_expression = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_prefer_simple_default_expression = true:suggestion +csharp_indent_labels = one_less_than_current + +[*.vb] +#### Стили именования #### + +# Правила именования + +dotnet_naming_rule.interface_should_be_начинается_с_i.severity = suggestion +dotnet_naming_rule.interface_should_be_начинается_с_i.symbols = interface +dotnet_naming_rule.interface_should_be_начинается_с_i.style = начинается_с_i + +dotnet_naming_rule.типы_should_be_всечастиспрописнойбуквы.severity = suggestion +dotnet_naming_rule.типы_should_be_всечастиспрописнойбуквы.symbols = типы +dotnet_naming_rule.типы_should_be_всечастиспрописнойбуквы.style = всечастиспрописнойбуквы + +dotnet_naming_rule.не_являющиеся_полем_члены_should_be_всечастиспрописнойбуквы.severity = suggestion +dotnet_naming_rule.не_являющиеся_полем_члены_should_be_всечастиспрописнойбуквы.symbols = не_являющиеся_полем_члены +dotnet_naming_rule.не_являющиеся_полем_члены_should_be_всечастиспрописнойбуквы.style = всечастиспрописнойбуквы + +# Спецификации символов + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.типы.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.типы.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected +dotnet_naming_symbols.типы.required_modifiers = + +dotnet_naming_symbols.не_являющиеся_полем_члены.applicable_kinds = property, event, method +dotnet_naming_symbols.не_являющиеся_полем_члены.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected +dotnet_naming_symbols.не_являющиеся_полем_члены.required_modifiers = + +# Стили именования + +dotnet_naming_style.начинается_с_i.required_prefix = I +dotnet_naming_style.начинается_с_i.required_suffix = +dotnet_naming_style.начинается_с_i.word_separator = +dotnet_naming_style.начинается_с_i.capitalization = pascal_case + +dotnet_naming_style.всечастиспрописнойбуквы.required_prefix = +dotnet_naming_style.всечастиспрописнойбуквы.required_suffix = +dotnet_naming_style.всечастиспрописнойбуквы.word_separator = +dotnet_naming_style.всечастиспрописнойбуквы.capitalization = pascal_case + +dotnet_naming_style.всечастиспрописнойбуквы.required_prefix = +dotnet_naming_style.всечастиспрописнойбуквы.required_suffix = +dotnet_naming_style.всечастиспрописнойбуквы.word_separator = +dotnet_naming_style.всечастиспрописнойбуквы.capitalization = pascal_case + +[*.{cs,vb}] +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/ParallelMatrixMultiplication.Test.csproj b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/ParallelMatrixMultiplication.Test.csproj new file mode 100644 index 0000000..e68a958 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/ParallelMatrixMultiplication.Test.csproj @@ -0,0 +1,58 @@ + + + + net9.0 + latest + enable + enable + false + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs new file mode 100644 index 0000000..7a4484f --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs @@ -0,0 +1,65 @@ +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// + +namespace ParallelMatrixMultiplication.Test +{ + public class TestLoadFromFile + { + private Matrix firstExpectedMatrix; + private Matrix secondExpectedMatrix; + + [SetUp] + public void Setup() + { + this.firstExpectedMatrix = new Matrix(3, 3); + this.firstExpectedMatrix[0, 0] = 15; + this.firstExpectedMatrix[0, 1] = 16; + this.firstExpectedMatrix[0, 2] = 17; + this.firstExpectedMatrix[1, 0] = 20; + this.firstExpectedMatrix[1, 1] = 23; + this.firstExpectedMatrix[1, 2] = 26; + this.firstExpectedMatrix[2, 0] = 29; + this.firstExpectedMatrix[2, 1] = 32; + this.firstExpectedMatrix[2, 2] = 35; + + this.secondExpectedMatrix = new Matrix(2, 5); + this.secondExpectedMatrix[0, 0] = 1; + this.secondExpectedMatrix[0, 1] = 2; + this.secondExpectedMatrix[0, 2] = 3; + this.secondExpectedMatrix[0, 3] = 4; + this.secondExpectedMatrix[0, 4] = 5; + this.secondExpectedMatrix[1, 0] = 6; + this.secondExpectedMatrix[1, 1] = 7; + this.secondExpectedMatrix[1, 2] = 8; + this.secondExpectedMatrix[1, 3] = 9; + this.secondExpectedMatrix[1, 4] = 10; + } + + [Test] + public void LoadFromFile_SquareMatrix_ShouldReturnExpectedResult() + { + var result = Matrix.LoadFromFile("firstTestFileForRead.txt"); + for (int i = 0; i < result.Rows; ++i) + { + for (int j = 0; j < result.Columns; ++j) + { + Assert.That(result[i, j], Is.EqualTo(this.firstExpectedMatrix[i, j])); + } + } + } + + [Test] + public void LoadFromFile_NotSquareMatrix_ShouldReturnExpectedResult() + { + var result = Matrix.LoadFromFile("secondTestFileForRead.txt"); + for (int i = 0; i < result.Rows; ++i) + { + for (int j = 0; j < result.Columns; ++j) + { + Assert.That(result[i, j], Is.EqualTo(this.secondExpectedMatrix[i, j])); + } + } + } + } +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs new file mode 100644 index 0000000..88bd043 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs @@ -0,0 +1,54 @@ +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// + +namespace ParallelMatrixMultiplication.Test +{ + public class TestSaveToFile + { + private Matrix matrixToSave; + private string currentFilePath; + + [SetUp] + public void Setup() + { + this.matrixToSave = new Matrix(3, 4); + this.matrixToSave[0, 0] = 99; + this.matrixToSave[0, 1] = 90; + this.matrixToSave[0, 2] = 88; + this.matrixToSave[0, 3] = 80; + this.matrixToSave[1, 0] = 77; + this.matrixToSave[1, 1] = 70; + this.matrixToSave[1, 2] = 66; + this.matrixToSave[1, 3] = 60; + this.matrixToSave[2, 0] = 55; + this.matrixToSave[2, 1] = 50; + this.matrixToSave[2, 2] = 44; + this.matrixToSave[2, 3] = 40; + + this.currentFilePath = "Test_STF.txt"; + } + + [TearDown] + public void Teardown() + { + if (File.Exists(this.currentFilePath)) + { + File.Delete(this.currentFilePath); + } + } + + [Test] + public void SaveToFile_ValidData_ShouldCreateExpectedFile() + { + this.matrixToSave.SaveToFile(this.currentFilePath); + + Assert.That(File.Exists(this.currentFilePath), Is.True); + + string expectedData = File.ReadAllText("expectedForSaveToFileTest.txt"); + string currentData = File.ReadAllText(this.currentFilePath); + + Assert.That(currentData, Is.EqualTo(expectedData)); + } + } +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsBothMethodsAreSimilar.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsBothMethodsAreSimilar.cs new file mode 100644 index 0000000..fca5ec6 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsBothMethodsAreSimilar.cs @@ -0,0 +1,33 @@ +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// + +namespace ParallelMatrixMultiplication.Test +{ + public class TestsBothMethodsAreSimilar + { + private Matrix testRandomMatrixA; + private Matrix testRandomMatrixB; + + [SetUp] + public void Setup() + { + this.testRandomMatrixA = Matrix.GenerateRandomMatrix(77, 33); + this.testRandomMatrixB = Matrix.GenerateRandomMatrix(33, 77); + } + + [Test] + public void SequentialAndParallelMultiplication_RandomMatrix_ShouldReturnSameResult() + { + var parallelResult = MatrixMultiplier.ParallelMultiplication(this.testRandomMatrixA, this.testRandomMatrixB, 4); + var sequentialResult = MatrixMultiplier.SequentialMultiplication(this.testRandomMatrixA, this.testRandomMatrixB); + for (int i = 0; i < parallelResult.Rows; ++i) + { + for (int j = 0; j < parallelResult.Columns; ++j) + { + Assert.That(parallelResult[i, j], Is.EqualTo(sequentialResult[i, j])); + } + } + } + } +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs new file mode 100644 index 0000000..d7b360b --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs @@ -0,0 +1,88 @@ +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// + +namespace ParallelMatrixMultiplication.Test +{ + public class TestsParallelMultiply + { + private Matrix testMatrixA2x2; + private Matrix testMatrixB2x2; + + private Matrix testMatrixA2x3; + private Matrix testMatrixB3x2; + + private Matrix firstExpectedResult; + private Matrix secondExpectedResult; + + [SetUp] + public void Setup() + { + this.testMatrixA2x2 = new Matrix(2, 2); + this.testMatrixA2x2[0, 0] = 9; + this.testMatrixA2x2[0, 1] = 4; + this.testMatrixA2x2[1, 0] = 5; + this.testMatrixA2x2[1, 1] = 1; + + this.testMatrixB2x2 = new Matrix(2, 2); + this.testMatrixB2x2[0, 0] = 5; + this.testMatrixB2x2[0, 1] = 3; + this.testMatrixB2x2[1, 0] = 8; + this.testMatrixB2x2[1, 1] = 7; + + this.testMatrixA2x3 = new Matrix(2, 3); + this.testMatrixA2x3[0, 0] = 2; + this.testMatrixA2x3[0, 1] = 1; + this.testMatrixA2x3[0, 2] = 0; + this.testMatrixA2x3[1, 0] = 7; + this.testMatrixA2x3[1, 1] = -5; + this.testMatrixA2x3[1, 2] = 6; + + this.testMatrixB3x2 = new Matrix(3, 2); + this.testMatrixB3x2[0, 0] = -2; + this.testMatrixB3x2[0, 1] = 6; + this.testMatrixB3x2[1, 0] = 4; + this.testMatrixB3x2[1, 1] = 2; + this.testMatrixB3x2[2, 0] = 3; + this.testMatrixB3x2[2, 1] = 8; + + this.firstExpectedResult = new Matrix(2, 2); + this.firstExpectedResult[0, 0] = 77; + this.firstExpectedResult[0, 1] = 55; + this.firstExpectedResult[1, 0] = 33; + this.firstExpectedResult[1, 1] = 22; + + this.secondExpectedResult = new Matrix(2, 2); + this.secondExpectedResult[0, 0] = 0; + this.secondExpectedResult[0, 1] = 14; + this.secondExpectedResult[1, 0] = -16; + this.secondExpectedResult[1, 1] = 80; + } + + [Test] + public void ParallelMultiplication_SquareMatrices_ShouldReturnExpectedResult() + { + var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x2, this.testMatrixB2x2, 4); + for (int i = 0; i < result.Rows; ++i) + { + for (int j = 0; j < result.Columns; ++j) + { + Assert.That(result[i, j], Is.EqualTo(this.firstExpectedResult[i, j])); + } + } + } + + [Test] + public void ParallelMultiplication_NotSquareMatrices_ShouldReturnExpectedResult() + { + var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x3, this.testMatrixB3x2, 4); + for (int i = 0; i < result.Rows; ++i) + { + for (int j = 0; j < result.Columns; ++j) + { + Assert.That(result[i, j], Is.EqualTo(this.secondExpectedResult[i, j])); + } + } + } + } +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs new file mode 100644 index 0000000..a0acebd --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs @@ -0,0 +1,88 @@ +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// + +namespace ParallelMatrixMultiplication.Test +{ + public class TestsSequentialMultiply + { + private Matrix testMatrixA2x2; + private Matrix testMatrixB2x2; + + private Matrix testMatrixA2x3; + private Matrix testMatrixB3x2; + + private Matrix firstExpectedResult; + private Matrix secondExpectedResult; + + [SetUp] + public void Setup() + { + this.testMatrixA2x2 = new Matrix(2, 2); + this.testMatrixA2x2[0, 0] = 1; + this.testMatrixA2x2[0, 1] = 2; + this.testMatrixA2x2[1, 0] = 3; + this.testMatrixA2x2[1, 1] = 4; + + this.testMatrixB2x2 = new Matrix(2, 2); + this.testMatrixB2x2[0, 0] = 9; + this.testMatrixB2x2[0, 1] = 8; + this.testMatrixB2x2[1, 0] = 7; + this.testMatrixB2x2[1, 1] = 6; + + this.testMatrixA2x3 = new Matrix(2, 3); + this.testMatrixA2x3[0, 0] = 2; + this.testMatrixA2x3[0, 1] = -3; + this.testMatrixA2x3[0, 2] = 1; + this.testMatrixA2x3[1, 0] = 5; + this.testMatrixA2x3[1, 1] = 4; + this.testMatrixA2x3[1, 2] = -2; + + this.testMatrixB3x2 = new Matrix(3, 2); + this.testMatrixB3x2[0, 0] = -7; + this.testMatrixB3x2[0, 1] = 5; + this.testMatrixB3x2[1, 0] = 2; + this.testMatrixB3x2[1, 1] = -1; + this.testMatrixB3x2[2, 0] = 4; + this.testMatrixB3x2[2, 1] = 3; + + this.firstExpectedResult = new Matrix(2, 2); + this.firstExpectedResult[0, 0] = 23; + this.firstExpectedResult[0, 1] = 20; + this.firstExpectedResult[1, 0] = 55; + this.firstExpectedResult[1, 1] = 48; + + this.secondExpectedResult = new Matrix(2, 2); + this.secondExpectedResult[0, 0] = -16; + this.secondExpectedResult[0, 1] = 16; + this.secondExpectedResult[1, 0] = -35; + this.secondExpectedResult[1, 1] = 15; + } + + [Test] + public void SequentialMultiplication_SquareMatrices_ShouldReturnExpectedResult() + { + var result = MatrixMultiplier.SequentialMultiplication(this.testMatrixA2x2, this.testMatrixB2x2); + for (int i = 0; i < result.Rows; ++i) + { + for (int j = 0; j < result.Columns; ++j) + { + Assert.That(result[i, j], Is.EqualTo(this.firstExpectedResult[i, j])); + } + } + } + + [Test] + public void SequentialMultiplication_NotSquareMatrices_ShouldReturnExpectedResult() + { + var result = MatrixMultiplier.SequentialMultiplication(this.testMatrixA2x3, this.testMatrixB3x2); + for (int i = 0; i < result.Rows; ++i) + { + for (int j = 0; j < result.Columns; ++j) + { + Assert.That(result[i, j], Is.EqualTo(this.secondExpectedResult[i, j])); + } + } + } + } +} \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/expectedForSaveToFileTest.txt b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/expectedForSaveToFileTest.txt new file mode 100644 index 0000000..8a1b8b5 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/expectedForSaveToFileTest.txt @@ -0,0 +1,3 @@ +99 90 88 80 +77 70 66 60 +55 50 44 40 \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/firstTestFileForRead.txt b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/firstTestFileForRead.txt new file mode 100644 index 0000000..dfd68d9 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/firstTestFileForRead.txt @@ -0,0 +1,3 @@ +15 16 17 +20 23 26 +29 32 35 \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/secondTestFileForRead.txt b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/secondTestFileForRead.txt new file mode 100644 index 0000000..ef25eaa --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/secondTestFileForRead.txt @@ -0,0 +1,2 @@ +1 2 3 4 5 +6 7 8 9 10 diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/stylecop.json b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/stylecop.json new file mode 100644 index 0000000..577bdb3 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/stylecop.json @@ -0,0 +1,15 @@ +{ + // ACTION REQUIRED: This file was automatically added to your project, but it + // will not take effect until additional steps are taken to enable it. See the + // following page for additional information: + // + // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md + + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "Kalinin Andrew", + "copyrightText": "Copyright (c) {companyName}. All rights reserved." + } + } +} diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs index 6206c39..4b4f51a 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs @@ -86,7 +86,11 @@ public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) } } }); - threads[i].Start(); + } + + foreach (var thread in threads) + { + thread.Start(); } foreach (var thread in threads) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/stylecop.json b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/stylecop.json new file mode 100644 index 0000000..577bdb3 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/stylecop.json @@ -0,0 +1,15 @@ +{ + // ACTION REQUIRED: This file was automatically added to your project, but it + // will not take effect until additional steps are taken to enable it. See the + // following page for additional information: + // + // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md + + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "Kalinin Andrew", + "copyrightText": "Copyright (c) {companyName}. All rights reserved." + } + } +} From 7f0581c6a58a22b5fe61500bd34ba48bdcd3661a Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Tue, 16 Sep 2025 04:04:50 +0300 Subject: [PATCH 07/15] docs: change stylecop.json --- .../ParallelMatrixMultiplication.Test/stylecop.json | 6 ------ .../ParallelMatrixMultiplication/stylecop.json | 6 ------ 2 files changed, 12 deletions(-) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/stylecop.json b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/stylecop.json index 577bdb3..ce12f73 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/stylecop.json +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/stylecop.json @@ -1,10 +1,4 @@ { - // ACTION REQUIRED: This file was automatically added to your project, but it - // will not take effect until additional steps are taken to enable it. See the - // following page for additional information: - // - // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md - "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", "settings": { "documentationRules": { diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/stylecop.json b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/stylecop.json index 577bdb3..ce12f73 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/stylecop.json +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/stylecop.json @@ -1,10 +1,4 @@ { - // ACTION REQUIRED: This file was automatically added to your project, but it - // will not take effect until additional steps are taken to enable it. See the - // following page for additional information: - // - // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md - "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", "settings": { "documentationRules": { From c7b27d06783d0b31fd32aecef014be7e12fe9014 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Tue, 16 Sep 2025 04:09:25 +0300 Subject: [PATCH 08/15] refactor: change .csproj from test project --- .../ParallelMatrixMultiplication.Test.csproj | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/ParallelMatrixMultiplication.Test.csproj b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/ParallelMatrixMultiplication.Test.csproj index e68a958..944a8ea 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/ParallelMatrixMultiplication.Test.csproj +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/ParallelMatrixMultiplication.Test.csproj @@ -31,14 +31,8 @@ - - - - - - - - + + From eee2c4d4c3a544eea20011b4fd09e8c44242ecc7 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sat, 20 Sep 2025 23:31:43 +0300 Subject: [PATCH 09/15] refactor: rational thread counts for parallel multiplication --- .../ParallelMatrixMultiplication/MatrixMultiplier.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs index 4b4f51a..a4b7896 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs @@ -62,8 +62,9 @@ public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) Matrix result = new Matrix(a.Rows, b.Columns); - Thread[] threads = new Thread[numThreads]; - int rowsForThread = a.Rows / numThreads; + int actualNumOfThread = Math.Min(a.Rows, numThreads); + Thread[] threads = new Thread[actualNumOfThread]; + int rowsForThread = a.Rows / actualNumOfThread; for (int i = 0; i < numThreads; ++i) { From cea4e5ccdfe787c0488171239ad65432d044fe09 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sun, 21 Sep 2025 01:51:02 +0300 Subject: [PATCH 10/15] feat: now it only works through the command line --- .../ArgumentParser.cs | 24 ++++++ .../ParallelMatrixMultiplication/Matrix.cs | 2 +- .../MatrixMultiplier.cs | 4 +- .../MatrixUserInterface.cs | 32 ++----- .../ParallelMatrixMultiplication/Program.cs | 85 ++++++++++--------- 5 files changed, 78 insertions(+), 69 deletions(-) create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs new file mode 100644 index 0000000..05a7e79 --- /dev/null +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs @@ -0,0 +1,24 @@ +// +// Copyright (c) Kalinin Andrew. All rights reserved. +// + +namespace ParallelMatrixMultiplication +{ + /// + /// A class for working with command line arguments. + /// + public static class ArgumentParser + { + /// + /// Analyzes the command line arguments and determines the execution mode. + /// + /// An array of command line arguments. + /// A tuple containing the execution mode and an array of parameters. + public static (string Mode, string[] Parametrs) Parse(string[] args) + { + string mode = args[0].ToLower(); + string[] parametrs = args.Skip(1).ToArray(); + return (mode, parametrs); + } + } +} diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs index b5c1aa7..615baf0 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs @@ -74,7 +74,7 @@ public static Matrix LoadFromFile(string filePath) { if (!File.Exists(filePath)) { - throw new FileNotFoundException("Файл не найден"); + throw new FileNotFoundException($"Файл {filePath} не найден"); } string[] lines = File.ReadAllLines(filePath); diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs index a4b7896..42d417b 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs @@ -66,10 +66,10 @@ public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) Thread[] threads = new Thread[actualNumOfThread]; int rowsForThread = a.Rows / actualNumOfThread; - for (int i = 0; i < numThreads; ++i) + for (int i = 0; i < actualNumOfThread; ++i) { int startRow = i * rowsForThread; - int endRow = (i == numThreads - 1) ? a.Rows : (i + 1) * rowsForThread; + int endRow = (i == actualNumOfThread - 1) ? a.Rows : (i + 1) * rowsForThread; threads[i] = new Thread(() => { diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs index 88936fc..b01efee 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs @@ -15,16 +15,12 @@ public class MatrixUserInterface /// Loads matrices from files, performs sequential and parallel multiplication, /// and saves the results to files, as well as additionally measures execution time. /// - public static void LoadFromFileAndMultiply() + /// The path to the first matrix. + /// The path to the second matrix. + /// The path to the sequential result matrix. + /// The path to the parallel result matrix. + public static void LoadFromFileAndMultiply(string pathA, string pathB, string sequentialSavePath, string parallelSavePath) { - Console.WriteLine("\nВведите путь к файлу с первой матрицей: "); - string? pathA = Console.ReadLine(); - ArgumentNullException.ThrowIfNullOrEmpty(pathA); - - Console.WriteLine("\nВведите путь к файлу со второй матрицей: "); - string? pathB = Console.ReadLine(); - ArgumentNullException.ThrowIfNullOrEmpty(pathB); - Matrix first = Matrix.LoadFromFile(pathA); Matrix second = Matrix.LoadFromFile(pathB); @@ -33,21 +29,15 @@ public static void LoadFromFileAndMultiply() stopwatch.Stop(); Console.WriteLine($"\nПоследовательное умножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); - Console.WriteLine("\nВведите путь для сохранения результата последовательного умножения: "); - string? sequentialSavePath = Console.ReadLine(); - ArgumentNullException.ThrowIfNullOrEmpty(sequentialSavePath); sequentialResult.SaveToFile(sequentialSavePath); int numOfThreads = Environment.ProcessorCount; - Console.WriteLine("\nПараллельное умножение:"); + Console.WriteLine($"\nПараллельное умножение c {numOfThreads} потоками:"); stopwatch.Restart(); Matrix parallelResult = MatrixMultiplier.ParallelMultiplication(first, second, numOfThreads); stopwatch.Stop(); Console.WriteLine($"\nПараллельное уммножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); - Console.WriteLine("\nВведите путь для сохранения результата параллельного умножения: "); - string? parallelSavePath = Console.ReadLine(); - ArgumentNullException.ThrowIfNullOrEmpty(parallelSavePath); parallelResult.SaveToFile(parallelSavePath); } @@ -55,15 +45,9 @@ public static void LoadFromFileAndMultiply() /// Performs performance testing of sequential and parallel matrix multiplication /// for various matrix sizes with a set number of runs. /// - public static void UsersMatrixTests() + /// The number of runs for each test. + public static void UsersMatrixTests(int n) { - Console.WriteLine("Введите количество запусков для каждого теста: "); - if (!int.TryParse(Console.ReadLine(), out int n) || n <= 0) - { - Console.WriteLine("Неверное количество запусков."); - return; - } - var testCases = new List<(int RowsA, int ColumnsA, int RowsB, int ColumnsB)>() { (100, 100, 100, 100), diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs index 53996f1..7aa822a 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs @@ -4,53 +4,54 @@ using ParallelMatrixMultiplication; -string? choice; +args = Environment.GetCommandLineArgs().Skip(1).ToArray(); +var (choice, parameters) = ArgumentParser.Parse(args); -while (true) +try { - if (args.Length == 0) + switch (choice) { - Console.WriteLine("Выберите способ получения матриц:"); - Console.WriteLine("1. Загрузить из файлов"); - Console.WriteLine("2. Рандомная генерация + тесты"); - Console.WriteLine("3. Выйти"); - Console.WriteLine("Выбор: "); - choice = Console.ReadLine(); - } - else - { - choice = args[0]; - } - - if (string.IsNullOrWhiteSpace(choice)) - { - Console.WriteLine("Выбор не указан"); - return; - } + case "load": + if (parameters.Length < 4) + { + Console.WriteLine("Недостаточно аргументов. (load )"); + return; + } + + string pathA = parameters[0]; + string pathB = parameters[1]; + string sequentialSavePath = parameters[2]; + string parallelSavePath = parameters[3]; + + ArgumentNullException.ThrowIfNullOrEmpty(pathA); + ArgumentNullException.ThrowIfNullOrEmpty(pathB); + ArgumentNullException.ThrowIfNullOrEmpty(sequentialSavePath); + ArgumentNullException.ThrowIfNullOrEmpty(parallelSavePath); + MatrixUserInterface.LoadFromFileAndMultiply(pathA, pathB, sequentialSavePath, parallelSavePath); + break; + + case "matrixtest": + if (parameters.Length < 1) + { + Console.WriteLine("Недостаточно аргументов. (matrixtest )"); + return; + } - try - { - switch (choice) - { - case "1": - MatrixUserInterface.LoadFromFileAndMultiply(); - break; - - case "2": - MatrixUserInterface.UsersMatrixTests(); - break; - - case "3": - Console.WriteLine("Выход..."); + if (!int.TryParse(parameters[0], out int n) || n <= 0) + { + Console.WriteLine("Неверное количество запусков. Ожидается целое положительное число"); return; + } - default: - Console.WriteLine("\nНеизвестный ввод\n"); - break; - } - } - catch (Exception ex) - { - Console.WriteLine($"Произошла ошибка: {ex.Message}"); + MatrixUserInterface.UsersMatrixTests(n); + break; + + default: + Console.WriteLine("\nНеизвестный ввод. Ожидается load или matrixtest\n"); + break; } +} +catch (Exception ex) +{ + Console.WriteLine($"Произошла ошибка: {ex.Message}"); } \ No newline at end of file From ee428d432ba90eddfd82762f9c0eb9f053f09e70 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sun, 30 Nov 2025 02:12:13 +0300 Subject: [PATCH 11/15] refactor: the beginning of work edits --- .../TestLoadFromFile.cs | 91 ++++--- .../TestSaveToFile.cs | 77 +++--- .../TestsBothMethodsAreSimilar.cs | 39 ++- .../TestsParallelMultiply.cs | 120 +++++---- .../TestsSequentialMultiply.cs | 120 +++++---- .../ArgumentParser.cs | 27 +-- .../ParallelMatrixMultiplication/Matrix.cs | 227 ++++++++++-------- .../MatrixMultiplier.cs | 147 ++++++------ .../MatrixUserInterface.cs | 182 +++++++------- .../ParallelMatrixMultiplication/matrixA.txt | 3 - .../ParallelMatrixMultiplication/matrixB.txt | 4 - 11 files changed, 516 insertions(+), 521 deletions(-) delete mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixA.txt delete mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixB.txt diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs index 7a4484f..5008179 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs @@ -2,63 +2,62 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication.Test +namespace ParallelMatrixMultiplication.Test; + +public class TestLoadFromFile { - public class TestLoadFromFile - { - private Matrix firstExpectedMatrix; - private Matrix secondExpectedMatrix; + private Matrix firstExpectedMatrix; + private Matrix secondExpectedMatrix; - [SetUp] - public void Setup() - { - this.firstExpectedMatrix = new Matrix(3, 3); - this.firstExpectedMatrix[0, 0] = 15; - this.firstExpectedMatrix[0, 1] = 16; - this.firstExpectedMatrix[0, 2] = 17; - this.firstExpectedMatrix[1, 0] = 20; - this.firstExpectedMatrix[1, 1] = 23; - this.firstExpectedMatrix[1, 2] = 26; - this.firstExpectedMatrix[2, 0] = 29; - this.firstExpectedMatrix[2, 1] = 32; - this.firstExpectedMatrix[2, 2] = 35; + [SetUp] + public void Setup() + { + this.firstExpectedMatrix = new Matrix(3, 3); + this.firstExpectedMatrix[0, 0] = 15; + this.firstExpectedMatrix[0, 1] = 16; + this.firstExpectedMatrix[0, 2] = 17; + this.firstExpectedMatrix[1, 0] = 20; + this.firstExpectedMatrix[1, 1] = 23; + this.firstExpectedMatrix[1, 2] = 26; + this.firstExpectedMatrix[2, 0] = 29; + this.firstExpectedMatrix[2, 1] = 32; + this.firstExpectedMatrix[2, 2] = 35; - this.secondExpectedMatrix = new Matrix(2, 5); - this.secondExpectedMatrix[0, 0] = 1; - this.secondExpectedMatrix[0, 1] = 2; - this.secondExpectedMatrix[0, 2] = 3; - this.secondExpectedMatrix[0, 3] = 4; - this.secondExpectedMatrix[0, 4] = 5; - this.secondExpectedMatrix[1, 0] = 6; - this.secondExpectedMatrix[1, 1] = 7; - this.secondExpectedMatrix[1, 2] = 8; - this.secondExpectedMatrix[1, 3] = 9; - this.secondExpectedMatrix[1, 4] = 10; - } + this.secondExpectedMatrix = new Matrix(2, 5); + this.secondExpectedMatrix[0, 0] = 1; + this.secondExpectedMatrix[0, 1] = 2; + this.secondExpectedMatrix[0, 2] = 3; + this.secondExpectedMatrix[0, 3] = 4; + this.secondExpectedMatrix[0, 4] = 5; + this.secondExpectedMatrix[1, 0] = 6; + this.secondExpectedMatrix[1, 1] = 7; + this.secondExpectedMatrix[1, 2] = 8; + this.secondExpectedMatrix[1, 3] = 9; + this.secondExpectedMatrix[1, 4] = 10; + } - [Test] - public void LoadFromFile_SquareMatrix_ShouldReturnExpectedResult() + [Test] + public void LoadFromFile_SquareMatrix_ShouldReturnExpectedResult() + { + var result = Matrix.LoadFromFile("firstTestFileForRead.txt"); + for (int i = 0; i < result.Rows; ++i) { - var result = Matrix.LoadFromFile("firstTestFileForRead.txt"); - for (int i = 0; i < result.Rows; ++i) + for (int j = 0; j < result.Columns; ++j) { - for (int j = 0; j < result.Columns; ++j) - { - Assert.That(result[i, j], Is.EqualTo(this.firstExpectedMatrix[i, j])); - } + Assert.That(result[i, j], Is.EqualTo(this.firstExpectedMatrix[i, j])); } } + } - [Test] - public void LoadFromFile_NotSquareMatrix_ShouldReturnExpectedResult() + [Test] + public void LoadFromFile_NotSquareMatrix_ShouldReturnExpectedResult() + { + var result = Matrix.LoadFromFile("secondTestFileForRead.txt"); + for (int i = 0; i < result.Rows; ++i) { - var result = Matrix.LoadFromFile("secondTestFileForRead.txt"); - for (int i = 0; i < result.Rows; ++i) + for (int j = 0; j < result.Columns; ++j) { - for (int j = 0; j < result.Columns; ++j) - { - Assert.That(result[i, j], Is.EqualTo(this.secondExpectedMatrix[i, j])); - } + Assert.That(result[i, j], Is.EqualTo(this.secondExpectedMatrix[i, j])); } } } diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs index 88bd043..bb96d5a 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs @@ -2,53 +2,52 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication.Test +namespace ParallelMatrixMultiplication.Test; + +public class TestSaveToFile { - public class TestSaveToFile - { - private Matrix matrixToSave; - private string currentFilePath; + private Matrix matrixToSave; + private string currentFilePath; - [SetUp] - public void Setup() - { - this.matrixToSave = new Matrix(3, 4); - this.matrixToSave[0, 0] = 99; - this.matrixToSave[0, 1] = 90; - this.matrixToSave[0, 2] = 88; - this.matrixToSave[0, 3] = 80; - this.matrixToSave[1, 0] = 77; - this.matrixToSave[1, 1] = 70; - this.matrixToSave[1, 2] = 66; - this.matrixToSave[1, 3] = 60; - this.matrixToSave[2, 0] = 55; - this.matrixToSave[2, 1] = 50; - this.matrixToSave[2, 2] = 44; - this.matrixToSave[2, 3] = 40; - - this.currentFilePath = "Test_STF.txt"; - } + [SetUp] + public void Setup() + { + this.matrixToSave = new Matrix(3, 4); + this.matrixToSave[0, 0] = 99; + this.matrixToSave[0, 1] = 90; + this.matrixToSave[0, 2] = 88; + this.matrixToSave[0, 3] = 80; + this.matrixToSave[1, 0] = 77; + this.matrixToSave[1, 1] = 70; + this.matrixToSave[1, 2] = 66; + this.matrixToSave[1, 3] = 60; + this.matrixToSave[2, 0] = 55; + this.matrixToSave[2, 1] = 50; + this.matrixToSave[2, 2] = 44; + this.matrixToSave[2, 3] = 40; + + this.currentFilePath = "Test_STF.txt"; + } - [TearDown] - public void Teardown() + [TearDown] + public void Teardown() + { + if (File.Exists(this.currentFilePath)) { - if (File.Exists(this.currentFilePath)) - { - File.Delete(this.currentFilePath); - } + File.Delete(this.currentFilePath); } + } - [Test] - public void SaveToFile_ValidData_ShouldCreateExpectedFile() - { - this.matrixToSave.SaveToFile(this.currentFilePath); + [Test] + public void SaveToFile_ValidData_ShouldCreateExpectedFile() + { + this.matrixToSave.SaveToFile(this.currentFilePath); - Assert.That(File.Exists(this.currentFilePath), Is.True); + Assert.That(File.Exists(this.currentFilePath), Is.True); - string expectedData = File.ReadAllText("expectedForSaveToFileTest.txt"); - string currentData = File.ReadAllText(this.currentFilePath); + string expectedData = File.ReadAllText("expectedForSaveToFileTest.txt"); + string currentData = File.ReadAllText(this.currentFilePath); - Assert.That(currentData, Is.EqualTo(expectedData)); - } + Assert.That(currentData, Is.EqualTo(expectedData)); } } \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsBothMethodsAreSimilar.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsBothMethodsAreSimilar.cs index fca5ec6..0218d7a 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsBothMethodsAreSimilar.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsBothMethodsAreSimilar.cs @@ -2,31 +2,30 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication.Test +namespace ParallelMatrixMultiplication.Test; + +public class TestsBothMethodsAreSimilar { - public class TestsBothMethodsAreSimilar - { - private Matrix testRandomMatrixA; - private Matrix testRandomMatrixB; + private Matrix testRandomMatrixA; + private Matrix testRandomMatrixB; - [SetUp] - public void Setup() - { - this.testRandomMatrixA = Matrix.GenerateRandomMatrix(77, 33); - this.testRandomMatrixB = Matrix.GenerateRandomMatrix(33, 77); - } + [SetUp] + public void Setup() + { + this.testRandomMatrixA = Matrix.GenerateRandomMatrix(77, 33); + this.testRandomMatrixB = Matrix.GenerateRandomMatrix(33, 77); + } - [Test] - public void SequentialAndParallelMultiplication_RandomMatrix_ShouldReturnSameResult() + [Test] + public void SequentialAndParallelMultiplication_RandomMatrix_ShouldReturnSameResult() + { + var parallelResult = MatrixMultiplier.ParallelMultiplication(this.testRandomMatrixA, this.testRandomMatrixB, 4); + var sequentialResult = MatrixMultiplier.SequentialMultiplication(this.testRandomMatrixA, this.testRandomMatrixB); + for (int i = 0; i < parallelResult.Rows; ++i) { - var parallelResult = MatrixMultiplier.ParallelMultiplication(this.testRandomMatrixA, this.testRandomMatrixB, 4); - var sequentialResult = MatrixMultiplier.SequentialMultiplication(this.testRandomMatrixA, this.testRandomMatrixB); - for (int i = 0; i < parallelResult.Rows; ++i) + for (int j = 0; j < parallelResult.Columns; ++j) { - for (int j = 0; j < parallelResult.Columns; ++j) - { - Assert.That(parallelResult[i, j], Is.EqualTo(sequentialResult[i, j])); - } + Assert.That(parallelResult[i, j], Is.EqualTo(sequentialResult[i, j])); } } } diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs index d7b360b..b68329f 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs @@ -2,86 +2,82 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication.Test +namespace ParallelMatrixMultiplication.Test; + +public class TestsParallelMultiply { - public class TestsParallelMultiply - { - private Matrix testMatrixA2x2; - private Matrix testMatrixB2x2; + private Matrix testMatrixA2x2; + private Matrix testMatrixB2x2; - private Matrix testMatrixA2x3; - private Matrix testMatrixB3x2; + private Matrix testMatrixA2x3; + private Matrix testMatrixB3x2; - private Matrix firstExpectedResult; - private Matrix secondExpectedResult; + private Matrix firstExpectedResult; + private Matrix secondExpectedResult; - [SetUp] - public void Setup() + [SetUp] + public void Setup() + { + this.testMatrixA2x2 = Matrix.FillInFromArray(new int[,] { - this.testMatrixA2x2 = new Matrix(2, 2); - this.testMatrixA2x2[0, 0] = 9; - this.testMatrixA2x2[0, 1] = 4; - this.testMatrixA2x2[1, 0] = 5; - this.testMatrixA2x2[1, 1] = 1; + { 9, 4 }, + { 5, 1 }, + }); - this.testMatrixB2x2 = new Matrix(2, 2); - this.testMatrixB2x2[0, 0] = 5; - this.testMatrixB2x2[0, 1] = 3; - this.testMatrixB2x2[1, 0] = 8; - this.testMatrixB2x2[1, 1] = 7; + this.testMatrixB2x2 = Matrix.FillInFromArray(new int[,] + { + { 5, 3 }, + { 8, 7 }, + }); - this.testMatrixA2x3 = new Matrix(2, 3); - this.testMatrixA2x3[0, 0] = 2; - this.testMatrixA2x3[0, 1] = 1; - this.testMatrixA2x3[0, 2] = 0; - this.testMatrixA2x3[1, 0] = 7; - this.testMatrixA2x3[1, 1] = -5; - this.testMatrixA2x3[1, 2] = 6; + this.testMatrixA2x3 = Matrix.FillInFromArray(new int[,] + { + { 2, 1, 0 }, + { 7, -5, 6 }, + }); - this.testMatrixB3x2 = new Matrix(3, 2); - this.testMatrixB3x2[0, 0] = -2; - this.testMatrixB3x2[0, 1] = 6; - this.testMatrixB3x2[1, 0] = 4; - this.testMatrixB3x2[1, 1] = 2; - this.testMatrixB3x2[2, 0] = 3; - this.testMatrixB3x2[2, 1] = 8; + this.testMatrixB3x2 = Matrix.FillInFromArray(new int[,] + { + { -2, 6 }, + { 4, 2 }, + { 3, 8 }, + }); - this.firstExpectedResult = new Matrix(2, 2); - this.firstExpectedResult[0, 0] = 77; - this.firstExpectedResult[0, 1] = 55; - this.firstExpectedResult[1, 0] = 33; - this.firstExpectedResult[1, 1] = 22; + this.firstExpectedResult = Matrix.FillInFromArray(new int[,] + { + { 77, 55 }, + { 33, 22 }, + }); - this.secondExpectedResult = new Matrix(2, 2); - this.secondExpectedResult[0, 0] = 0; - this.secondExpectedResult[0, 1] = 14; - this.secondExpectedResult[1, 0] = -16; - this.secondExpectedResult[1, 1] = 80; - } + this.secondExpectedResult = Matrix.FillInFromArray(new int[,] + { + { 0, 14 }, + { -16, 80 }, + }); + } - [Test] - public void ParallelMultiplication_SquareMatrices_ShouldReturnExpectedResult() + [Test] + public void ParallelMultiplication_SquareMatrices_ShouldReturnExpectedResult() + { + var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x2, this.testMatrixB2x2, 4); + for (int i = 0; i < result.Rows; ++i) { - var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x2, this.testMatrixB2x2, 4); - for (int i = 0; i < result.Rows; ++i) + for (int j = 0; j < result.Columns; ++j) { - for (int j = 0; j < result.Columns; ++j) - { - Assert.That(result[i, j], Is.EqualTo(this.firstExpectedResult[i, j])); - } + Assert.That(result[i, j], Is.EqualTo(this.firstExpectedResult[i, j])); } } + } - [Test] - public void ParallelMultiplication_NotSquareMatrices_ShouldReturnExpectedResult() + [Test] + public void ParallelMultiplication_NotSquareMatrices_ShouldReturnExpectedResult() + { + var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x3, this.testMatrixB3x2, 4); + for (int i = 0; i < result.Rows; ++i) { - var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x3, this.testMatrixB3x2, 4); - for (int i = 0; i < result.Rows; ++i) + for (int j = 0; j < result.Columns; ++j) { - for (int j = 0; j < result.Columns; ++j) - { - Assert.That(result[i, j], Is.EqualTo(this.secondExpectedResult[i, j])); - } + Assert.That(result[i, j], Is.EqualTo(this.secondExpectedResult[i, j])); } } } diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs index a0acebd..0b03f31 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs @@ -2,86 +2,82 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication.Test +namespace ParallelMatrixMultiplication.Test; + +public class TestsSequentialMultiply { - public class TestsSequentialMultiply - { - private Matrix testMatrixA2x2; - private Matrix testMatrixB2x2; + private Matrix testMatrixA2x2; + private Matrix testMatrixB2x2; - private Matrix testMatrixA2x3; - private Matrix testMatrixB3x2; + private Matrix testMatrixA2x3; + private Matrix testMatrixB3x2; - private Matrix firstExpectedResult; - private Matrix secondExpectedResult; + private Matrix firstExpectedResult; + private Matrix secondExpectedResult; - [SetUp] - public void Setup() + [SetUp] + public void Setup() + { + this.testMatrixA2x2 = Matrix.FillInFromArray(new int[,] { - this.testMatrixA2x2 = new Matrix(2, 2); - this.testMatrixA2x2[0, 0] = 1; - this.testMatrixA2x2[0, 1] = 2; - this.testMatrixA2x2[1, 0] = 3; - this.testMatrixA2x2[1, 1] = 4; + { 1, 2 }, + { 3, 4 }, + }); - this.testMatrixB2x2 = new Matrix(2, 2); - this.testMatrixB2x2[0, 0] = 9; - this.testMatrixB2x2[0, 1] = 8; - this.testMatrixB2x2[1, 0] = 7; - this.testMatrixB2x2[1, 1] = 6; + this.testMatrixB2x2 = Matrix.FillInFromArray(new int[,] + { + { 9, 8 }, + { 7, 6 }, + }); - this.testMatrixA2x3 = new Matrix(2, 3); - this.testMatrixA2x3[0, 0] = 2; - this.testMatrixA2x3[0, 1] = -3; - this.testMatrixA2x3[0, 2] = 1; - this.testMatrixA2x3[1, 0] = 5; - this.testMatrixA2x3[1, 1] = 4; - this.testMatrixA2x3[1, 2] = -2; + this.testMatrixA2x3 = Matrix.FillInFromArray(new int[,] + { + { 2, -3, 1 }, + { 5, 4, -2 }, + }); - this.testMatrixB3x2 = new Matrix(3, 2); - this.testMatrixB3x2[0, 0] = -7; - this.testMatrixB3x2[0, 1] = 5; - this.testMatrixB3x2[1, 0] = 2; - this.testMatrixB3x2[1, 1] = -1; - this.testMatrixB3x2[2, 0] = 4; - this.testMatrixB3x2[2, 1] = 3; + this.testMatrixB3x2 = Matrix.FillInFromArray(new int[,] + { + { -7, 5 }, + { 2, -1 }, + { 4, 3 }, + }); - this.firstExpectedResult = new Matrix(2, 2); - this.firstExpectedResult[0, 0] = 23; - this.firstExpectedResult[0, 1] = 20; - this.firstExpectedResult[1, 0] = 55; - this.firstExpectedResult[1, 1] = 48; + this.firstExpectedResult = Matrix.FillInFromArray(new int[,] + { + { 23, 20 }, + { 55, 48 }, + }); - this.secondExpectedResult = new Matrix(2, 2); - this.secondExpectedResult[0, 0] = -16; - this.secondExpectedResult[0, 1] = 16; - this.secondExpectedResult[1, 0] = -35; - this.secondExpectedResult[1, 1] = 15; - } + this.secondExpectedResult = Matrix.FillInFromArray(new int[,] + { + { -16, 16 }, + { -35, 15 }, + }); + } - [Test] - public void SequentialMultiplication_SquareMatrices_ShouldReturnExpectedResult() + [Test] + public void SequentialMultiplication_SquareMatrices_ShouldReturnExpectedResult() + { + var result = MatrixMultiplier.SequentialMultiplication(this.testMatrixA2x2, this.testMatrixB2x2); + for (int i = 0; i < result.Rows; ++i) { - var result = MatrixMultiplier.SequentialMultiplication(this.testMatrixA2x2, this.testMatrixB2x2); - for (int i = 0; i < result.Rows; ++i) + for (int j = 0; j < result.Columns; ++j) { - for (int j = 0; j < result.Columns; ++j) - { - Assert.That(result[i, j], Is.EqualTo(this.firstExpectedResult[i, j])); - } + Assert.That(result[i, j], Is.EqualTo(this.firstExpectedResult[i, j])); } } + } - [Test] - public void SequentialMultiplication_NotSquareMatrices_ShouldReturnExpectedResult() + [Test] + public void SequentialMultiplication_NotSquareMatrices_ShouldReturnExpectedResult() + { + var result = MatrixMultiplier.SequentialMultiplication(this.testMatrixA2x3, this.testMatrixB3x2); + for (int i = 0; i < result.Rows; ++i) { - var result = MatrixMultiplier.SequentialMultiplication(this.testMatrixA2x3, this.testMatrixB3x2); - for (int i = 0; i < result.Rows; ++i) + for (int j = 0; j < result.Columns; ++j) { - for (int j = 0; j < result.Columns; ++j) - { - Assert.That(result[i, j], Is.EqualTo(this.secondExpectedResult[i, j])); - } + Assert.That(result[i, j], Is.EqualTo(this.secondExpectedResult[i, j])); } } } diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs index 05a7e79..580a31c 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs @@ -2,23 +2,22 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication +namespace ParallelMatrixMultiplication; + +/// +/// A class for working with command line arguments. +/// +public static class ArgumentParser { /// - /// A class for working with command line arguments. + /// Analyzes the command line arguments and determines the execution mode. /// - public static class ArgumentParser + /// An array of command line arguments. + /// A tuple containing the execution mode and an array of parameters. + public static (string Mode, string[] Parametrs) Parse(string[] args) { - /// - /// Analyzes the command line arguments and determines the execution mode. - /// - /// An array of command line arguments. - /// A tuple containing the execution mode and an array of parameters. - public static (string Mode, string[] Parametrs) Parse(string[] args) - { - string mode = args[0].ToLower(); - string[] parametrs = args.Skip(1).ToArray(); - return (mode, parametrs); - } + string mode = args[0].ToLower(); + string[] parametrs = args.Skip(1).ToArray(); + return (mode, parametrs); } } diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs index 615baf0..3523390 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs @@ -2,138 +2,157 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication +namespace ParallelMatrixMultiplication; + +/// +/// A class representing a matrix and operations for working with it. +/// +/// +/// Initializes a new instance of the class. +/// +/// The number of specified rows. +/// The number of specified columns. +public class Matrix(int rows, int columns) { /// - /// A class representing a matrix and operations for working with it. + /// An array for storing matrix elements. /// - /// - /// Initializes a new instance of the class. - /// - /// The number of specified rows. - /// The number of specified columns. - public class Matrix(int rows, int columns) + private readonly int[,] numbers = new int[rows, columns]; + + /// + /// Gets number of rows in the matrix. + /// + public int Rows { get; private set; } = rows; + + /// + /// Gets number of columns in the matrix. + /// + public int Columns { get; private set; } = columns; + + /// + /// Indexer for accessing matrix elements. + /// + /// Row index. + /// Column index. + /// The value of the element. + public int this[int rows, int columns] { - /// - /// An array for storing matrix elements. - /// - private readonly int[,] numbers = new int[rows, columns]; - - /// - /// Gets number of rows in the matrix. - /// - public int Rows { get; private set; } = rows; - - /// - /// Gets number of columns in the matrix. - /// - public int Columns { get; private set; } = columns; - - /// - /// Indexer for accessing matrix elements. - /// - /// Row index. - /// Column index. - /// The value of the element. - public int this[int rows, int columns] - { - get => this.numbers[rows, columns]; - set => this.numbers[rows, columns] = value; - } + get => this.numbers[rows, columns]; + set => this.numbers[rows, columns] = value; + } - /// - /// A method for generating a matrix with random values. - /// - /// Number of lines. - /// Number of columns. - /// Matrix with random values. - public static Matrix GenerateRandomMatrix(int rows, int columns) + /// + /// A method for generating a matrix with random values. + /// + /// Number of lines. + /// Number of columns. + /// Matrix with random values. + public static Matrix GenerateRandomMatrix(int rows, int columns) + { + Random random = new Random(); + Matrix matrix = new Matrix(rows, columns); + for (int i = 0; i < rows; i++) { - Random random = new Random(); - Matrix matrix = new Matrix(rows, columns); - for (int i = 0; i < rows; i++) + for (int j = 0; j < columns; ++j) { - for (int j = 0; j < columns; ++j) - { - matrix[i, j] = random.Next(1, 74); - } + matrix[i, j] = random.Next(1, 74); } - - return matrix; } - /// - /// A method for loading a matrix from a file. - /// - /// The path to the matrix file. - /// The matrix from the file. - /// It is thrown if the file is not found. - /// It is thrown if the file is empty or contains incorrect data. - /// It is thrown if the numbers in the file have an incorrect format. - public static Matrix LoadFromFile(string filePath) + return matrix; + } + + /// + /// A method for loading a matrix from a file. + /// + /// The path to the matrix file. + /// The matrix from the file. + /// It is thrown if the file is not found. + /// It is thrown if the file is empty or contains incorrect data. + /// It is thrown if the numbers in the file have an incorrect format. + public static Matrix LoadFromFile(string filePath) + { + if (!File.Exists(filePath)) { - if (!File.Exists(filePath)) - { - throw new FileNotFoundException($"Файл {filePath} не найден"); - } + throw new FileNotFoundException($"Файл {filePath} не найден"); + } - string[] lines = File.ReadAllLines(filePath); + string[] lines = File.ReadAllLines(filePath); - if (lines.Length == 0) - { - throw new InvalidDataException("Файл пуст"); - } + if (lines.Length == 0) + { + throw new InvalidDataException("Файл пуст"); + } + + int rows = lines.Length; - int rows = lines.Length; + string[] firstRowValues = lines[0].Split(' ', StringSplitOptions.RemoveEmptyEntries); + int columnsSize = firstRowValues.Length; - string[] firstRowValues = lines[0].Split(' ', StringSplitOptions.RemoveEmptyEntries); - int columnsSize = firstRowValues.Length; + Matrix matrix = new Matrix(rows, columnsSize); - Matrix matrix = new Matrix(rows, columnsSize); + for (int i = 0; i < rows; ++i) + { + string[] values = lines[i].Split(' ', StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < rows; ++i) + if (values.Length != columnsSize) { - string[] values = lines[i].Split(' ', StringSplitOptions.RemoveEmptyEntries); + throw new InvalidDataException("Строка имеет некорректное значение стобцов"); + } - if (values.Length != columnsSize) + for (int j = 0; j < columnsSize; ++j) + { + if (!int.TryParse(values[j], out int parsedValue)) { - throw new InvalidDataException("Строка имеет некорректное значение стобцов"); + throw new FormatException("Неверный формат числа в строке"); } - for (int j = 0; j < columnsSize; ++j) - { - if (!int.TryParse(values[j], out int parsedValue)) - { - throw new FormatException("Неверный формат числа в строке"); - } - - matrix[i, j] = parsedValue; - } + matrix[i, j] = parsedValue; } + } + + return matrix; + } + + /// + /// Method for creating a matrix form array of values. + /// + /// Array. + /// Matrix with values from array. + public static Matrix FillInFromArray(int[,] data) + { + int rows = data.GetLength(0); + int columns = data.GetLength(1); + Matrix matrix = new Matrix(rows, columns); - return matrix; + for (int i = 0; i < rows; ++i) + { + for (int j = 0; j < columns; ++j) + { + matrix[i, j] = data[i, j]; + } } - /// - /// A method for saving a matrix to a file. - /// - /// The path to save the file. - public void SaveToFile(string filePath) + return matrix; + } + + /// + /// A method for saving a matrix to a file. + /// + /// The path to save the file. + public void SaveToFile(string filePath) + { + using StreamWriter writer = new StreamWriter(filePath); + for (int i = 0; i < this.Rows; i++) { - using (StreamWriter writer = new StreamWriter(filePath)) + for (int j = 0; j < this.Columns; j++) { - for (int i = 0; i < this.Rows; i++) - { - for (int j = 0; j < this.Columns; j++) - { - writer.Write(this.numbers[i, j] + (j == this.Columns - 1 ? string.Empty : " ")); - } - - if (i < this.Rows - 1) - { - writer.WriteLine(); - } - } + writer.Write(this.numbers[i, j] + (j == this.Columns - 1 ? string.Empty : " ")); + } + + if (i < this.Rows - 1) + { + writer.WriteLine(); } } } diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs index 42d417b..3e28752 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs @@ -2,104 +2,103 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication +namespace ParallelMatrixMultiplication; + +/// +/// A class for performing matrix multiplication in sequential and parallel ways. +/// +public class MatrixMultiplier { /// - /// A class for performing matrix multiplication in sequential and parallel ways. + /// Performs sequential multiplication of two matrices(AxB). /// - public class MatrixMultiplier + /// The first matrix. + /// The second matrix. + /// The resulting matrix. + /// It is thrown if the number of columns of the first + /// matrix is not equal to the number of rows of the second. + /// + public static Matrix SequentialMultiplication(Matrix a, Matrix b) { - /// - /// Performs sequential multiplication of two matrices(AxB). - /// - /// The first matrix. - /// The second matrix. - /// The resulting matrix. - /// It is thrown if the number of columns of the first - /// matrix is not equal to the number of rows of the second. - /// - public static Matrix SequentialMultiplication(Matrix a, Matrix b) + if (a.Columns != b.Rows) { - if (a.Columns != b.Rows) - { - throw new InvalidDataException("Умножение невозможно(количество столбцов первой матрицы не равно количеству строк второй)"); - } + throw new InvalidDataException("Умножение невозможно(количество столбцов первой матрицы не равно количеству строк второй)"); + } - Matrix result = new Matrix(a.Rows, b.Columns); - for (int i = 0; i < a.Rows; ++i) + Matrix result = new Matrix(a.Rows, b.Columns); + for (int i = 0; i < a.Rows; ++i) + { + for (int j = 0; j < b.Columns; j++) { - for (int j = 0; j < b.Columns; j++) + int sum = 0; + for (int k = 0; k < a.Columns; k++) { - int sum = 0; - for (int k = 0; k < a.Columns; k++) - { - sum += a[i, k] * b[k, j]; - } - - result[i, j] = sum; + sum += a[i, k] * b[k, j]; } - } - return result; + result[i, j] = sum; + } } - /// - /// Performs parallel multiplication of two matrices(AxB). - /// - /// The first matrix. - /// The second matrix. - /// Number of threads. - /// The resulting matrix. - /// It is thrown if the number of columns of the first - /// matrix is not equal to the number of rows of the second. - /// - public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) + return result; + } + + /// + /// Performs parallel multiplication of two matrices(AxB). + /// + /// The first matrix. + /// The second matrix. + /// Number of threads. + /// The resulting matrix. + /// It is thrown if the number of columns of the first + /// matrix is not equal to the number of rows of the second. + /// + public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) + { + if (a.Columns != b.Rows) { - if (a.Columns != b.Rows) - { - throw new InvalidDataException("Умножение невозможно(количество столбцов первой матрицы не равно количеству строк второй)"); - } + throw new InvalidDataException("Умножение невозможно(количество столбцов первой матрицы не равно количеству строк второй)"); + } - Matrix result = new Matrix(a.Rows, b.Columns); + Matrix result = new Matrix(a.Rows, b.Columns); - int actualNumOfThread = Math.Min(a.Rows, numThreads); - Thread[] threads = new Thread[actualNumOfThread]; - int rowsForThread = a.Rows / actualNumOfThread; + int actualNumOfThread = Math.Min(a.Rows, numThreads); + Thread[] threads = new Thread[actualNumOfThread]; + int rowsForThread = a.Rows / actualNumOfThread; - for (int i = 0; i < actualNumOfThread; ++i) - { - int startRow = i * rowsForThread; - int endRow = (i == actualNumOfThread - 1) ? a.Rows : (i + 1) * rowsForThread; + for (int i = 0; i < actualNumOfThread; ++i) + { + int startRow = i * rowsForThread; + int endRow = (i == actualNumOfThread - 1) ? a.Rows : (i + 1) * rowsForThread; - threads[i] = new Thread(() => + threads[i] = new Thread(() => + { + for (int row = startRow; row < endRow; row++) { - for (int row = startRow; row < endRow; row++) + for (int columns = 0; columns < b.Columns; columns++) { - for (int columns = 0; columns < b.Columns; columns++) + int sum = 0; + for (int k = 0; k < a.Columns; ++k) { - int sum = 0; - for (int k = 0; k < a.Columns; ++k) - { - sum += a[row, k] * b[k, columns]; - } - - result[row, columns] = sum; + sum += a[row, k] * b[k, columns]; } - } - }); - } - foreach (var thread in threads) - { - thread.Start(); - } + result[row, columns] = sum; + } + } + }); + } - foreach (var thread in threads) - { - thread.Join(); - } + foreach (var thread in threads) + { + thread.Start(); + } - return result; + foreach (var thread in threads) + { + thread.Join(); } + + return result; } } \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs index b01efee..942eb6a 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixUserInterface.cs @@ -2,120 +2,116 @@ // Copyright (c) Kalinin Andrew. All rights reserved. // -namespace ParallelMatrixMultiplication -{ - using System.Diagnostics; +namespace ParallelMatrixMultiplication; + +using System.Diagnostics; +/// +/// A user interface class for working with matrix multiplication. +/// +public static class MatrixUserInterface +{ /// - /// A user interface class for working with matrix multiplication. + /// Loads matrices from files, performs sequential and parallel multiplication, + /// and saves the results to files, as well as additionally measures execution time. /// - public class MatrixUserInterface + /// The path to the first matrix. + /// The path to the second matrix. + /// The path to the sequential result matrix. + /// The path to the parallel result matrix. + public static void LoadFromFileAndMultiply(string pathA, string pathB, string sequentialSavePath, string parallelSavePath) { - /// - /// Loads matrices from files, performs sequential and parallel multiplication, - /// and saves the results to files, as well as additionally measures execution time. - /// - /// The path to the first matrix. - /// The path to the second matrix. - /// The path to the sequential result matrix. - /// The path to the parallel result matrix. - public static void LoadFromFileAndMultiply(string pathA, string pathB, string sequentialSavePath, string parallelSavePath) - { - Matrix first = Matrix.LoadFromFile(pathA); - Matrix second = Matrix.LoadFromFile(pathB); + Matrix first = Matrix.LoadFromFile(pathA); + Matrix second = Matrix.LoadFromFile(pathB); - Stopwatch stopwatch = Stopwatch.StartNew(); - Matrix sequentialResult = MatrixMultiplier.SequentialMultiplication(first, second); - stopwatch.Stop(); - Console.WriteLine($"\nПоследовательное умножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); + Stopwatch stopwatch = Stopwatch.StartNew(); + Matrix sequentialResult = MatrixMultiplier.SequentialMultiplication(first, second); + stopwatch.Stop(); + Console.WriteLine($"\nПоследовательное умножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); - sequentialResult.SaveToFile(sequentialSavePath); + sequentialResult.SaveToFile(sequentialSavePath); - int numOfThreads = Environment.ProcessorCount; - Console.WriteLine($"\nПараллельное умножение c {numOfThreads} потоками:"); - stopwatch.Restart(); - Matrix parallelResult = MatrixMultiplier.ParallelMultiplication(first, second, numOfThreads); - stopwatch.Stop(); - Console.WriteLine($"\nПараллельное уммножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); + int numOfThreads = Environment.ProcessorCount; + Console.WriteLine($"\nПараллельное умножение c {numOfThreads} потоками:"); + stopwatch.Restart(); + Matrix parallelResult = MatrixMultiplier.ParallelMultiplication(first, second, numOfThreads); + stopwatch.Stop(); + Console.WriteLine($"\nПараллельное уммножение завершено. Время: {stopwatch.ElapsedMilliseconds} мс"); - parallelResult.SaveToFile(parallelSavePath); - } + parallelResult.SaveToFile(parallelSavePath); + } - /// - /// Performs performance testing of sequential and parallel matrix multiplication - /// for various matrix sizes with a set number of runs. - /// - /// The number of runs for each test. - public static void UsersMatrixTests(int n) + /// + /// Performs performance testing of sequential and parallel matrix multiplication + /// for various matrix sizes with a set number of runs. + /// + /// The number of runs for each test. + public static void UsersMatrixTests(int n) + { + var testCases = new List<(int RowsA, int ColumnsA, int RowsB, int ColumnsB)>() { - var testCases = new List<(int RowsA, int ColumnsA, int RowsB, int ColumnsB)>() - { - (100, 100, 100, 100), - (200, 200, 200, 200), - (300, 300, 300, 300), - (400, 400, 400, 400), - (500, 500, 500, 500), - }; - - Console.WriteLine($"Проведение тестирования с {n} запусками"); - Console.WriteLine("\nРазмеры матриц | " + - "Матожидание(последовательное) | " + - "СКО(последовательное) | " + - "Матожидание(параллельное) | " + - "СКО(параллельное) \n"); - - foreach (var testCase in testCases) - { - int rowsA = testCase.RowsA; - int columnsA = testCase.ColumnsA; - int rowsB = testCase.RowsB; - int columnsB = testCase.ColumnsB; - - Matrix matrixA = Matrix.GenerateRandomMatrix(rowsA, columnsA); - Matrix matrixB = Matrix.GenerateRandomMatrix(rowsB, columnsB); + (100, 100, 100, 100), + (200, 200, 200, 200), + (300, 300, 300, 300), + (400, 400, 400, 400), + (500, 500, 500, 500), + }; + + Console.WriteLine($"Проведение тестирования с {n} запусками"); + Console.WriteLine("\nРазмеры матриц | " + + "Матожидание(последовательное) | " + + "СКО(последовательное) | " + + "Матожидание(параллельное) | " + + "СКО(параллельное) \n"); + + foreach (var testCase in testCases) + { + int rowsA = testCase.RowsA; + int columnsA = testCase.ColumnsA; + int rowsB = testCase.RowsB; + int columnsB = testCase.ColumnsB; - var sequentialTimes = new List(); - var parallelTimes = new List(); + Matrix matrixA = Matrix.GenerateRandomMatrix(rowsA, columnsA); + Matrix matrixB = Matrix.GenerateRandomMatrix(rowsB, columnsB); - int numOfThreads = Environment.ProcessorCount; + var sequentialTimes = new List(); + var parallelTimes = new List(); - for (int i = 0; i < n; ++i) - { - Stopwatch stopwatch = Stopwatch.StartNew(); - MatrixMultiplier.SequentialMultiplication(matrixA, matrixB); - stopwatch.Stop(); - sequentialTimes.Add(stopwatch.Elapsed.TotalMilliseconds); + int numOfThreads = Environment.ProcessorCount; - stopwatch.Restart(); - MatrixMultiplier.ParallelMultiplication(matrixA, matrixB, numOfThreads); - stopwatch.Stop(); - parallelTimes.Add(stopwatch.Elapsed.TotalMilliseconds); - } + for (int i = 0; i < n; ++i) + { + Stopwatch stopwatch = Stopwatch.StartNew(); + MatrixMultiplier.SequentialMultiplication(matrixA, matrixB); + stopwatch.Stop(); + sequentialTimes.Add(stopwatch.Elapsed.TotalMilliseconds); + + stopwatch.Restart(); + MatrixMultiplier.ParallelMultiplication(matrixA, matrixB, numOfThreads); + stopwatch.Stop(); + parallelTimes.Add(stopwatch.Elapsed.TotalMilliseconds); + } - double sequentialExpectation = CalculateMathematicalExpectation(sequentialTimes); - double parallelExpectation = CalculateMathematicalExpectation(parallelTimes); + double sequentialExpectation = CalculateMathematicalExpectation(sequentialTimes); + double parallelExpectation = CalculateMathematicalExpectation(parallelTimes); - double sequentialStandardDeviation = CalculateStandardDeviation(sequentialTimes, sequentialExpectation); - double parallelStandardDeviation = CalculateStandardDeviation(parallelTimes, parallelExpectation); + double sequentialStandardDeviation = CalculateStandardDeviation(sequentialTimes, sequentialExpectation); + double parallelStandardDeviation = CalculateStandardDeviation(parallelTimes, parallelExpectation); - Console.WriteLine($"{rowsA}x{columnsA} * {rowsB}x{columnsB} | {sequentialExpectation:F2} мс | {sequentialStandardDeviation:F2} | {parallelExpectation:F2} | {parallelStandardDeviation:F2}\n"); - } + Console.WriteLine($"{rowsA}x{columnsA} * {rowsB}x{columnsB} | {sequentialExpectation:F2} мс | {sequentialStandardDeviation:F2} | {parallelExpectation:F2} | {parallelStandardDeviation:F2}\n"); } + } - private static double CalculateMathematicalExpectation(List values) - { - return values.Sum() / values.Count; - } + private static double CalculateMathematicalExpectation(List values) => values.Sum() / values.Count; - private static double CalculateStandardDeviation(List values, double expectation) + private static double CalculateStandardDeviation(List values, double expectation) + { + double sumOfSquares = 0; + foreach (double value in values) { - double sumOfSquares = 0; - foreach (double value in values) - { - sumOfSquares += (value - expectation) * (value - expectation); - } - - return Math.Sqrt(sumOfSquares / values.Count); + sumOfSquares += (value - expectation) * (value - expectation); } + + return Math.Sqrt(sumOfSquares / values.Count); } } \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixA.txt b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixA.txt deleted file mode 100644 index 217c474..0000000 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixA.txt +++ /dev/null @@ -1,3 +0,0 @@ -1 2 3 4 -5 -6 7 8 -9 -10 -11 -12 \ No newline at end of file diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixB.txt b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixB.txt deleted file mode 100644 index 15c198b..0000000 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/matrixB.txt +++ /dev/null @@ -1,4 +0,0 @@ -1 2 --3 4 -5 6 -7 -8 \ No newline at end of file From 3c1d0423e6e8c52b98daf4118055d6db0dce471f Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sun, 30 Nov 2025 02:24:43 +0300 Subject: [PATCH 12/15] refactor: processed an attempt to launch the application without input data --- .../ParallelMatrixMultiplication/ArgumentParser.cs | 5 +++++ .../ParallelMatrixMultiplication/Program.cs | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs index 580a31c..a321136 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/ArgumentParser.cs @@ -16,6 +16,11 @@ public static class ArgumentParser /// A tuple containing the execution mode and an array of parameters. public static (string Mode, string[] Parametrs) Parse(string[] args) { + if (args == null || args.Length == 0) + { + throw new ArgumentException("Укажите режим работы ('load' или 'matrixTest')"); + } + string mode = args[0].ToLower(); string[] parametrs = args.Skip(1).ToArray(); return (mode, parametrs); diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs index 7aa822a..7ff2eb9 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Program.cs @@ -5,6 +5,12 @@ using ParallelMatrixMultiplication; args = Environment.GetCommandLineArgs().Skip(1).ToArray(); + +if (args.Length == 0) +{ + Console.WriteLine("\n Укажите режим работы ('load' или 'matrixTest')"); + return; +} var (choice, parameters) = ArgumentParser.Parse(args); try From 9bb21c9145f50b80d7139adcbe0d2958a4eed3d6 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sun, 30 Nov 2025 02:25:39 +0300 Subject: [PATCH 13/15] add: photo of the results of an experiment to run matrix multiplication --- .../resultOfTheExperiment.png | Bin 0 -> 18243 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ParallelMatrixMultiplication/ParallelMatrixMultiplication/resultOfTheExperiment.png diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/resultOfTheExperiment.png b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/resultOfTheExperiment.png new file mode 100644 index 0000000000000000000000000000000000000000..174583c42de6f47212819ec34191aab75575fea8 GIT binary patch literal 18243 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 E0IcJ#@&Et; literal 0 HcmV?d00001 From ca5050e52715f1337ea00553f463f3f903bbde81 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sun, 30 Nov 2025 02:29:12 +0300 Subject: [PATCH 14/15] refactor: added a "Environment.ProcessorCount" in a parallel multiply tests. --- .../TestsParallelMultiply.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs index b68329f..d856697 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs @@ -59,7 +59,7 @@ public void Setup() [Test] public void ParallelMultiplication_SquareMatrices_ShouldReturnExpectedResult() { - var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x2, this.testMatrixB2x2, 4); + var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x2, this.testMatrixB2x2, Environment.ProcessorCount); for (int i = 0; i < result.Rows; ++i) { for (int j = 0; j < result.Columns; ++j) @@ -72,7 +72,7 @@ public void ParallelMultiplication_SquareMatrices_ShouldReturnExpectedResult() [Test] public void ParallelMultiplication_NotSquareMatrices_ShouldReturnExpectedResult() { - var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x3, this.testMatrixB3x2, 4); + var result = MatrixMultiplier.ParallelMultiplication(this.testMatrixA2x3, this.testMatrixB3x2, Environment.ProcessorCount); for (int i = 0; i < result.Rows; ++i) { for (int j = 0; j < result.Columns; ++j) From 6e7c9fa28f4e1cdf88b7a0d985e861b8c8f38b19 Mon Sep 17 00:00:00 2001 From: Andrew Kalinin Date: Sun, 21 Dec 2025 20:31:31 +0300 Subject: [PATCH 15/15] refactor: added all the corrections requested by the reviewer --- .../TestLoadFromFile.cs | 32 +++------ .../TestSaveToFile.cs | 19 ++--- .../TestsParallelMultiply.cs | 12 ++-- .../TestsSequentialMultiply.cs | 12 ++-- .../ParallelMatrixMultiplication/Matrix.cs | 72 +++++++++---------- .../MatrixMultiplier.cs | 14 ++-- 6 files changed, 69 insertions(+), 92 deletions(-) diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs index 5008179..bcc7691 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestLoadFromFile.cs @@ -12,28 +12,18 @@ public class TestLoadFromFile [SetUp] public void Setup() { - this.firstExpectedMatrix = new Matrix(3, 3); - this.firstExpectedMatrix[0, 0] = 15; - this.firstExpectedMatrix[0, 1] = 16; - this.firstExpectedMatrix[0, 2] = 17; - this.firstExpectedMatrix[1, 0] = 20; - this.firstExpectedMatrix[1, 1] = 23; - this.firstExpectedMatrix[1, 2] = 26; - this.firstExpectedMatrix[2, 0] = 29; - this.firstExpectedMatrix[2, 1] = 32; - this.firstExpectedMatrix[2, 2] = 35; + this.firstExpectedMatrix = new Matrix(new int[,] + { + { 15, 16, 17 }, + { 20, 23, 26 }, + { 29, 32, 35 }, + }); - this.secondExpectedMatrix = new Matrix(2, 5); - this.secondExpectedMatrix[0, 0] = 1; - this.secondExpectedMatrix[0, 1] = 2; - this.secondExpectedMatrix[0, 2] = 3; - this.secondExpectedMatrix[0, 3] = 4; - this.secondExpectedMatrix[0, 4] = 5; - this.secondExpectedMatrix[1, 0] = 6; - this.secondExpectedMatrix[1, 1] = 7; - this.secondExpectedMatrix[1, 2] = 8; - this.secondExpectedMatrix[1, 3] = 9; - this.secondExpectedMatrix[1, 4] = 10; + this.secondExpectedMatrix = new Matrix(new int[,] + { + { 1, 2, 3, 4, 5 }, + { 6, 7, 8, 9, 10 }, + }); } [Test] diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs index bb96d5a..1e4cd5a 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestSaveToFile.cs @@ -12,19 +12,12 @@ public class TestSaveToFile [SetUp] public void Setup() { - this.matrixToSave = new Matrix(3, 4); - this.matrixToSave[0, 0] = 99; - this.matrixToSave[0, 1] = 90; - this.matrixToSave[0, 2] = 88; - this.matrixToSave[0, 3] = 80; - this.matrixToSave[1, 0] = 77; - this.matrixToSave[1, 1] = 70; - this.matrixToSave[1, 2] = 66; - this.matrixToSave[1, 3] = 60; - this.matrixToSave[2, 0] = 55; - this.matrixToSave[2, 1] = 50; - this.matrixToSave[2, 2] = 44; - this.matrixToSave[2, 3] = 40; + this.matrixToSave = new Matrix(new int[,] + { + { 99, 90, 88, 80 }, + { 77, 70, 66, 60 }, + { 55, 50, 44, 40 }, + }); this.currentFilePath = "Test_STF.txt"; } diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs index d856697..467136c 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsParallelMultiply.cs @@ -18,38 +18,38 @@ public class TestsParallelMultiply [SetUp] public void Setup() { - this.testMatrixA2x2 = Matrix.FillInFromArray(new int[,] + this.testMatrixA2x2 = new Matrix(new int[,] { { 9, 4 }, { 5, 1 }, }); - this.testMatrixB2x2 = Matrix.FillInFromArray(new int[,] + this.testMatrixB2x2 = new Matrix(new int[,] { { 5, 3 }, { 8, 7 }, }); - this.testMatrixA2x3 = Matrix.FillInFromArray(new int[,] + this.testMatrixA2x3 = new Matrix(new int[,] { { 2, 1, 0 }, { 7, -5, 6 }, }); - this.testMatrixB3x2 = Matrix.FillInFromArray(new int[,] + this.testMatrixB3x2 = new Matrix(new int[,] { { -2, 6 }, { 4, 2 }, { 3, 8 }, }); - this.firstExpectedResult = Matrix.FillInFromArray(new int[,] + this.firstExpectedResult = new Matrix(new int[,] { { 77, 55 }, { 33, 22 }, }); - this.secondExpectedResult = Matrix.FillInFromArray(new int[,] + this.secondExpectedResult = new Matrix(new int[,] { { 0, 14 }, { -16, 80 }, diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs index 0b03f31..1cbf703 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication.Test/TestsSequentialMultiply.cs @@ -18,38 +18,38 @@ public class TestsSequentialMultiply [SetUp] public void Setup() { - this.testMatrixA2x2 = Matrix.FillInFromArray(new int[,] + this.testMatrixA2x2 = new Matrix(new int[,] { { 1, 2 }, { 3, 4 }, }); - this.testMatrixB2x2 = Matrix.FillInFromArray(new int[,] + this.testMatrixB2x2 = new Matrix(new int[,] { { 9, 8 }, { 7, 6 }, }); - this.testMatrixA2x3 = Matrix.FillInFromArray(new int[,] + this.testMatrixA2x3 = new Matrix(new int[,] { { 2, -3, 1 }, { 5, 4, -2 }, }); - this.testMatrixB3x2 = Matrix.FillInFromArray(new int[,] + this.testMatrixB3x2 = new Matrix(new int[,] { { -7, 5 }, { 2, -1 }, { 4, 3 }, }); - this.firstExpectedResult = Matrix.FillInFromArray(new int[,] + this.firstExpectedResult = new Matrix(new int[,] { { 23, 20 }, { 55, 48 }, }); - this.secondExpectedResult = Matrix.FillInFromArray(new int[,] + this.secondExpectedResult = new Matrix(new int[,] { { -16, 16 }, { -35, 15 }, diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs index 3523390..bf31fa7 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/Matrix.cs @@ -7,27 +7,45 @@ namespace ParallelMatrixMultiplication; /// /// A class representing a matrix and operations for working with it. /// -/// -/// Initializes a new instance of the class. -/// -/// The number of specified rows. -/// The number of specified columns. -public class Matrix(int rows, int columns) +public class Matrix { /// /// An array for storing matrix elements. /// - private readonly int[,] numbers = new int[rows, columns]; + private readonly int[,] numbers; + + /// + /// Initializes a new instance of the class. + /// + /// The number of specified rows. + /// The number of specified columns. + public Matrix(int rows, int columns) + { + this.numbers = new int[rows, columns]; + this.Rows = rows; + this.Columns = columns; + } + + /// + /// Initializes a new instance of the class from a 2D array. + /// + /// The 2D array containing matrix values. + public Matrix(int[,] data) + { + this.Rows = data.GetLength(0); + this.Columns = data.GetLength(1); + this.numbers = (int[,])data.Clone(); + } /// /// Gets number of rows in the matrix. /// - public int Rows { get; private set; } = rows; + public int Rows { get; private set; } /// /// Gets number of columns in the matrix. /// - public int Columns { get; private set; } = columns; + public int Columns { get; private set; } /// /// Indexer for accessing matrix elements. @@ -38,7 +56,6 @@ public class Matrix(int rows, int columns) public int this[int rows, int columns] { get => this.numbers[rows, columns]; - set => this.numbers[rows, columns] = value; } /// @@ -50,16 +67,16 @@ public class Matrix(int rows, int columns) public static Matrix GenerateRandomMatrix(int rows, int columns) { Random random = new Random(); - Matrix matrix = new Matrix(rows, columns); + int[,] data = new int[rows, columns]; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; ++j) { - matrix[i, j] = random.Next(1, 74); + data[i, j] = random.Next(1, 74); } } - return matrix; + return new Matrix(data); } /// @@ -89,8 +106,7 @@ public static Matrix LoadFromFile(string filePath) string[] firstRowValues = lines[0].Split(' ', StringSplitOptions.RemoveEmptyEntries); int columnsSize = firstRowValues.Length; - Matrix matrix = new Matrix(rows, columnsSize); - + int[,] data = new int[rows, columnsSize]; for (int i = 0; i < rows; ++i) { string[] values = lines[i].Split(' ', StringSplitOptions.RemoveEmptyEntries); @@ -107,33 +123,11 @@ public static Matrix LoadFromFile(string filePath) throw new FormatException("Неверный формат числа в строке"); } - matrix[i, j] = parsedValue; - } - } - - return matrix; - } - - /// - /// Method for creating a matrix form array of values. - /// - /// Array. - /// Matrix with values from array. - public static Matrix FillInFromArray(int[,] data) - { - int rows = data.GetLength(0); - int columns = data.GetLength(1); - Matrix matrix = new Matrix(rows, columns); - - for (int i = 0; i < rows; ++i) - { - for (int j = 0; j < columns; ++j) - { - matrix[i, j] = data[i, j]; + data[i, j] = parsedValue; } } - return matrix; + return new Matrix(data); } /// diff --git a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs index 3e28752..297df56 100644 --- a/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs +++ b/ParallelMatrixMultiplication/ParallelMatrixMultiplication/MatrixMultiplier.cs @@ -7,7 +7,7 @@ namespace ParallelMatrixMultiplication; /// /// A class for performing matrix multiplication in sequential and parallel ways. /// -public class MatrixMultiplier +public static class MatrixMultiplier { /// /// Performs sequential multiplication of two matrices(AxB). @@ -25,7 +25,7 @@ public static Matrix SequentialMultiplication(Matrix a, Matrix b) throw new InvalidDataException("Умножение невозможно(количество столбцов первой матрицы не равно количеству строк второй)"); } - Matrix result = new Matrix(a.Rows, b.Columns); + int[,] resultData = new int[a.Rows, b.Columns]; for (int i = 0; i < a.Rows; ++i) { for (int j = 0; j < b.Columns; j++) @@ -36,11 +36,11 @@ public static Matrix SequentialMultiplication(Matrix a, Matrix b) sum += a[i, k] * b[k, j]; } - result[i, j] = sum; + resultData[i, j] = sum; } } - return result; + return new Matrix(resultData); } /// @@ -60,7 +60,7 @@ public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) throw new InvalidDataException("Умножение невозможно(количество столбцов первой матрицы не равно количеству строк второй)"); } - Matrix result = new Matrix(a.Rows, b.Columns); + int[,] resultData = new int[a.Rows, b.Columns]; int actualNumOfThread = Math.Min(a.Rows, numThreads); Thread[] threads = new Thread[actualNumOfThread]; @@ -83,7 +83,7 @@ public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) sum += a[row, k] * b[k, columns]; } - result[row, columns] = sum; + resultData[row, columns] = sum; } } }); @@ -99,6 +99,6 @@ public static Matrix ParallelMultiplication(Matrix a, Matrix b, int numThreads) thread.Join(); } - return result; + return new Matrix(resultData); } } \ No newline at end of file