| 61 | |
| 62 | template<typename T> |
| 63 | void morph3d(Param<T> out, CParam<T> in, CParam<T> mask, bool isDilation) { |
| 64 | const int windLen = mask.dims[0]; |
| 65 | |
| 66 | if (windLen > 7) { |
| 67 | CUDA_NOT_SUPPORTED("Morph 3D does not support kernels larger than 7."); |
| 68 | } |
| 69 | |
| 70 | auto morph3D = common::getKernel( |
| 71 | "arrayfire::cuda::morph3D", {{morph_cuh_src}}, |
| 72 | TemplateArgs(TemplateTypename<T>(), TemplateArg(isDilation), |
| 73 | TemplateArg(windLen)), |
| 74 | {{DefineValue(MAX_MORPH_FILTER_LEN)}}); |
| 75 | |
| 76 | morph3D.copyToReadOnly( |
| 77 | morph3D.getDevPtr("cFilter"), reinterpret_cast<CUdeviceptr>(mask.ptr), |
| 78 | mask.dims[0] * mask.dims[1] * mask.dims[2] * sizeof(T)); |
| 79 | |
| 80 | dim3 threads(kernel::CUBE_X, kernel::CUBE_Y, kernel::CUBE_Z); |
| 81 | |
| 82 | int blk_x = divup(in.dims[0], CUBE_X); |
| 83 | int blk_y = divup(in.dims[1], CUBE_Y); |
| 84 | int blk_z = divup(in.dims[2], CUBE_Z); |
| 85 | dim3 blocks(blk_x * in.dims[3], blk_y, blk_z); |
| 86 | |
| 87 | // calculate shared memory size |
| 88 | int padding = (windLen % 2 == 0 ? (windLen - 1) : (2 * (windLen / 2))); |
| 89 | int shrdLen = |
| 90 | kernel::CUBE_X + padding + 1; // +1 for to avoid bank conflicts |
| 91 | int shrdSize = shrdLen * (kernel::CUBE_Y + padding) * |
| 92 | (kernel::CUBE_Z + padding) * sizeof(T); |
| 93 | |
| 94 | EnqueueArgs qArgs(blocks, threads, getActiveStream(), shrdSize); |
| 95 | morph3D(qArgs, out, in, blk_x); |
| 96 | POST_LAUNCH_CHECK(); |
| 97 | } |
| 98 | |
| 99 | } // namespace kernel |
| 100 | } // namespace cuda |
nothing calls this directly
no test coverage detected