| 27 | |
| 28 | template<typename inType, typename outType> |
| 29 | void bilateral(Param out, const Param in, const float s_sigma, |
| 30 | const float c_sigma) { |
| 31 | constexpr int THREADS_X = 16; |
| 32 | constexpr int THREADS_Y = 16; |
| 33 | constexpr bool UseNativeExp = !std::is_same<inType, double>::value || |
| 34 | std::is_same<inType, cdouble>::value; |
| 35 | |
| 36 | std::array<TemplateArg, 2> targs = { |
| 37 | TemplateTypename<inType>(), |
| 38 | TemplateTypename<outType>(), |
| 39 | }; |
| 40 | std::vector<std::string> options = { |
| 41 | DefineKeyValue(inType, dtype_traits<inType>::getName()), |
| 42 | DefineKeyValue(outType, dtype_traits<outType>::getName()), |
| 43 | }; |
| 44 | if (UseNativeExp) { options.emplace_back(DefineKey(USE_NATIVE_EXP)); } |
| 45 | options.emplace_back(getTypeBuildDefinition<inType>()); |
| 46 | |
| 47 | auto bilateralOp = |
| 48 | common::getKernel("bilateral", {{bilateral_cl_src}}, targs, options); |
| 49 | |
| 50 | cl::NDRange local(THREADS_X, THREADS_Y); |
| 51 | |
| 52 | int blk_x = divup(in.info.dims[0], THREADS_X); |
| 53 | int blk_y = divup(in.info.dims[1], THREADS_Y); |
| 54 | |
| 55 | cl::NDRange global(blk_x * in.info.dims[2] * THREADS_X, |
| 56 | blk_y * in.info.dims[3] * THREADS_Y); |
| 57 | |
| 58 | // calculate local memory size |
| 59 | int radius = (int)std::max(s_sigma * 1.5f, 1.f); |
| 60 | int num_shrd_elems = (THREADS_X + 2 * radius) * (THREADS_Y + 2 * radius); |
| 61 | int num_gauss_elems = (2 * radius + 1) * (2 * radius + 1); |
| 62 | size_t localMemSize = (num_shrd_elems + num_gauss_elems) * sizeof(outType); |
| 63 | size_t MaxLocalSize = |
| 64 | getDevice(getActiveDeviceId()).getInfo<CL_DEVICE_LOCAL_MEM_SIZE>(); |
| 65 | if (localMemSize > MaxLocalSize) { |
| 66 | char errMessage[256]; |
| 67 | snprintf(errMessage, sizeof(errMessage), |
| 68 | "\nOpenCL Bilateral filter doesn't support %f spatial sigma\n", |
| 69 | s_sigma); |
| 70 | OPENCL_NOT_SUPPORTED(errMessage); |
| 71 | } |
| 72 | |
| 73 | bilateralOp(cl::EnqueueArgs(getQueue(), global, local), *out.data, out.info, |
| 74 | *in.data, in.info, cl::Local(num_shrd_elems * sizeof(outType)), |
| 75 | cl::Local(num_gauss_elems * sizeof(outType)), s_sigma, c_sigma, |
| 76 | num_shrd_elems, blk_x, blk_y); |
| 77 | CL_DEBUG_FINISH(getQueue()); |
| 78 | } |
| 79 | } // namespace kernel |
| 80 | } // namespace opencl |
| 81 | } // namespace arrayfire |
nothing calls this directly
no test coverage detected