| 96 | |
| 97 | template <Mode mode, typename ctype> |
| 98 | void reduce_raw(HostTensorND& dest, const HostTensorND& src) { |
| 99 | auto tshp = dest.shape(); |
| 100 | using Impl = ImplTrait<mode, ctype>; |
| 101 | |
| 102 | if (tshp.is_scalar()) { |
| 103 | if (src.shape().is_scalar()) { |
| 104 | dest.copy_from_fixlayout(src); |
| 105 | return; |
| 106 | } |
| 107 | |
| 108 | Impl impl; |
| 109 | ctype val = impl.init(); |
| 110 | for (auto i : megdnn::tensor_iter_valonly<ctype>(src.as_megdnn())) |
| 111 | val = impl.reduce(val, i); |
| 112 | dest.ptr<ctype>()[0] = impl.finalize(val); |
| 113 | return; |
| 114 | } |
| 115 | |
| 116 | mgb_assert(tshp.ndim == src.shape().ndim); |
| 117 | |
| 118 | std::vector<size_t> axis_to_use; |
| 119 | for (size_t i = 0; i < tshp.ndim; i++) { |
| 120 | if (tshp.shape[i] != src.shape(i)) { |
| 121 | mgb_assert(tshp.shape[i] == 1); |
| 122 | axis_to_use.push_back(i); |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | if (axis_to_use.empty()) { |
| 127 | dest.copy_from_fixlayout(src); |
| 128 | return; |
| 129 | } |
| 130 | TensorLayout sub_layout{dest.dtype()}; |
| 131 | sub_layout.ndim = axis_to_use.size(); |
| 132 | for (size_t i = 0; i < axis_to_use.size(); i++) { |
| 133 | sub_layout.shape[i] = src.layout().shape[axis_to_use[i]]; |
| 134 | sub_layout.stride[i] = src.layout().stride[axis_to_use[i]]; |
| 135 | } |
| 136 | |
| 137 | auto diter_maker = megdnn::tensor_iter<ctype>(dest.as_megdnn()); |
| 138 | for (auto iter = diter_maker.begin(), iter_end = diter_maker.end(); |
| 139 | iter != iter_end; ++iter) { |
| 140 | ptrdiff_t offset = 0; |
| 141 | for (size_t i = 0; i < tshp.ndim; i++) |
| 142 | offset += iter.idx()[i] * src.layout().stride[i]; |
| 143 | |
| 144 | Impl impl; |
| 145 | ctype val = impl.init(); |
| 146 | auto subspec = SubTensorSpec::make_from_offset_elem(sub_layout, offset); |
| 147 | HostTensorND subt = const_cast<HostTensorND&>(src).sub(subspec); |
| 148 | for (ctype i : megdnn::tensor_iter_valonly<ctype>(subt.as_megdnn())) { |
| 149 | val = impl.reduce(val, i); |
| 150 | } |
| 151 | *iter = impl.finalize(val); |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | template <Mode mode, class dtype> |
nothing calls this directly
no test coverage detected