| 1496 | } |
| 1497 | |
| 1498 | void apply(module& m, const match::matcher_result& r) const |
| 1499 | { |
| 1500 | auto ins = r.result; |
| 1501 | std::vector<instruction_ref> splits; |
| 1502 | std::copy_if(ins->outputs().begin(), |
| 1503 | ins->outputs().end(), |
| 1504 | std::back_inserter(splits), |
| 1505 | [&](instruction_ref out) { |
| 1506 | return out->name() == "slice" and out->outputs().size() == 1 and |
| 1507 | out->outputs().front()->name() == "transpose"; |
| 1508 | }); |
| 1509 | if(splits.size() < 2) |
| 1510 | return; |
| 1511 | std::vector<instruction_ref> transposes; |
| 1512 | std::transform(splits.begin(), |
| 1513 | splits.end(), |
| 1514 | std::back_inserter(transposes), |
| 1515 | [](auto split) { return split->outputs().front(); }); |
| 1516 | auto perm = find_common_perm(transposes); |
| 1517 | auto iperm = invert_permutation(perm); |
| 1518 | auto pre = m.insert_instruction( |
| 1519 | std::next(ins), make_op("transpose", {{"permutation", perm}}), ins); |
| 1520 | for(auto i : range(transposes.size())) |
| 1521 | { |
| 1522 | auto split = splits[i]; |
| 1523 | auto t = transposes[i]; |
| 1524 | auto op = any_cast<op::slice>(split->get_operator()); |
| 1525 | std::transform(op.axes.begin(), op.axes.end(), op.axes.begin(), [&](auto axis) { |
| 1526 | return iperm[axis]; |
| 1527 | }); |
| 1528 | auto new_ins = m.insert_instruction(t, op, pre); |
| 1529 | if(t->get_operator() != pre->get_operator()) |
| 1530 | { |
| 1531 | auto curr = t->get_operator().to_value()["permutation"].to_vector<int64_t>(); |
| 1532 | new_ins = m.insert_instruction( |
| 1533 | t, make_op("transpose", {{"permutation", reorder_dims(iperm, curr)}}), new_ins); |
| 1534 | } |
| 1535 | m.replace_instruction(t, new_ins); |
| 1536 | } |
| 1537 | } |
| 1538 | }; |
| 1539 | |
| 1540 | struct find_transpose_slice |
nothing calls this directly
no test coverage detected