| 27 | |
| 28 | template<typename T> |
| 29 | void morph(Param out, const Param in, const Param mask, bool isDilation) { |
| 30 | using cl::Buffer; |
| 31 | using cl::EnqueueArgs; |
| 32 | using cl::NDRange; |
| 33 | using std::make_unique; |
| 34 | using std::string; |
| 35 | using std::vector; |
| 36 | |
| 37 | constexpr int THREADS_X = 16; |
| 38 | constexpr int THREADS_Y = 16; |
| 39 | |
| 40 | ToNumStr<T> toNumStr; |
| 41 | const T DefaultVal = isDilation ? common::Binary<T, af_max_t>::init() |
| 42 | : common::Binary<T, af_min_t>::init(); |
| 43 | const int windLen = mask.info.dims[0]; |
| 44 | const int SeLength = (windLen <= 10 ? windLen : 0); |
| 45 | |
| 46 | std::vector<TemplateArg> targs = { |
| 47 | TemplateTypename<T>(), |
| 48 | TemplateArg(isDilation), |
| 49 | TemplateArg(SeLength), |
| 50 | }; |
| 51 | vector<string> options = { |
| 52 | DefineKeyValue(T, dtype_traits<T>::getName()), |
| 53 | DefineValue(isDilation), |
| 54 | DefineValue(SeLength), |
| 55 | DefineKeyValue(init, toNumStr(DefaultVal)), |
| 56 | }; |
| 57 | options.emplace_back(getTypeBuildDefinition<T>()); |
| 58 | |
| 59 | auto morphOp = common::getKernel("morph", {{morph_cl_src}}, targs, options); |
| 60 | |
| 61 | NDRange local(THREADS_X, THREADS_Y); |
| 62 | |
| 63 | int blk_x = divup(in.info.dims[0], THREADS_X); |
| 64 | int blk_y = divup(in.info.dims[1], THREADS_Y); |
| 65 | |
| 66 | NDRange global(blk_x * THREADS_X * in.info.dims[2], |
| 67 | blk_y * THREADS_Y * in.info.dims[3]); |
| 68 | |
| 69 | // copy mask/filter to read-only memory |
| 70 | auto seBytes = windLen * windLen * sizeof(T); |
| 71 | auto mBuff = |
| 72 | make_unique<cl::Buffer>(getContext(), CL_MEM_READ_ONLY, seBytes); |
| 73 | morphOp.copyToReadOnly(mBuff.get(), mask.data, seBytes); |
| 74 | |
| 75 | // calculate shared memory size |
| 76 | const int padding = |
| 77 | (windLen % 2 == 0 ? (windLen - 1) : (2 * (windLen / 2))); |
| 78 | const int locLen = THREADS_X + padding + 1; |
| 79 | const int locSize = locLen * (THREADS_Y + padding); |
| 80 | |
| 81 | morphOp(EnqueueArgs(getQueue(), global, local), *out.data, out.info, |
| 82 | *in.data, in.info, *mBuff, cl::Local(locSize * sizeof(T)), blk_x, |
| 83 | blk_y, windLen); |
| 84 | CL_DEBUG_FINISH(getQueue()); |
| 85 | } |
| 86 |
nothing calls this directly
no test coverage detected