[FEAT] Add structural map, maybe_inplace_mutate, and var_remap APIs - #649
[FEAT] Add structural map, maybe_inplace_mutate, and var_remap APIs#649Kathryn-cat wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the StructuralMapper and StructuralMapperObj APIs in include/tvm/ffi/extra/structural_map.h to support structural mapping and in-place mutation of object-backed values. It also adds corresponding custom hooks (kStructuralMap and kStructuralInplaceMutate), registers test leaf objects, and includes comprehensive unit tests. The review feedback suggests two minor optimizations in structural_map.h: avoiding a const_cast when obtaining the field address, and reusing the calculated field address instead of recalculating it for the field setter.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
2d1fe02 to
94ef772
Compare
d407312 to
a72586a
Compare
1fa228c to
994c4f7
Compare
d635d50 to
5768af7
Compare
9858fd5 to
a86c5cf
Compare
ee20d47 to
9952e82
Compare
10276ce to
6b570b3
Compare
7b68f08 to
41290ae
Compare
|
One thing that worth double click on is var remapping handling when callback also presence. In an ideal case, the logic should be like follows:
To keep things consistent with structural hash, we can turn on the remapping for both This allows node being declared as DAG node also being mapped once on first occurance. |
a56ddb2 to
0f1e3d0
Compare
7c72b79 to
d334962
Compare
| Dispatch dispatch_; | ||
|
|
||
| /*! \brief Identity-substitution table. */ | ||
| Map<ObjectRef, Any> var_remap_; |
There was a problem hiding this comment.
var_remap_ should use object identity, but ffi::Map may treat different freevars as the same key, likely the second freevar may reuse the first's mapping
There was a problem hiding this comment.
This is fine given the assumption that var is defined once
tqchen
left a comment
There was a problem hiding this comment.
Comment on simplifying the str/bytes handling
c84d842 to
a20815a
Compare
0204164 to
67497fa
Compare
Summary
This PR adds structural transformation support to TVM FFI, complementing the existing structural equality, hashing, and walking APIs.
The new
StructuralMutatorrecursively transforms reflected object graphs, whilestructural_mapprovides a convenient callback-based interface for compiler passes.Structural mapping
structural_mapfollows the same typed callback model asstructural_walk. Callbacks are matched by runtime type and return either the unchanged value or a replacement.Mapping defaults to post-order, so callbacks observe values whose children have already been transformed. This makes bottom-up rewrites such as constant folding straightforward:
The PR exposes:
StructuralMutator
StructuralMutatorprovides the low-level transformation engine through two operations:Mutatetransforms a value without intentionally modifying the input.MaybeInplaceMutatepermits implementations to reuse an object when doing so is safe.Custom mutation behavior
Object types can customize mutation using:
__s_mutate__for canonical non-in-place transformation.__s_maybe_inplace_mutate__for an optional type-specific in-place optimization.The maybe-in-place hook owns its safety policy and may reuse the input, delegate to normal mutation, or return another value. A type providing it must also provide
__s_mutate__.Built-in hooks are registered for Array, List, Map, and Dict.
Variable identity remapping
The mutator maintains an identity-substitution environment for FreeVar objects. Once an identity is mapped, later occurrences reuse the same result.
For example:
If the same
Varoccurs in a function parameter and its body, both occurrences resolve to the same mapped result.The mutator also exposes
get_var_remapandset_var_remap, allowing custom DAG-style variable wrappers to use their underlying identity object as the remapping key.