MCPcopy Create free account
hub / github.com/arrayfire/arrayfire / gemm

Function gemm

src/backend/opencl/cpu/cpu_blas.cpp:174–235  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

172
173template<typename T>
174void gemm(Array<T> &out, af_mat_prop optLhs, af_mat_prop optRhs, const T *alpha,
175 const Array<T> &lhs, const Array<T> &rhs, const T *beta) {
176 using BT = typename blas_base<T>::type;
177 using CBT = const typename blas_base<T>::type;
178
179 const CBLAS_TRANSPOSE lOpts = toCblasTranspose(optLhs);
180 const CBLAS_TRANSPOSE rOpts = toCblasTranspose(optRhs);
181
182 const int aRowDim = (lOpts == CblasNoTrans) ? 0 : 1;
183 const int aColDim = (lOpts == CblasNoTrans) ? 1 : 0;
184 const int bColDim = (rOpts == CblasNoTrans) ? 1 : 0;
185
186 const dim4 &lDims = lhs.dims();
187 const dim4 &rDims = rhs.dims();
188 const int M = lDims[aRowDim];
189 const int N = rDims[bColDim];
190 const int K = lDims[aColDim];
191 const dim4 &oDims = out.dims();
192
193 dim4 lStrides = lhs.strides();
194 dim4 rStrides = rhs.strides();
195 dim4 oStrides = out.strides();
196
197 int batchSize = oDims[2] * oDims[3];
198
199 bool is_l_d2_batched = (oDims[2] == lDims[2]);
200 bool is_l_d3_batched = (oDims[3] == lDims[3]);
201 bool is_r_d2_batched = (oDims[2] == rDims[2]);
202 bool is_r_d3_batched = (oDims[3] == rDims[3]);
203
204 // get host pointers from mapped memory
205 mapped_ptr<T> lPtr = lhs.getMappedPtr(CL_MAP_READ);
206 mapped_ptr<T> rPtr = rhs.getMappedPtr(CL_MAP_READ);
207 mapped_ptr<T> oPtr = out.getMappedPtr(CL_MAP_READ | CL_MAP_WRITE);
208
209 for (int n = 0; n < batchSize; ++n) {
210 int w = n / oDims[2];
211 int z = n - w * oDims[2];
212
213 int loff = z * (is_l_d2_batched * lStrides[2]) +
214 w * (is_l_d3_batched * lStrides[3]);
215 int roff = z * (is_r_d2_batched * rStrides[2]) +
216 w * (is_r_d3_batched * rStrides[3]);
217
218 CBT *lptr = reinterpret_cast<CBT *>(lPtr.get() + loff);
219 CBT *rptr = reinterpret_cast<CBT *>(rPtr.get() + roff);
220 BT *optr = reinterpret_cast<BT *>(oPtr.get() + z * oStrides[2] +
221 w * oStrides[3]);
222
223 if (rDims[bColDim] == 1) {
224 dim_t incr = (rOpts == CblasNoTrans) ? rStrides[0] : rStrides[1];
225 gemv_func<T>()(CblasColMajor, lOpts, lDims[0], lDims[1],
226 getOneScalar<T>(alpha), lptr, lStrides[1], rptr,
227 incr, getOneScalar<T>(beta), optr, 1);
228 } else {
229 gemm_func<T>()(CblasColMajor, lOpts, rOpts, M, N, K,
230 getOneScalar<T>(alpha), lptr, lStrides[1], rptr,
231 rStrides[1], getOneScalar<T>(beta), optr,

Callers

nothing calls this directly

Calls 5

toCblasTransposeFunction · 0.70
dimsMethod · 0.45
stridesMethod · 0.45
getMappedPtrMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected