From 59c41819e6db31f99ddc988ddb429e4cb02b7853 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sat, 21 Jun 2014 16:11:07 +0200 Subject: [PATCH] Native: MKL optional max threads control, integrated with Control #223 --- src/NativeProviders/MKL/capabilities.cpp | 8 +++++++- src/Numerics/Control.cs | 20 +++++++++++++++++-- .../Mkl/MklLinearAlgebraProvider.cs | 7 +++++++ .../LinearAlgebra/Mkl/SafeNativeMethods.cs | 7 +++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/NativeProviders/MKL/capabilities.cpp b/src/NativeProviders/MKL/capabilities.cpp index 159d38c3..3c5ea5c4 100644 --- a/src/NativeProviders/MKL/capabilities.cpp +++ b/src/NativeProviders/MKL/capabilities.cpp @@ -41,8 +41,9 @@ extern "C" { #endif // COMMON/SHARED - case 64: return 5; // revision + case 64: return 6; // revision case 65: return 1; // numerical consistency, precision and accuracy modes + case 66: return 1; // threading control // LINEAR ALGEBRA case 128: return 1; // basic dense linear algebra @@ -68,6 +69,11 @@ extern "C" { vmlSetMode(mode); } + DLLEXPORT void set_max_threads(const MKL_INT num_threads) + { + mkl_set_num_threads(num_threads); + } + /* Obsolete, will be dropped in the next revision */ DLLEXPORT void SetImprovedConsistency(void) { diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index f6c2930e..65fade82 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.cs @@ -54,9 +54,9 @@ namespace MathNet.Numerics { // Random Numbers & Distributions CheckDistributionParameters = true; - ThreadSafeRandomNumberGenerators = true; // Parallelization & Threading + ThreadSafeRandomNumberGenerators = true; _maxDegreeOfParallelism = Environment.ProcessorCount; _blockSize = 512; _parallelizeOrder = 64; @@ -91,6 +91,16 @@ namespace MathNet.Numerics { _maxDegreeOfParallelism = 1; ThreadSafeRandomNumberGenerators = false; + + LinearAlgebraProvider.InitializeVerify(); + } + + public static void UseMultiThreading() + { + _maxDegreeOfParallelism = Environment.ProcessorCount; + ThreadSafeRandomNumberGenerators = true; + + LinearAlgebraProvider.InitializeVerify(); } public static void UseManaged() @@ -154,7 +164,13 @@ namespace MathNet.Numerics public static int MaxDegreeOfParallelism { get { return _maxDegreeOfParallelism; } - set { _maxDegreeOfParallelism = Math.Max(1, Math.Min(1024, value)); } + set + { + _maxDegreeOfParallelism = Math.Max(1, Math.Min(1024, value)); + + // Reinitialize providers: + LinearAlgebraProvider.InitializeVerify(); + } } /// diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs index 981162b0..b445dc28 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs @@ -149,11 +149,18 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl throw new NotSupportedException("MKL Native Provider found but too old or not compatible."); } + // set numerical consistency, precision and accuracy modes, if supported if (SafeNativeMethods.query_capability(65) > 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) + { + SafeNativeMethods.set_max_threads(Control.MaxDegreeOfParallelism); + } } public override string ToString() diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs index 663c92e6..357c7c07 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs @@ -41,6 +41,8 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl [SecurityCritical] internal static class SafeNativeMethods { + // ReSharper disable InconsistentNaming + /// /// Name of the native DLL. /// @@ -55,6 +57,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl [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 BLAS [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] @@ -342,6 +347,8 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl internal static extern void z_vector_divide(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result); #endregion Vector Functions + + // ReSharper restore InconsistentNaming } }