| 1082 | } |
| 1083 | |
| 1084 | void Reduce::KernScheduler::init_shapes( |
| 1085 | megdnn::Reduce* opr, CompNode comp_node, DType inp_dtype, Mode mode, |
| 1086 | TensorShape ishp, TensorShape oshp, const Param::DataType data_type) { |
| 1087 | mgb_assert(ishp.ndim && oshp.ndim); |
| 1088 | |
| 1089 | if (ishp.eq_shape(m_prev_ishp) && oshp.eq_shape(m_prev_oshp)) |
| 1090 | return; |
| 1091 | |
| 1092 | m_prev_ishp = ishp; |
| 1093 | m_prev_oshp = oshp; |
| 1094 | |
| 1095 | m_kern_param.clear(); |
| 1096 | |
| 1097 | if (oshp.is_scalar()) { |
| 1098 | // if ishp is non-contiguous, add_layout_constraint_contiguous would be |
| 1099 | // added; so we do not have to worry about this |
| 1100 | ishp.shape[0] = ishp.total_nr_elems(); |
| 1101 | ishp.ndim = 1; |
| 1102 | } |
| 1103 | |
| 1104 | mgb_assert( |
| 1105 | oshp.ndim == ishp.ndim, |
| 1106 | "input and output ndim mismatch for reduction: ishp=%s oshp=%s", |
| 1107 | ishp.to_string().c_str(), oshp.to_string().c_str()); |
| 1108 | |
| 1109 | for (size_t i = 0; i < ishp.ndim; ++i) { |
| 1110 | if (ishp.shape[i] != oshp.shape[i]) { |
| 1111 | mgb_assert( |
| 1112 | oshp.shape[i] == 1, |
| 1113 | "input and output shape mismatch for reduction: " |
| 1114 | "ishp=%s oshp=%s", |
| 1115 | ishp.to_string().c_str(), oshp.to_string().c_str()); |
| 1116 | } |
| 1117 | } |
| 1118 | |
| 1119 | auto remove_axis = [](TensorShape& shp, size_t ax) { |
| 1120 | mgb_assert(shp.ndim > 1); |
| 1121 | for (auto i = ax + 1; i < shp.ndim; ++i) |
| 1122 | shp.shape[i - 1] = shp.shape[i]; |
| 1123 | --shp.ndim; |
| 1124 | }; |
| 1125 | |
| 1126 | // collapse consecutive shape-1 axes in oshp |
| 1127 | for (size_t i = 0; i < oshp.ndim; ++i) { |
| 1128 | auto start = i; |
| 1129 | while (i < oshp.ndim && oshp.shape[i] == 1) |
| 1130 | ++i; |
| 1131 | |
| 1132 | if (start + 1 < i) { |
| 1133 | for (auto j = start + 1; j < i; ++j) |
| 1134 | ishp.shape[start] *= ishp.shape[j]; |
| 1135 | |
| 1136 | for (auto j = start + 1; j < i; ++j) { |
| 1137 | remove_axis(ishp, start + 1); |
| 1138 | remove_axis(oshp, start + 1); |
| 1139 | } |
| 1140 | |
| 1141 | i = start; |
no test coverage detected