From 3f11f410340a5e56050bf381de687811a2c9a03b Mon Sep 17 00:00:00 2001 From: Matthew Johnson Date: Sat, 16 May 2015 12:13:23 +0100 Subject: [PATCH] Adding blas exception handling to the library. --- src/NativeProviders/CUDA/blas.cpp | 141 ++++++++++-------- src/NativeProviders/CUDA/memory.c | 0 src/NativeProviders/CUDA/wrapper_cuda.h | 8 + .../Windows/CUDA/CUDAWrapper.vcxproj | 1 + .../Windows/CUDA/CUDAWrapper.vcxproj.filters | 3 + 5 files changed, 89 insertions(+), 64 deletions(-) delete mode 100644 src/NativeProviders/CUDA/memory.c create mode 100644 src/NativeProviders/CUDA/wrapper_cuda.h diff --git a/src/NativeProviders/CUDA/blas.cpp b/src/NativeProviders/CUDA/blas.cpp index b99559b6..76c67646 100644 --- a/src/NativeProviders/CUDA/blas.cpp +++ b/src/NativeProviders/CUDA/blas.cpp @@ -1,78 +1,91 @@ #include #include "cublas_v2.h" #include "cuda_runtime.h" -#include "wrapper_common.h" +#include "wrapper_cuda.h" template -void cuda_axpy(const cublasHandle_t blasHandle, const int n, const T alpha, const T x[], int incX, T y[], int incY, AXPY axpy) +void cuda_axpy(const cublasHandle_t blasHandle, const int n, const T alpha, const T x[], int incX, T y[], int incY, AXPY axpy, cudaError_t *error, cublasStatus_t *blasStatus) { T *d_X = NULL; T *d_Y = NULL; - cudaMalloc((void**)&d_X, n*sizeof(T)); - cudaMalloc((void**)&d_Y, n*sizeof(T)); + *error = cudaError_t::cudaSuccess; + *blasStatus = cublasStatus_t::CUBLAS_STATUS_SUCCESS; - cublasSetVector(n, sizeof(T), x, incX, d_X, incX); - cublasSetVector(n, sizeof(T), y, incY, d_Y, incY); + SAFECUDACALL(error, cudaMalloc((void**)&d_X, n*sizeof(T))) + SAFECUDACALL(error, cudaMalloc((void**)&d_Y, n*sizeof(T))) - axpy(blasHandle, n, &alpha, d_X, incX, d_Y, incX); + SAFECUDACALL(blasStatus, cublasSetVector(n, sizeof(T), x, incX, d_X, incX)) + SAFECUDACALL(blasStatus, cublasSetVector(n, sizeof(T), y, incY, d_Y, incY)) - cublasGetVector(n, sizeof(T), d_Y, incY, y, incY); + SAFECUDACALL(blasStatus, axpy(blasHandle, n, &alpha, d_X, incX, d_Y, incX)) + SAFECUDACALL(blasStatus, cublasGetVector(n, sizeof(T), d_Y, incY, y, incY)) + +exit: cudaFree(d_X); cudaFree(d_Y); } template -void cuda_scal(const cublasHandle_t blasHandle, const int n, const T alpha, T x[], int incX, SCAL scal) +void cuda_scal(const cublasHandle_t blasHandle, const int n, const T alpha, T x[], int incX, SCAL scal, cudaError_t *error, cublasStatus_t *blasStatus) { T *d_X = NULL; - cudaMalloc((void**)&d_X, n*sizeof(T)); - - cublasSetVector(n, sizeof(T), x, incX, d_X, incX); - - scal(blasHandle, n, &alpha, d_X, incX); + *error = cudaError_t::cudaSuccess; + *blasStatus = cublasStatus_t::CUBLAS_STATUS_SUCCESS; - cublasGetVector(n, sizeof(T), d_X, incX, x, incX); + SAFECUDACALL(error, cudaMalloc((void**)&d_X, n*sizeof(T))) + SAFECUDACALL(blasStatus, cublasSetVector(n, sizeof(T), x, incX, d_X, incX)) + SAFECUDACALL(blasStatus, scal(blasHandle, n, &alpha, d_X, incX)) + SAFECUDACALL(blasStatus, cublasGetVector(n, sizeof(T), d_X, incX, x, incX)) +exit: cudaFree(d_X); } template -void cuda_dot(const cublasHandle_t blasHandle, const int n, const T x[], int incX, const T y[], int incY, T* result, DOT dot) +void cuda_dot(const cublasHandle_t blasHandle, const int n, const T x[], int incX, const T y[], int incY, T* result, DOT dot, cudaError_t *error, cublasStatus_t *blasStatus) { T *d_X = NULL; T *d_Y = NULL; - cudaMalloc((void**)&d_X, n*sizeof(T)); - cudaMalloc((void**)&d_Y, n*sizeof(T)); + *error = cudaError_t::cudaSuccess; + *blasStatus = cublasStatus_t::CUBLAS_STATUS_SUCCESS; - cublasSetVector(n, sizeof(T), x, incX, d_X, incX); - cublasSetVector(n, sizeof(T), y, incY, d_Y, incY); + SAFECUDACALL(error, cudaMalloc((void**)&d_X, n*sizeof(T))) + SAFECUDACALL(error, cudaMalloc((void**)&d_Y, n*sizeof(T))) - dot(blasHandle, n, d_X, incX, d_Y, incY, result); + SAFECUDACALL(blasStatus, cublasSetVector(n, sizeof(T), x, incX, d_X, incX)) + SAFECUDACALL(blasStatus, cublasSetVector(n, sizeof(T), y, incY, d_Y, incY)) + SAFECUDACALL(blasStatus, dot(blasHandle, n, d_X, incX, d_Y, incY, result)) + +exit: cudaFree(d_X); cudaFree(d_Y); } template -void cuda_gemm(const cublasHandle_t handle, const cublasOperation_t transa, const cublasOperation_t transb, int m, int n, int k, const T alpha, const T A[], int lda, const T B[], int ldb, const T beta, T C[], int ldc, GEMM gemm) +void cuda_gemm(const cublasHandle_t handle, const cublasOperation_t transa, const cublasOperation_t transb, int m, int n, int k, const T alpha, const T A[], int lda, const T B[], int ldb, const T beta, T C[], int ldc, GEMM gemm, cudaError_t *error, cublasStatus_t *blasStatus) { T *d_A = NULL; - cudaMalloc((void**)&d_A, m*k*sizeof(T)); - cublasSetMatrix(m, k, sizeof(T), A, m, d_A, m); - T *d_B = NULL; - cudaMalloc((void**)&d_B, k*n*sizeof(T)); - cublasSetMatrix(k, n, sizeof(T), B, k, d_B, k); - T *d_C = NULL; - cudaMalloc((void**)&d_C, m*n*sizeof(T)); - cublasSetMatrix(m, n, sizeof(T), C, m, d_C, m); + *error = cudaError_t::cudaSuccess; + *blasStatus = cublasStatus_t::CUBLAS_STATUS_SUCCESS; + + SAFECUDACALL(error, cudaMalloc((void**)&d_A, m*k*sizeof(T))) + SAFECUDACALL(blasStatus, cublasSetMatrix(m, k, sizeof(T), A, m, d_A, m)) + + SAFECUDACALL(error, cudaMalloc((void**)&d_B, k*n*sizeof(T))) + SAFECUDACALL(blasStatus, cublasSetMatrix(k, n, sizeof(T), B, k, d_B, k)) + + SAFECUDACALL(error, cudaMalloc((void**)&d_C, m*n*sizeof(T))) + SAFECUDACALL(blasStatus, cublasSetMatrix(m, n, sizeof(T), C, m, d_C, m)) - gemm(handle, transa, transb, m, n, k, &alpha, d_A, lda, d_B, ldb, &beta, d_C, ldc); + SAFECUDACALL(blasStatus, gemm(handle, transa, transb, m, n, k, &alpha, d_A, lda, d_B, ldb, &beta, d_C, ldc)) - cublasGetMatrix(m, n, sizeof(T), d_C, m, C, m); + SAFECUDACALL(blasStatus, cublasGetMatrix(m, n, sizeof(T), d_C, m, C, m)) +exit: cudaFree(d_A); cudaFree(d_B); cudaFree(d_C); @@ -80,88 +93,88 @@ void cuda_gemm(const cublasHandle_t handle, const cublasOperation_t transa, cons extern "C" { - DLLEXPORT void s_axpy(const cublasHandle_t blasHandle, const int n, const float alpha, const float x[], float y[]){ - cuda_axpy(blasHandle, n, alpha, x, 1, y, 1, cublasSaxpy); + DLLEXPORT void s_axpy(const cublasHandle_t blasHandle, const int n, const float alpha, const float x[], float y[], cudaError_t *error, cublasStatus_t *blasStatus){ + cuda_axpy(blasHandle, n, alpha, x, 1, y, 1, cublasSaxpy, error, blasStatus); } - DLLEXPORT void d_axpy(const cublasHandle_t blasHandle, const int n, const double alpha, const double x[], double y[]){ - cuda_axpy(blasHandle, n, alpha, x, 1, y, 1, cublasDaxpy); + DLLEXPORT void d_axpy(const cublasHandle_t blasHandle, const int n, const double alpha, const double x[], double y[], cudaError_t *error, cublasStatus_t *blasStatus){ + cuda_axpy(blasHandle, n, alpha, x, 1, y, 1, cublasDaxpy, error, blasStatus); } - DLLEXPORT void c_axpy(const cublasHandle_t blasHandle, const int n, const cuComplex alpha, const cuComplex x[], cuComplex y[]){ - cuda_axpy(blasHandle, n, alpha, x, 1, y, 1, cublasCaxpy); + DLLEXPORT void c_axpy(const cublasHandle_t blasHandle, const int n, const cuComplex alpha, const cuComplex x[], cuComplex y[], cudaError_t *error, cublasStatus_t *blasStatus){ + cuda_axpy(blasHandle, n, alpha, x, 1, y, 1, cublasCaxpy, error, blasStatus); } - DLLEXPORT void z_axpy(const cublasHandle_t blasHandle, const int n, const cuDoubleComplex alpha, const cuDoubleComplex x[], cuDoubleComplex y[]){ - cuda_axpy(blasHandle, n, alpha, x, 1, y, 1, cublasZaxpy); + DLLEXPORT void z_axpy(const cublasHandle_t blasHandle, const int n, const cuDoubleComplex alpha, const cuDoubleComplex x[], cuDoubleComplex y[], cudaError_t *error, cublasStatus_t *blasStatus){ + cuda_axpy(blasHandle, n, alpha, x, 1, y, 1, cublasZaxpy, error, blasStatus); } - DLLEXPORT void s_scale(const cublasHandle_t blasHandle, const int n, const float alpha, float x[]){ - cuda_scal(blasHandle, n, alpha, x, 1, cublasSscal); + DLLEXPORT void s_scale(const cublasHandle_t blasHandle, const int n, const float alpha, float x[], cudaError_t *error, cublasStatus_t *blasStatus){ + cuda_scal(blasHandle, n, alpha, x, 1, cublasSscal, error, blasStatus); } - DLLEXPORT void d_scale(const cublasHandle_t blasHandle, const int n, const double alpha, double x[]){ - cuda_scal(blasHandle, n, alpha, x, 1, cublasDscal); + DLLEXPORT void d_scale(const cublasHandle_t blasHandle, const int n, const double alpha, double x[], cudaError_t *error, cublasStatus_t *blasStatus){ + cuda_scal(blasHandle, n, alpha, x, 1, cublasDscal, error, blasStatus); } - DLLEXPORT void c_scale(const cublasHandle_t blasHandle, const int n, const cuComplex alpha, cuComplex x[]){ - cuda_scal(blasHandle, n, alpha, x, 1, cublasCscal); + DLLEXPORT void c_scale(const cublasHandle_t blasHandle, const int n, const cuComplex alpha, cuComplex x[], cudaError_t *error, cublasStatus_t *blasStatus){ + cuda_scal(blasHandle, n, alpha, x, 1, cublasCscal, error, blasStatus); } - DLLEXPORT void z_scale(const cublasHandle_t blasHandle, const int n, const cuDoubleComplex alpha, cuDoubleComplex x[]){ - cuda_scal(blasHandle, n, alpha, x, 1, cublasZscal); + DLLEXPORT void z_scale(const cublasHandle_t blasHandle, const int n, const cuDoubleComplex alpha, cuDoubleComplex x[], cudaError_t *error, cublasStatus_t *blasStatus){ + cuda_scal(blasHandle, n, alpha, x, 1, cublasZscal, error, blasStatus); } - DLLEXPORT float s_dot_product(const cublasHandle_t blasHandle, const int n, const float x[], const float y[]){ + DLLEXPORT float s_dot_product(const cublasHandle_t blasHandle, const int n, const float x[], const float y[], cudaError_t *error, cublasStatus_t *blasStatus){ float ret; - cuda_dot(blasHandle, n, x, 1, y, 1, &ret, cublasSdot); + cuda_dot(blasHandle, n, x, 1, y, 1, &ret, cublasSdot, error, blasStatus); return ret; } - DLLEXPORT double d_dot_product(const cublasHandle_t blasHandle, const int n, const double x[], const double y[]){ + DLLEXPORT double d_dot_product(const cublasHandle_t blasHandle, const int n, const double x[], const double y[], cudaError_t *error, cublasStatus_t *blasStatus){ double ret; - cuda_dot(blasHandle, n, x, 1, y, 1, &ret, cublasDdot); + cuda_dot(blasHandle, n, x, 1, y, 1, &ret, cublasDdot, error, blasStatus); return ret; } - DLLEXPORT cuComplex c_dot_product(const cublasHandle_t blasHandle, const int n, const cuComplex x[], const cuComplex y[]){ + DLLEXPORT cuComplex c_dot_product(const cublasHandle_t blasHandle, const int n, const cuComplex x[], const cuComplex y[], cudaError_t *error, cublasStatus_t *blasStatus){ cuComplex ret; - cuda_dot(blasHandle, n, x, 1, y, 1, &ret, cublasCdotu); + cuda_dot(blasHandle, n, x, 1, y, 1, &ret, cublasCdotu, error, blasStatus); return ret; } - DLLEXPORT cuDoubleComplex z_dot_product(const cublasHandle_t blasHandle, const int n, const cuDoubleComplex x[], const cuDoubleComplex y[]){ + DLLEXPORT cuDoubleComplex z_dot_product(const cublasHandle_t blasHandle, const int n, const cuDoubleComplex x[], const cuDoubleComplex y[], cudaError_t *error, cublasStatus_t *blasStatus){ cuDoubleComplex ret; - cuda_dot(blasHandle, n, x, 1, y, 1, &ret, cublasZdotu); + cuda_dot(blasHandle, n, x, 1, y, 1, &ret, cublasZdotu, error, blasStatus); return ret; } - DLLEXPORT void s_matrix_multiply(const cublasHandle_t blasHandle, 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[]){ + DLLEXPORT void s_matrix_multiply(const cublasHandle_t blasHandle, 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[], cudaError_t *error, cublasStatus_t *blasStatus){ int lda = transA == CUBLAS_OP_N ? m : k; int ldb = transB == CUBLAS_OP_N ? k : n; - cuda_gemm(blasHandle, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m, cublasSgemm); + cuda_gemm(blasHandle, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m, cublasSgemm, error, blasStatus); } - DLLEXPORT void d_matrix_multiply(const cublasHandle_t blasHandle, 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[]){ + DLLEXPORT void d_matrix_multiply(const cublasHandle_t blasHandle, 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[], cudaError_t *error, cublasStatus_t *blasStatus){ int lda = transA == CUBLAS_OP_N ? m : k; int ldb = transB == CUBLAS_OP_N ? k : n; - cuda_gemm(blasHandle, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m, cublasDgemm); + cuda_gemm(blasHandle, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m, cublasDgemm, error, blasStatus); } - DLLEXPORT void c_matrix_multiply(const cublasHandle_t blasHandle, 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[]){ + DLLEXPORT void c_matrix_multiply(const cublasHandle_t blasHandle, 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[], cudaError_t *error, cublasStatus_t *blasStatus){ int lda = transA == CUBLAS_OP_N ? m : k; int ldb = transB == CUBLAS_OP_N ? k : n; - cuda_gemm(blasHandle, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m, cublasCgemm); + cuda_gemm(blasHandle, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m, cublasCgemm, error, blasStatus); } - DLLEXPORT void z_matrix_multiply(const cublasHandle_t blasHandle, 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[]){ + DLLEXPORT void z_matrix_multiply(const cublasHandle_t blasHandle, 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[], cudaError_t *error, cublasStatus_t *blasStatus){ int lda = transA == CUBLAS_OP_N ? m : k; int ldb = transB == CUBLAS_OP_N ? k : n; - cuda_gemm(blasHandle, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m, cublasZgemm); + cuda_gemm(blasHandle, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m, cublasZgemm, error, blasStatus); } } diff --git a/src/NativeProviders/CUDA/memory.c b/src/NativeProviders/CUDA/memory.c deleted file mode 100644 index e69de29b..00000000 diff --git a/src/NativeProviders/CUDA/wrapper_cuda.h b/src/NativeProviders/CUDA/wrapper_cuda.h new file mode 100644 index 00000000..cd25b753 --- /dev/null +++ b/src/NativeProviders/CUDA/wrapper_cuda.h @@ -0,0 +1,8 @@ +#ifndef WRAPPER_CUDA_H +#define WRAPPER_CUDA_H + +#include "wrapper_common.h" + +#define SAFECUDACALL(error,call) {*error = call; if(*error){goto exit;}} + +#endif \ No newline at end of file diff --git a/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj b/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj index 2544d23c..eef4e6cd 100644 --- a/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj +++ b/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj @@ -29,6 +29,7 @@ + {5A52B796-7F41-4C90-8DE2-F3F391C4482C} diff --git a/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj.filters b/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj.filters index 1813cb6b..e655e396 100644 --- a/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj.filters +++ b/src/NativeProviders/Windows/CUDA/CUDAWrapper.vcxproj.filters @@ -37,5 +37,8 @@ Header Files + + Header Files + \ No newline at end of file