| 29 | |
| 30 | template<typename T> |
| 31 | void nonMaxSuppression(Param output, const Param magnitude, const Param dx, |
| 32 | const Param dy) { |
| 33 | using cl::EnqueueArgs; |
| 34 | using cl::NDRange; |
| 35 | using std::string; |
| 36 | using std::vector; |
| 37 | |
| 38 | vector<string> options = { |
| 39 | DefineKeyValue(T, dtype_traits<T>::getName()), |
| 40 | DefineKeyValue(SHRD_MEM_HEIGHT, THREADS_X + 2), |
| 41 | DefineKeyValue(SHRD_MEM_WIDTH, THREADS_Y + 2), |
| 42 | }; |
| 43 | options.emplace_back(getTypeBuildDefinition<T>()); |
| 44 | |
| 45 | auto nonMaxOp = common::getKernel( |
| 46 | "nonMaxSuppressionKernel", {{nonmax_suppression_cl_src}}, |
| 47 | TemplateArgs(TemplateTypename<T>()), options); |
| 48 | |
| 49 | NDRange threads(kernel::THREADS_X, kernel::THREADS_Y, 1); |
| 50 | |
| 51 | // Launch only threads to process non-border pixels |
| 52 | int blk_x = divup(magnitude.info.dims[0] - 2, threads[0]); |
| 53 | int blk_y = divup(magnitude.info.dims[1] - 2, threads[1]); |
| 54 | |
| 55 | // launch batch * blk_x blocks along x dimension |
| 56 | NDRange global(blk_x * magnitude.info.dims[2] * threads[0], |
| 57 | blk_y * magnitude.info.dims[3] * threads[1], 1); |
| 58 | |
| 59 | nonMaxOp(EnqueueArgs(getQueue(), global, threads), *output.data, |
| 60 | output.info, *magnitude.data, magnitude.info, *dx.data, dx.info, |
| 61 | *dy.data, dy.info, blk_x, blk_y); |
| 62 | CL_DEBUG_FINISH(getQueue()); |
| 63 | } |
| 64 | |
| 65 | template<typename T> |
| 66 | void initEdgeOut(Param output, const Param strong, const Param weak) { |
nothing calls this directly
no test coverage detected