17 changed files with 1020 additions and 914 deletions
@ -0,0 +1,34 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio 14 |
|||
VisualStudioVersion = 14.0.25420.1 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "src\Benchmark\Benchmark.csproj", "{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Numerics", "src\Numerics\Numerics.csproj", "{B7CAE5F4-A23F-4438-B5BE-41226618B695}" |
|||
EndProject |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8DFE7990-CAC9-4BCC-A1D7-F86F0892DD84}" |
|||
ProjectSection(SolutionItems) = preProject |
|||
paket.dependencies = paket.dependencies |
|||
paket.lock = paket.lock |
|||
EndProjectSection |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Release|x64 = Release|x64 |
|||
Release|x86 = Release|x86 |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|x64.ActiveCfg = Release|x64 |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|x64.Build.0 = Release|x64 |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|x86.ActiveCfg = Release|x64 |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|x86.Build.0 = Release|x64 |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x64.ActiveCfg = Release|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x64.Build.0 = Release|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x86.ActiveCfg = Release|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x86.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
EndGlobal |
|||
@ -1,38 +0,0 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio 2013 |
|||
VisualStudioVersion = 12.0.30723.0 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Performance", "src\Performance\Performance.csproj", "{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Numerics", "src\Numerics\Numerics.csproj", "{B7CAE5F4-A23F-4438-B5BE-41226618B695}" |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release (No MKL)|Any CPU = Release (No MKL)|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
Release-Signed|Any CPU = Release-Signed|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release (No MKL)|Any CPU.ActiveCfg = Release (No MKL)|Any CPU |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release (No MKL)|Any CPU.Build.0 = Release (No MKL)|Any CPU |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU |
|||
{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}.Release-Signed|Any CPU.Build.0 = Release|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release (No MKL)|Any CPU.ActiveCfg = Release|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release (No MKL)|Any CPU.Build.0 = Release|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Any CPU.ActiveCfg = Release-Signed|Any CPU |
|||
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Any CPU.Build.0 = Release-Signed|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
EndGlobal |
|||
@ -0,0 +1,173 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
|||
<PropertyGroup> |
|||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|||
<ProjectGuid>{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}</ProjectGuid> |
|||
<OutputType>Exe</OutputType> |
|||
<AppDesignerFolder>Properties</AppDesignerFolder> |
|||
<RootNamespace>Benchmark</RootNamespace> |
|||
<AssemblyName>Benchmark</AssemblyName> |
|||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |
|||
<FileAlignment>512</FileAlignment> |
|||
</PropertyGroup> |
|||
<PropertyGroup> |
|||
<StartupObject /> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> |
|||
<OutputPath>bin\Release\</OutputPath> |
|||
<DefineConstants>TRACE;NATIVE</DefineConstants> |
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|||
<Optimize>true</Optimize> |
|||
<DebugType>pdbonly</DebugType> |
|||
<PlatformTarget>x64</PlatformTarget> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> |
|||
<Prefer32Bit>false</Prefer32Bit> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> |
|||
<OutputPath>bin\Release\</OutputPath> |
|||
<DefineConstants>TRACE;NATIVE</DefineConstants> |
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|||
<Optimize>true</Optimize> |
|||
<DebugType>pdbonly</DebugType> |
|||
<PlatformTarget>x86</PlatformTarget> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> |
|||
<Prefer32Bit>true</Prefer32Bit> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<Reference Include="System" /> |
|||
<Reference Include="System.Core" /> |
|||
<Reference Include="System.Numerics" /> |
|||
<Reference Include="System.Xml.Linq" /> |
|||
<Reference Include="System.Data.DataSetExtensions" /> |
|||
<Reference Include="Microsoft.CSharp" /> |
|||
<Reference Include="System.Data" /> |
|||
<Reference Include="System.Xml" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Compile Include="FFT.cs" /> |
|||
<Compile Include="LinearAlgebra\DenseVectorAdd.cs" /> |
|||
<Compile Include="LinearAlgebra\DenseMatrixProduct.cs" /> |
|||
<Compile Include="Program.cs" /> |
|||
<Compile Include="Properties\AssemblyInfo.cs" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<None Include="paket.references" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Numerics\Numerics.csproj"> |
|||
<Project>{b7cae5f4-a23f-4438-b5be-41226618b695}</Project> |
|||
<Name>Numerics</Name> |
|||
</ProjectReference> |
|||
</ItemGroup> |
|||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
|||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
|||
Other similar extension points exist, see Microsoft.Common.targets. |
|||
<Target Name="BeforeBuild"> |
|||
</Target> |
|||
<Target Name="AfterBuild"> |
|||
</Target> |
|||
--> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'"> |
|||
<ItemGroup> |
|||
<Reference Include="BenchmarkDotNet"> |
|||
<HintPath>..\..\packages\benchmark\BenchmarkDotNet\lib\net45\BenchmarkDotNet.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'"> |
|||
<ItemGroup> |
|||
<Reference Include="BenchmarkDotNet.Core"> |
|||
<HintPath>..\..\packages\benchmark\BenchmarkDotNet.Core\lib\net45\BenchmarkDotNet.Core.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
<Reference Include="System.Management"> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'"> |
|||
<ItemGroup> |
|||
<Reference Include="BenchmarkDotNet.Toolchains.Roslyn"> |
|||
<HintPath>..\..\packages\benchmark\BenchmarkDotNet.Toolchains.Roslyn\lib\net45\BenchmarkDotNet.Toolchains.Roslyn.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
<ItemGroup> |
|||
<Analyzer Include="..\..\packages\benchmark\Microsoft.CodeAnalysis.Analyzers\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll"> |
|||
<Paket>True</Paket> |
|||
</Analyzer> |
|||
<Analyzer Include="..\..\packages\benchmark\Microsoft.CodeAnalysis.Analyzers\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll"> |
|||
<Paket>True</Paket> |
|||
</Analyzer> |
|||
</ItemGroup> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'"> |
|||
<ItemGroup> |
|||
<Reference Include="Microsoft.CodeAnalysis"> |
|||
<HintPath>..\..\packages\benchmark\Microsoft.CodeAnalysis.Common\lib\net45\Microsoft.CodeAnalysis.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'"> |
|||
<ItemGroup> |
|||
<Reference Include="Microsoft.CodeAnalysis.CSharp"> |
|||
<HintPath>..\..\packages\benchmark\Microsoft.CodeAnalysis.CSharp\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'"> |
|||
<ItemGroup> |
|||
<Reference Include="System.Collections.Immutable"> |
|||
<HintPath>..\..\packages\benchmark\System.Collections.Immutable\lib\netstandard1.0\System.Collections.Immutable.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'"> |
|||
<ItemGroup> |
|||
<Reference Include="System.Reflection.Metadata"> |
|||
<HintPath>..\..\packages\benchmark\System.Reflection.Metadata\lib\netstandard1.1\System.Reflection.Metadata.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'"> |
|||
<ItemGroup> |
|||
<Reference Include="System.Threading.Tasks.Extensions"> |
|||
<HintPath>..\..\packages\benchmark\System.Threading.Tasks.Extensions\lib\netstandard1.0\System.Threading.Tasks.Extensions.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
</Project> |
|||
@ -0,0 +1,48 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Numerics; |
|||
using BenchmarkDotNet.Attributes; |
|||
using MathNet.Numerics; |
|||
using MathNet.Numerics.IntegralTransforms; |
|||
|
|||
namespace Benchmark |
|||
{ |
|||
public class FFT |
|||
{ |
|||
readonly Dictionary<int, Complex[]> _data = new Dictionary<int, Complex[]>(); |
|||
|
|||
[Params(64, 65, 4096, 4097, 65536, 65537, 1048576, 1048577)] |
|||
public int N { get; set; } |
|||
|
|||
[Setup] |
|||
public void Setup() |
|||
{ |
|||
var realSinusoidal = Generate.Sinusoidal(1048577, 32, -2.0, 2.0); |
|||
var imagSawtooth = Generate.Sawtooth(1048577, 32, -20.0, 20.0); |
|||
var signal = Generate.Map2(realSinusoidal, imagSawtooth, (r, i) => new Complex(r, i)); |
|||
foreach (var n in new[] { 64, 65, 4096, 4097, 65536, 65537, 1048576, 1048577 }) |
|||
{ |
|||
var s = new Complex[n]; |
|||
Array.Copy(signal, 0, s, 0, n); |
|||
_data[n] = s; |
|||
} |
|||
|
|||
Control.NativeProviderPath = @"C:\Triage\NATIVE-Win\"; |
|||
Control.UseNativeMKL(); |
|||
} |
|||
|
|||
[Benchmark(Baseline = true, OperationsPerInvoke = 2)] |
|||
public void Managed() |
|||
{ |
|||
Fourier.BluesteinForward(_data[N], FourierOptions.NoScaling); |
|||
Fourier.BluesteinInverse(_data[N], FourierOptions.NoScaling); |
|||
} |
|||
|
|||
[Benchmark(OperationsPerInvoke = 2)] |
|||
public void NativeMKL() |
|||
{ |
|||
Fourier.Forward(_data[N], FourierOptions.NoScaling); |
|||
Fourier.Inverse(_data[N], FourierOptions.NoScaling); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,556 @@ |
|||
using System; |
|||
using MathNet.Numerics; |
|||
using MathNet.Numerics.LinearAlgebra; |
|||
using MathNet.Numerics.Providers.LinearAlgebra; |
|||
using MathNet.Numerics.Providers.LinearAlgebra.Mkl; |
|||
using MathNet.Numerics.Threading; |
|||
|
|||
namespace Benchmark.LinearAlgebra |
|||
{ |
|||
// public class DenseMatrixProduct
|
|||
// {
|
|||
// readonly int _rounds;
|
|||
// readonly Matrix<double> _a;
|
|||
// readonly Matrix<double> _b;
|
|||
|
|||
// readonly ILinearAlgebraProvider _managed = new ManagedLinearAlgebraProvider();
|
|||
// readonly ILinearAlgebraProvider _mkl = new MklLinearAlgebraProvider();
|
|||
// readonly ILinearAlgebraProvider _safeProvider = new SafeProvider();
|
|||
// readonly ILinearAlgebraProvider _unsafeProvider = new UnsafeProvider();
|
|||
// readonly ILinearAlgebraProvider _experimentalProvider = new ExperimentalProvider();
|
|||
|
|||
// public DenseMatrixProduct(int size, int rounds)
|
|||
// {
|
|||
// _rounds = rounds;
|
|||
|
|||
// _b = Matrix<double>.Build.Random(size, size);
|
|||
// _a = Matrix<double>.Build.Random(size, size);
|
|||
|
|||
// _managed.InitializeVerify();
|
|||
// _safeProvider.InitializeVerify();
|
|||
// _unsafeProvider.InitializeVerify();
|
|||
// _experimentalProvider.InitializeVerify();
|
|||
|
|||
//#if NATIVE
|
|||
// _mkl.InitializeVerify();
|
|||
//#endif
|
|||
// }
|
|||
|
|||
// public static void Verify(int size)
|
|||
// {
|
|||
// var x = new DenseMatrixProduct(size, 1);
|
|||
// var managedResult = x.ManagedProvider();
|
|||
// var mklResult = x.MklProvider();
|
|||
// var safeResult = x.SafeProvider();
|
|||
// var unsafeResult = x.UnsafeProvider();
|
|||
// var experimentalResult = x.ExperimentalProvider();
|
|||
|
|||
// Console.WriteLine(managedResult.ToString());
|
|||
// //Console.WriteLine(mklResult.ToString());
|
|||
// //Console.WriteLine(safeResult.ToString());
|
|||
// //Console.WriteLine(unsafeResult.ToString());
|
|||
// //Console.WriteLine(experimentalResult.ToString());
|
|||
|
|||
// if (!managedResult.AlmostEqual(mklResult, 1e-12))
|
|||
// {
|
|||
// throw new Exception("MklProvider");
|
|||
// }
|
|||
// if (!managedResult.AlmostEqual(safeResult, 1e-12))
|
|||
// {
|
|||
// throw new Exception("SafeProvider");
|
|||
// }
|
|||
// if (!managedResult.AlmostEqual(unsafeResult, 1e-12))
|
|||
// {
|
|||
// throw new Exception("UnsafeProvider");
|
|||
// }
|
|||
// if (!managedResult.AlmostEqual(experimentalResult, 1e-12))
|
|||
// {
|
|||
// throw new Exception("ExperimentalProvider");
|
|||
// }
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("ManagedProvider")]
|
|||
// public Matrix<double> ManagedProvider()
|
|||
// {
|
|||
// Control.LinearAlgebraProvider = _managed;
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// z = _a*z;
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("MklProvider")]
|
|||
// public Matrix<double> MklProvider()
|
|||
// {
|
|||
// Control.LinearAlgebraProvider = _mkl;
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// z = _a*z;
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("SafeProvider")]
|
|||
// public Matrix<double> SafeProvider()
|
|||
// {
|
|||
// Control.LinearAlgebraProvider = _safeProvider;
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// z = _a*z;
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("UnsafeProvider")]
|
|||
// public Matrix<double> UnsafeProvider()
|
|||
// {
|
|||
// Control.LinearAlgebraProvider = _unsafeProvider;
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// z = _a*z;
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("ExperimentalProvider")]
|
|||
// public Matrix<double> ExperimentalProvider()
|
|||
// {
|
|||
// Control.LinearAlgebraProvider = _experimentalProvider;
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// z = _a*z;
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
// }
|
|||
|
|||
// public class SafeProvider : ManagedLinearAlgebraProvider
|
|||
// {
|
|||
// public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result)
|
|||
// {
|
|||
// if (rowsX + columnsY <= Control.ParallelizeOrder)
|
|||
// {
|
|||
// for (int i = 0; i < rowsX; ++i)
|
|||
// {
|
|||
// for (int j = 0; j < columnsY; ++j)
|
|||
// {
|
|||
// var jrowsY = j*rowsY;
|
|||
// double sum = 0.0;
|
|||
// for (int k = 0; k < columnsX; ++k)
|
|||
// {
|
|||
// sum += x[k*rowsX + i]*y[jrowsY + k];
|
|||
// }
|
|||
// result[j*rowsX + i] = sum;
|
|||
// }
|
|||
// }
|
|||
|
|||
// return;
|
|||
// }
|
|||
|
|||
// double[] xdata;
|
|||
// if (ReferenceEquals(x, result))
|
|||
// {
|
|||
// xdata = (double[])x.Clone();
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// xdata = x;
|
|||
// }
|
|||
|
|||
// double[] ydata;
|
|||
// if (ReferenceEquals(y, result))
|
|||
// {
|
|||
// ydata = (double[])y.Clone();
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// ydata = y;
|
|||
// }
|
|||
|
|||
// Array.Clear(result, 0, result.Length);
|
|||
|
|||
// CacheObliviousMatrixMultiply(xdata, 0, 0, ydata, 0, 0, result, 0, 0, rowsX, columnsY, columnsX, rowsX, columnsY, columnsX, 0);
|
|||
// }
|
|||
|
|||
// public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c)
|
|||
// {
|
|||
// if (transposeA == Transpose.DontTranspose && transposeB == Transpose.DontTranspose && alpha == 1.0 && beta == 0.0)
|
|||
// {
|
|||
// MatrixMultiply(a, rowsA, columnsA, b, rowsB, columnsB, c);
|
|||
// return;
|
|||
// }
|
|||
|
|||
// base.MatrixMultiplyWithUpdate(transposeA, transposeB, alpha, a, rowsA, columnsA, b, rowsB, columnsB, beta, c);
|
|||
// }
|
|||
|
|||
// static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level)
|
|||
// {
|
|||
// if (m + n <= Control.ParallelizeOrder)
|
|||
// {
|
|||
// for (var m1 = 0; m1 < m; m1++)
|
|||
// {
|
|||
// var matArowPos = m1 + shiftArow;
|
|||
// var matCrowPos = m1 + shiftCrow;
|
|||
// for (var n1 = 0; n1 < n; ++n1)
|
|||
// {
|
|||
// var boffset = ((n1 + shiftBcol)*constK) + shiftBrow;
|
|||
// double sum = 0;
|
|||
// for (var k1 = 0; k1 < k; ++k1)
|
|||
// {
|
|||
// sum += matrixA[((k1 + shiftAcol)*constM) + matArowPos]*matrixB[boffset + k1];
|
|||
// }
|
|||
|
|||
// result[((n1 + shiftCcol)*constM) + matCrowPos] += sum;
|
|||
// }
|
|||
// }
|
|||
|
|||
// return;
|
|||
// }
|
|||
|
|||
// // divide and conquer
|
|||
// int m2 = m/2, n2 = n/2, k2 = k/2;
|
|||
|
|||
// level++;
|
|||
// if (level <= 2)
|
|||
// {
|
|||
// CommonParallel.Invoke(
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level));
|
|||
|
|||
// CommonParallel.Invoke(
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level));
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level);
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level);
|
|||
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level);
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level);
|
|||
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level);
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level);
|
|||
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level);
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level);
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
|
|||
// public unsafe class UnsafeProvider : ManagedLinearAlgebraProvider
|
|||
// {
|
|||
// public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result)
|
|||
// {
|
|||
// if (rowsX + columnsY <= Control.ParallelizeOrder)
|
|||
// {
|
|||
// fixed (double* resultPtr = &result[0])
|
|||
// fixed (double* xPtr = &x[0])
|
|||
// fixed (double* yPtr = &y[0])
|
|||
// {
|
|||
// double* a = xPtr;
|
|||
// double* c = resultPtr;
|
|||
// for (int i = 0; i < rowsX; ++i)
|
|||
// {
|
|||
// double* b = yPtr;
|
|||
// double* cj = c;
|
|||
// for (int j = 0; j < columnsY; ++j)
|
|||
// {
|
|||
// double sum = 0.0;
|
|||
// for (int k = 0; k < columnsX; ++k)
|
|||
// {
|
|||
// sum += a[k*rowsX]*b[k];
|
|||
// }
|
|||
// *cj = sum;
|
|||
// cj += rowsX;
|
|||
// b += rowsY;
|
|||
// }
|
|||
// a++;
|
|||
// c++;
|
|||
// }
|
|||
// }
|
|||
|
|||
// return;
|
|||
// }
|
|||
|
|||
// double[] xdata;
|
|||
// if (ReferenceEquals(x, result))
|
|||
// {
|
|||
// xdata = (double[])x.Clone();
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// xdata = x;
|
|||
// }
|
|||
|
|||
// double[] ydata;
|
|||
// if (ReferenceEquals(y, result))
|
|||
// {
|
|||
// ydata = (double[])y.Clone();
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// ydata = y;
|
|||
// }
|
|||
|
|||
// Array.Clear(result, 0, result.Length);
|
|||
|
|||
// CacheObliviousMatrixMultiply(xdata, 0, 0, ydata, 0, 0, result, 0, 0, rowsX, columnsY, columnsX, rowsX, columnsY, columnsX, 0);
|
|||
// }
|
|||
|
|||
// public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c)
|
|||
// {
|
|||
// if (transposeA == Transpose.DontTranspose && transposeB == Transpose.DontTranspose && alpha == 1.0 && beta == 0.0)
|
|||
// {
|
|||
// MatrixMultiply(a, rowsA, columnsA, b, rowsB, columnsB, c);
|
|||
// return;
|
|||
// }
|
|||
|
|||
// base.MatrixMultiplyWithUpdate(transposeA, transposeB, alpha, a, rowsA, columnsA, b, rowsB, columnsB, beta, c);
|
|||
// }
|
|||
|
|||
// static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level)
|
|||
// {
|
|||
// if (m + n <= Control.ParallelizeOrder)
|
|||
// {
|
|||
// fixed (double* resultPtr = &result[0])
|
|||
// fixed (double* aPtr = &matrixA[0])
|
|||
// fixed (double* bPtr = &matrixB[0])
|
|||
// {
|
|||
// double* a = aPtr + shiftArow;
|
|||
// double* c = resultPtr + shiftCrow;
|
|||
// for (var m1 = 0; m1 < m; m1++)
|
|||
// {
|
|||
// for (var n1 = 0; n1 < n; ++n1)
|
|||
// {
|
|||
// double* b = bPtr + (n1 + shiftBcol)*constK + shiftBrow;
|
|||
// double sum = 0;
|
|||
// for (var k1 = 0; k1 < k; ++k1)
|
|||
// {
|
|||
// sum += a[((k1 + shiftAcol)*constM)]*b[k1];
|
|||
// }
|
|||
|
|||
// c[((n1 + shiftCcol)*constM)] += sum;
|
|||
// }
|
|||
// a++;
|
|||
// c++;
|
|||
// }
|
|||
// }
|
|||
|
|||
// return;
|
|||
// }
|
|||
|
|||
// // divide and conquer
|
|||
// int m2 = m/2, n2 = n/2, k2 = k/2;
|
|||
|
|||
// level++;
|
|||
// if (level <= 2)
|
|||
// {
|
|||
// CommonParallel.Invoke(
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level));
|
|||
|
|||
// CommonParallel.Invoke(
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level),
|
|||
// () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level));
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level);
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level);
|
|||
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level);
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level);
|
|||
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level);
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level);
|
|||
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level);
|
|||
// CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level);
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
|
|||
// public class ExperimentalProvider : ManagedLinearAlgebraProvider
|
|||
// {
|
|||
// public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result)
|
|||
// {
|
|||
// MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result);
|
|||
// }
|
|||
|
|||
// public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c)
|
|||
// {
|
|||
// if (a == null)
|
|||
// {
|
|||
// throw new ArgumentNullException("a");
|
|||
// }
|
|||
|
|||
// if (b == null)
|
|||
// {
|
|||
// throw new ArgumentNullException("b");
|
|||
// }
|
|||
|
|||
// if (c == null)
|
|||
// {
|
|||
// throw new ArgumentNullException("c");
|
|||
// }
|
|||
|
|||
// if (transposeA != Transpose.DontTranspose)
|
|||
// {
|
|||
// Swap(ref rowsA, ref columnsA);
|
|||
// }
|
|||
|
|||
// if (transposeB != Transpose.DontTranspose)
|
|||
// {
|
|||
// Swap(ref rowsB, ref columnsB);
|
|||
// }
|
|||
|
|||
// if (columnsA != rowsB)
|
|||
// {
|
|||
// throw new ArgumentOutOfRangeException(String.Format("columnsA ({0}) != rowsB ({1})", columnsA, rowsB));
|
|||
// }
|
|||
|
|||
// if (rowsA*columnsA != a.Length)
|
|||
// {
|
|||
// throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsA ({1}) != a.Length ({2})", rowsA, columnsA, a.Length));
|
|||
// }
|
|||
|
|||
// if (rowsB*columnsB != b.Length)
|
|||
// {
|
|||
// throw new ArgumentOutOfRangeException(String.Format("rowsB ({0}) * columnsB ({1}) != b.Length ({2})", rowsB, columnsB, b.Length));
|
|||
// }
|
|||
|
|||
// if (rowsA*columnsB != c.Length)
|
|||
// {
|
|||
// throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsB ({1}) != c.Length ({2})", rowsA, columnsB, c.Length));
|
|||
// }
|
|||
|
|||
// // handle the degenerate cases
|
|||
// if (beta == 0.0)
|
|||
// {
|
|||
// Array.Clear(c, 0, c.Length);
|
|||
// }
|
|||
// else if (beta != 1.0)
|
|||
// {
|
|||
// ScaleArray(beta, c, c);
|
|||
// }
|
|||
|
|||
// if (alpha == 0.0)
|
|||
// {
|
|||
// return;
|
|||
// }
|
|||
|
|||
// // Extract column arrays
|
|||
// var columnDataB = new double[columnsB][];
|
|||
// for (int i = 0; i < columnDataB.Length; i++)
|
|||
// {
|
|||
// columnDataB[i] = GetColumn(transposeB, i, rowsB, columnsB, b);
|
|||
// }
|
|||
|
|||
// var shouldNotParallelize = rowsA + columnsB + columnsA < Control.ParallelizeOrder || Control.MaxDegreeOfParallelism < 2;
|
|||
// if (shouldNotParallelize)
|
|||
// {
|
|||
// for (int i = 0; i < rowsA; i++)
|
|||
// {
|
|||
// var row = GetRow(transposeA, i, rowsA, columnsA, a);
|
|||
// for (int j = 0; j < columnsB; j++)
|
|||
// {
|
|||
// var col = columnDataB[j];
|
|||
// double sum = 0;
|
|||
// for (int ii = 0; ii < row.Length; ii++)
|
|||
// {
|
|||
// sum += row[ii]*col[ii];
|
|||
// }
|
|||
|
|||
// c[j*rowsA + i] += alpha*sum;
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// CommonParallel.For(0, rowsA, 1, (u, v) =>
|
|||
// {
|
|||
// for (int i = u; i < v; i++)
|
|||
// {
|
|||
// // for each row in a
|
|||
// var row = GetRow(transposeA, i, rowsA, columnsA, a);
|
|||
// for (int j = 0; j < columnsB; j++)
|
|||
// {
|
|||
// var column = columnDataB[j];
|
|||
// double sum = 0;
|
|||
// for (int ii = 0; ii < row.Length; ii++)
|
|||
// {
|
|||
// sum += row[ii]*column[ii];
|
|||
// }
|
|||
|
|||
// c[j*rowsA + i] += alpha*sum;
|
|||
// }
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
// }
|
|||
|
|||
// static void Swap(ref int first, ref int second)
|
|||
// {
|
|||
// var prior = first;
|
|||
// first = second;
|
|||
// second = prior;
|
|||
// }
|
|||
|
|||
// /// <summary>
|
|||
// /// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
|
|||
// /// </summary>
|
|||
// static double[] GetRow(Transpose transpose, int rowindx, int numRows, int numCols, double[] matrix)
|
|||
// {
|
|||
// var ret = new double[numCols];
|
|||
// if (transpose == Transpose.DontTranspose)
|
|||
// {
|
|||
// for (int i = 0; i < numCols; i++)
|
|||
// {
|
|||
// ret[i] = matrix[(i*numRows) + rowindx];
|
|||
// }
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// Array.Copy(matrix, rowindx*numCols, ret, 0, numCols);
|
|||
// }
|
|||
|
|||
// return ret;
|
|||
// }
|
|||
|
|||
// /// <summary>
|
|||
// /// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
|
|||
// /// </summary>
|
|||
// static double[] GetColumn(Transpose transpose, int colindx, int numRows, int numCols, double[] matrix)
|
|||
// {
|
|||
// var ret = new double[numRows];
|
|||
// if (transpose == Transpose.DontTranspose)
|
|||
// {
|
|||
// Array.Copy(matrix, colindx*numRows, ret, 0, numRows);
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// for (int i = 0; i < numRows; i++)
|
|||
// {
|
|||
// ret[i] = matrix[(i*numCols) + colindx];
|
|||
// }
|
|||
// }
|
|||
|
|||
// return ret;
|
|||
// }
|
|||
// }
|
|||
} |
|||
@ -0,0 +1,149 @@ |
|||
using System; |
|||
using MathNet.Numerics; |
|||
using MathNet.Numerics.LinearAlgebra; |
|||
using MathNet.Numerics.LinearAlgebra.Storage; |
|||
using MathNet.Numerics.Providers.LinearAlgebra; |
|||
using MathNet.Numerics.Providers.LinearAlgebra.Mkl; |
|||
using MathNet.Numerics.Threading; |
|||
|
|||
namespace Benchmark.LinearAlgebra |
|||
{ |
|||
// public class DenseVectorAdd
|
|||
// {
|
|||
// readonly int _rounds;
|
|||
// readonly Vector<double> _a;
|
|||
// readonly Vector<double> _b;
|
|||
|
|||
// readonly ILinearAlgebraProvider _managed = new ManagedLinearAlgebraProvider();
|
|||
// readonly ILinearAlgebraProvider _mkl = new MklLinearAlgebraProvider();
|
|||
|
|||
// public DenseVectorAdd(int size, int rounds)
|
|||
// {
|
|||
// _rounds = rounds;
|
|||
|
|||
// _b = Vector<double>.Build.Random(size);
|
|||
// _a = Vector<double>.Build.Random(size);
|
|||
|
|||
// _managed.InitializeVerify();
|
|||
// Control.LinearAlgebraProvider = _managed;
|
|||
|
|||
//#if NATIVE
|
|||
// _mkl.InitializeVerify();
|
|||
//#endif
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("AddOperator")]
|
|||
// public Vector<double> AddOperator()
|
|||
// {
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// z = _a + z;
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("Map2")]
|
|||
// public Vector<double> Map2()
|
|||
// {
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// z = _a.Map2((u, v) => u + v, z);
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("Loop")]
|
|||
// public Vector<double> Loop()
|
|||
// {
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// var aa = ((DenseVectorStorage<double>)_a.Storage).Data;
|
|||
// var az = ((DenseVectorStorage<double>)z.Storage).Data;
|
|||
// var ar = new Double[aa.Length];
|
|||
// for (int k = 0; k < ar.Length; k++)
|
|||
// {
|
|||
// ar[k] = aa[k] + az[k];
|
|||
// }
|
|||
// z = Vector<double>.Build.Dense(ar);
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("ParallelLoop4096")]
|
|||
// public Vector<double> ParallelLoop4096()
|
|||
// {
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// var aa = ((DenseVectorStorage<double>)_a.Storage).Data;
|
|||
// var az = ((DenseVectorStorage<double>)z.Storage).Data;
|
|||
// var ar = new Double[aa.Length];
|
|||
// CommonParallel.For(0, ar.Length, 4096, (u, v) =>
|
|||
// {
|
|||
// for (int k = u; k < v; k++)
|
|||
// {
|
|||
// ar[k] = aa[k] + az[k];
|
|||
// }
|
|||
// });
|
|||
// z = Vector<double>.Build.Dense(ar);
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("ParallelLoop32768")]
|
|||
// public Vector<double> ParallelLoop32768()
|
|||
// {
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// var aa = ((DenseVectorStorage<double>)_a.Storage).Data;
|
|||
// var az = ((DenseVectorStorage<double>)z.Storage).Data;
|
|||
// var ar = new Double[aa.Length];
|
|||
// CommonParallel.For(0, ar.Length, 32768, (u, v) =>
|
|||
// {
|
|||
// for (int k = u; k < v; k++)
|
|||
// {
|
|||
// ar[k] = aa[k] + az[k];
|
|||
// }
|
|||
// });
|
|||
// z = Vector<double>.Build.Dense(ar);
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
// [BenchSharkTask("ManagedProvider")]
|
|||
// public Vector<double> ManagedProvider()
|
|||
// {
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// var aa = ((DenseVectorStorage<double>)_a.Storage).Data;
|
|||
// var az = ((DenseVectorStorage<double>)z.Storage).Data;
|
|||
// var ar = new Double[aa.Length];
|
|||
// _managed.AddArrays(aa, az, ar);
|
|||
// z = Vector<double>.Build.Dense(ar);
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
|
|||
//#if NATIVEMKL
|
|||
// [BenchSharkTask("MklProvider")]
|
|||
// public Vector<double> MklProvider()
|
|||
// {
|
|||
// var z = _b;
|
|||
// for (int i = 0; i < _rounds; i++)
|
|||
// {
|
|||
// var aa = ((DenseVectorStorage<double>)_a.Storage).Data;
|
|||
// var az = ((DenseVectorStorage<double>)z.Storage).Data;
|
|||
// var ar = new Double[aa.Length];
|
|||
// _mkl.AddArrays(aa, az, ar);
|
|||
// z = Vector<double>.Build.Dense(ar);
|
|||
// }
|
|||
// return z;
|
|||
// }
|
|||
//#endif
|
|||
// }
|
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using System; |
|||
using BenchmarkDotNet.Running; |
|||
using MathNet.Numerics; |
|||
|
|||
namespace Benchmark |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static void Main() |
|||
{ |
|||
//Control.NativeProviderPath = @"..\..\..\..\out\MKL\Windows\";
|
|||
Control.NativeProviderPath = @"C:\Triage\NATIVE-Win\"; |
|||
|
|||
Console.WriteLine("Providers:"); |
|||
if (Control.TryUseNativeMKL()) Console.WriteLine(Control.LinearAlgebraProvider); |
|||
if (Control.TryUseNativeCUDA()) Console.WriteLine(Control.LinearAlgebraProvider); |
|||
if (Control.TryUseNativeOpenBLAS()) Console.WriteLine(Control.LinearAlgebraProvider); |
|||
|
|||
BenchmarkRunner.Run<FFT>(); |
|||
|
|||
//Benchmark(new LinearAlgebra.DenseVectorAdd(10000000,1), 10, "Large (10'000'000) - 10x1 iterations");
|
|||
//Benchmark(new LinearAlgebra.DenseVectorAdd(100,1000), 100, "Small (100) - 100x1000 iterations");
|
|||
|
|||
//DenseMatrixProduct.Verify(5);
|
|||
//DenseMatrixProduct.Verify(100);
|
|||
//Benchmark(new DenseMatrixProduct(10,100), 100, "10 - 100x100 iterations");
|
|||
//Benchmark(new DenseMatrixProduct(25, 100), 100, "25 - 100x100 iterations");
|
|||
//Benchmark(new DenseMatrixProduct(50, 10), 100, "50 - 100x10 iterations");
|
|||
//Benchmark(new DenseMatrixProduct(100, 10), 100, "100 - 100x10 iterations");
|
|||
//Benchmark(new DenseMatrixProduct(250, 1), 10, "250 - 10x1 iterations");
|
|||
//Benchmark(new DenseMatrixProduct(500,1), 10, "500 - 10x1 iterations");
|
|||
//Benchmark(new DenseMatrixProduct(1000,1), 2, "1000 - 2x1 iterations");
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
group Benchmark |
|||
BenchmarkDotNet |
|||
@ -1,557 +0,0 @@ |
|||
using System; |
|||
using Binarysharp.Benchmark; |
|||
using MathNet.Numerics; |
|||
using MathNet.Numerics.LinearAlgebra; |
|||
using MathNet.Numerics.Providers.LinearAlgebra; |
|||
using MathNet.Numerics.Providers.LinearAlgebra.Mkl; |
|||
using MathNet.Numerics.Threading; |
|||
|
|||
namespace Performance.LinearAlgebra |
|||
{ |
|||
public class DenseMatrixProduct |
|||
{ |
|||
readonly int _rounds; |
|||
readonly Matrix<double> _a; |
|||
readonly Matrix<double> _b; |
|||
|
|||
readonly ILinearAlgebraProvider _managed = new ManagedLinearAlgebraProvider(); |
|||
readonly ILinearAlgebraProvider _mkl = new MklLinearAlgebraProvider(); |
|||
readonly ILinearAlgebraProvider _safeProvider = new SafeProvider(); |
|||
readonly ILinearAlgebraProvider _unsafeProvider = new UnsafeProvider(); |
|||
readonly ILinearAlgebraProvider _experimentalProvider = new ExperimentalProvider(); |
|||
|
|||
public DenseMatrixProduct(int size, int rounds) |
|||
{ |
|||
_rounds = rounds; |
|||
|
|||
_b = Matrix<double>.Build.Random(size, size); |
|||
_a = Matrix<double>.Build.Random(size, size); |
|||
|
|||
_managed.InitializeVerify(); |
|||
_safeProvider.InitializeVerify(); |
|||
_unsafeProvider.InitializeVerify(); |
|||
_experimentalProvider.InitializeVerify(); |
|||
|
|||
#if NATIVE
|
|||
_mkl.InitializeVerify(); |
|||
#endif
|
|||
} |
|||
|
|||
public static void Verify(int size) |
|||
{ |
|||
var x = new DenseMatrixProduct(size, 1); |
|||
var managedResult = x.ManagedProvider(); |
|||
var mklResult = x.MklProvider(); |
|||
var safeResult = x.SafeProvider(); |
|||
var unsafeResult = x.UnsafeProvider(); |
|||
var experimentalResult = x.ExperimentalProvider(); |
|||
|
|||
Console.WriteLine(managedResult.ToString()); |
|||
//Console.WriteLine(mklResult.ToString());
|
|||
//Console.WriteLine(safeResult.ToString());
|
|||
//Console.WriteLine(unsafeResult.ToString());
|
|||
//Console.WriteLine(experimentalResult.ToString());
|
|||
|
|||
if (!managedResult.AlmostEqual(mklResult, 1e-12)) |
|||
{ |
|||
throw new Exception("MklProvider"); |
|||
} |
|||
if (!managedResult.AlmostEqual(safeResult, 1e-12)) |
|||
{ |
|||
throw new Exception("SafeProvider"); |
|||
} |
|||
if (!managedResult.AlmostEqual(unsafeResult, 1e-12)) |
|||
{ |
|||
throw new Exception("UnsafeProvider"); |
|||
} |
|||
if (!managedResult.AlmostEqual(experimentalResult, 1e-12)) |
|||
{ |
|||
throw new Exception("ExperimentalProvider"); |
|||
} |
|||
} |
|||
|
|||
[BenchSharkTask("ManagedProvider")] |
|||
public Matrix<double> ManagedProvider() |
|||
{ |
|||
Control.LinearAlgebraProvider = _managed; |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
z = _a*z; |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("MklProvider")] |
|||
public Matrix<double> MklProvider() |
|||
{ |
|||
Control.LinearAlgebraProvider = _mkl; |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
z = _a*z; |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("SafeProvider")] |
|||
public Matrix<double> SafeProvider() |
|||
{ |
|||
Control.LinearAlgebraProvider = _safeProvider; |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
z = _a*z; |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("UnsafeProvider")] |
|||
public Matrix<double> UnsafeProvider() |
|||
{ |
|||
Control.LinearAlgebraProvider = _unsafeProvider; |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
z = _a*z; |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("ExperimentalProvider")] |
|||
public Matrix<double> ExperimentalProvider() |
|||
{ |
|||
Control.LinearAlgebraProvider = _experimentalProvider; |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
z = _a*z; |
|||
} |
|||
return z; |
|||
} |
|||
} |
|||
|
|||
public class SafeProvider : ManagedLinearAlgebraProvider |
|||
{ |
|||
public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) |
|||
{ |
|||
if (rowsX + columnsY <= Control.ParallelizeOrder) |
|||
{ |
|||
for (int i = 0; i < rowsX; ++i) |
|||
{ |
|||
for (int j = 0; j < columnsY; ++j) |
|||
{ |
|||
var jrowsY = j*rowsY; |
|||
double sum = 0.0; |
|||
for (int k = 0; k < columnsX; ++k) |
|||
{ |
|||
sum += x[k*rowsX + i]*y[jrowsY + k]; |
|||
} |
|||
result[j*rowsX + i] = sum; |
|||
} |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
double[] xdata; |
|||
if (ReferenceEquals(x, result)) |
|||
{ |
|||
xdata = (double[])x.Clone(); |
|||
} |
|||
else |
|||
{ |
|||
xdata = x; |
|||
} |
|||
|
|||
double[] ydata; |
|||
if (ReferenceEquals(y, result)) |
|||
{ |
|||
ydata = (double[])y.Clone(); |
|||
} |
|||
else |
|||
{ |
|||
ydata = y; |
|||
} |
|||
|
|||
Array.Clear(result, 0, result.Length); |
|||
|
|||
CacheObliviousMatrixMultiply(xdata, 0, 0, ydata, 0, 0, result, 0, 0, rowsX, columnsY, columnsX, rowsX, columnsY, columnsX, 0); |
|||
} |
|||
|
|||
public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) |
|||
{ |
|||
if (transposeA == Transpose.DontTranspose && transposeB == Transpose.DontTranspose && alpha == 1.0 && beta == 0.0) |
|||
{ |
|||
MatrixMultiply(a, rowsA, columnsA, b, rowsB, columnsB, c); |
|||
return; |
|||
} |
|||
|
|||
base.MatrixMultiplyWithUpdate(transposeA, transposeB, alpha, a, rowsA, columnsA, b, rowsB, columnsB, beta, c); |
|||
} |
|||
|
|||
static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level) |
|||
{ |
|||
if (m + n <= Control.ParallelizeOrder) |
|||
{ |
|||
for (var m1 = 0; m1 < m; m1++) |
|||
{ |
|||
var matArowPos = m1 + shiftArow; |
|||
var matCrowPos = m1 + shiftCrow; |
|||
for (var n1 = 0; n1 < n; ++n1) |
|||
{ |
|||
var boffset = ((n1 + shiftBcol)*constK) + shiftBrow; |
|||
double sum = 0; |
|||
for (var k1 = 0; k1 < k; ++k1) |
|||
{ |
|||
sum += matrixA[((k1 + shiftAcol)*constM) + matArowPos]*matrixB[boffset + k1]; |
|||
} |
|||
|
|||
result[((n1 + shiftCcol)*constM) + matCrowPos] += sum; |
|||
} |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
// divide and conquer
|
|||
int m2 = m/2, n2 = n/2, k2 = k/2; |
|||
|
|||
level++; |
|||
if (level <= 2) |
|||
{ |
|||
CommonParallel.Invoke( |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level)); |
|||
|
|||
CommonParallel.Invoke( |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level)); |
|||
} |
|||
else |
|||
{ |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level); |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level); |
|||
|
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level); |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level); |
|||
|
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level); |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level); |
|||
|
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level); |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public unsafe class UnsafeProvider : ManagedLinearAlgebraProvider |
|||
{ |
|||
public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) |
|||
{ |
|||
if (rowsX + columnsY <= Control.ParallelizeOrder) |
|||
{ |
|||
fixed (double* resultPtr = &result[0]) |
|||
fixed (double* xPtr = &x[0]) |
|||
fixed (double* yPtr = &y[0]) |
|||
{ |
|||
double* a = xPtr; |
|||
double* c = resultPtr; |
|||
for (int i = 0; i < rowsX; ++i) |
|||
{ |
|||
double* b = yPtr; |
|||
double* cj = c; |
|||
for (int j = 0; j < columnsY; ++j) |
|||
{ |
|||
double sum = 0.0; |
|||
for (int k = 0; k < columnsX; ++k) |
|||
{ |
|||
sum += a[k*rowsX]*b[k]; |
|||
} |
|||
*cj = sum; |
|||
cj += rowsX; |
|||
b += rowsY; |
|||
} |
|||
a++; |
|||
c++; |
|||
} |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
double[] xdata; |
|||
if (ReferenceEquals(x, result)) |
|||
{ |
|||
xdata = (double[])x.Clone(); |
|||
} |
|||
else |
|||
{ |
|||
xdata = x; |
|||
} |
|||
|
|||
double[] ydata; |
|||
if (ReferenceEquals(y, result)) |
|||
{ |
|||
ydata = (double[])y.Clone(); |
|||
} |
|||
else |
|||
{ |
|||
ydata = y; |
|||
} |
|||
|
|||
Array.Clear(result, 0, result.Length); |
|||
|
|||
CacheObliviousMatrixMultiply(xdata, 0, 0, ydata, 0, 0, result, 0, 0, rowsX, columnsY, columnsX, rowsX, columnsY, columnsX, 0); |
|||
} |
|||
|
|||
public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) |
|||
{ |
|||
if (transposeA == Transpose.DontTranspose && transposeB == Transpose.DontTranspose && alpha == 1.0 && beta == 0.0) |
|||
{ |
|||
MatrixMultiply(a, rowsA, columnsA, b, rowsB, columnsB, c); |
|||
return; |
|||
} |
|||
|
|||
base.MatrixMultiplyWithUpdate(transposeA, transposeB, alpha, a, rowsA, columnsA, b, rowsB, columnsB, beta, c); |
|||
} |
|||
|
|||
static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level) |
|||
{ |
|||
if (m + n <= Control.ParallelizeOrder) |
|||
{ |
|||
fixed (double* resultPtr = &result[0]) |
|||
fixed (double* aPtr = &matrixA[0]) |
|||
fixed (double* bPtr = &matrixB[0]) |
|||
{ |
|||
double* a = aPtr + shiftArow; |
|||
double* c = resultPtr + shiftCrow; |
|||
for (var m1 = 0; m1 < m; m1++) |
|||
{ |
|||
for (var n1 = 0; n1 < n; ++n1) |
|||
{ |
|||
double* b = bPtr + (n1 + shiftBcol)*constK + shiftBrow; |
|||
double sum = 0; |
|||
for (var k1 = 0; k1 < k; ++k1) |
|||
{ |
|||
sum += a[((k1 + shiftAcol)*constM)]*b[k1]; |
|||
} |
|||
|
|||
c[((n1 + shiftCcol)*constM)] += sum; |
|||
} |
|||
a++; |
|||
c++; |
|||
} |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
// divide and conquer
|
|||
int m2 = m/2, n2 = n/2, k2 = k/2; |
|||
|
|||
level++; |
|||
if (level <= 2) |
|||
{ |
|||
CommonParallel.Invoke( |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level)); |
|||
|
|||
CommonParallel.Invoke( |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level), |
|||
() => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level)); |
|||
} |
|||
else |
|||
{ |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level); |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level); |
|||
|
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level); |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level); |
|||
|
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level); |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level); |
|||
|
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level); |
|||
CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public class ExperimentalProvider : ManagedLinearAlgebraProvider |
|||
{ |
|||
public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) |
|||
{ |
|||
MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result); |
|||
} |
|||
|
|||
public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) |
|||
{ |
|||
if (a == null) |
|||
{ |
|||
throw new ArgumentNullException("a"); |
|||
} |
|||
|
|||
if (b == null) |
|||
{ |
|||
throw new ArgumentNullException("b"); |
|||
} |
|||
|
|||
if (c == null) |
|||
{ |
|||
throw new ArgumentNullException("c"); |
|||
} |
|||
|
|||
if (transposeA != Transpose.DontTranspose) |
|||
{ |
|||
Swap(ref rowsA, ref columnsA); |
|||
} |
|||
|
|||
if (transposeB != Transpose.DontTranspose) |
|||
{ |
|||
Swap(ref rowsB, ref columnsB); |
|||
} |
|||
|
|||
if (columnsA != rowsB) |
|||
{ |
|||
throw new ArgumentOutOfRangeException(String.Format("columnsA ({0}) != rowsB ({1})", columnsA, rowsB)); |
|||
} |
|||
|
|||
if (rowsA*columnsA != a.Length) |
|||
{ |
|||
throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsA ({1}) != a.Length ({2})", rowsA, columnsA, a.Length)); |
|||
} |
|||
|
|||
if (rowsB*columnsB != b.Length) |
|||
{ |
|||
throw new ArgumentOutOfRangeException(String.Format("rowsB ({0}) * columnsB ({1}) != b.Length ({2})", rowsB, columnsB, b.Length)); |
|||
} |
|||
|
|||
if (rowsA*columnsB != c.Length) |
|||
{ |
|||
throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsB ({1}) != c.Length ({2})", rowsA, columnsB, c.Length)); |
|||
} |
|||
|
|||
// handle the degenerate cases
|
|||
if (beta == 0.0) |
|||
{ |
|||
Array.Clear(c, 0, c.Length); |
|||
} |
|||
else if (beta != 1.0) |
|||
{ |
|||
ScaleArray(beta, c, c); |
|||
} |
|||
|
|||
if (alpha == 0.0) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
// Extract column arrays
|
|||
var columnDataB = new double[columnsB][]; |
|||
for (int i = 0; i < columnDataB.Length; i++) |
|||
{ |
|||
columnDataB[i] = GetColumn(transposeB, i, rowsB, columnsB, b); |
|||
} |
|||
|
|||
var shouldNotParallelize = rowsA + columnsB + columnsA < Control.ParallelizeOrder || Control.MaxDegreeOfParallelism < 2; |
|||
if (shouldNotParallelize) |
|||
{ |
|||
for (int i = 0; i < rowsA; i++) |
|||
{ |
|||
var row = GetRow(transposeA, i, rowsA, columnsA, a); |
|||
for (int j = 0; j < columnsB; j++) |
|||
{ |
|||
var col = columnDataB[j]; |
|||
double sum = 0; |
|||
for (int ii = 0; ii < row.Length; ii++) |
|||
{ |
|||
sum += row[ii]*col[ii]; |
|||
} |
|||
|
|||
c[j*rowsA + i] += alpha*sum; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
CommonParallel.For(0, rowsA, 1, (u, v) => |
|||
{ |
|||
for (int i = u; i < v; i++) |
|||
{ |
|||
// for each row in a
|
|||
var row = GetRow(transposeA, i, rowsA, columnsA, a); |
|||
for (int j = 0; j < columnsB; j++) |
|||
{ |
|||
var column = columnDataB[j]; |
|||
double sum = 0; |
|||
for (int ii = 0; ii < row.Length; ii++) |
|||
{ |
|||
sum += row[ii]*column[ii]; |
|||
} |
|||
|
|||
c[j*rowsA + i] += alpha*sum; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
static void Swap(ref int first, ref int second) |
|||
{ |
|||
var prior = first; |
|||
first = second; |
|||
second = prior; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
|
|||
/// </summary>
|
|||
static double[] GetRow(Transpose transpose, int rowindx, int numRows, int numCols, double[] matrix) |
|||
{ |
|||
var ret = new double[numCols]; |
|||
if (transpose == Transpose.DontTranspose) |
|||
{ |
|||
for (int i = 0; i < numCols; i++) |
|||
{ |
|||
ret[i] = matrix[(i*numRows) + rowindx]; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
Array.Copy(matrix, rowindx*numCols, ret, 0, numCols); |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
|
|||
/// </summary>
|
|||
static double[] GetColumn(Transpose transpose, int colindx, int numRows, int numCols, double[] matrix) |
|||
{ |
|||
var ret = new double[numRows]; |
|||
if (transpose == Transpose.DontTranspose) |
|||
{ |
|||
Array.Copy(matrix, colindx*numRows, ret, 0, numRows); |
|||
} |
|||
else |
|||
{ |
|||
for (int i = 0; i < numRows; i++) |
|||
{ |
|||
ret[i] = matrix[(i*numCols) + colindx]; |
|||
} |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
} |
|||
} |
|||
@ -1,150 +0,0 @@ |
|||
using System; |
|||
using Binarysharp.Benchmark; |
|||
using MathNet.Numerics; |
|||
using MathNet.Numerics.Providers.LinearAlgebra; |
|||
using MathNet.Numerics.Providers.LinearAlgebra.Mkl; |
|||
using MathNet.Numerics.Threading; |
|||
using MathNet.Numerics.LinearAlgebra; |
|||
using MathNet.Numerics.LinearAlgebra.Storage; |
|||
|
|||
namespace Performance.LinearAlgebra |
|||
{ |
|||
public class DenseVectorAdd |
|||
{ |
|||
readonly int _rounds; |
|||
readonly Vector<double> _a; |
|||
readonly Vector<double> _b; |
|||
|
|||
readonly ILinearAlgebraProvider _managed = new ManagedLinearAlgebraProvider(); |
|||
readonly ILinearAlgebraProvider _mkl = new MklLinearAlgebraProvider(); |
|||
|
|||
public DenseVectorAdd(int size, int rounds) |
|||
{ |
|||
_rounds = rounds; |
|||
|
|||
_b = Vector<double>.Build.Random(size); |
|||
_a = Vector<double>.Build.Random(size); |
|||
|
|||
_managed.InitializeVerify(); |
|||
Control.LinearAlgebraProvider = _managed; |
|||
|
|||
#if NATIVE
|
|||
_mkl.InitializeVerify(); |
|||
#endif
|
|||
} |
|||
|
|||
[BenchSharkTask("AddOperator")] |
|||
public Vector<double> AddOperator() |
|||
{ |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
z = _a + z; |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("Map2")] |
|||
public Vector<double> Map2() |
|||
{ |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
z = _a.Map2((u, v) => u + v, z); |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("Loop")] |
|||
public Vector<double> Loop() |
|||
{ |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
var aa = ((DenseVectorStorage<double>)_a.Storage).Data; |
|||
var az = ((DenseVectorStorage<double>)z.Storage).Data; |
|||
var ar = new Double[aa.Length]; |
|||
for (int k = 0; k < ar.Length; k++) |
|||
{ |
|||
ar[k] = aa[k] + az[k]; |
|||
} |
|||
z = Vector<double>.Build.Dense(ar); |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("ParallelLoop4096")] |
|||
public Vector<double> ParallelLoop4096() |
|||
{ |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
var aa = ((DenseVectorStorage<double>)_a.Storage).Data; |
|||
var az = ((DenseVectorStorage<double>)z.Storage).Data; |
|||
var ar = new Double[aa.Length]; |
|||
CommonParallel.For(0, ar.Length, 4096, (u, v) => |
|||
{ |
|||
for (int k = u; k < v; k++) |
|||
{ |
|||
ar[k] = aa[k] + az[k]; |
|||
} |
|||
}); |
|||
z = Vector<double>.Build.Dense(ar); |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("ParallelLoop32768")] |
|||
public Vector<double> ParallelLoop32768() |
|||
{ |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
var aa = ((DenseVectorStorage<double>)_a.Storage).Data; |
|||
var az = ((DenseVectorStorage<double>)z.Storage).Data; |
|||
var ar = new Double[aa.Length]; |
|||
CommonParallel.For(0, ar.Length, 32768, (u, v) => |
|||
{ |
|||
for (int k = u; k < v; k++) |
|||
{ |
|||
ar[k] = aa[k] + az[k]; |
|||
} |
|||
}); |
|||
z = Vector<double>.Build.Dense(ar); |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
[BenchSharkTask("ManagedProvider")] |
|||
public Vector<double> ManagedProvider() |
|||
{ |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
var aa = ((DenseVectorStorage<double>)_a.Storage).Data; |
|||
var az = ((DenseVectorStorage<double>)z.Storage).Data; |
|||
var ar = new Double[aa.Length]; |
|||
_managed.AddArrays(aa, az, ar); |
|||
z = Vector<double>.Build.Dense(ar); |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
#if NATIVEMKL
|
|||
[BenchSharkTask("MklProvider")] |
|||
public Vector<double> MklProvider() |
|||
{ |
|||
var z = _b; |
|||
for (int i = 0; i < _rounds; i++) |
|||
{ |
|||
var aa = ((DenseVectorStorage<double>)_a.Storage).Data; |
|||
var az = ((DenseVectorStorage<double>)z.Storage).Data; |
|||
var ar = new Double[aa.Length]; |
|||
_mkl.AddArrays(aa, az, ar); |
|||
z = Vector<double>.Build.Dense(ar); |
|||
} |
|||
return z; |
|||
} |
|||
#endif
|
|||
} |
|||
} |
|||
@ -1,109 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
|||
<PropertyGroup> |
|||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|||
<ProjectGuid>{F2CA84AE-4B7C-46F5-9889-82BC5F9F0F4E}</ProjectGuid> |
|||
<OutputType>Exe</OutputType> |
|||
<AppDesignerFolder>Properties</AppDesignerFolder> |
|||
<RootNamespace>Performance</RootNamespace> |
|||
<AssemblyName>Performance</AssemblyName> |
|||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |
|||
<FileAlignment>512</FileAlignment> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|||
<DebugSymbols>true</DebugSymbols> |
|||
<DebugType>full</DebugType> |
|||
<Optimize>false</Optimize> |
|||
<OutputPath>bin\Debug\</OutputPath> |
|||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<WarningLevel>4</WarningLevel> |
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|||
<PlatformTarget>x64</PlatformTarget> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
|||
<DebugType>pdbonly</DebugType> |
|||
<Optimize>true</Optimize> |
|||
<OutputPath>bin\Release\</OutputPath> |
|||
<DefineConstants>TRACE;NATIVE</DefineConstants> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<WarningLevel>4</WarningLevel> |
|||
<PlatformTarget>x64</PlatformTarget> |
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|||
</PropertyGroup> |
|||
<PropertyGroup> |
|||
<StartupObject /> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release %28No MKL%29|AnyCPU'"> |
|||
<OutputPath>bin\Release\</OutputPath> |
|||
<DefineConstants>TRACE</DefineConstants> |
|||
<Optimize>true</Optimize> |
|||
<DebugType>pdbonly</DebugType> |
|||
<PlatformTarget>x64</PlatformTarget> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<Reference Include="System" /> |
|||
<Reference Include="System.Core" /> |
|||
<Reference Include="System.Numerics" /> |
|||
<Reference Include="System.Xml.Linq" /> |
|||
<Reference Include="System.Data.DataSetExtensions" /> |
|||
<Reference Include="Microsoft.CSharp" /> |
|||
<Reference Include="System.Data" /> |
|||
<Reference Include="System.Xml" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Compile Include="LinearAlgebra\DenseVectorAdd.cs" /> |
|||
<Compile Include="LinearAlgebra\DenseMatrixProduct.cs" /> |
|||
<Compile Include="Program.cs" /> |
|||
<Compile Include="Properties\AssemblyInfo.cs" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<None Include="paket.references" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Numerics\Numerics.csproj"> |
|||
<Project>{b7cae5f4-a23f-4438-b5be-41226618b695}</Project> |
|||
<Name>Numerics</Name> |
|||
</ProjectReference> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Content Include="..\..\out\MKL\Windows\x64\libiomp5md.dll"> |
|||
<Link>libiomp5md.dll</Link> |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</Content> |
|||
<Content Include="..\..\out\MKL\Windows\x64\MathNet.Numerics.MKL.dll"> |
|||
<Link>MathNet.Numerics.MKL.dll</Link> |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
|||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
|||
Other similar extension points exist, see Microsoft.Common.targets. |
|||
<Target Name="BeforeBuild"> |
|||
</Target> |
|||
<Target Name="AfterBuild"> |
|||
</Target> |
|||
--> |
|||
<ItemGroup> |
|||
<Reference Include="Benchmark"> |
|||
<HintPath>..\..\packages\benchmark\BenchShark\lib\Benchmark.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
<Choose> |
|||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.0' Or $(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3')"> |
|||
<ItemGroup> |
|||
<Reference Include="ConsoleDump"> |
|||
<HintPath>..\..\packages\benchmark\ConsoleDump\lib\net40-Client\ConsoleDump.dll</HintPath> |
|||
<Private>True</Private> |
|||
<Paket>True</Paket> |
|||
</Reference> |
|||
</ItemGroup> |
|||
</When> |
|||
</Choose> |
|||
</Project> |
|||
@ -1,52 +0,0 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using Binarysharp.Benchmark; |
|||
using ConsoleDump; |
|||
using MathNet.Numerics.Statistics; |
|||
|
|||
namespace Performance |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static void Main() |
|||
{ |
|||
//Benchmark(new LinearAlgebra.DenseVectorAdd(10000000,1), 10, "Large (10'000'000) - 10x1 iterations");
|
|||
//Benchmark(new LinearAlgebra.DenseVectorAdd(100,1000), 100, "Small (100) - 100x1000 iterations");
|
|||
|
|||
LinearAlgebra.DenseMatrixProduct.Verify(5); |
|||
LinearAlgebra.DenseMatrixProduct.Verify(100); |
|||
Benchmark(new LinearAlgebra.DenseMatrixProduct(10,100), 100, "10 - 100x100 iterations"); |
|||
Benchmark(new LinearAlgebra.DenseMatrixProduct(25, 100), 100, "25 - 100x100 iterations"); |
|||
Benchmark(new LinearAlgebra.DenseMatrixProduct(50, 10), 100, "50 - 100x10 iterations"); |
|||
Benchmark(new LinearAlgebra.DenseMatrixProduct(100, 10), 100, "100 - 100x10 iterations"); |
|||
Benchmark(new LinearAlgebra.DenseMatrixProduct(250, 1), 10, "250 - 10x1 iterations"); |
|||
Benchmark(new LinearAlgebra.DenseMatrixProduct(500,1), 10, "500 - 10x1 iterations"); |
|||
Benchmark(new LinearAlgebra.DenseMatrixProduct(1000,1), 2, "1000 - 2x1 iterations"); |
|||
} |
|||
|
|||
static void Benchmark(object obj, uint iterations, string suffix = null) |
|||
{ |
|||
var bench = new BenchShark(true); |
|||
var result = bench.EvaluateDecoratedTasks(obj, iterations); |
|||
var results = result.FastestEvaluations.Select(x => |
|||
{ |
|||
var series = x.Iterations.Select(it => (double)it.ElapsedTicks).ToArray(); |
|||
Array.Sort(series); |
|||
var summary = SortedArrayStatistics.FiveNumberSummary(series); |
|||
var ms = ArrayStatistics.MeanStandardDeviation(series); |
|||
return new { x.Name, Mean = ms.Item1, StdDev = ms.Item2, Min = summary[0], Q1 = summary[1], Median = summary[2], Q3 = summary[3], Max = summary[4] }; |
|||
}).ToArray(); |
|||
var top = results[0]; |
|||
var managed = results.Single(x => x.Name.StartsWith("Managed")); |
|||
var label = string.IsNullOrEmpty(suffix) ? obj.GetType().FullName : string.Concat(obj.GetType().FullName, ": ", suffix); |
|||
results.Select(x => new |
|||
{ |
|||
x.Name, |
|||
Mean = Math.Round(x.Mean), StdDev = Math.Round(x.StdDev), |
|||
Min = Math.Round(x.Min), Q1 = Math.Round(x.Q1), Median = Math.Round(x.Median), Q3 = Math.Round(x.Q3), Max = Math.Round(x.Max), |
|||
TopSlowdown = Math.Round(x.Median/top.Median, 2), |
|||
ManagedSpeedup = Math.Round(managed.Median/x.Median, 2) |
|||
}).Dump(label); |
|||
} |
|||
} |
|||
} |
|||
@ -1,3 +0,0 @@ |
|||
group Benchmark |
|||
BenchShark |
|||
ConsoleDump |
|||
Loading…
Reference in new issue