1
votes

I have 2 simple matrices A and B and I'm calculating their multiplication. The arrays looks like this (using numpy as as mockup)

A=np.array(([1,2,3],[4,5,6])).astype(np.float64)
B=np.array(([7,8],[9,10],[11,12])).astype(np.float64)

Here are the shapes of the Matrix

A: (2, 3)

B: (3, 2)

Now, I am trying to do this using cublasDgemmBatched to get the product.

I am confused on what my m,n,and k values should be when applying cublasDgemmBatched. Also, I'm not sure what my leading dimension (lda, ldb, ldc) of the array would be.

There is a nice 3d example here but I can't seem to get this function to work on 2d matrices.

Ideally, i would like to get the same results as np.dot.

2
It might be because the batched gemm is for an array of two dimensional matrices (or what you have called three dimensional matrices). If you really insist on using gemmbatched for a two dimensional array then for your example: m = 2, n = 2, k = 3, lda = 3, ldb = 2, ldc = 2. Although I cannot say with confidence whether or not this will work. Or, referencing the example you linked to, just set l=1. - inJeans
You might want to be a little more explicit about what you mean by the dot product of 2 matrices. matlab's definition indicates a set of dot products of the matrix columns. The implication is the matrices would have the same shape. If you indeed want a set of individual dot products of matrix columns, using batched gemm is probably not the way to go, since it is fairly compilicated to set up and using a matrix product for a vector dot-product is overkill I think - Robert Crovella
I would like to get the same results as np.dot() - NinjaGaiden
Then you probably want to use cublasDgemm. Adjusting the 3D example to fit your 2D one might look like this cublasDgemm(self.cublas_handle, 'n','n', 2, 2, 3, alpha, b_arr.gpudata, 2, a_arr.gpudata, 3, beta, c_arr.gpudata, 2) - inJeans
Thankyou. I would like to mark your response as an answer but I am not sure how. - NinjaGaiden

2 Answers

1
votes

I don't have skcuda.blas to confirm this. But a more complete example might look like

A = np.array(([1, 2, 3], [4, 5, 6])).astype(np.float64)
B = np.array(([7, 8], [9, 10], [11, 12])).astype(np.float64)

m, k = A.shape
k, n = B.shape

a_gpu = gpuarray.to_gpu(A)
b_gpu = gpuarray.to_gpu(B)
c_gpu = gpuarray.empty((m, n), np.float64)

alpha = np.float64(1.0)
beta = np.float64(0.0)

a_arr = bptrs(a_gpu)
b_arr = bptrs(b_gpu)
c_arr = bptrs(c_gpu)

cublas_handle = cublas.cublasCreate()

cublas.cublasDgemm(cublas_handle, 'n','n',
                   n, m, k, alpha,
                   b_arr.gpudata, m,
                   a_arr.gpudata, k,
                   beta, c_arr.gpudata, m)
0
votes

A very simple way to imitate np.dot() is using culinalg.dot() which uses cuBLAS behind, see skcuda.linalg.dot. Below, a simple example:

import pycuda.autoinit
import pycuda.gpuarray as gpuarray
import pycuda.driver as drv
import numpy as np

import skcuda.linalg as culinalg
import skcuda.misc as cumisc
culinalg.init()

A = np.array(([1, 2, 3], [4, 5, 6])).astype(np.float64)
B = np.array(([7, 8, 1, 5], [9, 10, 0, 9], [11, 12, 5, 5])).astype(np.float64)

A_gpu = gpuarray.to_gpu(A)
B_gpu = gpuarray.to_gpu(B)

C_gpu = culinalg.dot(A_gpu, B_gpu)

print(np.dot(A, B))
print(C_gpu)