## Summary
Update TVM to tvm-ffi's stable `TVMFFIAny`-backed Optional and Variant
layout.
- bump `3rdparty/tvm-ffi` from `84ee1a07` to `5411a642`
- migrate Optional presence checks from the removed inherited
`defined()` API
- adapt pointer, cast, JSON, and FFI return sites while preserving
missing-value semantics
- require `apache-tvm-ffi>=0.1.13` and preserve the source-matched FFI
build in the macOS wheel smoke test
## Validation
Validated with linked LLVM builds, default and conditional backend
compilation, an Emscripten 4.0.23 WebAssembly compile/link, C++
Optional/FFI and TVM suites, focused runtime/IR/Relax Python tests,
broad regression coverage, repository format/static checks, production
wheel metadata inspection, and an isolated source-FFI wheel
install/import smoke test.
## Release compatibility blocker
Do not merge or publish this bump until the tvm-ffi 0.1.13 release
preserves compatibility for TVM 0.25's by-value JSON `Stringify`
consumer, or an equivalent non-matching release/version strategy is in
place. The release also needs coordinated handling for the published
ORCJIT extension: `apache-tvm-ffi-orcjit==0.1.0` returns
`Optional<Function>` by value while the new layout grows from 8 to 16
bytes, which can corrupt return storage when mixed with the new runtime.
TVM's wheel now requires `apache-tvm-ffi>=0.1.13`; resolver-driven
publish tests remain enabled so production publication fails closed
until a compatible release exists.
In the past we have been using `DataType` in PrimExpr.dtype field to
check type information for PrimExpr while still having BaseExpr.ty for
richer type information. DataType is also used both in runtime and
compiler. This PR streamlines the boundary:
- PrimExpr.ty now carries PrimType that replaces original use of
`DataType`
- Runtime use will now favor DLPack DLDataType, removing one layer of
indirection.
- Constants attributes where values are usually runtime values, will use
`DLDataType`
- DataType will be phased out after this PR
We also brings up helper functions in PrimType, but also limits them to
a more concise set so the functions do not grow with the data type codes
in DLPack.
This is a major refactor that changes the IR primitive. It helps to
bring possible future benefits:
- Unified type mechanism through Expr.ty
- Possibility of carry future Type nodes
Migration Guide:
- Use `PrimType` when code reasons about compiler expression types,
tensor element compiler types, or constructs a `PrimExpr`/compiler type.
- Use existing source types such as `expr.ty()`, `ExprOp.expr_ty()`, or
TE tensor element `dtype` where possible instead of rebuilding a type
from dtype text.
- Use raw `DLDataType` for runtime constants, ABI paths, dtype-valued
attrs, and storage/runtime helper logic.
- Prefer direct `PrimType` equality, `MatchesCode(...)`,
`MatchesElementType(...)`, and `WithCode(...)` over local wrappers or
string dtype checks.
Performance:
Using Object type instead of DLDataType would indeed bring some
performance impact to the IR. We have done the following performance
optimizations:
- Make sure most of the outputs reuse one of the PrimType from inputs
- Cache a thread local PrimType based on input so we don't repeatly
realloc
We did benchmarks show that rewrite simplify operation stays within
+-10% overhead of original one. Which merits the refactor given the
benefit the unfication brings
This PR phases out the legacy `Downcast` helper and removes
`tvm/ir/cast.h`, replacing mandatory object casts with the strict
`as_or_throw` style APIs after bumping tvm-ffi to the latest fix.
The migration keeps nullable-object behavior explicit. Optional `Any`
conversions that need to preserve null use the nullable
`value_or(nullptr).as_or_throw<ffi::Optional<T>>()` pattern, while
simple mandatory casts use direct receivers such as
`obj.as_or_throw<T>()`.
Summary:
- Remove the Relax-specific PrimType node/API and use canonical
ir.PrimType for dtype-only scalar types.
- Update parser, printer, analysis, op inference/legalization, and tests
to avoid value-bearing PrimType semantics.
- Preserve scalar values where needed by reading PrimValue expressions
directly instead of storing values in the type.
## Summary
- unify Relax's former StructInfo surface into the Type vocabulary and
Expr.ty storage path
- remove leftover DependentTypeNode and legacy OpNode::op_type storage
- keep base Type nullable while concrete Relax/DTensor type refs are
non-nullable
- clean stale StructInfo/TensorStructInfo/sinfo vocabulary in
Python/docs and distributed-op macros
- address Gemini follow-ups for parser annotations, BlockBuilder
docstring, and Adreno TensorType cast audit
## Summary
Common bool, int32, and int64 scalar constants show up throughout TIRX
and related lowering code. Named constructors make these call sites
easier to read than repeated `DataType` spelling, and avoid routing
obvious scalar constants through the generic `MakeConst` helper.
## Usage guideline
Prefer direct `IntImm` or `FloatImm` construction when dtype is known to
be scalar integer or floating point. This makes the compiled code more
compact and efficient. Keep `MakeConst` for generic overload cases where
dtype can be integer, floating point, or vector-valued and the caller
needs its scalar/vector dispatch.
This PR establishes the scalar-constant construction policy:
- Prefer `IntImm::Bool`, `IntImm::Int32`, and `IntImm::Int64` for common
known scalar bool, int32, and int64 constants.
- Prefer direct `IntImm` or `FloatImm` construction when dtype is known
to be scalar integer or floating point.
- Keep `MakeConst` for generic overload cases where dtype can be
integer, floating point, or vector-valued and the caller needs its
scalar/vector dispatch.
- Phase out `make_zero` in favor of explicit scalar constructors, or
`ConstHandle(0)` for null handles.
## Changes
- Add `IntImm::Bool`, `IntImm::Int32`, and `IntImm::Int64` helpers.
- Rename `make_const` to `MakeConst` and document it as the
generic/vector construction helper.
- Migrate deterministic scalar constant construction to the clearer APIs
while keeping generic and vector-aware paths on `MakeConst`.
- Remove `make_zero`, `const_true`, `const_false`, and the unused
`tirx.const_true` registry entry.
## Background
`class Integer : public IntImm` and `class Bool : public IntImm` were
thin
wrappers sharing `IntImmNode` with no separate node class and no FFI
registration. They existed to provide implicit int→Integer constructors
and
a `.IntValue()` / `operator bool()` accessor, but the same functionality
is
available directly through `IntImm`.
## What this PR does
Migrates all call sites away from `Integer` / `Bool` and then deletes
the
class definitions. The changes are split into four commits, each
independently buildable:
**Commit 1 – [REFACTOR][TIR]** Replace IR-position `Integer(N)` /
`Bool(b)`
constructors with `IntImm(DataType::Int(32), N)` /
`IntImm(DataType::Bool(), b)`
across ~62 source files (arith, relax analysis, s_tir schedule state,
transform
passes, codegen).
**Commit 2 – [REFACTOR][SCHEDULE]** Migrate `Schedule` and
`MetaSchedule`
trace-boxing code: `Integer(N)` attrs in `TracedSchedule` →
`IntImm(DataType::Int(32), N)`;
`ffi::Array<Integer>` schedule-rule parameters → `int64_t`; `Bool(b)`
attrs →
`IntImm(DataType::Bool(), b)`.
**Commit 3 – [REFACTOR][TOPI]** Migrate topi container signatures
(`ffi::Array<Integer>` → `ffi::Array<int64_t>`) and update all internal
usages (`.IntValue()` → plain int64_t, `.defined()` → removed,
`->value` → direct indexing). Also handles stray `Integer` / `Bool`
variables in clml codegen, make_packed_api, infer_layout_utils, and
relax distributed code.
**Commit 4 – [REFACTOR][IR]** Delete `class Bool`, `class Integer`,
`TypeTraits<Bool>`, and `TypeTraits<Integer>` from
`include/tvm/ir/expr.h`.
## Canonical replacements
| Old | New |
|-----|-----|
| `Integer(N)` | `IntImm(DataType::Int(32), N)` |
| `Bool(b)` | `IntImm(DataType::Bool(), b)` |
| `x.IntValue()` | `x->value` |
| `x` as bool | `x->value != 0` |
| `ffi::Array<Integer>` | `ffi::Array<int64_t>` |
## Testing
- All 118 C++ unit tests pass (`./cpptest`)
- `tests/python/s_tir/` — 1251 passed (14 pre-existing failures
unrelated to this change, all in TIR transform tests with
annotation-mismatch errors)
- `tests/python/relax/` — passes (excluding pre-existing
torch/torchvision import failures in frontend tests)
## Summary
This PR adds the initial TIRx support needed for low-level programming
of Blackwell-class GPU architectures. As part of the ongoing TIRx
refactor, it introduces TVMScript support for directly scripting
advanced hardware features without relying on scheduling as the primary
programming interface.
The change keeps existing `s_tir` script support intact while making
direct scripting a first-class path for TIRx programs.
## Main Changes
- Add TIRx operator dispatch and layout infrastructure.
- Add TVMScript support for new low-level TIRx operations.
- Add analysis, transform, and lowering support for TIRx IR nodes.
- Add CUDA/Blackwell-oriented codegen and intrinsic coverage.
- Add Python and C++ integration points for TIRx scripting and runtime
support.
## Validation
- `pre-commit run --all-files`
- `ninja -C build -j32`
- `CUDA_VISIBLE_DEVICES=2 pytest tests/python/tirx/ -n 16`
- `1723 passed, 47 skipped, 32 warnings`
- `CUDA_VISIBLE_DEVICES=2 python -m pytest -v
tests/python/all-platform-minimal-test`
- `37 passed, 105 skipped`
- `TVM_TEST_TARGETS=llvm python -m pytest -v tests/python/tirx-analysis
tests/python/tirx-base tests/python/tirx-transform -n 16`
- `664 passed, 25 skipped, 9 xfailed, 1 xpassed`
## Local CI Notes
Some full CI-equivalent jobs were not locally reproducible because this
machine is missing parts of the Apache TVM CI environment, including
`llvm-config-15/17`, Vulkan, ROCm, Maven, Sphinx, Doxygen, Emscripten,
and ARM/QEMU cross-toolchain components. Metal-specific tests were
skipped locally because no Metal runtime is available.
## Summary
`include/tvm/node/` is a leftover separation from when "node" was a
distinct concept from "ir". Today everything in `include/tvm/node/` is
just lower-level IR plumbing routinely included from `ir/`. This PR
collapses the two by moving surviving headers into `ir/`, deleting dead
ones, and redirecting the rest to tvm-ffi where the machinery already
lives.
Main changes:
- Migrate
`include/tvm/node/{functor,cast,script_printer,attr_registry_map,repr}.h`
→ `include/tvm/ir/` (functor renamed to `node_functor.h` to preserve
type-name connection)
- Delete `repr_printer.h`, `structural_equal.h`, `structural_hash.h`
(post-#19461 shims and forwarding stubs; redirect 3 cpptest consumers to
`tvm/ffi/extra/structural_equal.h`)
- Remove inline `AccessStep`/`AccessPath` `operator<<` definitions
(existing `__ffi_repr__` registrations already cover these; migrate to
generic ObjectRef streaming via kRepr)
- Move `src/node/{repr,script_printer}.cc` → `src/ir/`
- Delete `src/node/` and empty `include/tvm/node/` directories entirely
(no shims)
- Update 35 includers across IR, relax, script, target, tirx, and tests
This PR brings up the tirx namespace. We have been spliting out the
original tir namespace to include high-level component s_tir and this PR
updates the remaining low-level part as tirx namespace
* [FFI][REFACTOR] Cleanup namespace
This PR cleansup the namespace to ensure all ffi classes
are accessed through ffi:: namespace.
It will helps to cleanup the ffi package before isolation.
* fix hexagon
This PR cleans up the container redirections and headers
so the files directly points to new ones in ffi folder
- runtime/shape_tuple.h => ffi/container/shape.h
- for IntTuple alias, introduce runtime/int_tuple.h for now
- runtime/container/array.h => ffi/container/array.h
- runtime/container/map.h => ffi/container/map.h
- runtime/container/optional.h => ffi/optional.h
- runtime/container/string.h => ffi/string.h
- runtime/container/variant.h => ffi/container/variant.h
- runtime/container/tuple.h => ffi/container/tuple.h
We also introduce limited number of tvm::ffi classes into tvm namespace,
when they are commonly used and their is no ambiguity.
This PR modernizes the FFI foundation of the project and introduce
a new minimal and lightweight module [tvm ffi](https://github.com/apache/tvm/tree/refactor-s3/ffi)
based on our lessons in the past few years. It implements a modern
version of the [Unified Packed and Object RFC](https://github.com/apache/tvm-rfcs/blob/main/rfcs/0097-unify-packed-and-object.md)
that unifies the packed function call and object systems.
Summary of the change:
- A dedicated clean Any/AnyView that can store strong and weak
references of items
- Function(previously PackedFunc) system built on top of the Any/AnyView
- A minimal C API that backs the overall calls. We are stabilizing the
API with a goal to bring clean, stable FFI conventions for both compiled
and registered code
- A rewrite of core python binding and generated code based on the module
- Update existing code and test cases to the new module
- Latest dlpack support
The new module brings many benefits thanks to the cleaner design,
to name a few:
- Any can support both POD types(int) and object types.
- Containers (e.g. Array) can now also contain Any value, e.g. now
`Array<int>` is supported, no need for boxed types
- Error handling now upgrades to object-based, allowing cleaner
traceback across languages
- Map now preserves insertion orders
- Path toward isolated stabilize minimum core ABI/API foundation module
- Type traits based design that cleanly defines how values interact
with Any system
- Automatic conversion of different types based on traits if needed
Because FFI upgrade is at heart of the project, the change touches every
component of the system. Importantly, this is an upgrade of the ABI so the
change is not backward compatible. The code compiled under the old
FFI won't work under the new one. We did provide example ABI translation
(e.g. LegacyTVMArgValueToFFIAny) functions for compatibility.
The PR tries to leave files in their old places while creating redirections.
The goal is to have the first milestone landed and infrastructure in place,
so we can do further refactors to complete features and cleanup legacy code
as trackable PRs. As of now, python binding and compiled code are under the
new convention while RPC and some other bindings still relies on legacy ABI
translation. We will work on upgrades in the coming PRs, including areas such
as reflection, phasing out legacy redirections etc.
* cleanup relay c++
* [REFACTOR] Phase out relay c++ components
This PR phases out the relay C++ components and
simplifies the overall codegen runtime logic.
---------
Co-authored-by: Siyuan Feng <hzfengsy@sjtu.edu.cn>
This PR introduce NestedMsg to robustly handle nested-tuple analysis.
Relax support nested tuple structures in the IR.
Nested tuple structure is important to support advanced groupings in
cases such as gradient calculation and other scenarios.
The possible presence of nested tuple does mean that we need to to
robustly handle analysis that contains nested tuple structures in a dataflow graph.
This PR introduces a NestedMsg<T> class that corresponds to a possibly
nested message tuple for a given leaf message class T.
We also introduces various helper functions to compose and decompose messages.
Co-authored-by: Bohan Hou <32121147+spectrometerHBH@users.noreply.github.com>
Co-authored-by: Yixin Dong <ubospica@gmail.com>
Co-authored-by: Ruihang Lai <ruihangl@cs.cmu.edu>