| 23 | |
| 24 | template<typename convT, typename T> |
| 25 | void packDataHelper(Param<convT> sig_packed, Param<convT> filter_packed, |
| 26 | CParam<T> sig, CParam<T> filter) { |
| 27 | auto packData = common::getKernel( |
| 28 | "arrayfire::cuda::packData", {{fftconvolve_cuh_src}}, |
| 29 | TemplateArgs(TemplateTypename<convT>(), TemplateTypename<T>())); |
| 30 | auto padArray = common::getKernel( |
| 31 | "arrayfire::cuda::padArray", {{fftconvolve_cuh_src}}, |
| 32 | TemplateArgs(TemplateTypename<convT>(), TemplateTypename<T>())); |
| 33 | |
| 34 | dim_t *sd = sig.dims; |
| 35 | |
| 36 | int sig_packed_elem = 1; |
| 37 | int filter_packed_elem = 1; |
| 38 | |
| 39 | for (int i = 0; i < 4; i++) { |
| 40 | sig_packed_elem *= sig_packed.dims[i]; |
| 41 | filter_packed_elem *= filter_packed.dims[i]; |
| 42 | } |
| 43 | |
| 44 | // Number of packed complex elements in dimension 0 |
| 45 | int sig_half_d0 = divup(sd[0], 2); |
| 46 | bool sig_half_d0_odd = (sd[0] % 2 == 1); |
| 47 | |
| 48 | dim3 threads(THREADS); |
| 49 | dim3 blocks(divup(sig_packed_elem, threads.x)); |
| 50 | |
| 51 | EnqueueArgs packQArgs(blocks, threads, getActiveStream()); |
| 52 | |
| 53 | // Pack signal in a complex matrix where first dimension is half the input |
| 54 | // (allows faster FFT computation) and pad array to a power of 2 with 0s |
| 55 | packData(packQArgs, sig_packed, sig, sig_half_d0, sig_half_d0_odd); |
| 56 | POST_LAUNCH_CHECK(); |
| 57 | |
| 58 | blocks = dim3(divup(filter_packed_elem, threads.x)); |
| 59 | |
| 60 | EnqueueArgs padQArgs(blocks, threads, getActiveStream()); |
| 61 | |
| 62 | // Pad filter array with 0s |
| 63 | padArray(padQArgs, filter_packed, filter); |
| 64 | POST_LAUNCH_CHECK(); |
| 65 | } |
| 66 | |
| 67 | // TODO(umar): This needs a better name |
| 68 | template<typename T, typename convT> |
nothing calls this directly
no test coverage detected