| 88 | } |
| 89 | |
| 90 | SmallVector<TensorPtr> apply_on_physical_tensor( |
| 91 | const OpDef& def, const SmallVector<TensorPtr>& inputs, |
| 92 | SmallVector<LogicalTensorDesc>& output_descs, const bool& validated) { |
| 93 | auto&& ds = static_cast<const Dimshuffle&>(def); |
| 94 | mgb_assert( |
| 95 | ds.pattern.size() <= TensorShape::MAX_NDIM, |
| 96 | "Dimshuffle pattern exceeds max length of %zd", TensorShape::MAX_NDIM); |
| 97 | size_t nr_inp = inputs.size(); |
| 98 | mgb_assert(nr_inp == 1, "Dimshuffle expects 1 inputs; got %lu actually", nr_inp); |
| 99 | auto&& src = inputs[0]; |
| 100 | auto inp_layout = src->layout(); |
| 101 | size_t pattern_ndim = *std::max_element(ds.pattern.begin(), ds.pattern.end()) + 1; |
| 102 | mgb_assert( |
| 103 | inp_layout.ndim == pattern_ndim, |
| 104 | "input ndim mismatch for Dimshuffle: expect=%zd actual=%zd", pattern_ndim, |
| 105 | inp_layout.ndim); |
| 106 | TensorLayout out_layout{inp_layout.dtype}; |
| 107 | out_layout.ndim = ds.pattern.size(); |
| 108 | |
| 109 | size_t idx = 0; |
| 110 | bool input_used[TensorLayout::MAX_NDIM] = {0}; |
| 111 | for (auto i : ds.pattern) { |
| 112 | if (i < 0) { |
| 113 | out_layout.shape[idx] = 1; |
| 114 | out_layout.stride[idx] = 1; |
| 115 | } else { |
| 116 | input_used[i] = true; |
| 117 | out_layout.shape[idx] = inp_layout.shape[i]; |
| 118 | out_layout.stride[idx] = inp_layout.stride[i]; |
| 119 | } |
| 120 | ++idx; |
| 121 | } |
| 122 | if (out_layout.is_contiguous()) { |
| 123 | out_layout.init_contiguous_stride(); |
| 124 | } |
| 125 | for (size_t i = 0; i < pattern_ndim; ++i) { |
| 126 | mgb_assert( |
| 127 | input_used[i] || inp_layout.shape[i] == 1, |
| 128 | "non-1 dim discarded in Dimshuffle: ishp=%s dim=%zd", |
| 129 | inp_layout.megdnn::TensorShape::to_string().c_str(), i); |
| 130 | } |
| 131 | // memory forward |
| 132 | return {Tensor::make(src->blob(), src->offset(), out_layout)}; |
| 133 | } |
| 134 | |
| 135 | OP_TRAIT_REG(Dimshuffle, Dimshuffle, opr::Dimshuffle) |
| 136 | .make_from_op_node(make_from_op_node) |
nothing calls this directly
no test coverage detected