| 76 | |
| 77 | template<typename T> |
| 78 | void wrapTest(const dim_t ix, const dim_t iy, const dim_t wx, const dim_t wy, |
| 79 | const dim_t sx, const dim_t sy, const dim_t px, const dim_t py, |
| 80 | bool cond) { |
| 81 | SUPPORTED_TYPE_CHECK(T); |
| 82 | |
| 83 | const int nc = 1; |
| 84 | |
| 85 | int lim = std::max((dim_t)2, (dim_t)(250) / (wx * wy)); |
| 86 | |
| 87 | dtype ty = (dtype)dtype_traits<T>::af_type; |
| 88 | array in = round(lim * randu(ix, iy, nc, f32)).as(ty); |
| 89 | |
| 90 | vector<T> h_in(in.elements()); |
| 91 | in.host(&h_in[0]); |
| 92 | |
| 93 | vector<int> h_factor(ix * iy); |
| 94 | |
| 95 | dim_t ny = (iy + 2 * py - wy) / sy + 1; |
| 96 | dim_t nx = (ix + 2 * px - wx) / sx + 1; |
| 97 | |
| 98 | for (int idy = 0; idy < ny; idy++) { |
| 99 | int fy = idy * sy - py; |
| 100 | if (fy + wy < 0 || fy >= iy) continue; |
| 101 | |
| 102 | for (int idx = 0; idx < nx; idx++) { |
| 103 | int fx = idx * sx - px; |
| 104 | if (fx + wx < 0 || fx >= ix) continue; |
| 105 | |
| 106 | for (int ly = 0; ly < wy; ly++) { |
| 107 | if (fy + ly < 0 || fy + ly >= iy) continue; |
| 108 | |
| 109 | for (int lx = 0; lx < wx; lx++) { |
| 110 | if (fx + lx < 0 || fx + lx >= ix) continue; |
| 111 | h_factor[(fy + ly) * ix + (fx + lx)]++; |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | array factor(ix, iy, &h_factor[0]); |
| 118 | |
| 119 | array in_dim = unwrap(in, wx, wy, sx, sy, px, py, cond); |
| 120 | array res_dim = wrap(in_dim, ix, iy, wx, wy, sx, sy, px, py, cond); |
| 121 | |
| 122 | ASSERT_EQ(in.elements(), res_dim.elements()); |
| 123 | |
| 124 | vector<T> h_res(ix * iy); |
| 125 | res_dim.host(&h_res[0]); |
| 126 | |
| 127 | for (int n = 0; n < nc; n++) { |
| 128 | T *iptr = &h_in[n * ix * iy]; |
| 129 | T *rptr = &h_res[n * ix * iy]; |
| 130 | |
| 131 | for (int y = 0; y < iy; y++) { |
| 132 | for (int x = 0; x < ix; x++) { |
| 133 | // FIXME: Use a better test |
| 134 | T ival = iptr[y * ix + x]; |
| 135 | T rval = rptr[y * ix + x]; |