|
|
|
@ -1,78 +1,91 @@ |
|
|
|
#include <stdio.h> |
|
|
|
#include "cublas_v2.h" |
|
|
|
#include "cuda_runtime.h" |
|
|
|
#include "wrapper_common.h" |
|
|
|
#include "wrapper_cuda.h" |
|
|
|
|
|
|
|
template<typename T, typename 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) |
|
|
|
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<typename T, typename SCAL> |
|
|
|
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<typename T, typename 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) |
|
|
|
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<typename T, typename 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) |
|
|
|
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); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|