| 145 | |
| 146 | template<typename T, typename aT> |
| 147 | void conv2Helper(const conv_kparam_t& p, Param<T> out, CParam<T> sig, |
| 148 | const aT* fptr, int f0, int f1, const bool expand) { |
| 149 | const bool isFilterSizeLt5 = (f0 <= 5 && f1 <= 5); |
| 150 | const bool isFilterGt5AndSq = (f0 == f1 && f0 > 5 && f0 < 18); |
| 151 | |
| 152 | if (!(isFilterSizeLt5 || isFilterGt5AndSq)) { |
| 153 | char errMessage[256]; |
| 154 | snprintf(errMessage, sizeof(errMessage), |
| 155 | "\nCUDA Convolution doesn't support %dx%d kernel\n", f0, f1); |
| 156 | CUDA_NOT_SUPPORTED(errMessage); |
| 157 | } |
| 158 | |
| 159 | auto convolve2 = common::getKernel( |
| 160 | "arrayfire::cuda::convolve2", {{convolve2_cuh_src}}, |
| 161 | TemplateArgs(TemplateTypename<T>(), TemplateTypename<aT>(), |
| 162 | TemplateArg(expand), TemplateArg(f0), TemplateArg(f1)), |
| 163 | {{DefineValue(MAX_CONV1_FILTER_LEN), DefineValue(CONV_THREADS), |
| 164 | DefineValue(CONV2_THREADS_X), DefineValue(CONV2_THREADS_Y)}}); |
| 165 | |
| 166 | // FIXME: case where filter array is strided |
| 167 | auto constMemPtr = convolve2.getDevPtr(conv_c_name); |
| 168 | convolve2.copyToReadOnly(constMemPtr, reinterpret_cast<CUdeviceptr>(fptr), |
| 169 | f0 * f1 * sizeof(aT)); |
| 170 | |
| 171 | EnqueueArgs qArgs(p.mBlocks, p.mThreads, getActiveStream()); |
| 172 | convolve2(qArgs, out, sig, p.mBlk_x, p.mBlk_y, p.o[1], p.o[2], p.s[1], |
| 173 | p.s[2]); |
| 174 | POST_LAUNCH_CHECK(); |
| 175 | } |
| 176 | |
| 177 | template<typename T, typename aT> |
| 178 | void convolve_2d(conv_kparam_t& p, Param<T> out, CParam<T> sig, CParam<aT> filt, |
nothing calls this directly
no test coverage detected