module_trace.h 2.1 KB
Newer Older
1 2
#pragma once

3
#include <list>
4 5 6
#include "megbrain/imperative/transformations/trace.h"
#include "megbrain/imperative/utils/map.h"

7 8 9 10
#include "./tensor.h"

namespace mgb::imperative::python {

11 12 13 14 15 16 17
namespace py = pybind11;

class ModuleTraceTransformation final : public Transformation {
private:
    py::function m_hook_fn;
    int m_enabled = 0;

18
    ValueRefList apply_module_trace_hook(const OpDef& op, Span<ValueRef> input_values) {
19 20 21 22 23
        py::list input_tws;
        for (auto&& input_value : input_values) {
            input_tws.append(TensorWrapper::make(py_tensor_type, input_value));
        }
        py::list output_tws = m_hook_fn(py::cast(op.shared_from_this()), *input_tws);
24 25
        ValueRefList outputs(output_tws.size());
        auto it = outputs.begin();
26
        for (auto&& output_tw : output_tws) {
27
            *(it++) = TensorWrapper::try_cast(output_tw.ptr())->m_tensor->data();
28 29 30 31 32
        }
        return outputs;
    }

public:
33
    inline static WeakKeyMap<ValueWeakRef, py::object> module_trace_info_map;
34
    ModuleTraceTransformation(py::function hook_fn) : m_hook_fn(hook_fn) {}
35
    ValueRefList apply_transformation(
36 37 38 39
            const Operator& op, Span<ValueRef> inputs) override {
        if (op.is<ApplyOp>() && m_enabled > 0) {
            auto outputs = apply_module_trace_hook(op.cast<ApplyOp>().op(), inputs);
            return outputs;
40 41 42 43 44 45 46 47 48
        } else if (op.is<RenameValue>()) {
            auto outputs = imperative::apply(op, inputs);
            if (auto module_trace_info = module_trace_info_map.try_get(inputs[0])) {
                if (module_trace_info->ptr()) {
                    auto node = module_trace_info.value();
                    module_trace_info_map[outputs[0]] = module_trace_info.value();
                }
            }
            return outputs;
49 50 51 52 53
        } else {
            return imperative::apply(op, inputs);
        }
    }

54 55 56 57 58 59
    void enable() { m_enabled = 1; }

    void disable() { m_enabled = 0; }

    bool enabled() const { return m_enabled; }

60 61 62 63
    ValueRef unwrap(ValueRef value) override { return value; }

    std::string name() const override { return "ModuleTraceTransformation"; }
};
64

M
Megvii Engine Team 已提交
65
}  // namespace mgb::imperative::python