This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new 20f0df6a [FEAT] Add optional in-place permission to default structural
descent (#781)
20f0df6a is described below
commit 20f0df6a38c1489cd035cf9702d533304c81bf96
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Sep 13 13:10:48 2026 -0400
[FEAT] Add optional in-place permission to default structural descent (#781)
Add optional `bool allow_inplace = true` to
`StructuralMutatorObj::DefaultMaybeInplaceMutateExpected` so callbacks
can forward their permission directly. False delegates to
`DefaultMutateExpected`; true and omission preserve the existing
behavior and ownership preconditions. Document the helper and simplify
an existing callback.
Validation: Debug C++ build, 69 existing structural tests, and
changed-file checks passed.
---
include/tvm/ffi/extra/structural_mutate.h | 15 ++++++++++++---
tests/cpp/extra/test_structural_mutate.cc | 3 +--
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/include/tvm/ffi/extra/structural_mutate.h
b/include/tvm/ffi/extra/structural_mutate.h
index 601d1bc6..06384b27 100644
--- a/include/tvm/ffi/extra/structural_mutate.h
+++ b/include/tvm/ffi/extra/structural_mutate.h
@@ -497,19 +497,28 @@ class StructuralMutatorObj : public Object {
}
/*!
- * \brief Apply custom maybe-in-place mutation, or fall back to non-in-place
mutation.
+ * \brief Apply default structural mutation with optional in-place
permission.
*
* \param value The borrowed value to mutate.
+ * \param allow_inplace Whether in-place mutation is permitted. Defaults to
true.
+ * If false, call \ref DefaultMutateExpected.
* \return The replacement or unchanged marker, or an Error if mutation
failed. In-place
* changes completed before an Error are not rolled back.
*
* \note In-place mutation is explicitly opt-in. A registered
* ``__s_maybe_inplace_mutate__`` hook may rely on its input being
safe to mutate and owns
* any variable-remap handling. When the hook is absent, this method
calls
- * \ref DefaultMutateExpected.
+ * \ref DefaultMutateExpected. This method does not check uniqueness.
When
+ * \p allow_inplace is true, the caller must already know that mutating
+ * \p value in place is safe, including ownership of the path from the
root.
+ *
+ * \code
+ * return mutator->DefaultMaybeInplaceMutateExpected(value, allow_inplace);
+ * \endcode
*/
TVM_FFI_INLINE Expected<UnchangedOr<Any>> DefaultMaybeInplaceMutateExpected(
- AnyView value) noexcept {
+ AnyView value, bool allow_inplace = true) noexcept {
+ if (!allow_inplace) return DefaultMutateExpected(value);
return details::ExpectedUnsafe::MoveFromTVMFFIAny<UnchangedOr<Any>>(
DefaultMaybeInplaceMutateRaw(value));
}
diff --git a/tests/cpp/extra/test_structural_mutate.cc
b/tests/cpp/extra/test_structural_mutate.cc
index 2866d1ca..5024613e 100644
--- a/tests/cpp/extra/test_structural_mutate.cc
+++ b/tests/cpp/extra/test_structural_mutate.cc
@@ -547,8 +547,7 @@ TEST(StructuralMutate,
CallbackArityControlsInplaceMutation) {
[&](const AnyArray& value, StructuralMutatorObj* mutator,
bool allow_inplace) -> Expected<Any> {
allow_inplace_trace.push_back(allow_inplace);
- return allow_inplace ?
mutator->DefaultMaybeInplaceMutateExpected(value)
- : mutator->DefaultMutateExpected(value);
+ return mutator->DefaultMaybeInplaceMutateExpected(value,
allow_inplace);
},
[&](int64_t value, StructuralMutatorObj*, bool allow_inplace) ->
Expected<Any> {
allow_inplace_trace.push_back(allow_inplace);