Browse Source

AppContext app switches to disable native providers or their probing

pull/729/head
Christoph Ruegg 6 years ago
parent
commit
ad05896d3b
  1. 1
      MathNet.Numerics.sln.DotSettings
  2. 109
      src/Numerics/AppSwitches.cs
  3. 20
      src/Numerics/Control.cs
  4. 12
      src/Numerics/Providers/Common/Cuda/CudaProvider.cs
  5. 12
      src/Numerics/Providers/Common/Mkl/MklProvider.cs
  6. 12
      src/Numerics/Providers/Common/OpenBlas/OpenBlasProvider.cs
  7. 19
      src/Numerics/Providers/FourierTransform/FourierTransformControl.cs
  8. 21
      src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs
  9. 4
      src/Numerics/Providers/SparseSolver/Mkl/MklSparseSolverProvider.cs
  10. 48
      src/Numerics/Providers/SparseSolver/SparseSolverControl.cs

1
MathNet.Numerics.sln.DotSettings

@ -1,6 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Full_0020Cleanup_0020_0028Math_002ENET_0029/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Full Cleanup (Math.NET)"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSRemoveCodeRedundancies&gt;True&lt;/CSRemoveCodeRedundancies&gt;&lt;CSUseAutoProperty&gt;True&lt;/CSUseAutoProperty&gt;&lt;CSMakeFieldReadonly&gt;True&lt;/CSMakeFieldReadonly&gt;&lt;CSUpdateFileHeader&gt;True&lt;/CSUpdateFileHeader&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;XMLReformatCode&gt;True&lt;/XMLReformatCode&gt;&lt;CssAlphabetizeProperties&gt;True&lt;/CssAlphabetizeProperties&gt;&lt;CssReformatCode&gt;True&lt;/CssReformatCode&gt;&lt;JsReformatCode&gt;True&lt;/JsReformatCode&gt;&lt;JsInsertSemicolon&gt;True&lt;/JsInsertSemicolon&gt;&lt;VBFormatDocComments&gt;True&lt;/VBFormatDocComments&gt;&lt;VBReformatCode&gt;True&lt;/VBReformatCode&gt;&lt;VBShortenReferences&gt;True&lt;/VBShortenReferences&gt;&lt;VBOptimizeImports&gt;True&lt;/VBOptimizeImports&gt;&lt;HtmlReformatCode&gt;True&lt;/HtmlReformatCode&gt;&lt;AspOptimizeRegisterDirectives&gt;True&lt;/AspOptimizeRegisterDirectives&gt;&lt;CSReorderTypeMembers&gt;True&lt;/CSReorderTypeMembers&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;CAN_CHANGE_BOTH&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_WHEN_INITIALIZER_HAS_TYPE&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;ALWAYS_EXPLICIT&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;/Profile&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Full Cleanup (Math.NET)</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_PRIVATE_MODIFIER/@EntryValue">Implicit</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_LINQ_QUERY/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARGUMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARRAY_AND_OBJECT_INITIALIZER/@EntryValue">False</s:Boolean>

109
src/Numerics/AppSwitches.cs

@ -0,0 +1,109 @@
// <copyright file="AppSwitches.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// https://numerics.mathdotnet.com
// https://github.com/mathnet/mathnet-numerics
// https://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2020 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>
namespace MathNet.Numerics
{
/// <summary>
/// AppContext based switches to disable functionality, controllable through also in the
/// host application through AppContext or by configuration with AppContextSwitchOverride.
/// https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/appcontextswitchoverrides-element
/// </summary>
/// <remarks>
/// Since AppContext is not supported on .NET Framework 4.0, a local implementation is used there instead,
/// which cannot be controlled though configuration or through AppContext.
/// </remarks>
public static class AppSwitches
{
const string AppSwitchDisableNativeProviderProbing = "Switch.MathNet.Numerics.Providers.DisableNativeProviderProbing";
const string AppSwitchDisableNativeProviders = "Switch.MathNet.Numerics.Providers.DisableNativeProviders";
const string AppSwitchDisableMklNativeProvider = "Switch.MathNet.Numerics.Providers.DisableMklNativeProvider";
const string AppSwitchDisableAcmlNativeProvider = "Switch.MathNet.Numerics.Providers.DisableAcmlNativeProvider";
const string AppSwitchDisableCudaNativeProvider = "Switch.MathNet.Numerics.Providers.DisableCudaNativeProvider";
const string AppSwitchDisableOpenBlasNativeProvider = "Switch.MathNet.Numerics.Providers.DisableOpenBlasNativeProvider";
#if NET40
static readonly System.Collections.Generic.Dictionary<string, bool> Switches = new System.Collections.Generic.Dictionary<string, bool>();
#endif
static void SetSwitch(string switchName, bool isEnabled)
{
#if NET40
Switches[switchName] = isEnabled;
#else
System.AppContext.SetSwitch(switchName, isEnabled);
#endif
}
static bool IsEnabled(string switchName)
{
#if NET40
return Switches.TryGetValue(switchName, out bool isEnabled) && isEnabled;
#else
return System.AppContext.TryGetSwitch(switchName, out bool isEnabled) && isEnabled;
#endif
}
public static bool DisableNativeProviderProbing
{
get => IsEnabled(AppSwitchDisableNativeProviderProbing);
set => SetSwitch(AppSwitchDisableNativeProviderProbing, value);
}
public static bool DisableNativeProviders
{
get => IsEnabled(AppSwitchDisableNativeProviders);
set => SetSwitch(AppSwitchDisableNativeProviders, value);
}
public static bool DisableMklNativeProvider
{
get => IsEnabled(AppSwitchDisableMklNativeProvider);
set => SetSwitch(AppSwitchDisableMklNativeProvider, value);
}
public static bool DisableAcmlNativeProvider
{
get => IsEnabled(AppSwitchDisableAcmlNativeProvider);
set => SetSwitch(AppSwitchDisableAcmlNativeProvider, value);
}
public static bool DisableCudaNativeProvider
{
get => IsEnabled(AppSwitchDisableCudaNativeProvider);
set => SetSwitch(AppSwitchDisableCudaNativeProvider, value);
}
public static bool DisableOpenBlasNativeProvider
{
get => IsEnabled(AppSwitchDisableOpenBlasNativeProvider);
set => SetSwitch(AppSwitchDisableOpenBlasNativeProvider, value);
}
}
}

20
src/Numerics/Control.cs

@ -87,6 +87,12 @@ namespace MathNet.Numerics
/// </summary>
public static void UseDefaultProviders()
{
if (AppSwitches.DisableNativeProviders)
{
UseManaged();
return;
}
LinearAlgebraControl.UseDefault();
FourierTransformControl.UseDefault();
SparseSolverControl.UseDefault();
@ -97,6 +103,12 @@ namespace MathNet.Numerics
/// </summary>
public static void UseBestProviders()
{
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableNativeProviderProbing)
{
UseManaged();
return;
}
LinearAlgebraControl.UseBest();
FourierTransformControl.UseBest();
SparseSolverControl.UseBest();
@ -198,9 +210,15 @@ namespace MathNet.Numerics
/// </returns>
public static bool TryUseNative()
{
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableNativeProviderProbing)
{
return false;
}
bool linearAlgebra = LinearAlgebraControl.TryUseNative();
bool fourierTransform = FourierTransformControl.TryUseNative();
return linearAlgebra || fourierTransform;
bool directSparseSolver = SparseSolverControl.TryUseNative();
return linearAlgebra || fourierTransform || directSparseSolver;
}
#endif

12
src/Numerics/Providers/Common/Cuda/CudaProvider.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2018 Math.NET
// Copyright (c) 2009-2020 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -52,6 +52,11 @@ namespace MathNet.Numerics.Providers.Common.Cuda
return true;
}
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableCudaNativeProvider)
{
return false;
}
try
{
if (!NativeProviderLoader.TryLoad(SafeNativeMethods.DllName, hintPath))
@ -78,6 +83,11 @@ namespace MathNet.Numerics.Providers.Common.Cuda
return _nativeRevision;
}
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableCudaNativeProvider)
{
throw new NotSupportedException("CUDA Native Provider support is actively disabled by AppSwitches.");
}
int a, b;
try
{

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

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2018 Math.NET
// Copyright (c) 2009-2020 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -53,6 +53,11 @@ namespace MathNet.Numerics.Providers.Common.Mkl
return true;
}
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableMklNativeProvider)
{
return false;
}
try
{
if (!NativeProviderLoader.TryLoad(SafeNativeMethods.DllName, hintPath))
@ -90,6 +95,11 @@ namespace MathNet.Numerics.Providers.Common.Mkl
return _nativeRevision;
}
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableMklNativeProvider)
{
throw new NotSupportedException("MKL Native Provider support is actively disabled by AppSwitches.");
}
int a, b;
try
{

12
src/Numerics/Providers/Common/OpenBlas/OpenBlasProvider.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2018 Math.NET
// Copyright (c) 2009-2020 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -53,6 +53,11 @@ namespace MathNet.Numerics.Providers.Common.OpenBlas
return true;
}
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableOpenBlasNativeProvider)
{
return false;
}
try
{
if (!NativeProviderLoader.TryLoad(SafeNativeMethods.DllName, hintPath))
@ -79,6 +84,11 @@ namespace MathNet.Numerics.Providers.Common.OpenBlas
return _nativeRevision;
}
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableOpenBlasNativeProvider)
{
throw new NotSupportedException("OpenBLAS Native Provider support is actively disabled by AppSwitches.");
}
int a, b;
try
{

19
src/Numerics/Providers/FourierTransform/FourierTransformControl.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2018 Math.NET
// Copyright (c) 2009-2020 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -107,6 +107,11 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// </summary>
public static bool TryUseNative()
{
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableNativeProviderProbing)
{
return false;
}
return TryUseNativeMKL();
}
#endif
@ -135,6 +140,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// </summary>
public static void UseBest()
{
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableNativeProviderProbing)
{
UseManaged();
return;
}
#if NATIVE
if (!TryUseNative())
{
@ -152,6 +163,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// </summary>
public static void UseDefault()
{
if (AppSwitches.DisableNativeProviders)
{
UseManaged();
return;
}
#if NATIVE
var value = Environment.GetEnvironmentVariable(EnvVarFFTProvider);
switch (value != null ? value.ToUpperInvariant() : string.Empty)

21
src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2018 Math.NET
// Copyright (c) 2009-2020 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -160,7 +160,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary>
public static bool TryUseNative()
{
return TryUseNativeCUDA() || TryUseNativeMKL() || TryUseNativeOpenBLAS();
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableNativeProviderProbing)
{
return false;
}
return TryUseNativeMKL() || TryUseNativeOpenBLAS() || TryUseNativeCUDA();
}
#endif
@ -188,6 +193,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary>
public static void UseBest()
{
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableNativeProviderProbing)
{
UseManaged();
return;
}
#if NATIVE
if (!TryUseNative())
{
@ -205,6 +216,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary>
public static void UseDefault()
{
if (AppSwitches.DisableNativeProviders)
{
UseManaged();
return;
}
#if NATIVE
var value = Environment.GetEnvironmentVariable(EnvVarLAProvider);
switch (value != null ? value.ToUpperInvariant() : string.Empty)

4
src/Numerics/Providers/SparseSolver/Mkl/MklSparseSolverProvider.cs

@ -10,7 +10,7 @@ namespace MathNet.Numerics.Providers.SparseSolver.Mkl
/// </summary>
internal partial class MklSparseSolverProvider : Managed.ManagedSparseSolverProvider, IDisposable
{
const int MinimumCompatibleRevision = 12;
const int MinimumCompatibleRevision = 14;
readonly string _hintPath;
@ -43,7 +43,7 @@ namespace MathNet.Numerics.Providers.SparseSolver.Mkl
{
throw new NotSupportedException($"MKL Native Provider revision r{revision} is too old. Consider upgrading to a newer version. Revision r{MinimumCompatibleRevision} and newer are supported.");
}
sparseSolverMajor = SafeNativeMethods.query_capability((int)ProviderCapability.SparseSolverMajor);
sparseSolverMinor = SafeNativeMethods.query_capability((int)ProviderCapability.SparseSolverMinor);
if (!(sparseSolverMajor == 1 && sparseSolverMinor >= 0))

48
src/Numerics/Providers/SparseSolver/SparseSolverControl.cs

@ -1,4 +1,33 @@
using System;
// <copyright file="SparseSolverControl.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-2020 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.SparseSolver
{
@ -78,6 +107,11 @@ namespace MathNet.Numerics.Providers.SparseSolver
/// </summary>
public static bool TryUseNative()
{
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableNativeProviderProbing)
{
return false;
}
return TryUseNativeMKL();
}
#endif
@ -106,6 +140,12 @@ namespace MathNet.Numerics.Providers.SparseSolver
/// </summary>
public static void UseBest()
{
if (AppSwitches.DisableNativeProviders || AppSwitches.DisableNativeProviderProbing)
{
UseManaged();
return;
}
#if NATIVE
if (!TryUseNative())
{
@ -123,6 +163,12 @@ namespace MathNet.Numerics.Providers.SparseSolver
/// </summary>
public static void UseDefault()
{
if (AppSwitches.DisableNativeProviders)
{
UseManaged();
return;
}
#if NATIVE
var value = Environment.GetEnvironmentVariable(EnvVarSSProvider);
switch (value != null ? value.ToUpperInvariant() : string.Empty)

Loading…
Cancel
Save