| 65 | |
| 66 | template<typename T, af_op_t op> |
| 67 | void ireduceDim(Param out, cl::Buffer *oidx, Param in, int dim, Param rlen) { |
| 68 | uint threads_y = std::min(THREADS_Y, nextpow2(in.info.dims[dim])); |
| 69 | uint threads_x = THREADS_X; |
| 70 | |
| 71 | uint groups_all[] = {(uint)divup(in.info.dims[0], threads_x), |
| 72 | (uint)in.info.dims[1], (uint)in.info.dims[2], |
| 73 | (uint)in.info.dims[3]}; |
| 74 | |
| 75 | groups_all[dim] = divup(in.info.dims[dim], threads_y * REPEAT); |
| 76 | |
| 77 | Param tmp = out; |
| 78 | cl::Buffer *tidx = oidx; |
| 79 | |
| 80 | int tmp_elements = 1; |
| 81 | if (groups_all[dim] > 1) { |
| 82 | tmp.info.dims[dim] = groups_all[dim]; |
| 83 | |
| 84 | for (int k = 0; k < 4; k++) tmp_elements *= tmp.info.dims[k]; |
| 85 | |
| 86 | tmp.data = bufferAlloc(tmp_elements * sizeof(T)); |
| 87 | tidx = bufferAlloc(tmp_elements * sizeof(uint)); |
| 88 | |
| 89 | for (int k = dim + 1; k < 4; k++) |
| 90 | tmp.info.strides[k] *= groups_all[dim]; |
| 91 | } |
| 92 | |
| 93 | ireduceDimLauncher<T, op>(tmp, tidx, in, tidx, dim, threads_y, true, |
| 94 | groups_all, rlen); |
| 95 | |
| 96 | if (groups_all[dim] > 1) { |
| 97 | groups_all[dim] = 1; |
| 98 | |
| 99 | ireduceDimLauncher<T, op>(out, oidx, tmp, tidx, dim, threads_y, false, |
| 100 | groups_all, rlen); |
| 101 | bufferFree(tmp.data); |
| 102 | bufferFree(tidx); |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | template<typename T, af_op_t op> |
| 107 | void ireduceFirstLauncher(Param out, cl::Buffer *oidx, Param in, |
no test coverage detected