forked from tsai/mathnet-numerics
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