From 999d1454aa8a078dbb2cc2bf1a5c0231cd220abc Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sun, 30 Oct 2016 18:29:54 +0100 Subject: [PATCH] Provider Control: expose separate control for LA and FFT, more sensible semantics on the Try variants --- src/Numerics/Control.cs | 49 ++++++++++++------- .../FourierTransformControl.cs | 29 +++++++++-- .../LinearAlgebra/LinearAlgebraControl.cs | 47 +++++++++++++++--- 3 files changed, 96 insertions(+), 29 deletions(-) diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index 8cbae11c..5b47a0c2 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.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 @@ -72,6 +72,25 @@ namespace MathNet.Numerics FourierTransformControl.UseManaged(); } + /// + /// Use a specific provider if configured, e.g. using + /// environment variables, or fall back to the best providers. + /// + public static void UseDefaultProviders() + { + LinearAlgebraControl.UseDefault(); + FourierTransformControl.UseDefault(); + } + + /// + /// Use the best provider available. + /// + public static void UseBestProviders() + { + LinearAlgebraControl.UseBest(); + FourierTransformControl.UseBest(); + } + #if NATIVE /// @@ -125,7 +144,9 @@ namespace MathNet.Numerics /// public static bool TryUseNativeMKL() { - return Try(UseNativeMKL); + bool linearAlgebra = LinearAlgebraControl.TryUseNativeMKL(); + bool fourierTransform = FourierTransformControl.TryUseNativeMKL(); + return linearAlgebra || fourierTransform; } /// @@ -146,7 +167,8 @@ namespace MathNet.Numerics /// public static bool TryUseNativeCUDA() { - return Try(UseNativeCUDA); + bool linearAlgebra = LinearAlgebraControl.TryUseNativeCUDA(); + return linearAlgebra; } /// @@ -167,7 +189,8 @@ namespace MathNet.Numerics /// public static bool TryUseNativeOpenBLAS() { - return Try(UseNativeOpenBLAS); + bool linearAlgebra = LinearAlgebraControl.TryUseNativeOpenBLAS(); + return linearAlgebra; } /// @@ -179,21 +202,9 @@ namespace MathNet.Numerics /// public static bool TryUseNative() { - return TryUseNativeCUDA() || TryUseNativeMKL() || TryUseNativeOpenBLAS(); - } - - static bool Try(Action action) - { - try - { - action(); - return true; - } - catch - { - // intentionally swallow exceptions here - use the non-try variants if you're interested in why - return false; - } + bool linearAlgebra = LinearAlgebraControl.TryUseNative(); + bool fourierTransform = FourierTransformControl.TryUseNative(); + return linearAlgebra || fourierTransform; } #endif diff --git a/src/Numerics/Providers/FourierTransform/FourierTransformControl.cs b/src/Numerics/Providers/FourierTransform/FourierTransformControl.cs index d553cd27..2e191bc6 100644 --- a/src/Numerics/Providers/FourierTransform/FourierTransformControl.cs +++ b/src/Numerics/Providers/FourierTransform/FourierTransformControl.cs @@ -31,7 +31,7 @@ using System; namespace MathNet.Numerics.Providers.FourierTransform { - internal static class FourierTransformControl + public static class FourierTransformControl { const string EnvVarFFTProvider = "MathNetNumericsFFTProvider"; @@ -45,9 +45,14 @@ namespace MathNet.Numerics.Providers.FourierTransform { Control.FourierTransformProvider = new Mkl.MklFourierTransformProvider(); } + + public static bool TryUseNativeMKL() + { + return TryUse(new Mkl.MklFourierTransformProvider()); + } #endif - public static bool TryUse(IFourierTransformProvider provider) + static bool TryUse(IFourierTransformProvider provider) { try { @@ -66,10 +71,21 @@ namespace MathNet.Numerics.Providers.FourierTransform } } + /// + /// Try to use a native provider, if available. + /// + public static bool TryUseNative() + { + return TryUseNativeMKL(); + } + + /// + /// Use the best provider available. + /// public static void UseBest() { #if NATIVE - if (!TryUse(new Mkl.MklFourierTransformProvider())) + if (!TryUseNative()) { UseManaged(); } @@ -78,6 +94,11 @@ namespace MathNet.Numerics.Providers.FourierTransform #endif } + /// + /// Use a specific provider if configured, e.g. using the + /// "MathNetNumericsFFTProvider" environment variable, + /// or fall back to the best provider. + /// public static void UseDefault() { #if NATIVE @@ -94,7 +115,7 @@ namespace MathNet.Numerics.Providers.FourierTransform break; } #else - UseManaged(); + UseBest(); #endif } } diff --git a/src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs b/src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs index e3712c46..c9787445 100644 --- a/src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs +++ b/src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs @@ -31,7 +31,7 @@ using System; namespace MathNet.Numerics.Providers.LinearAlgebra { - internal static class LinearAlgebraControl + public static class LinearAlgebraControl { const string EnvVarLAProvider = "MathNetNumericsLAProvider"; @@ -41,6 +41,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } #if NATIVE + [CLSCompliant(false)] public static void UseNativeMKL( Common.Mkl.MklConsistency consistency = Common.Mkl.MklConsistency.Auto, Common.Mkl.MklPrecision precision = Common.Mkl.MklPrecision.Double, @@ -49,18 +50,37 @@ namespace MathNet.Numerics.Providers.LinearAlgebra Control.LinearAlgebraProvider = new Mkl.MklLinearAlgebraProvider(consistency, precision, accuracy); } + [CLSCompliant(false)] + public static bool TryUseNativeMKL( + Common.Mkl.MklConsistency consistency = Common.Mkl.MklConsistency.Auto, + Common.Mkl.MklPrecision precision = Common.Mkl.MklPrecision.Double, + Common.Mkl.MklAccuracy accuracy = Common.Mkl.MklAccuracy.High) + { + return TryUse(new Mkl.MklLinearAlgebraProvider(consistency, precision, accuracy)); + } + public static void UseNativeCUDA() { Control.LinearAlgebraProvider = new Cuda.CudaLinearAlgebraProvider(); } + public static bool TryUseNativeCUDA() + { + return TryUse(new Cuda.CudaLinearAlgebraProvider()); + } + public static void UseNativeOpenBLAS() { Control.LinearAlgebraProvider = new OpenBlas.OpenBlasLinearAlgebraProvider(); } + + public static bool TryUseNativeOpenBLAS() + { + return TryUse(new OpenBlas.OpenBlasLinearAlgebraProvider()); + } #endif - public static bool TryUse(ILinearAlgebraProvider provider) + static bool TryUse(ILinearAlgebraProvider provider) { try { @@ -79,12 +99,21 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Try to use a native provider, if available. + /// + public static bool TryUseNative() + { + return TryUseNativeCUDA() || TryUseNativeMKL() || TryUseNativeOpenBLAS(); + } + + /// + /// Use the best provider available. + /// public static void UseBest() { #if NATIVE - if (!(TryUse(new Cuda.CudaLinearAlgebraProvider()) - || TryUse(new Mkl.MklLinearAlgebraProvider()) - || TryUse(new OpenBlas.OpenBlasLinearAlgebraProvider()))) + if (!TryUseNative()) { UseManaged(); } @@ -93,6 +122,11 @@ namespace MathNet.Numerics.Providers.LinearAlgebra #endif } + /// + /// Use a specific provider if configured, e.g. using the + /// "MathNetNumericsLAProvider" environment variable, + /// or fall back to the best provider. + /// public static void UseDefault() { #if NATIVE @@ -110,12 +144,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra case "OPENBLAS": UseNativeOpenBLAS(); break; + default: UseBest(); break; } #else - UseManaged(); + UseBest(); #endif } }