| 254 | } |
| 255 | |
| 256 | ValueRefList broadcast_rule( |
| 257 | const Broadcast& op, Span<ValueRef>& inputs, const bool& auto_convert, |
| 258 | const FormatTransformation& t) { |
| 259 | mgb_assert(inputs.size() >= 1); |
| 260 | auto& src = inputs[0].cast(t.value_type()); |
| 261 | if (auto_convert && src.format() == FT::NHWC) { |
| 262 | if (inputs.size() == 1) { |
| 263 | if (op.shape.size() == 4) { |
| 264 | // output is still NHWC format |
| 265 | auto nhwc_shape = convert_nchw2nhwc_vector(op.shape); |
| 266 | auto outputs = imperative::apply( |
| 267 | *Broadcast::make(nhwc_shape), {t.unwrap_input(inputs[0])}); |
| 268 | return t.wrap_outputs(outputs, FT::NHWC); |
| 269 | } else { |
| 270 | // will not maintain src's format |
| 271 | auto nchw_src = t.to(src, FT::DEFAULT, op.scope())->value(); |
| 272 | auto outputs = imperative::apply(op, {nchw_src}); |
| 273 | return t.wrap_outputs(outputs); |
| 274 | } |
| 275 | } else if (inputs.size() == 2) { |
| 276 | auto shape = t.unwrap_input(inputs[1]).numpy()->as_nd(); |
| 277 | if (shape.layout().total_nr_elems() == 4) { |
| 278 | // output is still NHWC format |
| 279 | auto nhwc_shape = convert_nchw2nhwc_tensornd(shape); |
| 280 | auto outputs = imperative::apply( |
| 281 | op, |
| 282 | SmallVector<ValueRef>{t.unwrap_input(inputs[0]), nhwc_shape}); |
| 283 | return t.wrap_outputs(outputs, FT::NHWC); |
| 284 | } else { |
| 285 | // will not maintain src's format |
| 286 | auto nchw_src = t.to(src, FT::DEFAULT, op.scope())->value(); |
| 287 | auto outputs = imperative::apply( |
| 288 | op, SmallVector<ValueRef>{nchw_src, t.unwrap_input(inputs[1])}); |
| 289 | return t.wrap_outputs(outputs); |
| 290 | } |
| 291 | } |
| 292 | } |
| 293 | return t.wrap_outputs(imperative::apply(op, t.unwrap_inputs(inputs))); |
| 294 | } |
| 295 | |
| 296 | inline bool is_reduce_ndim_idx_items( |
| 297 | const std::vector<std::tuple<int8_t, bool, bool, bool, bool>>& items, |
nothing calls this directly
no test coverage detected