diff --git a/build/MathNet.Numerics.CUDA.Win.nuspec b/build/MathNet.Numerics.CUDA.Win.nuspec
index 18c297df..928a1139 100644
--- a/build/MathNet.Numerics.CUDA.Win.nuspec
+++ b/build/MathNet.Numerics.CUDA.Win.nuspec
@@ -5,24 +5,22 @@
@build.number@
Math.NET Numerics - CUDA Native Provider for Windows (x64)
Matthew A Johnson, Christoph Ruegg
- Matthew A Johnson, Christoph Ruegg
false
- https://numerics.mathdotnet.com/License.html
+ MIT
https://numerics.mathdotnet.com/
- https://www.mathdotnet.com/images/MathNet128.png
Nvidia CUDA native libraries for Math.NET Numerics.
Nvidia CUDA native libraries for Math.NET Numerics.
@releaseNotes@
+ Copyright Math.NET Project
math numeric statistics probability integration interpolation linear algebra matrix fft native cuda gpu
-
-
-
-
+
+
+
+
-
-
+
diff --git a/build/MathNet.Numerics.MKL.Linux-x64.nuspec b/build/MathNet.Numerics.MKL.Linux-x64.nuspec
index 84a95856..5d0ce96e 100644
--- a/build/MathNet.Numerics.MKL.Linux-x64.nuspec
+++ b/build/MathNet.Numerics.MKL.Linux-x64.nuspec
@@ -5,23 +5,21 @@
@build.number@
Math.NET Numerics - MKL Native Provider for Linux (x64)
Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
- Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
false
- https://numerics.mathdotnet.com/License.html
+ MIT
https://numerics.mathdotnet.com/
- https://www.mathdotnet.com/images/MathNet128.png
Intel MKL native libraries for Math.NET Numerics on Linux.
Intel MKL native libraries for Math.NET Numerics on Linux.
@releaseNotes@
+ Copyright Math.NET Project
math numeric statistics probability integration interpolation linear algebra matrix fft native mkl
@dependencies@
-
-
+
+
-
-
+
diff --git a/build/MathNet.Numerics.MKL.Linux-x86.nuspec b/build/MathNet.Numerics.MKL.Linux-x86.nuspec
index 35125b42..266d5b3f 100644
--- a/build/MathNet.Numerics.MKL.Linux-x86.nuspec
+++ b/build/MathNet.Numerics.MKL.Linux-x86.nuspec
@@ -5,23 +5,21 @@
@build.number@
Math.NET Numerics - MKL Native Provider for Linux (x86)
Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
- Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
false
- https://numerics.mathdotnet.com/License.html
+ MIT
https://numerics.mathdotnet.com/
- https://www.mathdotnet.com/images/MathNet128.png
Intel MKL native libraries for Math.NET Numerics on Linux.
Intel MKL native libraries for Math.NET Numerics on Linux.
@releaseNotes@
+ Copyright Math.NET Project
math numeric statistics probability integration interpolation linear algebra matrix fft native mkl
@dependencies@
-
-
+
+
-
-
+
diff --git a/build/MathNet.Numerics.MKL.Linux.nuspec b/build/MathNet.Numerics.MKL.Linux.nuspec
index 3d70dfd1..a7408557 100644
--- a/build/MathNet.Numerics.MKL.Linux.nuspec
+++ b/build/MathNet.Numerics.MKL.Linux.nuspec
@@ -5,25 +5,23 @@
@build.number@
Math.NET Numerics - MKL Native Provider for Linux (x64 and x86)
Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
- Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
false
- https://numerics.mathdotnet.com/License.html
+ MIT
https://numerics.mathdotnet.com/
- https://www.mathdotnet.com/images/MathNet128.png
Intel MKL native libraries for Math.NET Numerics on Linux.
Intel MKL native libraries for Math.NET Numerics on Linux.
@releaseNotes@
+ Copyright Math.NET Project
math numeric statistics probability integration interpolation linear algebra matrix fft native mkl
@dependencies@
-
-
-
-
+
+
+
+
-
-
+
diff --git a/build/MathNet.Numerics.MKL.Win-x64.nuspec b/build/MathNet.Numerics.MKL.Win-x64.nuspec
index 6e51aa84..5940436e 100644
--- a/build/MathNet.Numerics.MKL.Win-x64.nuspec
+++ b/build/MathNet.Numerics.MKL.Win-x64.nuspec
@@ -5,23 +5,21 @@
@build.number@
Math.NET Numerics - MKL Native Provider for Windows (x64)
Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
- Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
false
- https://numerics.mathdotnet.com/License.html
+ MIT
https://numerics.mathdotnet.com/
- https://www.mathdotnet.com/images/MathNet128.png
Intel oneAPI MKL native libraries for Math.NET Numerics on Windows.
Intel oneAPI MKL native libraries for Math.NET Numerics on Windows.
@releaseNotes@
+ Copyright Math.NET Project
math numeric statistics probability integration interpolation linear algebra matrix fft native mkl
@dependencies@
-
-
+
+
-
-
+
diff --git a/build/MathNet.Numerics.MKL.Win-x86.nuspec b/build/MathNet.Numerics.MKL.Win-x86.nuspec
index 86158e0f..29215dfa 100644
--- a/build/MathNet.Numerics.MKL.Win-x86.nuspec
+++ b/build/MathNet.Numerics.MKL.Win-x86.nuspec
@@ -5,23 +5,21 @@
@build.number@
Math.NET Numerics - MKL Native Provider for Windows (x86)
Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
- Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
false
- https://numerics.mathdotnet.com/License.html
+ MIT
https://numerics.mathdotnet.com/
- https://www.mathdotnet.com/images/MathNet128.png
Intel oneAPI MKL native libraries for Math.NET Numerics on Windows.
Intel oneAPI MKL native libraries for Math.NET Numerics on Windows.
@releaseNotes@
+ Copyright Math.NET Project
math numeric statistics probability integration interpolation linear algebra matrix fft native mkl
@dependencies@
-
-
+
+
-
-
+
diff --git a/build/MathNet.Numerics.MKL.Win.nuspec b/build/MathNet.Numerics.MKL.Win.nuspec
index b2c9f3e7..227c9a76 100644
--- a/build/MathNet.Numerics.MKL.Win.nuspec
+++ b/build/MathNet.Numerics.MKL.Win.nuspec
@@ -5,25 +5,23 @@
@build.number@
Math.NET Numerics - MKL Native Provider for Windows (x64 and x86)
Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
- Christoph Ruegg, Marcus Cuda, Jurgen Van Gael
false
- https://numerics.mathdotnet.com/License.html
+ MIT
https://numerics.mathdotnet.com/
- https://www.mathdotnet.com/images/MathNet128.png
Intel oneAPI MKL native libraries for Math.NET Numerics on Windows.
Intel oneAPI MKL native libraries for Math.NET Numerics on Windows.
@releaseNotes@
+ Copyright Math.NET Project
math numeric statistics probability integration interpolation linear algebra matrix fft native mkl
@dependencies@
-
-
-
-
+
+
+
+
-
-
+
diff --git a/build/MathNet.Numerics.OpenBLAS.Win.nuspec b/build/MathNet.Numerics.OpenBLAS.Win.nuspec
index 26d225e3..f64dc155 100644
--- a/build/MathNet.Numerics.OpenBLAS.Win.nuspec
+++ b/build/MathNet.Numerics.OpenBLAS.Win.nuspec
@@ -5,31 +5,29 @@
@build.number@
Math.NET Numerics - OpenBLAS Native Provider for Windows (x64 and x86)
Kuan Bartel, Christoph Ruegg, Marcus Cuda
- Kuan Bartel, Christoph Ruegg, Marcus Cuda
false
- https://numerics.mathdotnet.com/License.html
+ MIT
https://numerics.mathdotnet.com/
- https://www.mathdotnet.com/images/MathNet128.png
OpenBLAS native libraries for Math.NET Numerics.
OpenBLAS native libraries for Math.NET Numerics.
@releaseNotes@
+ Copyright Math.NET Project
math numeric statistics probability integration interpolation linear algebra matrix fft native openblas
@dependencies@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
diff --git a/build/NativeProvider.targets b/build/NativeProvider.targets
index d32847dc..805634c5 100644
--- a/build/NativeProvider.targets
+++ b/build/NativeProvider.targets
@@ -4,9 +4,9 @@
** Math.NET Native Provider Interop Files **
******************************************************************************
-->
-
-
-
+
+
+
%(RecursiveDir)%(FileName)%(Extension)
PreserveNewest
diff --git a/src/Providers.CUDA/NativeProviderLoader.cs b/src/Providers.CUDA/NativeProviderLoader.cs
index 75a923b4..b1e72510 100644
--- a/src/Providers.CUDA/NativeProviderLoader.cs
+++ b/src/Providers.CUDA/NativeProviderLoader.cs
@@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
-// Copyright (c) 2009-2016 Math.NET
+// Copyright (c) 2009-2021 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -37,6 +37,17 @@ using System.Threading;
namespace MathNet.Numerics.Providers.CUDA
{
+ internal enum Runtime
+ {
+ Unknown = 0,
+ WindowsX64,
+ WindowsX86,
+ WindowsArm64,
+ WindowsArm,
+ LinuxX64,
+ LinuxX86,
+ }
+
///
/// Helper class to load native libraries depending on the architecture of the OS and process.
///
@@ -44,12 +55,6 @@ namespace MathNet.Numerics.Providers.CUDA
{
static readonly object StaticLock = new Object();
- const string X86 = "x86";
- const string X64 = "x64";
- const string IA64 = "ia64";
- const string ARM = "arm";
- const string ARM64 = "arm64";
-
///
/// Dictionary of handles to previously loaded libraries,
///
@@ -58,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA
///
/// Gets a string indicating the architecture and bitness of the current process.
///
- static readonly Lazy ArchitectureKey = new Lazy(EvaluateArchitectureKey, LazyThreadSafetyMode.PublicationOnly);
+ static readonly Lazy RuntimeKey = new Lazy(EvaluateRuntime, LazyThreadSafetyMode.PublicationOnly);
///
/// If the last native library failed to load then gets the corresponding exception
@@ -75,42 +80,35 @@ namespace MathNet.Numerics.Providers.CUDA
}
}
- static string EvaluateArchitectureKey()
+ static Runtime EvaluateRuntime()
{
//return (IntPtr.Size == 8) ? X64 : X86;
if (IsUnix)
{
-
// Only support x86 and amd64 on Unix as there isn't a reliable way to detect the architecture
- return Environment.Is64BitProcess ? X64 : X86;
-
+ return Environment.Is64BitProcess ? Runtime.LinuxX64 : Runtime.LinuxX86;
}
var architecture = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
if (string.Equals(architecture, "x86", StringComparison.OrdinalIgnoreCase))
{
- return X86;
+ return Runtime.WindowsX86;
}
if (string.Equals(architecture, "amd64", StringComparison.OrdinalIgnoreCase)
|| string.Equals(architecture, "x64", StringComparison.OrdinalIgnoreCase))
{
- return Environment.Is64BitProcess ? X64 : X86;
- }
-
- if (string.Equals(architecture, "ia64", StringComparison.OrdinalIgnoreCase))
- {
- return IA64;
+ return Environment.Is64BitProcess ? Runtime.WindowsX64 : Runtime.WindowsX86;
}
if (string.Equals(architecture, "arm", StringComparison.OrdinalIgnoreCase))
{
- return Environment.Is64BitProcess ? ARM64 : ARM;
+ return Environment.Is64BitProcess ? Runtime.WindowsArm64 : Runtime.WindowsArm;
}
// Fallback if unknown
- return architecture;
+ return Runtime.Unknown;
}
///
@@ -169,31 +167,77 @@ namespace MathNet.Numerics.Providers.CUDA
directory = Path.GetFullPath(directory);
// If we have a know architecture, try the matching subdirectory first
- var architecture = ArchitectureKey.Value;
- if (!string.IsNullOrEmpty(architecture) && TryLoadFile(new FileInfo(Path.Combine(Path.Combine(directory, architecture), fileName))))
+ switch (RuntimeKey.Value)
{
- return true;
+ case Runtime.WindowsX64:
+ if (TryLoadFile(directory, "x64", fileName)
+ || TryLoadFile(directory, "win-x64/native", fileName)
+ || TryLoadFile(directory, "win-x64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsX86:
+ if (TryLoadFile(directory, "x86", fileName)
+ || TryLoadFile(directory, "win-x86/native", fileName)
+ || TryLoadFile(directory, "win-x86", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsArm64:
+ if (TryLoadFile(directory, "arm64", fileName)
+ || TryLoadFile(directory, "win-arm64/native", fileName)
+ || TryLoadFile(directory, "win-arm64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsArm:
+ if (TryLoadFile(directory, "arm", fileName)
+ || TryLoadFile(directory, "win-arm/native", fileName)
+ || TryLoadFile(directory, "win-arm", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.LinuxX64:
+ if (TryLoadFile(directory, "x64", fileName)
+ || TryLoadFile(directory, "linux-x64/native", fileName)
+ || TryLoadFile(directory, "linux-x64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.LinuxX86:
+ if (TryLoadFile(directory, "x86", fileName)
+ || TryLoadFile(directory, "linux-x86/native", fileName)
+ || TryLoadFile(directory, "linux-x86", fileName))
+ {
+ return true;
+ }
+ break;
}
// Otherwise try to load directly from the provided directory
- return TryLoadFile(new FileInfo(Path.Combine(directory, fileName)));
+ return TryLoadFile(directory, string.Empty, fileName);
}
///
/// Try to load a native library by providing the full path including the file name of the library.
///
/// True if the library was successfully loaded or if it has already been loaded.
- static bool TryLoadFile(FileInfo file)
+ static bool TryLoadFile(string directory, string relativePath, string fileName)
{
lock (StaticLock)
{
- IntPtr libraryHandle;
- if (NativeHandles.Value.TryGetValue(file.Name, out libraryHandle))
+ if (NativeHandles.Value.TryGetValue(fileName, out IntPtr libraryHandle))
{
return true;
}
- if (!file.Exists)
+ var fullPath = Path.GetFullPath(Path.Combine(Path.Combine(directory, relativePath), fileName));
+ if (!File.Exists(fullPath))
{
// If the library isn't found within an architecture specific folder then return false
// to allow normal P/Invoke searching behavior when the library is called
@@ -201,7 +245,7 @@ namespace MathNet.Numerics.Providers.CUDA
}
// If successful this will return a handle to the library
- libraryHandle = IsUnix ? UnixLoader.LoadLibrary(file.FullName) : WindowsLoader.LoadLibrary(file.FullName);
+ libraryHandle = IsUnix ? UnixLoader.LoadLibrary(fullPath) : WindowsLoader.LoadLibrary(fullPath);
if (libraryHandle == IntPtr.Zero)
{
int lastError = Marshal.GetLastWin32Error();
@@ -211,7 +255,7 @@ namespace MathNet.Numerics.Providers.CUDA
else
{
LastException = null;
- NativeHandles.Value[file.Name] = libraryHandle;
+ NativeHandles.Value[fileName] = libraryHandle;
}
return libraryHandle != IntPtr.Zero;
diff --git a/src/Providers.MKL/NativeProviderLoader.cs b/src/Providers.MKL/NativeProviderLoader.cs
index 96d21224..9eea4b23 100644
--- a/src/Providers.MKL/NativeProviderLoader.cs
+++ b/src/Providers.MKL/NativeProviderLoader.cs
@@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
-// Copyright (c) 2009-2016 Math.NET
+// Copyright (c) 2009-2021 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -35,8 +35,21 @@ using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
+// ReSharper disable InconsistentNaming
+
namespace MathNet.Numerics.Providers.MKL
{
+ internal enum Runtime
+ {
+ Unknown = 0,
+ WindowsX64,
+ WindowsX86,
+ WindowsArm64,
+ WindowsArm,
+ LinuxX64,
+ LinuxX86,
+ }
+
///
/// Helper class to load native libraries depending on the architecture of the OS and process.
///
@@ -44,12 +57,6 @@ namespace MathNet.Numerics.Providers.MKL
{
static readonly object StaticLock = new Object();
- const string X86 = "x86";
- const string X64 = "x64";
- const string IA64 = "ia64";
- const string ARM = "arm";
- const string ARM64 = "arm64";
-
///
/// Dictionary of handles to previously loaded libraries,
///
@@ -58,7 +65,7 @@ namespace MathNet.Numerics.Providers.MKL
///
/// Gets a string indicating the architecture and bitness of the current process.
///
- static readonly Lazy ArchitectureKey = new Lazy(EvaluateArchitectureKey, LazyThreadSafetyMode.PublicationOnly);
+ static readonly Lazy RuntimeKey = new Lazy(EvaluateRuntime, LazyThreadSafetyMode.PublicationOnly);
///
/// If the last native library failed to load then gets the corresponding exception
@@ -75,42 +82,35 @@ namespace MathNet.Numerics.Providers.MKL
}
}
- static string EvaluateArchitectureKey()
+ static Runtime EvaluateRuntime()
{
//return (IntPtr.Size == 8) ? X64 : X86;
if (IsUnix)
{
-
// Only support x86 and amd64 on Unix as there isn't a reliable way to detect the architecture
- return Environment.Is64BitProcess ? X64 : X86;
-
+ return Environment.Is64BitProcess ? Runtime.LinuxX64 : Runtime.LinuxX86;
}
var architecture = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
if (string.Equals(architecture, "x86", StringComparison.OrdinalIgnoreCase))
{
- return X86;
+ return Runtime.WindowsX86;
}
if (string.Equals(architecture, "amd64", StringComparison.OrdinalIgnoreCase)
|| string.Equals(architecture, "x64", StringComparison.OrdinalIgnoreCase))
{
- return Environment.Is64BitProcess ? X64 : X86;
- }
-
- if (string.Equals(architecture, "ia64", StringComparison.OrdinalIgnoreCase))
- {
- return IA64;
+ return Environment.Is64BitProcess ? Runtime.WindowsX64 : Runtime.WindowsX86;
}
if (string.Equals(architecture, "arm", StringComparison.OrdinalIgnoreCase))
{
- return Environment.Is64BitProcess ? ARM64 : ARM;
+ return Environment.Is64BitProcess ? Runtime.WindowsArm64 : Runtime.WindowsArm;
}
// Fallback if unknown
- return architecture;
+ return Runtime.Unknown;
}
///
@@ -169,31 +169,77 @@ namespace MathNet.Numerics.Providers.MKL
directory = Path.GetFullPath(directory);
// If we have a know architecture, try the matching subdirectory first
- var architecture = ArchitectureKey.Value;
- if (!string.IsNullOrEmpty(architecture) && TryLoadFile(new FileInfo(Path.Combine(Path.Combine(directory, architecture), fileName))))
+ switch (RuntimeKey.Value)
{
- return true;
+ case Runtime.WindowsX64:
+ if (TryLoadFile(directory, "x64", fileName)
+ || TryLoadFile(directory, "win-x64/native", fileName)
+ || TryLoadFile(directory, "win-x64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsX86:
+ if (TryLoadFile(directory, "x86", fileName)
+ || TryLoadFile(directory, "win-x86/native", fileName)
+ || TryLoadFile(directory, "win-x86", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsArm64:
+ if (TryLoadFile(directory, "arm64", fileName)
+ || TryLoadFile(directory, "win-arm64/native", fileName)
+ || TryLoadFile(directory, "win-arm64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsArm:
+ if (TryLoadFile(directory, "arm", fileName)
+ || TryLoadFile(directory, "win-arm/native", fileName)
+ || TryLoadFile(directory, "win-arm", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.LinuxX64:
+ if (TryLoadFile(directory, "x64", fileName)
+ || TryLoadFile(directory, "linux-x64/native", fileName)
+ || TryLoadFile(directory, "linux-x64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.LinuxX86:
+ if (TryLoadFile(directory, "x86", fileName)
+ || TryLoadFile(directory, "linux-x86/native", fileName)
+ || TryLoadFile(directory, "linux-x86", fileName))
+ {
+ return true;
+ }
+ break;
}
// Otherwise try to load directly from the provided directory
- return TryLoadFile(new FileInfo(Path.Combine(directory, fileName)));
+ return TryLoadFile(directory, string.Empty, fileName);
}
///
/// Try to load a native library by providing the full path including the file name of the library.
///
/// True if the library was successfully loaded or if it has already been loaded.
- static bool TryLoadFile(FileInfo file)
+ static bool TryLoadFile(string directory, string relativePath, string fileName)
{
lock (StaticLock)
{
- IntPtr libraryHandle;
- if (NativeHandles.Value.TryGetValue(file.Name, out libraryHandle))
+ if (NativeHandles.Value.TryGetValue(fileName, out IntPtr libraryHandle))
{
return true;
}
- if (!file.Exists)
+ var fullPath = Path.GetFullPath(Path.Combine(Path.Combine(directory, relativePath), fileName));
+ if (!File.Exists(fullPath))
{
// If the library isn't found within an architecture specific folder then return false
// to allow normal P/Invoke searching behavior when the library is called
@@ -201,7 +247,7 @@ namespace MathNet.Numerics.Providers.MKL
}
// If successful this will return a handle to the library
- libraryHandle = IsUnix ? UnixLoader.LoadLibrary(file.FullName) : WindowsLoader.LoadLibrary(file.FullName);
+ libraryHandle = IsUnix ? UnixLoader.LoadLibrary(fullPath) : WindowsLoader.LoadLibrary(fullPath);
if (libraryHandle == IntPtr.Zero)
{
int lastError = Marshal.GetLastWin32Error();
@@ -211,7 +257,7 @@ namespace MathNet.Numerics.Providers.MKL
else
{
LastException = null;
- NativeHandles.Value[file.Name] = libraryHandle;
+ NativeHandles.Value[fileName] = libraryHandle;
}
return libraryHandle != IntPtr.Zero;
diff --git a/src/Providers.OpenBLAS/NativeProviderLoader.cs b/src/Providers.OpenBLAS/NativeProviderLoader.cs
index 17518d53..c8b995cf 100644
--- a/src/Providers.OpenBLAS/NativeProviderLoader.cs
+++ b/src/Providers.OpenBLAS/NativeProviderLoader.cs
@@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
-// Copyright (c) 2009-2016 Math.NET
+// Copyright (c) 2009-2021 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -37,6 +37,17 @@ using System.Threading;
namespace MathNet.Numerics.Providers.OpenBLAS
{
+ internal enum Runtime
+ {
+ Unknown = 0,
+ WindowsX64,
+ WindowsX86,
+ WindowsArm64,
+ WindowsArm,
+ LinuxX64,
+ LinuxX86,
+ }
+
///
/// Helper class to load native libraries depending on the architecture of the OS and process.
///
@@ -44,12 +55,6 @@ namespace MathNet.Numerics.Providers.OpenBLAS
{
static readonly object StaticLock = new Object();
- const string X86 = "x86";
- const string X64 = "x64";
- const string IA64 = "ia64";
- const string ARM = "arm";
- const string ARM64 = "arm64";
-
///
/// Dictionary of handles to previously loaded libraries,
///
@@ -58,7 +63,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS
///
/// Gets a string indicating the architecture and bitness of the current process.
///
- static readonly Lazy ArchitectureKey = new Lazy(EvaluateArchitectureKey, LazyThreadSafetyMode.PublicationOnly);
+ static readonly Lazy RuntimeKey = new Lazy(EvaluateRuntime, LazyThreadSafetyMode.PublicationOnly);
///
/// If the last native library failed to load then gets the corresponding exception
@@ -75,42 +80,35 @@ namespace MathNet.Numerics.Providers.OpenBLAS
}
}
- static string EvaluateArchitectureKey()
+ static Runtime EvaluateRuntime()
{
//return (IntPtr.Size == 8) ? X64 : X86;
if (IsUnix)
{
-
// Only support x86 and amd64 on Unix as there isn't a reliable way to detect the architecture
- return Environment.Is64BitProcess ? X64 : X86;
-
+ return Environment.Is64BitProcess ? Runtime.LinuxX64 : Runtime.LinuxX86;
}
var architecture = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
if (string.Equals(architecture, "x86", StringComparison.OrdinalIgnoreCase))
{
- return X86;
+ return Runtime.WindowsX86;
}
if (string.Equals(architecture, "amd64", StringComparison.OrdinalIgnoreCase)
|| string.Equals(architecture, "x64", StringComparison.OrdinalIgnoreCase))
{
- return Environment.Is64BitProcess ? X64 : X86;
- }
-
- if (string.Equals(architecture, "ia64", StringComparison.OrdinalIgnoreCase))
- {
- return IA64;
+ return Environment.Is64BitProcess ? Runtime.WindowsX64 : Runtime.WindowsX86;
}
if (string.Equals(architecture, "arm", StringComparison.OrdinalIgnoreCase))
{
- return Environment.Is64BitProcess ? ARM64 : ARM;
+ return Environment.Is64BitProcess ? Runtime.WindowsArm64 : Runtime.WindowsArm;
}
// Fallback if unknown
- return architecture;
+ return Runtime.Unknown;
}
///
@@ -169,31 +167,77 @@ namespace MathNet.Numerics.Providers.OpenBLAS
directory = Path.GetFullPath(directory);
// If we have a know architecture, try the matching subdirectory first
- var architecture = ArchitectureKey.Value;
- if (!string.IsNullOrEmpty(architecture) && TryLoadFile(new FileInfo(Path.Combine(Path.Combine(directory, architecture), fileName))))
+ switch (RuntimeKey.Value)
{
- return true;
+ case Runtime.WindowsX64:
+ if (TryLoadFile(directory, "x64", fileName)
+ || TryLoadFile(directory, "win-x64/native", fileName)
+ || TryLoadFile(directory, "win-x64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsX86:
+ if (TryLoadFile(directory, "x86", fileName)
+ || TryLoadFile(directory, "win-x86/native", fileName)
+ || TryLoadFile(directory, "win-x86", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsArm64:
+ if (TryLoadFile(directory, "arm64", fileName)
+ || TryLoadFile(directory, "win-arm64/native", fileName)
+ || TryLoadFile(directory, "win-arm64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.WindowsArm:
+ if (TryLoadFile(directory, "arm", fileName)
+ || TryLoadFile(directory, "win-arm/native", fileName)
+ || TryLoadFile(directory, "win-arm", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.LinuxX64:
+ if (TryLoadFile(directory, "x64", fileName)
+ || TryLoadFile(directory, "linux-x64/native", fileName)
+ || TryLoadFile(directory, "linux-x64", fileName))
+ {
+ return true;
+ }
+ break;
+ case Runtime.LinuxX86:
+ if (TryLoadFile(directory, "x86", fileName)
+ || TryLoadFile(directory, "linux-x86/native", fileName)
+ || TryLoadFile(directory, "linux-x86", fileName))
+ {
+ return true;
+ }
+ break;
}
// Otherwise try to load directly from the provided directory
- return TryLoadFile(new FileInfo(Path.Combine(directory, fileName)));
+ return TryLoadFile(directory, string.Empty, fileName);
}
///
/// Try to load a native library by providing the full path including the file name of the library.
///
/// True if the library was successfully loaded or if it has already been loaded.
- static bool TryLoadFile(FileInfo file)
+ static bool TryLoadFile(string directory, string relativePath, string fileName)
{
lock (StaticLock)
{
- IntPtr libraryHandle;
- if (NativeHandles.Value.TryGetValue(file.Name, out libraryHandle))
+ if (NativeHandles.Value.TryGetValue(fileName, out IntPtr libraryHandle))
{
return true;
}
- if (!file.Exists)
+ var fullPath = Path.GetFullPath(Path.Combine(Path.Combine(directory, relativePath), fileName));
+ if (!File.Exists(fullPath))
{
// If the library isn't found within an architecture specific folder then return false
// to allow normal P/Invoke searching behavior when the library is called
@@ -201,7 +245,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS
}
// If successful this will return a handle to the library
- libraryHandle = IsUnix ? UnixLoader.LoadLibrary(file.FullName) : WindowsLoader.LoadLibrary(file.FullName);
+ libraryHandle = IsUnix ? UnixLoader.LoadLibrary(fullPath) : WindowsLoader.LoadLibrary(fullPath);
if (libraryHandle == IntPtr.Zero)
{
int lastError = Marshal.GetLastWin32Error();
@@ -211,7 +255,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS
else
{
LastException = null;
- NativeHandles.Value[file.Name] = libraryHandle;
+ NativeHandles.Value[fileName] = libraryHandle;
}
return libraryHandle != IntPtr.Zero;