| 32 | inline namespace MIGRAPHX_INLINE_NS { |
| 33 | |
| 34 | void auto_contiguous::apply(module& m) const |
| 35 | { |
| 36 | std::string key = "require_std_shape"; |
| 37 | for(auto ins : reverse_iterator_for(m)) |
| 38 | { |
| 39 | auto&& attr = ins->get_operator().attributes(); |
| 40 | if((attr.get(key, false))) |
| 41 | { |
| 42 | auto args = ins->inputs(); |
| 43 | auto new_args = args; |
| 44 | std::transform(args.begin(), args.end(), new_args.begin(), [&](auto in) { |
| 45 | if(in->name() == "contiguous") |
| 46 | { |
| 47 | return in; |
| 48 | } |
| 49 | return m.insert_instruction(ins, make_op("contiguous"), in); |
| 50 | }); |
| 51 | |
| 52 | if(new_args != args) |
| 53 | { |
| 54 | m.replace_instruction(ins, ins->get_operator(), new_args); |
| 55 | } |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | auto last = std::prev(m.end()); |
| 60 | for(auto ins : iterator_for(m)) |
| 61 | { |
| 62 | if(contains({"layout", "@return"}, ins->name())) |
| 63 | continue; |
| 64 | // for last instruction that is NOT a return |
| 65 | if(ins->outputs().empty() and ins != last) |
| 66 | continue; |
| 67 | shape s = ins->get_shape(); |
| 68 | // If s is not standard layout or has out of sequence strides, insert "contiguous" op |
| 69 | // to make a standard shape |
| 70 | if(not s.dynamic() and (not s.standard() or s.normalize_standard() != s) and |
| 71 | s.elements() > 1) |
| 72 | { |
| 73 | auto c = m.insert_instruction(std::next(ins), make_op("contiguous"), ins); |
| 74 | m.replace_instruction(ins, c); |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | } // namespace MIGRAPHX_INLINE_NS |
| 80 | } // namespace migraphx |
nothing calls this directly
no test coverage detected