diff --git a/src/NativeProviders/CUDA/lapack.cpp b/src/NativeProviders/CUDA/lapack.cpp index a7bbbfbd..a4f27923 100644 --- a/src/NativeProviders/CUDA/lapack.cpp +++ b/src/NativeProviders/CUDA/lapack.cpp @@ -65,7 +65,7 @@ inline int lu_inverse(cusolverDnHandle_t solverHandle, cublasHandle_t blasHandle getrf(solverHandle, n, n, d_A, n, work, d_I, d_info); cudaMemcpy(&info, d_info, sizeof(int), cudaMemcpyDeviceToHost); - + cudaFree(work); if (info != 0) @@ -134,7 +134,7 @@ inline int lu_inverse_factored(cublasHandle_t blasHandle, int n, T a[], int ipiv getri(blasHandle, n, d_Aarray, n, d_I, d_Carray, n, d_info, 1); cudaMemcpy(&info, d_info, sizeof(int), cudaMemcpyDeviceToHost); - cublasGetMatrix(n, n, sizeof(T), d_C, n, a, n); + cublasGetMatrix(n, n, sizeof(T), d_C, n, a, n); cublasGetVector(n, sizeof(int), d_I, 1, ipiv, 1); shift_ipiv_down(n, ipiv); @@ -299,7 +299,7 @@ inline int cholesky_solve(cusolverDnHandle_t solverHandle, int n, int nrhs, T a[ cudaMemcpy(&info, d_info, sizeof(int), cudaMemcpyDeviceToHost); cudaFree(work); - + if (info != 0) { cudaFree(d_A); @@ -425,7 +425,7 @@ inline int cholesky_solve_factored(cusolverDnHandle_t solverHandle, int n, int n // int info = 0; // ormqr(solverHandle, &side, &tran, &m, &bn, &n, r, &m, tau, clone_b, &m, work, &len, &info); // trsm(blasHandle, CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, n, bn, 1.0, r, m, clone_b, m); -// +// // copyBtoX(m, n, bn, clone_b, x); // delete[] clone_b; // return info; diff --git a/src/NativeProviders/Common/WindowsDLL.cpp b/src/NativeProviders/Common/WindowsDLL.cpp index 83c4c1e1..7bafd83b 100644 --- a/src/NativeProviders/Common/WindowsDLL.cpp +++ b/src/NativeProviders/Common/WindowsDLL.cpp @@ -2,7 +2,7 @@ #define VC_EXTRALEAN #endif #include "windows.h" - + BOOL APIENTRY DllMain( HANDLE, DWORD, LPVOID ){ return TRUE; } diff --git a/src/NativeProviders/Common/lapack.cpp b/src/NativeProviders/Common/lapack.cpp index 4375f1ef..de6abbe6 100644 --- a/src/NativeProviders/Common/lapack.cpp +++ b/src/NativeProviders/Common/lapack.cpp @@ -16,12 +16,12 @@ inline lapack_int lu_factor(lapack_int m, T a[], lapack_int ipiv[], GETRF getrf) template inline lapack_int lu_inverse(lapack_int n, T a[], GETRF getrf, GETRI getri) { - try + try { auto ipiv = array_new(n); auto info = getrf(LAPACK_COL_MAJOR, n, n, a, n, ipiv.get()); - if (info != 0) + if (info != 0) { return info; } @@ -29,7 +29,7 @@ inline lapack_int lu_inverse(lapack_int n, T a[], GETRF getrf, GETRI getri) info = getri(LAPACK_COL_MAJOR, n, a, n, ipiv.get()); return info; } - catch (std::bad_alloc&) + catch (std::bad_alloc&) { return INSUFFICIENT_MEMORY; } @@ -56,20 +56,20 @@ inline lapack_int lu_solve_factored(lapack_int n, lapack_int nrhs, T a[], lapack template inline lapack_int lu_solve(lapack_int n, lapack_int nrhs, T a[], T b[], GETRF getrf, GETRS getrs) { - try + try { auto clone = array_clone(n * n, a); auto ipiv = array_new(n); auto info = getrf(LAPACK_COL_MAJOR, n, n, clone.get(), n, ipiv.get()); - if (info != 0) + if (info != 0) { return info; } return getrs(LAPACK_COL_MAJOR, 'N', n, nrhs, clone.get(), n, ipiv.get(), b, n); } - catch (std::bad_alloc&) + catch (std::bad_alloc&) { return INSUFFICIENT_MEMORY; } @@ -264,7 +264,7 @@ inline lapack_int svd_factor(bool compute_vectors, lapack_int m, lapack_int n, T template inline lapack_int complex_svd_factor(bool compute_vectors, lapack_int m, lapack_int n, T a[], T s[], T u[], T v[], GESVD gesvd) { - try + try { auto dim_s = std::min(m, n); auto s_local = array_new(dim_s); diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 1c546f4c..8a54e767 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -172,8 +172,10 @@ True Resources.resx + + @@ -188,8 +190,8 @@ - - + + @@ -197,7 +199,7 @@ - + @@ -227,7 +229,7 @@ - + @@ -483,5 +485,6 @@ Resources.Designer.cs + \ No newline at end of file diff --git a/src/Numerics/Providers/Common/Cuda/CudaProvider.cs b/src/Numerics/Providers/Common/Cuda/CudaProvider.cs new file mode 100644 index 00000000..53d2ded5 --- /dev/null +++ b/src/Numerics/Providers/Common/Cuda/CudaProvider.cs @@ -0,0 +1,107 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// +// 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 +// 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. +// + +using System; +using System.Collections.Generic; + +namespace MathNet.Numerics.Providers.Common.Cuda +{ + internal static class CudaProvider + { + static int _nativeRevision; + static bool _nativeX86; + static bool _nativeX64; + static bool _nativeIA64; + + public static bool IsAvailable(int minRevision) + { + try + { + if (!NativeProviderLoader.TryLoad(SafeNativeMethods.DllName)) + { + return false; + } + + int a = SafeNativeMethods.query_capability(0); + int b = SafeNativeMethods.query_capability(1); + int nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); + return a == 0 && b == -1 && nativeRevision >= minRevision; + } + catch + { + return false; + } + } + + public static void Load(int minRevision) + { + int a, b; + try + { + NativeProviderLoader.TryLoad(SafeNativeMethods.DllName); + + a = SafeNativeMethods.query_capability(0); + b = SafeNativeMethods.query_capability(1); + _nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); + + _nativeX86 = SafeNativeMethods.query_capability((int)ProviderPlatform.x86) > 0; + _nativeX64 = SafeNativeMethods.query_capability((int)ProviderPlatform.x64) > 0; + _nativeIA64 = SafeNativeMethods.query_capability((int)ProviderPlatform.ia64) > 0; + } + catch (DllNotFoundException e) + { + throw new NotSupportedException("Cuda Native Provider not found.", e); + } + catch (BadImageFormatException e) + { + throw new NotSupportedException("Cuda Native Provider found but failed to load. Please verify that the platform matches (x64 vs x32, Windows vs Linux).", e); + } + catch (EntryPointNotFoundException e) + { + throw new NotSupportedException("Cuda Native Provider does not support capability querying and is therefore not compatible. Consider upgrading to a newer version.", e); + } + + if (a != 0 || b != -1 || _nativeRevision < minRevision) + { + throw new NotSupportedException("Cuda Native Provider too old. Consider upgrading to a newer version."); + } + } + + public static string Describe() + { + var parts = new List(); + if (_nativeX86) parts.Add("x86"); + if (_nativeX64) parts.Add("x64"); + if (_nativeIA64) parts.Add("IA64"); + parts.Add("revision " + _nativeRevision); + + return string.Concat("Nvidia CUDA (", string.Join("; ", parts), ")"); + } + } +} diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaProviderCapabilities.cs b/src/Numerics/Providers/Common/Cuda/CudaProviderCapabilities.cs similarity index 90% rename from src/Numerics/Providers/LinearAlgebra/Cuda/CudaProviderCapabilities.cs rename to src/Numerics/Providers/Common/Cuda/CudaProviderCapabilities.cs index f25d161d..90002973 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaProviderCapabilities.cs +++ b/src/Numerics/Providers/Common/Cuda/CudaProviderCapabilities.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 @@ -27,7 +27,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // -namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda +namespace MathNet.Numerics.Providers.Common.Cuda { internal enum ProviderPlatform : int { @@ -43,6 +43,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda internal enum ProviderCapability : int { - LinearAlgebra = 128, + LinearAlgebraMajor = 128, + LinearAlgebraMinor = 129, } -} \ No newline at end of file +} diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/SafeNativeMethods.cs b/src/Numerics/Providers/Common/Cuda/SafeNativeMethods.cs similarity index 99% rename from src/Numerics/Providers/LinearAlgebra/Cuda/SafeNativeMethods.cs rename to src/Numerics/Providers/Common/Cuda/SafeNativeMethods.cs index ba58a483..d767e7b0 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/SafeNativeMethods.cs +++ b/src/Numerics/Providers/Common/Cuda/SafeNativeMethods.cs @@ -2,7 +2,7 @@ // Math.NET Numerics, part of the Math.NET Project // http://mathnet.opensourcedotnet.info // -// Copyright (c) 2009-2014 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 @@ -32,8 +32,9 @@ using System; using System.Numerics; using System.Runtime.InteropServices; using System.Security; +using MathNet.Numerics.Providers.LinearAlgebra; -namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda +namespace MathNet.Numerics.Providers.Common.Cuda { /// /// P/Invoke methods to the native math libraries. diff --git a/src/Numerics/Providers/Common/OpenBlas/OpenBlasProvider.cs b/src/Numerics/Providers/Common/OpenBlas/OpenBlasProvider.cs new file mode 100644 index 00000000..473ee263 --- /dev/null +++ b/src/Numerics/Providers/Common/OpenBlas/OpenBlasProvider.cs @@ -0,0 +1,121 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// +// 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 +// 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. +// + +using System; +using System.Collections.Generic; + +namespace MathNet.Numerics.Providers.Common.OpenBlas +{ + internal static class OpenBlasProvider + { + static int _nativeRevision; + static bool _nativeX86; + static bool _nativeX64; + static bool _nativeIA64; + static bool _nativeARM; + + public static bool IsAvailable(int minRevision) + { + try + { + if (!NativeProviderLoader.TryLoad(SafeNativeMethods.DllName)) + { + return false; + } + + int a = SafeNativeMethods.query_capability(0); + int b = SafeNativeMethods.query_capability(1); + int nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); + return a == 0 && b == -1 && nativeRevision >= minRevision; + } + catch + { + return false; + } + } + + public static void Load(int minRevision) + { + int a, b; + try + { + NativeProviderLoader.TryLoad(SafeNativeMethods.DllName); + + a = SafeNativeMethods.query_capability(0); + b = SafeNativeMethods.query_capability(1); + _nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); + + _nativeX86 = SafeNativeMethods.query_capability((int)ProviderPlatform.x86) > 0; + _nativeX64 = SafeNativeMethods.query_capability((int)ProviderPlatform.x64) > 0; + _nativeIA64 = SafeNativeMethods.query_capability((int)ProviderPlatform.ia64) > 0; + _nativeARM = SafeNativeMethods.query_capability((int)ProviderPlatform.arm) > 0; + } + catch (DllNotFoundException e) + { + throw new NotSupportedException("OpenBLAS Native Provider not found.", e); + } + catch (BadImageFormatException e) + { + throw new NotSupportedException("OpenBLAS Native Provider found but failed to load. Please verify that the platform matches (x64 vs x32, Windows vs Linux).", e); + } + catch (EntryPointNotFoundException e) + { + throw new NotSupportedException("OpenBLAS Native Provider does not support capability querying and is therefore not compatible. Consider upgrading to a newer version.", e); + } + + if (a != 0 || b != -1 || _nativeRevision < minRevision) + { + throw new NotSupportedException("OpenBLAS Native Provider too old. Consider upgrading to a newer version."); + } + + ConfigureThreading(); + } + + static void ConfigureThreading() + { + // set threading settings, if supported + if (SafeNativeMethods.query_capability((int)ProviderConfig.Threading) > 0) + { + SafeNativeMethods.set_max_threads(Control.MaxDegreeOfParallelism); + } + } + + public static string Describe() + { + var parts = new List(); + if (_nativeX86) parts.Add("x86"); + if (_nativeX64) parts.Add("x64"); + if (_nativeIA64) parts.Add("IA64"); + if (_nativeARM) parts.Add("ARM"); + parts.Add("revision " + _nativeRevision); + + return string.Concat("OpenBLAS (", string.Join("; ", parts), ")"); + } + } +} diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasProviderCapabilities.cs b/src/Numerics/Providers/Common/OpenBlas/OpenBlasProviderCapabilities.cs similarity index 90% rename from src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasProviderCapabilities.cs rename to src/Numerics/Providers/Common/OpenBlas/OpenBlasProviderCapabilities.cs index b86c52db..858c710e 100644 --- a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasProviderCapabilities.cs +++ b/src/Numerics/Providers/Common/OpenBlas/OpenBlasProviderCapabilities.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 @@ -27,7 +27,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // -namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas +namespace MathNet.Numerics.Providers.Common.OpenBlas { internal enum ProviderPlatform : int { @@ -45,6 +45,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas internal enum ProviderCapability : int { - LinearAlgebra = 128, + LinearAlgebraMajor = 128, + LinearAlgebraMinor = 129 } -} \ No newline at end of file +} diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/SafeNativeMethods.cs b/src/Numerics/Providers/Common/OpenBlas/SafeNativeMethods.cs similarity index 99% rename from src/Numerics/Providers/LinearAlgebra/OpenBlas/SafeNativeMethods.cs rename to src/Numerics/Providers/Common/OpenBlas/SafeNativeMethods.cs index fc024d90..aa62c2cc 100644 --- a/src/Numerics/Providers/LinearAlgebra/OpenBlas/SafeNativeMethods.cs +++ b/src/Numerics/Providers/Common/OpenBlas/SafeNativeMethods.cs @@ -31,8 +31,10 @@ using System.Numerics; using System.Runtime.InteropServices; using System.Security; +using MathNet.Numerics.Providers.LinearAlgebra; +using MathNet.Numerics.Providers.LinearAlgebra.OpenBlas; -namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas +namespace MathNet.Numerics.Providers.Common.OpenBlas { /// /// P/Invoke methods to the native math libraries. diff --git a/src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs b/src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs index eb2bb5c3..58d42e3d 100644 --- a/src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs +++ b/src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs @@ -53,6 +53,11 @@ namespace MathNet.Numerics.Providers.FourierTransform { } + public override string ToString() + { + return "Managed"; + } + public virtual void ForwardInplace(Complex[] complex, FourierTransformScaling scaling) { Fourier.BluesteinForward(complex, Options(scaling)); diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex.cs index 65a4689b..28ae3741 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex.cs @@ -33,6 +33,7 @@ using System; using System.Numerics; using System.Security; using MathNet.Numerics.Properties; +using MathNet.Numerics.Providers.Common.Cuda; namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda { @@ -569,7 +570,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd base.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt); else Solver(SafeNativeMethods.z_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt)); - } + } } } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex32.cs index 5a2f8806..4e5674ff 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex32.cs @@ -32,6 +32,7 @@ using System; using System.Security; using MathNet.Numerics.Properties; +using MathNet.Numerics.Providers.Common.Cuda; namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda { @@ -466,7 +467,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda } Solver(SafeNativeMethods.c_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b)); - } + } /// /// Solves A*X=B for X using the singular value decomposition of A. @@ -568,7 +569,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd base.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt); else Solver(SafeNativeMethods.c_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt)); - } + } } } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Double.cs index 5b3cc78c..1a60985b 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Double.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Double.cs @@ -32,6 +32,7 @@ using System; using System.Security; using MathNet.Numerics.Properties; +using MathNet.Numerics.Providers.Common.Cuda; namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda { @@ -466,7 +467,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda } Solver(SafeNativeMethods.d_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b)); - } + } /// /// Solves A*X=B for X using the singular value decomposition of A. @@ -568,7 +569,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd base.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt); else Solver (SafeNativeMethods.d_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt)); - } + } } } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Single.cs index bfcbf73e..fa109558 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Single.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Single.cs @@ -32,6 +32,7 @@ using System; using System.Security; using MathNet.Numerics.Properties; +using MathNet.Numerics.Providers.Common.Cuda; namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda { @@ -466,7 +467,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda } Solver(SafeNativeMethods.s_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b)); - } + } /// /// Solves A*X=B for X using the singular value decomposition of A. @@ -568,7 +569,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd base.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt); else Solver(SafeNativeMethods.s_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt)); - } + } } } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs index b1c3de28..6ae60291 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs @@ -28,7 +28,7 @@ // using System; -using MathNet.Numerics.Providers.Common; +using MathNet.Numerics.Providers.Common.Cuda; #if NATIVE @@ -39,10 +39,6 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda /// public partial class CudaLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable { - int _nativeRevision; - bool _nativeIX86; - bool _nativeX64; - bool _nativeIA64; IntPtr _blasHandle; IntPtr _solverHandle; @@ -52,22 +48,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda /// public override bool IsAvailable() { - try - { - if (!NativeProviderLoader.TryLoad(SafeNativeMethods.DllName)) - { - return false; - } - - int a = SafeNativeMethods.query_capability(0); - int b = SafeNativeMethods.query_capability(1); - int nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); - return a == 0 && b == -1 && nativeRevision >= 1; - } - catch - { - return false; - } + return CudaProvider.IsAvailable(minRevision: 1); } /// @@ -76,38 +57,14 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda /// public override void InitializeVerify() { - int a, b, linearAlgebra; - try - { - // Load the native library - NativeProviderLoader.TryLoad(SafeNativeMethods.DllName); - - a = SafeNativeMethods.query_capability(0); - b = SafeNativeMethods.query_capability(1); - _nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); + CudaProvider.Load(minRevision: 1); - _nativeIX86 = SafeNativeMethods.query_capability((int)ProviderPlatform.x86) > 0; - _nativeX64 = SafeNativeMethods.query_capability((int)ProviderPlatform.x64) > 0; - _nativeIA64 = SafeNativeMethods.query_capability((int)ProviderPlatform.ia64) > 0; + int linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebraMajor); - linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebra); - } - catch (DllNotFoundException e) + // we only support exactly one major version, since major version changes imply a breaking change. + if (linearAlgebra != 1) { - throw new NotSupportedException("Cuda Native Provider not found.", e); - } - catch (BadImageFormatException e) - { - throw new NotSupportedException("Cuda Native Provider found but failed to load. Please verify that the platform matches (x64 vs x32, Windows vs Linux).", e); - } - catch (EntryPointNotFoundException e) - { - throw new NotSupportedException("Cuda Native Provider does not support capability querying and is therefore not compatible. Consider upgrading to a newer version.", e); - } - - if (a != 0 || b != -1 || linearAlgebra <=0 || _nativeRevision < 1) - { - throw new NotSupportedException("Cuda Native Provider too old or not compatible. Consider upgrading to a newer version."); + throw new NotSupportedException(string.Format("Cuda Native Provider not compatible. Expecting linear algebra v1 but provider implements v{0}.", linearAlgebra)); } BLAS(SafeNativeMethods.createBLASHandle(ref _blasHandle)); @@ -200,12 +157,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda public override string ToString() { - return string.Format("Nvidia CUDA ({1}; revision {0})", - _nativeRevision, - _nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : "unknown"); + return CudaProvider.Describe(); } - public void Dispose() { BLAS(SafeNativeMethods.destroyBLASHandle(_blasHandle)); diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs index f6d1c34a..1de85759 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs @@ -28,7 +28,6 @@ // using System; -using MathNet.Numerics.Providers.Common; using MathNet.Numerics.Providers.Common.Mkl; #if NATIVE diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex.cs index 7a87dac9..88c15144 100644 --- a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex.cs @@ -34,6 +34,7 @@ using MathNet.Numerics.Properties; using System; using System.Numerics; using System.Security; +using MathNet.Numerics.Providers.Common.OpenBlas; namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas { @@ -357,7 +358,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas if (info > 0) { throw new SingularUMatrixException(info); - } + } } /// diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex32.cs index d431c8c9..d49562cf 100644 --- a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex32.cs @@ -34,6 +34,7 @@ using MathNet.Numerics.Properties; using System; using System.Numerics; using System.Security; +using MathNet.Numerics.Providers.Common.OpenBlas; namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas { @@ -357,7 +358,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas if (info > 0) { throw new SingularUMatrixException(info); - } + } } /// diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Double.cs index d4e6b117..4cd9888c 100644 --- a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Double.cs +++ b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Double.cs @@ -34,6 +34,7 @@ using MathNet.Numerics.Properties; using System; using System.Numerics; using System.Security; +using MathNet.Numerics.Providers.Common.OpenBlas; namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas { @@ -357,7 +358,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas if (info > 0) { throw new SingularUMatrixException(info); - } + } } /// diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Single.cs index 7de51a33..2752606f 100644 --- a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Single.cs +++ b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Single.cs @@ -34,6 +34,7 @@ using MathNet.Numerics.Properties; using System; using System.Numerics; using System.Security; +using MathNet.Numerics.Providers.Common.OpenBlas; namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas { @@ -357,7 +358,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas if (info > 0) { throw new SingularUMatrixException(info); - } + } } /// @@ -811,7 +812,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas if (method == QRMethod.Full) { var info = SafeNativeMethods.s_qr_solve_factored(rowsA, columnsA, columnsB, r, b, tau, x); - + if (info == (int)NativeError.MemoryAllocation) { throw new MemoryAllocationException(); diff --git a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs index 18b4cc52..c7306b06 100644 --- a/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs @@ -30,7 +30,7 @@ #if NATIVE using System; -using MathNet.Numerics.Providers.Common; +using MathNet.Numerics.Providers.Common.OpenBlas; namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas { @@ -57,34 +57,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas /// public partial class OpenBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider { - int _nativeRevision; - bool _nativeIX86; - bool _nativeX64; - bool _nativeIA64; - bool _nativeARM; - /// /// Try to find out whether the provider is available, at least in principle. /// Verification may still fail if available, but it will certainly fail if unavailable. /// public override bool IsAvailable() { - try - { - if (!NativeProviderLoader.TryLoad(SafeNativeMethods.DllName)) - { - return false; - } - - int a = SafeNativeMethods.query_capability(0); - int b = SafeNativeMethods.query_capability(1); - int nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); - return a == 0 && b == -1 && nativeRevision >= 1; - } - catch - { - return false; - } + return OpenBlasProvider.IsAvailable(minRevision: 1); } /// @@ -93,53 +72,20 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas /// public override void InitializeVerify() { - int a, b, linearAlgebra; - try - { - // Load the native library - NativeProviderLoader.TryLoad(SafeNativeMethods.DllName); - - a = SafeNativeMethods.query_capability(0); - b = SafeNativeMethods.query_capability(1); - _nativeRevision = SafeNativeMethods.query_capability((int)ProviderConfig.Revision); + OpenBlasProvider.Load(minRevision: 1); - _nativeIX86 = SafeNativeMethods.query_capability((int)ProviderPlatform.x86) > 0; - _nativeX64 = SafeNativeMethods.query_capability((int)ProviderPlatform.x64) > 0; - _nativeIA64 = SafeNativeMethods.query_capability((int)ProviderPlatform.ia64) > 0; - _nativeARM = SafeNativeMethods.query_capability((int)ProviderPlatform.arm) > 0; - - linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebra); - } - catch (DllNotFoundException e) - { - throw new NotSupportedException("OpenBLAS Native Provider not found.", e); - } - catch (BadImageFormatException e) - { - throw new NotSupportedException("OpenBLAS Native Provider found but failed to load. Please verify that the platform matches (x64 vs x32, Windows vs Linux).", e); - } - catch (EntryPointNotFoundException e) - { - throw new NotSupportedException("OpenBLAS Native Provider does not support capability querying and is therefore not compatible. Consider upgrading to a newer version.", e); - } - - if (a != 0 || b != -1 || linearAlgebra <=0 || _nativeRevision < 1) - { - throw new NotSupportedException("OpenBLAS Native Provider too old or not compatible. Consider upgrading to a newer version."); - } + int linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebraMajor); - // set threading settings, if supported - if (SafeNativeMethods.query_capability((int)ProviderConfig.Threading) > 0) + // we only support exactly one major version, since major version changes imply a breaking change. + if (linearAlgebra != 1) { - SafeNativeMethods.set_max_threads(Control.MaxDegreeOfParallelism); + throw new NotSupportedException(string.Format("OpenBLAS Native Provider not compatible. Expecting linear algebra v1 but provider implements v{0}.", linearAlgebra)); } } public override string ToString() { - return string.Format("OpenBLAS ({1}; revision {0})", - _nativeRevision, - _nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : _nativeARM ? "ARM" : "unknown"); + return OpenBlasProvider.Describe(); } } }