From ac8088e2b20450d44bc74962244c6f5daf83712e Mon Sep 17 00:00:00 2001 From: syurkevi Date: Wed, 21 Feb 2018 18:34:31 -0500 Subject: [PATCH 1/2] fixes batch matmul for opencl::cpu backend --- src/backend/opencl/cpu/cpu_blas.cpp | 77 +++++++++++++++++++---------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/src/backend/opencl/cpu/cpu_blas.cpp b/src/backend/opencl/cpu/cpu_blas.cpp index 9511523c1b..1d22f47124 100644 --- a/src/backend/opencl/cpu/cpu_blas.cpp +++ b/src/backend/opencl/cpu/cpu_blas.cpp @@ -158,40 +158,65 @@ Array matmul(const Array &lhs, const Array &rhs, int M = lDims[aRowDim]; int N = rDims[bColDim]; int K = lDims[aColDim]; + dim_t d2 = std::max(lDims[2], rDims[2]); + dim_t d3 = std::max(lDims[3], rDims[3]); + dim4 oDims = af::dim4(M, N, d2, d3); //FIXME: Leaks on errors. - Array out = createValueArray(af::dim4(M, N, 1, 1), scalar(0)); + Array out = createValueArray(oDims, scalar(0)); auto alpha = getScale(); auto beta = getScale(); dim4 lStrides = lhs.strides(); dim4 rStrides = rhs.strides(); - using BT = typename blas_base::type; + dim4 oStrides = out.strides(); - // get host pointers from mapped memory - auto lPtr = lhs.getMappedPtr(); - auto rPtr = rhs.getMappedPtr(); - auto oPtr = out.getMappedPtr(); - - if(rDims[bColDim] == 1) { - N = lDims[aColDim]; - gemv_func()( - CblasColMajor, lOpts, - lDims[0], lDims[1], - alpha, - (BT*)lPtr.get(), lStrides[1], - (BT*)rPtr.get(), rStrides[0], - beta, - (BT*)oPtr.get(), 1); - } else { - gemm_func()( - CblasColMajor, lOpts, rOpts, - M, N, K, - alpha, - (BT*)lPtr.get(), lStrides[1], - (BT*)rPtr.get(), rStrides[1], - beta, - (BT*)oPtr.get(), out.dims()[0]); + using BT = typename blas_base::type; + using CBT = const typename blas_base::type; + + int batchSize = oDims[2] * oDims[3]; + + bool is_l_d2_batched = (oDims[2] == lDims[2]); + bool is_l_d3_batched = (oDims[3] == lDims[3]); + bool is_r_d2_batched = (oDims[2] == rDims[2]); + bool is_r_d3_batched = (oDims[3] == rDims[3]); + + for(int n = 0; n < batchSize; ++n) { + int w = n / rDims[2]; + int z = n - w * rDims[2]; + + int loff = z * (is_l_d2_batched * lStrides[2]) + w * (is_l_d3_batched * lStrides[3]); + int roff = z * (is_r_d2_batched * rStrides[2]) + w * (is_r_d3_batched * rStrides[3]); + + // get host pointers from mapped memory + auto lPtr = lhs.getMappedPtr(); + auto rPtr = rhs.getMappedPtr(); + auto oPtr = out.getMappedPtr(); + + CBT *lptr = (CBT*)(lPtr.get() + loff); + CBT *rptr = (CBT*)(rPtr.get() + roff); + BT *optr = (BT*)(oPtr.get() + z * oStrides[2] + w * oStrides[3]); + + if(rDims[bColDim] == 1) { + N = lDims[aColDim]; + gemv_func()( + CblasColMajor, lOpts, + lDims[0], lDims[1], + alpha, + lptr, lStrides[1], + rptr, rStrides[0], + beta, + optr, 1); + } else { + gemm_func()( + CblasColMajor, lOpts, rOpts, + M, N, K, + alpha, + lptr, lStrides[1], + rptr, rStrides[1], + beta, + optr, out.dims()[0]); + } } return out; From 2c73c66ed546f6415493f26c8ca601b4b5d49283 Mon Sep 17 00:00:00 2001 From: syurkevi Date: Thu, 22 Feb 2018 12:18:48 -0500 Subject: [PATCH 2/2] fixes issue 1882 for opencl::cpu backend --- src/backend/opencl/cpu/cpu_blas.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/opencl/cpu/cpu_blas.cpp b/src/backend/opencl/cpu/cpu_blas.cpp index 1d22f47124..38679cc8c4 100644 --- a/src/backend/opencl/cpu/cpu_blas.cpp +++ b/src/backend/opencl/cpu/cpu_blas.cpp @@ -198,13 +198,14 @@ Array matmul(const Array &lhs, const Array &rhs, BT *optr = (BT*)(oPtr.get() + z * oStrides[2] + w * oStrides[3]); if(rDims[bColDim] == 1) { + dim_t incr = (rOpts == CblasNoTrans) ? rStrides[0] : rStrides[1]; N = lDims[aColDim]; gemv_func()( CblasColMajor, lOpts, lDims[0], lDims[1], alpha, lptr, lStrides[1], - rptr, rStrides[0], + rptr, incr, beta, optr, 1); } else {