| 51 | |
| 52 | template<typename Ti, typename Tw, typename To, uint dim, uint DIMY> |
| 53 | __global__ static void mean_dim_kernel(Param<To> out, Param<Tw> owt, |
| 54 | CParam<Ti> in, CParam<Tw> iwt, |
| 55 | uint blocks_x, uint blocks_y, |
| 56 | uint offset_dim) { |
| 57 | const uint tidx = threadIdx.x; |
| 58 | const uint tidy = threadIdx.y; |
| 59 | const uint tid = tidy * THREADS_X + tidx; |
| 60 | |
| 61 | const uint zid = blockIdx.x / blocks_x; |
| 62 | const uint wid = blockIdx.y / blocks_y; |
| 63 | const uint blockIdx_x = blockIdx.x - (blocks_x)*zid; |
| 64 | const uint blockIdx_y = blockIdx.y - (blocks_y)*wid; |
| 65 | const uint xid = blockIdx_x * blockDim.x + tidx; |
| 66 | const uint yid = blockIdx_y; // yid of output. updated for input later. |
| 67 | |
| 68 | uint ids[4] = {xid, yid, zid, wid}; |
| 69 | |
| 70 | const Ti *iptr = in.ptr; |
| 71 | const Tw *iwptr = iwt.ptr; |
| 72 | To *optr = out.ptr; |
| 73 | Tw *owptr = owt.ptr; |
| 74 | |
| 75 | int ooffset = ids[3] * out.strides[3] + ids[2] * out.strides[2] + |
| 76 | ids[1] * out.strides[1] + ids[0]; |
| 77 | // There is only one element per block for out |
| 78 | // There are blockDim.y elements per block for in |
| 79 | // Hence increment ids[dim] just after offseting out and before offsetting |
| 80 | // in |
| 81 | optr += ooffset; |
| 82 | if (owptr != NULL) owptr += ooffset; |
| 83 | |
| 84 | const uint blockIdx_dim = ids[dim]; |
| 85 | |
| 86 | ids[dim] = ids[dim] * blockDim.y + tidy; |
| 87 | |
| 88 | int ioffset = ids[3] * in.strides[3] + ids[2] * in.strides[2] + |
| 89 | ids[1] * in.strides[1] + ids[0]; |
| 90 | iptr += ioffset; |
| 91 | if (iwptr != NULL) iwptr += ioffset; |
| 92 | |
| 93 | const uint id_dim_in = ids[dim]; |
| 94 | const uint istride_dim = in.strides[dim]; |
| 95 | |
| 96 | bool is_valid = (ids[0] < in.dims[0]) && (ids[1] < in.dims[1]) && |
| 97 | (ids[2] < in.dims[2]) && (ids[3] < in.dims[3]); |
| 98 | |
| 99 | common::Transform<Ti, compute_t<To>, af_add_t> transform; |
| 100 | |
| 101 | compute_t<To> val = common::Binary<compute_t<To>, af_add_t>::init(); |
| 102 | compute_t<Tw> weight = common::Binary<compute_t<Tw>, af_add_t>::init(); |
| 103 | |
| 104 | if (is_valid && id_dim_in < in.dims[dim]) { |
| 105 | val = transform(*iptr); |
| 106 | if (iwptr != NULL) { |
| 107 | weight = *iwptr; |
| 108 | } else { |
| 109 | weight = (Tw)1; |
| 110 | } |
nothing calls this directly
no test coverage detected