Skip to content
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 18 additions & 0 deletions C#/forSpbu/MatrixMult.Benchmark/MatrixMult.Benchmark.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.9" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MatrixMult\MatrixMult.csproj" />
</ItemGroup>

</Project>
41 changes: 41 additions & 0 deletions C#/forSpbu/MatrixMult.Benchmark/MatrixMultBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using BenchmarkDotNet.Attributes;
namespace MatrixMult.Benchmark;

public class MatrixMultBenchmark
{
[Params(12, 24, 48, 96, 192, 384, 768, 1536)]
public int Size { get; set; }
private Matrix _fst = new Matrix();
private Matrix _sec = new Matrix();

[GlobalSetup]
public void GenerateRandomMatrix()
{
var random = new Random();
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++)
{
fstElements[i, j] = random.Next();
secElements[i, j] = random.Next();
}
}

_fst = new Matrix(fstElements);
_sec = new Matrix(secElements);
}

[Benchmark]
public void MultiThreaded()
{
MatrixMultiplier.MultiThreadedMultiply(_fst, _sec);
}

[Benchmark]
public void SingleThreaded()
{
MatrixMultiplier.SingleThreadedMultiply(_fst, _sec);
}
}
5 changes: 5 additions & 0 deletions C#/forSpbu/MatrixMult.Benchmark/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using MatrixMult.Benchmark;
using BenchmarkDotNet.Running;

var table = BenchmarkRunner.Run<MatrixMultBenchmark>();
Console.WriteLine(table);
24 changes: 24 additions & 0 deletions C#/forSpbu/MatrixMult.Tests/MatrixMult.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.5.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MatrixMult\MatrixMult.csproj" />
</ItemGroup>

</Project>
108 changes: 108 additions & 0 deletions C#/forSpbu/MatrixMult.Tests/MultTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
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[,]
{
{ 10, 13 },
{ 22, 29 }
})
),
(
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<TestCaseData> TestCases()
{
foreach (var test in Tests)
{
yield return new TestCaseData(new Func<Matrix, Matrix, Matrix>(MatrixMultiplier.MultiThreadedMultiply), test);
yield return new TestCaseData(new Func<Matrix, Matrix, Matrix>(MatrixMultiplier.SingleThreadedMultiply), 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(TestCases))]
public static void MultiplyMatricesTest(Func<Matrix, Matrix, Matrix> matrixMultImpl, (Matrix, Matrix, Matrix?) test)
{
if (test.Item3 == null)
{
Assert.Throws<MatrixMultiplierException>(() => matrixMultImpl(test.Item1, test.Item2));
}
else
{
var multResult = matrixMultImpl(test.Item1, test.Item2);
Assert.That(AreMatricesEqual(multResult, test.Item3), Is.True);
}
}
}
1 change: 1 addition & 0 deletions C#/forSpbu/MatrixMult.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using NUnit.Framework;
101 changes: 101 additions & 0 deletions C#/forSpbu/MatrixMult/Matrix.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
namespace MatrixMult;

/// <summary>
/// Class with matrix container
/// </summary>
public class Matrix
{
/// <summary>
/// Matrix elements
/// </summary>
private readonly int[,] _elements;

/// <summary>
/// Number of matrix rows
/// </summary>
public int Height => this._elements.GetLength(0);

/// <summary>
/// Number of matrix columns
/// </summary>
public int Width => this._elements.GetLength(1);

/// <summary>
/// Constructs empty matrix
/// </summary>
public Matrix()
Comment on lines +21 to +26

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Всё-таки лучше как StyleCop советует: поля, конструкторы, свойства, методы

{
this._elements = new int[0, 0];
}

/// <summary>
/// Constructs matrix with given elements
/// </summary>
/// <param name="newElements">Matrix elements</param>
public Matrix(int [,] newElements)
{
this._elements = newElements;
}

/// <summary>
/// Constructs matrix with given string lines
/// </summary>
/// <param name="lines">Array of lines to build matrix from</param>
/// <exception cref="MatrixCreationException">If given array of lines is incorrect</exception>
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];
for (int i = 0; i < localHeight; i++)
{
if (splitLines[i].Length != localWidth)
{
throw new MatrixCreationException("Inconsistent lines length");
}

for (var j = 0; j < localWidth; j++)
{
if (!int.TryParse(splitLines[i][j], out var parseValue))
{
throw new MatrixCreationException("Incorrect matrix element");
}
this._elements[i, j] = parseValue;
}
}
}

/// <summary>
/// Returns element by index
/// </summary>
/// <param name="firstInd">First index</param>
/// <param name="secondInd">Second index</param>
/// <returns>Value of matrix element in given position</returns>
/// <exception cref="IndexOutOfRangeException">If some index is out of range</exception>
public int GetElement(int firstInd, int secondInd) =>
firstInd < 0 || firstInd >= this.Height
? throw new ArgumentOutOfRangeException(nameof(firstInd))
: secondInd < 0 || secondInd >= this.Width
? throw new ArgumentOutOfRangeException(nameof(secondInd))
: this._elements[firstInd, secondInd];

/// <summary>
/// Returns matrix as array of string
/// </summary>
/// <returns>String array matrix representation</returns>
public string[] GetStringRepresentation()
{
var lines = new string[this.Height];
for (int i = 0; i < this.Height; i++)
{
for (int j = 0; j < this.Width; j++)
{
lines[i] += _elements[i, j] + " ";
}
}

return lines;
}
}
15 changes: 15 additions & 0 deletions C#/forSpbu/MatrixMult/MatrixCreationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace MatrixMult;

/// <summary>
/// Class for matrix creation exceptions
/// </summary>
public class MatrixCreationException : Exception
{
public MatrixCreationException() : base()
{
}

public MatrixCreationException(string message) : base(message)
{
}
}
10 changes: 10 additions & 0 deletions C#/forSpbu/MatrixMult/MatrixMult.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Loading