transformation.h 2.3 KB
Newer Older
1 2
#pragma once

3 4 5 6 7 8
#include <optional>
#include <string>

#include "pybind11/pybind11.h"

#include "megbrain/imperative/dispatch.h"
9
#include "megbrain/imperative/transformation.h"
10
#include "megbrain/imperative/utils/helper.h"
11 12
#include "megbrain/imperative/value.h"
#include "megbrain/utils/small_vector.h"
13 14 15

namespace mgb::imperative::python {
struct TransformationManager {
16
public:
17 18
    enum Segment {
        ModuleTrace,
19
        GroupComm,
20
        DTypePromote,
21
        DimExpansion,
22
        Complex,
23
        Format,
24
        Grad,
25
        ExternalConvert,
26
        Scalar,
27
        Symbol,
28 29
        Trace,
        Eval,
30
        SEGMENT_COUNT,
31 32
    };

33
    std::array<std::vector<std::shared_ptr<Transformation>>, SEGMENT_COUNT> segments;
34

35 36 37 38 39 40 41 42 43 44 45 46
private:
    template <Segment segment>
    void unregister(std::shared_ptr<Transformation> transformation) noexcept {
        mgb_assert(segment < segments.size());
        auto iter = std::find(
                segments[segment].begin(), segments[segment].end(), transformation);
        mgb_assert(iter != segments[segment].end());
        transformation->unregister();
        segments[segment].erase(iter);
    }

public:
47
    template <Segment segment>
48 49
    [[nodiscard]] std::unique_ptr<CleanupGuard<>> register_at(
            std::shared_ptr<Transformation> transformation) {
50 51 52 53 54 55 56 57 58 59 60 61 62 63
        mgb_assert(segment < segments.size());
        std::shared_ptr<Transformation> next;
        for (size_t i = segment; i < segments.size(); ++i) {
            if (!segments[i].empty()) {
                next = segments[i].back();
                break;
            }
        }
        if (!next) {
            transformation->register_at(Transformation::bottom());
        } else {
            transformation->register_at(next->pos());
        }
        segments[segment].push_back(transformation);
64 65
        return std::make_unique<CleanupGuard<>>(
                [this, transformation]() { unregister<segment>(transformation); });
66 67 68 69 70 71 72
    }

    static TransformationManager& get_instance() {
        static TransformationManager sl_instance;
        return sl_instance;
    }
};
73

74
class PyValue final : public PrimitiveValue<PyValue, pybind11::object> {
75
public:
76
    using PrimitiveValue::PrimitiveValue;
77 78 79 80 81 82

    std::string to_string() const {
        return pybind11::str((const pybind11::object&)*this).cast<std::string>();
    }
};

83
}  // namespace mgb::imperative::python