| 200 | |
| 201 | template<typename T, typename aT> |
| 202 | void convolve_3d(conv_kparam_t& p, Param<T> out, CParam<T> sig, CParam<aT> filt, |
| 203 | const bool expand) { |
| 204 | auto convolve3 = common::getKernel( |
| 205 | "arrayfire::cuda::convolve3", {{convolve3_cuh_src}}, |
| 206 | TemplateArgs(TemplateTypename<T>(), TemplateTypename<aT>(), |
| 207 | TemplateArg(expand)), |
| 208 | {{DefineValue(MAX_CONV1_FILTER_LEN), DefineValue(CONV_THREADS), |
| 209 | DefineValue(CONV3_CUBE_X), DefineValue(CONV3_CUBE_Y), |
| 210 | DefineValue(CONV3_CUBE_Z)}}); |
| 211 | |
| 212 | prepareKernelArgs<T>(p, out.dims, filt.dims, 3); |
| 213 | |
| 214 | size_t filterSize = filt.dims[0] * filt.dims[1] * filt.dims[2] * sizeof(aT); |
| 215 | |
| 216 | for (int b3 = 0; b3 < filt.dims[3]; ++b3) { |
| 217 | int f3Off = b3 * filt.strides[3]; |
| 218 | |
| 219 | const aT* fptr = filt.ptr + f3Off; |
| 220 | |
| 221 | // FIXME: case where filter array is strided |
| 222 | auto constMemPtr = convolve3.getDevPtr(conv_c_name); |
| 223 | convolve3.copyToReadOnly( |
| 224 | constMemPtr, reinterpret_cast<CUdeviceptr>(fptr), filterSize); |
| 225 | |
| 226 | p.o[2] = (p.outHasNoOffset ? 0 : b3); |
| 227 | p.s[2] = (p.inHasNoOffset ? 0 : b3); |
| 228 | |
| 229 | EnqueueArgs qArgs(p.mBlocks, p.mThreads, getActiveStream(), |
| 230 | p.mSharedSize); |
| 231 | convolve3(qArgs, out, sig, filt.dims[0], filt.dims[1], filt.dims[2], |
| 232 | p.mBlk_x, p.o[2], p.s[2]); |
| 233 | POST_LAUNCH_CHECK(); |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | template<typename T, typename aT> |
| 238 | void convolve_nd(Param<T> out, CParam<T> signal, CParam<aT> filt, |
nothing calls this directly
no test coverage detected