I have written a struct
and some functions that wrap the "CUBLAS matrix object"
struct
is:
#include <cuda.h>
#include <cuda_runtime.h>
#include <cublas_v2.h>
#define uint unsigned int
typedef struct {
uint rows;
uint cols;
float* devPtrvals;
} matrix;
The alloc function creates the matrix struct:
matrix* matrix_alloc(uint rows, uint cols)
{
cudaError_t cudaStat;
matrix* w = malloc(sizeof(matrix));
w->rows = rows;
w->cols = cols;
cudaStat = cudaMalloc((void**)&w->devPtrvals, sizeof(float) * rows * cols);
if(cudaStat != cudaSuccess) {
fprintf(stderr, "device memory allocation failed\n");
return NULL;
}
return w;
};
Free function:
uint matrix_free(matrix* w)
{
cudaFree(w->devPtrvals);
free(w);
return 1;
};
Function that sets the values of the matrix from a float array:
uint matrix_set_vals(matrix* w, float* vals)
{
cublasStatus_t stat;
stat = cublasSetMatrix(w->rows, w->cols, sizeof(float),
vals, w->rows, w->devPtrvals, w->rows);
if(stat != CUBLAS_STATUS_SUCCESS) {
fprintf(stderr, "data upload failed\n");
return 0;
}
return 1;
};
I have a problem to write an universal dot product function, that covers the transposing of the matrices. This is what I have written:
matrix* matrix_dot(cublasHandle_t handle, char transA, char transB,
float alpha, matrix* v, matrix* w, float beta)
{
matrix* x = matrix_alloc(transA == CUBLAS_OP_N ? v->rows : v->cols,
transB == CUBLAS_OP_N ? w->cols : w->rows);
//cublasStatus_t cublasSgemm(cublasHandle_t handle,
// cublasOperation_t transa, cublasOperation_t transb,
// int m, int n, int k,
// const float *alpha,
// const float *A, int lda,
// const float *B, int ldb,
// const float *beta,
// float *C, int ldc)
cublasSgemm(handle, transA, transB,
transA == CUBLAS_OP_N ? v->rows : v->cols,
transB == CUBLAS_OP_N ? w->cols : w->rows,
transA == CUBLAS_OP_N ? v->cols : v->rows,
&alpha, v->devPtrvals, v->rows, w->devPtrvals,
w->rows, &beta, x->devPtrvals, x->rows);
return x;
};
example:
I want a matrix A:
1 2 3
4 5 6
7 8 9
10 11 12
that means:
float* a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
matrix* A = matrix_alloc(4, 3);
matrix_set_vals(A, a);
and multiply it with transposed B:
1 2 3
4 5 6
also:
float* b = {1, 2, 3, 4, 5, 6};
matrix* B = matrix_alloc(2, 3);
matrix_set_vals(B, b);
the result of A*B^T=C:
14 32
32 77
50 122
68 167
I'm using the dot function:
matrix* C = matrix_dot(handle, CUBLAS_OP_N, CUBLAS_OP_T, 1.0, A, B, 0.0);
When using this function I get: ** On entry to SGEMM parameter number 10 had an illegal value
What am I doing wrong?