From a239fdc21c810b76140c954a988491124f14f0c2 Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Thu, 21 Sep 2023 23:54:31 +0300 Subject: [PATCH 01/13] Init commit --- C#/forSpbu/Matrix-mult/Matrix-mult.csproj | 11 +++++++++++ C#/forSpbu/Matrix-mult/Program.cs | 3 +++ C#/forSpbu/Routers/WrongGraphException.cs | 22 ++++++++++++++++++++++ C#/forSpbu/forSpbu.sln | 20 ++++++++++++++++---- 4 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 C#/forSpbu/Matrix-mult/Matrix-mult.csproj create mode 100644 C#/forSpbu/Matrix-mult/Program.cs create mode 100644 C#/forSpbu/Routers/WrongGraphException.cs diff --git a/C#/forSpbu/Matrix-mult/Matrix-mult.csproj b/C#/forSpbu/Matrix-mult/Matrix-mult.csproj new file mode 100644 index 0000000..a58698f --- /dev/null +++ b/C#/forSpbu/Matrix-mult/Matrix-mult.csproj @@ -0,0 +1,11 @@ + + + + Exe + net7.0 + Matrix_mult + enable + enable + + + diff --git a/C#/forSpbu/Matrix-mult/Program.cs b/C#/forSpbu/Matrix-mult/Program.cs new file mode 100644 index 0000000..e5dff12 --- /dev/null +++ b/C#/forSpbu/Matrix-mult/Program.cs @@ -0,0 +1,3 @@ +// See https://aka.ms/new-console-template for more information + +Console.WriteLine("Hello, World!"); \ No newline at end of file diff --git a/C#/forSpbu/Routers/WrongGraphException.cs b/C#/forSpbu/Routers/WrongGraphException.cs new file mode 100644 index 0000000..5950363 --- /dev/null +++ b/C#/forSpbu/Routers/WrongGraphException.cs @@ -0,0 +1,22 @@ +// Copyright 2023 Ignatii Sergeev. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +namespace Routers; + +public class WrongGraphException : Exception +{ + public WrongGraphException(string message) : base(message) {} +} +public class ParseException : Exception {} \ No newline at end of file diff --git a/C#/forSpbu/forSpbu.sln b/C#/forSpbu/forSpbu.sln index 527f400..77deb00 100644 --- a/C#/forSpbu/forSpbu.sln +++ b/C#/forSpbu/forSpbu.sln @@ -10,6 +10,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03.03", "03.03", "{882A9B9C EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "10.03", "10.03", "{EA6FC7D9-BDFB-49CD-AC00-FC5DDC5274B0}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2023", "2023", "{C0783CE2-5615-41A8-B385-64A80FBD28AC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "07.09", "07.09", "{39F19078-6F77-48A7-A107-91BE48897BC7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Matrix-mult", "Matrix-mult\Matrix-mult.csproj", "{CB747B1B-24B1-497A-BEB4-F3A9A932B01C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,12 +27,18 @@ Global {E007586F-9760-4744-BB25-EDEFD6BA860C}.Release|Any CPU.ActiveCfg = Release|Any CPU {E007586F-9760-4744-BB25-EDEFD6BA860C}.Release|Any CPU.Build.0 = Release|Any CPU {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Release|Any CPU.Build.0 = Release|Any CPU + {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Release|Any CPU.Build.0 = Release|Any CPU + {CB747B1B-24B1-497A-BEB4-F3A9A932B01C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB747B1B-24B1-497A-BEB4-F3A9A932B01C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB747B1B-24B1-497A-BEB4-F3A9A932B01C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB747B1B-24B1-497A-BEB4-F3A9A932B01C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution - {E007586F-9760-4744-BB25-EDEFD6BA860C} = {D3FCB669-E93F-4F0B-B9C5-6592CE93AC7F} + {E007586F-9760-4744-BB25-EDEFD6BA860C} = {D3FCB669-E93F-4F0B-B9C5-6592CE93AC7F} {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E} = {D3FCB669-E93F-4F0B-B9C5-6592CE93AC7F} + {39F19078-6F77-48A7-A107-91BE48897BC7} = {C0783CE2-5615-41A8-B385-64A80FBD28AC} + {CB747B1B-24B1-497A-BEB4-F3A9A932B01C} = {39F19078-6F77-48A7-A107-91BE48897BC7} EndGlobalSection EndGlobal From 146e0a076ea734cc80f776a17cb881eb5b55a86c Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Mon, 25 Sep 2023 15:17:38 +0300 Subject: [PATCH 02/13] Added realisation --- C#/forSpbu/Matrix-mult/Matrix.cs | 95 +++++++++++++++++++ C#/forSpbu/Matrix-mult/MatrixMultiplier.cs | 75 +++++++++++++++ .../Matrix-mult/MatrixMultiplierException.cs | 8 ++ C#/forSpbu/Matrix-mult/Program.cs | 10 +- 4 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 C#/forSpbu/Matrix-mult/Matrix.cs create mode 100644 C#/forSpbu/Matrix-mult/MatrixMultiplier.cs create mode 100644 C#/forSpbu/Matrix-mult/MatrixMultiplierException.cs diff --git a/C#/forSpbu/Matrix-mult/Matrix.cs b/C#/forSpbu/Matrix-mult/Matrix.cs new file mode 100644 index 0000000..aa2685e --- /dev/null +++ b/C#/forSpbu/Matrix-mult/Matrix.cs @@ -0,0 +1,95 @@ +namespace Matrix_mult; + +public class Matrix +{ + /// + /// Default matrix constructor, creates matrix with one element + /// + public Matrix() + { + this.elements = new int[this.Height, this.Width]; + } + + /// + /// Matrix constructor with given elements + /// + /// Matrix elements + public Matrix(int [,] newElements, int height, int width) + { + Height = height; + Width = width; + this.elements = newElements; + } + + /// + /// Parses matrix with give string lines + /// + /// Array of lines to parse matrix from + /// Bool determined by parse success + public bool Parse(string[] lines) + { + var splitLines = lines.Select(str => str.Split(' ')).ToArray(); + var localHeight = splitLines.Length; + var localWidth = splitLines[0].Length; + + this.elements = new int[localHeight, localWidth]; + for (int i = 0; i < localHeight; i++) + { + if (splitLines[i].Length != localWidth) + { + return false; + } + + for (var j = 0; j < localWidth; j++) + { + bool parseResult = int.TryParse(splitLines[i][j], out var parseValue); + if (!parseResult) + { + return false; + } + this.elements[i, j] = parseValue; + } + } + + this.Height = localHeight; + this.Width = localWidth; + + return true; + } + + /// + /// Get element by index + /// + /// First index + /// Second index + /// Value of matrix element in given position + /// If some index is out of range + public int GetElement(int firstInd, int secondInd) => + firstInd >= 0 && firstInd < this.Height && secondInd >= 0 && secondInd < this.Width + ? elements[firstInd, secondInd] + : throw new ArgumentOutOfRangeException(); + + /// + /// Number of matrix rows + /// + public int Height{ get; private set; } + + /// + /// Number of matrix columns + /// + public int Width{ get; private set; } + + public void Print() + { + for (int i = 0; i < Height; i++) + { + for (int j = 0; j < Width; j++) + { + Console.Write($"{elements[i, j]} "); + } + Console.WriteLine(); + } + } + + private int[,] elements; +} \ No newline at end of file diff --git a/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs b/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs new file mode 100644 index 0000000..514bceb --- /dev/null +++ b/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs @@ -0,0 +1,75 @@ +namespace Matrix_mult; + +public static class MatrixMultiplier +{ + /// + /// Performs matrix multiplication in single thread + /// + /// First matrix in multiplication + /// Second matrix in multiplication + /// Result matrix + /// If matrices are incompatible(width of first and height of second are not equal) + public static Matrix SingleThreaded(Matrix first, Matrix second) + { + if (first.Width != second.Height) + { + throw new MatrixMultiplierException("Incompatible matrices"); + } + + var newElements = new int[first.Height, second.Width]; + for (var i = 0; i < first.Height; i++) + { + for (var j = 0; j < second.Width; j++) + { + for (var k = 0; k < second.Height; k++) + { + newElements[i, j] += first.GetElement(i, k) * second.GetElement(k, j); + } + } + } + + return new Matrix(newElements, first.Height, second.Width); + } + + public static Matrix MultiThreaded(Matrix first, Matrix second) + { + var threadsAmount = Math.Min(Environment.ProcessorCount, first.Height); + + var threads = new Thread[threadsAmount]; + var newElements = new int[first.Height, second.Width]; + for (int i = 0; i < threadsAmount; i++) + { + var rows = new List{}; + for (int row = i; row < first.Height; row += threadsAmount) + { + rows.Add(row); + } + + threads[i] = new Thread(() => + { + foreach (var row in rows) + { + for (int j = 0; j < second.Width; j++) + { + for (int k = 0; j < second.Height; k++) + { + newElements[row, j] += first.GetElement(row, k) * second.GetElement(j, k); + } + } + } + }); + } + + foreach (var thread in threads) + { + thread.Start(); + } + + foreach (var thread in threads) + { + thread.Join(); + } + + return new Matrix(newElements, first.Height, second.Width); + } +} \ No newline at end of file diff --git a/C#/forSpbu/Matrix-mult/MatrixMultiplierException.cs b/C#/forSpbu/Matrix-mult/MatrixMultiplierException.cs new file mode 100644 index 0000000..de52c58 --- /dev/null +++ b/C#/forSpbu/Matrix-mult/MatrixMultiplierException.cs @@ -0,0 +1,8 @@ +namespace Matrix_mult; + +public class MatrixMultiplierException : Exception +{ + public MatrixMultiplierException(string message) : base(message) + { + } +} \ No newline at end of file diff --git a/C#/forSpbu/Matrix-mult/Program.cs b/C#/forSpbu/Matrix-mult/Program.cs index e5dff12..831831d 100644 --- a/C#/forSpbu/Matrix-mult/Program.cs +++ b/C#/forSpbu/Matrix-mult/Program.cs @@ -1,3 +1,9 @@ -// See https://aka.ms/new-console-template for more information +using Matrix_mult; -Console.WriteLine("Hello, World!"); \ No newline at end of file +var matrixLines = new string[] { "1 2", "2 3" }; +var firMatrix = new Matrix(); +firMatrix.Parse(matrixLines); +var secMatrix = new Matrix(); +secMatrix.Parse(matrixLines); +var result = MatrixMultiplier.MultiThreaded(firMatrix, secMatrix); +result.Print(); From f4f6f17d033527c90413382764c353391b82c4df Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Mon, 25 Sep 2023 15:44:19 +0300 Subject: [PATCH 03/13] Updated multithread variant --- C#/forSpbu/Matrix-mult/MatrixMultiplier.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs b/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs index 514bceb..ddacea5 100644 --- a/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs +++ b/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs @@ -34,24 +34,22 @@ public static Matrix SingleThreaded(Matrix first, Matrix second) public static Matrix MultiThreaded(Matrix first, Matrix second) { var threadsAmount = Math.Min(Environment.ProcessorCount, first.Height); - + var rowsForThread = first.Height / threadsAmount; + var threads = new Thread[threadsAmount]; var newElements = new int[first.Height, second.Width]; for (int i = 0; i < threadsAmount; i++) { - var rows = new List{}; - for (int row = i; row < first.Height; row += threadsAmount) - { - rows.Add(row); - } + var startRow = i * rowsForThread; + var endRow = (i == threadsAmount - 1) ? first.Height : (i + 1) * rowsForThread; threads[i] = new Thread(() => { - foreach (var row in rows) + for (var row = startRow; row < endRow; row++) { for (int j = 0; j < second.Width; j++) { - for (int k = 0; j < second.Height; k++) + for (int k = 0; k < second.Height; k++) { newElements[row, j] += first.GetElement(row, k) * second.GetElement(j, k); } From b3db32d530d5e2818c798efbde7c802dc9e15494 Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Sat, 7 Oct 2023 22:08:55 +0300 Subject: [PATCH 04/13] Added tests --- C#/forSpbu/Matrix-mult/Program.cs | 9 -- .../MatrixMult.Tests/MatrixMult.Tests.csproj | 24 ++++ C#/forSpbu/MatrixMult.Tests/MultTests.cs | 110 ++++++++++++++++++ C#/forSpbu/MatrixMult.Tests/Usings.cs | 1 + .../{Matrix-mult => MatrixMult}/Matrix.cs | 61 +++++----- .../MatrixMult/MatrixCreationException.cs | 8 ++ .../MatrixMult.csproj} | 1 - .../MatrixMultiplier.cs | 20 +++- .../MatrixMultiplierException.cs | 5 +- C#/forSpbu/MatrixMult/Program.cs | 7 ++ C#/forSpbu/forSpbu.sln | 19 ++- 11 files changed, 209 insertions(+), 56 deletions(-) delete mode 100644 C#/forSpbu/Matrix-mult/Program.cs create mode 100644 C#/forSpbu/MatrixMult.Tests/MatrixMult.Tests.csproj create mode 100644 C#/forSpbu/MatrixMult.Tests/MultTests.cs create mode 100644 C#/forSpbu/MatrixMult.Tests/Usings.cs rename C#/forSpbu/{Matrix-mult => MatrixMult}/Matrix.cs (56%) create mode 100644 C#/forSpbu/MatrixMult/MatrixCreationException.cs rename C#/forSpbu/{Matrix-mult/Matrix-mult.csproj => MatrixMult/MatrixMult.csproj} (83%) rename C#/forSpbu/{Matrix-mult => MatrixMult}/MatrixMultiplier.cs (76%) rename C#/forSpbu/{Matrix-mult => MatrixMult}/MatrixMultiplierException.cs (59%) create mode 100644 C#/forSpbu/MatrixMult/Program.cs diff --git a/C#/forSpbu/Matrix-mult/Program.cs b/C#/forSpbu/Matrix-mult/Program.cs deleted file mode 100644 index 831831d..0000000 --- a/C#/forSpbu/Matrix-mult/Program.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Matrix_mult; - -var matrixLines = new string[] { "1 2", "2 3" }; -var firMatrix = new Matrix(); -firMatrix.Parse(matrixLines); -var secMatrix = new Matrix(); -secMatrix.Parse(matrixLines); -var result = MatrixMultiplier.MultiThreaded(firMatrix, secMatrix); -result.Print(); diff --git a/C#/forSpbu/MatrixMult.Tests/MatrixMult.Tests.csproj b/C#/forSpbu/MatrixMult.Tests/MatrixMult.Tests.csproj new file mode 100644 index 0000000..7cdd389 --- /dev/null +++ b/C#/forSpbu/MatrixMult.Tests/MatrixMult.Tests.csproj @@ -0,0 +1,24 @@ + + + + net7.0 + enable + enable + + false + true + + + + + + + + + + + + + + + diff --git a/C#/forSpbu/MatrixMult.Tests/MultTests.cs b/C#/forSpbu/MatrixMult.Tests/MultTests.cs new file mode 100644 index 0000000..dd322db --- /dev/null +++ b/C#/forSpbu/MatrixMult.Tests/MultTests.cs @@ -0,0 +1,110 @@ +namespace MatrixMult.Tests; + +public static class MultTests +{ + private static readonly (Matrix, Matrix, Matrix?)[] Tests = + { + ( + new Matrix( + new int[,] + { + { 1, 2 }, + { 3, 4 } + }), + new Matrix( + new int[,] + { + { 2, 3 }, + { 4, 5 } + }), + new Matrix( + new int[,] + { + { 1, 2 }, + { 4, 5 } + }) + ), + ( + new Matrix( + new int[,] + { + { 1, 2, 3 }, + { 4, 5, 6 } + }), + new Matrix( + new int[,] + { + { 1, 2 }, + { 4, 5 } + }), + null + ), + ( + new Matrix( + new int[,] + { + { 1, 2, 3 }, + { 4, 5, 6 } + }), + new Matrix( + new int[,] + { + { 1, 2 }, + { 3, 4 }, + { 5, 6 } + }), + new Matrix( + new int[,] + { + { 22, 28 }, + { 49, 64 } + }) + ) + }; + + private static IEnumerable MultImplementations() + { + yield return new TestCaseData(MatrixMultiplier.MultiThreaded); + yield return new TestCaseData(MatrixMultiplier.SingleThreaded); + } + + private static IEnumerable TestCases() + { + return Tests.Select(test => new TestCaseData(test)); + } + + private static bool AreMatricesEqual(Matrix fst, Matrix sec) + { + if (fst.Height != sec.Height || fst.Width != sec.Width) + { + return false; + } + + for (int i = 0; i < fst.Height; i++) + { + for (int j = 0; j < sec.Width; j++) + { + if (fst.GetElement(i, j) != sec.GetElement(i, j)) + { + return false; + } + } + } + + return true; + } + + [Test, TestCaseSource(nameof(MultImplementations)), TestCaseSource(nameof(TestCases))] + public static void MultiplyMatricesTest(Func matrixMultImpl, (Matrix, Matrix, Matrix?) test) + { + if (test.Item3 == null) + { + Assert.Throws(() => matrixMultImpl(test.Item1, test.Item2)); + } + else + { + var multResult = matrixMultImpl(test.Item1, test.Item2); + Assert.That(AreMatricesEqual(multResult, test.Item3), Is.True); + } + } +} \ No newline at end of file diff --git a/C#/forSpbu/MatrixMult.Tests/Usings.cs b/C#/forSpbu/MatrixMult.Tests/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/C#/forSpbu/MatrixMult.Tests/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file diff --git a/C#/forSpbu/Matrix-mult/Matrix.cs b/C#/forSpbu/MatrixMult/Matrix.cs similarity index 56% rename from C#/forSpbu/Matrix-mult/Matrix.cs rename to C#/forSpbu/MatrixMult/Matrix.cs index aa2685e..04ff598 100644 --- a/C#/forSpbu/Matrix-mult/Matrix.cs +++ b/C#/forSpbu/MatrixMult/Matrix.cs @@ -1,43 +1,36 @@ -namespace Matrix_mult; +namespace MatrixMult; +/// +/// Class with matrix container +/// public class Matrix { - /// - /// Default matrix constructor, creates matrix with one element - /// - public Matrix() - { - this.elements = new int[this.Height, this.Width]; - } - /// /// Matrix constructor with given elements /// /// Matrix elements - public Matrix(int [,] newElements, int height, int width) + public Matrix(int [,] newElements) { - Height = height; - Width = width; - this.elements = newElements; + this._elements = newElements; } /// - /// Parses matrix with give string lines + /// Constructs matrix with given string lines /// - /// Array of lines to parse matrix from - /// Bool determined by parse success - public bool Parse(string[] lines) + /// Array of lines to build matrix from + /// If given array of lines is incorrect + public Matrix(string[] lines) { var splitLines = lines.Select(str => str.Split(' ')).ToArray(); var localHeight = splitLines.Length; var localWidth = splitLines[0].Length; - this.elements = new int[localHeight, localWidth]; + this._elements = new int[localHeight, localWidth]; for (int i = 0; i < localHeight; i++) { if (splitLines[i].Length != localWidth) { - return false; + throw new MatrixCreationException("Inconsistent lines length"); } for (var j = 0; j < localWidth; j++) @@ -45,16 +38,11 @@ public bool Parse(string[] lines) bool parseResult = int.TryParse(splitLines[i][j], out var parseValue); if (!parseResult) { - return false; + throw new MatrixCreationException("Incorrect matrix element"); } - this.elements[i, j] = parseValue; + this._elements[i, j] = parseValue; } } - - this.Height = localHeight; - this.Width = localWidth; - - return true; } /// @@ -65,31 +53,36 @@ public bool Parse(string[] lines) /// Value of matrix element in given position /// If some index is out of range public int GetElement(int firstInd, int secondInd) => - firstInd >= 0 && firstInd < this.Height && secondInd >= 0 && secondInd < this.Width - ? elements[firstInd, secondInd] - : throw new ArgumentOutOfRangeException(); + firstInd < 0 || firstInd >= this.Height + ? throw new ArgumentOutOfRangeException(nameof(firstInd)) + : secondInd < 0 || secondInd >= this.Width + ? throw new ArgumentOutOfRangeException(nameof(secondInd)) + : _elements[firstInd, secondInd]; /// /// Number of matrix rows /// - public int Height{ get; private set; } - + public int Height => this._elements.GetLength(0); + /// /// Number of matrix columns /// - public int Width{ get; private set; } + public int Width => this._elements.GetLength(1); + /// + /// Prints matrix into console + /// public void Print() { for (int i = 0; i < Height; i++) { for (int j = 0; j < Width; j++) { - Console.Write($"{elements[i, j]} "); + Console.Write($"{_elements[i, j]} "); } Console.WriteLine(); } } - private int[,] elements; + private int[,] _elements; } \ No newline at end of file diff --git a/C#/forSpbu/MatrixMult/MatrixCreationException.cs b/C#/forSpbu/MatrixMult/MatrixCreationException.cs new file mode 100644 index 0000000..d4fac20 --- /dev/null +++ b/C#/forSpbu/MatrixMult/MatrixCreationException.cs @@ -0,0 +1,8 @@ +namespace MatrixMult; + +public class MatrixCreationException : Exception +{ + public MatrixCreationException(string message) : base(message) + { + } +} \ No newline at end of file diff --git a/C#/forSpbu/Matrix-mult/Matrix-mult.csproj b/C#/forSpbu/MatrixMult/MatrixMult.csproj similarity index 83% rename from C#/forSpbu/Matrix-mult/Matrix-mult.csproj rename to C#/forSpbu/MatrixMult/MatrixMult.csproj index a58698f..2b14c81 100644 --- a/C#/forSpbu/Matrix-mult/Matrix-mult.csproj +++ b/C#/forSpbu/MatrixMult/MatrixMult.csproj @@ -3,7 +3,6 @@ Exe net7.0 - Matrix_mult enable enable diff --git a/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs b/C#/forSpbu/MatrixMult/MatrixMultiplier.cs similarity index 76% rename from C#/forSpbu/Matrix-mult/MatrixMultiplier.cs rename to C#/forSpbu/MatrixMult/MatrixMultiplier.cs index ddacea5..687dd5a 100644 --- a/C#/forSpbu/Matrix-mult/MatrixMultiplier.cs +++ b/C#/forSpbu/MatrixMult/MatrixMultiplier.cs @@ -1,9 +1,12 @@ -namespace Matrix_mult; +namespace MatrixMult; +/// +/// Class for matrix multiplication +/// public static class MatrixMultiplier { /// - /// Performs matrix multiplication in single thread + /// Performs matrix multiplication in single threaded mode /// /// First matrix in multiplication /// Second matrix in multiplication @@ -28,9 +31,16 @@ public static Matrix SingleThreaded(Matrix first, Matrix second) } } - return new Matrix(newElements, first.Height, second.Width); + return new Matrix(newElements); } + /// + /// Performs matrix multiplication in multi threaded mode + /// + /// First matrix in multiplication + /// Second matrix in multiplication + /// Result matrix + /// If matrices are incompatible(width of first and height of second are not equal) public static Matrix MultiThreaded(Matrix first, Matrix second) { var threadsAmount = Math.Min(Environment.ProcessorCount, first.Height); @@ -51,7 +61,7 @@ public static Matrix MultiThreaded(Matrix first, Matrix second) { for (int k = 0; k < second.Height; k++) { - newElements[row, j] += first.GetElement(row, k) * second.GetElement(j, k); + newElements[row, j] += first.GetElement(row, k) * second.GetElement(k, j); } } } @@ -68,6 +78,6 @@ public static Matrix MultiThreaded(Matrix first, Matrix second) thread.Join(); } - return new Matrix(newElements, first.Height, second.Width); + return new Matrix(newElements); } } \ No newline at end of file diff --git a/C#/forSpbu/Matrix-mult/MatrixMultiplierException.cs b/C#/forSpbu/MatrixMult/MatrixMultiplierException.cs similarity index 59% rename from C#/forSpbu/Matrix-mult/MatrixMultiplierException.cs rename to C#/forSpbu/MatrixMult/MatrixMultiplierException.cs index de52c58..87d0939 100644 --- a/C#/forSpbu/Matrix-mult/MatrixMultiplierException.cs +++ b/C#/forSpbu/MatrixMult/MatrixMultiplierException.cs @@ -1,5 +1,8 @@ -namespace Matrix_mult; +namespace MatrixMult; +/// +/// Class for matrix multiplier exceptions +/// public class MatrixMultiplierException : Exception { public MatrixMultiplierException(string message) : base(message) diff --git a/C#/forSpbu/MatrixMult/Program.cs b/C#/forSpbu/MatrixMult/Program.cs new file mode 100644 index 0000000..5b4b3bc --- /dev/null +++ b/C#/forSpbu/MatrixMult/Program.cs @@ -0,0 +1,7 @@ +using MatrixMult; + +var matrixLines = new string[] { "1 2", "2 3" }; +var firMatrix = new Matrix(matrixLines); +var secMatrix = new Matrix(matrixLines); +var result = MatrixMultiplier.MultiThreaded(firMatrix, secMatrix); +result.Print(); diff --git a/C#/forSpbu/forSpbu.sln b/C#/forSpbu/forSpbu.sln index 77deb00..c8a4db6 100644 --- a/C#/forSpbu/forSpbu.sln +++ b/C#/forSpbu/forSpbu.sln @@ -14,7 +14,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2023", "2023", "{C0783CE2-5 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "07.09", "07.09", "{39F19078-6F77-48A7-A107-91BE48897BC7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Matrix-mult", "Matrix-mult\Matrix-mult.csproj", "{CB747B1B-24B1-497A-BEB4-F3A9A932B01C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixMult", "MatrixMult\MatrixMult.csproj", "{2D51ED0F-2E78-41A9-B4D7-CFD36A9FCCEB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixMult.Tests", "MatrixMult.Tests\MatrixMult.Tests.csproj", "{CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -30,15 +32,20 @@ Global {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Debug|Any CPU.Build.0 = Debug|Any CPU {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Release|Any CPU.ActiveCfg = Release|Any CPU {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E}.Release|Any CPU.Build.0 = Release|Any CPU - {CB747B1B-24B1-497A-BEB4-F3A9A932B01C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CB747B1B-24B1-497A-BEB4-F3A9A932B01C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CB747B1B-24B1-497A-BEB4-F3A9A932B01C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CB747B1B-24B1-497A-BEB4-F3A9A932B01C}.Release|Any CPU.Build.0 = Release|Any CPU + {2D51ED0F-2E78-41A9-B4D7-CFD36A9FCCEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D51ED0F-2E78-41A9-B4D7-CFD36A9FCCEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D51ED0F-2E78-41A9-B4D7-CFD36A9FCCEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D51ED0F-2E78-41A9-B4D7-CFD36A9FCCEB}.Release|Any CPU.Build.0 = Release|Any CPU + {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {E007586F-9760-4744-BB25-EDEFD6BA860C} = {D3FCB669-E93F-4F0B-B9C5-6592CE93AC7F} {A4F6ADD5-85FD-4F67-8B29-549DDDF6F82E} = {D3FCB669-E93F-4F0B-B9C5-6592CE93AC7F} {39F19078-6F77-48A7-A107-91BE48897BC7} = {C0783CE2-5615-41A8-B385-64A80FBD28AC} - {CB747B1B-24B1-497A-BEB4-F3A9A932B01C} = {39F19078-6F77-48A7-A107-91BE48897BC7} + {2D51ED0F-2E78-41A9-B4D7-CFD36A9FCCEB} = {39F19078-6F77-48A7-A107-91BE48897BC7} + {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28} = {39F19078-6F77-48A7-A107-91BE48897BC7} EndGlobalSection EndGlobal From e2b5d05e355d029a2cefe02bf4d930f2e0d33662 Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Sun, 8 Oct 2023 03:03:41 +0300 Subject: [PATCH 05/13] Fixed tests and added benchmark --- .../MatrixMult.Benchmark.csproj | 18 ++++++++++ .../MatrixMultBenchmark.cs | 36 +++++++++++++++++++ C#/forSpbu/MatrixMult.Benchmark/Program.cs | 5 +++ C#/forSpbu/MatrixMult.Tests/MultTests.cs | 20 +++++------ C#/forSpbu/MatrixMult/Matrix.cs | 20 ++++++++++- .../MatrixMult/MatrixCreationException.cs | 3 ++ C#/forSpbu/MatrixMult/MatrixMultiplier.cs | 5 +++ C#/forSpbu/forSpbu.sln | 7 ++++ 8 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 C#/forSpbu/MatrixMult.Benchmark/MatrixMult.Benchmark.csproj create mode 100644 C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs create mode 100644 C#/forSpbu/MatrixMult.Benchmark/Program.cs diff --git a/C#/forSpbu/MatrixMult.Benchmark/MatrixMult.Benchmark.csproj b/C#/forSpbu/MatrixMult.Benchmark/MatrixMult.Benchmark.csproj new file mode 100644 index 0000000..78592f1 --- /dev/null +++ b/C#/forSpbu/MatrixMult.Benchmark/MatrixMult.Benchmark.csproj @@ -0,0 +1,18 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + + + + diff --git a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs new file mode 100644 index 0000000..14cf780 --- /dev/null +++ b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs @@ -0,0 +1,36 @@ +using BenchmarkDotNet.Attributes; +namespace MatrixMult.Benchmark; + +public class MatrixMultBenchmark +{ + [Params(16, 32, 64, 128, 256, 512, 1024, 2048)] + private int _size; + private Matrix _fst; + private Matrix _sec; + + [GlobalSetup] + public void GenerateRandomMatrix(int size) + { + var random = new Random(); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + _fst.SetElement(random.Next(), i, j); + _sec.SetElement(random.Next(), i, j); + } + } + } + + [Benchmark] + public void MultiThreaded() + { + MatrixMultiplier.MultiThreaded(_fst, _sec); + } + + [Benchmark] + public void SingleThreaded() + { + MatrixMultiplier.SingleThreaded(_fst, _sec); + } +} \ No newline at end of file diff --git a/C#/forSpbu/MatrixMult.Benchmark/Program.cs b/C#/forSpbu/MatrixMult.Benchmark/Program.cs new file mode 100644 index 0000000..04960b1 --- /dev/null +++ b/C#/forSpbu/MatrixMult.Benchmark/Program.cs @@ -0,0 +1,5 @@ +using MatrixMult.Benchmark; +using BenchmarkDotNet.Running; + +var table = BenchmarkRunner.Run(); +Console.WriteLine(table); \ No newline at end of file diff --git a/C#/forSpbu/MatrixMult.Tests/MultTests.cs b/C#/forSpbu/MatrixMult.Tests/MultTests.cs index dd322db..8797ad9 100644 --- a/C#/forSpbu/MatrixMult.Tests/MultTests.cs +++ b/C#/forSpbu/MatrixMult.Tests/MultTests.cs @@ -20,8 +20,8 @@ private static readonly (Matrix, Matrix, Matrix?)[] Tests = new Matrix( new int[,] { - { 1, 2 }, - { 4, 5 } + { 10, 13 }, + { 22, 29 } }) ), ( @@ -61,16 +61,14 @@ private static readonly (Matrix, Matrix, Matrix?)[] Tests = }) ) }; - - private static IEnumerable MultImplementations() - { - yield return new TestCaseData(MatrixMultiplier.MultiThreaded); - yield return new TestCaseData(MatrixMultiplier.SingleThreaded); - } - + private static IEnumerable TestCases() { - return Tests.Select(test => new TestCaseData(test)); + foreach (var test in Tests) + { + yield return new TestCaseData(MatrixMultiplier.MultiThreaded, test); + yield return new TestCaseData(MatrixMultiplier.SingleThreaded, test); + } } private static bool AreMatricesEqual(Matrix fst, Matrix sec) @@ -94,7 +92,7 @@ private static bool AreMatricesEqual(Matrix fst, Matrix sec) return true; } - [Test, TestCaseSource(nameof(MultImplementations)), TestCaseSource(nameof(TestCases))] + [Test, TestCaseSource(nameof(TestCases))] public static void MultiplyMatricesTest(Func matrixMultImpl, (Matrix, Matrix, Matrix?) test) { if (test.Item3 == null) diff --git a/C#/forSpbu/MatrixMult/Matrix.cs b/C#/forSpbu/MatrixMult/Matrix.cs index 04ff598..f39edb2 100644 --- a/C#/forSpbu/MatrixMult/Matrix.cs +++ b/C#/forSpbu/MatrixMult/Matrix.cs @@ -58,6 +58,21 @@ public int GetElement(int firstInd, int secondInd) => : secondInd < 0 || secondInd >= this.Width ? throw new ArgumentOutOfRangeException(nameof(secondInd)) : _elements[firstInd, secondInd]; + + /// + /// Set element by index + /// + /// Element value + /// First index + /// Second index + /// Value of matrix element in given position + /// If some index is out of range + public int SetElement(int value, int firstInd, int secondInd) => + firstInd < 0 || firstInd >= this.Height + ? throw new ArgumentOutOfRangeException(nameof(firstInd)) + : secondInd < 0 || secondInd >= this.Width + ? throw new ArgumentOutOfRangeException(nameof(secondInd)) + : _elements[firstInd, secondInd] = value; /// /// Number of matrix rows @@ -84,5 +99,8 @@ public void Print() } } - private int[,] _elements; + /// + /// Matrix elements + /// + private readonly int[,] _elements; } \ No newline at end of file diff --git a/C#/forSpbu/MatrixMult/MatrixCreationException.cs b/C#/forSpbu/MatrixMult/MatrixCreationException.cs index d4fac20..5104cc6 100644 --- a/C#/forSpbu/MatrixMult/MatrixCreationException.cs +++ b/C#/forSpbu/MatrixMult/MatrixCreationException.cs @@ -1,5 +1,8 @@ namespace MatrixMult; +/// +/// Class for matrix creation exceptions +/// public class MatrixCreationException : Exception { public MatrixCreationException(string message) : base(message) diff --git a/C#/forSpbu/MatrixMult/MatrixMultiplier.cs b/C#/forSpbu/MatrixMult/MatrixMultiplier.cs index 687dd5a..b29c89c 100644 --- a/C#/forSpbu/MatrixMult/MatrixMultiplier.cs +++ b/C#/forSpbu/MatrixMult/MatrixMultiplier.cs @@ -43,6 +43,11 @@ public static Matrix SingleThreaded(Matrix first, Matrix second) /// If matrices are incompatible(width of first and height of second are not equal) public static Matrix MultiThreaded(Matrix first, Matrix second) { + if (first.Width != second.Height) + { + throw new MatrixMultiplierException("Incompatible matrices"); + } + var threadsAmount = Math.Min(Environment.ProcessorCount, first.Height); var rowsForThread = first.Height / threadsAmount; diff --git a/C#/forSpbu/forSpbu.sln b/C#/forSpbu/forSpbu.sln index c8a4db6..04b3136 100644 --- a/C#/forSpbu/forSpbu.sln +++ b/C#/forSpbu/forSpbu.sln @@ -18,6 +18,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixMult", "MatrixMult\Ma EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixMult.Tests", "MatrixMult.Tests\MatrixMult.Tests.csproj", "{CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixMult.Benchmark", "MatrixMult.Benchmark\MatrixMult.Benchmark.csproj", "{85632487-7520-4FD5-9FCB-56E9C2C147E3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -40,6 +42,10 @@ Global {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}.Release|Any CPU.ActiveCfg = Release|Any CPU {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28}.Release|Any CPU.Build.0 = Release|Any CPU + {85632487-7520-4FD5-9FCB-56E9C2C147E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85632487-7520-4FD5-9FCB-56E9C2C147E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85632487-7520-4FD5-9FCB-56E9C2C147E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85632487-7520-4FD5-9FCB-56E9C2C147E3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {E007586F-9760-4744-BB25-EDEFD6BA860C} = {D3FCB669-E93F-4F0B-B9C5-6592CE93AC7F} @@ -47,5 +53,6 @@ Global {39F19078-6F77-48A7-A107-91BE48897BC7} = {C0783CE2-5615-41A8-B385-64A80FBD28AC} {2D51ED0F-2E78-41A9-B4D7-CFD36A9FCCEB} = {39F19078-6F77-48A7-A107-91BE48897BC7} {CCF2E7C9-46CB-4D91-8277-761DD7A5CF28} = {39F19078-6F77-48A7-A107-91BE48897BC7} + {85632487-7520-4FD5-9FCB-56E9C2C147E3} = {39F19078-6F77-48A7-A107-91BE48897BC7} EndGlobalSection EndGlobal From e3edce63ce445ede0d12844f0838d2f9013eae49 Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Sun, 8 Oct 2023 16:05:08 +0300 Subject: [PATCH 06/13] Finished benchmark --- .../MatrixMultBenchmark.cs | 19 ++++++++++++------- C#/forSpbu/MatrixMult/Matrix.cs | 15 --------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs index 14cf780..8907729 100644 --- a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs +++ b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs @@ -3,23 +3,28 @@ namespace MatrixMult.Benchmark; public class MatrixMultBenchmark { - [Params(16, 32, 64, 128, 256, 512, 1024, 2048)] - private int _size; + [Params(12, 24, 48, 96, 192, 384, 768, 1536)] + public int Size; private Matrix _fst; private Matrix _sec; [GlobalSetup] - public void GenerateRandomMatrix(int size) + public void GenerateRandomMatrix() { var random = new Random(); - for (int i = 0; i < size; i++) + var fstElements = new int[Size, Size]; + var secElements = new int[Size, Size]; + for (int i = 0; i < Size; i++) { - for (int j = 0; j < size; j++) + for (int j = 0; j < Size; j++) { - _fst.SetElement(random.Next(), i, j); - _sec.SetElement(random.Next(), i, j); + fstElements[i, j] = random.Next(); + secElements[i, j] = random.Next(); } } + + _fst = new Matrix(fstElements); + _sec = new Matrix(secElements); } [Benchmark] diff --git a/C#/forSpbu/MatrixMult/Matrix.cs b/C#/forSpbu/MatrixMult/Matrix.cs index f39edb2..d9e327f 100644 --- a/C#/forSpbu/MatrixMult/Matrix.cs +++ b/C#/forSpbu/MatrixMult/Matrix.cs @@ -58,21 +58,6 @@ public int GetElement(int firstInd, int secondInd) => : secondInd < 0 || secondInd >= this.Width ? throw new ArgumentOutOfRangeException(nameof(secondInd)) : _elements[firstInd, secondInd]; - - /// - /// Set element by index - /// - /// Element value - /// First index - /// Second index - /// Value of matrix element in given position - /// If some index is out of range - public int SetElement(int value, int firstInd, int secondInd) => - firstInd < 0 || firstInd >= this.Height - ? throw new ArgumentOutOfRangeException(nameof(firstInd)) - : secondInd < 0 || secondInd >= this.Width - ? throw new ArgumentOutOfRangeException(nameof(secondInd)) - : _elements[firstInd, secondInd] = value; /// /// Number of matrix rows From d427e9c519dfed3b56385e24238d86f38dd8dfcd Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Sun, 8 Oct 2023 16:12:46 +0300 Subject: [PATCH 07/13] Finished --- .../MatrixMultBenchmark.cs | 4 ++-- C#/forSpbu/MatrixMult.Tests/MultTests.cs | 4 ++-- .../MatrixMult/MatrixCreationException.cs | 4 ++++ C#/forSpbu/MatrixMult/MatrixMultiplier.cs | 4 ++-- .../MatrixMult/MatrixMultiplierException.cs | 4 ++++ C#/forSpbu/MatrixMult/Program.cs | 2 +- C#/forSpbu/Routers/WrongGraphException.cs | 22 ------------------- 7 files changed, 15 insertions(+), 29 deletions(-) delete mode 100644 C#/forSpbu/Routers/WrongGraphException.cs diff --git a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs index 8907729..b398ab5 100644 --- a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs +++ b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs @@ -30,12 +30,12 @@ public void GenerateRandomMatrix() [Benchmark] public void MultiThreaded() { - MatrixMultiplier.MultiThreaded(_fst, _sec); + MatrixMultiplier.MultiThreadedMultiply(_fst, _sec); } [Benchmark] public void SingleThreaded() { - MatrixMultiplier.SingleThreaded(_fst, _sec); + MatrixMultiplier.SingleThreadedMultiply(_fst, _sec); } } \ No newline at end of file diff --git a/C#/forSpbu/MatrixMult.Tests/MultTests.cs b/C#/forSpbu/MatrixMult.Tests/MultTests.cs index 8797ad9..5ab19d9 100644 --- a/C#/forSpbu/MatrixMult.Tests/MultTests.cs +++ b/C#/forSpbu/MatrixMult.Tests/MultTests.cs @@ -66,8 +66,8 @@ private static IEnumerable TestCases() { foreach (var test in Tests) { - yield return new TestCaseData(MatrixMultiplier.MultiThreaded, test); - yield return new TestCaseData(MatrixMultiplier.SingleThreaded, test); + yield return new TestCaseData(MatrixMultiplier.MultiThreadedMultiply, test); + yield return new TestCaseData(MatrixMultiplier.SingleThreadedMultiply, test); } } diff --git a/C#/forSpbu/MatrixMult/MatrixCreationException.cs b/C#/forSpbu/MatrixMult/MatrixCreationException.cs index 5104cc6..bcd56ac 100644 --- a/C#/forSpbu/MatrixMult/MatrixCreationException.cs +++ b/C#/forSpbu/MatrixMult/MatrixCreationException.cs @@ -5,6 +5,10 @@ /// public class MatrixCreationException : Exception { + public MatrixCreationException() : base() + { + } + public MatrixCreationException(string message) : base(message) { } diff --git a/C#/forSpbu/MatrixMult/MatrixMultiplier.cs b/C#/forSpbu/MatrixMult/MatrixMultiplier.cs index b29c89c..486acfa 100644 --- a/C#/forSpbu/MatrixMult/MatrixMultiplier.cs +++ b/C#/forSpbu/MatrixMult/MatrixMultiplier.cs @@ -12,7 +12,7 @@ public static class MatrixMultiplier /// Second matrix in multiplication /// Result matrix /// If matrices are incompatible(width of first and height of second are not equal) - public static Matrix SingleThreaded(Matrix first, Matrix second) + public static Matrix SingleThreadedMultiply(Matrix first, Matrix second) { if (first.Width != second.Height) { @@ -41,7 +41,7 @@ public static Matrix SingleThreaded(Matrix first, Matrix second) /// Second matrix in multiplication /// Result matrix /// If matrices are incompatible(width of first and height of second are not equal) - public static Matrix MultiThreaded(Matrix first, Matrix second) + public static Matrix MultiThreadedMultiply(Matrix first, Matrix second) { if (first.Width != second.Height) { diff --git a/C#/forSpbu/MatrixMult/MatrixMultiplierException.cs b/C#/forSpbu/MatrixMult/MatrixMultiplierException.cs index 87d0939..01b5d2b 100644 --- a/C#/forSpbu/MatrixMult/MatrixMultiplierException.cs +++ b/C#/forSpbu/MatrixMult/MatrixMultiplierException.cs @@ -5,6 +5,10 @@ namespace MatrixMult; /// public class MatrixMultiplierException : Exception { + public MatrixMultiplierException() : base() + { + } + public MatrixMultiplierException(string message) : base(message) { } diff --git a/C#/forSpbu/MatrixMult/Program.cs b/C#/forSpbu/MatrixMult/Program.cs index 5b4b3bc..ac3f355 100644 --- a/C#/forSpbu/MatrixMult/Program.cs +++ b/C#/forSpbu/MatrixMult/Program.cs @@ -3,5 +3,5 @@ var matrixLines = new string[] { "1 2", "2 3" }; var firMatrix = new Matrix(matrixLines); var secMatrix = new Matrix(matrixLines); -var result = MatrixMultiplier.MultiThreaded(firMatrix, secMatrix); +var result = MatrixMultiplier.MultiThreadedMultiply(firMatrix, secMatrix); result.Print(); diff --git a/C#/forSpbu/Routers/WrongGraphException.cs b/C#/forSpbu/Routers/WrongGraphException.cs deleted file mode 100644 index 5950363..0000000 --- a/C#/forSpbu/Routers/WrongGraphException.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2023 Ignatii Sergeev. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -namespace Routers; - -public class WrongGraphException : Exception -{ - public WrongGraphException(string message) : base(message) {} -} -public class ParseException : Exception {} \ No newline at end of file From 25adb99c2cfc574ade4c3b6522f32055a3f322d4 Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Sun, 8 Oct 2023 16:37:26 +0300 Subject: [PATCH 08/13] Finished --- C#/forSpbu/MatrixMult/Matrix.cs | 29 ++++++++++----- C#/forSpbu/MatrixMult/Program.cs | 61 +++++++++++++++++++++++++++++--- 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/C#/forSpbu/MatrixMult/Matrix.cs b/C#/forSpbu/MatrixMult/Matrix.cs index d9e327f..20e3250 100644 --- a/C#/forSpbu/MatrixMult/Matrix.cs +++ b/C#/forSpbu/MatrixMult/Matrix.cs @@ -6,7 +6,15 @@ namespace MatrixMult; public class Matrix { /// - /// Matrix constructor with given elements + /// Constructs empty matrix + /// + public Matrix() + { + this._elements = new int[0, 0]; + } + + /// + /// Constructs matrix with given elements /// /// Matrix elements public Matrix(int [,] newElements) @@ -46,7 +54,7 @@ public Matrix(string[] lines) } /// - /// Get element by index + /// Returns element by index /// /// First index /// Second index @@ -57,7 +65,7 @@ public int GetElement(int firstInd, int secondInd) => ? throw new ArgumentOutOfRangeException(nameof(firstInd)) : secondInd < 0 || secondInd >= this.Width ? throw new ArgumentOutOfRangeException(nameof(secondInd)) - : _elements[firstInd, secondInd]; + : this._elements[firstInd, secondInd]; /// /// Number of matrix rows @@ -70,18 +78,21 @@ public int GetElement(int firstInd, int secondInd) => public int Width => this._elements.GetLength(1); /// - /// Prints matrix into console + /// Returns matrix as array of string /// - public void Print() + /// String array matrix representation + public string[] GetStringRepresentation() { - for (int i = 0; i < Height; i++) + var lines = new string[this.Height]; + for (int i = 0; i < this.Height; i++) { - for (int j = 0; j < Width; j++) + for (int j = 0; j < this.Width; j++) { - Console.Write($"{_elements[i, j]} "); + lines[i] += _elements[i, j] + " "; } - Console.WriteLine(); } + + return lines; } /// diff --git a/C#/forSpbu/MatrixMult/Program.cs b/C#/forSpbu/MatrixMult/Program.cs index ac3f355..ddf9141 100644 --- a/C#/forSpbu/MatrixMult/Program.cs +++ b/C#/forSpbu/MatrixMult/Program.cs @@ -1,7 +1,58 @@ using MatrixMult; -var matrixLines = new string[] { "1 2", "2 3" }; -var firMatrix = new Matrix(matrixLines); -var secMatrix = new Matrix(matrixLines); -var result = MatrixMultiplier.MultiThreadedMultiply(firMatrix, secMatrix); -result.Print(); +if (args.Length != 3) +{ + Console.WriteLine("Wrong number of arguments(should be mode -s(single) or -m(multi) and two file paths)"); + return; +} + +var mode = args[0]; +var fstFilePath = args[1]; +var secFilePath = args[2]; +if (string.IsNullOrEmpty(fstFilePath) || string.IsNullOrEmpty(secFilePath)) +{ + Console.WriteLine("Wrong(null or empty) paths"); + return; +} +if (mode != "-m" && mode != "-s") +{ + Console.WriteLine("Incorrect mode - s(single) or m(multi)"); + return; +} + +try +{ + var fstMatrix = new Matrix(File.ReadAllLines(fstFilePath)); + var secMatrix = new Matrix(File.ReadAllLines(secFilePath)); + + var result = new Matrix(); + switch (mode) + { + case "-m": + { + result = MatrixMultiplier.MultiThreadedMultiply(fstMatrix, secMatrix); + break; + } + case "-s": + { + result = MatrixMultiplier.SingleThreadedMultiply(fstMatrix, secMatrix); + break; + } + } + + var resultLines = result.GetStringRepresentation(); + File.WriteAllLines("result.txt", resultLines); + Console.WriteLine("Multiplication successful, result matrix has been written to result.txt"); +} +catch (IOException) +{ + Console.WriteLine("File not found"); +} +catch (MatrixCreationException) +{ + Console.WriteLine("Matrix creation error(given incorrect matrices)"); +} +catch (MatrixMultiplierException) +{ + Console.WriteLine("Multiplication error(given incompatible matrices)"); +} From bdbf47a685ddbde807a176d9ab6576b139e1e7b4 Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Sun, 8 Oct 2023 16:38:26 +0300 Subject: [PATCH 09/13] Changed ci --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2b53b5..868d947 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,5 +25,5 @@ jobs: run: For /R %%I in (*.sln) do dotnet build %%I shell: cmd - name: test - run: For /R %%I in (*.sln) do dotnet build %%I + run: For /R %%I in (*.sln) do dotnet test %%I shell: cmd From cef52da6859923b4422e3e37c6be4e158ef2a927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B5=D0=B2=20=D0=98=D0=B3?= =?UTF-8?q?=D0=BD=D0=B0=D1=82=D0=B8=D0=B9?= <114506759+IgnatSergeev@users.noreply.github.com> Date: Sun, 29 Oct 2023 16:33:49 +0300 Subject: [PATCH 10/13] Update C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs Co-authored-by: Yuri Ufimtsev <91129832+YuriUfimtsev@users.noreply.github.com> --- C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs index b398ab5..f17aa22 100644 --- a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs +++ b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs @@ -4,7 +4,7 @@ namespace MatrixMult.Benchmark; public class MatrixMultBenchmark { [Params(12, 24, 48, 96, 192, 384, 768, 1536)] - public int Size; + public int Size { get; set; } private Matrix _fst; private Matrix _sec; From d3bedeb4ff8f7f8f2add8255927fc9e2674c0d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B5=D0=B2=20=D0=98=D0=B3?= =?UTF-8?q?=D0=BD=D0=B0=D1=82=D0=B8=D0=B9?= <114506759+IgnatSergeev@users.noreply.github.com> Date: Sun, 29 Oct 2023 16:34:03 +0300 Subject: [PATCH 11/13] Update C#/forSpbu/MatrixMult/Matrix.cs Co-authored-by: Yuri Ufimtsev <91129832+YuriUfimtsev@users.noreply.github.com> --- C#/forSpbu/MatrixMult/Matrix.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/C#/forSpbu/MatrixMult/Matrix.cs b/C#/forSpbu/MatrixMult/Matrix.cs index 20e3250..832bec8 100644 --- a/C#/forSpbu/MatrixMult/Matrix.cs +++ b/C#/forSpbu/MatrixMult/Matrix.cs @@ -43,8 +43,7 @@ public Matrix(string[] lines) for (var j = 0; j < localWidth; j++) { - bool parseResult = int.TryParse(splitLines[i][j], out var parseValue); - if (!parseResult) + if (!int.TryParse(splitLines[i][j], out var parseValue)) { throw new MatrixCreationException("Incorrect matrix element"); } From b8e84d88c8f9639dbb0557f8742efc08ae19b68f Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Sun, 29 Oct 2023 16:38:11 +0300 Subject: [PATCH 12/13] Fixed --- .../MatrixMultBenchmark.cs | 4 ++-- C#/forSpbu/MatrixMult.Tests/MultTests.cs | 4 ++-- C#/forSpbu/MatrixMult/Matrix.cs | 20 +++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs index b398ab5..62727d4 100644 --- a/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs +++ b/C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs @@ -5,8 +5,8 @@ public class MatrixMultBenchmark { [Params(12, 24, 48, 96, 192, 384, 768, 1536)] public int Size; - private Matrix _fst; - private Matrix _sec; + private Matrix _fst = new Matrix(); + private Matrix _sec = new Matrix(); [GlobalSetup] public void GenerateRandomMatrix() diff --git a/C#/forSpbu/MatrixMult.Tests/MultTests.cs b/C#/forSpbu/MatrixMult.Tests/MultTests.cs index 5ab19d9..bab80a0 100644 --- a/C#/forSpbu/MatrixMult.Tests/MultTests.cs +++ b/C#/forSpbu/MatrixMult.Tests/MultTests.cs @@ -66,8 +66,8 @@ private static IEnumerable TestCases() { foreach (var test in Tests) { - yield return new TestCaseData(MatrixMultiplier.MultiThreadedMultiply, test); - yield return new TestCaseData(MatrixMultiplier.SingleThreadedMultiply, test); + yield return new TestCaseData(new Func(MatrixMultiplier.MultiThreadedMultiply), test); + yield return new TestCaseData(new Func(MatrixMultiplier.SingleThreadedMultiply), test); } } diff --git a/C#/forSpbu/MatrixMult/Matrix.cs b/C#/forSpbu/MatrixMult/Matrix.cs index 20e3250..8a12aea 100644 --- a/C#/forSpbu/MatrixMult/Matrix.cs +++ b/C#/forSpbu/MatrixMult/Matrix.cs @@ -67,16 +67,6 @@ public int GetElement(int firstInd, int secondInd) => ? throw new ArgumentOutOfRangeException(nameof(secondInd)) : this._elements[firstInd, secondInd]; - /// - /// Number of matrix rows - /// - public int Height => this._elements.GetLength(0); - - /// - /// Number of matrix columns - /// - public int Width => this._elements.GetLength(1); - /// /// Returns matrix as array of string /// @@ -99,4 +89,14 @@ public string[] GetStringRepresentation() /// Matrix elements /// private readonly int[,] _elements; + + /// + /// Number of matrix rows + /// + public int Height => this._elements.GetLength(0); + + /// + /// Number of matrix columns + /// + public int Width => this._elements.GetLength(1); } \ No newline at end of file From b0412813673750771adb0fd191559f15a9771abe Mon Sep 17 00:00:00 2001 From: IgnatSergeev Date: Sun, 29 Oct 2023 16:40:22 +0300 Subject: [PATCH 13/13] Changed order --- C#/forSpbu/MatrixMult/Matrix.cs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/C#/forSpbu/MatrixMult/Matrix.cs b/C#/forSpbu/MatrixMult/Matrix.cs index 9fd94ad..23b88c2 100644 --- a/C#/forSpbu/MatrixMult/Matrix.cs +++ b/C#/forSpbu/MatrixMult/Matrix.cs @@ -5,6 +5,21 @@ namespace MatrixMult; /// public class Matrix { + /// + /// Matrix elements + /// + private readonly int[,] _elements; + + /// + /// Number of matrix rows + /// + public int Height => this._elements.GetLength(0); + + /// + /// Number of matrix columns + /// + public int Width => this._elements.GetLength(1); + /// /// Constructs empty matrix /// @@ -83,19 +98,4 @@ public string[] GetStringRepresentation() return lines; } - - /// - /// Matrix elements - /// - private readonly int[,] _elements; - - /// - /// Number of matrix rows - /// - public int Height => this._elements.GetLength(0); - - /// - /// Number of matrix columns - /// - public int Width => this._elements.GetLength(1); } \ No newline at end of file