simplify_reshapes.cpp 1.8 KB
Newer Older
Paul's avatar
Paul committed
1
2
3
4
5
6
7
8
9
#include <migraph/simplify_reshapes.hpp>
#include <migraph/program.hpp>
#include <migraph/instruction.hpp>
#include <migraph/operators.hpp>
#include <migraph/iterator_for.hpp>
#include <migraph/ranges.hpp>
#include <unordered_set>

namespace migraph {
10
namespace MIGRAPH_INLINE_NS {
Paul's avatar
Paul committed
11
12
13

bool is_reshaper(const std::string& name)
{
14
15
16
17
18
19
20
21
    // clang-format off
    static const std::unordered_set<std::string> names = {
        "reshape",
        "transpose",
        // "broadcast",
        "contiguous"
    };
    // clang-format on
Paul's avatar
Paul committed
22
23
24
25
26
27
28
    return contains(names, name);
}

void simplify_reshapes::apply(program& p) const
{
    for(auto ins : iterator_for(p))
    {
Paul's avatar
Paul committed
29
        if(not is_reshaper(ins->name()))
Paul's avatar
Paul committed
30
            continue;
Paul's avatar
Paul committed
31
        if(ins->outputs().size() != 1)
Paul's avatar
Paul committed
32
            continue;
Paul's avatar
Paul committed
33
        if(is_reshaper(ins->outputs().front()->name()))
Paul's avatar
Paul committed
34
35
36
            continue;
        // Gather reshapes
        std::vector<instruction_ref> reshapes{ins};
Paul's avatar
Paul committed
37
        while(is_reshaper(reshapes.back()->name()))
Paul's avatar
Paul committed
38
        {
Paul's avatar
Paul committed
39
40
41
            assert(!reshapes.back()->inputs().empty());
            assert(p.has_instruction(reshapes.back()->inputs().front()));
            reshapes.push_back(reshapes.back()->inputs().front());
Paul's avatar
Paul committed
42
43
44
        }

        std::pair<instruction_ref, instruction_ref> r{p.end(), p.end()};
Paul's avatar
Paul committed
45
        for(auto start : iterator_for(reshapes))
Paul's avatar
Paul committed
46
47
        {
            auto last = std::find_if(reshapes.rbegin(), reshapes.rend(), [&](auto&& i) {
Paul's avatar
Paul committed
48
                return i->get_shape() == (*start)->get_shape() and i != (*start);
Paul's avatar
Paul committed
49
            });
Paul's avatar
Paul committed
50
51
            if(last != reshapes.rend())
            {
Paul's avatar
Paul committed
52
53
54
55
                r = std::make_pair(*start, *last);
                break;
            }
        }
Paul's avatar
Paul committed
56
57
        if(r.first != r.second)
        {
Paul's avatar
Paul committed
58
59
60
61
62
            p.replace_instruction(r.first, r.second);
        }
    }
}

63
} // namespace MIGRAPH_INLINE_NS
Paul's avatar
Paul committed
64
} // namespace migraph