Browse Source

FFT: MKL provider refactoring due to sharing between FFT and LA

benchmark-la
Christoph Ruegg 10 years ago
parent
commit
a4f5b618e4
  1. 5
      src/NativeProviders/MKL/capabilities.cpp
  2. 8
      src/Numerics/Numerics.csproj
  3. 84
      src/Numerics/Providers/Common/Mkl/MklProvider.cs
  4. 6
      src/Numerics/Providers/Common/Mkl/MklProviderCapabilities.cs
  5. 21
      src/Numerics/Providers/Common/Mkl/SafeNativeMethods.cs
  6. 4
      src/Numerics/Providers/Common/NativeProviderLoader.cs
  7. 15
      src/Numerics/Providers/FourierTransform/Mkl/MklFourierTransformProvider.cs
  8. 102
      src/Numerics/Providers/FourierTransform/Mkl/SafeNativeMethods.cs
  9. 1
      src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs
  10. 1
      src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs
  11. 1
      src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs
  12. 1
      src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Double.cs
  13. 1
      src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Single.cs
  14. 45
      src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs
  15. 1
      src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs

5
src/NativeProviders/MKL/capabilities.cpp

@ -41,7 +41,7 @@ extern "C" {
#endif
// COMMON/SHARED
case 64: return 10; // revision
case 64: return 11; // revision
case 65: return 1; // numerical consistency, precision and accuracy modes
case 66: return 1; // threading control
case 67: return 1; // memory management
@ -54,7 +54,8 @@ extern "C" {
case 256: return 0; // basic optimization
// FFT
case 384: return 0; // basic FFT
case 384: return 1; // basic FFT (major - breaking)
case 385: return 0; // basic FFT (minor - non-breaking)
default: return 0; // unknown or not supported

8
src/Numerics/Numerics.csproj

@ -172,10 +172,10 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Providers\Common\Mkl\MklProvider.cs" />
<Compile Include="Providers\FourierTransform\IFourierTransformProvider.cs" />
<Compile Include="Providers\FourierTransform\ManagedFourierTransformProvider.cs" />
<Compile Include="Providers\FourierTransform\Mkl\MklFourierTransformProvider.cs" />
<Compile Include="Providers\FourierTransform\Mkl\SafeNativeMethods.cs" />
<Compile Include="Providers\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Complex.cs" />
<Compile Include="Providers\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Complex32.cs" />
<Compile Include="Providers\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Double.cs" />
@ -188,7 +188,7 @@
<Compile Include="Providers\LinearAlgebra\Cuda\CudaLinearAlgebraProvider.Single.cs" />
<Compile Include="Providers\LinearAlgebra\Cuda\CudaProviderCapabilities.cs" />
<Compile Include="Providers\LinearAlgebra\Cuda\SafeNativeMethods.cs" />
<Compile Include="Providers\LinearAlgebra\Mkl\MklProviderCapabilities.cs" />
<Compile Include="Providers\Common\Mkl\MklProviderCapabilities.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasLinearAlgebraProvider.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasLinearAlgebraProvider.Complex.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasLinearAlgebraProvider.Complex32.cs" />
@ -206,7 +206,7 @@
<Compile Include="Providers\LinearAlgebra\Mkl\MklLinearAlgebraProvider.cs" />
<Compile Include="Providers\LinearAlgebra\Mkl\MklLinearAlgebraProvider.Double.cs" />
<Compile Include="Providers\LinearAlgebra\Mkl\MklLinearAlgebraProvider.Single.cs" />
<Compile Include="Providers\LinearAlgebra\Mkl\SafeNativeMethods.cs" />
<Compile Include="Providers\Common\Mkl\SafeNativeMethods.cs" />
<Compile Include="ArrayExtensions.cs" />
<Compile Include="Complex64.cs" />
<Compile Include="Combinatorics.cs" />
@ -225,7 +225,7 @@
<Compile Include="LinearAlgebra\Vector.Operators.cs" />
<Compile Include="Exceptions.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasProviderCapabilities.cs" />
<Compile Include="Providers\NativeProviderLoader.cs" />
<Compile Include="Providers\Common\NativeProviderLoader.cs" />
<Compile Include="Random\SystemRandomSource.cs" />
<Compile Include="Random\RandomSeed.cs" />
<Compile Include="RootFinding\Broyden.cs" />

84
src/Numerics/Providers/Common/Mkl/MklProvider.cs

@ -0,0 +1,84 @@
// <copyright file="MklProvider.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2016 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
namespace MathNet.Numerics.Providers.Common.Mkl
{
internal static class MklProvider
{
static int _nativeRevision;
static bool _nativeX86;
static bool _nativeX64;
static bool _nativeIA64;
public static void Load(int minRevision)
{
int a, b;
try
{
// Load the native library
NativeProviderLoader.TryLoad(SafeNativeMethods.DllName);
a = SafeNativeMethods.query_capability(0);
b = SafeNativeMethods.query_capability(1);
_nativeX86 = SafeNativeMethods.query_capability((int)ProviderPlatform.x86) > 0;
_nativeX64 = SafeNativeMethods.query_capability((int)ProviderPlatform.x64) > 0;
_nativeIA64 = SafeNativeMethods.query_capability((int)ProviderPlatform.ia64) > 0;
_nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision);
}
catch (DllNotFoundException e)
{
throw new NotSupportedException("MKL Native Provider not found.", e);
}
catch (BadImageFormatException e)
{
throw new NotSupportedException("MKL Native Provider found but failed to load. Please verify that the platform matches (x64 vs x32, Windows vs Linux).", e);
}
catch (EntryPointNotFoundException e)
{
throw new NotSupportedException("MKL Native Provider does not support capability querying and is therefore not compatible. Consider upgrading to a newer version.", e);
}
if (a != 0 || b != -1 || _nativeRevision < minRevision)
{
throw new NotSupportedException("MKL Native Provider too old. Consider upgrading to a newer version.");
}
}
public static string Describe()
{
return string.Format("Intel MKL ({1}; revision {0})",
_nativeRevision,
_nativeX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : "unknown");
}
}
}

6
src/Numerics/Providers/LinearAlgebra/Mkl/MklProviderCapabilities.cs → src/Numerics/Providers/Common/Mkl/MklProviderCapabilities.cs

@ -27,7 +27,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
namespace MathNet.Numerics.Providers.Common.Mkl
{
internal enum ProviderPlatform : int
{
@ -46,7 +46,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
internal enum ProviderCapability : int
{
LinearAlgebra = 128,
LinearAlgebraMajor = 128,
LinearAlgebraMinor = 129,
FourierTransformMajor = 384,
FourierTransformMinor = 385
}
}

21
src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs → src/Numerics/Providers/Common/Mkl/SafeNativeMethods.cs

@ -2,7 +2,7 @@
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009-2014 Math.NET
// Copyright (c) 2009-2016 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -31,8 +31,9 @@
using System.Numerics;
using System.Runtime.InteropServices;
using System.Security;
using MathNet.Numerics.Providers.LinearAlgebra;
namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
namespace MathNet.Numerics.Providers.Common.Mkl
{
/// <summary>
/// P/Invoke methods to the native math libraries.
@ -367,6 +368,22 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
#endregion Vector Functions
#region FFT
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long z_fft_forward_inplace(long n, double scaling, [In, Out] Complex[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long c_fft_forward_inplace(long n, float scaling, [In, Out] Complex32[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long z_fft_backward_inplace(long n, double scaling, [In, Out] Complex[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long c_fft_backward_inplace(long n, float scaling, [In, Out] Complex32[] x);
#endregion FFT
// ReSharper restore InconsistentNaming
}
}

4
src/Numerics/Providers/NativeProviderLoader.cs → src/Numerics/Providers/Common/NativeProviderLoader.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2015 Math.NET
// Copyright (c) 2009-2016 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -37,7 +37,7 @@ using System.Threading;
#if NATIVE
namespace MathNet.Numerics.Providers
namespace MathNet.Numerics.Providers.Common
{
/// <summary>
/// Helper class to load native libraries depending on the architecture of the OS and process.

15
src/Numerics/Providers/FourierTransform/Mkl/MklFourierTransformProvider.cs

@ -30,6 +30,7 @@
using System;
using System.Numerics;
using MathNet.Numerics.Providers.Common.Mkl;
namespace MathNet.Numerics.Providers.FourierTransform.Mkl
{
@ -37,6 +38,20 @@ namespace MathNet.Numerics.Providers.FourierTransform.Mkl
{
public void InitializeVerify()
{
MklProvider.Load(minRevision: 11);
// we only support exactly one major version, since major version changes imply a breaking change.
int fftMajor = SafeNativeMethods.query_capability((int)ProviderCapability.FourierTransformMajor);
int fftMinor = SafeNativeMethods.query_capability((int)ProviderCapability.FourierTransformMinor);
if (!(fftMajor == 1 && fftMinor >= 0))
{
throw new NotSupportedException(string.Format("MKL Native Provider not compatible. Expecting fourier transform v1 but provider implements v{0}.", fftMajor));
}
}
public override string ToString()
{
return MklProvider.Describe();
}
public void ForwardInplace(Complex[] complex, FourierTransformScaling scaling)

102
src/Numerics/Providers/FourierTransform/Mkl/SafeNativeMethods.cs

@ -1,102 +0,0 @@
// <copyright file="SafeNativeMethods.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009-2016 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVE
using System.Numerics;
using System.Runtime.InteropServices;
using System.Security;
namespace MathNet.Numerics.Providers.FourierTransform.Mkl
{
/// <summary>
/// P/Invoke methods to the native math libraries.
/// </summary>
[SuppressUnmanagedCodeSecurity]
[SecurityCritical]
internal static class SafeNativeMethods
{
// ReSharper disable InconsistentNaming
/// <summary>
/// Name of the native DLL.
/// </summary>
const string _DllName = "MathNet.Numerics.MKL.dll";
internal static string DllName { get { return _DllName; } }
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int query_capability(int capability);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void set_consistency_mode(int mode);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void set_vml_mode(uint mode);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void set_max_threads(int num_threads);
#region Memory
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void free_buffers();
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void thread_free_buffers();
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int disable_fast_mm();
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long mem_stat([Out]out int allocatedBuffers);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long peak_mem_usage(int mode);
#endregion Memory
#region FFT
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long z_fft_forward_inplace(long n, double scaling, [In, Out] Complex[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long c_fft_forward_inplace(long n, float scaling, [In, Out] Complex32[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long z_fft_backward_inplace(long n, double scaling, [In, Out] Complex[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern long c_fft_backward_inplace(long n, float scaling, [In, Out] Complex32[] x);
#endregion FFT
// ReSharper restore InconsistentNaming
}
}
#endif

1
src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs

@ -28,6 +28,7 @@
// </copyright>
using System;
using MathNet.Numerics.Providers.Common;
#if NATIVE

1
src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs

@ -34,6 +34,7 @@ using System.Numerics;
using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Providers.Common.Mkl;
namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
{

1
src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs

@ -34,6 +34,7 @@ using System.Numerics;
using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Providers.Common.Mkl;
namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
{

1
src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Double.cs

@ -34,6 +34,7 @@ using System.Numerics;
using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Providers.Common.Mkl;
namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
{

1
src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Single.cs

@ -34,6 +34,7 @@ using System.Numerics;
using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Providers.Common.Mkl;
namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
{

45
src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs

@ -28,6 +28,8 @@
// </copyright>
using System;
using MathNet.Numerics.Providers.Common;
using MathNet.Numerics.Providers.Common.Mkl;
#if NATIVE
@ -105,11 +107,6 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// </summary>
public partial class MklLinearAlgebraProvider : ManagedLinearAlgebraProvider
{
int _nativeRevision;
bool _nativeIX86;
bool _nativeX64;
bool _nativeIA64;
readonly MklConsistency _consistency;
readonly MklPrecision _precision;
readonly MklAccuracy _accuracy;
@ -144,39 +141,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// </summary>
public override void InitializeVerify()
{
int a, b, linearAlgebra;
try
{
// Load the native library
NativeProviderLoader.TryLoad(SafeNativeMethods.DllName);
a = SafeNativeMethods.query_capability(0);
b = SafeNativeMethods.query_capability(1);
_nativeIX86 = SafeNativeMethods.query_capability((int)ProviderPlatform.x86) > 0;
_nativeX64 = SafeNativeMethods.query_capability((int)ProviderPlatform.x64) > 0;
_nativeIA64 = SafeNativeMethods.query_capability((int)ProviderPlatform.ia64) > 0;
_nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision);
linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebra);
}
catch (DllNotFoundException e)
{
throw new NotSupportedException("MKL Native Provider not found.", e);
}
catch (BadImageFormatException e)
{
throw new NotSupportedException("MKL Native Provider found but failed to load. Please verify that the platform matches (x64 vs x32, Windows vs Linux).", e);
}
catch (EntryPointNotFoundException e)
{
throw new NotSupportedException("MKL Native Provider does not support capability querying and is therefore not compatible. Consider upgrading to a newer version.", e);
}
MklProvider.Load(minRevision: 4);
if (a != 0 || b != -1 || _nativeRevision < 4)
{
throw new NotSupportedException("MKL Native Provider too old. Consider upgrading to a newer version.");
}
int linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebraMajor);
// we only support exactly one major version, since major version changes imply a breaking change.
if (linearAlgebra != 2)
@ -295,9 +262,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
public override string ToString()
{
return string.Format("Intel MKL ({1}; revision {0})",
_nativeRevision,
_nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : "unknown");
return MklProvider.Describe();
}
}
}

1
src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs

@ -30,6 +30,7 @@
#if NATIVE
using System;
using MathNet.Numerics.Providers.Common;
namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
{

Loading…
Cancel
Save