diff --git a/MathNet.Numerics.NativeProviders.sln b/MathNet.Numerics.NativeProviders.sln index 4e790037..be88b6d5 100644 --- a/MathNet.Numerics.NativeProviders.sln +++ b/MathNet.Numerics.NativeProviders.sln @@ -170,6 +170,7 @@ Global {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|Win32.ActiveCfg = Debug|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|x64.ActiveCfg = Debug|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|x64.Build.0 = Debug|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Any CPU.ActiveCfg = Release|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Any CPU.Build.0 = Release|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU @@ -196,6 +197,7 @@ Global {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|Mixed Platforms.Build.0 = Release|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|Win32.ActiveCfg = Release|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|x64.ActiveCfg = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|x64.Build.0 = Release|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Any CPU.Build.0 = Release|Any CPU {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Any CPU @@ -245,6 +247,7 @@ Global {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Debug|Win32.ActiveCfg = Debug|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Debug|x64.ActiveCfg = Debug|Any CPU + {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Debug|x64.Build.0 = Debug|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release|Any CPU.ActiveCfg = Release|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release|Any CPU.Build.0 = Release|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU @@ -271,6 +274,7 @@ Global {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|Mixed Platforms.Build.0 = Release|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|Win32.ActiveCfg = Release|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|x64.ActiveCfg = Release|Any CPU + {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release|x64.Build.0 = Release|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|Any CPU.Build.0 = Release|Any CPU {E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Any CPU @@ -344,6 +348,26 @@ Global {96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|Mixed Platforms.Build.0 = Release|Any CPU {96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|Win32.ActiveCfg = Release|Any CPU {96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|x64.ActiveCfg = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Debug|x64.ActiveCfg = Debug|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Debug|x64.Build.0 = Debug|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release|Any CPU.Build.0 = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release|Win32.ActiveCfg = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release|x64.ActiveCfg = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release|x64.Build.0 = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release-Signed|Any CPU.Build.0 = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release-Signed|Mixed Platforms.Build.0 = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release-Signed|Win32.ActiveCfg = Release|Any CPU + {2386FAD1-BB99-4597-885C-8EF81D0637BA}.Release-Signed|x64.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/NativeProviders/CUDA/capabilities.cpp b/src/NativeProviders/CUDA/capabilities.cpp index f1a15370..db1e6faf 100644 --- a/src/NativeProviders/CUDA/capabilities.cpp +++ b/src/NativeProviders/CUDA/capabilities.cpp @@ -1,3 +1,5 @@ +#include + #include "wrapper_cuda.h" #include "cuda_runtime.h" #include "cublas_v2.h" @@ -19,20 +21,6 @@ extern "C" { int device; cudaDeviceProp prop; - if (cudaGetDeviceCount(&count)) - return 0; - - if (count == 0) - return 0; - - if (cudaGetDevice(&device)) - return 0; - - if (cudaGetDeviceProperties(&prop, device)) - return 0; - - - switch (capability) { @@ -62,10 +50,34 @@ extern "C" { // COMMON/SHARED case 64: + if (cudaGetDeviceCount(&count)) + return 0; + + if (count == 0) + return 0; + + if (cudaGetDevice(&device)) + return 0; + + if (cudaGetDeviceProperties(&prop, device)) + return 0; + return prop.major; // LINEAR ALGEBRA case 128: + if (cudaGetDeviceCount(&count)) + return 0; + + if (count == 0) + return 0; + + if (cudaGetDevice(&device)) + return 0; + + if (cudaGetDeviceProperties(&prop, device)) + return 0; + return prop.major >= 2; // OPTIMIZATION @@ -80,25 +92,25 @@ extern "C" { } DLLEXPORT CudaResults createBLASHandle(cublasHandle_t *blasHandle){ - CudaResults ret; - ret.blasStatus = cublasCreate(blasHandle); + CudaResults ret = { cudaError_t::cudaSuccess, cublasStatus_t::CUBLAS_STATUS_SUCCESS, cusolverStatus_t::CUSOLVER_STATUS_SUCCESS }; + ret.blasStatus = cublasCreate(blasHandle); return ret; } DLLEXPORT CudaResults destroyBLASHandle(cublasHandle_t blasHandle){ - CudaResults ret; + CudaResults ret = { cudaError_t::cudaSuccess, cublasStatus_t::CUBLAS_STATUS_SUCCESS, cusolverStatus_t::CUSOLVER_STATUS_SUCCESS }; ret.blasStatus = cublasDestroy(blasHandle); return ret; } DLLEXPORT CudaResults createSolverHandle(cusolverDnHandle_t *solverHandle){ - CudaResults ret; + CudaResults ret = { cudaError_t::cudaSuccess, cublasStatus_t::CUBLAS_STATUS_SUCCESS, cusolverStatus_t::CUSOLVER_STATUS_SUCCESS }; ret.solverStatus = cusolverDnCreate(solverHandle); return ret; } DLLEXPORT CudaResults destroySolverHandle(cusolverDnHandle_t solverHandle){ - CudaResults ret; + CudaResults ret = { cudaError_t::cudaSuccess, cublasStatus_t::CUBLAS_STATUS_SUCCESS, cusolverStatus_t::CUSOLVER_STATUS_SUCCESS }; ret.solverStatus = cusolverDnDestroy(solverHandle); return ret; } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CuSolverException.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CuSolverException.cs index b1617ee3..9b63a4f1 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CuSolverException.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CuSolverException.cs @@ -58,7 +58,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda /// /// Returns the appropriate error message for each status code. /// - /// The status code returned from the API + /// The status code returned from the API /// The corresponding error message private static string GetErrorMessage(int statusCode) { diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CublasException.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CublasException.cs index 1d51f603..65b536ff 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CublasException.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CublasException.cs @@ -58,7 +58,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda /// /// Returns the appropriate error message for each status code. /// - /// The status code returned from the API + /// The status code returned from the API /// The corresponding error message private static string GetErrorMessage(int statusCode) { diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex.cs index 1215689d..c87b6880 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex.cs @@ -477,6 +477,11 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda int info = 0; HandleResults(SafeNativeMethods.z_cholesky_factor(_solverHandle, order, a, ref info)); + + if (info > 0) + { + throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); + } } /// @@ -707,10 +712,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda throw new ArgumentException(Resources.ArgumentArraysSameLength, "s"); } - int info = 0; 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, new Complex[rowsA]); - else HandleResults(SafeNativeMethods.z_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt, ref info)); + else + { + int info = 0; + HandleResults(SafeNativeMethods.z_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt, ref info)); + if (info != 0) + throw new NonConvergenceException(); + } } } } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex32.cs index 091e693c..edde9c1e 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Complex32.cs @@ -477,6 +477,11 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda int info = 0; HandleResults(SafeNativeMethods.c_cholesky_factor(_solverHandle, order, a, ref info)); + + if (info > 0) + { + throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); + } } /// @@ -707,10 +712,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda throw new ArgumentException(Resources.ArgumentArraysSameLength, "s"); } - int info = 0; 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, new Complex32[rowsA]); - else HandleResults(SafeNativeMethods.c_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt, ref info)); + else + { + int info = 0; + HandleResults(SafeNativeMethods.c_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt, ref info)); + if (info != 0) + throw new NonConvergenceException(); + } } } } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Double.cs index 65ed5fff..d722994c 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Double.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Double.cs @@ -477,6 +477,11 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda int info = 0; HandleResults(SafeNativeMethods.d_cholesky_factor(_solverHandle, order, a, ref info)); + + if (info > 0) + { + throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); + } } /// @@ -707,10 +712,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda throw new ArgumentException(Resources.ArgumentArraysSameLength, "s"); } - int info = 0; 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, new double[rowsA]); - else HandleResults(SafeNativeMethods.d_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt, ref info)); + else + { + int info = 0; + HandleResults(SafeNativeMethods.d_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt, ref info)); + if (info != 0) + throw new NonConvergenceException(); + } } } } diff --git a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Single.cs index d2549030..ba3e187f 100644 --- a/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Single.cs +++ b/src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.Single.cs @@ -477,6 +477,11 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda int info = 0; HandleResults(SafeNativeMethods.s_cholesky_factor(_solverHandle, order, a, ref info)); + + if (info > 0) + { + throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); + } } /// @@ -707,10 +712,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda throw new ArgumentException(Resources.ArgumentArraysSameLength, "s"); } - int info = 0; 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, new float[rowsA]); - else HandleResults(SafeNativeMethods.s_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt, ref info)); + else + { + int info = 0; + HandleResults(SafeNativeMethods.s_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt, ref info)); + if (info != 0) + throw new NonConvergenceException(); + } } } }