diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs
index 9ccd07e4..f8475fd2 100644
--- a/src/Numerics/Control.cs
+++ b/src/Numerics/Control.cs
@@ -30,7 +30,6 @@
using MathNet.Numerics.Providers.LinearAlgebra;
using System;
-using System.IO;
using System.Threading.Tasks;
namespace MathNet.Numerics
@@ -40,6 +39,8 @@ namespace MathNet.Numerics
///
public static class Control
{
+ const string EnvVarLAProvider = "MathNetNumericsLAProvider";
+
static int _maxDegreeOfParallelism;
static int _blockSize;
static int _parallelizeOrder;
@@ -70,63 +71,58 @@ namespace MathNet.Numerics
#else
try
{
- const string name = "MathNetNumericsLAProvider";
- var value = Environment.GetEnvironmentVariable(name);
+ var value = Environment.GetEnvironmentVariable(EnvVarLAProvider);
switch (value != null ? value.ToUpperInvariant() : string.Empty)
{
#if NATIVE
case "MKL":
- LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
+ UseNativeMKL();
break;
case "CUDA":
- LinearAlgebraProvider = new Providers.LinearAlgebra.Cuda.CudaLinearAlgebraProvider();
+ UseNativeCUDA();
break;
case "OPENBLAS":
- LinearAlgebraProvider = new Providers.LinearAlgebra.OpenBlas.OpenBlasLinearAlgebraProvider();
+ UseNativeOpenBLAS();
break;
#endif
default:
- LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
+ if (!TryUseNative())
+ {
+ UseManaged();
+ }
break;
}
}
catch
{
// We don't care about any failures here at all (because "auto")
- LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
+ UseManaged();
}
#endif
}
- public static void UseSingleThread()
- {
- _maxDegreeOfParallelism = 1;
- ThreadSafeRandomNumberGenerators = false;
-
- LinearAlgebraProvider.InitializeVerify();
- }
-
- public static void UseMultiThreading()
- {
- _maxDegreeOfParallelism = Environment.ProcessorCount;
- ThreadSafeRandomNumberGenerators = true;
-
- LinearAlgebraProvider.InitializeVerify();
- }
-
public static void UseManaged()
{
LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
}
#if NATIVE
+
+ ///
+ /// Use the Intel MKL native provider for linear algebra.
+ /// Throws if it is not available or failed to initialize, in which case the previous provider is still active.
+ ///
public static void UseNativeMKL()
{
LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
}
+ ///
+ /// Use the Intel MKL native provider for linear algebra, with the specified configuration parameters.
+ /// Throws if it is not available or failed to initialize, in which case the previous provider is still active.
+ ///
[CLSCompliant(false)]
public static void UseNativeMKL(
Providers.LinearAlgebra.Mkl.MklConsistency consistency = Providers.LinearAlgebra.Mkl.MklConsistency.Auto,
@@ -136,17 +132,103 @@ namespace MathNet.Numerics
LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider(consistency, precision, accuracy);
}
+ ///
+ /// Try to use the Intel MKL native provider for linear algebra.
+ ///
+ ///
+ /// True if the provider was found and initialized successfully.
+ /// False if it failed and the previous provider is still active.
+ ///
+ public static bool TryUseNativeMKL()
+ {
+ return Try(UseNativeMKL);
+ }
+
+ ///
+ /// Use the Nvidia CUDA native provider for linear algebra.
+ /// Throws if it is not available or failed to initialize, in which case the previous provider is still active.
+ ///
public static void UseNativeCUDA()
{
LinearAlgebraProvider = new Providers.LinearAlgebra.Cuda.CudaLinearAlgebraProvider();
}
+ ///
+ /// Try to use the Nvidia CUDA native provider for linear algebra.
+ ///
+ ///
+ /// True if the provider was found and initialized successfully.
+ /// False if it failed and the previous provider is still active.
+ ///
+ public static bool TryUseNativeCUDA()
+ {
+ return Try(UseNativeCUDA);
+ }
+
+ ///
+ /// Use the OpenBLAS native provider for linear algebra.
+ /// Throws if it is not available or failed to initialize, in which case the previous provider is still active.
+ ///
public static void UseNativeOpenBLAS()
{
LinearAlgebraProvider = new Providers.LinearAlgebra.OpenBlas.OpenBlasLinearAlgebraProvider();
}
+
+ ///
+ /// Try to use the OpenBLAS native provider for linear algebra.
+ ///
+ ///
+ /// True if the provider was found and initialized successfully.
+ /// False if it failed and the previous provider is still active.
+ ///
+ public static bool TryUseNativeOpenBLAS()
+ {
+ return Try(UseNativeOpenBLAS);
+ }
+
+ ///
+ /// Try to use any available native provider in an undefined order.
+ ///
+ ///
+ /// True if one of the native providers was found and successfully initialized.
+ /// False if it failed and the previous provider is still active.
+ ///
+ 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;
+ }
+ }
#endif
+ public static void UseSingleThread()
+ {
+ _maxDegreeOfParallelism = 1;
+ ThreadSafeRandomNumberGenerators = false;
+
+ LinearAlgebraProvider.InitializeVerify();
+ }
+
+ public static void UseMultiThreading()
+ {
+ _maxDegreeOfParallelism = Environment.ProcessorCount;
+ ThreadSafeRandomNumberGenerators = true;
+
+ LinearAlgebraProvider.InitializeVerify();
+ }
+
///
/// Gets or sets a value indicating whether the distribution classes check validate each parameter.
/// For the multivariate distributions this could involve an expensive matrix factorization.