| 243 | } |
| 244 | |
| 245 | static bool is_broadcast_only(const std::vector<dimension>& src_dims, |
| 246 | const std::vector<dimension>& dst_dims) |
| 247 | { |
| 248 | return std::equal(src_dims.begin(), |
| 249 | src_dims.end(), |
| 250 | dst_dims.begin(), |
| 251 | dst_dims.end(), |
| 252 | [](const auto& src_dim, const auto& dst_dim) { |
| 253 | if(src_dim.subdimensions.size() != dst_dim.subdimensions.size()) |
| 254 | return false; |
| 255 | auto match_sub_dim = [](const dimension::sub& src_sub, |
| 256 | const dimension::sub& dst_sub) { |
| 257 | if(src_sub.len == 1) |
| 258 | return true; |
| 259 | return src_sub.len == dst_sub.len; |
| 260 | }; |
| 261 | auto [src_it, dst_it] = std::mismatch(src_dim.subdimensions.begin(), |
| 262 | src_dim.subdimensions.end(), |
| 263 | dst_dim.subdimensions.begin(), |
| 264 | dst_dim.subdimensions.end(), |
| 265 | match_sub_dim); |
| 266 | if(src_it == src_dim.subdimensions.end()) |
| 267 | return true; |
| 268 | // One mismatch is fine as long as the dimension is still the same size |
| 269 | if(src_dim.len() != dst_dim.len()) |
| 270 | return false; |
| 271 | return std::equal(std::next(src_it), |
| 272 | src_dim.subdimensions.end(), |
| 273 | std::next(dst_it), |
| 274 | dst_dim.subdimensions.end(), |
| 275 | match_sub_dim); |
| 276 | }); |
| 277 | } |
| 278 | |
| 279 | template <class Dimensions, class Predicate> |
| 280 | static auto find_subdimension_with_dimension(Dimensions& dims, Predicate pred) |