From c906a2a6af93ab3c4de8c5751beed094c2ce110f Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sat, 9 May 2015 20:02:58 +0200 Subject: [PATCH] Native: cleanup --- src/NativeProviders/OpenBLAS/capabilities.cpp | 2 +- src/Numerics/Control.cs | 4 ++ src/Numerics/Numerics.csproj | 4 +- .../Cuda/CudaLinearAlgebraProvider.cs | 37 +++++--------- .../Cuda/CudaProviderCapabilities.cs | 49 ++++++++++++++++++ .../Mkl/MklLinearAlgebraProvider.cs | 33 ++++++------ .../MklProviderCapabilities.cs} | 15 +++--- .../OpenBlas/OpenBlasLinearAlgebraProvider.cs | 27 +++++----- .../OpenBlas/OpenBlasProviderCapabilities.cs | 51 +++++++++++++++++++ 9 files changed, 159 insertions(+), 63 deletions(-) create mode 100644 src/Numerics/Providers/LinearAlgebra/Cuda/CudaProviderCapabilities.cs rename src/Numerics/Providers/LinearAlgebra/{ProviderCapabilities.cs => Mkl/MklProviderCapabilities.cs} (83%) create mode 100644 src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasProviderCapabilities.cs diff --git a/src/NativeProviders/OpenBLAS/capabilities.cpp b/src/NativeProviders/OpenBLAS/capabilities.cpp index 90dc57f2..4e51b6c1 100644 --- a/src/NativeProviders/OpenBLAS/capabilities.cpp +++ b/src/NativeProviders/OpenBLAS/capabilities.cpp @@ -41,7 +41,7 @@ extern "C" { #endif // COMMON/SHARED - case 64: return 7; // revision + case 64: return 1; // revision case 66: return 1; // threading control // LINEAR ALGEBRA diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index 804721ca..9ccd07e4 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.cs @@ -82,6 +82,10 @@ namespace MathNet.Numerics case "CUDA": LinearAlgebraProvider = new Providers.LinearAlgebra.Cuda.CudaLinearAlgebraProvider(); break; + + case "OPENBLAS": + LinearAlgebraProvider = new Providers.LinearAlgebra.OpenBlas.OpenBlasLinearAlgebraProvider(); + break; #endif default: LinearAlgebraProvider = new ManagedLinearAlgebraProvider(); diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 8255c31f..a5a42d96 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -162,7 +162,9 @@ + + @@ -198,7 +200,7 @@ - + diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs index fa11f02e..a2748d0b 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs @@ -39,21 +39,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda /// public partial class CudaLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable { - private int _nativeRevision; - private bool _nativeIX86; - private bool _nativeX64; - private bool _nativeIA64; - private IntPtr _blasHandle; - private IntPtr _solverHandle; - - - /// - /// Constructor. - /// - [CLSCompliant(false)] - public CudaLinearAlgebraProvider() - { - } + int _nativeRevision; + bool _nativeIX86; + bool _nativeX64; + bool _nativeIA64; + IntPtr _blasHandle; + IntPtr _solverHandle; /// /// Initialize and verify that the provided is indeed available. @@ -70,12 +61,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda a = SafeNativeMethods.query_capability(0); b = SafeNativeMethods.query_capability(1); - _nativeIX86 = SafeNativeMethods.query_capability(8) > 0; - _nativeX64 = SafeNativeMethods.query_capability(9) > 0; - _nativeIA64 = SafeNativeMethods.query_capability(10) > 0; + _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(64); - linearAlgebra = SafeNativeMethods.query_capability(128); + _nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); + linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebra); } catch (DllNotFoundException e) { @@ -180,14 +171,14 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda default: throw new Exception("Unrecognized cuSolverDn status code: " + status); - - } } public override string ToString() { - return string.Format("Nvidia CUDA ({1}; revision {0})", _nativeRevision, _nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : "unknown"); + return string.Format("Nvidia CUDA ({1}; revision {0})", + _nativeRevision, + _nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : "unknown"); } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaProviderCapabilities.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaProviderCapabilities.cs new file mode 100644 index 00000000..a691f767 --- /dev/null +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaProviderCapabilities.cs @@ -0,0 +1,49 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2015 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. +// + +namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda +{ + internal enum ProviderPlatform : int + { + x86 = 8, + x64 = 9, + ia64 = 10, + } + + internal enum ProviderConfig : int + { + Revision = 64, + } + + internal enum ProviderCapability : int + { + LinearAlgebra = 128, + } +} \ No newline at end of file diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs index 33ee212e..780d3fa8 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs @@ -143,12 +143,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl a = SafeNativeMethods.query_capability(0); b = SafeNativeMethods.query_capability(1); - _nativeIX86 = SafeNativeMethods.query_capability(8) > 0; - _nativeX64 = SafeNativeMethods.query_capability(9) > 0; - _nativeIA64 = SafeNativeMethods.query_capability(10) > 0; + _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(64); - linearAlgebra = SafeNativeMethods.query_capability(128); + _nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); + linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebra); } catch (DllNotFoundException e) { @@ -169,14 +169,14 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl } // set numerical consistency, precision and accuracy modes, if supported - if (SafeNativeMethods.query_capability(65) > 0) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Precision) > 0) { SafeNativeMethods.set_consistency_mode((int)_consistency); SafeNativeMethods.set_vml_mode((uint)_precision | (uint)_accuracy); } // set threading settings, if supported - if (SafeNativeMethods.query_capability(66) > 0) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Threading) > 0) { SafeNativeMethods.set_max_threads(Control.MaxDegreeOfParallelism); } @@ -187,7 +187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl /// public void FreeBuffers() { - if (SafeNativeMethods.query_capability(67) < 1) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Memory) < 1) { throw new NotSupportedException("MKL Native Provider does not support memory management functions. Consider upgrading to a newer version."); } @@ -200,7 +200,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl /// public void ThreadFreeBuffers() { - if (SafeNativeMethods.query_capability(67) < 1) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Memory) < 1) { throw new NotSupportedException("MKL Native Provider does not support memory management functions. Consider upgrading to a newer version."); } @@ -213,7 +213,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl /// public void DisableMemoryPool() { - if (SafeNativeMethods.query_capability(67) < 1) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Memory) < 1) { throw new NotSupportedException("MKL Native Provider does not support memory management functions. Consider upgrading to a newer version."); } @@ -228,7 +228,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl /// Returns the number of bytes allocated to all memory buffers. public long MemoryStatistics(out int allocatedBuffers) { - if (SafeNativeMethods.query_capability(67) < 1) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Memory) < 1) { throw new NotSupportedException("MKL Native Provider does not support memory management functions. Consider upgrading to a newer version."); } @@ -241,7 +241,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl /// public void EnablePeakMemoryStatistics() { - if (SafeNativeMethods.query_capability(67) < 1) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Memory) < 1) { throw new NotSupportedException("MKL Native Provider does not support memory management functions. Consider upgrading to a newer version."); } @@ -254,7 +254,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl /// public void DisablePeakMemoryStatistics() { - if (SafeNativeMethods.query_capability(67) < 1) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Memory) < 1) { throw new NotSupportedException("MKL Native Provider does not support memory management functions. Consider upgrading to a newer version."); } @@ -269,7 +269,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl /// The peak number of bytes allocated to all memory buffers. public long PeakMemoryStatistics(bool reset = true) { - if (SafeNativeMethods.query_capability(67) < 1) + if (SafeNativeMethods.query_capability((int)ProviderConfig.Memory) < 1) { throw new NotSupportedException("MKL Native Provider does not support memory management functions. Consider upgrading to a newer version."); } @@ -279,9 +279,10 @@ 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 string.Format("Intel MKL ({1}; revision {0})", + _nativeRevision, + _nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : "unknown"); } - } } diff --git a/src/Numerics/Providers/LinearAlgebra/ProviderCapabilities.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklProviderCapabilities.cs similarity index 83% rename from src/Numerics/Providers/LinearAlgebra/ProviderCapabilities.cs rename to src/Numerics/Providers/LinearAlgebra/Mkl/MklProviderCapabilities.cs index b07d4e0f..80ec4ebb 100644 --- a/src/Numerics/Providers/LinearAlgebra/ProviderCapabilities.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklProviderCapabilities.cs @@ -1,4 +1,4 @@ -// +// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics @@ -28,17 +28,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // -namespace MathNet.Numerics.Providers.LinearAlgebra +namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl { - public enum ProviderPlatform : int + internal enum ProviderPlatform : int { x86 = 8, x64 = 9, ia64 = 10, - arm = 11, } - public enum ProviderConfig : int + internal enum ProviderConfig : int { Revision = 64, Precision = 65, @@ -46,10 +45,8 @@ namespace MathNet.Numerics.Providers.LinearAlgebra Memory = 67, } - public enum ProviderCapability : int + internal enum ProviderCapability : int { LinearAlgebra = 128, - Optimization = 256, - FFT = 384, } -} \ No newline at end of file +} diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs index 6a70a194..2b240f26 100644 --- a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs @@ -30,10 +30,7 @@ #if NATIVE -using MathNet.Numerics.Properties; using System; -using System.Numerics; -using System.Security; namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas { @@ -49,29 +46,29 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas /// public partial class OpenBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider { + int _nativeRevision; bool _nativeIX86; bool _nativeX64; bool _nativeIA64; bool _nativeARM; - public OpenBlasLinearAlgebraProvider() - { - - } - public override void InitializeVerify() { - int linearAlgebra; + 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; _nativeARM = SafeNativeMethods.query_capability((int)ProviderPlatform.arm) > 0; + _nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebra); } catch (DllNotFoundException e) @@ -87,6 +84,11 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas throw new NotSupportedException("OpenBLAS Native Provider does not support capability querying and is therefore not compatible. Consider upgrading to a newer version.", e); } + if (a != 0 || b != -1 || linearAlgebra <=0 || _nativeRevision < 1) + { + throw new NotSupportedException("OpenBLAS Native Provider too old or not compatible. Consider upgrading to a newer version."); + } + // set threading settings, if supported if (SafeNativeMethods.query_capability((int)ProviderConfig.Threading) > 0) { @@ -96,10 +98,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas public override string ToString() { - return string.Format("OpenBLAS\r\nProvider revision: {0}\r\nCPU core name: {1}\r\nLibrary config: {1})", - SafeNativeMethods.query_capability((int)ProviderConfig.Revision), - SafeNativeMethods.get_cpu_core(), - SafeNativeMethods.get_build_config()); + return string.Format("OpenBLAS ({1}; revision {0})", + _nativeRevision, + _nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : _nativeARM ? "ARM" : "unknown"); } } } diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasProviderCapabilities.cs b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasProviderCapabilities.cs new file mode 100644 index 00000000..01a14855 --- /dev/null +++ b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasProviderCapabilities.cs @@ -0,0 +1,51 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2015 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. +// + +namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas +{ + internal enum ProviderPlatform : int + { + x86 = 8, + x64 = 9, + ia64 = 10, + arm = 11, + } + + internal enum ProviderConfig : int + { + Revision = 64, + Threading = 66, + } + + internal enum ProviderCapability : int + { + LinearAlgebra = 128, + } +} \ No newline at end of file