10 Commits

Author SHA1 Message Date
Tianqi Chen c717c5b217 [IR][Relax][TIRx] Unify Var identity (#20004) 2026-07-15 17:12:40 +08:00
Tianqi Chen 275114b327 [REFACTOR][IR] Unify PrimExpr with Expr typed view (#19910)
## Summary
- Make `PrimExpr` a typed C++ view over `Expr` values whose
`ExprNode::ty` is `PrimType`, instead of using a separate runtime node
class as the proof of primitive-ness.
- Use the shared `ir::Call` node for Relax, TIRX, and primitive-valued
calls, while keeping primitive-only APIs explicit at their semantic
boundaries.
- Keep Python on the general `Expr` surface for primitive-typed values
so `isinstance` behavior does not imply a nominal primitive-expression
subclass.

## Design Rationale
The main advantage of this change is that common expression nodes such
as `Call` can be unified without specializing each one to `PrimType`. A
single `ir::Call` can represent a Relax tensor call, a Relax scalar
call, or a primitive-valued intrinsic call; the result type stored in
`ExprNode::ty` determines whether that particular value can be viewed as
`PrimExpr`.

This keeps the IR node hierarchy focused on expression structure rather
than result-type categories. Nodes that are intrinsically primitive,
such as integer and floating-point literals or TIRX primitive operators,
still have strongly typed C++ APIs and data structures. General nodes
whose result type may vary, such as `Call`, remain general `Expr` nodes
and are narrowed to `PrimExpr` only where primitive-only semantics are
required.

The PR also keeps the compatibility surface practical: C++
primitive-only APIs continue to accept `PrimExpr`, Python exposes a
compatibility predicate for checking the primitive typed category, and
visitors/printers use one natural `Call` path rather than duplicating
Relax and primitive call handling. Missing expression types are
represented explicitly with `Type::Missing()` so constructors can leave
type inference to later analysis without relying on nullable `Type`
values.
2026-07-01 18:55:33 -04:00
Tianqi Chen e43555f739 [REFACTOR][DataType] Phase out target custom datatype support (#19760)
## Summary

The in-tree target custom datatype path adds maintenance surface while
current development focuses on core datatypes. This PR phases out the
built-in registry/lowering implementation and keeps the core dtype
behavior intact.

- Remove the target/datatype implementation, BYODT posit build option,
and related Python helpers
- Remove the custom datatype lowering pass from TIRX and S-TIR
finalization pipelines
- Simplify remaining TIRX dtype handling back to built-in/core datatypes
2026-06-14 09:11:13 -04:00
Bohan Hou bb6f8aec55 [TIRx] Post-bringup follow-ups: op-dispatch, namespaces, launch bounds, gemm-async, backend reorg (#19757)
This PR batches several post-bringup TIRx follow-ups, rebased onto
current `main`.

### Changes
- **op-dispatch**: per-call exec scope via `Tx.<scope>.op`; remove
`ExecScopeStmt`
- **namespaces**: split TIRx op namespaces; remove tile-primitive kind
attrs
- **codegen**: support explicit CUDA launch bounds
- **gemm-async**: support contiguous-axis (K-major) operand slicing
- **backend reorg**: move in-tree GPU backends out of core into
`src/backend/<target>/` and `python/tvm/backend/<target>/`
(codegen/runtime/op), with the corresponding `CMakeLists.txt` /
`cmake/modules` and include-path updates

### Testing
- Builds with `USE_CUDA=ON` / `USE_LLVM=ON`
- The TIRx Python test suite (`tests/python/tirx/`) passes locally
2026-06-13 21:12:40 -04:00
Tianqi Chen 08af2cd3b4 [REFACTOR][PYTHON] Remove tvm.ffi shim; import tvm_ffi directly (#19721)
`python/tvm/ffi.py` was a thin `from tvm_ffi import *` redirect. This
removes it and imports `tvm_ffi` directly at the single use site.
2026-06-10 17:25:46 -04:00
Tianqi Chen dea2bf933e [REFACTOR][TIRX] Consolidate split host device stages (#19663)
The host/device split flow already runs device-region annotation,
host/device function extraction, and device-kernel launch lowering as
one consecutive pipeline. Keeping those stages exposed as separate
public passes makes the API surface larger than the actual execution
model and leaves the stage dependencies spread across multiple files.

This change makes `tirx.transform.SplitHostDevice` the single public
entry point for that flow, while preserving the existing stage order
internally.

Changes:
- Merge the annotation, splitting, and kernel-launch lowering
implementations into `src/tirx/transform/split_host_device.cc` as
private sections.
- Remove the old public C++ declarations, FFI registrations, and Python
wrappers for `AnnotateDeviceRegions` and `LowerDeviceKernelLaunch`.
- Replace pipeline call sites that previously invoked the three-stage
sequence with one `SplitHostDevice()` call.
- Update TIRx and S-TIR tests to exercise the consolidated pass and the
reduced public API surface.
2026-06-03 15:57:57 -04:00
Tianqi Chen 02b130249c [REFACTOR][TIR][ARITH] Phase out ControlFlowGraph, NarrowPredicateExpression, and rename Simplify to StmtSimplify (#19604)
## Summary

This PR cleans up technical debt in the TIR simplification machinery via
two commits:

**Commit 1: Phase out ControlFlowGraph and NarrowPredicateExpression**

- Remove `ControlFlowGraph` (~2360 lines) from `src/tirx/analysis/` —
used only in
  non-default config paths that are no longer maintained
- Remove `NarrowPredicateExpression` from `src/arith/` — sole non-test
caller was `ControlFlowGraph`
- Remove gated config fields `propagate_knowns_to_prove_conditional` and
  `propagate_knowns_to_simplify_expressions` from `SimplifyConfig`
- Remove `use_dataflow_analysis` from `RemoveNoOpConfig`
- Delete the associated test files and test cases that tested the
now-removed paths
- ~3800 lines deleted

**Commit 2: Rename Simplify → StmtSimplify**

- Rename `src/tirx/transform/simplify.{h,cc}` → `stmt_simplify.{h,cc}`
- Rename C++ identifiers: `Simplify` → `StmtSimplify`, `SimplifyConfig`
→ `StmtSimplifyConfig`
- Rename FFI keys: `"tirx.Simplify"` → `"tirx.StmtSimplify"`,
`"tirx.transform.Simplify"` → `"tirx.transform.StmtSimplify"`
- Update Python wrappers and all call sites (~40 files)
- Clarifies that this pass operates on statements (distinct from
expression-level `arith::Analyzer::Simplify()`)

## Test plan

- [x] `tests/python/tirx-transform/test_tir_transform_simplify.py` — 52
tests pass
- [x] `tests/python/tirx-transform/test_tir_transform_remove_no_op.py` —
18 pass, 5 xfail
- [x] `tests/python/arith/` — full arith test suite passes
- [x] `tests/python/tirx-transform/` — full suite: 315 passed, 8
xfailed, 1 xpassed (pre-existing vectorize failure unrelated to this
change)
- [x] `pre-commit run --all-files` — all hooks pass
2026-05-26 15:33:40 -04:00
Tianqi Chen b1e1566f82 [REFACTOR][IR] Cleanup attrs.h: drop NullValue, AttrsNodeReflAdapter, legacy BaseAttrsNode methods (#19607)
## Overview

This PR cleans up `include/tvm/ir/attrs.h` by removing four deprecated
abstractions:

1. `NullValue<T>()` sentinel helpers (replaced by `ffi::Optional<T>`)
2. `AttrsNodeReflAdapter<DerivedType>` shim template (Attrs structs now
inherit `BaseAttrsNode` directly)
3. `BaseAttrsNode::InitBySeq` / `InitByPackedArgs` legacy initialization
methods
4. `DictAttrsNode::InitByPackedArgs` override

It also migrates 9 pass-config classes from
`Attrs`/`AttrsNodeReflAdapter` to `ffi::Object`, since they are pass
configuration objects, not IR attributes.

## Changes

**Commit A — Replace NullValue<T>() call sites** (`[REFACTOR][IR]
Replace NullValue<T>() call sites with default construction`)
- 11 source files: replace `NullValue<T>()` with `T()`, `std::nullopt`,
or `DataType::Void()`
- `manipulate.h`/`manipulate.cc`: `FlipAttrs::axis` changed from
`Integer` to `ffi::Optional<int64_t>`

**Commit B — Drop NullValue, AttrsNodeReflAdapter, legacy BaseAttrsNode
methods** (`[REFACTOR][IR] Drop NullValue declaration,
AttrsNodeReflAdapter, BaseAttrsNode legacy methods`)
- `include/tvm/ir/attrs.h`: removes `NullValue<T>`, `InitBySeq`,
`InitByPackedArgs`, `AttrsNodeReflAdapter<T>`
- `src/ir/attrs.cc`: removes `DictAttrsNode::InitByPackedArgs`
definition
- `AttrsWithDefaultValues<T>()` broadened to accept any `ffi::ObjectRef`
subtype (needed for Commit D)
- Removes unused includes: `reflection/accessor.h`, `<functional>`,
`<vector>`

**Commit C — Subclass BaseAttrsNode directly** (`[REFACTOR][IR] Subclass
BaseAttrsNode directly, drop AttrsNodeReflAdapter`)
- 17 attrs headers in `include/tvm/relax/attrs/` +
`include/tvm/target/virtual_device.h`
- All `struct FooAttrs : public AttrsNodeReflAdapter<FooAttrs>` →
`struct FooAttrs : public BaseAttrsNode`

**Commit D — Migrate pass-config classes to ffi::Object** (`[REFACTOR]
Migrate pass-config classes to subclass ffi::Object`)
- 9 pass-config classes in `src/s_tir/`, `src/tirx/`,
`src/relax/backend/contrib/`
- `XConfigNode : public ffi::Object` (was
`AttrsNodeReflAdapter<XConfigNode>`)
- `XConfig : public ffi::ObjectRef` (was `Attrs`)
- Python bindings updated: 7 classes changed from `_ir.Attrs` to
`_ffi.Object`

## Design Decisions

**`AttrFieldInfo` / `OpNode::arguments` kept**: Pre-flight check
revealed `GetArgStructInfo()` in `op_common.h` and `op_common.cc`
actively reads `op->arguments` (names, counts). These were not dead
metadata — deleting them would break Relax op argument validation. They
are kept as-is.

**Commit E (trim attrs.h includes) reduced in scope**: Removing
`structural_equal.h`, `structural_hash.h`, and `<unordered_map>` from
`attrs.h` caused 47 downstream files to fail compilation. Rather than
adding explicit includes to 47 files, only clearly-unused includes
(`reflection/accessor.h`, `<functional>`, `<vector>`) were removed in
Commit B.

## Testing

- Build: clean compile with `-DUSE_CUDA=OFF -DUSE_LLVM=ON`
- Tests passing:
  - `tests/python/ir/` (93 passed)
- `tests/python/relax/test_analysis.py`, `test_blockbuilder_core.py`,
`test_op_manipulate.py`, `test_transform.py` (209 passed)
- `tests/python/s_tir/transform/test_s_tir_transform_loop_partition.py`,
`test_s_tir_transform_unify_thread_binding.py` (30 passed)
- `tests/python/tirx-transform/test_tir_transform_unroll_loop.py`,
`test_tir_transform_simplify.py`, `test_tir_transform_remove_no_op.py`
(108 passed, 6 xfailed)
- Pre-existing failures (unrelated to this PR):
`test_s_tir_transform_lower_opaque_block`,
`test_s_tir_transform_compact_buffer_region::TestLetBinding::test_compact`,
`test_tir_transform_vectorize::test_vectorize_llvm_pure_intrin_fail`
2026-05-26 10:03:17 -04:00
Bohan Hou 859498dc01 [TIRx] Bringup TIRx Infrastructure (#19581)
## 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.
2026-05-18 16:44:43 -07:00
Tianqi Chen 141c22fd8a [Refactor] Bring up tirx namespace (#18913)
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
2026-03-19 21:27:54 -07:00