| 198 | } |
| 199 | |
| 200 | void convolution_brute( |
| 201 | const std::vector<std::shared_ptr<HostTensorND>>& in_tensor, |
| 202 | std::shared_ptr<HostTensorND>& out_tensor, |
| 203 | const opr::Convolution::Param& param) { |
| 204 | mgb_assert(in_tensor.size() == 2); |
| 205 | auto in = in_tensor[0], filter = in_tensor[1]; |
| 206 | mgb_assert(in->shape().ndim == 4); |
| 207 | mgb_assert(filter->shape().ndim == 4); |
| 208 | |
| 209 | int batch_size = in->shape().shape[0]; |
| 210 | int ic = in->shape().shape[1]; |
| 211 | int ih = in->shape().shape[2]; |
| 212 | int iw = in->shape().shape[3]; |
| 213 | |
| 214 | int fh = filter->shape().shape[2]; |
| 215 | int fw = filter->shape().shape[3]; |
| 216 | |
| 217 | int ph = param.pad_h; |
| 218 | int pw = param.pad_w; |
| 219 | |
| 220 | int sh = param.stride_h; |
| 221 | int sw = param.stride_w; |
| 222 | |
| 223 | int dh = param.dilate_h; |
| 224 | int dw = param.dilate_w; |
| 225 | |
| 226 | mgb_assert(ih + 2 * ph >= (fh - 1) * dh + 1); |
| 227 | mgb_assert(iw + 2 * pw >= (fw - 1) * dw + 1); |
| 228 | int oh = (ih + 2 * ph - ((fh - 1) * dh + 1)) / sh + 1; |
| 229 | int ow = (iw + 2 * pw - ((fw - 1) * dw + 1)) / sw + 1; |
| 230 | mgb_assert(static_cast<size_t>(ic) == filter->shape().shape[1]); |
| 231 | int oc = filter->shape().shape[0]; |
| 232 | |
| 233 | out_tensor = std::make_shared<HostTensorND>( |
| 234 | CompNode::load("xpu0"), |
| 235 | TensorShape{ |
| 236 | static_cast<size_t>(batch_size), static_cast<size_t>(oc), |
| 237 | static_cast<size_t>(oh), static_cast<size_t>(ow)}); |
| 238 | |
| 239 | int pn, poc, poh, pow, pih, piw, pic, pfh, pfw; |
| 240 | for (pn = 0; pn < batch_size; ++pn) |
| 241 | for (poc = 0; poc < oc; ++poc) |
| 242 | for (poh = 0, pih = -ph; poh < oh; ++poh, pih += sh) |
| 243 | for (pow = 0, piw = -pw; pow < ow; ++pow, piw += sw) { |
| 244 | float& target = out_tensor->ptr<float>( |
| 245 | {static_cast<size_t>(pn), static_cast<size_t>(poc), |
| 246 | static_cast<size_t>(poh), static_cast<size_t>(pow)})[0]; |
| 247 | target = 0; |
| 248 | for (pic = 0; pic < ic; ++pic) |
| 249 | for (pfh = 0; pfh < fh; ++pfh) |
| 250 | for (pfw = 0; pfw < fw; ++pfw) { |
| 251 | int prih, priw; |
| 252 | float img_data, filter_data; |
| 253 | if (param.mode == Param::Mode::CONVOLUTION) { |
| 254 | prih = pih + (fh - pfh - 1) * dh; |
| 255 | priw = piw + (fw - pfw - 1) * dw; |
| 256 | } else { |
| 257 | mgb_assert( |
no test coverage detected