"src/include/migraph/operators.hpp" did not exist on "796d1802bd02dcce684a5723f41e10d4cb42d943"
program.hpp 2.22 KB
Newer Older
Paul's avatar
Paul committed
1
2
3
#ifndef GUARD_RTGLIB_PROGRAM_HPP
#define GUARD_RTGLIB_PROGRAM_HPP

Paul's avatar
Paul committed
4
#include <list>
Paul's avatar
Paul committed
5
6
#include <unordered_map>
#include <rtg/instruction.hpp>
Paul's avatar
Paul committed
7
#include <rtg/operand.hpp>
Paul's avatar
Paul committed
8
#include <rtg/builtin.hpp>
Paul's avatar
Paul committed
9
#include <algorithm>
Paul's avatar
Paul committed
10
11
12
13
14

namespace rtg {

struct program
{
Paul's avatar
Paul committed
15
    // TODO: A program should be copyable
Paul's avatar
Paul committed
16
    program()               = default;
Paul's avatar
Paul committed
17
18
19
    program(const program&) = delete;
    program& operator=(const program&) = delete;

Paul's avatar
Paul committed
20
21
    template <class... Ts>
    instruction* add_instruction(operand op, Ts*... args)
Paul's avatar
Paul committed
22
23
    {
        shape r = op.compute_shape({args->result...});
Paul's avatar
Paul committed
24
        instructions.push_back({op, r, {args...}});
Paul's avatar
Paul committed
25
26
        return std::addressof(instructions.back());
    }
Paul's avatar
Paul committed
27
    instruction* add_instruction(operand op, std::vector<instruction*> args)
Paul's avatar
Paul committed
28
    {
Paul's avatar
Paul committed
29
30
31
        assert(std::all_of(
                   args.begin(), args.end(), [&](instruction* x) { return has_instruction(x); }) &&
               "Argument is not an exisiting instruction");
Paul's avatar
Paul committed
32
        std::vector<shape> shapes(args.size());
Paul's avatar
Paul committed
33
34
        std::transform(
            args.begin(), args.end(), shapes.begin(), [](instruction* ins) { return ins->result; });
Paul's avatar
Paul committed
35
36
37
38
39
        shape r = op.compute_shape(shapes);
        instructions.push_back({op, r, args});
        assert(instructions.back().arguments == args);
        return std::addressof(instructions.back());
    }
Paul's avatar
Paul committed
40
41
    template <class... Ts>
    instruction* add_literal(Ts&&... xs)
Paul's avatar
Paul committed
42
43
44
45
46
    {
        instructions.emplace_back(literal{std::forward<Ts>(xs)...});
        return std::addressof(instructions.back());
    }

Paul's avatar
Paul committed
47
    instruction* add_parameter(std::string name, shape s)
Paul's avatar
Paul committed
48
    {
Paul's avatar
Paul committed
49
        instructions.push_back({builtin::param{std::move(name)}, s, {}});
Paul's avatar
Paul committed
50
51
52
53
        return std::addressof(instructions.back());
    }

    literal eval(std::unordered_map<std::string, argument> params) const;
Paul's avatar
Paul committed
54

Paul's avatar
Paul committed
55
56
57
    // TODO: Change to stream operator
    void print() const;

Paul's avatar
Paul committed
58
    bool has_instruction(const instruction* ins) const
Paul's avatar
Paul committed
59
    {
Paul's avatar
Paul committed
60
61
62
        return std::find_if(instructions.begin(), instructions.end(), [&](const instruction& x) {
                   return ins == std::addressof(x);
               }) != instructions.end();
Paul's avatar
Paul committed
63
64
    }

Paul's avatar
Paul committed
65
    private:
Paul's avatar
Paul committed
66
67
    // A list is used to keep references to an instruction stable
    std::list<instruction> instructions;
Paul's avatar
Paul committed
68
69
};

Paul's avatar
Paul committed
70
} // namespace rtg
Paul's avatar
Paul committed
71
72

#endif