From bf1f3b81523673d1a3b4ce4b987710d32fbf57e6 Mon Sep 17 00:00:00 2001 From: Matthew Johnson Date: Fri, 24 Apr 2015 02:18:22 +0100 Subject: [PATCH] Adding in some naive first stabs at integration. --- MathNet.Numerics.NativeProviders.sln | 3 +- src/NativeProviders/CUDA/blas.c | 93 ++++ src/NativeProviders/CUDA/lapack.cpp | 521 ++++++++++++++++++ src/NativeProviders/CUDA/vector_functions.c | 0 .../Windows/CUDA/CUDAWrapper.vcxproj | 70 ++- .../Windows/CUDA/CUDAWrapper.vcxproj.filters | 3 - 6 files changed, 684 insertions(+), 6 deletions(-) delete mode 100644 src/NativeProviders/CUDA/vector_functions.c diff --git a/MathNet.Numerics.NativeProviders.sln b/MathNet.Numerics.NativeProviders.sln index 232e00b6..1c7bf18d 100644 --- a/MathNet.Numerics.NativeProviders.sln +++ b/MathNet.Numerics.NativeProviders.sln @@ -118,7 +118,8 @@ Global {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Debug|Win32.ActiveCfg = Debug|Win32 {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Debug|Win32.Build.0 = Debug|Win32 - {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Debug|x64.ActiveCfg = Debug|Win32 + {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Debug|x64.ActiveCfg = Debug|x64 + {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Debug|x64.Build.0 = Debug|x64 {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release|Any CPU.ActiveCfg = Release|Win32 {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release|Mixed Platforms.Build.0 = Release|Win32 diff --git a/src/NativeProviders/CUDA/blas.c b/src/NativeProviders/CUDA/blas.c index e69de29b..18ff81aa 100644 --- a/src/NativeProviders/CUDA/blas.c +++ b/src/NativeProviders/CUDA/blas.c @@ -0,0 +1,93 @@ +#include "cublas_v2.h" +#include "wrapper_common.h" + +#if GCC +extern "C" { +#endif + DLLEXPORT void s_axpy(const cublasHandle_t handle, const int n, const float alpha, const float x[], float y[]){ + cublasSaxpy(handle, n, &alpha, x, 1, y, 1); + } + + DLLEXPORT void d_axpy(const cublasHandle_t handle, const int n, const double alpha, const double x[], double y[]){ + cublasDaxpy(handle, n, &alpha, x, 1, y, 1); + } + + DLLEXPORT void c_axpy(const cublasHandle_t handle, const int n, const cuComplex alpha, const cuComplex x[], cuComplex y[]){ + cublasCaxpy(handle, n, &alpha, x, 1, y, 1); + } + + DLLEXPORT void z_axpy(const cublasHandle_t handle, const int n, const cuDoubleComplex alpha, const cuDoubleComplex x[], cuDoubleComplex y[]){ + cublasZaxpy(handle, n, &alpha, x, 1, y, 1); + } + + DLLEXPORT void s_scale(const cublasHandle_t handle, const int n, const float alpha, float x[]){ + cublasSscal(handle, n, &alpha, x, 1); + } + + DLLEXPORT void d_scale(const cublasHandle_t handle, const int n, const double alpha, double x[]){ + cublasDscal(handle, n, &alpha, x, 1); + } + + DLLEXPORT void c_scale(const cublasHandle_t handle, const int n, const cuComplex alpha, cuComplex x[]){ + cublasCscal(handle, n, &alpha, x, 1); + } + + DLLEXPORT void z_scale(const cublasHandle_t handle, const int n, const cuDoubleComplex alpha, cuDoubleComplex x[]){ + cublasZscal(handle, n, &alpha, x, 1); + } + + DLLEXPORT float s_dot_product(const cublasHandle_t handle, const int n, const float x[], const float y[]){ + float ret; + cublasSdot(handle, n, x, 1, y, 1, &ret); + return ret; + } + + DLLEXPORT double d_dot_product(const cublasHandle_t handle, const int n, const double x[], const double y[]){ + double ret; + cublasDdot(handle, n, x, 1, y, 1, &ret); + return ret; + } + + DLLEXPORT cuComplex c_dot_product(const cublasHandle_t handle, const int n, const cuComplex x[], const cuComplex y[]){ + cuComplex ret; + cublasCdotu(handle, n, x, 1, y, 1, &ret); + return ret; + } + + DLLEXPORT cuDoubleComplex z_dot_product(const cublasHandle_t handle, const int n, const cuDoubleComplex x[], const cuDoubleComplex y[]){ + cuDoubleComplex ret; + cublasZdotu(handle, n, x, 1, y, 1, &ret); + return ret; + } + + DLLEXPORT void s_matrix_multiply(const cublasHandle_t handle, cublasOperation_t transA, cublasOperation_t transB, const int m, const int n, const int k, const float alpha, const float x[], const float y[], const float beta, float c[]){ + int lda = transA == CUBLAS_OP_N ? m : k; + int ldb = transB == CUBLAS_OP_N ? k : n; + + cublasSgemm(handle, transA, transB, m, n, k, &alpha, x, lda, y, ldb, &beta, c, m); + } + + DLLEXPORT void d_matrix_multiply(const cublasHandle_t handle, cublasOperation_t transA, cublasOperation_t transB, const int m, const int n, const int k, const double alpha, const double x[], const double y[], const double beta, double c[]){ + int lda = transA == CUBLAS_OP_N ? m : k; + int ldb = transB == CUBLAS_OP_N ? k : n; + + cublasDgemm(handle, transA, transB, m, n, k, &alpha, x, lda, y, ldb, &beta, c, m); + } + + DLLEXPORT void c_matrix_multiply(const cublasHandle_t handle, cublasOperation_t transA, cublasOperation_t transB, const int m, const int n, const int k, const cuComplex alpha, const cuComplex x[], const cuComplex y[], const cuComplex beta, cuComplex c[]){ + int lda = transA == CUBLAS_OP_N ? m : k; + int ldb = transB == CUBLAS_OP_N ? k : n; + + cublasCgemm(handle, transA, transB, m, n, k, &alpha, x, lda, y, ldb, &beta, c, m); + } + + DLLEXPORT void z_matrix_multiply(const cublasHandle_t handle, cublasOperation_t transA, cublasOperation_t transB, const int m, const int n, const int k, const cuDoubleComplex alpha, const cuDoubleComplex x[], const cuDoubleComplex y[], const cuDoubleComplex beta, cuDoubleComplex c[]){ + int lda = transA == CUBLAS_OP_N ? m : k; + int ldb = transB == CUBLAS_OP_N ? k : n; + + cublasZgemm(handle, transA, transB, m, n, k, &alpha, x, lda, y, ldb, &beta, c, m); + } + +#if GCC +} +#endif diff --git a/src/NativeProviders/CUDA/lapack.cpp b/src/NativeProviders/CUDA/lapack.cpp index e69de29b..189a0b4c 100644 --- a/src/NativeProviders/CUDA/lapack.cpp +++ b/src/NativeProviders/CUDA/lapack.cpp @@ -0,0 +1,521 @@ +#include "lapack_common.h" +#include "wrapper_common.h" +#include "cublas.h" +#include "cusolverDn.h" +#include + +template +inline int lu_factor(int m, T a[], int ipiv[], + int(*getrf) (CBLAS_ORDER, const int, const int, K*, const int, int*)) +{ + int info = getrf(CblasColMajor, m, m, a, m, ipiv); + shift_ipiv_down(m, ipiv); + return info; +}; + +template +inline int lu_inverse(int n, T a[], + int(*getrf) (CBLAS_ORDER, const int, const int, K*, const int, int*), + int(*getri) (CBLAS_ORDER, const int, K*, const int, const int*)) +{ + int* ipiv = new int[n]; + int info = getrf(CblasColMajor, n, n, a, n, ipiv); + + if (info != 0){ + delete[] ipiv; + return info; + } + + info = getri(CblasColMajor, n, a, n, ipiv); + delete[] ipiv; + return info; +}; + +template +inline int lu_inverse_factored(int n, T a[], int ipiv[], + int(*getri) (CBLAS_ORDER, const int, K*, const int, const int*)) +{ + shift_ipiv_up(n, ipiv); + int info = getri(CblasColMajor, n, a, n, ipiv); + shift_ipiv_down(n, ipiv); + return info; +} + +template +inline int lu_solve_factored(int n, int nrhs, T a[], int ipiv[], T b[], + int(*getrs) (CBLAS_ORDER, CBLAS_TRANSPOSE, const int, const int, const K*, const int, const int*, K*, const int)) +{ + shift_ipiv_up(n, ipiv); + int info = getrs(CblasColMajor, CblasNoTrans, n, nrhs, a, n, ipiv, b, n); + shift_ipiv_down(n, ipiv); + return info; +} + +template +inline int lu_solve(int n, int nrhs, T a[], T b[], + int(*getrf) (CBLAS_ORDER, const int, const int, K*, const int, int*), + int(*getrs) (CBLAS_ORDER, CBLAS_TRANSPOSE, const int, const int, const K*, const int, const int*, K*, const int)) +{ + T* clone = Clone(n, n, a); + int* ipiv = new int[n]; + int info = getrf(CblasColMajor, n, n, clone, n, ipiv); + + if (info != 0){ + delete[] ipiv; + delete[] clone; + return info; + } + + info = getrs(CblasColMajor, CblasNoTrans, n, nrhs, clone, n, ipiv, b, n); + delete[] ipiv; + delete[] clone; + return info; +} + +template +inline int cholesky_factor(int n, T* a, int(*potrf) (CBLAS_ORDER, CBLAS_UPLO, const int, K*, const int)) +{ + int info = potrf(CblasColMajor, CblasLower, n, a, n); + T zero = T(); + for (int i = 0; i < n; ++i) + { + int index = i * n; + for (int j = 0; j < n && i > j; ++j) + { + a[index + j] = zero; + } + } + return info; +} + +template +inline int cholesky_solve(int n, int nrhs, T a[], T b[], + int(*potrf) (CBLAS_ORDER, CBLAS_UPLO, const int, K*, const int), + int(*potrs) (CBLAS_ORDER, CBLAS_UPLO, const int, const int, const K*, const int, K*, const int)) +{ + T* clone = Clone(n, n, a); + int info = potrf(CblasColMajor, CblasLower, n, clone, n); + + if (info != 0){ + delete[] clone; + return info; + } + + info = potrs(CblasColMajor, CblasLower, n, nrhs, clone, n, b, n); + delete[] clone; + return info; +} + +template +inline int cholesky_solve_factored(int n, int nrhs, T a[], T b[], + int(*potrs) (CBLAS_ORDER, CBLAS_UPLO, const int, const int, const K*, const int, K*, const int)) +{ + return potrs(CblasColMajor, CblasLower, n, nrhs, a, n, b, n); +} + +template +inline int qr_factor(int m, int n, T r[], T tau[], T q[], T work[], int len, + int(*geqrf) (const int, const int, K*, const int, T*), + int(*orgqr) (const int, const int, const int, K*, const int, const K*)) +{ + int info = geqrf(m, n, r, m, tau); + + for (int i = 0; i < m; ++i) + { + for (int j = 0; j < m && j < n; ++j) + { + if (i > j) + { + q[j * m + i] = r[j * m + i]; + } + } + } + + //compute the q elements explicitly + if (m <= n) + { + info = orgqr(m, m, m, q, m, tau); + } + else + { + info = orgqr(m, m, n, q, m, tau); + } + + return info; +} + +template +inline int qr_thin_factor(int m, int n, T q[], T tau[], T r[], T work[], int len, + void(*geqrf) (const int*, const int*, T*, const int*, T*, T*, const int*, int*), + void(*orgqr) (const int*, const int*, const int*, T*, const int*, const T*, T*, const int*, int*)) +{ + int info = 0; + geqrf(&m, &n, q, &m, tau, work, &len, &info); + + for (int i = 0; i < n; ++i) + { + for (int j = 0; j < n; ++j) + { + if (i <= j) { + r[j * n + i] = q[j * m + i]; + } + } + } + + orgqr(&m, &n, &n, q, &m, tau, work, &len, &info); + + return info; +} + +template +inline int qr_solve(int m, int n, int bn, T a[], T b[], T x[], T work[], int len, + void(*gels) (const char*, const int*, const int*, const int*, T*, + const int*, T* b, const int*, T*, const int*, int*)) +{ + T* clone_a = new T[m*n]; + std::memcpy(clone_a, a, m*n*sizeof(T)); + + T* clone_b = new T[m*bn]; + std::memcpy(clone_b, b, m*bn*sizeof(T)); + + char N = 'N'; + int info = 0; + gels(&N, &m, &n, &bn, clone_a, &m, clone_b, &m, work, &len, &info); + copyBtoX(n, n, bn, clone_b, x); + + delete[] clone_a; + delete[] clone_b; + return info; +} + +template +inline int qr_solve_factored(int m, int n, int bn, T r[], T b[], T tau[], T x[], T work[], int len, + void(*ormqr) (const char*, const char*, const int*, const int*, const int*, + const T*, const int*, const T*, T*, const int*, T*, const int*, int* info), + void(*trsm) (const CBLAS_ORDER, const CBLAS_SIDE, const CBLAS_UPLO, const CBLAS_TRANSPOSE, const CBLAS_DIAG, + const int, const int, const T, const T*, const int, T*, const int)) +{ + T* clone_b = new T[m*bn]; + std::memcpy(clone_b, b, m*bn*sizeof(T)); + + char side = 'L'; + char tran = 'T'; + int info = 0; + ormqr(&side, &tran, &m, &bn, &n, r, &m, tau, clone_b, &m, work, &len, &info); + trsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, n, bn, 1.0, r, m, clone_b, m); + copyBtoX(n, n, bn, clone_b, x); + + delete[] clone_b; + return info; +} + +template +inline int complex_qr_solve_factored(int m, int n, int bn, T r[], T b[], T tau[], T x[], T work[], int len, + void(*unmqr) (const char*, const char*, const int*, const int*, const int*, + const T*, const int*, const T*, T*, const int*, T*, const int*, int* info), + void(*trsm) (const CBLAS_ORDER, const CBLAS_SIDE, const CBLAS_UPLO, const CBLAS_TRANSPOSE, const CBLAS_DIAG, + const int, const int, const void*, const void*, const int, void*, const int ldb)) +{ + T* clone_b = new T[m*bn]; + std::memcpy(clone_b, b, m*bn*sizeof(T)); + + char side = 'L'; + char tran = 'C'; + int info = 0; + unmqr(&side, &tran, &m, &bn, &n, r, &m, tau, clone_b, &m, work, &len, &info); + + T one = { 1.0f, 0.0f }; + trsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, n, bn, &one, r, m, clone_b, m); + copyBtoX(n, n, bn, clone_b, x); + + delete[] clone_b; + return info; +} + +template +inline int svd_factor(bool compute_vectors, int m, int n, T a[], T s[], T u[], T v[], T work[], int len, + void(*gesvd) (const char*, const char*, const int*, const int*, T*, const int*, + T*, T*, const int*, T*, const int*, T*, const int*, int*)) +{ + int info = 0; + char job = compute_vectors ? 'A' : 'N'; + gesvd(&job, &job, &m, &n, a, &m, s, u, &m, v, &n, work, &len, &info); + return info; +} + + +template +inline int complex_svd_factor(bool compute_vectors, int m, int n, T a[], T s[], T u[], T v[], T work[], int len, + void(*gesvd) (const char*, const char*, const int*, const int*, T*, const int*, + R*, T*, const int*, T*, const int*, T*, const int*, R*, int*)) +{ + int info = 0; + int dim_s = std::min(m, n); + R* rwork = new R[5 * dim_s]; + R* s_local = new R[dim_s]; + char job = compute_vectors ? 'A' : 'N'; + gesvd(&job, &job, &m, &n, a, &m, s_local, u, &m, v, &n, work, &len, rwork, &info); + + for (int index = 0; index < dim_s; ++index){ + T value = { s_local[index], 0.0f }; + s[index] = value; + } + + delete[] rwork; + delete[] s_local; + return info; +} + +extern "C" { + DLLEXPORT int s_lu_factor(int m, float a[], int ipiv[]) { + return lu_factor(m, a, ipiv, cusolverDnSgetrf); + } + + DLLEXPORT int d_lu_factor(int m, double a[], int ipiv[]) { + return lu_factor(m, a, ipiv, cusolverDnDgetrf); + } + + DLLEXPORT int c_lu_factor(int m, cuComplex a[], int ipiv[]) { + return lu_factor(m, a, ipiv, cusolverDnCgetrf); + } + + DLLEXPORT int z_lu_factor(int m, cuDoubleComplex a[], int ipiv[]) { + return lu_factor(m, a, ipiv, cusolverDnZgetrf); + } + + DLLEXPORT int s_lu_inverse(int n, float a[]) + { + return lu_inverse(n, a, cusolverDnSgetrf, cusolverDnSgetri); + } + + DLLEXPORT int d_lu_inverse(int n, double a[]) + { + return lu_inverse(n, a, cusolverDnDgetrf, cusolverDnDgetri); + } + + DLLEXPORT int c_lu_inverse(int n, cuComplex a[]) + { + return lu_inverse(n, a, cusolverDnCgetrf, cusolverDnCgetri); + } + + DLLEXPORT int z_lu_inverse(int n, cuDoubleComplex a[]) + { + return lu_inverse(n, a, cusolverDnZgetrf, cusolverDnZgetri); + } + + DLLEXPORT int s_lu_inverse_factored(int n, float a[], int ipiv[], float work[], int lwork) + { + return lu_inverse_factored(n, a, ipiv, cusolverDnSgetri); + } + + DLLEXPORT int d_lu_inverse_factored(int n, double a[], int ipiv[], double work[], int lwork) + { + return lu_inverse_factored(n, a, ipiv, cusolverDnDgetri); + } + + DLLEXPORT int c_lu_inverse_factored(int n, cuComplex a[], int ipiv[], cuComplex work[], int lwork) + { + return lu_inverse_factored(n, a, ipiv, cusolverDnCgetri); + } + + DLLEXPORT int z_lu_inverse_factored(int n, cuDoubleComplex a[], int ipiv[], cuDoubleComplex work[], int lwork) + { + return lu_inverse_factored(n, a, ipiv, cusolverDnZgetri); + } + + DLLEXPORT int s_lu_solve_factored(int n, int nrhs, float a[], int ipiv[], float b[]) + { + return lu_solve_factored(n, nrhs, a, ipiv, b, cusolverDnSgetrs); + } + + DLLEXPORT int d_lu_solve_factored(int n, int nrhs, double a[], int ipiv[], double b[]) + { + return lu_solve_factored(n, nrhs, a, ipiv, b, cusolverDnDgetrs); + } + + DLLEXPORT int c_lu_solve_factored(int n, int nrhs, cuComplex a[], int ipiv[], cuComplex b[]) + { + return lu_solve_factored(n, nrhs, a, ipiv, b, cusolverDnCgetrs); + } + + DLLEXPORT int z_lu_solve_factored(int n, int nrhs, cuDoubleComplex a[], int ipiv[], cuDoubleComplex b[]) + { + return lu_solve_factored(n, nrhs, a, ipiv, b, cusolverDnZgetrs); + } + + DLLEXPORT int s_lu_solve(int n, int nrhs, float a[], float b[]) + { + return lu_solve(n, nrhs, a, b, cusolverDnSgetrf, cusolverDnSgetrs); + } + + DLLEXPORT int d_lu_solve(int n, int nrhs, double a[], double b[]) + { + return lu_solve(n, nrhs, a, b, cusolverDnDgetrf, cusolverDnDgetrs); + } + + DLLEXPORT int c_lu_solve(int n, int nrhs, cuComplex a[], cuComplex b[]) + { + return lu_solve(n, nrhs, a, b, cusolverDnCgetrf, cusolverDnCgetrs); + } + + DLLEXPORT int z_lu_solve(int n, int nrhs, cuDoubleComplex a[], cuDoubleComplex b[]) + { + return lu_solve(n, nrhs, a, b, cusolverDnZgetrf, cusolverDnZgetrs); + } + + DLLEXPORT int s_cholesky_factor(int n, float a[]){ + return cholesky_factor(n, a, cusolverDnSpotrf); + } + + DLLEXPORT int d_cholesky_factor(int n, double* a){ + return cholesky_factor(n, a, cusolverDnDpotrf); + } + + DLLEXPORT int c_cholesky_factor(int n, cuComplex a[]){ + return cholesky_factor(n, a, cusolverDnCpotrf); + } + + DLLEXPORT int z_cholesky_factor(int n, cuDoubleComplex a[]){ + return cholesky_factor(n, a, cusolverDnZpotrf); + } + + DLLEXPORT int s_cholesky_solve(int n, int nrhs, float a[], float b[]) + { + return cholesky_solve(n, nrhs, a, b, cusolverDnSpotrf, cusolverDnSpotrs); + } + + DLLEXPORT int d_cholesky_solve(int n, int nrhs, double a[], double b[]) + { + return cholesky_solve(n, nrhs, a, b, cusolverDnDpotrf, cusolverDnDpotrs); + } + + DLLEXPORT int c_cholesky_solve(int n, int nrhs, cuComplex a[], cuComplex b[]) + { + return cholesky_solve(n, nrhs, a, b, cusolverDnCpotrf, cusolverDnCpotrs); + } + + DLLEXPORT int z_cholesky_solve(int n, int nrhs, cuDoubleComplex a[], cuDoubleComplex b[]) + { + return cholesky_solve(n, nrhs, a, b, cusolverDnZpotrf, cusolverDnZpotrs); + } + + DLLEXPORT int s_cholesky_solve_factored(int n, int nrhs, float a[], float b[]) + { + return cholesky_solve_factored(n, nrhs, a, b, cusolverDnSpotrs); + } + + DLLEXPORT int d_cholesky_solve_factored(int n, int nrhs, double a[], double b[]) + { + return cholesky_solve_factored(n, nrhs, a, b, cusolverDnDpotrs); + } + + DLLEXPORT int c_cholesky_solve_factored(int n, int nrhs, cuComplex a[], cuComplex b[]) + { + return cholesky_solve_factored(n, nrhs, a, b, cusolverDnCpotrs); + } + + DLLEXPORT int z_cholesky_solve_factored(int n, int nrhs, cuDoubleComplex a[], cuDoubleComplex b[]) + { + return cholesky_solve_factored(n, nrhs, a, b, cusolverDnZpotrs); + } + + /*DLLEXPORT int s_qr_factor(int m, int n, float r[], float tau[], float q[], float work[], int len) + { + return qr_factor(m, n, r, tau, q, work, len, cusolverDnSgeqrf, cusolverDnSorgqr); + } + + DLLEXPORT int s_qr_thin_factor(int m, int n, float q[], float tau[], float r[], float work[], int len) + { + return qr_thin_factor(m, n, q, tau, r, work, len, cusolverDnSgeqrf, cusolverDnSorgqr); + } + + DLLEXPORT int d_qr_factor(int m, int n, double r[], double tau[], double q[], double work[], int len) + { + return qr_factor(m, n, r, tau, q, work, len, cusolverDnDgeqrf, cusolverDnDorgqr); + } + + DLLEXPORT int d_qr_thin_factor(int m, int n, double q[], double tau[], double r[], double work[], int len) + { + return qr_thin_factor(m, n, q, tau, r, work, len, cusolverDnDgeqrf, cusolverDnDorgqr); + } + + DLLEXPORT int c_qr_factor(int m, int n, cuComplex r[], cuComplex tau[], cuComplex q[], cuComplex work[], int len) + { + return qr_factor(m, n, r, tau, q, work, len, cusolverDnCgeqrf, cusolverDnCungqr); + } + + DLLEXPORT int c_qr_thin_factor(int m, int n, cuComplex q[], cuComplex tau[], cuComplex r[], cuComplex work[], int len) + { + return qr_thin_factor(m, n, q, tau, r, work, len, cusolverDnCgeqrf, cusolverDnCungqr); + } + + DLLEXPORT int z_qr_factor(int m, int n, cuDoubleComplex r[], cuDoubleComplex tau[], cuDoubleComplex q[]) + { + return qr_factor(m, n, r, tau, q, work, len, cusolverDnZgeqrf, cusolverDnZungqr); + } + + DLLEXPORT int z_qr_thin_factor(int m, int n, cuDoubleComplex q[], cuDoubleComplex tau[], cuDoubleComplex r[]) + { + return qr_thin_factor(m, n, q, tau, r, work, len, cusolverDnZgeqrf, cusolverDnZungqr); + } + + DLLEXPORT int s_qr_solve(int m, int n, int bn, float a[], float b[], float x[], float work[], int len) + { + return qr_solve(m, n, bn, a, b, x, work, len, sgels); + } + + DLLEXPORT int d_qr_solve(int m, int n, int bn, double a[], double b[], double x[], double work[], int len) + { + return qr_solve(m, n, bn, a, b, x, work, len, dgels); + } + + DLLEXPORT int c_qr_solve(int m, int n, int bn, cuComplex a[], cuComplex b[], cuComplex x[], cuComplex work[], int len) + { + return qr_solve(m, n, bn, a, b, x, work, len, cgels); + } + + DLLEXPORT int z_qr_solve(int m, int n, int bn, cuDoubleComplex a[], cuDoubleComplex b[], cuDoubleComplex x[], cuDoubleComplex work[], int len) + { + return qr_solve(m, n, bn, a, b, x, work, len, zgels); + } + + DLLEXPORT int s_qr_solve_factored(int m, int n, int bn, float r[], float b[], float tau[], float x[], float work[], int len) + { + return qr_solve_factored(m, n, bn, r, b, tau, x, work, len, sormqr, cblas_strsm); + } + + DLLEXPORT int d_qr_solve_factored(int m, int n, int bn, double r[], double b[], double tau[], double x[], double work[], int len) + { + return qr_solve_factored(m, n, bn, r, b, tau, x, work, len, dormqr, cblas_dtrsm); + } + + DLLEXPORT int c_qr_solve_factored(int m, int n, int bn, cuComplex r[], cuComplex b[], cuComplex tau[], cuComplex x[], cuComplex work[], int len) + { + return complex_qr_solve_factored(m, n, bn, r, b, tau, x, work, len, cunmqr, cblas_ctrsm); + } + + DLLEXPORT int z_qr_solve_factored(int m, int n, int bn, cuDoubleComplex r[], cuDoubleComplex b[], cuDoubleComplex tau[], cuDoubleComplex x[], cuDoubleComplex work[], int len) + { + return complex_qr_solve_factored(m, n, bn, r, b, tau, x, work, len, zunmqr, cblas_ztrsm); + } + + DLLEXPORT int s_svd_factor(bool compute_vectors, int m, int n, float a[], float s[], float u[], float v[], float work[], int len) + { + return svd_factor(compute_vectors, m, n, a, s, u, v, work, len, sgesvd); + } + + DLLEXPORT int d_svd_factor(bool compute_vectors, int m, int n, double a[], double s[], double u[], double v[], double work[], int len) + { + return svd_factor(compute_vectors, m, n, a, s, u, v, work, len, dgesvd); + } + + DLLEXPORT int c_svd_factor(bool compute_vectors, int m, int n, cuComplex a[], cuComplex s[], cuComplex u[], cuComplex v[], cuComplex work[], int len) + { + return complex_svd_factor(compute_vectors, m, n, a, s, u, v, work, len, cgesvd); + } + + DLLEXPORT int z_svd_factor(bool compute_vectors, int m, int n, cuDoubleComplex a[], cuDoubleComplex s[], cuDoubleComplex u[], cuDoubleComplex v[], cuDoubleComplex work[], int len) + { + return complex_svd_factor(compute_vectors, m, n, a, s, u, v, work, len, zgesvd); + }*/ +} \ No newline at end of file diff --git a/src/NativeProviders/CUDA/vector_functions.c b/src/NativeProviders/CUDA/vector_functions.c deleted file mode 100644 index e69de29b..00000000 diff --git a/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj b/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj index 22dc1a85..ec8944fd 100644 --- a/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj +++ b/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + @@ -19,7 +27,6 @@ - {5A52B796-7F41-4C90-8DE2-F3F391C4482C} @@ -33,6 +40,12 @@ v120 MultiByte + + DynamicLibrary + true + v120 + MultiByte + DynamicLibrary false @@ -40,26 +53,49 @@ true MultiByte + + DynamicLibrary + false + v120 + true + MultiByte + + + + + + + $(ProjectDir)..\..\..\..\out\CUDA\Windows\x86\ $(Platform)\$(Configuration)\ MathNet.Numerics.CUDA + + $(Platform)\$(Configuration)\ + MathNet.Numerics.CUDA + $(ProjectDir)..\..\..\..\out\CUDA\Windows\x64\ + $(ProjectDir)..\..\..\..\out\CUDA\Windows\x86\ $(Platform)\$(Configuration)\ MathNet.Numerics.CUDA + + $(Platform)\$(Configuration)\ + MathNet.Numerics.CUDA + $(ProjectDir)..\..\..\..\out\CUDA\Windows\x64\ + Level3 @@ -69,7 +105,20 @@ true - cublas.lib;%(AdditionalDependencies) + cublas.lib;cublas_device.lib;%(AdditionalDependencies) + $(CUDA_PATH)\lib\x64;%(AdditionalLibraryDirectories) + + + + + Level3 + Disabled + true + $(CUDA_PATH)\include;$(ProjectDir)..\..\Common;$(ProjectDir)..\..\CUDA;%(AdditionalIncludeDirectories) + + + true + cusolver.lib;cublas.lib;cublas_device.lib;%(AdditionalDependencies) $(CUDA_PATH)\lib\x64;%(AdditionalLibraryDirectories) @@ -90,6 +139,23 @@ $(CUDA_PATH)\lib\x64;%(AdditionalLibraryDirectories) + + + Level3 + MaxSpeed + true + true + true + $(CUDA_PATH)\include;$(ProjectDir)..\..\Common;$(ProjectDir)..\..\CUDA;%(AdditionalIncludeDirectories) + + + true + true + true + cusolver.lib;cublas.lib;%(AdditionalDependencies) + $(CUDA_PATH)\lib\x64;%(AdditionalLibraryDirectories) + + diff --git a/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj.filters b/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj.filters index f834db07..0e998fbe 100644 --- a/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj.filters +++ b/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj.filters @@ -35,8 +35,5 @@ Source Files - - Source Files - \ No newline at end of file