diff --git a/imperative/python/megengine/core/tensor/megbrain_graph.py b/imperative/python/megengine/core/tensor/megbrain_graph.py index 5ad3391e..818d119e 100644 --- a/imperative/python/megengine/core/tensor/megbrain_graph.py +++ b/imperative/python/megengine/core/tensor/megbrain_graph.py @@ -95,6 +95,10 @@ class VarNode(TensorBase): def shape(self): return self._node.shape + @property + def value(self): + return self._node.value + class OpNode: def __init__(self, node: _imperative_rt.OperatorNode): diff --git a/imperative/python/megengine/jit/tracing.py b/imperative/python/megengine/jit/tracing.py index e3c20a5d..2a788960 100644 --- a/imperative/python/megengine/jit/tracing.py +++ b/imperative/python/megengine/jit/tracing.py @@ -399,7 +399,7 @@ class LazyEvalTensor(RawTensor): return self.__varnode.shape def numpy(self): - raise RuntimeError("cannot read value during symbolic tracing") + return self.__varnode.value def _dev_tensor(self): raise RuntimeError("cannot access data during symbolic tracing") diff --git a/imperative/python/src/graph_rt.cpp b/imperative/python/src/graph_rt.cpp index a021c2b7..38b2b3b5 100644 --- a/imperative/python/src/graph_rt.cpp +++ b/imperative/python/src/graph_rt.cpp @@ -58,6 +58,19 @@ void init_graph_rt(py::module m) { return nullptr; } return mgr.infer_shape_fallible(v); + }) + .def_property_readonly("value", [](cg::VarNode* v) -> py::object { + auto&& mgr = v->owner_graph()->static_infer_manager(); + auto&& type = mgr.get_infer_type(v); + using InferType = cg::static_infer::InferType; + if (!(type.value & (InferType::CONST | InferType::RT_STATIC))) { + return py::none(); + } + auto* val = mgr.infer_value_fallible(v); + if (!val) { + return py::none(); + } + return py::cast(*val).attr("numpy")(); }); py::class_>(m, "OperatorNode")