| 1035 | // subdimension if available. |
| 1036 | template <class Predicate> |
| 1037 | static auto find_subdimension_with_prev(shape_transform_descriptor& td, Predicate p) |
| 1038 | { |
| 1039 | dimension* prev_dim = nullptr; |
| 1040 | for(auto& d : td.dimensions) |
| 1041 | { |
| 1042 | auto it = std::find_if(d.subdimensions.begin(), d.subdimensions.end(), p); |
| 1043 | if(it != d.subdimensions.end()) |
| 1044 | { |
| 1045 | decltype(std::make_optional(it)) prev = nullopt; |
| 1046 | if(it == d.subdimensions.begin()) |
| 1047 | { |
| 1048 | if(prev_dim != nullptr and not prev_dim->subdimensions.empty()) |
| 1049 | { |
| 1050 | prev = std::prev(prev_dim->subdimensions.end()); |
| 1051 | } |
| 1052 | } |
| 1053 | else |
| 1054 | { |
| 1055 | prev = std::prev(it); |
| 1056 | } |
| 1057 | return std::make_tuple(&d.subdimensions, it, prev); |
| 1058 | } |
| 1059 | prev_dim = &d; |
| 1060 | } |
| 1061 | MIGRAPHX_THROW("Searching for non-existent subdimension"); |
| 1062 | } |
| 1063 | |
| 1064 | static bool is_broadcast_dim(const dimension& d) |
| 1065 | { |