Skip to content

Conversation

@tqchen
Copy link
Member

@tqchen tqchen commented Jun 14, 2025

This PR enhances and refactors the reflection module to support nanobind/pybind style reflection definition.

This is one step to upgrade the overall reflection mechanism in the project.

@tqchen
Copy link
Member Author

tqchen commented Jun 14, 2025

Python binding updates will follow this, then we will gradually move towards the field reflection to the new mechanism, specifically the VisitAttrs based reflection

@tqchen
Copy link
Member Author

tqchen commented Jun 14, 2025

Example code https://github.com/apache/tvm/blob/140bc3b0ffdf445e5e38ed81b6bbe3342cdb548e/ffi/tests/cpp/test_reflection.cc

TVM_FFI_REFLECTION_DEF(TFloatObj)
    .def_rw("value", &TFloatObj::value, "float value field", refl::DefaultValue(10.0))
    .def("sub", [](const TFloatObj* self, double other) -> double { return self->value - other; })
    .def("add", &TFloatObj::Add, "add method");

TVM_FFI_REFLECTION_DEF(TIntObj)
    .def_ro("value", &TIntObj::value)
    .def_static("static_add", &TInt::StaticAdd, "static add method");

TVM_FFI_REFLECTION_DEF(TPrimExprObj)
    .def_ro("dtype", &TPrimExprObj::dtype, "dtype field", refl::DefaultValue("float"))
    .def_ro("value", &TPrimExprObj::value, "value field", refl::DefaultValue(0))
    .def("sub", [](TPrimExprObj* self, double other) -> double {
      // this is ok because TPrimExprObj is declared asmutable
      return self->value - other;
    });

This PR enhances and refactors the reflection module to support
nanobind/pybind style reflection definition.

This is one step to upgrade the overall reflection
mechanism in the project.
@tqchen tqchen merged commit 0f5bb20 into apache:main Jun 15, 2025
13 checks passed
@Johnson9009
Copy link
Contributor

Curious, why we will refactor the reflection implementation, there isn't any disagree, just want to know the motivation. For the new FFI's refactor, I think it will be faster (only provide cython solution) and powerful (Array), so does the future implementation of reflection will be performance better or something else? Thanks.

@tqchen
Copy link
Member Author

tqchen commented Jun 15, 2025

thanks @Johnson9009 for asking! there are several reasons, mostly better design, broader coverage and faster speed

  • It will be able to be more unified with the FFI system, for example have Any as a field in object (that is currently not supported)
  • Likely the new impl will be faster when accessing AST fields from the frontend as we will directly jump to getter of the field instead of running through runtime visitor
  • We can try to enable more type information so that can be used to generate type information in the python side.
  • API will align closer to standard experiences like nanobind/pybind

@Johnson9009
Copy link
Contributor

@tqchen Thanks for the explanation, for the cross language binding solution, In comparison with (ctypes, Cython more Python side), (pybind11, nanobind, boost, more C++ side), I love TVM's FFI more, we needn't write lots of glue code in C++ like pybind11, we just need decorate the Python side class to the Python part with the C++ part. If we need to do some process before the FFI call from Python to C++, we can write the process logic in Python directly, that so nice.

What I want to know is the future of reflection usage, does the usage of example will only replace the current reflection visitor? or the method binding will use the method instead of current packed function way?

@tqchen
Copy link
Member Author

tqchen commented Jun 16, 2025

great point, right now we plan to only replace reflection visitor.

The ffi::Function and other elements will be preserved and likely built on top with optional extra metadata.

Note that it is still ffi::Function under the hood, and python side decorator will be preserved, the method binding will allow us to expose private method funtions (x.__foo) for example, and write x.foo in python to call into x.__foo similar to the current way. We will also likely preserve the global function registration so if we want to choose to expose methods as global functions it will continue to work. I expect most code likely will be like this.

It will indeed allow full method decoration on c++ side with meta-data, so if user want to shift more to c++, e.g. writing x.foo completely in c++, that is also fine. But I agree doing more preprocessing in python in such case is good.

@Johnson9009
Copy link
Contributor

Got it, thanks.

ShiboXing pushed a commit to ShiboXing/tvm that referenced this pull request Aug 10, 2025
This PR enhances and refactors the reflection module to support
nanobind/pybind style reflection definition.

This is one step to upgrade the overall reflection
mechanism in the project.
tqchen added a commit to tqchen/tvm that referenced this pull request Sep 13, 2025
This PR enhances and refactors the reflection module to support
nanobind/pybind style reflection definition.

This is one step to upgrade the overall reflection
mechanism in the project.
tqchen added a commit to tqchen/tvm that referenced this pull request Sep 13, 2025
This PR enhances and refactors the reflection module to support
nanobind/pybind style reflection definition.

This is one step to upgrade the overall reflection
mechanism in the project.
tqchen added a commit to tqchen/tvm that referenced this pull request Sep 13, 2025
This PR enhances and refactors the reflection module to support
nanobind/pybind style reflection definition.

This is one step to upgrade the overall reflection
mechanism in the project.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants