You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by tq...@apache.org on 2026/10/16 20:55:21 UTC
(tvm) branch tirx-standalone-root updated (40c5620ac4 -> 6a4f354cf4)
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a change to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
discard 40c5620ac4 [DOCS] Add standalone TIRx Python API scaffold
discard 1c423e35b7 [CI] Add standalone TIRx build, wheel, and docs pipelines
discard 6052c04140 [LINT] Add standalone TIRx lint configuration
discard 0bd0fbf0af [META] Add repository ignore rules and release keys
discard 38f24bcd89 [META] Add ASF configuration and standalone FFI submodule mapping
discard f9efc0853f [REFACTOR] Make standalone TIRx the repository root
new 96e7e85dc7 [BUILD] Enable LLVM and automatic CUDA in standalone TIRx (#20755)
new 69215634db [REFACTOR][TIRx] Align public APIs and package boundaries (#20759)
new 52441cdf2b [FIX][Sym] Reject non-positive divisors in iter map floordiv/floormod (#20756)
new 341e3fd7f5 [REFACTOR] Separate TIRx compiler and runtime deployment APIs (#20763)
new 8a10be0a14 [TIRx] Clarify overload sets, leaf ownership, and terminal throws (#20765)
new 80d645d824 [TIRx] Simplify Python APIs and configuration discovery (#20766)
new 54a62ddf4b [REFACTOR] Make standalone TIRx the repository root
new 9a242ed23e [META] Add ASF configuration and standalone FFI submodule mapping
new b2e6e56471 [META] Add repository ignore rules and release keys
new eef005bf30 [LINT] Add standalone TIRx lint configuration
new 8bfc5bd764 [CI] Add standalone TIRx build, wheel, and docs pipelines
new 6a4f354cf4 [DOCS] Add standalone TIRx Python API scaffold
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (40c5620ac4)
\
N -- N -- N refs/heads/tirx-standalone-root (6a4f354cf4)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 12 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.github/actions/build-wheel-for-publish/action.yml | 2 +-
.github/workflows/main.yml | 4 +-
.gitignore | 2 +-
CMakeLists.txt | 45 ++-
cmake/modules/CUDA.cmake | 24 +-
cmake/modules/ClangFlags.cmake | 2 +-
cmake/modules/Logging.cmake | 4 +-
docs/conf.py => cmake/tvm-tirx-config.in | 15 +-
cmake/tvm_tirx-config.cmake | 6 +-
cmake/utils/FindLLVM.cmake | 11 +-
docs/reference/python/index.rst | 9 +-
include/tvm/backend/cuda/attr.h | 20 +-
include/tvm/backend/cuda/op/iket.h | 17 +-
include/tvm/backend/cuda/op_attr_types.h | 5 +-
include/tvm/codegen/codegen.h | 6 +-
include/tvm/codegen/intrin_rule.h | 5 +-
include/tvm/ir/attrs.h | 2 +-
include/tvm/ir/expr.h | 2 +-
include/tvm/ir/location.h | 79 +---
include/tvm/ir/module.h | 26 +-
include/tvm/ir/prim/op.h | 2 +-
include/tvm/ir/transform.h | 7 +-
include/tvm/ir/with_context.h | 2 +-
include/tvm/runtime/base.h | 8 +-
include/tvm/runtime/c_backend_api.h | 9 +-
include/tvm/runtime/device_api.h | 8 +-
include/tvm/runtime/memory_scope.h | 17 +-
include/tvm/runtime/tensor.h | 106 +-----
include/tvm/runtime/timer.h | 120 +------
include/tvm/script/ir_builder/base.h | 4 +
include/tvm/script/ir_builder/frame.h | 21 +-
include/tvm/script/ir_builder/ir.h | 4 +
include/tvm/script/printer/doc.h | 4 +
include/tvm/script/printer/doc_translator.h | 5 +
include/tvm/support/base64.h | 302 ----------------
include/tvm/support/bytes_io.h | 2 +-
include/tvm/support/cuda/nvtx.h | 71 ----
include/tvm/support/env.h | 2 +-
include/tvm/support/ordered_map.h | 2 +-
include/tvm/support/str_escape.h | 123 -------
include/tvm/sym/bound.h | 25 +-
include/tvm/sym/int_set.h | 31 +-
include/tvm/target/target.h | 6 +-
include/tvm/target/target_kind.h | 11 +-
include/tvm/tirx/analysis.h | 21 +-
include/tvm/tirx/function.h | 20 +-
include/tvm/tirx/index_map.h | 6 +-
include/tvm/tirx/layout.h | 3 -
include/tvm/tirx/op/memory.h | 10 +-
include/tvm/tirx/op/region.h | 3 +-
include/tvm/tirx/op_attr_types.h | 10 +-
include/tvm/tirx/script/ir_builder/frame.h | 20 +-
include/tvm/tirx/script/ir_builder/ir.h | 89 +----
include/tvm/tirx/stmt.h | 10 +-
include/tvm/tirx/stmt_functor.h | 2 +-
include/tvm/tirx/tile/context.h | 5 +-
include/tvm/tirx/tile/dispatch.h | 5 +-
include/tvm/tirx/tile/op.h | 5 +-
include/tvm/tirx/tile/thread_scope.h | 5 +-
include/tvm/tirx/transform.h | 6 +-
pyproject.toml | 8 +-
python/tvm_tirx/__init__.py | 31 +-
python/tvm_tirx/backend/cuda/codegen/registry.py | 26 +-
python/tvm_tirx/backend/cuda/codegen/schema.py | 6 +-
python/tvm_tirx/backend/cuda/cpp/asm.py | 40 +--
python/tvm_tirx/backend/cuda/cpp/builtins.py | 86 ++---
python/tvm_tirx/backend/cuda/cpp/descriptors.py | 12 +-
python/tvm_tirx/backend/cuda/cpp/instrument.py | 14 +-
python/tvm_tirx/backend/cuda/cpp/nvshmem.py | 6 +-
python/tvm_tirx/backend/cuda/iket.py | 2 +-
python/tvm_tirx/backend/cuda/lang/pipeline.py | 2 +-
python/tvm_tirx/backend/cuda/launch/_impl.py | 2 +-
python/tvm_tirx/backend/cuda/op.py | 112 +++---
python/tvm_tirx/backend/cuda/ptx/engine.py | 20 +-
python/tvm_tirx/backend/cuda/ptx/gen_stubs.py | 6 +-
python/tvm_tirx/backend/cuda/script.py | 48 +--
.../backend/cuda/tile/patterns/async_copy.py | 10 +-
.../tvm_tirx/backend/cuda/tile/patterns/common.py | 5 +-
.../backend/cuda/tile/patterns/descriptors.py | 9 +-
.../backend/cuda/tile/patterns/tcgen05_mma.py | 8 +-
python/tvm_tirx/backend/cuda/tile/patterns/tma.py | 14 +-
python/tvm_tirx/backend/metal/op.py | 15 +-
python/tvm_tirx/backend/metal/target_tags.py | 4 +-
python/tvm_tirx/backend/trn/tile/binary/default.py | 3 +-
python/tvm_tirx/backend/trn/tile/binary/utils.py | 3 +-
.../backend/trn/tile/instruction_generator.py | 4 +-
python/tvm_tirx/backend/trn/tile/private_alloc.py | 4 +-
python/tvm_tirx/backend/trn/tile/select/default.py | 4 +-
python/tvm_tirx/backend/trn/tile/unary/default.py | 3 +-
python/tvm_tirx/backend/trn/tile/unary/utils.py | 3 +-
.../backend/trn/transform/naive_allocator.py | 3 +-
python/tvm_tirx/base.py | 8 +-
python/tvm_tirx/codegen/__init__.py | 68 ++++
.../{runtime/module.py => codegen/executable.py} | 351 +++++-------------
python/tvm_tirx/{codegen.py => codegen/llvm.py} | 72 +---
python/tvm_tirx/config.py | 211 ++++++-----
python/tvm_tirx/error.py | 126 -------
python/tvm_tirx/ir/__init__.py | 3 +
python/tvm_tirx/ir/_overload_prim_expr.py | 2 +-
python/tvm_tirx/ir/attrs.py | 38 +-
python/tvm_tirx/ir/base.py | 4 -
python/tvm_tirx/ir/expr.py | 114 +++++-
python/tvm_tirx/ir/function.py | 7 +-
python/tvm_tirx/ir/json_compact.py | 64 ----
python/tvm_tirx/ir/location.py | 8 +-
python/tvm_tirx/ir/module.py | 38 +-
python/tvm_tirx/ir/op.py | 234 ++++++------
python/tvm_tirx/ir/prim/__init__.py | 6 +-
python/tvm_tirx/ir/prim/expr.py | 171 +--------
python/tvm_tirx/ir/prim/op.py | 96 ++---
python/tvm_tirx/ir/prim/vector_expr.py | 109 ++++++
python/tvm_tirx/ir/stmt.py | 12 +-
python/tvm_tirx/ir/type.py | 7 +-
.../ir/{supply.py => unique_name_supply.py} | 0
python/tvm_tirx/libinfo.py | 149 +++++++-
python/tvm_tirx/runtime/__init__.py | 43 ++-
python/tvm_tirx/runtime/_tensor.py | 10 +-
python/tvm_tirx/runtime/device.py | 19 +-
python/tvm_tirx/runtime/executable.py | 175 ---------
python/tvm_tirx/script/ir_builder/_ffi_api.py | 22 --
python/tvm_tirx/script/ir_builder/frame.py | 14 +-
python/tvm_tirx/script/ir_builder/stmt.py | 3 +-
python/tvm_tirx/script/printer/doc.py | 2 +-
python/tvm_tirx/script/tirx.pyi | 2 +-
python/tvm_tirx/support/cc.py | 6 +-
python/tvm_tirx/support/clang.py | 2 +-
python/tvm_tirx/support/ndk.py | 4 +-
python/tvm_tirx/support/rocm.py | 2 +-
python/tvm_tirx/sym/analyzer.py | 2 +-
python/tvm_tirx/sym/bound.py | 2 +-
python/tvm_tirx/sym/int_set.py | 10 +-
python/tvm_tirx/sym/iter_affine_map.py | 18 +-
python/tvm_tirx/sym/utils.py | 2 +-
python/tvm_tirx/target/intrin.py | 81 -----
python/tvm_tirx/target/target.py | 14 +-
python/tvm_tirx/testing/env.py | 8 +-
python/tvm_tirx/tirx/__init__.py | 10 +-
python/tvm_tirx/tirx/_compile.py | 4 +-
python/tvm_tirx/tirx/_tensor_view.py | 8 +-
python/tvm_tirx/tirx/analysis/analysis.py | 2 +-
python/tvm_tirx/tirx/backend/__init__.py | 17 -
python/tvm_tirx/tirx/expr.py | 39 --
python/tvm_tirx/tirx/function.py | 297 +--------------
python/tvm_tirx/tirx/{function.py => index_map.py} | 169 +--------
python/tvm_tirx/tirx/layout.py | 5 +-
python/tvm_tirx/tirx/op/__init__.py | 249 +++++--------
python/tvm_tirx/tirx/script/ir_builder/frame.py | 7 -
python/tvm_tirx/tirx/script/ir_builder/ir.py | 19 +-
python/tvm_tirx/tirx/script/ir_builder/op.py | 53 ++-
.../tirx/script/ir_builder/parser_protocol.py | 67 ++--
python/tvm_tirx/tirx/script/ir_builder/triton.py | 3 +-
python/tvm_tirx/tirx/tile/instruction.py | 6 +-
src/backend/cuda/codegen/codegen_cuda_host.cc | 2 +
src/backend/cuda/runtime/cuda_device_api.cc | 2 +-
src/backend/cuda/transforms/bind_backend_config.cc | 6 +-
src/backend/cuda/transforms/lower_iket.cc | 7 +-
src/backend/metal/runtime/metal_device_api.mm | 2 +-
src/backend/opencl/runtime/opencl_common.h | 2 +-
src/backend/rocm/runtime/rocm_device_api.cc | 2 +-
src/backend/vulkan/runtime/vulkan_timer.h | 2 +-
src/codegen/c/codegen_c.h | 1 +
src/codegen/c/codegen_c_host.cc | 13 +-
src/codegen/llvm/codegen_cpu.cc | 3 +-
src/codegen/llvm/codegen_llvm.h | 1 +
src/codegen/llvm/codegen_x86_64.cc | 2 +
src/ir/attrs.cc | 5 -
src/ir/env_func.cc | 13 +-
src/ir/expr.cc | 30 +-
src/ir/function.cc | 1 -
src/ir/location.cc | 70 ----
src/ir/module.cc | 49 ++-
src/ir/op.cc | 12 +-
src/ir/prim/math.cc | 1 +
src/ir/prim/op.cc | 15 +-
src/ir/type.cc | 1 -
src/runtime/device_api.cc | 56 +--
src/runtime/tensor.cc | 116 ++++--
src/runtime/timer.cc | 276 --------------
src/script/ir_builder/frame.cc | 4 +-
src/script/ir_builder/ir.cc | 28 +-
src/script/printer/doc_printer.cc | 139 +++-----
src/script/printer/doc_translator.cc | 17 -
src/script/printer/printer.cc | 2 +-
src/sym/analyzer.cc | 3 +-
src/sym/bound_deducer.cc | 34 +-
src/sym/const_int_bound.cc | 2 +-
src/sym/int_set.cc | 34 +-
src/sym/iter_affine_map.cc | 27 +-
src/sym/modular_set.cc | 3 +-
src/sym/z3_prover.cc | 2 +-
src/target/target.cc | 10 -
src/tirx/analysis/check_well_formed.cc | 1 +
src/tirx/analysis/verify_memory.cc | 2 +-
src/tirx/ir/data_type_rewriter.h | 6 +-
src/tirx/ir/index_map.cc | 4 +-
src/tirx/ir/ir_mutator_with_analyzer.cc | 2 +-
src/tirx/op/region.cc | 13 +-
src/tirx/script/ir_builder/ir.cc | 138 +------
src/tirx/tile/lower.cc | 4 +-
src/tirx/transform/dtype_conversion.h | 6 +-
src/tirx/transform/force_narrow_index_to_i32.cc | 2 +-
src/tirx/transform/ir_utils.h | 6 +-
src/tirx/transform/narrow_datatype.cc | 2 +
src/tirx/transform/remove_no_op.cc | 9 +-
src/tirx/transform/remove_no_op.h | 6 +-
src/tirx/transform/split_host_device.cc | 32 +-
src/tirx/transform/tvm_ffi_binder.h | 6 +-
src/tirx/transform/vectorize_loop.cc | 4 +
tests/cpp/CMakeLists.txt | 2 +-
tests/cpp/runtime/backend_workspace_test.cc | 54 +++
tests/cpp/runtime/tensor_io_test.cc | 105 ++++++
tests/cpp/script/string_escape_test.cc | 65 ++++
tests/cpp/sym/domain_map_test.cc | 66 ++++
tests/python/backend/cuda/codegen/test_basic.py | 2 +-
tests/python/backend/cuda/codegen/test_fastmath.py | 2 +-
tests/python/backend/metal/codegen/test_basic.py | 12 +-
tests/python/backend/vulkan/codegen/test_basic.py | 6 +-
tests/python/backend/webgpu/codegen/test_basic.py | 20 +-
tests/python/codegen/c/test_basic.py | 8 +-
tests/python/codegen/llvm/test_aarch64.py | 36 +-
tests/python/codegen/llvm/test_basic.py | 22 +-
tests/python/codegen/llvm/test_riscv.py | 2 +-
tests/python/codegen/llvm/test_scalable_vector.py | 8 +-
tests/python/codegen/llvm/test_x86.py | 2 +-
tests/python/codegen/test_executable.py | 145 ++++++++
tests/python/conftest.py | 78 ++++
tests/python/ir/test_attrs.py | 29 ++
tests/python/ir/test_expr_layout.py | 80 +++++
tests/python/ir/test_json.py | 19 +-
tests/python/ir/test_module.py | 2 +-
tests/python/runtime/test_module.py | 152 +-------
tests/python/runtime/test_tirx_config.py | 46 ++-
.../test_validate_wheel_library.py} | 45 ++-
tests/python/script/test_basic_usage.py | 4 +-
tests/python/script/test_error_handling.py | 3 +-
tests/python/script/test_ir_builder.py | 9 +-
tests/python/script/test_printer_doc.py | 4 +-
tests/python/script/test_source_locations.py | 12 +-
tests/python/support/test_config.py | 131 ++++++-
tests/python/sym/test_analyzer_object.py | 25 --
tests/python/sym/test_const_int_bound.py | 6 +-
tests/python/sym/test_intset.py | 8 +-
tests/python/sym/test_iter_affine_map.py | 41 ++-
tests/python/sym/test_rewrite_simplify.py | 397 +++++++++++++++------
tests/python/sym/test_z3.py | 6 +-
tests/python/target/test_llvm_features_info.py | 34 +-
tests/python/target/test_riscv_features.py | 6 +-
tests/python/target/test_x86_features.py | 8 +-
tests/python/testing/test_env.py | 332 -----------------
.../tirx/analysis/test_check_well_defined.py | 26 +-
tests/python/tirx/base/test_imm_values.py | 24 +-
tests/python/tirx/base/test_index_map.py | 4 +-
tests/python/tirx/base/test_nodes.py | 48 +--
tests/python/tirx/base/test_op_types.py | 111 ++++--
tests/python/tirx/base/test_scalable_datatype.py | 10 +-
tests/python/tirx/codegen/test_cuda.py | 20 +-
tests/python/tirx/codegen/test_cuda_wait_until.py | 4 +-
tests/python/tirx/codegen/test_dsmem.py | 8 +-
tests/python/tirx/codegen/test_hopper.py | 2 +-
tests/python/tirx/codegen/test_ptx_addr.py | 8 +-
tests/python/tirx/codegen/test_ptx_dialect.py | 10 +-
.../codegen/test_tcgen05_descriptor_encoders.py | 4 +-
tests/python/tirx/iket/test_profiler.py | 9 +-
tests/python/tirx/script/test_basic_usage.py | 16 +-
tests/python/tirx/script/test_gpu.py | 14 +-
tests/python/tirx/script/test_source_locations.py | 22 +-
tests/python/tirx/test_cuda_backend_config.py | 2 +-
tests/python/tirx/test_op.py | 2 +-
tests/python/tirx/test_op_namespace_cleanup.py | 11 +-
.../python/tirx/tile/cuda/test_add_sub_mul_div.py | 6 +-
tests/python/tirx/tile/cuda/test_cp_async_bulk.py | 4 +-
.../tirx/tile/cuda/test_cp_async_bulk_tensor.py | 6 +-
tests/python/tirx/tile/cuda/test_cvt.py | 6 +-
tests/python/tirx/tile/cuda/test_ewise.py | 22 +-
tests/python/tirx/tile/cuda/test_fma.py | 4 +-
.../python/tirx/tile/cuda/test_ld_st_registers.py | 26 +-
tests/python/tirx/tile/cuda/test_mma_sync.py | 4 +-
tests/python/tirx/tile/cuda/test_mov.py | 2 +-
tests/python/tirx/tile/cuda/test_tcgen05_cp.py | 6 +-
tests/python/tirx/tile/cuda/test_tcgen05_ld_st.py | 6 +-
tests/python/tirx/tile/test_dispatcher.py | 5 +-
tests/python/tirx/transform/test_flatten_tensor.py | 4 +-
.../transform/test_force_narrow_index_to_i32.py | 12 +-
tests/python/tirx/transform/test_hoist_if.py | 2 +-
tests/python/tirx/transform/test_lower_tirx.py | 23 +-
.../python/tirx/transform/test_make_packed_api.py | 6 +-
.../python/tirx/transform/test_narrow_datatype.py | 6 +-
tests/python/tirx/transform/test_simplify.py | 5 +-
.../tirx/transform/test_split_host_device.py | 2 +-
tests/python/tirx/transform/test_unroll.py | 2 +-
tests/python/tirx/transform/test_vectorize.py | 16 +-
291 files changed, 3563 insertions(+), 5444 deletions(-)
copy docs/conf.py => cmake/tvm-tirx-config.in (71%)
delete mode 100644 include/tvm/support/base64.h
delete mode 100644 include/tvm/support/cuda/nvtx.h
delete mode 100644 include/tvm/support/str_escape.h
create mode 100644 python/tvm_tirx/codegen/__init__.py
rename python/tvm_tirx/{runtime/module.py => codegen/executable.py} (52%)
rename python/tvm_tirx/{codegen.py => codegen/llvm.py} (75%)
delete mode 100644 python/tvm_tirx/error.py
create mode 100644 python/tvm_tirx/ir/prim/vector_expr.py
rename python/tvm_tirx/ir/{supply.py => unique_name_supply.py} (100%)
delete mode 100644 python/tvm_tirx/runtime/executable.py
delete mode 100644 python/tvm_tirx/target/intrin.py
delete mode 100644 python/tvm_tirx/tirx/backend/__init__.py
copy python/tvm_tirx/tirx/{function.py => index_map.py} (69%)
delete mode 100644 src/runtime/timer.cc
create mode 100644 tests/cpp/runtime/backend_workspace_test.cc
create mode 100644 tests/cpp/runtime/tensor_io_test.cc
create mode 100644 tests/cpp/script/string_escape_test.cc
create mode 100644 tests/cpp/sym/domain_map_test.cc
create mode 100644 tests/python/codegen/test_executable.py
create mode 100644 tests/python/conftest.py
create mode 100644 tests/python/ir/test_expr_layout.py
rename tests/python/{all-platform-minimal-test/test_validate_runtime_library.py => runtime/test_validate_wheel_library.py} (63%)
delete mode 100644 tests/python/testing/test_env.py
(tvm) 03/12: [FIX][Sym] Reject non-positive divisors in iter map floordiv/floormod (#20756)
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 52441cdf2bb26eefc565d557f99b2c22d89b1047
Author: alumkal <al...@outlook.com>
AuthorDate: Fri Oct 16 22:41:51 2026 +0800
[FIX][Sym] Reject non-positive divisors in iter map floordiv/floormod (#20756)
Fixes #20736.
### Problem
`SplitFloorDivConst` and `SplitFloorModConst` cancel a non-unit iterator
scale against the divisor. With a negative scale this produces a
negative divisor: `floordiv(63 - x, 2)` (scale `-1`, base `63`) becomes
`floordiv(x - 63, -2)`. `PadDividendToDivisor` and the split
construction assume a positive divisor:
- `left_pad = floormod(-63, -2) = -1`. In the first pass the mark's
padding is `max(info.left_pad, -1) = 0`, so the split is not shifted,
while `new_base = floordiv(base - left_pad, rhs) = 31` still assumes the
shift.
- The new split gets `lower_factor = -2`.
As a result, over `x in [0, 64)`:
| expression | `iter_map_simplify` on main | wrong values |
|---|---|---|
| `floordiv(63 - x, 2)` | `x // -2 + 31` | 32 / 64 |
| `floormod(63 - x, 2)` | `x % -2 * -1` | 64 / 64 |
| `floordiv(63 - x, 4)` | `x // -4 + 15` | 48 / 64 |
| `floormod(65 - x, 4)` | `x % -4 * -1` | 64 / 64 |
| `floordiv(x + 1, -2)` | `x // -2 + -1` | 32 / 64 |
| `floormod(x + 1, -2)` | `x % -2` | 64 / 64 |
Downstream, a buffer flattening pass that uses the iter-map simplifier
turns a reversed block index `A[(63 - bx) // 2, tx]` into an index that
reads the previous row for odd `bx` and row -1 (out of bounds) for `bx =
63`.
### Fix
After the scale handling, report a provably non-positive divisor as not
representable (via `ErrorLogger`), so these expressions are left
unchanged. Negative scales that divide out exactly (e.g. `floordiv(x *
-2 + 62, 2)` -> `x * -1 + 31`) take the earlier exact-division branches
and are still simplified. Divisors of unknown sign are not affected, so
symbolic divisors such as `n * 4096` keep simplifying as before.
`DetectIterMap` callers already handle this failure: `IterMapSimplify`
keeps the original expressions, `SubspaceDivide` returns empty, and
region evaluation falls back to `EvalSet`.
### Testing
- New `test_non_positive_divisor_is_not_simplified`: fails on main,
passes with this change.
- `tirx/tests/python/sym/test_iter_affine_map.py`: 46 passed.
- `tirx/tests/python/sym`, `tirx/base/test_index_map.py`,
`tirx/transform`, `tirx/analysis`, `tirx/test_layout.py`: 1466 passed.
The 7 failures are unrelated: 6 need LLVM (not built here) and
`test_vectorize_nested_predicates_preserve_both_masks` fails identically
on main.
- A probe over 15 negative-scale and negative-divisor expressions gives
0 wrong values after the change.
---
tirx/src/sym/iter_affine_map.cc | 17 +++++++++++++++++
tirx/tests/python/sym/test_iter_affine_map.py | 22 ++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/tirx/src/sym/iter_affine_map.cc b/tirx/src/sym/iter_affine_map.cc
index 8627bbf609..def26c2903 100644
--- a/tirx/src/sym/iter_affine_map.cc
+++ b/tirx/src/sym/iter_affine_map.cc
@@ -1993,6 +1993,16 @@ ffi::Optional<PrimExpr> IterMapRewriter::SplitFloorDivConst(IterSplitExpr lhs, P
// We handle scale!=1 in above code, hence we only consider floordiv(x, rhs) below
// where x=floormod(floordiv(iter, lower_factor), extent) + base
+ if (analyzer_->CanProveLess(rhs, 1)) {
+ // The padding and the split constructed below assume a positive divisor.
+ // A non-positive one can be written directly or come from dividing the
+ // divisor by a negative scale above, e.g. floordiv(63 - x, 2) becomes
+ // floordiv(x - 63, -2).
+ ErrorLogger(this) << "Cannot represent as IterMap: the divisor " << rhs
+ << " of FloorDiv is not positive.";
+ return std::nullopt;
+ }
+
auto pair = PadDividendToDivisor(lhs, base, rhs);
if (!pair) return std::nullopt;
IterSplitExpr padded = pair->first;
@@ -2112,6 +2122,13 @@ ffi::Optional<PrimExpr> IterMapRewriter::SplitFloorModConst(IterSplitExpr lhs, P
// We handle scale!=1 in above code, hence we only consider floormod(x, rhs) below
// where x=floormod(floordiv(iter, lower_factor), extent) + base
+ if (analyzer_->CanProveLess(rhs, 1)) {
+ // See SplitFloorDivConst: the padding and the split below assume a
+ // positive divisor.
+ ErrorLogger(this) << "Cannot represent as IterMap: the divisor " << rhs
+ << " of FloorMod is not positive.";
+ return std::nullopt;
+ }
PrimExpr source_upper_bound = lhs->source->extent;
auto origin_it = padded_origin_map_.find(lhs->source);
if (origin_it != padded_origin_map_.end()) {
diff --git a/tirx/tests/python/sym/test_iter_affine_map.py b/tirx/tests/python/sym/test_iter_affine_map.py
index 44ccc72d40..03b675bd44 100644
--- a/tirx/tests/python/sym/test_iter_affine_map.py
+++ b/tirx/tests/python/sym/test_iter_affine_map.py
@@ -250,6 +250,28 @@ def test_compound_floormod_two_regression():
)
+def test_non_positive_divisor_is_not_simplified():
+ # Dividing out a negative scale turns floordiv(63 - x, 2) into
+ # floordiv(x - 63, -2); padding with a negative divisor used to drop the
+ # remainder (e.g. x // -2 + 31, wrong for every odd x). Such expressions
+ # are left unchanged, as are directly written negative divisors.
+ x = tvm_tirx.tirx.Var("x", "int32")
+ fld = tvm_tirx.tirx.floordiv
+ flm = tvm_tirx.tirx.floormod
+ for index in [
+ fld(63 - x, 2),
+ flm(63 - x, 2),
+ fld(63 - x, 4),
+ flm(65 - x, 4),
+ fld(x + 1, -2),
+ flm(x + 1, -2),
+ ]:
+ assert_iter_map_simplify({index: index}, var_dom([(x, 64)]))
+
+ # A negative scale that divides out exactly is still simplified.
+ assert_iter_map_simplify({fld(x * -2 + 62, 2): x * -1 + 31}, var_dom([(x, 64)]))
+
+
def test_nested_floormod_requires_divisible_extents():
x = tvm_tirx.tirx.Var("x", "int32")
flm = tvm_tirx.tirx.floormod
(tvm) 01/12: [BUILD] Enable LLVM and automatic CUDA in standalone TIRx (#20755)
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 96e7e85dc7c6ee779da1fef6215824d9cc9d960f
Author: Tianqi Chen <tq...@users.noreply.github.com>
AuthorDate: Fri Oct 16 09:39:26 2026 -0400
[BUILD] Enable LLVM and automatic CUDA in standalone TIRx (#20755)
Standalone TIRx builds now enable LLVM by default and detect CUDA when a
complete toolkit is available. Preserve explicit backend and toolchain
overrides, explain missing LLVM development dependencies, and use the
same defaults for normal Python package installation.
---
tirx/CMakeLists.txt | 6 ++++--
tirx/cmake/modules/CUDA.cmake | 24 ++++++++++++++++--------
tirx/cmake/utils/FindLLVM.cmake | 11 ++++++++++-
tirx/pyproject.toml | 3 ---
tirx/src/sym/rewrite_simplify.cc | 2 +-
5 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/tirx/CMakeLists.txt b/tirx/CMakeLists.txt
index 234f0d4776..efe2deee46 100644
--- a/tirx/CMakeLists.txt
+++ b/tirx/CMakeLists.txt
@@ -42,7 +42,7 @@ tvm_tirx_option(TVM_TIRX_USE_CUSTOM_LOGGING BOOL OFF "Use user-defined logging i
# ######### LLVM ##########
-tvm_tirx_option(TVM_TIRX_USE_LLVM STRING OFF "Build with LLVM (OFF, ON, or llvm-config command)")
+tvm_tirx_option(TVM_TIRX_USE_LLVM STRING ON "Build with LLVM (OFF, ON, or llvm-config command)")
# ######### Z3 ##########
@@ -51,7 +51,7 @@ set_property(CACHE TVM_TIRX_USE_Z3 PROPERTY STRINGS OFF ON AUTO)
# ######### CUDA ##########
-tvm_tirx_option(TVM_TIRX_USE_CUDA STRING OFF "Build with CUDA (OFF, ON, or SDK path)")
+tvm_tirx_option(TVM_TIRX_USE_CUDA STRING AUTO "Build with CUDA (OFF, ON, AUTO, or SDK path)")
# ######### Other device runtimes ##########
@@ -323,6 +323,8 @@ if(NOT PROJECT_IS_TOP_LEVEL)
# The parent checks the core version and reuses its dependency finders.
set(TVM_TIRX_VERSION "${TVM_TIRX_VERSION}" PARENT_SCOPE)
set(TVM_TIRX_CMAKE_DIR "${TVM_TIRX_CMAKE_DIR}" PARENT_SCOPE)
+ # Parent runtime extensions must use the resolved AUTO selection, not the cache.
+ set(TVM_TIRX_USE_CUDA "${TVM_TIRX_USE_CUDA}" PARENT_SCOPE)
return()
endif()
diff --git a/tirx/cmake/modules/CUDA.cmake b/tirx/cmake/modules/CUDA.cmake
index 68525b7d87..c98527092e 100644
--- a/tirx/cmake/modules/CUDA.cmake
+++ b/tirx/cmake/modules/CUDA.cmake
@@ -16,7 +16,20 @@
# under the License.
# CUDA Module
-find_cuda(${TVM_TIRX_USE_CUDA} OFF)
+if("${TVM_TIRX_USE_CUDA}" MATCHES "^[Aa][Uu][Tt][Oo]$")
+ find_cuda(ON OFF)
+ # Keep AUTO in the cache, but resolve it before any backend build guards.
+ # FindCUDA requires nvcc and headers, but may accept only static cudart.
+ # Our runtime needs shared cudart and the driver library (or its toolkit stub).
+ if(CUDA_FOUND AND CUDA_CUDART_LIBRARY AND CUDA_CUDA_LIBRARY)
+ set(TVM_TIRX_USE_CUDA ON)
+ else()
+ set(TVM_TIRX_USE_CUDA OFF)
+ message(STATUS "CUDA AUTO: usable toolkit not found; building without CUDA")
+ endif()
+else()
+ find_cuda(${TVM_TIRX_USE_CUDA} OFF)
+endif()
if(CUDA_FOUND)
# always set the includedir when CUDA is available
@@ -48,13 +61,8 @@ if(TVM_TIRX_USE_CUDA)
# [0] https://github.com/Kitware/CMake/commit/6377a438
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0)
- if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
- if(CMAKE_VERSION VERSION_LESS "3.24")
- message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES not set. Please upgrade CMake to 3.24 to use native, or set CMAKE_CUDA_ARCHITECTURES manually")
- endif()
- message(STATUS "CMAKE_CUDA_ARCHITECTURES not set, using native")
- set(CMAKE_CUDA_ARCHITECTURES native)
- endif()
+ # Use CMake's compiler-selected architectures unless the user overrides them.
+ # Unlike 'native', this also works on build hosts without a visible GPU.
endif(TVM_TIRX_USE_CUDA)
if(TVM_TIRX_USE_CUDA)
diff --git a/tirx/cmake/utils/FindLLVM.cmake b/tirx/cmake/utils/FindLLVM.cmake
index e249de8b01..de5fb324ca 100644
--- a/tirx/cmake/utils/FindLLVM.cmake
+++ b/tirx/cmake/utils/FindLLVM.cmake
@@ -75,7 +75,16 @@ macro(find_llvm use_llvm)
# [1] https://github.com/llvm/llvm-project/pull/83807
include(GNUInstallDirs)
- find_package(LLVM ${llvm_version_required} REQUIRED CONFIG)
+ find_package(LLVM ${llvm_version_required} QUIET CONFIG)
+ if(NOT LLVM_FOUND)
+ message(FATAL_ERROR
+ "LLVM development files were not found. Install LLVM 15 or newer, including "
+ "its development headers and libraries (for example, llvm-dev on Debian/Ubuntu "
+ "or llvm-devel on Fedora). Set LLVM_DIR to the directory containing "
+ "LLVMConfig.cmake, add the LLVM installation to CMAKE_PREFIX_PATH, or set "
+ "TVM_TIRX_USE_LLVM to the full path to llvm-config. To build without LLVM, "
+ "explicitly set TVM_TIRX_USE_LLVM=OFF.")
+ endif()
llvm_map_components_to_libnames(LLVM_LIBS "all")
if (NOT LLVM_LIBS)
message(STATUS "Not found - LLVM_LIBS")
diff --git a/tirx/pyproject.toml b/tirx/pyproject.toml
index 98afc68828..9043a5163e 100644
--- a/tirx/pyproject.toml
+++ b/tirx/pyproject.toml
@@ -122,9 +122,6 @@ logging.level = "INFO"
[tool.scikit-build.cmake.define]
TVM_TIRX_BUILD_PYTHON_MODULE = "ON"
-TVM_TIRX_USE_CUDA = "OFF"
-# Statically link Z3 from the mlc-z3-static build dependency by default.
-TVM_TIRX_USE_Z3 = "AUTO"
TVM_TIRX_BUILD_TESTS = "OFF"
[tool.pytest.ini_options]
diff --git a/tirx/src/sym/rewrite_simplify.cc b/tirx/src/sym/rewrite_simplify.cc
index 68f1a29734..716832d266 100644
--- a/tirx/src/sym/rewrite_simplify.cc
+++ b/tirx/src/sym/rewrite_simplify.cc
@@ -429,7 +429,7 @@ UnchangedOr<PrimExpr> RewriteSimplifier::Impl::Mutate_(const prim::SubNode* op,
// mul co-efficient folding: pefer co-effiicent to stay at rhs
TVM_TRY_REWRITE(x - x, ZeroWithTypeLike(x));
TVM_TRY_REWRITE(matches_one_of(x * y - x, y * x - x), (y - 1) * x);
- TVM_TRY_REWRITE(matches_one_of(x - y * x, x - x * y), (1 - y) * x);
+ TVM_TRY_REWRITE(matches_one_of(x - x * y, x - y * x), (1 - y) * x);
TVM_TRY_REWRITE(matches_one_of(x * y - x * z, y * x - x * z, x * y - z * x, y * x - z * x),
(y - z) * x);
(tvm) 02/12: [REFACTOR][TIRx] Align public APIs and package boundaries (#20759)
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 69215634dbe2044c20377099a1d12f5e5381a6b0
Author: Tianqi Chen <tq...@users.noreply.github.com>
AuthorDate: Fri Oct 16 10:12:36 2026 -0400
[REFACTOR][TIRx] Align public APIs and package boundaries (#20759)
Align the TIRx public surface across C++, Python, and registry bindings.
Normalize global names and result-type arguments, use reflected fields
and documented Python operator helpers, mirror header layout in Python
modules, centralize dictionary attribute construction, and update
callers across the compiler and runtime integrations. Expression callers
use the public IR namespace; the shared script cast builder accepts a
value followed by its result type, with optional explicit `ty=` and
keyword-only source locations.
Remove unused declarations, registrations, and source-map plumbing;
simplify shared IR builders and domain-map APIs; and keep VM-only
helpers in the compiler runtime. Tighten tensor serialization sizes and
reads, preserve workspace API error handling, and use shared FFI base64
and string escaping helpers.
Meta-schedule database payloads now use direct base64 encoding without
the legacy length prefix. Registry, Python API, and database format
changes update consumers directly without compatibility aliases.
---
tirx/CMakeLists.txt | 3 +-
tirx/include/tvm/backend/cuda/attr.h | 20 +-
tirx/include/tvm/backend/cuda/op/iket.h | 17 +-
tirx/include/tvm/backend/cuda/op_attr_types.h | 5 +-
tirx/include/tvm/codegen/codegen.h | 6 +-
tirx/include/tvm/codegen/intrin_rule.h | 5 +-
tirx/include/tvm/ir/attrs.h | 2 +-
tirx/include/tvm/ir/expr.h | 2 +-
tirx/include/tvm/ir/location.h | 79 +---
tirx/include/tvm/ir/module.h | 26 +-
tirx/include/tvm/ir/prim/op.h | 2 +-
tirx/include/tvm/ir/transform.h | 6 +-
tirx/include/tvm/ir/with_context.h | 2 +-
tirx/include/tvm/runtime/base.h | 6 +-
tirx/include/tvm/runtime/c_backend_api.h | 9 +-
tirx/include/tvm/runtime/device_api.h | 8 +-
tirx/include/tvm/runtime/memory_scope.h | 17 +-
tirx/include/tvm/runtime/tensor.h | 106 +-----
tirx/include/tvm/runtime/timer.h | 58 +--
tirx/include/tvm/script/ir_builder/base.h | 4 +
tirx/include/tvm/script/ir_builder/frame.h | 21 +-
tirx/include/tvm/script/ir_builder/ir.h | 4 +
tirx/include/tvm/script/printer/doc.h | 4 +
tirx/include/tvm/script/printer/doc_translator.h | 4 +
tirx/include/tvm/support/base64.h | 302 ----------------
tirx/include/tvm/support/bytes_io.h | 2 +-
tirx/include/tvm/support/cuda/nvtx.h | 71 ----
tirx/include/tvm/support/env.h | 2 +-
tirx/include/tvm/support/ordered_map.h | 2 +-
tirx/include/tvm/support/str_escape.h | 123 -------
tirx/include/tvm/sym/bound.h | 25 +-
tirx/include/tvm/sym/int_set.h | 31 +-
tirx/include/tvm/target/target.h | 6 +-
tirx/include/tvm/target/target_kind.h | 11 +-
tirx/include/tvm/tirx/analysis.h | 21 +-
tirx/include/tvm/tirx/function.h | 20 +-
tirx/include/tvm/tirx/index_map.h | 6 +-
tirx/include/tvm/tirx/layout.h | 3 -
tirx/include/tvm/tirx/op/memory.h | 10 +-
tirx/include/tvm/tirx/op/region.h | 3 +-
tirx/include/tvm/tirx/op_attr_types.h | 10 +-
tirx/include/tvm/tirx/script/ir_builder/frame.h | 20 +-
tirx/include/tvm/tirx/script/ir_builder/ir.h | 89 +----
tirx/include/tvm/tirx/stmt.h | 10 +-
tirx/include/tvm/tirx/stmt_functor.h | 2 +-
tirx/include/tvm/tirx/tile/context.h | 5 +-
tirx/include/tvm/tirx/tile/dispatch.h | 5 +-
tirx/include/tvm/tirx/tile/op.h | 5 +-
tirx/include/tvm/tirx/tile/thread_scope.h | 5 +-
tirx/include/tvm/tirx/transform.h | 6 +-
.../tvm_tirx/backend/cuda/codegen/registry.py | 26 +-
.../python/tvm_tirx/backend/cuda/codegen/schema.py | 6 +-
tirx/python/tvm_tirx/backend/cuda/cpp/asm.py | 40 +--
tirx/python/tvm_tirx/backend/cuda/cpp/builtins.py | 86 ++---
.../tvm_tirx/backend/cuda/cpp/descriptors.py | 12 +-
.../python/tvm_tirx/backend/cuda/cpp/instrument.py | 14 +-
tirx/python/tvm_tirx/backend/cuda/cpp/nvshmem.py | 6 +-
tirx/python/tvm_tirx/backend/cuda/iket.py | 2 +-
tirx/python/tvm_tirx/backend/cuda/lang/pipeline.py | 2 +-
tirx/python/tvm_tirx/backend/cuda/launch/_impl.py | 2 +-
tirx/python/tvm_tirx/backend/cuda/op.py | 112 +++---
tirx/python/tvm_tirx/backend/cuda/ptx/engine.py | 20 +-
tirx/python/tvm_tirx/backend/cuda/ptx/gen_stubs.py | 6 +-
tirx/python/tvm_tirx/backend/cuda/script.py | 48 +--
.../backend/cuda/tile/patterns/async_copy.py | 10 +-
.../tvm_tirx/backend/cuda/tile/patterns/common.py | 5 +-
.../backend/cuda/tile/patterns/descriptors.py | 9 +-
.../backend/cuda/tile/patterns/tcgen05_mma.py | 8 +-
.../tvm_tirx/backend/cuda/tile/patterns/tma.py | 14 +-
tirx/python/tvm_tirx/backend/metal/op.py | 15 +-
.../tvm_tirx/backend/trn/tile/binary/default.py | 3 +-
.../tvm_tirx/backend/trn/tile/binary/utils.py | 3 +-
.../backend/trn/tile/instruction_generator.py | 4 +-
.../tvm_tirx/backend/trn/tile/private_alloc.py | 4 +-
.../tvm_tirx/backend/trn/tile/select/default.py | 4 +-
.../tvm_tirx/backend/trn/tile/unary/default.py | 3 +-
.../tvm_tirx/backend/trn/tile/unary/utils.py | 3 +-
.../backend/trn/transform/naive_allocator.py | 3 +-
tirx/python/tvm_tirx/ir/__init__.py | 3 +
tirx/python/tvm_tirx/ir/_overload_prim_expr.py | 2 +-
tirx/python/tvm_tirx/ir/attrs.py | 38 +-
tirx/python/tvm_tirx/ir/base.py | 4 -
tirx/python/tvm_tirx/ir/expr.py | 114 +++++-
tirx/python/tvm_tirx/ir/function.py | 7 +-
tirx/python/tvm_tirx/ir/json_compact.py | 64 ----
tirx/python/tvm_tirx/ir/location.py | 8 +-
tirx/python/tvm_tirx/ir/module.py | 38 +-
tirx/python/tvm_tirx/ir/op.py | 4 +-
tirx/python/tvm_tirx/ir/prim/__init__.py | 6 +-
tirx/python/tvm_tirx/ir/prim/expr.py | 171 +--------
tirx/python/tvm_tirx/ir/prim/op.py | 96 ++---
tirx/python/tvm_tirx/ir/prim/vector_expr.py | 109 ++++++
tirx/python/tvm_tirx/ir/stmt.py | 12 +-
tirx/python/tvm_tirx/ir/type.py | 7 +-
.../ir/{supply.py => unique_name_supply.py} | 0
tirx/python/tvm_tirx/runtime/_tensor.py | 10 +-
tirx/python/tvm_tirx/runtime/device.py | 19 +-
tirx/python/tvm_tirx/script/ir_builder/_ffi_api.py | 22 --
tirx/python/tvm_tirx/script/ir_builder/frame.py | 14 +-
tirx/python/tvm_tirx/script/ir_builder/stmt.py | 3 +-
tirx/python/tvm_tirx/script/printer/doc.py | 2 +-
tirx/python/tvm_tirx/script/tirx.pyi | 2 +-
tirx/python/tvm_tirx/sym/analyzer.py | 2 +-
tirx/python/tvm_tirx/sym/bound.py | 2 +-
tirx/python/tvm_tirx/sym/int_set.py | 10 +-
tirx/python/tvm_tirx/sym/iter_affine_map.py | 18 +-
tirx/python/tvm_tirx/sym/utils.py | 2 +-
tirx/python/tvm_tirx/target/intrin.py | 81 -----
tirx/python/tvm_tirx/target/target.py | 14 +-
tirx/python/tvm_tirx/tirx/__init__.py | 6 +-
tirx/python/tvm_tirx/tirx/_tensor_view.py | 8 +-
tirx/python/tvm_tirx/tirx/analysis/analysis.py | 2 +-
tirx/python/tvm_tirx/tirx/expr.py | 39 --
tirx/python/tvm_tirx/tirx/layout.py | 5 +-
tirx/python/tvm_tirx/tirx/op/__init__.py | 245 +++++--------
.../tvm_tirx/tirx/script/ir_builder/frame.py | 7 -
tirx/python/tvm_tirx/tirx/script/ir_builder/ir.py | 19 +-
tirx/python/tvm_tirx/tirx/script/ir_builder/op.py | 51 ++-
.../tirx/script/ir_builder/parser_protocol.py | 65 ++--
.../tvm_tirx/tirx/script/ir_builder/triton.py | 3 +-
tirx/python/tvm_tirx/tirx/tile/instruction.py | 6 +-
tirx/src/backend/cuda/runtime/cuda_device_api.cc | 2 +-
.../backend/cuda/transforms/bind_backend_config.cc | 4 +-
tirx/src/backend/cuda/transforms/lower_iket.cc | 3 +-
tirx/src/backend/metal/runtime/metal_device_api.mm | 2 +-
tirx/src/backend/opencl/runtime/opencl_common.h | 2 +-
tirx/src/backend/rocm/runtime/rocm_device_api.cc | 2 +-
tirx/src/backend/vulkan/runtime/vulkan_timer.h | 2 +-
tirx/src/codegen/c/codegen_c_host.cc | 13 +-
tirx/src/codegen/llvm/codegen_cpu.cc | 2 +-
tirx/src/ir/attrs.cc | 5 -
tirx/src/ir/env_func.cc | 13 +-
tirx/src/ir/expr.cc | 30 +-
tirx/src/ir/function.cc | 1 -
tirx/src/ir/location.cc | 70 ----
tirx/src/ir/module.cc | 49 ++-
tirx/src/ir/op.cc | 12 +-
tirx/src/ir/prim/op.cc | 13 +-
tirx/src/ir/type.cc | 1 -
tirx/src/runtime/device_api.cc | 56 +--
tirx/src/runtime/tensor.cc | 116 ++++--
tirx/src/runtime/timer.cc | 14 +-
tirx/src/script/ir_builder/frame.cc | 4 +-
tirx/src/script/ir_builder/ir.cc | 28 +-
tirx/src/script/printer/doc_printer.cc | 139 +++-----
tirx/src/script/printer/doc_translator.cc | 17 -
tirx/src/script/printer/printer.cc | 2 +-
tirx/src/sym/analyzer.cc | 3 +-
tirx/src/sym/bound_deducer.cc | 34 +-
tirx/src/sym/int_set.cc | 34 +-
tirx/src/sym/iter_affine_map.cc | 10 +-
tirx/src/target/target.cc | 10 -
tirx/src/tirx/analysis/verify_memory.cc | 2 +-
tirx/src/tirx/ir/data_type_rewriter.h | 6 +-
tirx/src/tirx/ir/index_map.cc | 4 +-
tirx/src/tirx/ir/ir_mutator_with_analyzer.cc | 2 +-
tirx/src/tirx/op/region.cc | 13 +-
tirx/src/tirx/script/ir_builder/ir.cc | 138 +------
tirx/src/tirx/tile/lower.cc | 4 +-
tirx/src/tirx/transform/dtype_conversion.h | 6 +-
.../tirx/transform/force_narrow_index_to_i32.cc | 2 +-
tirx/src/tirx/transform/ir_utils.h | 6 +-
tirx/src/tirx/transform/remove_no_op.cc | 9 +-
tirx/src/tirx/transform/remove_no_op.h | 6 +-
tirx/src/tirx/transform/split_host_device.cc | 32 +-
tirx/src/tirx/transform/tvm_ffi_binder.h | 6 +-
tirx/tests/cpp/runtime/backend_workspace_test.cc | 54 +++
tirx/tests/cpp/runtime/tensor_io_test.cc | 105 ++++++
tirx/tests/cpp/script/string_escape_test.cc | 65 ++++
tirx/tests/cpp/sym/domain_map_test.cc | 66 ++++
.../python/backend/cuda/codegen/test_basic.py | 2 +-
.../python/backend/vulkan/codegen/test_basic.py | 6 +-
tirx/tests/python/codegen/c/test_basic.py | 2 +-
tirx/tests/python/ir/test_attrs.py | 29 ++
tirx/tests/python/ir/test_expr_layout.py | 80 +++++
tirx/tests/python/ir/test_json.py | 19 +-
tirx/tests/python/ir/test_module.py | 2 +-
tirx/tests/python/script/test_error_handling.py | 3 +-
tirx/tests/python/script/test_ir_builder.py | 9 +-
tirx/tests/python/script/test_printer_doc.py | 4 +-
tirx/tests/python/script/test_source_locations.py | 12 +-
tirx/tests/python/sym/test_analyzer_object.py | 25 --
tirx/tests/python/sym/test_const_int_bound.py | 6 +-
tirx/tests/python/sym/test_intset.py | 8 +-
tirx/tests/python/sym/test_iter_affine_map.py | 19 +-
tirx/tests/python/sym/test_rewrite_simplify.py | 397 +++++++++++++++------
tirx/tests/python/sym/test_z3.py | 6 +-
.../tirx/analysis/test_check_well_defined.py | 2 +-
tirx/tests/python/tirx/base/test_imm_values.py | 20 +-
tirx/tests/python/tirx/base/test_index_map.py | 4 +-
tirx/tests/python/tirx/base/test_nodes.py | 48 +--
tirx/tests/python/tirx/base/test_op_types.py | 111 ++++--
.../python/tirx/base/test_scalable_datatype.py | 2 +-
tirx/tests/python/tirx/codegen/test_cuda.py | 14 +-
.../python/tirx/codegen/test_cuda_wait_until.py | 4 +-
tirx/tests/python/tirx/codegen/test_dsmem.py | 8 +-
tirx/tests/python/tirx/codegen/test_ptx_addr.py | 4 +-
tirx/tests/python/tirx/codegen/test_ptx_dialect.py | 8 +-
.../codegen/test_tcgen05_descriptor_encoders.py | 4 +-
tirx/tests/python/tirx/iket/test_profiler.py | 4 +-
tirx/tests/python/tirx/script/test_basic_usage.py | 8 +-
tirx/tests/python/tirx/script/test_gpu.py | 14 +-
.../python/tirx/script/test_source_locations.py | 22 +-
tirx/tests/python/tirx/test_op.py | 2 +-
.../tests/python/tirx/test_op_namespace_cleanup.py | 11 +-
.../python/tirx/tile/cuda/test_add_sub_mul_div.py | 6 +-
.../python/tirx/tile/cuda/test_cp_async_bulk.py | 4 +-
.../tirx/tile/cuda/test_cp_async_bulk_tensor.py | 6 +-
tirx/tests/python/tirx/tile/cuda/test_cvt.py | 6 +-
tirx/tests/python/tirx/tile/cuda/test_ewise.py | 22 +-
tirx/tests/python/tirx/tile/cuda/test_fma.py | 4 +-
.../python/tirx/tile/cuda/test_ld_st_registers.py | 26 +-
tirx/tests/python/tirx/tile/cuda/test_mma_sync.py | 4 +-
tirx/tests/python/tirx/tile/cuda/test_mov.py | 2 +-
.../tests/python/tirx/tile/cuda/test_tcgen05_cp.py | 6 +-
.../python/tirx/tile/cuda/test_tcgen05_ld_st.py | 6 +-
tirx/tests/python/tirx/tile/test_dispatcher.py | 3 +-
.../python/tirx/transform/test_flatten_tensor.py | 4 +-
.../transform/test_force_narrow_index_to_i32.py | 12 +-
tirx/tests/python/tirx/transform/test_hoist_if.py | 2 +-
.../tests/python/tirx/transform/test_lower_tirx.py | 21 +-
.../python/tirx/transform/test_make_packed_api.py | 2 +-
.../python/tirx/transform/test_narrow_datatype.py | 6 +-
tirx/tests/python/tirx/transform/test_simplify.py | 5 +-
tirx/tests/python/tirx/transform/test_unroll.py | 2 +-
225 files changed, 2250 insertions(+), 3058 deletions(-)
diff --git a/tirx/CMakeLists.txt b/tirx/CMakeLists.txt
index efe2deee46..683377e4da 100644
--- a/tirx/CMakeLists.txt
+++ b/tirx/CMakeLists.txt
@@ -47,7 +47,6 @@ tvm_tirx_option(TVM_TIRX_USE_LLVM STRING ON "Build with LLVM (OFF, ON, or llvm-c
# ######### Z3 ##########
tvm_tirx_option(TVM_TIRX_USE_Z3 STRING AUTO "Build with Z3 SMT solver support (OFF, ON, AUTO)")
-set_property(CACHE TVM_TIRX_USE_Z3 PROPERTY STRINGS OFF ON AUTO)
# ######### CUDA ##########
@@ -101,7 +100,7 @@ if(PROJECT_IS_TOP_LEVEL)
set(CMAKE_INSTALL_LIBDIR lib)
endif()
endif()
-add_compile_definitions(TVM_VERSION="${TVM_TIRX_VERSION}")
+add_compile_definitions(TVM_TIRX_VERSION="${TVM_TIRX_VERSION}")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/compiler-rt")
if(MSVC)
diff --git a/tirx/include/tvm/backend/cuda/attr.h b/tirx/include/tvm/backend/cuda/attr.h
index 7ff54cae22..225f36001a 100644
--- a/tirx/include/tvm/backend/cuda/attr.h
+++ b/tirx/include/tvm/backend/cuda/attr.h
@@ -16,18 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-
+/*!
+ * \file tvm/backend/cuda/attr.h
+ * \brief CUDA backend attribute keys.
+ */
#ifndef TVM_BACKEND_CUDA_ATTR_H_
#define TVM_BACKEND_CUDA_ATTR_H_
+#include <tvm/ffi/reflection/accessor.h>
+#include <tvm/ir/expr.h>
+
namespace tvm {
namespace backend {
namespace cuda {
namespace attr {
-inline constexpr const char* kLaunchFields = "cuda.launch_fields";
-inline constexpr const char* kKernelAttrs = "cuda.kernel_attrs";
-inline constexpr const char* kSmemRequired = "cuda.smem_required";
-inline constexpr const char* kLaunchDimensions = "cuda.launch_dimensions";
+inline constexpr ffi::reflection::AttrKey<ffi::Array<ffi::String>> kLaunchFields{
+ "cuda.launch_fields"};
+inline constexpr ffi::reflection::AttrKey<ffi::Map<ffi::String, int64_t>> kKernelAttrs{
+ "cuda.kernel_attrs"};
+inline constexpr ffi::reflection::AttrKey<int64_t> kSmemRequired{"cuda.smem_required"};
+inline constexpr ffi::reflection::AttrKey<ffi::Array<PrimExpr>> kLaunchDimensions{
+ "cuda.launch_dimensions"};
+inline constexpr ffi::reflection::AttrKey<bool> kIKetEnabled{"cuda.iket.enabled"};
} // namespace attr
} // namespace cuda
} // namespace backend
diff --git a/tirx/include/tvm/backend/cuda/op/iket.h b/tirx/include/tvm/backend/cuda/op/iket.h
index 026f42b5ad..4c39654349 100644
--- a/tirx/include/tvm/backend/cuda/op/iket.h
+++ b/tirx/include/tvm/backend/cuda/op/iket.h
@@ -43,7 +43,7 @@ namespace cuda {
/*!
* \brief Get the NVIDIA IKET marker operator, tirx.cuda.iket_mark.
- * Python: C.cuda_iket_mark(name, payload=None).
+ * Python: C.iket_mark(name, payload=None).
* Script: T.cuda.iket.mark(name, payload=None).
* Operands: [0] name, the marker name; [1...] args, the optional payload tail.
* Result: void. Effects: opaque marker annotation.
@@ -52,7 +52,7 @@ TVM_TIRX_DLL const Op& iket_mark_op();
/*!
* \brief Get the NVIDIA IKET token-range start operator, tirx.cuda.iket_range_start.
- * Python: C.cuda_iket_range_start(name, payload=None).
+ * Python: C.iket_range_start(name, payload=None).
* Script: T.cuda.iket.range_start(name, payload=None).
* Operands: [0] name, the range name; [1...] args, the optional payload tail.
* Result: uint32 range token. Effects: opaque range-start annotation.
@@ -61,7 +61,7 @@ TVM_TIRX_DLL const Op& iket_range_start_op();
/*!
* \brief Get the NVIDIA IKET token-range end operator, tirx.cuda.iket_range_end.
- * Python: C.cuda_iket_range_end(token, payload=None).
+ * Python: C.iket_range_end(token, payload=None).
* Script: T.cuda.iket.range_end(token, payload=None).
* Operands: [0] token, an IntExpr identifying the range to end;
* [1...] args, the optional payload tail. IKET lowering requires a uint32 token.
@@ -71,7 +71,7 @@ TVM_TIRX_DLL const Op& iket_range_end_op();
/*!
* \brief Get the NVIDIA IKET stack-range push operator, tirx.cuda.iket_range_push.
- * Python: C.cuda_iket_range_push(name, payload=None).
+ * Python: C.iket_range_push(name, payload=None).
* Script: T.cuda.iket.range_push(name, payload=None).
* Operands: [0] name, the range name; [1...] args, the optional payload tail.
* Result: void. Effects: opaque stack-range push annotation.
@@ -80,7 +80,7 @@ TVM_TIRX_DLL const Op& iket_range_push_op();
/*!
* \brief Get the NVIDIA IKET stack-range pop operator, tirx.cuda.iket_range_pop.
- * Python: C.cuda_iket_range_pop(). Script: T.cuda.iket.range_pop().
+ * Python: C.iket_range_pop(). Script: T.cuda.iket.range_pop().
* Operands: none; IKET lowering enforces the empty operand list.
* Result: void. Effects: opaque stack-range pop annotation.
*/
@@ -88,7 +88,7 @@ TVM_TIRX_DLL const Op& iket_range_pop_op();
/*!
* \brief Get the NVIDIA IKET sentinel-token operator, tirx.cuda.iket_sentinel_token.
- * Python: C.cuda_iket_sentinel_token(name). Script: T.cuda.iket.sentinel_token(name).
+ * Python: C.iket_sentinel_token(name). Script: T.cuda.iket.sentinel_token(name).
* Operands: [0] name, the event name.
* Result: uint32 sentinel token. Registered effects: opaque. The sentinel carries
* token-flow identity; IKET lowering emits no runtime event for it.
@@ -97,11 +97,6 @@ TVM_TIRX_DLL const Op& iket_sentinel_token_op();
/*! \} */
-namespace attr {
-
-constexpr const char* kIKetEnabled = "tirx.iket.enabled";
-} // namespace attr
-
} // namespace cuda
} // namespace backend
} // namespace tvm
diff --git a/tirx/include/tvm/backend/cuda/op_attr_types.h b/tirx/include/tvm/backend/cuda/op_attr_types.h
index f3f6b4b2d6..e5f38bad09 100644
--- a/tirx/include/tvm/backend/cuda/op_attr_types.h
+++ b/tirx/include/tvm/backend/cuda/op_attr_types.h
@@ -16,7 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-
+/*!
+ * \file tvm/backend/cuda/op_attr_types.h
+ * \brief CUDA backend operator attribute keys.
+ */
#ifndef TVM_BACKEND_CUDA_OP_ATTR_TYPES_H_
#define TVM_BACKEND_CUDA_OP_ATTR_TYPES_H_
diff --git a/tirx/include/tvm/codegen/codegen.h b/tirx/include/tvm/codegen/codegen.h
index 8fdb4a1b0d..a7f465c43b 100644
--- a/tirx/include/tvm/codegen/codegen.h
+++ b/tirx/include/tvm/codegen/codegen.h
@@ -75,10 +75,8 @@ TVM_TIRX_DLL void PackImportsToObjectFile(const ffi::Module& mod, bool system_li
const std::string& c_symbol_prefix = "");
namespace attr {
-constexpr const char* kParallelStridePattern = "parallel_stride_pattern";
-
-constexpr const char* kRunnerFunction = "runner_function";
-
+inline constexpr ffi::reflection::AttrKey<bool> kParallelStridePattern{
+ "codegen.parallel_stride_pattern"};
} // namespace attr
} // namespace codegen
diff --git a/tirx/include/tvm/codegen/intrin_rule.h b/tirx/include/tvm/codegen/intrin_rule.h
index 4d0f866d88..45d534ccb4 100644
--- a/tirx/include/tvm/codegen/intrin_rule.h
+++ b/tirx/include/tvm/codegen/intrin_rule.h
@@ -72,12 +72,11 @@ template <typename T, bool dtype_from_arg = false>
inline PrimExpr DispatchPureExtern(const PrimExpr& e) {
const CallNode* call = e.as<CallNode>();
TVM_FFI_ICHECK(call != nullptr);
- // Both primitive and TIRx intrinsic names use a five-character namespace prefix.
+ // Primitive intrinsic names use the prim. namespace prefix.
const OpNode* op = call->op.as<OpNode>();
TVM_FFI_ICHECK(op != nullptr);
std::string name = op->name;
- TVM_FFI_ICHECK(name.substr(0, 5) == "tirx." || name.substr(0, 5) == "prim.")
- << "Unexpected intrinsic name: " << name;
+ TVM_FFI_ICHECK(name.substr(0, 5) == "prim.") << "Unexpected intrinsic name: " << name;
if (dtype_from_arg) {
TVM_FFI_ICHECK_EQ(call->args.size(), 1U);
}
diff --git a/tirx/include/tvm/ir/attrs.h b/tirx/include/tvm/ir/attrs.h
index 5a774f4a38..2288305f4e 100644
--- a/tirx/include/tvm/ir/attrs.h
+++ b/tirx/include/tvm/ir/attrs.h
@@ -80,7 +80,7 @@ class DictAttrsNode : public AttrsNode {
static void RegisterReflection() {
namespace rfl = ffi::reflection;
- rfl::ObjectDef<DictAttrsNode>().def_ro("__dict__", &DictAttrsNode::dict);
+ rfl::ObjectDef<DictAttrsNode>().def_ro("dict", &DictAttrsNode::dict);
}
// type info
diff --git a/tirx/include/tvm/ir/expr.h b/tirx/include/tvm/ir/expr.h
index f25cb63752..8e6b1e89a2 100644
--- a/tirx/include/tvm/ir/expr.h
+++ b/tirx/include/tvm/ir/expr.h
@@ -822,7 +822,7 @@ class LambdaExprNode : public StagingExprNode {
/*! \brief Managed reference to a typed staging lambda. */
class LambdaExpr : public StagingExpr {
public:
- TVM_TIRX_DLL explicit LambdaExpr(ffi::Array<Var> vars, Expr body);
+ TVM_TIRX_DLL explicit LambdaExpr(ffi::Array<Var> vars, Expr body, Location loc = UnknownLoc());
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(LambdaExpr, StagingExpr, LambdaExprNode);
};
diff --git a/tirx/include/tvm/ir/location.h b/tirx/include/tvm/ir/location.h
index df862b12cc..6546965e05 100644
--- a/tirx/include/tvm/ir/location.h
+++ b/tirx/include/tvm/ir/location.h
@@ -17,7 +17,7 @@
* under the License.
*/
/*!
- * \file location.h
+ * \file tvm/ir/location.h
* \brief Source locations and source-text lookup.
*/
#ifndef TVM_IR_LOCATION_H_
@@ -174,83 +174,6 @@ class CallSiteLoc : public Location {
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(CallSiteLoc, Location, CallSiteLocNode);
};
-/*! \brief A program source in any language.
- *
- * Could represent the source from an ML framework or a source
- * representing a tvm::IRModule.
- */
-class Source;
-
-class SourceObj : public ffi::Object {
- public:
- explicit SourceObj(SourceName source_name) : source_name(std::move(source_name)) {}
- explicit SourceObj(ffi::UnsafeInit tag) : source_name(tag) {}
- /*! \brief The source name. */
- SourceName source_name;
-
- /*! \brief The raw source. */
- ffi::String source;
-
- /*! \brief A mapping of line breaks into the raw source. */
- std::vector<std::pair<int, int>> line_map;
-
- static void RegisterReflection() {
- namespace refl = tvm::ffi::reflection;
- refl::ObjectDef<SourceObj>()
- .def_ro("source_name", &SourceObj::source_name)
- .def_ro("source", &SourceObj::source);
- }
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.Source", SourceObj, ffi::Object);
-};
-
-class Source : public ffi::ObjectRef {
- public:
- TVM_TIRX_DLL Source(SourceName src_name, std::string source);
- TVM_TIRX_DLL tvm::ffi::String GetLine(int line);
-
- TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Source, ffi::ObjectRef, SourceObj);
-};
-
-/*!
- * \brief A mapping from a unique source name to source fragment.
- */
-class SourceMap;
-/*!
- * \brief Stores locations in frontend source that generated a node.
- */
-class SourceMapObj : public ffi::Object {
- public:
- /*! \brief The source mapping. */
- ffi::Map<SourceName, Source> source_map;
-
- static void RegisterReflection() {
- namespace refl = tvm::ffi::reflection;
- refl::ObjectDef<SourceMapObj>().def_ro("source_map", &SourceMapObj::source_map);
- }
-
- static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindTreeNode;
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.SourceMap", SourceMapObj, ffi::Object);
-};
-
-class SourceMap : public ffi::ObjectRef {
- public:
- TVM_TIRX_DLL explicit SourceMap(ffi::Map<SourceName, Source> source_map);
-
- explicit SourceMap(std::initializer_list<std::pair<SourceName, Source>> source_map)
- : SourceMap(ffi::Map<SourceName, Source>(source_map)) {}
-
- SourceMap() : SourceMap(ffi::Map<SourceName, Source>()) {}
-
- void Add(const Source& source);
-
- SourceMapObj* operator->() {
- TVM_FFI_ICHECK(get() != nullptr);
- return static_cast<SourceMapObj*>(get_mutable());
- }
-
- TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(SourceMap, ffi::ObjectRef, SourceMapObj);
-};
-
} // namespace tvm
#endif // TVM_IR_LOCATION_H_
diff --git a/tirx/include/tvm/ir/module.h b/tirx/include/tvm/ir/module.h
index 04a2d8a99f..25dbf94575 100644
--- a/tirx/include/tvm/ir/module.h
+++ b/tirx/include/tvm/ir/module.h
@@ -61,8 +61,6 @@ class IRModuleNode : public ffi::Object {
public:
/*! \brief A map from ids to all global functions. */
ffi::Map<GlobalVar, BaseFunc> functions;
- /*! \brief The source map for the module. */
- SourceMap source_map;
/* \brief Additional attributes storing meta-data about the module. */
DictAttrs attrs;
/*! \brief Globally static object that are referred by the IR itself */
@@ -150,14 +148,13 @@ class IRModuleNode : public ffi::Object {
*/
bool HasNonzeroAttr(const std::string& attr_key) const { return attrs.HasNonzeroAttr(attr_key); }
- IRModuleNode() : source_map() {}
+ IRModuleNode() = default;
static void RegisterReflection() {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<IRModuleNode>()
.def_ro("functions", &IRModuleNode::functions)
.def_ro("global_var_map_", &IRModuleNode::global_var_map_)
- .def_ro("source_map", &IRModuleNode::source_map)
.def_ro("attrs", &IRModuleNode::attrs)
.def_ro("global_infos", &IRModuleNode::global_infos);
// register custom structural equal and hash.
@@ -256,10 +253,6 @@ class IRModuleNode : public ffi::Object {
* \returns The shallow copy of the IRModule.
*/
TVM_TIRX_DLL IRModule ShallowCopy();
- /*!
- * \brief The set of imported files.
- */
- TVM_TIRX_DLL std::unordered_set<ffi::String> Imports() const;
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindTreeNode;
@@ -279,11 +272,10 @@ class IRModule : public ffi::ObjectRef {
/*!
* \brief constructor
* \param functions Functions in the module.
- * \param map The module source map.
* \param attrs The module meta-data attributes.
* \param global_infos Global infos in the module.
*/
- TVM_TIRX_DLL explicit IRModule(ffi::Map<GlobalVar, BaseFunc> functions, SourceMap map = {},
+ TVM_TIRX_DLL explicit IRModule(ffi::Map<GlobalVar, BaseFunc> functions,
DictAttrs attrs = DictAttrs(),
ffi::Map<ffi::String, ffi::Array<GlobalInfo>> global_infos = {});
@@ -311,13 +303,6 @@ class IRModule : public ffi::ObjectRef {
TVM_TIRX_DLL static IRModule FromExpr(const Expr& expr,
const ffi::Map<GlobalVar, BaseFunc>& global_funcs = {});
- /*!
- * \brief Create a shallow copy of an IRModule.
- * \param mod The module to copy.
- * \return The copied module.
- */
- IRModule ShallowCopyIRModule(IRModule mod);
-
/*! \brief Declare the container type. */
using ContainerType = IRModuleNode;
@@ -329,13 +314,6 @@ namespace attr {
// Following are attributes for IRModule only.
-/*!
- * \brief Name of the module
- *
- * Type: String
- */
-constexpr const char* kModuleName = "mod_name";
-
/*!
* \brief All the runtime::Modules accumulated during compilation by external codegen. These
* modules must be either directly linked or captured in the final compilation artifact.
diff --git a/tirx/include/tvm/ir/prim/op.h b/tirx/include/tvm/ir/prim/op.h
index 53154d8ba1..2d332439cf 100644
--- a/tirx/include/tvm/ir/prim/op.h
+++ b/tirx/include/tvm/ir/prim/op.h
@@ -459,11 +459,11 @@ TVM_TIRX_DLL PrimExpr if_then_else(PrimExpr cond, PrimExpr true_value, PrimExpr
* \return The marked expression.
*/
TVM_TIRX_DLL PrimExpr likely(PrimExpr cond, Location loc = UnknownLoc());
+namespace prim {
/*! \brief Round up to the nearest integral value, preserving the input type. */
TVM_TIRX_DLL PrimExpr ceil(PrimExpr x, Location loc = UnknownLoc());
/*! \brief Construct a base-two logarithm with the input's primitive type. */
TVM_TIRX_DLL PrimExpr log2(PrimExpr x, Location loc = UnknownLoc());
-namespace prim {
/*! \brief Count leading zero bits, preserving the input primitive type. */
TVM_TIRX_DLL PrimExpr clz(PrimExpr x, Location loc = UnknownLoc());
/*!
diff --git a/tirx/include/tvm/ir/transform.h b/tirx/include/tvm/ir/transform.h
index d8d767c2f2..b08c6d8d4f 100644
--- a/tirx/include/tvm/ir/transform.h
+++ b/tirx/include/tvm/ir/transform.h
@@ -262,9 +262,9 @@ class PassInfo : public ffi::ObjectRef {
};
/*!
- * \brief PassObj is the base type of differnt types of optimization passes.
+ * \brief PassObj is the base type of different types of optimization passes.
* It is designed as a pure class and implemented by different pass subclasses
- * at different granularity of Relax nodes.
+ * at different granularity of IR nodes.
*/
class PassObj : public ffi::Object {
public:
@@ -333,7 +333,7 @@ class Pass : public ffi::ObjectRef {
};
/*!
- * \brief The SequentialObj contains a set of passes that transform Relax
+ * \brief The SequentialObj contains a set of passes that transform
* programs from one AST to another semantically equivalent one.
*
* One example of this level of pass is that the pass manager needs to correctly
diff --git a/tirx/include/tvm/ir/with_context.h b/tirx/include/tvm/ir/with_context.h
index f2e3fcbbbc..1c5bce47d2 100644
--- a/tirx/include/tvm/ir/with_context.h
+++ b/tirx/include/tvm/ir/with_context.h
@@ -83,7 +83,7 @@ class With {
ContextType* operator->() { return get(); }
const ContextType* operator->() const { return get(); }
ContextType& operator*() { return *get(); }
- const ContextType* operator*() const { return *get(); }
+ const ContextType& operator*() const { return *get(); }
ContextType operator()() { return ctx_; }
diff --git a/tirx/include/tvm/runtime/base.h b/tirx/include/tvm/runtime/base.h
index aa9c527d38..d4e7e6e20c 100644
--- a/tirx/include/tvm/runtime/base.h
+++ b/tirx/include/tvm/runtime/base.h
@@ -28,11 +28,11 @@
// we will avoid defining extra C APIs here
#include <tvm/ffi/c_api.h>
-// TVM version. Overridable at build time via -DTVM_VERSION="..." (scikit-build-core
+// TIRx version. Overridable at build time via -DTVM_TIRX_VERSION="..." (scikit-build-core
// passes the setuptools_scm-resolved version through CMake). The literal below is the
// fallback for a bare build with no override.
-#ifndef TVM_VERSION
-#define TVM_VERSION "0.1.0a0"
+#ifndef TVM_TIRX_VERSION
+#define TVM_TIRX_VERSION "0.1.0a0"
#endif
// The compiler, core runtime and runtime-extra libraries expose independent
diff --git a/tirx/include/tvm/runtime/c_backend_api.h b/tirx/include/tvm/runtime/c_backend_api.h
index d167e98a28..00410dfa5d 100644
--- a/tirx/include/tvm/runtime/c_backend_api.h
+++ b/tirx/include/tvm/runtime/c_backend_api.h
@@ -81,7 +81,9 @@ TVM_RUNTIME_DLL int TVMBackendGetDeviceIndex(int device_type, int* out_device_in
* certain backends such as OpenGL.
* \param dtype_bits_hint The type bits of the array elements. Only used in
* certain backends such as OpenGL.
- * \return nullptr when error is thrown, a valid ptr if success
+ * \return A valid pointer on success, nullptr on failure. Failure records the
+ * raised TVM FFI error on the calling thread; no C++ exception crosses this C
+ * entry point.
*/
TVM_RUNTIME_DLL void* TVMBackendAllocWorkspace(int device_type, int device_id, uint64_t nbytes,
int dtype_code_hint, int dtype_bits_hint);
@@ -92,7 +94,8 @@ TVM_RUNTIME_DLL void* TVMBackendAllocWorkspace(int device_type, int device_id, u
* \param ptr The result allocated space pointer.
* \param device_type The device type which the space will be allocated.
* \param device_id The device id which the space will be allocated.
- * \return 0 when no error is thrown, -1 when failure happens
+ * \return 0 on success, -1 on failure. Failure records the raised TVM FFI error
+ * on the calling thread; no C++ exception crosses this C entry point.
*
* \sa TVMBackendAllocWorkspace
*/
@@ -131,7 +134,7 @@ typedef int (*FTVMParallelLambda)(int task_id, TVMParallelGroupEnv* penv, void*
TVM_RUNTIME_DLL int TVMBackendParallelLaunch(FTVMParallelLambda flambda, void* cdata, int num_task);
/*!
- * \brief BSP barrrier between parallel threads
+ * \brief BSP barrier between parallel threads
* \param task_id the task id of the function.
* \param penv The parallel environment backs the execution.
* \return 0 when no error is thrown, -1 when failure happens
diff --git a/tirx/include/tvm/runtime/device_api.h b/tirx/include/tvm/runtime/device_api.h
index 0d54fe0b87..39bc1a2bb0 100644
--- a/tirx/include/tvm/runtime/device_api.h
+++ b/tirx/include/tvm/runtime/device_api.h
@@ -98,10 +98,6 @@ constexpr int kTempAllocaAlignment = 64;
/*! \brief Maximum size that can be allocated on stack */
constexpr int kMaxStackAlloca = 1024;
-/*! \brief Number of bytes each allocation must align to by default in the workspace buffer to
- * service intermediate tensors */
-constexpr int kDefaultWorkspaceAlignment = 1;
-
/*!
* \brief TVM Runtime Device API, abstracts the device
* specific interface for memory management.
@@ -238,7 +234,7 @@ class TVM_RUNTIME_DLL DeviceAPI {
static DeviceAPI* Get(Device dev, bool allow_missing = false);
/*!
- * \brief Whether a certian device type requires set device device
+ * \brief Whether a certain device type requires setting the device
* before launching the kernel function.
* \param device_type The device type.
*/
@@ -265,7 +261,7 @@ class TVM_RUNTIME_DLL DeviceAPI {
/*!
* \brief copy data from one place to another
* \param from The source array.
- * \param from_offset The byte offeset in the from.
+ * \param from_offset The byte offset in the from.
* \param to The target array.
* \param to_offset The byte offset in the to.
* \param num_bytes The size of the memory in bytes
diff --git a/tirx/include/tvm/runtime/memory_scope.h b/tirx/include/tvm/runtime/memory_scope.h
index 4755b59099..c9a7f390da 100644
--- a/tirx/include/tvm/runtime/memory_scope.h
+++ b/tirx/include/tvm/runtime/memory_scope.h
@@ -16,7 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-
+/*!
+ * \file tvm/runtime/memory_scope.h
+ * \brief Memory scopes and allocation properties for runtime storage.
+ */
#ifndef TVM_RUNTIME_MEMORY_SCOPE_H_
#define TVM_RUNTIME_MEMORY_SCOPE_H_
@@ -69,17 +72,7 @@ class MemoryScope : public ffi::Enum {
const ffi::String& name() const { return get()->_str_index; }
/*! \brief Test whether a name is registered, without initializing memory scopes. */
static bool IsDefined(const ffi::String& name) {
- namespace refl = ffi::reflection;
- constexpr auto key = refl::AsByteArray(ffi::type_attr::kEnumState.name);
- if (TVMFFIGetTypeAttrColumn(&key) == nullptr) return false;
- auto value = refl::TypeAttrColumn(
- ffi::type_attr::kEnumState)[MemoryScopeObj::_GetOrAllocRuntimeTypeIndex()];
- if (value == nullptr) return false;
- TVM_FFI_CHECK(value.type_index() == ffi::EnumStateObj::_GetOrAllocRuntimeTypeIndex(), TypeError)
- << "Expected enum state for memory scopes";
- // The derived EnumState type index may still be deferred during static initialization.
- auto* state = static_cast<const ffi::EnumStateObj*>(value.cast<ffi::ObjectRef>().get());
- return state->indexes.count(name) != 0;
+ return ffi::reflection::EnumDef<MemoryScopeObj>::IsDefined(name);
}
/*! \brief Look up a registered name. Unknown names raise ValueError. */
TVM_RUNTIME_DLL static MemoryScope Get(const ffi::String& name);
diff --git a/tirx/include/tvm/runtime/tensor.h b/tirx/include/tvm/runtime/tensor.h
index dea5a1361a..27c0795131 100644
--- a/tirx/include/tvm/runtime/tensor.h
+++ b/tirx/include/tvm/runtime/tensor.h
@@ -99,105 +99,19 @@ TVM_RUNTIME_DLL void CopyToBytes(ffi::TensorView source, void* destination_bytes
/*! \brief Magic number for Tensor file */
constexpr uint64_t kTVMTensorMagic = 0xDD5E40F096B4A13F;
-/*! \brief Save a tensor in the portable CPU tensor format. */
-inline void SaveTensor(ffi::TensorView source, support::Stream* strm) {
- const DLTensor* tensor = ffi::AnyView(source).cast<DLTensor*>();
- uint64_t header = kTVMTensorMagic, reserved = 0;
- strm->Write(header);
- strm->Write(reserved);
- // Always save data as CPU context
- //
- // Parameters that get serialized should be in CPU by default.
- // So even the array's context is GPU, it will be stored as CPU array.
- // This is used to prevent case when another user loads the parameters
- // back on machine that do not have GPU or related context.
- //
- // We can always do array.CopyTo(target_dev) to get a corresponding
- // array in the target context.
- Device cpu_dev;
- cpu_dev.device_type = kDLCPU;
- cpu_dev.device_id = 0;
- strm->Write(cpu_dev);
- strm->Write(tensor->ndim);
- strm->Write(tensor->dtype);
- int ndim = tensor->ndim;
- strm->WriteArray(tensor->shape, ndim);
- int type_bytes = (tensor->dtype.bits + 7) / 8;
- int64_t num_elems = 1;
- for (int i = 0; i < ndim; ++i) {
- num_elems *= tensor->shape[i];
- }
- int64_t data_byte_size = type_bytes * num_elems;
- strm->Write(data_byte_size);
-
- if (TVM_FFI_IO_NO_ENDIAN_SWAP && tensor->device.device_type == kDLCPU &&
- ffi::IsContiguous(*tensor) && tensor->byte_offset == 0) {
- // quick path
- strm->Write(tensor->data, data_byte_size);
- } else {
- std::vector<uint8_t> bytes(data_byte_size);
- CopyToBytes(source, bytes.data(), data_byte_size);
- if (!TVM_FFI_IO_NO_ENDIAN_SWAP) {
- ffi::ByteSwap(bytes.data(), type_bytes, num_elems);
- }
- strm->Write(bytes.data(), data_byte_size);
- }
-}
-
-/*! \brief Load a tensor from the portable format into CPU storage. */
-inline ffi::Tensor LoadTensor(support::Stream* strm) {
- uint64_t header, reserved;
- TVM_FFI_ICHECK(strm->Read(&header)) << "Invalid DLTensor file format";
- TVM_FFI_ICHECK(strm->Read(&reserved)) << "Invalid DLTensor file format";
- TVM_FFI_ICHECK(header == kTVMTensorMagic) << "Invalid DLTensor file format";
- Device dev;
- int ndim;
- DLDataType dtype;
- TVM_FFI_ICHECK(strm->Read(&dev)) << "Invalid DLTensor file format";
- TVM_FFI_ICHECK(strm->Read(&ndim)) << "Invalid DLTensor file format";
- TVM_FFI_ICHECK(strm->Read(&dtype)) << "Invalid DLTensor file format";
- TVM_FFI_ICHECK_EQ(dev.device_type, kDLCPU)
- << "Invalid DLTensor device: can only save as CPU tensor";
- std::vector<int64_t> shape(ndim);
- if (ndim != 0) {
- TVM_FFI_ICHECK(strm->ReadArray(&shape[0], ndim)) << "Invalid DLTensor file format";
- }
- ffi::Tensor ret = Empty(ffi::Shape(shape), dtype, dev);
- int64_t num_elems = 1;
- int elem_bytes = (ret.GetDLTensorPtr()->dtype.bits + 7) / 8;
- for (int i = 0; i < ret.GetDLTensorPtr()->ndim; ++i) {
- num_elems *= ret.shape()[i];
- }
- int64_t data_byte_size;
- TVM_FFI_ICHECK(strm->Read(&data_byte_size)) << "Invalid DLTensor file format";
- TVM_FFI_ICHECK(data_byte_size == num_elems * elem_bytes) << "Invalid DLTensor file format";
- auto read_ret = strm->Read(ret.GetDLTensorPtr()->data, data_byte_size);
- // Only check non-empty data
- if (ndim > 0 && shape[0] != 0) {
- TVM_FFI_ICHECK(read_ret) << "Invalid DLTensor file format";
- }
- if (!TVM_FFI_IO_NO_ENDIAN_SWAP) {
- ffi::ByteSwap(ret.GetDLTensorPtr()->data, elem_bytes, num_elems);
- }
- return ret;
-}
+/*!
+ * \brief Save a tensor in the portable CPU tensor format.
+ * \param source The tensor to save. Non-CPU tensors are copied to the host first.
+ * \param strm The output stream.
+ */
+TVM_RUNTIME_DLL void SaveTensor(ffi::TensorView source, support::Stream* strm);
/*!
- * \brief Get the preferred host device from the input device.
- * - For CUDA and ROCm, CUDAHost and ROCMHost will be returned for pinned memory,
- * since pinned memory reduces copy overhead.
- * - For other devices, CPU is returned as a fallback.
+ * \brief Load a tensor from the portable format into CPU storage.
+ * \param strm The input stream.
+ * \return The loaded CPU tensor.
*/
-inline Device GetPreferredHostDevice(Device device) {
- if (device.device_type == DLDeviceType::kDLCUDA) {
- return Device{DLDeviceType::kDLCUDAHost, 0};
- } else if (device.device_type == DLDeviceType::kDLROCM) {
- return Device{DLDeviceType::kDLROCMHost, 0};
- } else {
- // Fallback to CPU.
- return Device{DLDeviceType::kDLCPU, 0};
- }
-}
+TVM_RUNTIME_DLL ffi::Tensor LoadTensor(support::Stream* strm);
class TensorMemoryPool;
diff --git a/tirx/include/tvm/runtime/timer.h b/tirx/include/tvm/runtime/timer.h
index ff4df2c1b2..07abab3b0d 100644
--- a/tirx/include/tvm/runtime/timer.h
+++ b/tirx/include/tvm/runtime/timer.h
@@ -18,8 +18,8 @@
*/
/*!
- * \file include/tvm/runtime/timer.h
- * \brief Runtime timer primitives: Timer, TimerObj, WrapTimeEvaluator.
+ * \file tvm/runtime/timer.h
+ * \brief Runtime timer primitives: Timer, TimerObj.
*/
#ifndef TVM_RUNTIME_TIMER_H_
#define TVM_RUNTIME_TIMER_H_
@@ -65,7 +65,7 @@ class TimerObj : public ffi::Object {
virtual ~TimerObj() {}
static constexpr const bool _type_mutable = true;
- TVM_FFI_DECLARE_OBJECT_INFO("runtime.TimerNode", TimerObj, ffi::Object);
+ TVM_FFI_DECLARE_OBJECT_INFO("runtime.Timer", TimerObj, ffi::Object);
};
/*! \brief Timer for a specific device.
@@ -140,58 +140,6 @@ class Timer : public ffi::ObjectRef {
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Timer, ffi::ObjectRef, TimerObj);
};
-/*!
- * \brief Wrap a timer function to measure the time cost of a given packed function.
- *
- * Approximate implementation:
- * \code{.py}
- * f() // warmup
- * for i in range(repeat)
- * f_preproc()
- * while True:
- * start = time()
- * for j in range(number):
- * f()
- * duration_ms = time() - start
- * if duration_ms >= min_repeat_ms:
- * break
- * else:
- * number = (min_repeat_ms / (duration_ms / number) + 1
- * if cooldown_interval_ms and i % repeats_to_cooldown == 0:
- * sleep(cooldown_interval_ms)
- * \endcode
- *
- * \param f The function argument.
- * \param dev The device.
- * \param number The number of times to run this function for taking average.
- * We call these runs as one `repeat` of measurement.
- * \param repeat The number of times to repeat the measurement.
- * In total, the function will be invoked (1 + number x repeat) times,
- * where the first one is warm up and will be discarded.
- * The returned result contains `repeat` costs,
- * each of which is an average of `number` costs.
- * \param min_repeat_ms The minimum duration of one `repeat` in milliseconds.
- * By default, one `repeat` contains `number` runs. If this parameter is set,
- * the parameters `number` will be dynamically adjusted to meet the
- * minimum duration requirement of one `repeat`.
- * i.e., When the run time of one `repeat` falls below this time,
- * the `number` parameter will be automatically increased.
- * \param limit_zero_time_iterations The maximum number of repeats when
- * measured time is equal to 0. It helps to avoid hanging during measurements.
- * \param cooldown_interval_ms The cooldown interval in milliseconds between the number of repeats
- * defined by `repeats_to_cooldown`.
- * \param repeats_to_cooldown The number of repeats before the
- * cooldown is activated.
- * \param cache_flush_bytes The number of bytes to flush from cache before
- * \param f_preproc The function to be executed before we execute time
- * evaluator.
- * \return f_timer A timer function.
- */
-ffi::Function WrapTimeEvaluator(ffi::Function f, Device dev, int number, int repeat,
- int min_repeat_ms, int limit_zero_time_iterations,
- int cooldown_interval_ms, int repeats_to_cooldown,
- int cache_flush_bytes = 0, ffi::Function f_preproc = nullptr);
-
} // namespace runtime
} // namespace tvm
diff --git a/tirx/include/tvm/script/ir_builder/base.h b/tirx/include/tvm/script/ir_builder/base.h
index bccff9eec2..580f78b122 100644
--- a/tirx/include/tvm/script/ir_builder/base.h
+++ b/tirx/include/tvm/script/ir_builder/base.h
@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
+/*!
+ * \file tvm/script/ir_builder/base.h
+ * \brief Base IRBuilder and frame definitions.
+ */
#ifndef TVM_SCRIPT_IR_BUILDER_BASE_H_
#define TVM_SCRIPT_IR_BUILDER_BASE_H_
diff --git a/tirx/include/tvm/script/ir_builder/frame.h b/tirx/include/tvm/script/ir_builder/frame.h
index 07f8aff0e4..7e7b215897 100644
--- a/tirx/include/tvm/script/ir_builder/frame.h
+++ b/tirx/include/tvm/script/ir_builder/frame.h
@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
+/*!
+ * \file tvm/script/ir_builder/frame.h
+ * \brief Shared IRBuilder frames for IRModules and statements.
+ */
#ifndef TVM_SCRIPT_IR_BUILDER_FRAME_H_
#define TVM_SCRIPT_IR_BUILDER_FRAME_H_
@@ -152,7 +156,7 @@ class ForFrameObj : public StmtFrameObj {
.def_ro("doms", &ForFrameObj::doms);
// `f_make_for_loop` is not registered as it's not visited.
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.tirx.ForFrame", ForFrameObj, StmtFrameObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.ForFrame", ForFrameObj, StmtFrameObj);
public:
/*! \brief Apply source target names before entry, preserving variable identity. */
@@ -202,8 +206,7 @@ class AssertFrameObj : public StmtFrameObj {
.def_ro("error_kind", &AssertFrameObj::error_kind)
.def_ro("message_parts", &AssertFrameObj::message_parts);
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.tirx.AssertFrame", AssertFrameObj,
- StmtFrameObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.AssertFrame", AssertFrameObj, StmtFrameObj);
public:
/*!
@@ -253,8 +256,7 @@ class RegionFrameObj : public StmtFrameObj {
.def_ro("body_params", &RegionFrameObj::body_params)
.def_ro("attrs", &RegionFrameObj::attrs);
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.tirx.RegionFrame", RegionFrameObj,
- StmtFrameObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.RegionFrame", RegionFrameObj, StmtFrameObj);
/*! \brief Construct the region and add it to the enclosing builder frame. */
void ExitWithScope() final;
@@ -288,8 +290,7 @@ class WhileFrameObj : public StmtFrameObj {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<WhileFrameObj>().def_ro("condition", &WhileFrameObj::condition);
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.tirx.WhileFrame", WhileFrameObj,
- StmtFrameObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.WhileFrame", WhileFrameObj, StmtFrameObj);
public:
/*!
@@ -338,7 +339,7 @@ class IfFrameObj : public StmtFrameObj {
.def_ro("then_stmts", &IfFrameObj::then_stmts)
.def_ro("else_stmts", &IfFrameObj::else_stmts);
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.tirx.IfFrame", IfFrameObj, StmtFrameObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.IfFrame", IfFrameObj, StmtFrameObj);
public:
/*!
@@ -372,7 +373,7 @@ class ThenFrameObj : public StmtFrameObj {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<ThenFrameObj>();
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.tirx.ThenFrame", ThenFrameObj, StmtFrameObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.ThenFrame", ThenFrameObj, StmtFrameObj);
public:
/*!
@@ -411,7 +412,7 @@ class ElseFrameObj : public StmtFrameObj {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<ElseFrameObj>();
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.tirx.ElseFrame", ElseFrameObj, StmtFrameObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("script.ir_builder.ElseFrame", ElseFrameObj, StmtFrameObj);
public:
/*!
diff --git a/tirx/include/tvm/script/ir_builder/ir.h b/tirx/include/tvm/script/ir_builder/ir.h
index 725434a73c..271914c8c3 100644
--- a/tirx/include/tvm/script/ir_builder/ir.h
+++ b/tirx/include/tvm/script/ir_builder/ir.h
@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
+/*!
+ * \file tvm/script/ir_builder/ir.h
+ * \brief Shared IRBuilder APIs for IRModule construction.
+ */
#ifndef TVM_SCRIPT_IR_BUILDER_IR_H_
#define TVM_SCRIPT_IR_BUILDER_IR_H_
diff --git a/tirx/include/tvm/script/printer/doc.h b/tirx/include/tvm/script/printer/doc.h
index b8afc30f40..6441b40b97 100644
--- a/tirx/include/tvm/script/printer/doc.h
+++ b/tirx/include/tvm/script/printer/doc.h
@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
+/*!
+ * \file tvm/script/printer/doc.h
+ * \brief Doc nodes used by the TVMScript printer.
+ */
#ifndef TVM_SCRIPT_PRINTER_DOC_H_
#define TVM_SCRIPT_PRINTER_DOC_H_
diff --git a/tirx/include/tvm/script/printer/doc_translator.h b/tirx/include/tvm/script/printer/doc_translator.h
index ea58c960c9..283fa81d55 100644
--- a/tirx/include/tvm/script/printer/doc_translator.h
+++ b/tirx/include/tvm/script/printer/doc_translator.h
@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
+/*!
+ * \file tvm/script/printer/doc_translator.h
+ * \brief Translator from IR values to printer docs.
+ */
#ifndef TVM_SCRIPT_PRINTER_DOC_TRANSLATOR_H_
#define TVM_SCRIPT_PRINTER_DOC_TRANSLATOR_H_
diff --git a/tirx/include/tvm/support/base64.h b/tirx/include/tvm/support/base64.h
deleted file mode 100644
index 36cb81cb54..0000000000
--- a/tirx/include/tvm/support/base64.h
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- *
- * \file base64.h
- * \brief data stream support to input and output from/to base64 stream
- * base64 is easier to store and pass as text format in mapreduce
- */
-#ifndef TVM_SUPPORT_BASE64_H_
-#define TVM_SUPPORT_BASE64_H_
-
-#include <tvm/ffi/error.h>
-#include <tvm/support/io.h>
-
-#include <cctype>
-#include <cstdio>
-#include <string>
-
-namespace tvm {
-namespace support {
-/*! \brief namespace of base64 decoding and encoding table */
-namespace base64 {
-// decoding table
-const char DecodeTable[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, // '+'
- 0, 0, 0,
- 63, // '/'
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
- 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
-};
-// encoding table
-static const char EncodeTable[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-} // namespace base64
-
-/*!
- * \brief Buffer reader from stream to avoid
- * virtual call overhead on each read.
- */
-class StreamBufferReader {
- public:
- explicit StreamBufferReader(size_t buffer_size) { buffer_.resize(buffer_size); }
- /*!
- * \brief set input stream
- * \param stream The stream to be set
- */
- void set_stream(tvm::support::Stream* stream) {
- stream_ = stream;
- read_len_ = read_ptr_ = 1;
- }
- /*!
- * \return allows quick read using get char
- */
- int GetChar() {
- while (true) {
- if (read_ptr_ < read_len_) {
- return static_cast<int>(buffer_[read_ptr_++]);
- } else {
- read_len_ = stream_->Read(&buffer_[0], buffer_.length());
- if (read_len_ == 0) return EOF;
- read_ptr_ = 0;
- }
- }
- }
- /*! \return whether we are reaching the end of file */
- bool AtEnd() const { return read_len_ == 0; }
-
- private:
- /*! \brief the underlying stream */
- tvm::support::Stream* stream_{nullptr};
- /*! \brief buffer to hold data */
- std::string buffer_;
- /*! \brief length of valid data in buffer */
- size_t read_len_{1};
- /*! \brief pointer in the buffer */
- size_t read_ptr_{1};
-};
-
-/*!
- * \brief Input stream from base64 encoding
- */
-class Base64InStream : public tvm::support::Stream {
- public:
- explicit Base64InStream(tvm::support::Stream* fs) : reader_(256) { reader_.set_stream(fs); }
- /*!
- * \brief initialize the stream position to beginning of next base64 stream
- * \note call this function before actually start read
- */
- void InitPosition(void) {
- // get a character
- do {
- temp_ch_ = reader_.GetChar();
- } while (isspace(temp_ch_));
- }
- /*! \brief whether current position is end of a base64 stream */
- bool IsEOF(void) const { return num_prev_ == 0 && (temp_ch_ == EOF || isspace(temp_ch_)); }
-
- using tvm::support::Stream::Read;
- // override read function.
- size_t Read(void* ptr, size_t size) final {
- using base64::DecodeTable;
- if (size == 0) return 0;
- // use tlen to record left size
- size_t tlen = size;
- unsigned char* cptr = static_cast<unsigned char*>(ptr);
- // if anything left, load from previous buffered result
- if (num_prev_ != 0) {
- if (num_prev_ == 2) {
- if (tlen >= 2) {
- *cptr++ = buf_prev[0];
- *cptr++ = buf_prev[1];
- tlen -= 2;
- num_prev_ = 0;
- } else {
- // assert tlen == 1
- *cptr++ = buf_prev[0];
- --tlen;
- buf_prev[0] = buf_prev[1];
- num_prev_ = 1;
- }
- } else {
- // assert num_prev_ == 1
- *cptr++ = buf_prev[0];
- --tlen;
- num_prev_ = 0;
- }
- }
- if (tlen == 0) return size;
- int nvalue;
- // note: everything goes with 4 bytes in Base64
- // so we process 4 bytes a unit
- while (tlen && temp_ch_ != EOF && !isspace(temp_ch_)) {
- // first byte
- nvalue = DecodeTable[temp_ch_] << 18;
- {
- // second byte
- temp_ch_ = reader_.GetChar();
- TVM_FFI_ICHECK(temp_ch_ != EOF && !isspace(temp_ch_)) << "invalid base64 format";
- nvalue |= DecodeTable[temp_ch_] << 12;
- *cptr++ = (nvalue >> 16) & 0xFF;
- --tlen;
- }
- {
- // third byte
- temp_ch_ = reader_.GetChar();
- TVM_FFI_ICHECK(temp_ch_ != EOF && !isspace(temp_ch_)) << "invalid base64 format";
- // handle termination
- if (temp_ch_ == '=') {
- temp_ch_ = reader_.GetChar();
- TVM_FFI_ICHECK(temp_ch_ == '=') << "invalid base64 format";
- temp_ch_ = reader_.GetChar();
- TVM_FFI_ICHECK(temp_ch_ == EOF || isspace(temp_ch_)) << "invalid base64 format";
- break;
- }
- nvalue |= DecodeTable[temp_ch_] << 6;
- if (tlen) {
- *cptr++ = (nvalue >> 8) & 0xFF;
- --tlen;
- } else {
- buf_prev[num_prev_++] = (nvalue >> 8) & 0xFF;
- }
- }
- {
- // fourth byte
- temp_ch_ = reader_.GetChar();
- TVM_FFI_ICHECK(temp_ch_ != EOF && !isspace(temp_ch_)) << "invalid base64 format";
- if (temp_ch_ == '=') {
- temp_ch_ = reader_.GetChar();
- TVM_FFI_ICHECK(temp_ch_ == EOF || isspace(temp_ch_)) << "invalid base64 format";
- break;
- }
- nvalue |= DecodeTable[temp_ch_];
- if (tlen) {
- *cptr++ = nvalue & 0xFF;
- --tlen;
- } else {
- buf_prev[num_prev_++] = nvalue & 0xFF;
- }
- }
- // get next char
- temp_ch_ = reader_.GetChar();
- }
- if (kStrictCheck) {
- TVM_FFI_ICHECK_EQ(tlen, 0) << "Base64InStream: read incomplete";
- }
- return size - tlen;
- }
- size_t Write(const void* ptr, size_t size) final {
- TVM_FFI_THROW(InternalError) << "Base64InStream do not support write";
- return 0;
- }
-
- private:
- // internal reader
- StreamBufferReader reader_;
- int temp_ch_{0};
- int num_prev_{0};
- unsigned char buf_prev[2];
- // whether we need to do strict check
- static const bool kStrictCheck = false;
-};
-
-/*!
- * \brief Stream to write to base64 format.
- */
-class Base64OutStream : public tvm::support::Stream {
- public:
- explicit Base64OutStream(tvm::support::Stream* fp) : fp_(fp) {}
-
- using tvm::support::Stream::Write;
-
- size_t Write(const void* ptr, size_t size) final {
- using base64::EncodeTable;
- size_t tlen = size;
- const unsigned char* cptr = static_cast<const unsigned char*>(ptr);
- while (tlen) {
- while (buf__top_ < 3 && tlen != 0) {
- buf_[++buf__top_] = *cptr++;
- --tlen;
- }
- if (buf__top_ == 3) {
- // flush 4 bytes out
- PutChar(EncodeTable[buf_[1] >> 2]);
- PutChar(EncodeTable[((buf_[1] << 4) | (buf_[2] >> 4)) & 0x3F]);
- PutChar(EncodeTable[((buf_[2] << 2) | (buf_[3] >> 6)) & 0x3F]);
- PutChar(EncodeTable[buf_[3] & 0x3F]);
- buf__top_ = 0;
- }
- }
- return size;
- }
- virtual size_t Read(void* ptr, size_t size) {
- TVM_FFI_THROW(InternalError) << "Base64OutStream do not support read";
- return 0;
- }
- /*!
- * \brief finish writing of all current base64 stream, do some post processing
- * \param endch character to put to end of stream, if it is EOF, then nothing will be appended.
- */
- void Finish(int endch = EOF) {
- using base64::EncodeTable;
- if (buf__top_ == 1) {
- PutChar(EncodeTable[buf_[1] >> 2]);
- PutChar(EncodeTable[(buf_[1] << 4) & 0x3F]);
- PutChar('=');
- PutChar('=');
- }
- if (buf__top_ == 2) {
- PutChar(EncodeTable[buf_[1] >> 2]);
- PutChar(EncodeTable[((buf_[1] << 4) | (buf_[2] >> 4)) & 0x3F]);
- PutChar(EncodeTable[(buf_[2] << 2) & 0x3F]);
- PutChar('=');
- }
- buf__top_ = 0;
- if (endch != EOF) PutChar(endch);
- this->Flush();
- }
-
- private:
- static constexpr size_t kBufferSize = 256;
-
- tvm::support::Stream* fp_{nullptr};
- int buf__top_{0};
- unsigned char buf_[4];
- std::string out_buf_;
-
- void PutChar(char ch) {
- out_buf_ += ch;
- if (out_buf_.length() >= kBufferSize) Flush();
- }
- void Flush(void) {
- if (out_buf_.length() != 0) {
- fp_->Write(&out_buf_[0], out_buf_.length());
- out_buf_.clear();
- }
- }
-};
-} // namespace support
-} // namespace tvm
-#endif // TVM_SUPPORT_BASE64_H_
diff --git a/tirx/include/tvm/support/bytes_io.h b/tirx/include/tvm/support/bytes_io.h
index 5c9d0a4f09..233393634f 100644
--- a/tirx/include/tvm/support/bytes_io.h
+++ b/tirx/include/tvm/support/bytes_io.h
@@ -18,7 +18,7 @@
*/
/*!
- * \file support/bytes_io.h
+ * \file tvm/support/bytes_io.h
* \brief In-memory byte stream implementations.
*
* BytesInStream — sequential read from a fixed memory region
diff --git a/tirx/include/tvm/support/cuda/nvtx.h b/tirx/include/tvm/support/cuda/nvtx.h
deleted file mode 100644
index a2e58523f7..0000000000
--- a/tirx/include/tvm/support/cuda/nvtx.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*!
- * \file tvm/support/cuda/nvtx.h
- * \brief NVTX scoped range utility (header-only).
- *
- * Provides NVTXScopedRange: a lightweight RAII wrapper over
- * nvtxRangePush/Pop. When TVM_NVTX_ENABLED is not defined or is 0,
- * all methods are no-ops compiled away by the optimizer.
- */
-#ifndef TVM_SUPPORT_CUDA_NVTX_H_
-#define TVM_SUPPORT_CUDA_NVTX_H_
-
-#include <string>
-
-#ifndef TVM_NVTX_ENABLED
-#define TVM_NVTX_ENABLED 0
-#endif
-
-#if TVM_NVTX_ENABLED
-#include <nvtx3/nvToolsExt.h>
-#endif // TVM_NVTX_ENABLED
-
-namespace tvm {
-namespace support {
-
-/*!
- * \brief A class to create a NVTX range. No-op if TVM is not built against NVTX.
- */
-class NVTXScopedRange {
- public:
- /*! \brief Enter an NVTX scoped range */
-#if TVM_NVTX_ENABLED
- explicit NVTXScopedRange(const char* name) { nvtxRangePush(name); }
-#else
- explicit NVTXScopedRange(const char* name) {}
-#endif // TVM_NVTX_ENABLED
- /*! \brief Enter an NVTX scoped range */
- explicit NVTXScopedRange(const std::string& name) : NVTXScopedRange(name.c_str()) {}
- /*! \brief Exit an NVTX scoped range */
-#if TVM_NVTX_ENABLED
- ~NVTXScopedRange() { nvtxRangePop(); }
-#else
- ~NVTXScopedRange() {}
-#endif // TVM_NVTX_ENABLED
- NVTXScopedRange(const NVTXScopedRange& other) = delete;
- NVTXScopedRange(NVTXScopedRange&& other) = delete;
- NVTXScopedRange& operator=(const NVTXScopedRange& other) = delete;
- NVTXScopedRange& operator=(NVTXScopedRange&& other) = delete;
-};
-
-} // namespace support
-} // namespace tvm
-
-#endif // TVM_SUPPORT_CUDA_NVTX_H_
diff --git a/tirx/include/tvm/support/env.h b/tirx/include/tvm/support/env.h
index 81e865290f..a9480331fd 100644
--- a/tirx/include/tvm/support/env.h
+++ b/tirx/include/tvm/support/env.h
@@ -18,7 +18,7 @@
*/
/*!
- * \file support/env.h
+ * \file tvm/support/env.h
* \brief Typed environment variable access.
*/
#ifndef TVM_SUPPORT_ENV_H_
diff --git a/tirx/include/tvm/support/ordered_map.h b/tirx/include/tvm/support/ordered_map.h
index 81b0fd38a7..15f833dc01 100644
--- a/tirx/include/tvm/support/ordered_map.h
+++ b/tirx/include/tvm/support/ordered_map.h
@@ -18,7 +18,7 @@
*/
/*!
- * \file support/ordered_map.h
+ * \file tvm/support/ordered_map.h
* \brief An STL-like map that preserves insertion order.
*/
#ifndef TVM_SUPPORT_ORDERED_MAP_H_
diff --git a/tirx/include/tvm/support/str_escape.h b/tirx/include/tvm/support/str_escape.h
deleted file mode 100644
index 07599b256f..0000000000
--- a/tirx/include/tvm/support/str_escape.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- *
- * \file support/str_escape.h
- * \brief Print escape sequence of a string.
- */
-#ifndef TVM_SUPPORT_STR_ESCAPE_H_
-#define TVM_SUPPORT_STR_ESCAPE_H_
-
-#include <sstream>
-#include <string>
-
-namespace tvm {
-namespace support {
-
-/*!
- * \brief Create a stream with escape.
- *
- * \param data The data
- *
- * \param size The size of the string.
- *
- * \param use_octal_escape True to use octal escapes instead of hex. If producing C
- * strings, use octal escapes to avoid ambiguously-long hex escapes.
- *
- * \param escape_whitespace_special_chars If True (default), escape
- * any tab, newline, and carriage returns that occur in the string.
- * If False, do not escape these characters.
- *
- * \return the Result string.
- */
-inline std::string StrEscape(const char* data, size_t size, bool use_octal_escape = false,
- bool escape_whitespace_special_chars = true) {
- std::ostringstream stream;
- for (size_t i = 0; i < size; ++i) {
- unsigned char c = data[i];
- if (c >= ' ' && c <= '~' && c != '\\' && c != '"') {
- stream << c;
- } else {
- switch (c) {
- case '"':
- stream << '\\' << '"';
- break;
- case '\\':
- stream << '\\' << '\\';
- break;
- case '\t':
- if (escape_whitespace_special_chars) {
- stream << '\\' << 't';
- } else {
- stream << c;
- }
- break;
- case '\r':
- if (escape_whitespace_special_chars) {
- stream << '\\' << 'r';
- } else {
- stream << c;
- }
- break;
- case '\n':
- if (escape_whitespace_special_chars) {
- stream << '\\' << 'n';
- } else {
- stream << c;
- }
- break;
- default:
- if (use_octal_escape) {
- stream << '\\' << static_cast<unsigned char>('0' + ((c >> 6) & 0x03))
- << static_cast<unsigned char>('0' + ((c >> 3) & 0x07))
- << static_cast<unsigned char>('0' + (c & 0x07));
- } else {
- const char* hex_digits = "0123456789ABCDEF";
- stream << '\\' << 'x' << hex_digits[c >> 4] << hex_digits[c & 0xf];
- }
- }
- }
- }
- return stream.str();
-}
-
-/*!
- * \brief Create a stream with escape.
- *
- * \param val The C++ string
- *
- * \param use_octal_escape True to use octal escapes instead of hex. If producing C
- * strings, use octal escapes to avoid ambiguously-long hex escapes.
- *
- * \param escape_whitespace_special_chars If True (default), escape
- * any tab, newline, and carriage returns that occur in the string.
- * If False, do not escape these characters. If producing python
- * strings with """triple quotes""", do not escape these characters.
- *
- * \return the Result string.
- */
-inline std::string StrEscape(const std::string& val, bool use_octal_escape = false,
- bool escape_whitespace_special_chars = true) {
- return StrEscape(val.data(), val.length(), use_octal_escape, escape_whitespace_special_chars);
-}
-
-} // namespace support
-} // namespace tvm
-#endif // TVM_SUPPORT_STR_ESCAPE_H_
diff --git a/tirx/include/tvm/sym/bound.h b/tirx/include/tvm/sym/bound.h
index e8deed0652..5bee6dddef 100644
--- a/tirx/include/tvm/sym/bound.h
+++ b/tirx/include/tvm/sym/bound.h
@@ -27,14 +27,12 @@
#include <tvm/ir/prim/expr.h>
#include <tvm/sym/int_set.h>
-#include <unordered_map>
-
namespace tvm {
namespace sym {
/*!
- * \brief Deduce the bound of the target variable in a expression,
- * give the domain of each variables. Return undefined IntSet to
+ * \brief Deduce the bound of the target variable in an expression,
+ * given the domain of each variable. Return IntSet::Nothing() to
* represent failure.
*
* \note The returned set may be smaller than set that
@@ -44,24 +42,11 @@ namespace sym {
* \param cond The conditional expression.
* \param hint_map The domain of variable, used to help deduce.
* \param relax_map The domain of each variable, used to relax the domain,
- * The deduce bound must implies e for all value in relax_map
- * \return An integer set that always satisfies the condition.
- */
-IntSet DeduceBound(PrimExpr v, PrimExpr cond, const ffi::Map<Var, IntSet>& hint_map,
- const ffi::Map<Var, IntSet>& relax_map);
-/*!
- * \brief Same as DeduceBound with unordered_map signature.
- *
- * \param v The target variable to be deduced.
- * \param cond The conditional expression.
- * \param hint_map The domain of variable, used to help deduce.
- * \param relax_map The domain of each variable, used to relax the domain,
- * The deduce bound mush implies e for all value in relax_map
+ * The deduce bound must imply e for all value in relax_map
* \return An integer set that always satisfies the condition.
*/
-TVM_TIRX_DLL IntSet DeduceBound(PrimExpr v, PrimExpr cond,
- const std::unordered_map<const VarNode*, IntSet>& hint_map,
- const std::unordered_map<const VarNode*, IntSet>& relax_map);
+TVM_TIRX_DLL IntSet DeduceBound(PrimExpr v, PrimExpr cond, const ffi::Map<Var, IntSet>& hint_map,
+ const ffi::Map<Var, IntSet>& relax_map);
} // namespace sym
} // namespace tvm
diff --git a/tirx/include/tvm/sym/int_set.h b/tirx/include/tvm/sym/int_set.h
index 8758796b33..c71307c4bd 100644
--- a/tirx/include/tvm/sym/int_set.h
+++ b/tirx/include/tvm/sym/int_set.h
@@ -53,7 +53,7 @@ enum SignType { kPositive, kNegative, kZero, kUnknown };
*/
class IntSetObj : public ffi::Object {
public:
- TVM_FFI_DECLARE_OBJECT_INFO("ir.IntSet", IntSetObj, ffi::Object);
+ TVM_FFI_DECLARE_OBJECT_INFO("sym.IntSet", IntSetObj, ffi::Object);
};
/*!
@@ -161,17 +161,6 @@ class IntSet : public ffi::ObjectRef {
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(IntSet, ffi::ObjectRef, IntSetObj);
};
-//-----------------------------------------------
-// Integer set legacy API.
-//------------------------------------------------
-/*!
- * \brief Convert std::unordered_map<const VarNode*, IntSet> to ffi::Map<Var, IntSet>
- *
- * \param dom_map The domain map to convert.
- * \return The converted map.
- */
-TVM_TIRX_DLL ffi::Map<Var, IntSet> ConvertDomMap(
- const std::unordered_map<const VarNode*, IntSet>& dom_map);
/*!
* \brief Find an symbolic integer set that contains all possible values of
* e given the domain of each variables.
@@ -181,15 +170,6 @@ TVM_TIRX_DLL ffi::Map<Var, IntSet> ConvertDomMap(
* \return An integer set that can cover all the possible values of e.
*/
TVM_TIRX_DLL IntSet EvalSet(PrimExpr e, const ffi::Map<Var, IntSet>& dom_map);
-/*!
- * \brief Same as EvalSet, but takes unordered_map
- *
- * \param e The expression to be evaluated.
- * \param dom_map The domain of each variable.
- * \return An integer set that can cover all the possible values of e.
- */
-TVM_TIRX_DLL IntSet EvalSet(PrimExpr e, const std::unordered_map<const VarNode*, IntSet>& dom_map);
-
/*!
* \brief Find an symbolic integer set that contains is union over
* all the possible conditional values in dom_map.
@@ -198,15 +178,15 @@ TVM_TIRX_DLL IntSet EvalSet(PrimExpr e, const std::unordered_map<const VarNode*,
* \param dom_map The domain of each variable.
* \return An integer set that can cover all the possible values.
*/
-TVM_TIRX_DLL IntSet EvalSet(IntSet s, const std::unordered_map<const VarNode*, IntSet>& dom_map);
+TVM_TIRX_DLL IntSet EvalSet(IntSet s, const ffi::Map<Var, IntSet>& dom_map);
/*!
- * \brief Same as EvalSet, but takes unordered_map
+ * \brief Evaluate the range over the domain of each variable
*
* \param r The range to be evaluated.
* \param dom_map The domain of each variable.
* \return An integer set that can cover all the possible values of e.
*/
-TVM_TIRX_DLL IntSet EvalSet(Range r, const std::unordered_map<const VarNode*, IntSet>& dom_map);
+TVM_TIRX_DLL IntSet EvalSet(Range r, const ffi::Map<Var, IntSet>& dom_map);
/*!
* \brief Same as EvalSet, but takes ffi::Array<Range>
*
@@ -226,8 +206,7 @@ using ExprIntSetMap = std::unordered_map<PrimExpr, IntSet, ffi::ObjectPtrHash, f
* \param dom_map The domain of each variable.
* \return the map from the expression to its possible value.
*/
-TVM_TIRX_DLL ExprIntSetMap
-EvalSetForEachSubExpr(PrimExpr e, const std::unordered_map<const VarNode*, IntSet>& dom_map);
+TVM_TIRX_DLL ExprIntSetMap EvalSetForEachSubExpr(PrimExpr e, const ffi::Map<Var, IntSet>& dom_map);
/*!
* \brief Create a union set of all sets, possibly relaxed
diff --git a/tirx/include/tvm/target/target.h b/tirx/include/tvm/target/target.h
index b1dce829e9..52ed87c731 100644
--- a/tirx/include/tvm/target/target.h
+++ b/tirx/include/tvm/target/target.h
@@ -172,16 +172,12 @@ class Target : public ffi::ObjectRef {
Target WithoutHost() const;
private:
- Target(TargetKind kind, ffi::Optional<ffi::ObjectRef> host, ffi::String tag,
- ffi::Array<ffi::String> keys, ffi::Map<ffi::String, ffi::Any> attrs);
-
// enable with syntax.
friend class TargetInternal;
friend class With<Target>;
/*!
* \brief Push a new target context onto the thread local stack.
- * The Target on top of the stack is used to determine which
- * specialization to use when invoking a GenericFunc.
+ * The Target on top of the stack is returned by Target::Current().
*/
TVM_TIRX_DLL void EnterWithScope();
/*!
diff --git a/tirx/include/tvm/target/target_kind.h b/tirx/include/tvm/target/target_kind.h
index 3ee45dd619..e5c9a104a4 100644
--- a/tirx/include/tvm/target/target_kind.h
+++ b/tirx/include/tvm/target/target_kind.h
@@ -57,8 +57,6 @@ class TargetKindObj : public ffi::Object {
int default_device_type;
/*! \brief Default keys of the target */
ffi::Array<ffi::String> default_keys;
- /*! \brief Function used to canonicalize a JSON target during creation */
- FTargetCanonicalizer target_canonicalizer;
static void RegisterReflection() {
namespace refl = tvm::ffi::reflection;
@@ -105,12 +103,6 @@ class TargetKind : public ffi::ObjectRef {
friend class TargetInternal;
};
-/*! \brief Value used with --runtime in target specs to indicate the C++ runtime. */
-static constexpr const char* kTvmRuntimeCpp = "c++";
-
-/*! \brief Value used with --runtime in target specs to indicate the C runtime. */
-static constexpr const char* kTvmRuntimeCrt = "c";
-
/*!
* \brief Process-wide registry of canonical target kinds, keyed by name.
*/
@@ -196,8 +188,7 @@ class TargetKindDef {
* \return This builder for chaining. Also updates the kind's ConfigSchema.
*/
TargetKindDef& set_target_canonicalizer(FTargetCanonicalizer canonicalizer) {
- kind_->target_canonicalizer = canonicalizer;
- kind_->schema_.set_canonicalizer(canonicalizer);
+ kind_->schema_.set_canonicalizer(std::move(canonicalizer));
return *this;
}
/*!
diff --git a/tirx/include/tvm/tirx/analysis.h b/tirx/include/tvm/tirx/analysis.h
index d976b3513e..424766849a 100644
--- a/tirx/include/tvm/tirx/analysis.h
+++ b/tirx/include/tvm/tirx/analysis.h
@@ -21,8 +21,8 @@
* \file tvm/tirx/analysis.h
* \brief Analysis utilities and passes for TIR.
*/
-#ifndef TVM_TIR_ANALYSIS_H_
-#define TVM_TIR_ANALYSIS_H_
+#ifndef TVM_TIRX_ANALYSIS_H_
+#define TVM_TIRX_ANALYSIS_H_
#include <tvm/ir/module.h>
#include <tvm/ir/prim/expr.h>
@@ -56,21 +56,6 @@ TVM_TIRX_DLL bool VerifyMemory(const Function& func);
*/
TVM_TIRX_DLL size_t CalculateExprComplexity(const PrimExpr& expr);
-/*!
- * \brief Calculate the constants size in bytes needed by the TIR allocates inside the TIR Function
- * \param func The TIR Function for which the constants size to be calculated
- * \param constant_byte_alignment The byte alignment required for each constant allocated
- */
-TVM_TIRX_DLL size_t CalculateConstantBytes(const Function& func, int64_t constant_byte_alignment);
-
-/*!
- * \brief Calculate the workspace size in bytes needed by the TIR allocates inside the TIR Function
- * \param func The TIR Function for which the workspace size to be calculated
- * \param workspace_byte_alignment The byte alignment required for each tensor allocated in this
- * workspace
- */
-TVM_TIRX_DLL size_t CalculateWorkspaceBytes(const Function& func, int64_t workspace_byte_alignment);
-
/*!
* \brief Verify if the given TIR is well-formed. The verification includes:
*
@@ -133,4 +118,4 @@ TVM_TIRX_DLL Pass VerifyMemory();
} // namespace transform
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_ANALYSIS_H_
+#endif // TVM_TIRX_ANALYSIS_H_
diff --git a/tirx/include/tvm/tirx/function.h b/tirx/include/tvm/tirx/function.h
index 32202efa90..615e5cec27 100644
--- a/tirx/include/tvm/tirx/function.h
+++ b/tirx/include/tvm/tirx/function.h
@@ -21,8 +21,8 @@
* \file tvm/tirx/function.h
* \brief TIR Function.
*/
-#ifndef TVM_TIR_FUNCTION_H_
-#define TVM_TIR_FUNCTION_H_
+#ifndef TVM_TIRX_FUNCTION_H_
+#define TVM_TIRX_FUNCTION_H_
#include <tvm/ffi/container/map.h>
#include <tvm/ffi/container/variant.h>
@@ -145,18 +145,16 @@ TVM_TIRX_DLL Function RenewDef(Function func);
* \param func The Function to be specialized.
* \param param_map The mapping from function params to the instance.
* \return The new function with parameter specialized.
- * \note We can define a Meta TIR function with symbolic shape:
+ * \note We can define a TIRx function with symbolic shape:
*
* \code{.py}
* from __future__ import annotations
*
- * @Ts.function
+ * @T.function
* def mem_copy(A: T.Tensor((m, n), "float32"), B: T.Tensor((m, n), "float32"),
* m: T.int32, n: T.int32) -> None:
* for i, j in T.grid(m, n):
- * with Ts.sblock():
- * vi, vj = Ts.axis.remap("SS", [i, j])
- * B[vi, vj] = A[vi, vj]
+ * B[i, j] = A[i, j]
* \endcode
*
* Then we can make it specialized with given shapes or tensors.
@@ -169,13 +167,11 @@ TVM_TIRX_DLL Function RenewDef(Function func);
* \endcode
*
* \code{.py}
- * @Ts.function
+ * @T.function
* def mem_copy_16_16(A: T.Tensor((16, 16), "float32"),
* B: T.Tensor((16, 16), "float32")) -> None:
* for i, j in T.grid(16, 16):
- * with Ts.sblock():
- * vi, vj = Ts.axis.remap("SS", [i, j])
- * B[vi, vj] = A[vi, vj]
+ * B[i, j] = A[i, j]
* \endcode
*/
TVM_TIRX_DLL Function Specialize(Function func,
@@ -279,4 +275,4 @@ constexpr const char* kPersistentKernel = "tirx.persistent_kernel";
} // namespace attr
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_FUNCTION_H_
+#endif // TVM_TIRX_FUNCTION_H_
diff --git a/tirx/include/tvm/tirx/index_map.h b/tirx/include/tvm/tirx/index_map.h
index 8f0e45f6f2..b4e73824fb 100644
--- a/tirx/include/tvm/tirx/index_map.h
+++ b/tirx/include/tvm/tirx/index_map.h
@@ -23,8 +23,8 @@
*
* For use with TIR tensors.
*/
-#ifndef TVM_TIR_INDEX_MAP_H_
-#define TVM_TIR_INDEX_MAP_H_
+#ifndef TVM_TIRX_INDEX_MAP_H_
+#define TVM_TIRX_INDEX_MAP_H_
#include <tvm/ffi/container/array.h>
#include <tvm/ir/expr.h>
@@ -276,4 +276,4 @@ class IndexMap : public ffi::ObjectRef {
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_INDEX_MAP_H_
+#endif // TVM_TIRX_INDEX_MAP_H_
diff --git a/tirx/include/tvm/tirx/layout.h b/tirx/include/tvm/tirx/layout.h
index e499fa38e4..933e0e2e0e 100644
--- a/tirx/include/tvm/tirx/layout.h
+++ b/tirx/include/tvm/tirx/layout.h
@@ -277,9 +277,6 @@ class ComposeLayout : public Layout {
TVM_DEFINE_OBJECT_REF_COW_METHOD(ComposeLayoutNode);
};
-constexpr int kPSUMMaxElemPerBank = 512;
-constexpr int kPSUMBankNum = 8;
-
} // namespace tirx
} // namespace tvm
diff --git a/tirx/include/tvm/tirx/op/memory.h b/tirx/include/tvm/tirx/op/memory.h
index f5f8b8f4b7..68769721a9 100644
--- a/tirx/include/tvm/tirx/op/memory.h
+++ b/tirx/include/tvm/tirx/op/memory.h
@@ -154,8 +154,8 @@ TVM_TIRX_DLL const Op& undef_op();
*
* Arguments, in order:
* - args[0]: tensor, The tensor.
- * - args[1]: index, The index.
- * - args[2...]: args, trailing PrimExpr operands.
+ * - args[1...n-2]: The tensor indices (at least one).
+ * - args[n-1]: The boolean lane mask, matching the lanes of the loaded vector.
*/
TVM_TIRX_DLL const Op& masked_load_op();
@@ -164,9 +164,9 @@ TVM_TIRX_DLL const Op& masked_load_op();
*
* Arguments, in order:
* - args[0]: tensor, The tensor.
- * - args[1]: value, The value to use.
- * - args[2]: index, The index.
- * - args[3...]: args, trailing PrimExpr operands.
+ * - args[1]: value, The vector value to store.
+ * - args[2...n-2]: The tensor indices (at least one).
+ * - args[n-1]: The boolean lane mask, matching the lanes of value.
*/
TVM_TIRX_DLL const Op& masked_store_op();
diff --git a/tirx/include/tvm/tirx/op/region.h b/tirx/include/tvm/tirx/op/region.h
index f405475235..f54ea77340 100644
--- a/tirx/include/tvm/tirx/op/region.h
+++ b/tirx/include/tvm/tirx/op/region.h
@@ -40,7 +40,8 @@ TVM_TIRX_DLL const Op& launch_thread_op();
/*!
* \brief Mark a user-facing device entry containing device scope definitions.
- * Takes no operands, body parameters, attributes or results.
+ * Operands are optional launch configuration values, each named by the
+ * cuda.launch_fields attribute; there are no body parameters or results.
*/
TVM_TIRX_DLL const Op& device_entry_op();
diff --git a/tirx/include/tvm/tirx/op_attr_types.h b/tirx/include/tvm/tirx/op_attr_types.h
index 9deffebe3e..27a82e2618 100644
--- a/tirx/include/tvm/tirx/op_attr_types.h
+++ b/tirx/include/tvm/tirx/op_attr_types.h
@@ -25,8 +25,8 @@
*
* \sa tvm/ir/op.h
*/
-#ifndef TVM_TIR_OP_ATTR_TYPES_H_
-#define TVM_TIR_OP_ATTR_TYPES_H_
+#ifndef TVM_TIRX_OP_ATTR_TYPES_H_
+#define TVM_TIRX_OP_ATTR_TYPES_H_
#include <tvm/ffi/function.h>
#include <tvm/ffi/reflection/native_function.h>
@@ -58,10 +58,6 @@ inline constexpr ffi::reflection::AttrKey<ffi::String> kGlobalSymbol{"TGlobalSym
inline constexpr ffi::reflection::AttrKey<bool> kVectorizable{"TVectorizable"};
} // namespace op_attr
-// Compatibility names; new callers can deduce the value type from the key.
-using TGlobalSymbol = decltype(op_attr::kGlobalSymbol)::ValueType;
-using TVectorizable = decltype(op_attr::kVectorizable)::ValueType;
-
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_OP_ATTR_TYPES_H_
+#endif // TVM_TIRX_OP_ATTR_TYPES_H_
diff --git a/tirx/include/tvm/tirx/script/ir_builder/frame.h b/tirx/include/tvm/tirx/script/ir_builder/frame.h
index 04e8cbc228..bbef2c86fa 100644
--- a/tirx/include/tvm/tirx/script/ir_builder/frame.h
+++ b/tirx/include/tvm/tirx/script/ir_builder/frame.h
@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
+/*!
+ * \file tvm/tirx/script/ir_builder/frame.h
+ * \brief IRBuilder frames for TIRx functions and statements.
+ */
#ifndef TVM_TIRX_SCRIPT_IR_BUILDER_FRAME_H_
#define TVM_TIRX_SCRIPT_IR_BUILDER_FRAME_H_
@@ -33,22 +37,6 @@ namespace script {
namespace ir_builder {
namespace tirx {
-// Retain dialect imports as aliases of the shared canonical frames.
-using ir::AssertFrame;
-using ir::AssertFrameObj;
-using ir::ElseFrame;
-using ir::ElseFrameObj;
-using ir::ForFrame;
-using ir::ForFrameObj;
-using ir::IfFrame;
-using ir::IfFrameObj;
-using ir::RegionFrame;
-using ir::RegionFrameObj;
-using ir::ThenFrame;
-using ir::ThenFrameObj;
-using ir::WhileFrame;
-using ir::WhileFrameObj;
-
/*!
* \brief A frame that represents the Function containing TIR statements.
*
diff --git a/tirx/include/tvm/tirx/script/ir_builder/ir.h b/tirx/include/tvm/tirx/script/ir_builder/ir.h
index 4c47bf960b..d700009505 100644
--- a/tirx/include/tvm/tirx/script/ir_builder/ir.h
+++ b/tirx/include/tvm/tirx/script/ir_builder/ir.h
@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
+/*!
+ * \file tvm/tirx/script/ir_builder/ir.h
+ * \brief IRBuilder APIs for TIRx functions and statements.
+ */
#ifndef TVM_TIRX_SCRIPT_IR_BUILDER_IR_H_
#define TVM_TIRX_SCRIPT_IR_BUILDER_IR_H_
@@ -34,20 +38,6 @@ namespace script {
namespace ir_builder {
namespace tirx {
-using ir::Assert;
-using ir::Bind;
-using ir::Break;
-using ir::Continue;
-using ir::Else;
-using ir::Evaluate;
-using ir::For;
-using ir::Grid;
-using ir::If;
-using ir::Region;
-using ir::Return;
-using ir::Then;
-using ir::While;
-
using tvm::Var;
using tvm::ffi::Tensor;
using tvm::ffi::Tuple;
@@ -59,10 +49,8 @@ using tvm::tirx::ThreadScope;
* \brief The primitive function statement.
* \return The FunctionFrame.
*/
-FunctionFrame Function(bool is_private, bool persistent = false);
-
-/*! \brief Construct a bodyless function signature using the ordinary signature operations. */
-FunctionFrame DeclFunction(bool is_private = false, bool persistent = false);
+FunctionFrame Function(bool is_private = false, bool persistent = false,
+ bool is_declaration = false);
/*!
* \brief The Function variable arguments adding function.
@@ -127,71 +115,6 @@ inline Var Handle(ffi::Optional<PrimType> dtype = std::nullopt,
inline Var TensorMap() { return tvm::Var("", PtrType(tvm::tirx::TensorMapType())); }
-#define TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(FuncName, DType) \
- inline PrimExpr FuncName(ffi::Optional<PrimExpr> expr = std::nullopt) { \
- PrimType dtype = DType; \
- return expr.has_value() ? tvm::prim::cast(expr.value(), dtype) \
- : tvm::Var("", dtype).as_or_throw<PrimExpr>(); \
- }
-
-#define TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES(DType, Code) \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##8, (PrimType(DLDataType{Code, 8, 1}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##16, (PrimType(DLDataType{Code, 16, 1}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##32, (PrimType(DLDataType{Code, 32, 1}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##64, (PrimType(DLDataType{Code, 64, 1})));
-
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES(BFloat, kDLBfloat);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES(Float, kDLFloat);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES(UInt, kDLUInt);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES(Int, kDLInt);
-
-#define TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES(FuncName, Code, Size) \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(FuncName##x2, (PrimType(DLDataType{Code, Size, 2}))) \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(FuncName##x4, (PrimType(DLDataType{Code, Size, 4}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(FuncName##x8, (PrimType(DLDataType{Code, Size, 8}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(FuncName##x16, (PrimType(DLDataType{Code, Size, 16}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(FuncName##x32, (PrimType(DLDataType{Code, Size, 32}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(FuncName##x64, (PrimType(DLDataType{Code, Size, 64})));
-
-#define TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES_LANES(DType, Code) \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES(DType##8, Code, 8); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES(DType##16, Code, 16); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES(DType##32, Code, 32); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES(DType##64, Code, 64);
-
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES_LANES(BFloat, kDLBfloat);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES_LANES(Float, kDLFloat);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES_LANES(UInt, kDLUInt);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_SIZES_LANES(Int, kDLInt);
-
-#define TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(DType, Code, Bits) \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType, (PrimType(DLDataType{Code, Bits, 1}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##x2, (PrimType(DLDataType{Code, Bits, 2}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##x4, (PrimType(DLDataType{Code, Bits, 4}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##x8, (PrimType(DLDataType{Code, Bits, 8}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##x16, (PrimType(DLDataType{Code, Bits, 16}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##x32, (PrimType(DLDataType{Code, Bits, 32}))); \
- TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(DType##x64, (PrimType(DLDataType{Code, Bits, 64})));
-
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float8E3M4, kDLFloat8_e3m4, 8);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float8E4M3, kDLFloat8_e4m3, 8);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float8E4M3B11FNUZ, kDLFloat8_e4m3b11fnuz, 8);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float8E4M3FN, kDLFloat8_e4m3fn, 8);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float8E4M3FNUZ, kDLFloat8_e4m3fnuz, 8);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float8E5M2, kDLFloat8_e5m2, 8);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float8E5M2FNUZ, kDLFloat8_e5m2fnuz, 8);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float8E8M0FNU, kDLFloat8_e8m0fnu, 8);
-
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float6E2M3FN, kDLFloat6_e2m3fn, 6);
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float6E3M2FN, kDLFloat6_e3m2fn, 6);
-
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST_LANES_FIXED_SIZE(Float4E2M1FN, kDLFloat4_e2m1fn, 4);
-
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(Boolean, PrimType::Bool());
-TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST(Void, PrimType::Void());
-
-#undef TVM_TIRX_IR_BUILDER_DEF_DTYPE_CAST
-
} // namespace tirx
} // namespace ir_builder
} // namespace script
diff --git a/tirx/include/tvm/tirx/stmt.h b/tirx/include/tvm/tirx/stmt.h
index eb1b26a4a7..c0a0fe7292 100644
--- a/tirx/include/tvm/tirx/stmt.h
+++ b/tirx/include/tvm/tirx/stmt.h
@@ -39,26 +39,26 @@ inline bool IsNoOp(const Stmt& stmt) {
/*! \brief Statement attribute and loop annotation keys. */
namespace attr {
-constexpr const char* kPragmaUnroll = "pragma_unroll";
+constexpr const char* kPragmaUnroll = "tirx.pragma_unroll";
-constexpr const char* kDisableUnroll = "disable_unroll";
+constexpr const char* kDisableUnroll = "tirx.disable_unroll";
/*!
* \brief For annotation: maximum work for automatic unrolling.
*
* Integer policy inherited by nested loops unless they override it. Consumed by UnrollLoop.
*/
-constexpr const char* kAutoUnrollMaxStep = "auto_unroll_max_step";
+constexpr const char* kAutoUnrollMaxStep = "tirx.auto_unroll_max_step";
/*!
* \brief For annotation: expand unrolled bodies instead of preserving unrolled loops.
*
* Integer policy inherited by nested loops unless they override it. Consumed by UnrollLoop.
*/
-constexpr const char* kUnrollExplicit = "unroll_explicit";
+constexpr const char* kUnrollExplicit = "tirx.unroll_explicit";
/*! \brief Annotation key on AllocTensor marking the allocation as volatile. */
constexpr const char* kVolatile = "tirx.volatile";
/*! \brief Mark tensor initial addr alignment in bytes */
-constexpr const char* kTensorDataAlignment = "tensor_data_alignment";
+constexpr const char* kTensorDataAlignment = "tirx.tensor_data_alignment";
} // namespace attr
diff --git a/tirx/include/tvm/tirx/stmt_functor.h b/tirx/include/tvm/tirx/stmt_functor.h
index e706800802..bf7d59c2ea 100644
--- a/tirx/include/tvm/tirx/stmt_functor.h
+++ b/tirx/include/tvm/tirx/stmt_functor.h
@@ -344,4 +344,4 @@ bool ContainsNode(const Stmt& stmt) {
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_STMT_FUNCTOR_H_
+#endif // TVM_TIRX_STMT_FUNCTOR_H_
diff --git a/tirx/include/tvm/tirx/tile/context.h b/tirx/include/tvm/tirx/tile/context.h
index b075f35d1c..c514548ee1 100644
--- a/tirx/include/tvm/tirx/tile/context.h
+++ b/tirx/include/tvm/tirx/tile/context.h
@@ -16,7 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-/*! \brief Context and callbacks shared by tile operation dispatchers. */
+/*!
+ * \file tvm/tirx/tile/context.h
+ * \brief Context and callbacks shared by tile operation dispatchers.
+ */
#ifndef TVM_TIRX_TILE_CONTEXT_H_
#define TVM_TIRX_TILE_CONTEXT_H_
diff --git a/tirx/include/tvm/tirx/tile/dispatch.h b/tirx/include/tvm/tirx/tile/dispatch.h
index 8cc916f540..d03ff3270b 100644
--- a/tirx/include/tvm/tirx/tile/dispatch.h
+++ b/tirx/include/tvm/tirx/tile/dispatch.h
@@ -16,7 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-/*! \brief Dispatch interface for lowering tile instruction Calls. */
+/*!
+ * \file tvm/tirx/tile/dispatch.h
+ * \brief Dispatch interface for lowering tile instruction Calls.
+ */
#ifndef TVM_TIRX_TILE_DISPATCH_H_
#define TVM_TIRX_TILE_DISPATCH_H_
diff --git a/tirx/include/tvm/tirx/tile/op.h b/tirx/include/tvm/tirx/tile/op.h
index 61cf213432..bf89ae3958 100644
--- a/tirx/include/tvm/tirx/tile/op.h
+++ b/tirx/include/tvm/tirx/tile/op.h
@@ -16,7 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-/*! \brief Operator registration contracts for tile instructions. */
+/*!
+ * \file tvm/tirx/tile/op.h
+ * \brief Operator registration contracts for tile instructions.
+ */
#ifndef TVM_TIRX_TILE_OP_H_
#define TVM_TIRX_TILE_OP_H_
diff --git a/tirx/include/tvm/tirx/tile/thread_scope.h b/tirx/include/tvm/tirx/tile/thread_scope.h
index 98957211d8..a1df7c65ef 100644
--- a/tirx/include/tvm/tirx/tile/thread_scope.h
+++ b/tirx/include/tvm/tirx/tile/thread_scope.h
@@ -16,7 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-/*! \brief Enum identities for backend-defined thread hierarchies. */
+/*!
+ * \file tvm/tirx/tile/thread_scope.h
+ * \brief Enum identities for backend-defined thread hierarchies.
+ */
#ifndef TVM_TIRX_TILE_THREAD_SCOPE_H_
#define TVM_TIRX_TILE_THREAD_SCOPE_H_
#include <tvm/ffi/enum.h>
diff --git a/tirx/include/tvm/tirx/transform.h b/tirx/include/tvm/tirx/transform.h
index 7da082b7e3..478bcbbc8f 100644
--- a/tirx/include/tvm/tirx/transform.h
+++ b/tirx/include/tvm/tirx/transform.h
@@ -21,8 +21,8 @@
* \file tvm/tirx/transform.h
* \brief TIR specific transformation passes.
*/
-#ifndef TVM_TIR_TRANSFORM_H_
-#define TVM_TIR_TRANSFORM_H_
+#ifndef TVM_TIRX_TRANSFORM_H_
+#define TVM_TIRX_TRANSFORM_H_
#include <tvm/ir/function.h>
#include <tvm/ir/prim/expr.h>
@@ -327,4 +327,4 @@ TVM_TIRX_DLL Pass LowerTIRx();
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_TRANSFORM_H_
+#endif // TVM_TIRX_TRANSFORM_H_
diff --git a/tirx/python/tvm_tirx/backend/cuda/codegen/registry.py b/tirx/python/tvm_tirx/backend/cuda/codegen/registry.py
index 2fac39671b..14fe8dcd89 100644
--- a/tirx/python/tvm_tirx/backend/cuda/codegen/registry.py
+++ b/tirx/python/tvm_tirx/backend/cuda/codegen/registry.py
@@ -28,25 +28,6 @@ import tvm_ffi
CODEGEN_REGISTRY = {}
-def _canonical_device_intrin_name(op_name: str) -> str:
- if not op_name.startswith("tirx."):
- return op_name
- basename = op_name[len("tirx.") :]
- if "." in basename:
- return op_name
- for prefix, namespace in (
- ("cuda_", "cuda"),
- ("ptx_legacy_", "ptx_legacy"),
- ("ptx_", "ptx"),
- ("s_tir_", "s_tir"),
- ("nvshmem_", "nvshmem"),
- ("nki_", "nki"),
- ):
- if basename.startswith(prefix):
- return f"tirx.{namespace}.{basename[len(prefix) :]}"
- return op_name
-
-
@tvm_ffi.register_global_func("tirx.intrinsics.cuda.get_codegen")
def get_codegen(op):
"""get the codegen function for a given op"""
@@ -56,14 +37,12 @@ def get_codegen(op):
def register_codegen(op, backend="cuda"):
"""Register a codegen function for a given op.
- The codegen function should return a ``cuda_func_call`` statement, and
+ The codegen function should return a ``func_call`` statement, and
optionally a list of tags that the codegen function needs.
"""
def decorator(func):
full_op_name = "tirx." + op
- canonical_op_name = _canonical_device_intrin_name(full_op_name)
- op_names = {full_op_name, canonical_op_name}
@functools.wraps(func)
def wrapper(arg_list, attrs=None):
@@ -75,8 +54,7 @@ def register_codegen(op, backend="cuda"):
return res[0], res[1]
return res, list()
- for op_name in op_names:
- CODEGEN_REGISTRY[op_name] = wrapper
+ CODEGEN_REGISTRY[full_op_name] = wrapper
return wrapper
return decorator
diff --git a/tirx/python/tvm_tirx/backend/cuda/codegen/schema.py b/tirx/python/tvm_tirx/backend/cuda/codegen/schema.py
index fc13856d47..3365002367 100644
--- a/tirx/python/tvm_tirx/backend/cuda/codegen/schema.py
+++ b/tirx/python/tvm_tirx/backend/cuda/codegen/schema.py
@@ -43,7 +43,7 @@ from __future__ import annotations
from collections.abc import Callable
-from tvm_tirx.backend.cuda.op import cuda_func_call
+from tvm_tirx.backend.cuda.op import func_call
from .registry import register_codegen
@@ -119,7 +119,7 @@ def device_intrinsic(
prerequisite snippets.
"""
if helper_name is None:
- helper_name = f"tvm_builtin_{op_name}"
+ helper_name = "tvm_builtin_" + op_name.replace(".", "_")
extra_deps = tuple(extra_deps)
def codegen(*args):
@@ -137,7 +137,7 @@ def device_intrinsic(
kwargs["ty"] = tvm_return_type(*args) if callable(tvm_return_type) else tvm_return_type
elif ret_type != "void":
kwargs["ty"] = _C_TO_TVM_DTYPE.get(ret_type, ret_type)
- result = cuda_func_call(name, *forward, source_code, **kwargs)
+ result = func_call(name, *forward, source_code, **kwargs)
return (result, list(extra_deps)) if extra_deps else result
codegen.__name__ = f"codegen_{op_name}"
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/asm.py b/tirx/python/tvm_tirx/backend/cuda/cpp/asm.py
index 43ff67aa53..9b4e558e48 100644
--- a/tirx/python/tvm_tirx/backend/cuda/cpp/asm.py
+++ b/tirx/python/tvm_tirx/backend/cuda/cpp/asm.py
@@ -28,7 +28,7 @@ the PTX text, or the offset-scaling ``cp.async`` form the legacy
import re
from tvm_tirx import ir
-from tvm_tirx.backend.cuda.op import cuda_func_call
+from tvm_tirx.backend.cuda.op import func_call
from tvm_tirx.runtime import MemoryScope
from ..codegen.registry import CODEGEN_REGISTRY, register_codegen
@@ -156,8 +156,8 @@ def _wait_until_forward(spelling, *args):
return CODEGEN_REGISTRY[call.op.name](call.args)
-@register_codegen("cuda_wait_until")
-def cuda_wait_until(dst, ptr, condition, scope, space, ptx_type, backoff_ns):
+@register_codegen("cuda.wait_until")
+def wait_until(dst, ptr, condition, scope, space, ptx_type, backoff_ns):
"""Lower a declared wait to a pre-tested loop around one scoped load."""
scope, space, ptx_type = (parse_str(x) for x in (scope, space, ptx_type))
dtype = _wait_until_thread_local_scalar(dst, "wait_until")
@@ -258,7 +258,7 @@ def cuda_wait_until(dst, ptr, condition, scope, space, ptx_type, backoff_ns):
f"{closing} }} while (0)\n"
)
operands = (condition, backoff_ns)
- return cuda_func_call(name, *load_call.args[1:-1], *operands, source), tags
+ return func_call(name, *load_call.args[1:-1], *operands, source), tags
# =============================================================================
@@ -287,7 +287,7 @@ def _mbarrier_wait_parts(barrier, *_rest):
device_intrinsic(
- "cuda_mbarrier_wait",
+ "cuda.mbarrier_wait",
helper_name=lambda *a: f"tvm_builtin_cuda_mbarrier_wait{_mbarrier_wait_parts(*a)[0]}",
c_signature=lambda *a: _mbarrier_wait_parts(*a)[1],
body=lambda *a: (
@@ -309,7 +309,7 @@ device_intrinsic(
# mbarrier.try_wait.parity.acquire.cluster — cluster-scope acquire wait used for
# cross-CTA barrier handshakes (e.g. the tmem-finished handoff).
device_intrinsic(
- "cuda_mbarrier_wait_acquire_cluster",
+ "cuda.mbarrier_wait_acquire_cluster",
c_signature="(void* barrier, int phase)",
body=(
" unsigned int barrier_addr_int = __cvta_generic_to_shared(barrier);\n"
@@ -331,11 +331,11 @@ device_intrinsic(
# Cluster / warpgroup barriers — open-coded arrive+wait and ``bar.sync``.
# =============================================================================
device_intrinsic(
- "cuda_cluster_sync",
+ "cuda.cluster_sync",
body=(' asm("barrier.cluster.arrive.aligned;");\n asm("barrier.cluster.wait.aligned;");'),
)
device_intrinsic(
- "cuda_warpgroup_sync",
+ "cuda.warpgroup_sync",
c_signature="(int name_bar_id)",
body=' asm volatile("bar.sync %0, 128;" : : "r"(name_bar_id));',
)
@@ -364,7 +364,7 @@ def _cuda_mov_sreg_body(bits):
for _bits in (32, 64):
device_intrinsic(
- f"cuda_mov_sreg_{_bits}",
+ f"cuda.mov_sreg_{_bits}",
n_attrs=1,
helper_name=(
lambda *a, bits=_bits: (
@@ -378,13 +378,13 @@ for _bits in (32, 64):
del _bits
-@register_codegen("cuda_mov_sreg")
+@register_codegen("cuda.mov_sreg")
def codegen_cuda_mov_sreg(bits, reg):
bits = int(bits)
reg = parse_str(reg)
if bits not in (32, 64):
- raise ValueError(f"Only support 32/64 bits for cuda_mov_sreg, but got {bits}.")
- result = CODEGEN_REGISTRY[f"tirx.cuda_mov_sreg_{bits}"]([reg])
+ raise ValueError(f"Only support 32/64 bits for mov_sreg, but got {bits}.")
+ result = CODEGEN_REGISTRY[f"tirx.cuda.mov_sreg_{bits}"]([reg])
return result[0] if isinstance(result, tuple) else result
@@ -394,27 +394,27 @@ def codegen_cuda_mov_sreg(bits, reg):
# based on the operand's runtime dtype.
# =============================================================================
device_intrinsic(
- "cuda_wgmma_noop_barrier_uint32",
+ "cuda.wgmma_noop_barrier_uint32",
helper_name="ptx_wgmma_fence_uint32_t",
c_signature="(uint32_t reg)",
body=' asm volatile("" : "+r"(reg) :: "memory");',
)
device_intrinsic(
- "cuda_wgmma_noop_barrier_float32",
+ "cuda.wgmma_noop_barrier_float32",
helper_name="ptx_wgmma_fence_float",
c_signature="(float reg)",
body=' asm volatile("" : "+f"(reg) :: "memory");',
)
-@register_codegen("cuda_wgmma_noop_barrier")
+@register_codegen("cuda.wgmma_noop_barrier")
def codegen_cuda_wgmma_noop_barrier(reg):
dtype = str(reg.dtype)
dtype_enum = PTXDataType.from_string(dtype)
if dtype_enum == PTXDataType.UINT32:
- op_name = "tirx.cuda_wgmma_noop_barrier_uint32"
+ op_name = "tirx.cuda.wgmma_noop_barrier_uint32"
elif dtype_enum == PTXDataType.FLOAT32:
- op_name = "tirx.cuda_wgmma_noop_barrier_float32"
+ op_name = "tirx.cuda.wgmma_noop_barrier_float32"
else:
raise ValueError(f"Only support uint32/float32 for wgmma_fence, but got {dtype}.")
result = CODEGEN_REGISTRY[op_name]([reg])
@@ -425,7 +425,7 @@ def codegen_cuda_wgmma_noop_barrier(reg):
# The raw cp.async op behind ``InjectPTXAsyncCopy``. All user-issued
# cp.async / cp.async.bulk copies go through ``T.ptx`` instead.
# =============================================================================
-@register_codegen("s_tir_cp_async_raw")
+@register_codegen("s_tir.cp_async_raw")
def codegen_s_tir_cp_async_raw(*args):
"""The raw cp.async op InjectPTXAsyncCopy emits (new copies are ptx).
@@ -516,7 +516,7 @@ def codegen_s_tir_cp_async_raw(*args):
f"{body}\n"
"}\n"
)
- return cuda_func_call(
+ return func_call(
func_name,
dst_ptr_in,
dst_offset,
@@ -541,7 +541,7 @@ def codegen_s_tir_cp_async_raw(*args):
f"{body}\n"
"}\n"
)
- return cuda_func_call(
+ return func_call(
func_name,
dst_ptr_in,
dst_offset,
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/builtins.py b/tirx/python/tvm_tirx/backend/cuda/cpp/builtins.py
index a072f1b077..b5ac6b2f99 100644
--- a/tirx/python/tvm_tirx/backend/cuda/cpp/builtins.py
+++ b/tirx/python/tvm_tirx/backend/cuda/cpp/builtins.py
@@ -29,7 +29,7 @@ inline asm; anything that needs a hand-written PTX body lives in
* thread queries, scheduling hints, and the CUDA-side sync helpers
"""
-from tvm_tirx.backend.cuda.op import cuda_func_call
+from tvm_tirx.backend.cuda.op import func_call
from ..codegen.registry import register_codegen
from ..codegen.schema import device_intrinsic
@@ -39,7 +39,7 @@ from ..codegen.utils import parse_str, validate_power_of_two_range
# Scalar float math.
# =============================================================================
device_intrinsic(
- "cuda_fdividef",
+ "cuda.fdividef",
helper_name="tvm_builtin_cuda_fdividef",
c_signature="(float x, float y)",
return_type="float",
@@ -50,7 +50,7 @@ device_intrinsic(
# =============================================================================
# CUDA-side warp / CTA reductions (templated butterfly shuffle-XOR).
-# Emitted directly via ``cuda_func_call`` — the helper signature uses a
+# Emitted directly via ``func_call`` — the helper signature uses a
# single template parameter ``T`` for both arg and return, which doesn't
# match the operand-driven C signature pattern.
# =============================================================================
@@ -83,7 +83,7 @@ def _warp_reduce_source(func_name, width_int, step_expr):
)
-@register_codegen("cuda_warp_reduce")
+@register_codegen("cuda.warp_reduce")
def codegen_cuda_warp_reduce(value, op, width):
op_str = parse_str(op)
width_int = validate_power_of_two_range(width, 2, 32, "warp_reduce width")
@@ -91,10 +91,10 @@ def codegen_cuda_warp_reduce(value, op, width):
func_name = f"tvm_builtin_cuda_warp_reduce_{op_str}_{width_int}"
source_code = _warp_reduce_source(func_name, width_int, step_expr)
- return cuda_func_call(func_name, value, source_code, ty=value.ty)
+ return func_call(func_name, value, source_code, ty=value.ty)
-@register_codegen("cuda_cta_reduce")
+@register_codegen("cuda.cta_reduce")
def codegen_cuda_cta_reduce(value, op, num_warps, scratch):
op_str = parse_str(op)
nw = validate_power_of_two_range(num_warps, 1, 32, "cta_reduce num_warps")
@@ -124,14 +124,14 @@ def codegen_cuda_cta_reduce(value, op, num_warps, scratch):
" return scratch[0];\n"
"}\n"
)
- return cuda_func_call(func_name, value, scratch, cta_body, ty=value.ty)
+ return func_call(func_name, value, scratch, cta_body, ty=value.ty)
# =============================================================================
# FP8 / BF16 packing, integer, and activation helpers.
# =============================================================================
device_intrinsic(
- "cuda_ffs_u32",
+ "cuda.ffs_u32",
helper_name="tvm_builtin_ffs_u32",
c_signature="(unsigned int value)",
return_type="int",
@@ -139,7 +139,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_make_float2",
+ "cuda.make_float2",
helper_name="tvm_builtin_make_float2",
c_signature="(float x, float y)",
return_type="unsigned long long",
@@ -150,7 +150,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_float2_x",
+ "cuda.float2_x",
helper_name="tvm_builtin_float2_x",
c_signature="(unsigned long long packed)",
return_type="float",
@@ -158,7 +158,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_float2_y",
+ "cuda.float2_y",
helper_name="tvm_builtin_float2_y",
c_signature="(unsigned long long packed)",
return_type="float",
@@ -166,7 +166,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_fmul2_rn",
+ "cuda.fmul2_rn",
helper_name="tvm_builtin_fmul2_rn",
c_signature="(unsigned long long a, unsigned long long b)",
return_type="unsigned long long",
@@ -179,7 +179,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_fadd2_rn",
+ "cuda.fadd2_rn",
helper_name="tvm_builtin_fadd2_rn",
c_signature="(unsigned long long a, unsigned long long b)",
return_type="unsigned long long",
@@ -192,7 +192,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_float22bfloat162_rn",
+ "cuda.float22bfloat162_rn",
helper_name="tvm_builtin_float22bfloat162_rn",
c_signature="(float x, float y)",
return_type="unsigned int",
@@ -204,7 +204,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_float22bfloat162_rn_from_float2",
+ "cuda.float22bfloat162_rn_from_float2",
helper_name="tvm_builtin_float22bfloat162_rn_from_float2",
c_signature="(unsigned long long packed)",
return_type="unsigned int",
@@ -217,7 +217,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_bfloat1622float2",
+ "cuda.bfloat1622float2",
helper_name="tvm_builtin_bfloat1622float2",
c_signature="(unsigned int packed)",
return_type="unsigned long long",
@@ -231,7 +231,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_hmin2",
+ "cuda.hmin2",
helper_name="tvm_builtin_hmin2",
c_signature="(unsigned int a, unsigned int b)",
return_type="unsigned int",
@@ -247,7 +247,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_hmax2",
+ "cuda.hmax2",
helper_name="tvm_builtin_hmax2",
c_signature="(unsigned int a, unsigned int b)",
return_type="unsigned int",
@@ -263,7 +263,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_fp8x4_e4m3_from_float4",
+ "cuda.fp8x4_e4m3_from_float4",
helper_name="tvm_builtin_fp8x4_e4m3_from_float4",
c_signature="(float x, float y, float z, float w)",
return_type="unsigned int",
@@ -279,7 +279,7 @@ device_intrinsic(
# Atomics — templated wrappers around CUDA's ``atomicAdd`` / ``atomicCAS``.
# =============================================================================
device_intrinsic(
- "cuda_atomic_add",
+ "cuda.atomic_add",
helper_name="tvm_builtin_cuda_atomic_add",
c_signature="(T* addr, T value)",
body=" return atomicAdd(addr, value);",
@@ -288,7 +288,7 @@ device_intrinsic(
tvm_return_type=lambda _addr, value: value.ty,
)
device_intrinsic(
- "cuda_atomic_cas",
+ "cuda.atomic_cas",
helper_name="tvm_builtin_cuda_atomic_cas",
c_signature="(T* address, T compare, T val)",
body=" return atomicCAS(address, compare, val);",
@@ -302,21 +302,21 @@ device_intrinsic(
# half / bfloat16 ↔ float type-punned conversions.
# =============================================================================
device_intrinsic(
- "cuda_half2float",
+ "cuda.half2float",
c_signature="(half src)",
body=" return __half2float(src);",
return_type="float",
tvm_return_type="float32",
)
device_intrinsic(
- "cuda_bfloat162float",
+ "cuda.bfloat162float",
c_signature="(nv_bfloat16 src)",
body=" return __bfloat162float(src);",
return_type="float",
tvm_return_type="float32",
)
device_intrinsic(
- "cuda_float22half2",
+ "cuda.float22half2",
c_signature="(void* dst, void* src)",
body=(
" half2* dst_p = (half2*) dst;\n"
@@ -325,7 +325,7 @@ device_intrinsic(
),
)
device_intrinsic(
- "cuda_half8tofloat8",
+ "cuda.half8tofloat8",
c_signature="(void* src_addr, void* dst_addr)",
body=(
" half2* source = (half2*) src_addr;\n"
@@ -336,7 +336,7 @@ device_intrinsic(
),
)
device_intrinsic(
- "cuda_float8tohalf8",
+ "cuda.float8tohalf8",
c_signature="(void* src_addr, void* dst_addr)",
body=(
" float2* source = (float2*) src_addr;\n"
@@ -354,7 +354,7 @@ device_intrinsic(
# typed scalar input (instead of doing the conversion inside the asm helper).
# =============================================================================
device_intrinsic(
- "cuda_cvta_generic_to_shared",
+ "cuda.cvta_generic_to_shared",
c_signature="(void* p)",
body=" return __cvta_generic_to_shared(p);",
return_type="unsigned int",
@@ -362,7 +362,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_smem_addr_from_uint64",
+ "cuda.smem_addr_from_uint64",
c_signature="(uint64_t cluster_addr)",
body=" return static_cast<unsigned int>(cluster_addr);",
return_type="unsigned int",
@@ -370,14 +370,14 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_uint_as_float",
+ "cuda.uint_as_float",
helper_name="tvm_builtin_uint_as_float",
c_signature="(unsigned int bits)",
return_type="float",
body=" return __uint_as_float(bits);",
)
device_intrinsic(
- "cuda_float_as_uint",
+ "cuda.float_as_uint",
helper_name="tvm_builtin_float_as_uint",
c_signature="(float x)",
return_type="unsigned int",
@@ -389,7 +389,7 @@ device_intrinsic(
# Per-thread queries / scheduling hints.
# =============================================================================
device_intrinsic(
- "cuda_thread_rank",
+ "cuda.thread_rank",
body=(
" namespace cg = cooperative_groups;\n return cg::this_thread_block().thread_rank();"
),
@@ -397,7 +397,7 @@ device_intrinsic(
tvm_return_type="int32",
extra_deps=("cooperative_groups",),
)
-device_intrinsic("cuda_nano_sleep", c_signature="(uint64_t time)", body=" __nanosleep(time);")
+device_intrinsic("cuda.nano_sleep", c_signature="(uint64_t time)", body=" __nanosleep(time);")
# =============================================================================
@@ -405,7 +405,7 @@ device_intrinsic("cuda_nano_sleep", c_signature="(uint64_t time)", body=" __n
# helper (declared in the CUDA header tags), not direct PTX.
# =============================================================================
device_intrinsic(
- "cuda_elect_sync",
+ "cuda.elect_sync",
helper_name="tvm_builtin_elect_one_sync_op",
return_type="uint32_t",
body=" return tvm_builtin_elect_one_sync();",
@@ -417,7 +417,7 @@ device_intrinsic(
# __any_sync — warp-vote (pure CUDA helper).
# =============================================================================
device_intrinsic(
- "cuda_any_sync",
+ "cuda.any_sync",
c_signature="(unsigned mask, int pred)",
body=" return __any_sync(mask, pred);",
return_type="int",
@@ -428,23 +428,23 @@ device_intrinsic(
# =============================================================================
# CUDA-side sync helpers (zero-arg void unless noted).
# =============================================================================
-device_intrinsic("cuda_thread_fence", body=" __threadfence();")
-device_intrinsic("cuda_warp_sync", body=" __syncwarp();")
-device_intrinsic("cuda_cta_sync", body=" __syncthreads();")
+device_intrinsic("cuda.thread_fence", body=" __threadfence();")
+device_intrinsic("cuda.warp_sync", body=" __syncwarp();")
+device_intrinsic("cuda.cta_sync", body=" __syncthreads();")
device_intrinsic(
- "cuda_grid_sync",
+ "cuda.grid_sync",
body=" namespace cg = cooperative_groups;\n cg::this_grid().sync();",
extra_deps=("cooperative_groups",),
)
device_intrinsic(
- "cuda_syncthreads_and",
+ "cuda.syncthreads_and",
c_signature="(int predicate)",
body=" return __syncthreads_and(predicate);",
return_type="int",
tvm_return_type="int32",
)
device_intrinsic(
- "cuda_syncthreads_or",
+ "cuda.syncthreads_or",
c_signature="(int predicate)",
body=" return __syncthreads_or(predicate);",
return_type="int",
@@ -456,21 +456,21 @@ device_intrinsic(
# Warp collectives — ballot and the hardware ``__reduce_*_sync`` reductions.
# =============================================================================
device_intrinsic(
- "cuda_ballot_sync",
+ "cuda.ballot_sync",
helper_name="tvm_builtin_ballot_sync",
c_signature="(unsigned int mask, int pred)",
return_type="unsigned int",
body=" return __ballot_sync(mask, pred);",
)
device_intrinsic(
- "cuda_reduce_add_sync_u32",
+ "cuda.reduce_add_sync_u32",
helper_name="tvm_builtin_reduce_add_sync_u32",
c_signature="(unsigned int mask, unsigned int value)",
return_type="unsigned int",
body=" return __reduce_add_sync(mask, value);",
)
device_intrinsic(
- "cuda_reduce_min_sync_u32",
+ "cuda.reduce_min_sync_u32",
helper_name="tvm_builtin_reduce_min_sync_u32",
c_signature="(unsigned int mask, unsigned int value)",
return_type="unsigned int",
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/descriptors.py b/tirx/python/tvm_tirx/backend/cuda/cpp/descriptors.py
index e6c451e58e..182a261faf 100644
--- a/tirx/python/tvm_tirx/backend/cuda/cpp/descriptors.py
+++ b/tirx/python/tvm_tirx/backend/cuda/cpp/descriptors.py
@@ -36,7 +36,7 @@ from ..codegen.utils import validate_cta_group
# wgmma_encode_matrix_descriptor — pure-C bitfield struct fill (no asm).
# =============================================================================
device_intrinsic(
- "cuda_wgmma_encode_matrix_descriptor",
+ "cuda.wgmma_encode_matrix_descriptor",
helper_name="ptx_wgmma_encode_matrix_descriptor",
c_signature="(uint64_t* desc, void* addr, int ldo, int sdo, int swizzle)",
body=(
@@ -68,7 +68,7 @@ device_intrinsic(
# tcgen05 SMEM / instr descriptor encoders — pure-C bitfield struct fills.
# =============================================================================
device_intrinsic(
- "cuda_tcgen05_encode_matrix_descriptor",
+ "cuda.tcgen05_encode_matrix_descriptor",
helper_name="tvm_builtin_ptx_tcgen05_encode_matrix_descriptor",
c_signature="(uint64_t* desc, void* addr, int ldo, int sdo, int swizzle)",
body=(
@@ -320,7 +320,7 @@ device_intrinsic(
)
-@register_codegen("cuda_tcgen05_encode_instr_descriptor")
+@register_codegen("cuda.tcgen05_encode_instr_descriptor")
def codegen_cuda_tcgen05_encode_instr_descriptor(desc, *, attrs):
"""Validate static Call.attrs and lower the in-place descriptor fill."""
d_dtype = attrs.d_dtype
@@ -419,7 +419,7 @@ device_intrinsic(
)
-@register_codegen("cuda_tcgen05_encode_instr_descriptor_block_scaled")
+@register_codegen("cuda.tcgen05_encode_instr_descriptor_block_scaled")
def codegen_cuda_tcgen05_encode_instr_descriptor_block_scaled(desc, *, attrs):
"""Validate static Call.attrs and lower the in-place descriptor fill."""
d_dtype = attrs.d_dtype
@@ -534,7 +534,7 @@ def _get_tcgen05_mma_scale_vec_size(kind, scale_dtype):
# (bits [29, 31)) fields of an in-flight ``InstrDescriptorBlockScaled``.
# =============================================================================
device_intrinsic(
- "cuda_get_tmem_addr",
+ "cuda.get_tmem_addr",
c_signature="(uint32_t addr, int row_offset, int col_offset)",
body=" return get_tmem_addr(addr, row_offset, col_offset);",
return_type="uint32_t",
@@ -543,7 +543,7 @@ device_intrinsic(
)
device_intrinsic(
- "cuda_runtime_instr_desc",
+ "cuda.runtime_instr_desc",
c_signature="(uint32_t* desc, const uint32_t& sf_id)",
body=" *desc = (*desc & ~0x60000030) | ((sf_id << 29) | (sf_id << 4));",
)
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/instrument.py b/tirx/python/tvm_tirx/backend/cuda/cpp/instrument.py
index 514add577f..f22ab10961 100644
--- a/tirx/python/tvm_tirx/backend/cuda/cpp/instrument.py
+++ b/tirx/python/tvm_tirx/backend/cuda/cpp/instrument.py
@@ -27,7 +27,7 @@ import hashlib
import json
import tvm_tirx
-from tvm_tirx.backend.cuda.op import cuda_func_call
+from tvm_tirx.backend.cuda.op import func_call
from ..codegen.registry import register_codegen
from ..codegen.schema import device_intrinsic
@@ -111,14 +111,14 @@ device_intrinsic(
# =============================================================================
# Official IKET NativeDump placeholder.
# =============================================================================
-@register_codegen("cuda_iket_official_event")
+@register_codegen("cuda.iket_official_event")
def codegen_cuda_iket_official_event(event_id, source_code, payload=None):
if isinstance(source_code, tvm_tirx.ir.StringImm):
source_code = source_code.value
else:
source_code = parse_str(source_code)
args = (event_id,) if payload is None else (event_id, payload)
- return cuda_func_call(
+ return func_call(
"tvm_builtin_iket_official_event",
*args,
source_code,
@@ -130,13 +130,13 @@ def codegen_cuda_iket_official_event(event_id, source_code, payload=None):
# Debug helpers — ``printf`` (variadic templated) and ``trap`` on assert.
# =============================================================================
device_intrinsic(
- "cuda_trap_when_assert_failed",
+ "cuda.trap_when_assert_failed",
c_signature="(bool cond)",
body=' do {\n if (not (cond))\n asm("trap;");\n } while (0);',
)
-@register_codegen("cuda_printf")
+@register_codegen("cuda.printf")
def codegen_cuda_printf(fmt, *args):
if isinstance(fmt, tvm_tirx.ir.StringImm):
fmt = fmt.value
@@ -175,11 +175,11 @@ __noinline__ __device__ void {func_name}({params}) {{
printf({fmt_literal}{comma_call_args});
}}
"""
- return cuda_func_call(func_name, *args, source_code)
+ return func_call(func_name, *args, source_code)
device_intrinsic(
- "cuda_clock64",
+ "cuda.clock64",
helper_name="tvm_builtin_clock64",
return_type="unsigned long long",
body=" return clock64();",
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/nvshmem.py b/tirx/python/tvm_tirx/backend/cuda/cpp/nvshmem.py
index 2b6524cc87..197f7c6e07 100644
--- a/tirx/python/tvm_tirx/backend/cuda/cpp/nvshmem.py
+++ b/tirx/python/tvm_tirx/backend/cuda/cpp/nvshmem.py
@@ -89,7 +89,7 @@ device_intrinsic(
)
-@register_codegen("nvshmem_signal_op")
+@register_codegen("nvshmem.signal_op")
def codegen_nvshmem_signal_op(sig_addr, signal, sig_op, pe):
"""Map ``sig_op`` (string) to its NVSHMEM int constant, then forward."""
sig_op_int = _resolve_attr(sig_op, _SIG_OP_VAL, "signal op")
@@ -111,7 +111,7 @@ for _c_type, _suffix in [("uint64_t", "uint64")]:
del _c_type, _suffix
-@register_codegen("nvshmem_wait_until")
+@register_codegen("nvshmem.wait_until")
def codegen_nvshmem_wait_until(ivar, cmp, cmp_value, type):
"""Dispatch to the type-specific wait_until helper after mapping ``cmp``
(string) to its NVSHMEM int constant."""
@@ -145,7 +145,7 @@ del _scope_suffix, _backend_call
def _make_putmem_signal_dispatcher(scope_suffix):
- @register_codegen(f"nvshmem_putmem_signal_nbi{scope_suffix}")
+ @register_codegen(f"nvshmem.putmem_signal_nbi{scope_suffix}")
def _codegen(dest, source, nelems, sig_addr, signal, sig_op, pe):
sig_op_int = _resolve_attr(sig_op, _SIG_OP_VAL, "signal op")
result = CODEGEN_REGISTRY[f"tirx._nvshmem_putmem_signal_nbi{scope_suffix}_impl"](
diff --git a/tirx/python/tvm_tirx/backend/cuda/iket.py b/tirx/python/tvm_tirx/backend/cuda/iket.py
index 01597a5265..d3e520f6b0 100644
--- a/tirx/python/tvm_tirx/backend/cuda/iket.py
+++ b/tirx/python/tvm_tirx/backend/cuda/iket.py
@@ -315,7 +315,7 @@ class IketProfiler:
mod = tvm_tirx.IRModule.from_expr(mod)
if not isinstance(mod, tvm_tirx.IRModule):
raise TypeError("IketProfiler.compile expects a TIRx Function or IRModule")
- enabled_mod = mod.with_attr("tirx.iket.enabled", True)
+ enabled_mod = mod.with_attr("cuda.iket.enabled", True)
executable = tvm_tirx.tirx.compile(enabled_mod, target=target, pipeline=tir_pipeline)
return _OfficialIketExecutable(executable)
diff --git a/tirx/python/tvm_tirx/backend/cuda/lang/pipeline.py b/tirx/python/tvm_tirx/backend/cuda/lang/pipeline.py
index 6a7233b3ff..e9c4c56342 100644
--- a/tirx/python/tvm_tirx/backend/cuda/lang/pipeline.py
+++ b/tirx/python/tvm_tirx/backend/cuda/lang/pipeline.py
@@ -20,8 +20,8 @@ These classes emit TIR via @T.inline. Decorate with @T.meta_class so that
instances are automatically treated as meta values inside @T.function.
"""
+from tvm_tirx.ir import IntImm as _IntImm
from tvm_tirx.script import tirx as T
-from tvm_tirx.tirx import IntImm as _IntImm
def _tcgen05_commit_is_unicast(cta_mask):
diff --git a/tirx/python/tvm_tirx/backend/cuda/launch/_impl.py b/tirx/python/tvm_tirx/backend/cuda/launch/_impl.py
index 19a0e37245..ae440d350e 100644
--- a/tirx/python/tvm_tirx/backend/cuda/launch/_impl.py
+++ b/tirx/python/tvm_tirx/backend/cuda/launch/_impl.py
@@ -27,7 +27,7 @@ def _integer(value):
if isinstance(value, Integral):
return int(value)
# Avoid importing TVM while the generated configuration module is loaded.
- from tvm_tirx.ir.prim import IntImm
+ from tvm_tirx.ir import IntImm
return int(value) if isinstance(value, IntImm) else None
diff --git a/tirx/python/tvm_tirx/backend/cuda/op.py b/tirx/python/tvm_tirx/backend/cuda/op.py
index fcfd9a46cd..5943bb3ccd 100644
--- a/tirx/python/tvm_tirx/backend/cuda/op.py
+++ b/tirx/python/tvm_tirx/backend/cuda/op.py
@@ -24,6 +24,7 @@ from functools import cache
import tvm_ffi
+import tvm_tirx
from tvm_tirx import DataType, tirx
from tvm_tirx.ir import Attrs, Call, Op, StringImm, const
from tvm_tirx.ir.location import UNKNOWN_LOC, Location
@@ -45,7 +46,10 @@ def _tmem_address(tensor):
"""Recover the encoded 32-bit address from an explicit TMEM backing pointer."""
if tensor.scope() != _scope_tmem():
raise ValueError("Expected a TMEM tensor")
- return tirx.Cast(tirx.reinterpret("uint64", tensor.data), "uint32")
+ return tirx.Cast(
+ tirx.reinterpret(tensor.data, ty="uint64"),
+ "uint32",
+ )
########################################################
@@ -53,44 +57,44 @@ def _tmem_address(tensor):
########################################################
-def cuda_iket_mark(name, payload=None):
+def iket_mark(name, payload=None):
"""Create an NVIDIA IKET marker annotation."""
if payload is not None:
- return call_intrin("", "tirx.cuda.iket_mark", name, payload)
- return call_intrin("", "tirx.cuda.iket_mark", name)
+ return call_intrin("tirx.cuda.iket_mark", name, payload, ty="")
+ return call_intrin("tirx.cuda.iket_mark", name, ty="")
-def cuda_iket_range_start(name, payload=None):
+def iket_range_start(name, payload=None):
"""Create an NVIDIA IKET token-range start annotation."""
if payload is not None:
- return call_intrin("uint32", "tirx.cuda.iket_range_start", name, payload)
- return call_intrin("uint32", "tirx.cuda.iket_range_start", name)
+ return call_intrin("tirx.cuda.iket_range_start", name, payload, ty="uint32")
+ return call_intrin("tirx.cuda.iket_range_start", name, ty="uint32")
-def cuda_iket_range_end(token, payload=None):
+def iket_range_end(token, payload=None):
"""Create an NVIDIA IKET token-range end annotation."""
if payload is not None:
- return call_intrin("", "tirx.cuda.iket_range_end", token, payload)
- return call_intrin("", "tirx.cuda.iket_range_end", token)
+ return call_intrin("tirx.cuda.iket_range_end", token, payload, ty="")
+ return call_intrin("tirx.cuda.iket_range_end", token, ty="")
-def cuda_iket_range_push(name, payload=None):
+def iket_range_push(name, payload=None):
"""Create an NVIDIA IKET stack-range push annotation."""
if payload is not None:
- return call_intrin("", "tirx.cuda.iket_range_push", name, payload)
- return call_intrin("", "tirx.cuda.iket_range_push", name)
+ return call_intrin("tirx.cuda.iket_range_push", name, payload, ty="")
+ return call_intrin("tirx.cuda.iket_range_push", name, ty="")
-def cuda_iket_official_event(event_id, source_code="", payload=None):
+def iket_official_event(event_id, source_code="", payload=None):
"""Create an NVIDIA IKET official range-end event."""
if payload is not None:
return call_intrin(
- "uint32", "tirx.cuda.iket_official_event", event_id, source_code, payload
+ "tirx.cuda.iket_official_event", event_id, source_code, payload, ty="uint32"
)
- return call_intrin("uint32", "tirx.cuda.iket_official_event", event_id, source_code)
+ return call_intrin("tirx.cuda.iket_official_event", event_id, source_code, ty="uint32")
-def cuda_func_call(func_name, *args, ty=None, loc: Location = UNKNOWN_LOC):
+def func_call(func_name, *args, ty=None, loc: Location = UNKNOWN_LOC):
"""Call a CUDA function with its source code as the final operand.
``args`` contains the function arguments followed by the source string.
@@ -99,7 +103,7 @@ def cuda_func_call(func_name, *args, ty=None, loc: Location = UNKNOWN_LOC):
return Call("tirx.cuda.func_call", [func_name, *args], ty=ty, loc=loc)
-def cuda_warp_reduce(value, op, width=32, *, ty=None, loc: Location = UNKNOWN_LOC):
+def warp_reduce(value, op, width=32, *, ty=None, loc: Location = UNKNOWN_LOC):
"""Warp-level butterfly shuffle-XOR reduction.
Reduces ``value`` across ``width`` adjacent lanes using the specified
@@ -131,22 +135,22 @@ def cuda_warp_reduce(value, op, width=32, *, ty=None, loc: Location = UNKNOWN_LO
)
-def cuda_warp_sum(value, width=32):
- """Convenience wrapper: ``cuda_warp_reduce(value, "sum", width)``."""
- return cuda_warp_reduce(value, "sum", width)
+def warp_sum(value, width=32):
+ """Convenience wrapper: ``warp_reduce(value, "sum", width)``."""
+ return warp_reduce(value, "sum", width)
-def cuda_warp_max(value, width=32):
- """Convenience wrapper: ``cuda_warp_reduce(value, "max", width)``."""
- return cuda_warp_reduce(value, "max", width)
+def warp_max(value, width=32):
+ """Convenience wrapper: ``warp_reduce(value, "max", width)``."""
+ return warp_reduce(value, "max", width)
-def cuda_warp_min(value, width=32):
- """Convenience wrapper: ``cuda_warp_reduce(value, "min", width)``."""
- return cuda_warp_reduce(value, "min", width)
+def warp_min(value, width=32):
+ """Convenience wrapper: ``warp_reduce(value, "min", width)``."""
+ return warp_reduce(value, "min", width)
-def cuda_cta_reduce(value, op, num_warps, scratch, *, ty=None, loc: Location = UNKNOWN_LOC):
+def cta_reduce(value, op, num_warps, scratch, *, ty=None, loc: Location = UNKNOWN_LOC):
"""CTA-wide reduction via warp shuffle + shared memory.
Two-step reduction: (1) intra-warp shuffle reduction, (2) warp-0
@@ -180,19 +184,19 @@ def cuda_cta_reduce(value, op, num_warps, scratch, *, ty=None, loc: Location = U
)
-def cuda_cta_sum(value, num_warps, scratch):
- """Convenience wrapper: ``cuda_cta_reduce(value, "sum", num_warps, scratch)``."""
- return cuda_cta_reduce(value, "sum", num_warps, scratch)
+def cta_sum(value, num_warps, scratch):
+ """Convenience wrapper: ``cta_reduce(value, "sum", num_warps, scratch)``."""
+ return cta_reduce(value, "sum", num_warps, scratch)
-def cuda_cta_max(value, num_warps, scratch):
- """Convenience wrapper: ``cuda_cta_reduce(value, "max", num_warps, scratch)``."""
- return cuda_cta_reduce(value, "max", num_warps, scratch)
+def cta_max(value, num_warps, scratch):
+ """Convenience wrapper: ``cta_reduce(value, "max", num_warps, scratch)``."""
+ return cta_reduce(value, "max", num_warps, scratch)
-def cuda_cta_min(value, num_warps, scratch):
- """Convenience wrapper: ``cuda_cta_reduce(value, "min", num_warps, scratch)``."""
- return cuda_cta_reduce(value, "min", num_warps, scratch)
+def cta_min(value, num_warps, scratch):
+ """Convenience wrapper: ``cta_reduce(value, "min", num_warps, scratch)``."""
+ return cta_reduce(value, "min", num_warps, scratch)
_WAIT_UNTIL_SCOPE = ("cta", "cluster", "gpu", "sys")
@@ -256,7 +260,7 @@ def _reject_wide_word_for_predicate(ptx_type, what):
)
-def cuda_wait_until(
+def wait_until(
dst,
ptr,
predicate,
@@ -389,13 +393,13 @@ def ptx_cp_async_legacy(
def _is_static_unicast_cta_mask(cta_mask):
if isinstance(cta_mask, int):
return cta_mask == 0 or cta_mask & (cta_mask - 1) == 0
- if isinstance(cta_mask, tirx.IntImm):
+ if isinstance(cta_mask, tvm_tirx.ir.IntImm):
value = int(cta_mask)
return value == 0 or value & (value - 1) == 0
return False
-def cuda_mov_sreg(bits, reg_name, *, ty=None, loc: Location = UNKNOWN_LOC):
+def mov_sreg(bits, reg_name, *, ty=None, loc: Location = UNKNOWN_LOC):
"""TVM intrinsic to tvm instrinsics to fetch PTX pre-defined registers
Parameters
@@ -509,7 +513,6 @@ def bmma_sync(
The call expression.
"""
return call_intrin(
- ty,
"tirx.cuda.bmma_sync",
fragment_d,
index_d,
@@ -520,19 +523,20 @@ def bmma_sync(
fragment_c,
index_c,
loc=loc,
+ ty=ty,
)
-def mma_store(dtype, m, n, dst_ptr, src_ptr, src_offset, dst_stride):
+def mma_store(m, n, dst_ptr, src_ptr, src_offset, dst_stride, *, ty):
"""Store the result of PTX MMA into a destination pointer."""
- return call_intrin(dtype, "tirx.cuda.mma_store", m, n, dst_ptr, src_ptr, src_offset, dst_stride)
+ return call_intrin("tirx.cuda.mma_store", m, n, dst_ptr, src_ptr, src_offset, dst_stride, ty=ty)
-def mma_fill(dtype, local_size, local_ptr, offset):
+def mma_fill(local_size, local_ptr, offset, *, ty):
"""Zero-initialize an MMA accumulation register."""
- return call_intrin(dtype, "tirx.cuda.mma_fill", local_size, local_ptr, offset)
+ return call_intrin("tirx.cuda.mma_fill", local_size, local_ptr, offset, ty=ty)
_PTX_TO_NUMPY_DTYPE = {
@@ -615,7 +619,7 @@ _encode_instr_descriptor_block_scaled = _make_op_api(
)
-def cuda_tcgen05_encode_instr_descriptor(
+def tcgen05_encode_instr_descriptor(
desc,
*,
d_dtype,
@@ -699,7 +703,7 @@ def cuda_tcgen05_encode_instr_descriptor(
)
-def cuda_tcgen05_encode_instr_descriptor_block_scaled(
+def tcgen05_encode_instr_descriptor_block_scaled(
desc,
*,
d_dtype,
@@ -1015,7 +1019,7 @@ def timer_finalize(
)
-def cuda_atomic_add(res_addr, value, *, ty=None, loc: Location = UNKNOWN_LOC):
+def atomic_add(res_addr, value, *, ty=None, loc: Location = UNKNOWN_LOC):
"""TVM intrinsic to call cuda atomic add instruction
Parameters
@@ -1040,7 +1044,7 @@ def cuda_atomic_add(res_addr, value, *, ty=None, loc: Location = UNKNOWN_LOC):
)
-def cuda_sm100_2sm_leader_smem_addr(ptr):
+def sm100_2sm_leader_smem_addr(ptr):
"""Return the SM100 2SM leader CTA shared-address operand.
The input is a generic pointer to shared memory.
@@ -1168,7 +1172,7 @@ def _validate_ptx_address(addr, space, op_name):
)
-def cuda_atomic_cas(ptr, old_val, new_val, *, ty=None, loc: Location = UNKNOWN_LOC):
+def atomic_cas(ptr, old_val, new_val, *, ty=None, loc: Location = UNKNOWN_LOC):
"""TVM intrinsic to call cuda atomic cas instruction
Parameters
@@ -1643,9 +1647,6 @@ def nvshmem_barrier_all(*, ty=None, loc: Location = UNKNOWN_LOC):
return Call("tirx.nvshmem.barrier_all", [], ty=ty, loc=loc)
-# Canonical Op builders also supply the historical direct-import aliases.
-
-
@tvm_ffi.register_object("tirx.cuda.TensorMapEncodeTiledAttr")
class TensorMapEncodeTiledAttr(Attrs):
"""Descriptor dtype and fixed options for tiled tensor-map encoding."""
@@ -1704,8 +1705,3 @@ def tensormap_encode_tiled(
_init_op_api("tirx.cuda", __name__)
-for _name in Op.list_op_names():
- if _name.startswith("tirx.cuda."):
- _suffix = _name.removeprefix("tirx.cuda.")
- if "." not in _suffix:
- globals().setdefault("cuda_" + _suffix, globals()[_suffix])
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/engine.py b/tirx/python/tvm_tirx/backend/cuda/ptx/engine.py
index 80438e8436..c23a9a3c5c 100644
--- a/tirx/python/tvm_tirx/backend/cuda/ptx/engine.py
+++ b/tirx/python/tvm_tirx/backend/cuda/ptx/engine.py
@@ -41,12 +41,11 @@ from tvm_ffi import get_global_func, register_global_func, structural_equal
from tvm_tirx.backend.cuda.codegen.registry import register_codegen
from tvm_tirx.backend.cuda.codegen.utils import parse_str
-from tvm_tirx.backend.cuda.op import cuda_cvta_generic_to_shared, cuda_func_call
-from tvm_tirx.ir import Call, Op, StringImm, TensorLoad, const
+from tvm_tirx.backend.cuda.op import cvta_generic_to_shared, func_call
+from tvm_tirx.ir import Call, CallEffectKind, IntImm, Op, StringImm, TensorLoad, const
from tvm_tirx.ir.op import register_op_attr
from tvm_tirx.ir.type import PrimType, PtrType
from tvm_tirx.runtime import MemoryScope
-from tvm_tirx.tirx.expr import CallEffectKind, IntImm
from tvm_tirx.tirx.op import call_intrin, reinterpret
from .render import render_variant
@@ -94,8 +93,8 @@ _INTEGER_DTYPES = frozenset(
def register_table(table: dict[str, InstructionEntry]) -> None:
"""Register every table entry as a TVM Op + generic codegen."""
for entry in table.values():
- # First attr call implicitly creates the Op registry entry. Effect
- # kind must exist before any side-effect analysis sees the op.
+ get_global_func("ir.RegisterOp")(entry.op_name, entry.name)
+ # Effect kind must exist before any side-effect analysis sees the op.
register_op_attr(entry.op_name, "TCallEffectKind", _EFFECT_OPAQUE)
# Encoded variants have no shared named operand prefix; codegen checks
# each variant's operands, predicate, modifier tokens, and marker.
@@ -112,6 +111,7 @@ def register_table(table: dict[str, InstructionEntry]) -> None:
def register_addr() -> None:
"""Register the pure address-expression op consumed by PTX instructions."""
+ get_global_func("ir.RegisterOp")(_ADDR_OP_NAME, "PTX address expression")
register_op_attr(_ADDR_OP_NAME, "TCallEffectKind", _EFFECT_PURE)
op = Op.get(_ADDR_OP_NAME)
op.add_arg("base", "The base pointer.")
@@ -298,7 +298,7 @@ def _make_codegen(entry: InstructionEntry):
# is forwarded as-is.
forwarded = [rest[at[i]] for i in range(n_operands) if i not in imm_at and i not in sunk]
forwarded += list(rest[n_present:])
- return cuda_func_call(helper, *forwarded, source)
+ return func_call(helper, *forwarded, source)
return codegen
@@ -450,7 +450,7 @@ def _coerce_operand(entry, slot, values, mod_map):
def _coerce_addr_arg(entry, slot, value, mod_map):
base = getattr(value.base, "scalar", value.base)
base = _coerce_address(entry, slot, base, mod_map)
- return call_intrin(base.ty, _ADDR_OP_NAME, base, value.byte_offset)
+ return call_intrin(_ADDR_OP_NAME, base, value.byte_offset, ty=base.ty)
def _coerce_pred_operand(entry, slot, values):
@@ -579,7 +579,7 @@ def _coerce_address(entry, slot, value, mod_map):
# helpers did. The pointer's storage_scope is not a reliable
# discriminator here: a shared buffer's ptr_to() reports 'global',
# so gating on it rejects correct code.
- return cuda_cvta_generic_to_shared(value)
+ return cvta_generic_to_shared(value)
if isinstance(ty, PrimType) and ty.dtype == "uint32":
return value # trusted raw shared-window address
raise ValueError(
@@ -598,7 +598,7 @@ def _coerce_address(entry, slot, value, mod_map):
# parameter is `const void*` and PTX binds it to the same "l" register
# either way, so make the conversion an explicit, visible IR node
# rather than a silent type pun.
- return reinterpret("handle", value)
+ return reinterpret(value, ty="handle")
if isinstance(ty, PrimType) and ty.dtype == "uint32":
raise ValueError(f"{entry.name}: uint32 address requires shared state space")
raise ValueError(f"{entry.name}: operand '{slot.name}' must be a pointer or uint64 handle")
@@ -790,12 +790,12 @@ def _emit(entry, filled, operands, pred=None, preserve_dst=False):
# there -- without it a printed call would re-parse at the wrong arity.
flags += [f"s{i}" for i in sorted(sunk)]
return call_intrin(
- "", # every ptx call is a void statement; destinations are operands
entry.op_name,
*coerced,
*((pred,) if pred is not None else ()),
*mod_map.values(),
",".join(flags),
+ ty="",
)
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/gen_stubs.py b/tirx/python/tvm_tirx/backend/cuda/ptx/gen_stubs.py
index d67014cb02..a18c037e03 100644
--- a/tirx/python/tvm_tirx/backend/cuda/ptx/gen_stubs.py
+++ b/tirx/python/tvm_tirx/backend/cuda/ptx/gen_stubs.py
@@ -18,11 +18,11 @@
Run manually (never at import time)::
- python -m tvm_tirx.backend.cuda.ptx.gen_stubs -o python/tvm/script/tirx.pyi
+ python -m tvm_tirx.backend.cuda.ptx.gen_stubs -o python/tvm_tirx/script/tirx.pyi
The output is a *module stub for* ``tvm_tirx.script.tirx``: that module is
virtual at runtime (dialect-registry ``__getattr__``), but a ``.pyi`` file
-at ``python/tvm/script/tirx.pyi`` makes Pyright/Pylance resolve it — giving
+at ``python/tvm_tirx/script/tirx.pyi`` makes Pyright/Pylance resolve it — giving
VS Code completion for ``T.ptx.`` chains. All other members fall back to
``Any`` via the stub's module ``__getattr__``, matching today's behavior.
@@ -157,7 +157,7 @@ def generate() -> str:
'"""Generated stub for T.ptx — do not edit.',
"",
"Regenerate:",
- " python -m tvm_tirx.backend.cuda.ptx.gen_stubs -o python/tvm/script/tirx.pyi",
+ " python -m tvm_tirx.backend.cuda.ptx.gen_stubs -o python/tvm_tirx/script/tirx.pyi",
'"""',
"",
"from typing import Any",
diff --git a/tirx/python/tvm_tirx/backend/cuda/script.py b/tirx/python/tvm_tirx/backend/cuda/script.py
index d939e4e0e0..1098ebe655 100644
--- a/tirx/python/tvm_tirx/backend/cuda/script.py
+++ b/tirx/python/tvm_tirx/backend/cuda/script.py
@@ -87,9 +87,9 @@ class CudaWgmmaNamespace:
"""WGMMA companions that are not PTX instructions (pure-C / empty-asm helpers)."""
def __init__(self):
- self.noop_barrier = _auto_emit_void_call(_cuda_op.cuda_wgmma_noop_barrier)
+ self.noop_barrier = _auto_emit_void_call(_cuda_op.wgmma_noop_barrier)
self.encode_matrix_descriptor = _auto_emit_void_call(
- _cuda_op.cuda_wgmma_encode_matrix_descriptor
+ _cuda_op.wgmma_encode_matrix_descriptor
)
@@ -98,7 +98,7 @@ class CudaTcgen05Namespace:
def __init__(self):
self.encode_matrix_descriptor = _auto_emit_void_call(
- _cuda_op.cuda_tcgen05_encode_matrix_descriptor
+ _cuda_op.tcgen05_encode_matrix_descriptor
)
self.encode_instr_descriptor = _auto_emit_void_call(
_ir.op._make_op_api(_ir.Op.get("tirx.cuda.tcgen05_encode_instr_descriptor"), __name__)
@@ -114,13 +114,13 @@ class IketNamespace:
"""Frontend-only NVIDIA IKET annotations."""
def __init__(self):
- self.mark = _auto_emit_void_call(_cuda_op.cuda_iket_mark)
- self.range_start = _auto_emit_void_call(_cuda_op.cuda_iket_range_start)
- self.range_end = _auto_emit_void_call(_cuda_op.cuda_iket_range_end)
- self.range_push = _auto_emit_void_call(_cuda_op.cuda_iket_range_push)
- self.range_pop = _auto_emit_void_call(_cuda_op.cuda_iket_range_pop)
- self.sentinel_token = _auto_emit_void_call(_cuda_op.cuda_iket_sentinel_token)
- self.official_event = _auto_emit_void_call(_cuda_op.cuda_iket_official_event)
+ self.mark = _auto_emit_void_call(_cuda_op.iket_mark)
+ self.range_start = _auto_emit_void_call(_cuda_op.iket_range_start)
+ self.range_end = _auto_emit_void_call(_cuda_op.iket_range_end)
+ self.range_push = _auto_emit_void_call(_cuda_op.iket_range_push)
+ self.range_pop = _auto_emit_void_call(_cuda_op.iket_range_pop)
+ self.sentinel_token = _auto_emit_void_call(_cuda_op.iket_sentinel_token)
+ self.official_event = _auto_emit_void_call(_cuda_op.iket_official_event)
TensorMapEncodeTiledAttr = _cuda_op.TensorMapEncodeTiledAttr
@@ -130,14 +130,14 @@ TCGen05InstrDescriptorBlockScaledAttrs = _cuda_op.TCGen05InstrDescriptorBlockSca
iket = IketNamespace()
wgmma = CudaWgmmaNamespace()
tcgen05 = CudaTcgen05Namespace()
-warp_sum = _auto_emit_void_call(_cuda_op.cuda_warp_sum)
-warp_max = _auto_emit_void_call(_cuda_op.cuda_warp_max)
-warp_min = _auto_emit_void_call(_cuda_op.cuda_warp_min)
-cta_sum = _auto_emit_void_call(_cuda_op.cuda_cta_sum)
-cta_max = _auto_emit_void_call(_cuda_op.cuda_cta_max)
-cta_min = _auto_emit_void_call(_cuda_op.cuda_cta_min)
-func_call = _auto_emit_void_call(_cuda_op.cuda_func_call)
-sm100_2sm_leader_smem_addr = _auto_emit_void_call(_cuda_op.cuda_sm100_2sm_leader_smem_addr)
+warp_sum = _auto_emit_void_call(_cuda_op.warp_sum)
+warp_max = _auto_emit_void_call(_cuda_op.warp_max)
+warp_min = _auto_emit_void_call(_cuda_op.warp_min)
+cta_sum = _auto_emit_void_call(_cuda_op.cta_sum)
+cta_max = _auto_emit_void_call(_cuda_op.cta_max)
+cta_min = _auto_emit_void_call(_cuda_op.cta_min)
+func_call = _auto_emit_void_call(_cuda_op.func_call)
+sm100_2sm_leader_smem_addr = _auto_emit_void_call(_cuda_op.sm100_2sm_leader_smem_addr)
timer_init = _auto_emit_void_call(_cuda_op.timer_init)
timer_start = _auto_emit_void_call(_cuda_op.timer_start)
timer_end = _auto_emit_void_call(_cuda_op.timer_end)
@@ -145,12 +145,12 @@ timer_finalize = _auto_emit_void_call(_cuda_op.timer_finalize)
mma_store = _auto_emit_void_call(_ir.op._make_op_api(_ir.Op.get("tirx.cuda.mma_store"), __name__))
mma_fill = _auto_emit_void_call(_ir.op._make_op_api(_ir.Op.get("tirx.cuda.mma_fill"), __name__))
bmma_sync = _auto_emit_void_call(_cuda_op.bmma_sync)
-atomic_add = _auto_emit_void_call(_cuda_op.cuda_atomic_add)
-atomic_cas = _auto_emit_void_call(_cuda_op.cuda_atomic_cas)
-cta_reduce = _auto_emit_void_call(_cuda_op.cuda_cta_reduce)
-mov_sreg = _auto_emit_void_call(_cuda_op.cuda_mov_sreg)
-wait_until = _auto_emit_void_call(_cuda_op.cuda_wait_until)
-warp_reduce = _auto_emit_void_call(_cuda_op.cuda_warp_reduce)
+atomic_add = _auto_emit_void_call(_cuda_op.atomic_add)
+atomic_cas = _auto_emit_void_call(_cuda_op.atomic_cas)
+cta_reduce = _auto_emit_void_call(_cuda_op.cta_reduce)
+mov_sreg = _auto_emit_void_call(_cuda_op.mov_sreg)
+wait_until = _auto_emit_void_call(_cuda_op.wait_until)
+warp_reduce = _auto_emit_void_call(_cuda_op.warp_reduce)
__shfl_sync = _auto_emit_void_call(_cuda_op.__shfl_sync)
__shfl_up_sync = _auto_emit_void_call(_cuda_op.__shfl_up_sync)
__shfl_down_sync = _auto_emit_void_call(_cuda_op.__shfl_down_sync)
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/async_copy.py b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/async_copy.py
index e3f711e311..3e25521419 100644
--- a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/async_copy.py
+++ b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/async_copy.py
@@ -66,14 +66,16 @@ def lower(opcode, entry, modifiers, args, params, sctx):
barrier, remote = params.pop("mbar"), params.pop("remote_cta_id")
mapped = Var("remote_addresses", T.Tensor((2,), "uint64", scope="local", layout="default"))
ctx.bindings.append(Bind(mapped, T.alloc_tensor(ty_args=[mapped.ty])))
- ctx.bindings.append(Evaluate(T.ptx.mapa.u64(mapped[0], barrier, T.cast(remote, "uint32"))))
+ ctx.bindings.append(
+ Evaluate(T.ptx.mapa.u64(mapped[0], barrier, T.cast(remote, ty="uint32")))
+ )
body = [
- T.ptx.mapa.u64(mapped[1], dst.pointer((0,)), T.cast(remote, "uint32")),
+ T.ptx.mapa.u64(mapped[1], dst.pointer((0,)), T.cast(remote, ty="uint32")),
instruction(
- T.cast(mapped[1], "uint32"),
+ T.cast(mapped[1], ty="uint32"),
src.pointer((0,)),
T.uint32(size),
- T.cast(mapped[0], "uint32"),
+ T.cast(mapped[0], ty="uint32"),
pred=pred,
),
]
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/common.py b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/common.py
index 7a4ae09733..0382449415 100644
--- a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/common.py
+++ b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/common.py
@@ -33,6 +33,7 @@ from tvm_tirx.ir import (
Evaluate,
For,
ForKind,
+ IntImm,
Op,
PrimType,
Range,
@@ -44,7 +45,7 @@ from tvm_tirx.ir.prim import Let
from tvm_tirx.runtime import DataType, MemoryScope
from tvm_tirx.script import tirx as T
from tvm_tirx.sym import Analyzer
-from tvm_tirx.tirx import Function, IntImm
+from tvm_tirx.tirx import Function
from tvm_tirx.tirx.layout import TileLayout
@@ -107,7 +108,7 @@ class Context:
self.owners["cbx" if name == "cta_id" else name] = var + offset
# A singleton group coordinate is known without a CUDA index
# read, including the sole warp in a block smaller than 32 lanes.
- coordinate = T.int32(0) if extent == 1 else T.cast(index(), "int32") - offset
+ coordinate = T.int32(0) if extent == 1 else T.cast(index(), ty="int32") - offset
self.bindings.append(Bind(var, coordinate))
self.repeat = None
self.repeat_shape = None
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/descriptors.py b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/descriptors.py
index 744ff83706..c729614dbb 100644
--- a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/descriptors.py
+++ b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/descriptors.py
@@ -25,9 +25,8 @@ selection is performed. PTX ISA 9.7.18.3.1 and 9.7.18.4.1.
import tvm_ffi
from tvm_tirx.backend.cuda.cpp.descriptors import encode_smem_descriptor_base_uint64
-from tvm_tirx.ir import Var
+from tvm_tirx.ir import IntImm, Var
from tvm_tirx.script import tirx as T
-from tvm_tirx.tirx import IntImm
from tvm_tirx.tirx.layout import ComposeLayout
@@ -58,10 +57,10 @@ def _encode_matrix_descriptor(ctx, smem, ldo, sdo, swizzle, atom_origin):
physical = smem.memory(atom_origin) * smem.bits // 8
address = (
address
- - T.cast(physical, "uint32")
- + T.cast(swizzle_bytes(physical, swizzle), "uint32")
+ - T.cast(physical, ty="uint32")
+ + T.cast(swizzle_bytes(physical, swizzle), ty="uint32")
)
- address = T.cast(address // T.uint32(16), "uint64")
+ address = T.cast(address // T.uint32(16), ty="uint64")
return T.bitwise_or(descriptor, T.bitwise_and(address, T.uint64(0x3FFF)))
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py
index 89330184b0..c84c0faa2b 100644
--- a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py
+++ b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py
@@ -193,7 +193,7 @@ def lower(opcode, entry, modifiers, args, params, sctx):
neg_a=neg_a,
neg_b=neg_b,
)
- accum = Or(ctx.repeat[-1] != 0, T.cast(params.pop("accum", False), "bool"))
+ accum = Or(ctx.repeat[-1] != 0, T.cast(params.pop("accum", False), ty="bool"))
pred = params.pop("pred", None)
if block_scale:
vec = int(modifiers["scale_vec"].split("::")[1][:-1])
@@ -210,8 +210,8 @@ def lower(opcode, entry, modifiers, args, params, sctx):
descriptor = encode_instr_descriptor_block_scaled_uint32(**common, sf_dtype=a_dtype)
idesc = (
T.uint32(descriptor)
- | (T.cast(a_id, "uint32") << T.uint32(29))
- | (T.cast(b_id, "uint32") << T.uint32(4))
+ | (T.cast(a_id, ty="uint32") << T.uint32(29))
+ | (T.cast(b_id, ty="uint32") << T.uint32(4))
)
native = [da, aa, ba, idesc, sfa, sfb, accum]
else:
@@ -227,7 +227,7 @@ def lower(opcode, entry, modifiers, args, params, sctx):
masks = sequence(params.pop("disable_output_lane", (0,) * (4 * cta_group)))
if len(masks) != 4 * cta_group:
raise ValueError("disable_output_lane has four entries per CTA")
- native = [da, aa, ba, idesc, *(T.cast(x, "uint32") for x in masks), accum]
+ native = [da, aa, ba, idesc, *(T.cast(x, ty="uint32") for x in masks), accum]
if modifiers["kind"] != "kind::" + kind:
raise ValueError("explicit MMA kind disagrees with operand formats")
if params:
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tma.py b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tma.py
index dba3fa7881..a467872eb4 100644
--- a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tma.py
+++ b/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tma.py
@@ -108,7 +108,7 @@ def _tensor_map(ctx, region, rank, box, encoding):
view_dims = tuple(r.extent for r in region.region)
dims = view_dims[:rank]
for size in dims:
- wide = T.cast(size, "int64")
+ wide = T.cast(size, ty="int64")
_encode_requirement(
ctx, T.And(wide > 0, wide <= 2**32), "TMA dimensions must be in 1..2^32"
)
@@ -166,7 +166,7 @@ def _tensor_map(ctx, region, rank, box, encoding):
f"TMA global origin requires {alignment}-byte alignment",
)
for stride in strides[:-1]:
- byte_stride = T.cast(stride, "int64") * bits // 8
+ byte_stride = T.cast(stride, ty="int64") * bits // 8
_encode_requirement(
ctx,
byte_stride % alignment == 0,
@@ -300,8 +300,8 @@ def lower(opcode, entry, modifiers, args, params, sctx):
ctx.require(base_bits % 1024 == 0, "TMA atom origin must be 128-byte aligned")
pointer = (
T.cuda.cvta_generic_to_shared(pointer)
- - T.cast(physical_bits // 8, "uint32")
- + T.cast(base_bits // 8, "uint32")
+ - T.cast(physical_bits // 8, ty="uint32")
+ + T.cast(base_bits // 8, ty="uint32")
)
else:
smem.aligned(origin, 128)
@@ -341,20 +341,20 @@ def lower(opcode, entry, modifiers, args, params, sctx):
if len(rows) != 4:
raise ValueError("gather4 requires four explicit row coordinates")
native_coords = [coords[-1], *rows]
- native_coords = [T.cast(c, "int32") for c in native_coords]
+ native_coords = [T.cast(c, ty="int32") for c in native_coords]
if load:
native = [pointer, tmap, *native_coords, params.pop("mbar")]
if modifiers.get("multicast"):
native.append(
T.cast(
params.pop("cta_mask"),
- "uint32" if entry.name.endswith("multicast32") else "uint16",
+ ty="uint32" if entry.name.endswith("multicast32") else "uint16",
)
)
else:
native = [tmap, *native_coords, pointer]
if modifiers.get("cache"):
- native.append(T.cast(params.pop("cache_policy"), "uint64"))
+ native.append(T.cast(params.pop("cache_policy"), ty="uint64"))
pred = params.pop("pred", None)
if params:
raise ValueError(f"{opcode}: unknown fields {tuple(params)}")
diff --git a/tirx/python/tvm_tirx/backend/metal/op.py b/tirx/python/tvm_tirx/backend/metal/op.py
index a3965ef994..9f3d85e86b 100644
--- a/tirx/python/tvm_tirx/backend/metal/op.py
+++ b/tirx/python/tvm_tirx/backend/metal/op.py
@@ -147,14 +147,7 @@ def cooperative_tensor_fill(
loc: Location = UNKNOWN_LOC,
):
return call_intrin(
- ty,
- "tirx.metal.cooperative_tensor_fill",
- d,
- index,
- value,
- rows,
- cols,
- loc=loc,
+ "tirx.metal.cooperative_tensor_fill", d, index, value, rows, cols, loc=loc, ty=ty
)
@@ -175,7 +168,6 @@ def cooperative_tensor_load(
loc: Location = UNKNOWN_LOC,
):
return call_intrin(
- ty,
"tirx.metal.cooperative_tensor_load",
d,
index,
@@ -189,6 +181,7 @@ def cooperative_tensor_load(
mma_K,
operand_role,
loc=loc,
+ ty=ty,
)
@@ -209,7 +202,6 @@ def cooperative_tensor_store(
loc: Location = UNKNOWN_LOC,
):
return call_intrin(
- ty,
"tirx.metal.cooperative_tensor_store",
d,
index,
@@ -223,6 +215,7 @@ def cooperative_tensor_store(
mma_K,
operand_role,
loc=loc,
+ ty=ty,
)
@@ -245,7 +238,6 @@ def cooperative_tensor_multiply_accumulate(
loc: Location = UNKNOWN_LOC,
):
return call_intrin(
- ty,
"tirx.metal.cooperative_tensor_multiply_accumulate",
d,
index_d,
@@ -261,4 +253,5 @@ def cooperative_tensor_multiply_accumulate(
transpose_a,
transpose_b,
loc=loc,
+ ty=ty,
)
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/binary/default.py b/tirx/python/tvm_tirx/backend/trn/tile/binary/default.py
index e74211e42b..8fc9014fe4 100644
--- a/tirx/python/tvm_tirx/backend/trn/tile/binary/default.py
+++ b/tirx/python/tvm_tirx/backend/trn/tile/binary/default.py
@@ -17,8 +17,9 @@
"""Implementation of binary operator dispatches."""
+from tvm_tirx.ir import FloatImm
from tvm_tirx.script import tirx as T
-from tvm_tirx.tirx import FloatImm, Function
+from tvm_tirx.tirx import Function
from tvm_tirx.tirx.tile import DispatchContext, fail
from tvm_tirx.tirx.tile.common import MapOpType
from tvm_tirx.tirx.tile.instruction import TensorCall
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/binary/utils.py b/tirx/python/tvm_tirx/backend/trn/tile/binary/utils.py
index a0ccfdabd7..1e068a565e 100644
--- a/tirx/python/tvm_tirx/backend/trn/tile/binary/utils.py
+++ b/tirx/python/tvm_tirx/backend/trn/tile/binary/utils.py
@@ -21,10 +21,9 @@ from enum import Enum
from functools import cache
from tvm_tirx.backend.trn.layout import is_trainium_layout
-from tvm_tirx.ir import TensorRegion
+from tvm_tirx.ir import FloatImm, TensorRegion
from tvm_tirx.runtime import MemoryScope
from tvm_tirx.sym.analyzer import Analyzer
-from tvm_tirx.tirx import FloatImm
from tvm_tirx.tirx.tile.common import MapOpType
from ..dim_utils import get_ewise_dim_map
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/instruction_generator.py b/tirx/python/tvm_tirx/backend/trn/tile/instruction_generator.py
index 727b8f5d4b..964f1b1b99 100644
--- a/tirx/python/tvm_tirx/backend/trn/tile/instruction_generator.py
+++ b/tirx/python/tvm_tirx/backend/trn/tile/instruction_generator.py
@@ -26,10 +26,10 @@ from operator import mul
import tvm_ffi
from tvm_tirx.backend.trn.layout import is_trainium_layout
-from tvm_tirx.ir import Range, TensorRegion, TensorRegionType
+from tvm_tirx.ir import IntImm, Range, TensorRegion, TensorRegionType
from tvm_tirx.script import tirx as T
from tvm_tirx.sym.analyzer import Analyzer
-from tvm_tirx.tirx import Expr, IntImm, Var, is_tensor_var
+from tvm_tirx.tirx import Expr, Var, is_tensor_var
from tvm_tirx.tirx.layout import Iter, TileLayout
from .dim_utils import DimensionMapper, RangeInfo, normalize_and_group
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/private_alloc.py b/tirx/python/tvm_tirx/backend/trn/tile/private_alloc.py
index 96d371cc82..43b63cad6e 100644
--- a/tirx/python/tvm_tirx/backend/trn/tile/private_alloc.py
+++ b/tirx/python/tvm_tirx/backend/trn/tile/private_alloc.py
@@ -19,10 +19,10 @@ from functools import cache
from typing import Any
from tvm_tirx.backend.trn.tile.common import nki_dim
-from tvm_tirx.ir import Bind, Call, DictAttrs, Stmt, Tuple
+from tvm_tirx.ir import Bind, Call, DictAttrs, FloatImm, IntImm, Stmt, Tuple
from tvm_tirx.runtime import MemoryScope
from tvm_tirx.script import tirx as T
-from tvm_tirx.tirx import FloatImm, IntImm, Var
+from tvm_tirx.tirx import Var
from tvm_tirx.tirx.tile import DispatchContext
from tvm_tirx.tirx.tile.dispatch import run_dispatch
from tvm_tirx.tirx.tile.instruction import TensorCall
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/select/default.py b/tirx/python/tvm_tirx/backend/trn/tile/select/default.py
index f147540f1b..e3e738d925 100644
--- a/tirx/python/tvm_tirx/backend/trn/tile/select/default.py
+++ b/tirx/python/tvm_tirx/backend/trn/tile/select/default.py
@@ -20,10 +20,10 @@
from functools import cache
from tvm_tirx.backend.trn.layout import is_trainium_layout
-from tvm_tirx.ir import TensorRegion
+from tvm_tirx.ir import FloatImm, TensorRegion
from tvm_tirx.runtime import MemoryScope
from tvm_tirx.script import tirx as T
-from tvm_tirx.tirx import FloatImm, Function
+from tvm_tirx.tirx import Function
from tvm_tirx.tirx.tile import DispatchContext, fail
from tvm_tirx.tirx.tile.instruction import TensorCall
from tvm_tirx.tirx.tile.views import Select
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/unary/default.py b/tirx/python/tvm_tirx/backend/trn/tile/unary/default.py
index daa88d2842..f921915e6f 100644
--- a/tirx/python/tvm_tirx/backend/trn/tile/unary/default.py
+++ b/tirx/python/tvm_tirx/backend/trn/tile/unary/default.py
@@ -17,7 +17,8 @@
"""Implementation of default unary operator dispatches."""
-from tvm_tirx.tirx import FloatImm, Function
+from tvm_tirx.ir import FloatImm
+from tvm_tirx.tirx import Function
from tvm_tirx.tirx.tile import DispatchContext, fail
from tvm_tirx.tirx.tile.common import MapOpType
from tvm_tirx.tirx.tile.instruction import TensorCall
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/unary/utils.py b/tirx/python/tvm_tirx/backend/trn/tile/unary/utils.py
index de1873c36c..dfd904691e 100644
--- a/tirx/python/tvm_tirx/backend/trn/tile/unary/utils.py
+++ b/tirx/python/tvm_tirx/backend/trn/tile/unary/utils.py
@@ -20,11 +20,10 @@
from functools import cache
from tvm_tirx.backend.trn.layout import is_trainium_layout
-from tvm_tirx.ir import TensorRegion
+from tvm_tirx.ir import FloatImm, TensorRegion
from tvm_tirx.runtime import MemoryScope
from tvm_tirx.script import tirx as T
from tvm_tirx.sym.analyzer import Analyzer
-from tvm_tirx.tirx import FloatImm
from tvm_tirx.tirx.tile.common import MapOpType
from ..common import nki_dim
diff --git a/tirx/python/tvm_tirx/backend/trn/transform/naive_allocator.py b/tirx/python/tvm_tirx/backend/trn/transform/naive_allocator.py
index 9e4a8be57f..26b5d8eafa 100644
--- a/tirx/python/tvm_tirx/backend/trn/transform/naive_allocator.py
+++ b/tirx/python/tvm_tirx/backend/trn/transform/naive_allocator.py
@@ -20,9 +20,8 @@ from functools import cache
import tvm_ffi
-from tvm_tirx.ir import Bind, Call, Op, Tuple, Var
+from tvm_tirx.ir import Bind, Call, IntImm, Op, Tuple, Var
from tvm_tirx.runtime import MemoryScope
-from tvm_tirx.tirx import IntImm
from tvm_tirx.tirx.transform.function_pass import function_pass
_SCOPE_SHARED = MemoryScope("shared")
diff --git a/tirx/python/tvm_tirx/ir/__init__.py b/tirx/python/tvm_tirx/ir/__init__.py
index e7a69a26a7..a577eeeb6b 100644
--- a/tirx/python/tvm_tirx/ir/__init__.py
+++ b/tirx/python/tvm_tirx/ir/__init__.py
@@ -39,6 +39,9 @@ from .type import (
)
from .expr import (
Call,
+ CallEffectKind,
+ IntImm,
+ FloatImm,
Constant,
GenericConst,
DataTypeImm,
diff --git a/tirx/python/tvm_tirx/ir/_overload_prim_expr.py b/tirx/python/tvm_tirx/ir/_overload_prim_expr.py
index dcc73e3358..a0e6f2f230 100644
--- a/tirx/python/tvm_tirx/ir/_overload_prim_expr.py
+++ b/tirx/python/tvm_tirx/ir/_overload_prim_expr.py
@@ -180,7 +180,7 @@ class ExprOp:
def __invert__(self) -> Expr:
if _dtype_is_float(self):
raise RuntimeError("Cannot use ~ operator on float type Expr.")
- return _prim_ffi_api.bitwise_not(self, UNKNOWN_LOC) # type: ignore
+ return _prim_ffi_api.BitwiseNot(self, UNKNOWN_LOC) # type: ignore
def __lt__(self, other: Expr) -> Expr:
return _prim_ffi_api._OpLT(self, other, UNKNOWN_LOC) # type: ignore
diff --git a/tirx/python/tvm_tirx/ir/attrs.py b/tirx/python/tvm_tirx/ir/attrs.py
index 4bd7336ecd..90f8dd6496 100644
--- a/tirx/python/tvm_tirx/ir/attrs.py
+++ b/tirx/python/tvm_tirx/ir/attrs.py
@@ -21,8 +21,6 @@ import tvm_ffi._ffi_api as _tvm_ffi_api
from tvm_tirx.runtime import Object
-from . import _ffi_api
-
@tvm_ffi.register_object("ir.Attrs")
class Attrs(Object):
@@ -79,20 +77,6 @@ class Attrs(Object):
class DictAttrs(Attrs):
"""Dictionary attributes."""
- @property
- def __dict__(self):
- """Return the underlying key-value map as a Python dict.
-
- Defined explicitly so that tvm_ffi's _add_class_attrs skips registering
- the C++ reflection field named '__dict__' (Python forbids adding a class
- attribute named '__dict__' via setattr on extension-type subclasses).
- """
- return dict(self._dict())
-
- def _dict(self):
- """Get internal dict"""
- return _ffi_api.DictAttrsGetDict(self)
-
def keys(self):
"""Get list of names in the attribute.
@@ -104,30 +88,30 @@ class DictAttrs(Attrs):
return [k for k, _ in self.items()]
def __getitem__(self, k):
- return self._dict().__getitem__(k)
+ return self.dict.__getitem__(k)
def get(self, key, default=None):
"""Get an element with a default value."""
- return self._dict().get(key, default)
+ return self.dict.get(key, default)
def __contains__(self, k):
- return self._dict().__contains__(k)
+ return self.dict.__contains__(k)
def __getattr__(self, name):
try:
- return self._dict().__getitem__(name)
+ return self.dict.__getitem__(name)
except KeyError:
raise AttributeError(f"DictAttrs has no attribute {name}")
def items(self):
"""Get items from the map."""
- return self._dict().items()
+ return self.dict.items()
def __len__(self):
- return self._dict().__len__()
+ return self.dict.__len__()
-def make_node(type_key, **kwargs):
+def make_node(type_key, /, **kwargs):
"""Make a new IR node by its type key and fields
Parameters
@@ -136,7 +120,7 @@ def make_node(type_key, **kwargs):
The type key of the node.
**kwargs : dict
- The fields of the node.
+ The fields of the node. For ``ir.DictAttrs``, these are the dictionary entries.
Returns
-------
@@ -158,13 +142,11 @@ def make_node(type_key, **kwargs):
x = tvm_tirx.ir.make_node(
"ir.IntImm", ty=tvm_tirx.ir.PrimType("int32"), value=10, loc=tvm_tirx.ir.UnknownLoc()
)
- assert isinstance(x, tvm_tirx.ir.prim.IntImm)
+ assert isinstance(x, tvm_tirx.ir.IntImm)
assert x.value == 10
"""
if type_key == "ir.DictAttrs":
- # DictAttrs stores kwargs as a key-value dict, not as named fields.
- # MakeObjectFromPackedArgs would look for a field named "__dict__".
- return _tvm_ffi_api.MakeObjectFromPackedArgs("ir.DictAttrs", "__dict__", kwargs)
+ return DictAttrs(dict=kwargs)
args = [type_key]
for k, v in kwargs.items():
args += [k, v]
diff --git a/tirx/python/tvm_tirx/ir/base.py b/tirx/python/tvm_tirx/ir/base.py
index a7af458c45..b0d2706f16 100644
--- a/tirx/python/tvm_tirx/ir/base.py
+++ b/tirx/python/tvm_tirx/ir/base.py
@@ -58,10 +58,6 @@ class EnvFunc(Object):
def __call__(self, *args):
return _ffi_api.EnvFuncCall(self, *args) # type: ignore # pylint: disable=no-member
- @property
- def func(self):
- return _ffi_api.EnvFuncGetFunction(self) # type: ignore # pylint: disable=no-member
-
@staticmethod
def get(name):
"""Get a static env function
diff --git a/tirx/python/tvm_tirx/ir/expr.py b/tirx/python/tvm_tirx/ir/expr.py
index cef924cc4e..66dd64a2de 100644
--- a/tirx/python/tvm_tirx/ir/expr.py
+++ b/tirx/python/tvm_tirx/ir/expr.py
@@ -17,6 +17,7 @@
"""Common expressions data structures in the IR."""
from collections.abc import Callable
+from enum import IntEnum
from functools import partial
from inspect import getattr_static
from numbers import Number
@@ -30,6 +31,7 @@ from ..runtime import Object
from . import _ffi_api, _tensor_expr_overload
from ._constant import const
from .base import Node, Scriptable
+from .type import PrimType
_ATTRIBUTE_MISSING = object()
@@ -148,12 +150,15 @@ class GlobalVar(Expr):
----------
name_hint: str
The name of the variable.
+
+ loc : Location, optional
+ The location of this node in the source code.
"""
name_hint: str
- def __init__(self, name_hint: str):
- self.__init_handle_by_constructor__(_ffi_api.GlobalVar, name_hint)
+ def __init__(self, name_hint: str, loc: Location = UNKNOWN_LOC):
+ self.__init_handle_by_constructor__(_ffi_api.GlobalVar, name_hint, loc)
def __call__(self, *args: Expr) -> Expr:
"""Call the global variable.
@@ -513,6 +518,85 @@ class Constant(ExprWithOp):
"""Base class of literal constants."""
+@tvm_ffi.register_object("ir.FloatImm")
+class FloatImm(Constant):
+ """Float constant.
+
+ Parameters
+ ----------
+ dtype : str
+ The data type
+
+ value : float
+ The constant value.
+
+ loc : Location, optional
+ The location of this expression in the source code.
+ """
+
+ value: float
+
+ def __init__(self, dtype: str | PrimType, value: float, loc: Location = UNKNOWN_LOC) -> None:
+ if isinstance(dtype, PrimType):
+ dtype = dtype.dtype
+ self.__init_handle_by_constructor__(
+ _ffi_api.FloatImm,
+ dtype,
+ value,
+ loc, # type: ignore
+ )
+
+ def __float__(self) -> float:
+ return self.value
+
+
+@tvm_ffi.register_object("ir.IntImm")
+class IntImm(Constant):
+ """Int constant.
+
+ Parameters
+ ----------
+ dtype : str
+ The data type
+
+ value : int
+ The constant value.
+
+ loc : Location, optional
+ The location of this expression in the source code.
+ """
+
+ value: int
+
+ def __init__(self, dtype: str | PrimType, value: int, loc: Location = UNKNOWN_LOC) -> None:
+ if isinstance(dtype, PrimType):
+ dtype = dtype.dtype
+ self.__init_handle_by_constructor__(
+ _ffi_api.IntImm,
+ dtype,
+ value,
+ loc, # type: ignore
+ )
+
+ def __hash__(self) -> int:
+ return self.value
+
+ def __int__(self) -> int:
+ return self.value
+
+ def __nonzero__(self) -> bool:
+ return self.value != 0
+
+ def __eq__(self, other: Expr) -> Expr:
+ return _prim_ffi_api._OpEQ(self, other, UNKNOWN_LOC) # type: ignore
+
+ def __ne__(self, other: Expr) -> Expr:
+ return _prim_ffi_api._OpNE(self, other, UNKNOWN_LOC) # type: ignore
+
+ def __bool__(self) -> bool:
+ return self.__nonzero__()
+
+
@tvm_ffi.register_object("ir.GenericConst")
class GenericConst(_ExprCallable, Constant):
"""A literal payload with an explicit expression type."""
@@ -560,6 +644,19 @@ class StringImm(Constant):
__hash__ = Expr.__hash__
+class CallEffectKind(IntEnum):
+ """Possible call effects, matching the shared C++ IR effect kinds."""
+
+ ExprAnnotation = 0
+ Pure = 1
+ ReadState = 2
+ UpdateState = 3
+ Opaque = UpdateState
+ SpecialCallArg = 4
+ EmbedInfo = 5
+ ControlJump = 6
+
+
@tvm_ffi.register_object("ir.Call")
class Call(_CallableExprWithOp):
"""Core function call node.
@@ -757,19 +854,23 @@ class LambdaExpr(StagingExpr, Scriptable):
Tuple/list results become shared IR Tuple expressions.
ret_type : Type, optional
An exact return-type check. No implicit conversion or cast is inserted.
+ loc : Location, optional
+ The location of this node in the source code.
"""
vars: list[Var]
body: Expr
- def __init__(self, parameter_types, function: Callable, *, ret_type=None):
+ def __init__(
+ self, parameter_types, function: Callable, *, ret_type=None, loc: Location = UNKNOWN_LOC
+ ):
variables = [Var(f"arg{i}", _lambda_type(ty)) for i, ty in enumerate(parameter_types)]
body = _lambda_result(function(*variables))
if ret_type is not None:
expected = _lambda_type(ret_type)
if not tvm_ffi.structural_equal(expected, body.ty):
raise TypeError("LambdaExpr return annotation does not match the body type")
- self.__init_handle_by_constructor__(_ffi_api.LambdaExpr, variables, body)
+ self.__init_handle_by_constructor__(_ffi_api.LambdaExpr, variables, body, loc)
def apply(self, arguments: list[Expr]) -> Expr:
"""Substitute arguments simultaneously for the lambda's bound variables."""
@@ -786,8 +887,8 @@ class Range(Node, Scriptable):
Parameters
----------
begin : Expr
- The begin value of the range when end is None.
- Otherwise it is the length of the range.
+ The begin value of the range when end is not None.
+ Otherwise it is the extent of the range ``[0, begin)``.
end : Optional[Expr]
The end value of the range.
@@ -842,3 +943,4 @@ class Range(Node, Scriptable):
# Primitive overloads also initialize the concrete primitive nodes, whose bases
# must be defined before importing them.
from . import _overload_prim_expr # noqa: E402 # pylint: disable=wrong-import-position
+from .prim import _ffi_api as _prim_ffi_api # noqa: E402 # pylint: disable=wrong-import-position
diff --git a/tirx/python/tvm_tirx/ir/function.py b/tirx/python/tvm_tirx/ir/function.py
index d9ad5ce9fd..c7814119fb 100644
--- a/tirx/python/tvm_tirx/ir/function.py
+++ b/tirx/python/tvm_tirx/ir/function.py
@@ -44,11 +44,6 @@ class BaseFunc(_CallableExprWithOp):
def __bool__(self) -> bool:
return True
- @property
- def attrs(self):
- """Return the attrs member of the function."""
- return _ffi_api.BaseFunc_Attrs(self)
-
def with_attr(self, attr_key_or_dict, attr_value=None) -> "BaseFunc":
"""Create a new copy of the function and update the attribute.
@@ -97,7 +92,7 @@ class BaseFunc(_CallableExprWithOp):
A new copy of the function
"""
if isinstance(attr_map, tvm_tirx.ir.DictAttrs):
- attr_map = attr_map._dict()
+ attr_map = attr_map.dict
return _ffi_api.BaseFuncWithAttrs(self, attr_map)
diff --git a/tirx/python/tvm_tirx/ir/json_compact.py b/tirx/python/tvm_tirx/ir/json_compact.py
index 66a76c5cfe..783ae55401 100644
--- a/tirx/python/tvm_tirx/ir/json_compact.py
+++ b/tirx/python/tvm_tirx/ir/json_compact.py
@@ -18,55 +18,6 @@
import json
-_PRIM_TYPE_KEY_RENAMES = {
- "arith.Analyzer": "sym.Analyzer",
- "arith.CanonicalExpr": "sym.CanonicalExpr",
- "arith.ConstIntBound": "sym.ConstIntBound",
- "arith.IntervalSet": "sym.IntervalSet",
- "arith.IterMapExpr": "sym.IterMapExpr",
- "arith.IterMapResult": "sym.IterMapResult",
- "arith.IterMark": "sym.IterMark",
- "arith.IterSplitExpr": "sym.IterSplitExpr",
- "arith.IterSumExpr": "sym.IterSumExpr",
- "arith.ModularSet": "sym.ModularSet",
- "arith.RewriteSimplifierStats": "sym.RewriteSimplifierStats",
- "arith.SplitExpr": "sym.SplitExpr",
- "arith.SumExpr": "sym.SumExpr",
- "tirx.BufferRegion": "ir.TensorRegion",
- "tirx.BufferRegionType": "ir.TensorRegionType",
- "tirx.IterVar": "s_tir.IterVar",
- "tirx.SBlock": "s_tir.SBlock",
- "tirx.SBlockRealize": "s_tir.SBlockRealize",
- "tirx.MatchBufferRegion": "s_tir.MatchBufferRegion",
- "tirx.TensorIntrin": "s_tir.TensorIntrin",
- "tirx.Cast": "ir.prim.Cast",
- "tirx.Add": "ir.prim.Add",
- "tirx.Sub": "ir.prim.Sub",
- "tirx.Mul": "ir.prim.Mul",
- "tirx.Div": "ir.prim.Div",
- "tirx.Mod": "ir.prim.Mod",
- "tirx.FloorDiv": "ir.prim.FloorDiv",
- "tirx.FloorMod": "ir.prim.FloorMod",
- "tirx.Min": "ir.prim.Min",
- "tirx.Max": "ir.prim.Max",
- "tirx.EQ": "ir.prim.EQ",
- "tirx.NE": "ir.prim.NE",
- "tirx.LT": "ir.prim.LT",
- "tirx.LE": "ir.prim.LE",
- "tirx.GT": "ir.prim.GT",
- "tirx.GE": "ir.prim.GE",
- "tirx.And": "ir.prim.And",
- "tirx.Or": "ir.prim.Or",
- "tirx.Not": "ir.prim.Not",
- "tirx.Select": "ir.prim.Select",
- "tirx.Let": "ir.prim.Let",
- "tirx.Ramp": "ir.prim.Ramp",
- "tirx.Broadcast": "ir.prim.Broadcast",
- "tirx.Shuffle": "ir.prim.Shuffle",
- "tirx.CommReducer": "te.CommReducer",
- "tirx.Reduce": "te.Reduce",
-}
-
def get_version(jgraph):
"""
@@ -139,22 +90,7 @@ def upgrade_json(json_str):
# written before the canonical Var field was renamed to `name`. Rewriting
# nodes in place preserves node indices and shared references.
nodes = data.get("nodes", [])
- tensor_region_type = None
for node in nodes:
- if node.get("type") == "tirx.BufferRegion":
- fields = node.get("data")
- if not isinstance(fields, dict) or "buffer" not in fields:
- raise ValueError("Legacy tirx.BufferRegion requires a buffer field")
- fields["source"] = fields.pop("buffer")
- # Typed BufferRegion already carries type/loc. Before it became
- # an Expr, it had only buffer/region; supply that form's defaults
- # by appending a type node so existing graph indices stay intact.
- if "ty" not in fields:
- if tensor_region_type is None:
- tensor_region_type = len(nodes)
- nodes.append({"type": "ir.TensorRegionType", "data": {}})
- fields["ty"] = tensor_region_type
- node["type"] = _PRIM_TYPE_KEY_RENAMES.get(node.get("type"), node.get("type"))
if node.get("type") == "relax.expr.Var":
node["type"] = "ir.Var"
elif node.get("type") == "tirx.Var":
diff --git a/tirx/python/tvm_tirx/ir/location.py b/tirx/python/tvm_tirx/ir/location.py
index eb3a802dc9..eeeb35d62c 100644
--- a/tirx/python/tvm_tirx/ir/location.py
+++ b/tirx/python/tvm_tirx/ir/location.py
@@ -16,7 +16,7 @@
# under the License.
"""Source-location metadata and the shared unknown location."""
-from tvm_ffi import get_global_func, register_object
+from tvm_ffi import register_object
from tvm_tirx.base import _RUNTIME_ONLY
from tvm_tirx.runtime import Object
@@ -24,12 +24,6 @@ from tvm_tirx.runtime import Object
from . import _ffi_api
-@register_object("ir.SourceMap")
-class SourceMap(Object):
- def add(self, name, content):
- return get_global_func("SourceMapAdd")(self, name, content)
-
-
@register_object("ir.SourceName")
class SourceName(Object):
"""An identifier for a source location.
diff --git a/tirx/python/tvm_tirx/ir/module.py b/tirx/python/tvm_tirx/ir/module.py
index 187340c6d1..3be29155a6 100644
--- a/tirx/python/tvm_tirx/ir/module.py
+++ b/tirx/python/tvm_tirx/ir/module.py
@@ -66,7 +66,7 @@ class IRModule(Node, Scriptable):
self.__pyfuncs__ = {}
def clone(self) -> "IRModule":
- return _ffi_api.Module_Clone(self)
+ return _ffi_api.IRModuleClone(self)
def functions_items(self):
"""Get items in self.functions.items() in alphabetical order.
@@ -96,11 +96,11 @@ class IRModule(Node, Scriptable):
def _add(self, var, val, update=True):
if isinstance(val, BaseFunc):
if isinstance(var, str):
- if _ffi_api.Module_ContainGlobalVar(self, var):
- var = _ffi_api.Module_GetGlobalVar(self, var)
+ if _ffi_api.IRModuleContainGlobalVar(self, var):
+ var = _ffi_api.IRModuleGetGlobalVar(self, var)
else:
var = _expr.GlobalVar(var)
- _ffi_api.Module_Add(self, var, val, update)
+ _ffi_api.IRModuleAdd(self, var, val, update)
def __getitem__(self, var):
"""Lookup a global definition by name or by variable.
@@ -116,15 +116,15 @@ class IRModule(Node, Scriptable):
The definition referenced by :code:`var` (either a function or type).
"""
if isinstance(var, str):
- return _ffi_api.Module_Lookup_str(self, var)
+ return _ffi_api.IRModuleLookupStr(self, var)
assert isinstance(var, _expr.GlobalVar)
- return _ffi_api.Module_Lookup(self, var)
+ return _ffi_api.IRModuleLookup(self, var)
def __delitem__(self, var: str | _expr.GlobalVar):
- _ffi_api.Module_Remove(self, var)
+ _ffi_api.IRModuleRemove(self, var)
def __contains__(self, var: str | _expr.GlobalVar) -> bool:
- return _ffi_api.Module_Contains(self, var)
+ return _ffi_api.IRModuleContains(self, var)
def update(self, other):
"""Insert functions in another Module to current one.
@@ -137,7 +137,7 @@ class IRModule(Node, Scriptable):
if isinstance(other, dict):
other = IRModule(other)
- return _ffi_api.Module_Update(self, other)
+ return _ffi_api.IRModuleUpdate(self, other)
def update_func(self, var, func):
"""Update the function corresponding to a global variable in the
@@ -151,7 +151,7 @@ class IRModule(Node, Scriptable):
func: tvm_tirx.ir.BaseFunc
The function to be inserted.
"""
- return _ffi_api.Module_UpdateFunction(self, var, func)
+ return _ffi_api.IRModuleUpdateFunction(self, var, func)
def update_global_info(self, name, global_info):
"""Update global info in the module
@@ -164,7 +164,7 @@ class IRModule(Node, Scriptable):
global_info: List[GlobalInfo]
The global info to be updated.
"""
- return _ffi_api.Module_UpdateGlobalInfo(self, name, global_info)
+ return _ffi_api.IRModuleUpdateGlobalInfo(self, name, global_info)
def get_global_var(self, name):
"""Get a global variable in the function by name.
@@ -183,7 +183,7 @@ class IRModule(Node, Scriptable):
------
RuntimeError if we cannot find corresponding global var.
"""
- return _ffi_api.Module_GetGlobalVar(self, name)
+ return _ffi_api.IRModuleGetGlobalVar(self, name)
def get_global_vars(self):
"""Collect all global vars defined in this module.
@@ -193,7 +193,7 @@ class IRModule(Node, Scriptable):
global_vars: Array[GlobalVar]
An array of global vars.
"""
- return _ffi_api.Module_GetGlobalVars(self)
+ return _ffi_api.IRModuleGetGlobalVars(self)
@staticmethod
def from_expr(expr, functions=None):
@@ -215,7 +215,7 @@ class IRModule(Node, Scriptable):
(wrapped in a function if necessary)
"""
funcs = functions if functions is not None else {}
- return _ffi_api.Module_FromExpr(expr, funcs)
+ return _ffi_api.IRModuleFromExpr(expr, funcs)
def get_attr(self, attr_key):
"""Get the IRModule attribute.
@@ -231,7 +231,7 @@ class IRModule(Node, Scriptable):
Attribute value
"""
- return _ffi_api.Module_GetAttr(self, attr_key)
+ return _ffi_api.IRModuleGetAttr(self, attr_key)
def with_attr(self, attr_key, attr_value):
"""Copy the IRModule and add an attribute to it.
@@ -250,7 +250,7 @@ class IRModule(Node, Scriptable):
A new copy of the IRModule with the attribute
"""
- return _ffi_api.Module_WithAttr(self, attr_key, attr_value)
+ return _ffi_api.IRModuleWithAttr(self, attr_key, attr_value)
def without_attr(self, attr_key: str) -> "IRModule":
"""Copy the IRModule and remove an attribute key and its associated value.
@@ -264,7 +264,7 @@ class IRModule(Node, Scriptable):
A new copy of the IRModule without the attribute
"""
- return _ffi_api.Module_WithoutAttr(self, attr_key)
+ return _ffi_api.IRModuleWithoutAttr(self, attr_key)
def with_attrs(self, attr_map: DictAttrs | dict[str, Object]) -> "IRModule":
"""Copy the IRModule and add the given attribute map to it.
@@ -278,6 +278,6 @@ class IRModule(Node, Scriptable):
A new copy of the IRModule with the attribute
"""
if isinstance(attr_map, DictAttrs):
- attr_map = attr_map._dict()
+ attr_map = attr_map.dict
- return _ffi_api.Module_WithAttrs(self, attr_map)
+ return _ffi_api.IRModuleWithAttrs(self, attr_map)
diff --git a/tirx/python/tvm_tirx/ir/op.py b/tirx/python/tvm_tirx/ir/op.py
index 5d878316be..7773e33129 100644
--- a/tirx/python/tvm_tirx/ir/op.py
+++ b/tirx/python/tvm_tirx/ir/op.py
@@ -271,12 +271,12 @@ def register_op_attr(op_name, attr_key, value=None, override=False):
-------
result : object or function
The registered value when supplied, or a decorator that registers and
- returns its argument. The named Op is created if it does not exist.
+ returns its argument. The named Op must already be registered.
"""
def _register(v):
"""internal register function"""
- _ffi_api.RegisterOpAttr(op_name, attr_key, v, override)
+ Op.get(op_name).set_attr(attr_key, v, override)
return v
return _register(value) if value is not None else _register
diff --git a/tirx/python/tvm_tirx/ir/prim/__init__.py b/tirx/python/tvm_tirx/ir/prim/__init__.py
index 730885e7ee..8745506616 100644
--- a/tirx/python/tvm_tirx/ir/prim/__init__.py
+++ b/tirx/python/tvm_tirx/ir/prim/__init__.py
@@ -34,14 +34,11 @@ from .expr import (
BitwiseNot,
BitwiseOr,
BitwiseXor,
- Broadcast,
Cast,
CmpExpr,
Div,
- FloatImm,
FloorDiv,
FloorMod,
- IntImm,
Let,
LogicalExpr,
LShift,
@@ -51,10 +48,8 @@ from .expr import (
Mul,
Not,
Or,
- Ramp,
RShift,
Select,
- Shuffle,
Sub,
)
from .op import (
@@ -128,6 +123,7 @@ from .op import (
truncmod,
vscale,
)
+from .vector_expr import Broadcast, Ramp, Shuffle
def expr_deep_equal(lhs: Expr, rhs: Expr) -> bool:
diff --git a/tirx/python/tvm_tirx/ir/prim/expr.py b/tirx/python/tvm_tirx/ir/prim/expr.py
index e98d7a26c0..516eefcc5b 100644
--- a/tirx/python/tvm_tirx/ir/prim/expr.py
+++ b/tirx/python/tvm_tirx/ir/prim/expr.py
@@ -20,8 +20,8 @@ import tvm_ffi
from tvm_tirx.ir.location import UNKNOWN_LOC, Location
-from .. import _ffi_api as _ir_ffi_api
-from ..expr import Constant, Expr, ExprWithOp, Var
+from ..expr import Expr, ExprWithOp, Var
+from ..expr import IntImm as _IntImm
from ..type import PrimType
from . import _ffi_api as _prim_ffi_api
@@ -40,85 +40,6 @@ class LogicalExpr(ExprWithOp):
pass
-@tvm_ffi.register_object("ir.FloatImm")
-class FloatImm(Constant):
- """Float constant.
-
- Parameters
- ----------
- dtype : str
- The data type
-
- value : float
- The constant value.
-
- loc : Location, optional
- The location of this expression in the source code.
- """
-
- value: float
-
- def __init__(self, dtype: str | PrimType, value: float, loc: Location = UNKNOWN_LOC) -> None:
- if isinstance(dtype, PrimType):
- dtype = dtype.dtype
- self.__init_handle_by_constructor__(
- _ir_ffi_api.FloatImm,
- dtype,
- value,
- loc, # type: ignore
- )
-
- def __float__(self) -> float:
- return self.value
-
-
-@tvm_ffi.register_object("ir.IntImm")
-class IntImm(Constant):
- """Int constant.
-
- Parameters
- ----------
- dtype : str
- The data type
-
- value : int
- The constant value.
-
- loc : Location, optional
- The location of this expression in the source code.
- """
-
- value: int
-
- def __init__(self, dtype: str | PrimType, value: int, loc: Location = UNKNOWN_LOC) -> None:
- if isinstance(dtype, PrimType):
- dtype = dtype.dtype
- self.__init_handle_by_constructor__(
- _ir_ffi_api.IntImm,
- dtype,
- value,
- loc, # type: ignore
- )
-
- def __hash__(self) -> int:
- return self.value
-
- def __int__(self) -> int:
- return self.value
-
- def __nonzero__(self) -> bool:
- return self.value != 0
-
- def __eq__(self, other: Expr) -> Expr:
- return _prim_ffi_api._OpEQ(self, other, UNKNOWN_LOC) # type: ignore
-
- def __ne__(self, other: Expr) -> Expr:
- return _prim_ffi_api._OpNE(self, other, UNKNOWN_LOC) # type: ignore
-
- def __bool__(self) -> bool:
- return self.__nonzero__()
-
-
@tvm_ffi.register_object("prim.Cast")
class Cast(ExprWithOp):
"""Cast expression.
@@ -662,7 +583,7 @@ class Select(ExprWithOp):
loc: Location = UNKNOWN_LOC,
) -> None:
if isinstance(condition, bool):
- condition = IntImm("bool", condition)
+ condition = _IntImm("bool", condition)
self.__init_handle_by_constructor__(
_prim_ffi_api.Select,
condition,
@@ -672,92 +593,6 @@ class Select(ExprWithOp):
)
-@tvm_ffi.register_object("prim.Ramp")
-class Ramp(ExprWithOp):
- """Ramp node.
-
- Parameters
- ----------
- base : Expr
- The base expression.
-
- stride : Expr
- The stride of the ramp.
-
- lanes : Expr
- The lanes of the expression.
-
- loc : Location, optional
- The location of this expression in the source code.
- """
-
- base: Expr
- stride: Expr
- lanes: Expr
-
- def __init__(self, base: Expr, stride: Expr, lanes: Expr, loc: Location = UNKNOWN_LOC) -> None:
- self.__init_handle_by_constructor__(
- _prim_ffi_api.Ramp,
- base,
- stride,
- lanes,
- loc, # type: ignore
- )
-
-
-@tvm_ffi.register_object("prim.Broadcast")
-class Broadcast(ExprWithOp):
- """Broadcast node.
-
- Parameters
- ----------
- value : Expr
- The value of the expression.
-
- lanes : Expr
- The lanes of the expression.
-
- loc : Location, optional
- The location of this expression in the source code.
- """
-
- value: Expr
- lanes: Expr
-
- def __init__(self, value: Expr, lanes: Expr, loc: Location = UNKNOWN_LOC) -> None:
- self.__init_handle_by_constructor__(_prim_ffi_api.Broadcast, value, lanes, loc) # type: ignore
-
-
-@tvm_ffi.register_object("prim.Shuffle")
-class Shuffle(ExprWithOp):
- """Shuffle node.
-
- Parameters
- ----------
- vectors : List[Expr]
- The vectors
-
- indices : List[Expr]
- The indices
-
- loc : Location, optional
- The location of this expression in the source code.
- """
-
- vectors: list[Expr]
- indices: list[Expr]
-
- def __init__(
- self, vectors: list[Expr], indices: list[Expr], loc: Location = UNKNOWN_LOC
- ) -> None:
- self.__init_handle_by_constructor__(
- _prim_ffi_api.Shuffle,
- vectors,
- indices,
- loc, # type: ignore
- )
-
-
@tvm_ffi.register_object("prim.Let")
class Let(ExprWithOp):
"""Let node.
diff --git a/tirx/python/tvm_tirx/ir/prim/op.py b/tirx/python/tvm_tirx/ir/prim/op.py
index 9ba0bbf08b..80b8f6d675 100644
--- a/tirx/python/tvm_tirx/ir/prim/op.py
+++ b/tirx/python/tvm_tirx/ir/prim/op.py
@@ -30,12 +30,12 @@ def convert(expr) -> Expr:
return _ffi_api.convert(expr)
-def min_value(dtype, loc: Location = UNKNOWN_LOC):
- """minimum value of dtype
+def min_value(*, ty, loc: Location = UNKNOWN_LOC):
+ """minimum value of ty
Parameters
----------
- dtype : str
+ ty : str
The data type.
loc : Location, optional
@@ -44,17 +44,17 @@ def min_value(dtype, loc: Location = UNKNOWN_LOC):
Returns
-------
value : tvm_tirx.ir.Expr
- The minimum value of dtype.
+ The minimum value of ty.
"""
- return _ffi_api.min_value(dtype, loc) # type: ignore
+ return _ffi_api.min_value(ty, loc) # type: ignore
-def max_value(dtype: str, loc: Location = UNKNOWN_LOC) -> Any:
- """maximum value of dtype
+def max_value(*, ty: str, loc: Location = UNKNOWN_LOC) -> Any:
+ """maximum value of ty
Parameters
----------
- dtype : str
+ ty : str
The data type.
loc : Location, optional
@@ -63,9 +63,9 @@ def max_value(dtype: str, loc: Location = UNKNOWN_LOC) -> Any:
Returns
-------
value : tvm_tirx.ir.Expr
- The maximum value of dtype.
+ The maximum value of ty.
"""
- return _ffi_api.max_value(dtype, loc) # type: ignore
+ return _ffi_api.max_value(ty, loc) # type: ignore
def clz(x):
@@ -212,7 +212,7 @@ def bitwise_not(x, loc: Location = UNKNOWN_LOC):
res : Expr
The result.
"""
- return _ffi_api.bitwise_not(x, loc)
+ return _ffi_api.BitwiseNot(x, loc)
def bitwise_or(x, y, loc: Location = UNKNOWN_LOC):
@@ -568,7 +568,7 @@ def max(a, b, loc: Location = UNKNOWN_LOC):
return _ffi_api._OpMax(a, b, loc)
-def _call_prim(ty, op, *args, loc: Location = UNKNOWN_LOC):
+def _call_prim(op, *args, ty, loc: Location = UNKNOWN_LOC):
return Call(op, args, ty=ty, loc=loc)
@@ -593,15 +593,15 @@ def assume(cond=None, *, ty=None, loc: Location = UNKNOWN_LOC):
call : Expr
The call expression.
"""
- return _call_prim(ty, "prim.assume", cond, loc=loc)
+ return _call_prim("prim.assume", cond, loc=loc, ty=ty)
-def infinity(dtype: str, loc: Location = UNKNOWN_LOC) -> Any:
- """infinity value of dtype
+def infinity(*, ty: str, loc: Location = UNKNOWN_LOC) -> Any:
+ """infinity value of ty
Parameters
----------
- dtype : str
+ ty : str
The data type.
loc : Location, optional
@@ -610,9 +610,9 @@ def infinity(dtype: str, loc: Location = UNKNOWN_LOC) -> Any:
Returns
-------
value : tvm.Expr
- The infinity value of dtype.
+ The infinity value of ty.
"""
- return _ffi_api.infinity(dtype, loc) # type: ignore
+ return _ffi_api.infinity(ty, loc) # type: ignore
def exp(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -629,7 +629,7 @@ def exp(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.exp", x, loc=loc)
+ return _call_prim("prim.exp", x, loc=loc, ty=ty)
def exp2(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -646,7 +646,7 @@ def exp2(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.exp2", x, loc=loc)
+ return _call_prim("prim.exp2", x, loc=loc, ty=ty)
def exp10(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -663,7 +663,7 @@ def exp10(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.exp10", x, loc=loc)
+ return _call_prim("prim.exp10", x, loc=loc, ty=ty)
def fma(x, y, z, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -688,7 +688,7 @@ def fma(x, y, z, *, ty=None, loc: Location = UNKNOWN_LOC):
x = convert(x)
y = convert(y)
z = convert(z)
- return _call_prim(ty, "prim.fma", x, y, z, loc=loc)
+ return _call_prim("prim.fma", x, y, z, loc=loc, ty=ty)
def erf(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -705,7 +705,7 @@ def erf(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.erf", x, loc=loc)
+ return _call_prim("prim.erf", x, loc=loc, ty=ty)
def tanh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -722,7 +722,7 @@ def tanh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.tanh", x, loc=loc)
+ return _call_prim("prim.tanh", x, loc=loc, ty=ty)
def sigmoid(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -739,7 +739,7 @@ def sigmoid(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.sigmoid", x, loc=loc)
+ return _call_prim("prim.sigmoid", x, loc=loc, ty=ty)
def log(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -756,7 +756,7 @@ def log(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.log", x, loc=loc)
+ return _call_prim("prim.log", x, loc=loc, ty=ty)
def log10(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -773,7 +773,7 @@ def log10(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.log10", x, loc=loc)
+ return _call_prim("prim.log10", x, loc=loc, ty=ty)
def log1p(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -790,7 +790,7 @@ def log1p(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.log1p", x, loc=loc)
+ return _call_prim("prim.log1p", x, loc=loc, ty=ty)
def tan(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -807,7 +807,7 @@ def tan(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = _require_float_arg("tan", x)
- return _call_prim(ty, "prim.tan", x, loc=loc)
+ return _call_prim("prim.tan", x, loc=loc, ty=ty)
def cos(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -824,7 +824,7 @@ def cos(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = _require_float_arg("cos", x)
- return _call_prim(ty, "prim.cos", x, loc=loc)
+ return _call_prim("prim.cos", x, loc=loc, ty=ty)
def cosh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -841,7 +841,7 @@ def cosh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.cosh", x, loc=loc)
+ return _call_prim("prim.cosh", x, loc=loc, ty=ty)
def acos(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -858,7 +858,7 @@ def acos(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.acos", x, loc=loc)
+ return _call_prim("prim.acos", x, loc=loc, ty=ty)
def acosh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -875,7 +875,7 @@ def acosh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.acosh", x, loc=loc)
+ return _call_prim("prim.acosh", x, loc=loc, ty=ty)
def sin(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -892,7 +892,7 @@ def sin(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = _require_float_arg("sin", x)
- return _call_prim(ty, "prim.sin", x, loc=loc)
+ return _call_prim("prim.sin", x, loc=loc, ty=ty)
def sinh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -909,7 +909,7 @@ def sinh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.sinh", x, loc=loc)
+ return _call_prim("prim.sinh", x, loc=loc, ty=ty)
def asin(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -926,7 +926,7 @@ def asin(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.asin", x, loc=loc)
+ return _call_prim("prim.asin", x, loc=loc, ty=ty)
def asinh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -943,7 +943,7 @@ def asinh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.asinh", x, loc=loc)
+ return _call_prim("prim.asinh", x, loc=loc, ty=ty)
def atan(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -960,7 +960,7 @@ def atan(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.atan", x, loc=loc)
+ return _call_prim("prim.atan", x, loc=loc, ty=ty)
def atanh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -977,7 +977,7 @@ def atanh(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.atanh", x, loc=loc)
+ return _call_prim("prim.atanh", x, loc=loc, ty=ty)
def atan2(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -998,7 +998,7 @@ def atan2(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
"""
x1 = convert(x1)
x2 = convert(x2)
- return _call_prim(ty, "prim.atan2", x1, x2, loc=loc)
+ return _call_prim("prim.atan2", x1, x2, loc=loc, ty=ty)
def sqrt(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -1015,7 +1015,7 @@ def sqrt(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.sqrt", x, loc=loc)
+ return _call_prim("prim.sqrt", x, loc=loc, ty=ty)
def rsqrt(x, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -1032,7 +1032,7 @@ def rsqrt(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.rsqrt", x, loc=loc)
+ return _call_prim("prim.rsqrt", x, loc=loc, ty=ty)
def floor(x: ExprWithOp, loc: Location = UNKNOWN_LOC):
@@ -1158,7 +1158,7 @@ def nextafter(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
"""
x1 = convert(x1)
x2 = convert(x2)
- return _call_prim(ty, "prim.nextafter", x1, x2, loc=loc) # type: ignore
+ return _call_prim("prim.nextafter", x1, x2, loc=loc, ty=ty) # type: ignore
def hypot(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -1179,7 +1179,7 @@ def hypot(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
"""
x1 = convert(x1)
x2 = convert(x2)
- return _call_prim(ty, "prim.hypot", x1, x2, loc=loc) # type: ignore
+ return _call_prim("prim.hypot", x1, x2, loc=loc, ty=ty) # type: ignore
def copysign(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -1200,7 +1200,7 @@ def copysign(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
"""
x1 = convert(x1)
x2 = convert(x2)
- return _call_prim(ty, "prim.copysign", x1, x2, loc=loc) # type: ignore
+ return _call_prim("prim.copysign", x1, x2, loc=loc, ty=ty) # type: ignore
def ldexp(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -1221,7 +1221,7 @@ def ldexp(x1, x2, *, ty=None, loc: Location = UNKNOWN_LOC):
"""
x1 = convert(x1)
x2 = convert(x2)
- return _call_prim(ty, "prim.ldexp", x1, x2, loc=loc) # type: ignore
+ return _call_prim("prim.ldexp", x1, x2, loc=loc, ty=ty) # type: ignore
def isnan(x, loc: Location = UNKNOWN_LOC, *, ty=None):
@@ -1317,7 +1317,7 @@ def popcount(x, *, ty=None, loc: Location = UNKNOWN_LOC):
The result.
"""
x = convert(x)
- return _call_prim(ty, "prim.popcount", x, loc=loc)
+ return _call_prim("prim.popcount", x, loc=loc, ty=ty)
def fmod(x, y, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -1337,7 +1337,7 @@ def fmod(x, y, *, ty=None, loc: Location = UNKNOWN_LOC):
"""
x = convert(x)
y = convert(y)
- return _call_prim(ty, "prim.fmod", x, y, loc=loc)
+ return _call_prim("prim.fmod", x, y, loc=loc, ty=ty)
def pow(x, y, loc: Location = UNKNOWN_LOC):
diff --git a/tirx/python/tvm_tirx/ir/prim/vector_expr.py b/tirx/python/tvm_tirx/ir/prim/vector_expr.py
new file mode 100644
index 0000000000..6712d0e45e
--- /dev/null
+++ b/tirx/python/tvm_tirx/ir/prim/vector_expr.py
@@ -0,0 +1,109 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Vector expression nodes shared by TVM IR dialects."""
+
+import tvm_ffi
+
+from ..expr import Expr, ExprWithOp
+from ..location import UNKNOWN_LOC, Location
+from . import _ffi_api as _prim_ffi_api
+
+
+@tvm_ffi.register_object("prim.Ramp")
+class Ramp(ExprWithOp):
+ """Ramp node.
+
+ Parameters
+ ----------
+ base : Expr
+ The base expression.
+
+ stride : Expr
+ The stride of the ramp.
+
+ lanes : Expr
+ The lanes of the expression.
+
+ loc : Location, optional
+ The location of this expression in the source code.
+ """
+
+ base: Expr
+ stride: Expr
+ lanes: Expr
+
+ def __init__(self, base: Expr, stride: Expr, lanes: Expr, loc: Location = UNKNOWN_LOC) -> None:
+ self.__init_handle_by_constructor__(
+ _prim_ffi_api.Ramp,
+ base,
+ stride,
+ lanes,
+ loc, # type: ignore
+ )
+
+
+@tvm_ffi.register_object("prim.Broadcast")
+class Broadcast(ExprWithOp):
+ """Broadcast node.
+
+ Parameters
+ ----------
+ value : Expr
+ The value of the expression.
+
+ lanes : Expr
+ The lanes of the expression.
+
+ loc : Location, optional
+ The location of this expression in the source code.
+ """
+
+ value: Expr
+ lanes: Expr
+
+ def __init__(self, value: Expr, lanes: Expr, loc: Location = UNKNOWN_LOC) -> None:
+ self.__init_handle_by_constructor__(_prim_ffi_api.Broadcast, value, lanes, loc) # type: ignore
+
+
+@tvm_ffi.register_object("prim.Shuffle")
+class Shuffle(ExprWithOp):
+ """Shuffle node.
+
+ Parameters
+ ----------
+ vectors : List[Expr]
+ The vectors
+
+ indices : List[Expr]
+ The indices
+
+ loc : Location, optional
+ The location of this expression in the source code.
+ """
+
+ vectors: list[Expr]
+ indices: list[Expr]
+
+ def __init__(
+ self, vectors: list[Expr], indices: list[Expr], loc: Location = UNKNOWN_LOC
+ ) -> None:
+ self.__init_handle_by_constructor__(
+ _prim_ffi_api.Shuffle,
+ vectors,
+ indices,
+ loc, # type: ignore
+ )
diff --git a/tirx/python/tvm_tirx/ir/stmt.py b/tirx/python/tvm_tirx/ir/stmt.py
index ca749e9ae8..2197ffd480 100644
--- a/tirx/python/tvm_tirx/ir/stmt.py
+++ b/tirx/python/tvm_tirx/ir/stmt.py
@@ -74,12 +74,12 @@ class AssertStmt(Stmt):
Parameters
----------
- kind : StringImm
- The error kind, e.g. "RuntimeError", "TypeError", "ValueError".
-
condition : Expr
The assert condition.
+ error_kind : StringImm
+ The error kind, e.g. "RuntimeError", "TypeError", "ValueError".
+
message_parts : list[StringImm]
Error message fragments, concatenated at runtime when assertion fails.
@@ -87,15 +87,15 @@ class AssertStmt(Stmt):
The location of the stmt in the source code.
"""
- kind: StringImm
condition: Expr
+ error_kind: StringImm
message_parts: list
loc: Location
def __init__(
self,
- kind: StringImm,
condition: Expr,
+ error_kind: StringImm,
message_parts: list | None = None,
loc: Location = UNKNOWN_LOC,
) -> None:
@@ -103,8 +103,8 @@ class AssertStmt(Stmt):
message_parts = []
self.__init_handle_by_constructor__(
_ffi_api.AssertStmt,
- kind,
condition,
+ error_kind,
message_parts,
loc, # type: ignore
)
diff --git a/tirx/python/tvm_tirx/ir/type.py b/tirx/python/tvm_tirx/ir/type.py
index fcaf4cbf36..2626e92f1e 100644
--- a/tirx/python/tvm_tirx/ir/type.py
+++ b/tirx/python/tvm_tirx/ir/type.py
@@ -49,12 +49,7 @@ class Type(Node, Scriptable):
@staticmethod
def missing():
"""Construct a MissingType for missing type information."""
- return _ffi_api.TypeMissing()
-
- @staticmethod
- def Missing():
- """Construct a MissingType for missing type information."""
- return _ffi_api.TypeMissing()
+ return MissingType()
def __eq__(self, other):
"""Compare two types for structural equivalence."""
diff --git a/tirx/python/tvm_tirx/ir/supply.py b/tirx/python/tvm_tirx/ir/unique_name_supply.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/supply.py
rename to tirx/python/tvm_tirx/ir/unique_name_supply.py
diff --git a/tirx/python/tvm_tirx/runtime/_tensor.py b/tirx/python/tvm_tirx/runtime/_tensor.py
index 0f9aa86842..af3f79b4ad 100644
--- a/tirx/python/tvm_tirx/runtime/_tensor.py
+++ b/tirx/python/tvm_tirx/runtime/_tensor.py
@@ -146,7 +146,7 @@ class Tensor(tvm_ffi.core.Tensor):
assert source_array.flags["C_CONTIGUOUS"]
data = source_array.ctypes.data_as(ctypes.c_void_p)
nbytes = source_array.size * source_array.dtype.itemsize
- _ffi_api.TVMTensorCopyFromBytes(self, data, nbytes)
+ _ffi_api.TensorCopyFromBytes(self, data, nbytes)
return self
def __repr__(self):
@@ -205,7 +205,7 @@ class Tensor(tvm_ffi.core.Tensor):
# TODO(kathy): revisit and get a mirrored function of ffi::GetDataSize
# in Python to replace line below
nbytes = np_arr.size if dtype == "bool" else (np_arr.size * old_dtype.bits + 7) // 8
- _ffi_api.TVMTensorCopyToBytes(self, data, nbytes)
+ _ffi_api.TensorCopyToBytes(self, data, nbytes)
if old_dtype == "int4" or old_dtype.startswith("float4_e2m1fn"):
length = np_arr.size
@@ -240,7 +240,7 @@ class Tensor(tvm_ffi.core.Tensor):
def _copyto(self, target_nd):
"""Internal function that implements copy to target ndarray."""
- _ffi_api.TVMTensorCopyFromTo(self, target_nd)
+ _ffi_api.TensorCopyFromTo(self, target_nd)
return target_nd
def _create_view(self, shape, dtype: str | None = None, relative_byte_offset: int = 0):
@@ -288,7 +288,7 @@ class Tensor(tvm_ffi.core.Tensor):
if dtype is None:
dtype = self.dtype
- return _ffi_api.TVMTensorCreateView(self, shape, dtype, relative_byte_offset)
+ return _ffi_api.TensorCreateView(self, shape, dtype, relative_byte_offset)
def empty(shape, dtype="float32", device=None, mem_scope=None):
@@ -317,7 +317,7 @@ def empty(shape, dtype="float32", device=None, mem_scope=None):
if not isinstance(shape, tvm_ffi.Shape):
shape = tvm_ffi.Shape([int(dim) for dim in shape])
dtype = tvm_ffi.dtype(dtype)
- arr = _ffi_api.TVMTensorAllocWithScope(shape, dtype, device, mem_scope)
+ arr = _ffi_api.TensorAllocWithScope(shape, dtype, device, mem_scope)
return arr
diff --git a/tirx/python/tvm_tirx/runtime/device.py b/tirx/python/tvm_tirx/runtime/device.py
index 35da81c699..44004555ed 100644
--- a/tirx/python/tvm_tirx/runtime/device.py
+++ b/tirx/python/tvm_tirx/runtime/device.py
@@ -283,17 +283,6 @@ class Device(tvm_ffi.core.Device):
"""
return self.get_attr("available_global_memory")
- def texture_spatial_limit(self):
- """Returns limits for textures by spatial dimensions
-
- Returns
- -------
- limit : int or None
- Maximum size of the texture by spatial dimensions
-
- """
- return self.get_attr("driver_version")
-
def create_raw_stream(self):
"""Create a new runtime stream at the context.
@@ -304,7 +293,7 @@ class Device(tvm_ffi.core.Device):
stream : TVMStreamHandle
The created runtime stream.
"""
- return _ffi_api.Device_StreamCreate(self)
+ return _ffi_api.DeviceStreamCreate(self)
def free_raw_stream(self, stream):
"""Free a created stream handle.
@@ -314,7 +303,7 @@ class Device(tvm_ffi.core.Device):
stream : TVMStreamHandle
The stream which should to be released.
"""
- _ffi_api.Device_StreamFree(self, stream)
+ _ffi_api.DeviceStreamFree(self, stream)
def set_raw_stream(self, stream):
"""Set a created stream handle.
@@ -324,7 +313,7 @@ class Device(tvm_ffi.core.Device):
stream : TVMStreamHandle
The stream which should to be set to the device.
"""
- _ffi_api.Device_SetStream(self, stream)
+ _ffi_api.DeviceSetStream(self, stream)
def sync(self, stream=None):
"""Synchronize until jobs finished at the context.
@@ -334,7 +323,7 @@ class Device(tvm_ffi.core.Device):
stream : TVMStreamHandle
Jobs in this stream should be finished.
"""
- _ffi_api.Device_StreamSync(self, stream or 0)
+ _ffi_api.DeviceStreamSync(self, stream or 0)
def __device_type_name__(self):
return Device._DEVICE_TYPE_TO_NAME[self.dlpack_device_type()]
diff --git a/tirx/python/tvm_tirx/script/ir_builder/_ffi_api.py b/tirx/python/tvm_tirx/script/ir_builder/_ffi_api.py
index ff370237f0..962e007725 100644
--- a/tirx/python/tvm_tirx/script/ir_builder/_ffi_api.py
+++ b/tirx/python/tvm_tirx/script/ir_builder/_ffi_api.py
@@ -22,25 +22,3 @@ tvm_ffi.init_ffi_api("script.ir_builder", __name__) # pylint: disable=protected
# Shared module construction retains its native registry namespace.
tvm_ffi.init_ffi_api("script.ir_builder.ir", __name__) # pylint: disable=protected-access
-
-# These core-statement builders retain their historical registry identities.
-# Resolve only the shared functions; importing an entire dialect API here would
-# collide with module construction and couple shared script to dialect loading.
-for _name in (
- "AddToParent",
- "Assert",
- "Bind",
- "Break",
- "Continue",
- "Else",
- "Evaluate",
- "ForFrameSetNames",
- "Grid",
- "If",
- "Region",
- "Return",
- "Then",
- "While",
-):
- globals()[_name] = tvm_ffi.get_global_func("script.ir_builder.tirx." + _name)
-del _name
diff --git a/tirx/python/tvm_tirx/script/ir_builder/frame.py b/tirx/python/tvm_tirx/script/ir_builder/frame.py
index 7069f3a677..f338bf3ae0 100644
--- a/tirx/python/tvm_tirx/script/ir_builder/frame.py
+++ b/tirx/python/tvm_tirx/script/ir_builder/frame.py
@@ -53,7 +53,7 @@ class StmtFrame(IRBuilderFrame):
"""A frame containing a sequence of core IR statements."""
-@_register_object("script.ir_builder.tirx.ForFrame")
+@_register_object("script.ir_builder.ForFrame")
class ForFrame(StmtFrame):
def set_names(self, names: str | Sequence[str] | None) -> None:
"""Configure final variable names before entry, preserving native identities.
@@ -70,27 +70,27 @@ class ForFrame(StmtFrame):
return self.vars[0] if len(self.vars) == 1 else self.vars
-@_register_object("script.ir_builder.tirx.AssertFrame")
+@_register_object("script.ir_builder.AssertFrame")
class AssertFrame(StmtFrame): ...
-@_register_object("script.ir_builder.tirx.WhileFrame")
+@_register_object("script.ir_builder.WhileFrame")
class WhileFrame(StmtFrame): ...
-@_register_object("script.ir_builder.tirx.IfFrame")
+@_register_object("script.ir_builder.IfFrame")
class IfFrame(StmtFrame): ...
-@_register_object("script.ir_builder.tirx.ThenFrame")
+@_register_object("script.ir_builder.ThenFrame")
class ThenFrame(StmtFrame): ...
-@_register_object("script.ir_builder.tirx.ElseFrame")
+@_register_object("script.ir_builder.ElseFrame")
class ElseFrame(StmtFrame): ...
-@_register_object("script.ir_builder.tirx.RegionFrame")
+@_register_object("script.ir_builder.RegionFrame")
class RegionFrame(StmtFrame):
"""A result-free region whose body parameters are lexical bindings."""
diff --git a/tirx/python/tvm_tirx/script/ir_builder/stmt.py b/tirx/python/tvm_tirx/script/ir_builder/stmt.py
index 1b2f1e6160..402956631f 100644
--- a/tirx/python/tvm_tirx/script/ir_builder/stmt.py
+++ b/tirx/python/tvm_tirx/script/ir_builder/stmt.py
@@ -30,9 +30,8 @@ from typing import Any
import tvm_tirx
from tvm_tirx import ir as _ir
-from tvm_tirx.ir import Expr, TensorRegion, Type, Var
+from tvm_tirx.ir import Expr, IntImm, TensorRegion, Type, Var
from tvm_tirx.ir import StringImm as _StringImm
-from tvm_tirx.ir.prim import IntImm
from tvm_tirx.script.ir_builder import base as _base
from tvm_tirx.script.ir_builder.base import AlreadyEmitted
diff --git a/tirx/python/tvm_tirx/script/printer/doc.py b/tirx/python/tvm_tirx/script/printer/doc.py
index 4d9ac5abcd..775dd33311 100644
--- a/tirx/python/tvm_tirx/script/printer/doc.py
+++ b/tirx/python/tvm_tirx/script/printer/doc.py
@@ -23,7 +23,7 @@ from typing import Union
from tvm_ffi import register_object
from tvm_ffi.access_path import AccessPath
-from tvm_tirx.ir.prim import FloatImm, IntImm
+from tvm_tirx.ir import FloatImm, IntImm
from tvm_tirx.runtime import Object
from . import _ffi_api
diff --git a/tirx/python/tvm_tirx/script/tirx.pyi b/tirx/python/tvm_tirx/script/tirx.pyi
index 3acfadbce1..8c0d914349 100644
--- a/tirx/python/tvm_tirx/script/tirx.pyi
+++ b/tirx/python/tvm_tirx/script/tirx.pyi
@@ -17,7 +17,7 @@
"""Generated stub for T.ptx — do not edit.
Regenerate:
- python -m tvm_tirx.backend.cuda.ptx.gen_stubs -o python/tvm/script/tirx.pyi
+ python -m tvm_tirx.backend.cuda.ptx.gen_stubs -o python/tvm_tirx/script/tirx.pyi
"""
from typing import Any
diff --git a/tirx/python/tvm_tirx/sym/analyzer.py b/tirx/python/tvm_tirx/sym/analyzer.py
index 4da7004f1c..2925d4f25d 100644
--- a/tirx/python/tvm_tirx/sym/analyzer.py
+++ b/tirx/python/tvm_tirx/sym/analyzer.py
@@ -507,7 +507,7 @@ def allow_uint_as_index():
provably stay small), NOT for runtime codegen semantics where unsigned
wraparound is real behavior.
"""
- exit_scope = _ffi_api.EnterAllowUintAsIndex()
+ exit_scope = _ffi_api.AnalyzerEnterAllowUintAsIndex()
try:
yield
finally:
diff --git a/tirx/python/tvm_tirx/sym/bound.py b/tirx/python/tvm_tirx/sym/bound.py
index 58f205710e..f000fa7490 100644
--- a/tirx/python/tvm_tirx/sym/bound.py
+++ b/tirx/python/tvm_tirx/sym/bound.py
@@ -34,7 +34,7 @@ def deduce_bound(var, cond, hint_map, relax_map):
Domain of variables used to help deduction.
relax_map : Map[tvm_tirx.ir.Var, IntSet]
- The fomain of the variables to be relaxed
+ The domain of the variables to be relaxed
using the provided domain.
"""
return _ffi_api.DeduceBound(var, cond, hint_map, relax_map)
diff --git a/tirx/python/tvm_tirx/sym/int_set.py b/tirx/python/tvm_tirx/sym/int_set.py
index aaff9e7266..67d28c4c43 100644
--- a/tirx/python/tvm_tirx/sym/int_set.py
+++ b/tirx/python/tvm_tirx/sym/int_set.py
@@ -23,7 +23,7 @@ from tvm_tirx.runtime import Object
from . import _ffi_api
-@tvm_ffi.register_object("ir.IntSet")
+@tvm_ffi.register_object("sym.IntSet")
class IntSet(Object):
"""Represent a set of integer in one dimension."""
@@ -49,7 +49,7 @@ class IntSet(Object):
rset : IntSet
The result set.
"""
- return _ffi_api.intset_vector(vec)
+ return _ffi_api.IntSetVector(vec)
@staticmethod
def single_point(point):
@@ -65,7 +65,7 @@ class IntSet(Object):
rset : IntSet
The result set.
"""
- return _ffi_api.intset_single_point(point)
+ return _ffi_api.IntSetSinglePoint(point)
@tvm_ffi.register_object("sym.IntervalSet")
@@ -179,12 +179,12 @@ def pos_inf():
def neg_inf():
- """Returns the symbolic positive infinity
+ """Returns the symbolic negative infinity
Returns
----------
neg_inf : tvm_tirx.ir.Var
- A symbolic var that indicates positive infinity
+ A symbolic var that indicates negative infinity
"""
return _ffi_api.NegInf()
diff --git a/tirx/python/tvm_tirx/sym/iter_affine_map.py b/tirx/python/tvm_tirx/sym/iter_affine_map.py
index 4d1c50866e..1c8112c570 100644
--- a/tirx/python/tvm_tirx/sym/iter_affine_map.py
+++ b/tirx/python/tvm_tirx/sym/iter_affine_map.py
@@ -128,8 +128,8 @@ def detect_iter_map(
input_iters,
predicate=True,
check_level=IterMapLevel.Surjective,
- simplify_trivial_iterators=True,
analyzer=None,
+ simplify_trivial_iterators=True,
):
"""Detect if indices can be written as mapped iters from input iters
@@ -167,7 +167,7 @@ def detect_iter_map(
elif check_level is None:
check_level = IterMapLevel.NoCheck
return _ffi_api.DetectIterMap(
- indices, input_iters, predicate, check_level, simplify_trivial_iterators, analyzer
+ indices, input_iters, predicate, check_level, analyzer, simplify_trivial_iterators
)
@@ -211,8 +211,8 @@ def iter_map_simplify(
input_iters,
predicate=True,
check_level=IterMapLevel.Surjective,
- simplify_trivial_iterators=True,
analyzer=None,
+ simplify_trivial_iterators=True,
):
"""Simplify the indices using iter map detection.
@@ -240,9 +240,9 @@ def iter_map_simplify(
Returns
-------
- results : IterMapResult
- The iter map matching result.
- The result's .indices is empty array if no match can be found.
+ results : List[Expr]
+ The simplified indices.
+ The input indices are returned unchanged if no match can be found.
"""
if isinstance(check_level, str):
@@ -250,7 +250,7 @@ def iter_map_simplify(
elif check_level is None:
check_level = IterMapLevel.NoCheck
return _ffi_api.IterMapSimplify(
- indices, input_iters, predicate, check_level, simplify_trivial_iterators, analyzer
+ indices, input_iters, predicate, check_level, analyzer, simplify_trivial_iterators
)
@@ -276,8 +276,8 @@ def subspace_divide(
sub_iters,
predicate=True,
check_level=IterMapLevel.Surjective,
- simplify_trivial_iterators=True,
analyzer=None,
+ simplify_trivial_iterators=True,
):
"""Detect if bindings can be written as
``[a_0*e_0 + b_0 + c_0, a_1*e_1 + b_1, ..., a_n*e_n + b_n]``
@@ -343,8 +343,8 @@ def subspace_divide(
sub_iters,
predicate,
check_level,
- simplify_trivial_iterators,
analyzer,
+ simplify_trivial_iterators,
)
diff --git a/tirx/python/tvm_tirx/sym/utils.py b/tirx/python/tvm_tirx/sym/utils.py
index 07f6d2fe9b..4cf1457aa9 100644
--- a/tirx/python/tvm_tirx/sym/utils.py
+++ b/tirx/python/tvm_tirx/sym/utils.py
@@ -18,7 +18,7 @@
from numbers import Integral
-from tvm_tirx.ir.prim import IntImm
+from tvm_tirx.ir import IntImm
from .analyzer import Analyzer
diff --git a/tirx/python/tvm_tirx/target/intrin.py b/tirx/python/tvm_tirx/target/intrin.py
deleted file mode 100644
index d825f5c4c6..0000000000
--- a/tirx/python/tvm_tirx/target/intrin.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-"""Target dependent intrinsic registration."""
-
-from tvm_tirx.tirx import call_pure_extern, register_intrin_lowering
-
-
-def _rule_float_suffix(op):
- """Intrinsic rule: Add float suffix if it is float32.
-
- This is an example intrinsic generation rule.
-
- Parameters
- ----------
- op : Expr
- The call expression of original intrinsic.
-
- Returns
- -------
- ret : Expr
- The translated intrinsic rule.
- Return same op if no translation is possible.
-
- See Also
- --------
- register_intrin_lowering : The registration function for intrinsic lowering rule.
- """
- name = op.op.name
- assert name.startswith(("tirx.", "prim."))
- prefix = name[5:]
-
- if op.ty.dtype == "float32":
- return call_pure_extern(op.ty, f"{prefix}f", *op.args)
- if op.ty.dtype == "float64":
- return call_pure_extern(op.ty, prefix, *op.args)
- return op
-
-
-def _rule_float_direct(op):
- """Intrinsic rule: Directly call pure extern function for floats.
-
- This is an example intrinsic generation rule.
-
- Parameters
- ----------
- op : Expr
- The call expression of original intrinsic.
-
- Returns
- -------
- ret : Expr
- The translated intrinsic rule.
- Return same op if no translation is possible.
-
- See Also
- --------
- register_intrin_lowering : The registration function for intrinsic lowering rule.
- """
- if str(op.ty.dtype).startswith("float"):
- return call_pure_extern(op.ty, op.op.name[5:], *op.args)
- return None
-
-
-# opencl pattern for exp
-register_intrin_lowering("prim.exp", target="opencl", f=_rule_float_direct, override=True)
-# default pattern for exp
-register_intrin_lowering("prim.exp", target="default", f=_rule_float_suffix, override=True)
diff --git a/tirx/python/tvm_tirx/target/target.py b/tirx/python/tvm_tirx/target/target.py
index bf5b385ce1..3724502d90 100644
--- a/tirx/python/tvm_tirx/target/target.py
+++ b/tirx/python/tvm_tirx/target/target.py
@@ -155,7 +155,19 @@ class Target(Object):
return _ffi_api.TargetExport(self)
def with_host(self, host=None):
- return _ffi_api.WithHost(self, Target(host))
+ """Return a copy of this target with the given host.
+
+ Parameters
+ ----------
+ host : Optional[Union[str, Dict, Target]]
+ The new host target. ``None`` removes the host.
+
+ Returns
+ -------
+ target : Target
+ The target with the updated host.
+ """
+ return _ffi_api.WithHost(self, Target(host) if host is not None else None)
@staticmethod
def from_device(device: str | Device) -> "Target":
diff --git a/tirx/python/tvm_tirx/tirx/__init__.py b/tirx/python/tvm_tirx/tirx/__init__.py
index a9d3e1f8c4..c6653bfa1f 100644
--- a/tirx/python/tvm_tirx/tirx/__init__.py
+++ b/tirx/python/tvm_tirx/tirx/__init__.py
@@ -36,12 +36,12 @@ from .tensor import (
)
from .type import TensorMapType
from .expr import convert
-from .expr import Var, FloatImm, IntImm, Cast
+from .expr import Var, Cast
from .expr import Add, Sub, Mul, Div, Mod, FloorDiv, FloorMod
from .expr import LShift, RShift, BitwiseAnd, BitwiseOr, BitwiseXor, BitwiseNot
from .expr import Min, Max, EQ, NE, LT, LE, GT, GE, And, Or, Not
-from .expr import Select, TensorLoad, Ramp, Broadcast, Shuffle
-from .expr import CallEffectKind, Let
+from .expr import Select, TensorLoad
+from .expr import Let
from .function import Function, IndexMap, renew_def
diff --git a/tirx/python/tvm_tirx/tirx/_tensor_view.py b/tirx/python/tvm_tirx/tirx/_tensor_view.py
index fdfa9f9015..a8d100d172 100644
--- a/tirx/python/tvm_tirx/tirx/_tensor_view.py
+++ b/tirx/python/tvm_tirx/tirx/_tensor_view.py
@@ -316,7 +316,7 @@ def _concrete_int(value):
return None
if isinstance(value, Integral):
return int(value)
- if isinstance(value, tvm_tirx.tirx.IntImm):
+ if isinstance(value, tvm_tirx.ir.IntImm):
return int(value)
return None
@@ -356,7 +356,7 @@ def _dim_group_offset(group, index):
extents = []
for iterator in group[1:]:
extent = iterator.extent
- if not isinstance(extent, tvm_tirx.tirx.IntImm):
+ if not isinstance(extent, tvm_tirx.ir.IntImm):
raise ValueError(
"select/narrow: dim with multiple layout iters requires concrete iter extents"
)
@@ -538,7 +538,7 @@ def _view_narrow(buf: Var, dim, start, length):
inner = 1
for iterator in group[1:]:
extent = iterator.extent
- if not isinstance(extent, tvm_tirx.tirx.IntImm):
+ if not isinstance(extent, tvm_tirx.ir.IntImm):
raise ValueError(
"sub: dim with multiple layout iters requires concrete iter extents"
)
@@ -591,7 +591,7 @@ class SubIndexer:
if item.stop is not None:
raise ValueError("sub: a stop bound with a step is not supported")
extent = buf.shape[dim]
- if not isinstance(extent, tvm_tirx.tirx.IntImm):
+ if not isinstance(extent, tvm_tirx.ir.IntImm):
raise ValueError("sub: a stepped slice requires a concrete dim extent")
extent = int(extent)
if extent % step != 0:
diff --git a/tirx/python/tvm_tirx/tirx/analysis/analysis.py b/tirx/python/tvm_tirx/tirx/analysis/analysis.py
index 4e7ba50888..4a0879724c 100644
--- a/tirx/python/tvm_tirx/tirx/analysis/analysis.py
+++ b/tirx/python/tvm_tirx/tirx/analysis/analysis.py
@@ -38,7 +38,7 @@ def verify_memory(func: Function) -> bool:
result : bool
The result of verification.
"""
- return _ffi_api.verify_memory(func) # type: ignore
+ return _ffi_api.VerifyMemory(func) # type: ignore
def undefined_vars(node: Stmt | Expr, defs: list[Var] | None = None) -> list[Var]:
diff --git a/tirx/python/tvm_tirx/tirx/expr.py b/tirx/python/tvm_tirx/tirx/expr.py
index bf819b8c34..c3329aa36e 100644
--- a/tirx/python/tvm_tirx/tirx/expr.py
+++ b/tirx/python/tvm_tirx/tirx/expr.py
@@ -55,14 +55,11 @@ from tvm_tirx.ir.prim.expr import ( # noqa: F401
BitwiseNot,
BitwiseOr,
BitwiseXor,
- Broadcast,
Cast,
CmpExpr,
Div,
- FloatImm,
FloorDiv,
FloorMod,
- IntImm,
Let,
LogicalExpr,
LShift,
@@ -72,36 +69,11 @@ from tvm_tirx.ir.prim.expr import ( # noqa: F401
Mul,
Not,
Or,
- Ramp,
RShift,
Select,
- Shuffle,
Sub,
)
-
-class IntImmEnum:
- """Lazily evaluate an IntImm in case
- the constructor is not available in runtime.
-
- Parameters
- ----------
- value : int
- The enum value
-
- loc : Location, optional
- The location of the cast in the source.
- """
-
- def __init__(self, value: int, loc: Location = UNKNOWN_LOC) -> None:
- self.value = value
- self.loc = loc
-
- def __tvm_ffi_object__(self) -> "IntImm":
- """Convert object."""
- return IntImm("int32", self.value, self.loc) # type: ignore
-
-
Var = ir.Var
@@ -122,14 +94,3 @@ def TensorLoad(tensor: Var, indices: list[Expr], loc: Location = UNKNOWN_LOC) ->
"""
return ir.TensorLoad(tensor, indices, loc)
-
-
-class CallEffectKind:
- """Possible kinds of Call effects."""
-
- # only expose up to opaque
- ExprAnnotation = IntImmEnum(0)
- Pure = IntImmEnum(1)
- ReadState = IntImmEnum(2)
- UpdateState = IntImmEnum(3)
- Opaque = UpdateState
diff --git a/tirx/python/tvm_tirx/tirx/layout.py b/tirx/python/tvm_tirx/tirx/layout.py
index 9de8cebed6..3a20a07e6f 100644
--- a/tirx/python/tvm_tirx/tirx/layout.py
+++ b/tirx/python/tvm_tirx/tirx/layout.py
@@ -33,9 +33,6 @@ from .thread_scope import ThreadScope
@tvm_ffi.register_object("tirx.Layout")
class Layout(Object):
- def __init__(self):
- self.__init_handle_by_constructor__(_ffi_api.Layout) # pylint: disable=no-member
-
def verify_well_formed(self) -> bool:
"""Verify if the layout is well-formed.
@@ -144,7 +141,7 @@ class Layout(Object):
# Python ``int`` -> int32 IntImm and breaks structural-equal).
for t in data:
if tvm_tirx.ir.is_prim_expr(t) and t.ty.dtype != "int32":
- from .expr import IntImm # pylint: disable=import-outside-toplevel
+ from tvm_tirx.ir import IntImm # pylint: disable=import-outside-toplevel
stride = IntImm(t.ty, stride)
break
diff --git a/tirx/python/tvm_tirx/tirx/op/__init__.py b/tirx/python/tvm_tirx/tirx/op/__init__.py
index a12e85206c..a167f8cb62 100644
--- a/tirx/python/tvm_tirx/tirx/op/__init__.py
+++ b/tirx/python/tvm_tirx/tirx/op/__init__.py
@@ -32,6 +32,7 @@ from tvm_tirx.ir import (
Call,
Expr,
ExprWithOp,
+ IntImm,
PrimType,
PtrType,
TensorLoad,
@@ -110,24 +111,13 @@ from tvm_tirx.ir.prim.op import truncmod as truncmod
from tvm_tirx.ir.prim.op import vscale as vscale
from .. import _ffi_api
-from ..expr import ExprOp, IntImm
+from ..expr import ExprOp
from ..expr import TensorLoad as _make_tensor_load
from ..tensor import is_tensor_var, tensor_data_ptr
from ..type import TensorMapType
tir = tirx # alias for backward compat with upstream tir.convert() calls
-# Insertion order matters: a longer prefix has to be tried before the shorter
-# one it starts with, or `ptx_legacy_mma` would strip as `ptx` + `legacy_mma`.
-_DEVICE_INTRIN_PREFIX_TO_NAMESPACE = {
- "cuda_": "cuda",
- "ptx_legacy_": "ptx_legacy",
- "ptx_": "ptx",
- "s_tir_": "s_tir",
- "nvshmem_": "nvshmem",
- "nki_": "nki",
-}
-
def register_intrin_lowering(
op_name,
@@ -167,20 +157,6 @@ def register_intrin_lowering(
return _register(f) if f is not None else _register
-def _canonical_device_intrin_name(func_name: str) -> str:
- """Return the canonical registry name for statically registered device intrinsics."""
-
- if not isinstance(func_name, str) or not func_name.startswith("tirx."):
- return func_name
- basename = func_name[len("tirx.") :]
- if "." in basename:
- return func_name
- for prefix, namespace in _DEVICE_INTRIN_PREFIX_TO_NAMESPACE.items():
- if basename.startswith(prefix):
- return f"tirx.{namespace}.{basename[len(prefix) :]}"
- return func_name
-
-
def _reject_tensor_region(value, api_name):
"""Reject region metadata where a call argument must denote a runtime value."""
if isinstance(value, TensorRegion):
@@ -214,10 +190,7 @@ def _primexpr_dtype(expr):
def _pack_tensor(buf, loc: Location = UNKNOWN_LOC):
"""Build intrinsics that packs the tensor."""
shape = Call(
- "tirx.stack_make_shape",
- buf.ty.shape,
- loc=loc,
- ty=PtrType(tvm_tirx.ir.PrimType("int64")),
+ "tirx.stack_make_shape", buf.ty.shape, loc=loc, ty=PtrType(tvm_tirx.ir.PrimType("int64"))
)
strides = (
Call(
@@ -423,7 +396,7 @@ def call_cpacked(*args, loc: Location = UNKNOWN_LOC, ty=None):
def call_intrin(
- dtype: str | tvm_tirx.ir.Type, func_name, *args, attrs=None, loc: Location = UNKNOWN_LOC
+ func_name, *args, ty: str | tvm_tirx.ir.Type, attrs=None, loc: Location = UNKNOWN_LOC
):
"""Build expression by calling an intrinsic function.
@@ -432,7 +405,7 @@ def call_intrin(
Parameters
----------
- dtype : str or tvm_tirx.ir.Type
+ ty : str or tvm_tirx.ir.Type
The data type of the result.
func_name: str
@@ -452,18 +425,16 @@ def call_intrin(
call : Expr
The call expression.
"""
- if isinstance(func_name, str):
- func_name = _canonical_device_intrin_name(func_name)
args = tuple(_reject_tensor_region(arg, "call_intrin") for arg in args)
- return Call(func_name, args, attrs=attrs, loc=loc, ty=dtype)
+ return Call(func_name, args, attrs=attrs, loc=loc, ty=ty)
-def call_pure_extern(dtype, func_name, *args, loc: Location = UNKNOWN_LOC):
+def call_pure_extern(func_name, *args, ty, loc: Location = UNKNOWN_LOC):
"""Build expression by calling a pure extern function.
Parameters
----------
- dtype : str
+ ty : str
The data type of the result.
func_name: str
@@ -484,16 +455,16 @@ def call_pure_extern(dtype, func_name, *args, loc: Location = UNKNOWN_LOC):
"tirx.call_pure_extern",
[func_name, *(_reject_tensor_region(arg, "call_pure_extern") for arg in args)],
loc=loc,
- ty=dtype,
+ ty=ty,
)
-def call_extern(dtype, func_name, *args, loc: Location = UNKNOWN_LOC):
+def call_extern(func_name, *args, ty, loc: Location = UNKNOWN_LOC):
"""Build expression by calling a extern function.
Parameters
----------
- dtype : str
+ ty : str
The data type of the result.
func_name: str
@@ -514,16 +485,16 @@ def call_extern(dtype, func_name, *args, loc: Location = UNKNOWN_LOC):
"tirx.call_extern",
[func_name, *(_reject_tensor_region(arg, "call_extern") for arg in args)],
loc=loc,
- ty=dtype,
+ ty=ty,
)
-def call_llvm_intrin(dtype, name, *args, loc: Location = UNKNOWN_LOC):
+def call_llvm_intrin(name, *args, ty, loc: Location = UNKNOWN_LOC):
"""Build expression by calling a llvm intrinsic function
Parameters
----------
- dtype : str
+ ty : str
The data type of the result.
name : str
@@ -552,22 +523,22 @@ def call_llvm_intrin(dtype, name, *args, loc: Location = UNKNOWN_LOC):
if llvm_id == 0:
raise ValueError(f"Unknown llvm intrinsic function {name}")
return call_intrin(
- dtype,
"tirx.call_llvm_intrin",
name
if isinstance(name, IntImm)
else tvm_tirx.tirx.const(llvm_id, "int32" if isinstance(name, str) else "uint32"),
*args,
loc=loc,
+ ty=ty,
)
-def call_llvm_pure_intrin(dtype, name, *args, loc: Location = UNKNOWN_LOC):
+def call_llvm_pure_intrin(name, *args, ty, loc: Location = UNKNOWN_LOC):
"""Build expression by calling a pure llvm intrinsic function
Parameters
----------
- dtype : str
+ ty : str
The data type of the result.
name : str
@@ -596,13 +567,13 @@ def call_llvm_pure_intrin(dtype, name, *args, loc: Location = UNKNOWN_LOC):
if llvm_id == 0:
raise ValueError(f"Unknown llvm intrinsic function {name}")
return call_intrin(
- dtype,
"tirx.call_llvm_pure_intrin",
name
if isinstance(name, IntImm)
else tvm_tirx.tirx.const(llvm_id, "int32" if isinstance(name, str) else "uint32"),
*args,
loc=loc,
+ ty=ty,
)
@@ -622,7 +593,7 @@ def stack_alloca(dtype_str, num, *, ty=None, loc: Location = UNKNOWN_LOC):
call : Expr
The call expression.
"""
- return call_intrin(ty, "tirx.stack_alloca", dtype_str, num, loc=loc)
+ return call_intrin("tirx.stack_alloca", dtype_str, num, loc=loc, ty=ty)
def stack_make_shape(*args, ty=None, loc: Location = UNKNOWN_LOC):
@@ -638,7 +609,7 @@ def stack_make_shape(*args, ty=None, loc: Location = UNKNOWN_LOC):
call : Expr
The call expression.
"""
- return call_intrin(ty, "tirx.stack_make_shape", *args, loc=loc)
+ return call_intrin("tirx.stack_make_shape", *args, loc=loc, ty=ty)
def stack_make_dltensor(
@@ -683,7 +654,6 @@ def stack_make_dltensor(
arr_dtype = const(0, dtype=arr_dtype)
return call_intrin(
- ty,
"tirx.stack_make_dltensor",
data,
shape,
@@ -692,6 +662,7 @@ def stack_make_dltensor(
arr_dtype,
elem_offset,
loc=loc,
+ ty=ty,
)
@@ -702,7 +673,7 @@ def assume_aligned(tensor, alignment_bytes, *, ty=None, loc: Location = UNKNOWN_
be a tensor variable and alignment a scalar integer constant, a power of
two between 1 and 2**27 bytes (inclusive).
"""
- return call_intrin(ty, "tirx.assume_aligned", tensor, alignment_bytes, loc=loc)
+ return call_intrin("tirx.assume_aligned", tensor, alignment_bytes, loc=loc, ty=ty)
def undef(*, ty=None, loc: Location = UNKNOWN_LOC):
@@ -713,7 +684,7 @@ def undef(*, ty=None, loc: Location = UNKNOWN_LOC):
call : Expr
The call expression.
"""
- return call_intrin(ty, "tirx.undef", loc=loc)
+ return call_intrin("tirx.undef", loc=loc, ty=ty)
def handle_add_byte_offset(handle, offset, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -732,15 +703,15 @@ def handle_add_byte_offset(handle, offset, *, ty=None, loc: Location = UNKNOWN_L
call : Expr
The call expression.
"""
- return call_intrin(ty, "tirx.handle_add_byte_offset", handle, offset, loc=loc)
+ return call_intrin("tirx.handle_add_byte_offset", handle, offset, loc=loc, ty=ty)
-def abi_field_get(arr, index, field, dtype):
+def abi_field_get(arr, index, field, *, ty, loc: Location = UNKNOWN_LOC):
"""Get struct field value in array
Parameters
----------
- dtype : str
+ ty : str
The date type of the result.
arr : StructType*
@@ -757,7 +728,7 @@ def abi_field_get(arr, index, field, dtype):
call : Expr
The call expression.
"""
- return call_intrin(dtype, "tirx.abi_field_get", arr, index, field)
+ return call_intrin("tirx.abi_field_get", arr, index, field, loc=loc, ty=ty)
def abi_field_set(arr, index, field, value, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -782,7 +753,7 @@ def abi_field_set(arr, index, field, value, *, ty=None, loc: Location = UNKNOWN_
call : Expr
The call expression.
"""
- return call_intrin(ty, "tirx.abi_field_set", arr, index, field, value, loc=loc)
+ return call_intrin("tirx.abi_field_set", arr, index, field, value, loc=loc, ty=ty)
def _is_tensormap_var(obj: Var) -> bool:
@@ -811,7 +782,7 @@ def address_of(obj: Var | TensorLoad, loc: Location = UNKNOWN_LOC, *, ty=None) -
return Call("tirx.address_of", [tensor_load], ty=ty, loc=loc)
elif isinstance(obj, Var):
if _is_tensormap_var(obj):
- return call_intrin(ty, "tirx.address_of", obj, loc=loc)
+ return call_intrin("tirx.address_of", obj, loc=loc, ty=ty)
if not isinstance(obj.ty, tvm_tirx.ir.PrimType):
raise TypeError(f"address_of expects a scalar or TensorMap Var, but got {obj.ty}")
return Call("tirx.address_of", [obj], ty=ty, loc=loc)
@@ -862,7 +833,6 @@ def gpu_thread_allreduce(
return tvm_tirx.ir.Tuple(value) if isinstance(value, list | tuple | Array) else value
return call_intrin(
- ty,
"tirx.gpu_thread_allreduce",
combine,
as_operand(identity),
@@ -871,6 +841,7 @@ def gpu_thread_allreduce(
as_operand(destinations),
as_operand(thread_axes),
loc=loc,
+ ty=ty,
)
@@ -888,7 +859,7 @@ def gpu_thread_invariant(cond, *, ty=None, loc: Location = UNKNOWN_LOC):
The call expression.
"""
assert tvm_tirx.ir.is_prim_expr(cond)
- return call_intrin(ty, "tirx.gpu_thread_invariant", cond, loc=loc)
+ return call_intrin("tirx.gpu_thread_invariant", cond, loc=loc, ty=ty)
def gpu_storage_sync(storage_scope, *, ty=None, loc: Location = UNKNOWN_LOC):
@@ -903,7 +874,7 @@ def gpu_storage_sync(storage_scope, *, ty=None, loc: Location = UNKNOWN_LOC):
loc : tvm_tirx.ir.Location, optional
The source location.
"""
- return call_intrin(ty, "tirx.gpu_storage_sync", storage_scope, loc=loc)
+ return call_intrin("tirx.gpu_storage_sync", storage_scope, loc=loc, ty=ty)
def cpu_parallel_barrier(*, ty=None, loc: Location = UNKNOWN_LOC):
@@ -917,12 +888,12 @@ def cpu_parallel_barrier(*, ty=None, loc: Location = UNKNOWN_LOC):
To replace ``pragma_parallel_barrier_when_finish``, place this operation
after the former attribute body.
"""
- return call_intrin(ty, "tirx.cpu_parallel_barrier", loc=loc)
+ return call_intrin("tirx.cpu_parallel_barrier", loc=loc, ty=ty)
def kernel_replace_point(*, ty=None, loc: Location = UNKNOWN_LOC):
"""Mark where a transform should replace generated kernel initialization."""
- return call_intrin(ty, "tirx.kernel_replace_point", loc=loc)
+ return call_intrin("tirx.kernel_replace_point", loc=loc, ty=ty)
def gpu_warp_shuffle(
@@ -949,14 +920,7 @@ def gpu_warp_shuffle(
The call expression.
"""
return call_intrin(
- ty,
- "tirx.gpu_warp_shuffle",
- mask,
- value,
- warp_id,
- width,
- warp_size,
- loc=loc,
+ "tirx.gpu_warp_shuffle", mask, value, warp_id, width, warp_size, loc=loc, ty=ty
)
@@ -985,14 +949,7 @@ def gpu_warp_shuffle_up(
The call expression.
"""
return call_intrin(
- ty,
- "tirx.gpu_warp_shuffle_up",
- mask,
- value,
- offset,
- width,
- warp_size,
- loc=loc,
+ "tirx.gpu_warp_shuffle_up", mask, value, offset, width, warp_size, loc=loc, ty=ty
)
@@ -1021,14 +978,7 @@ def gpu_warp_shuffle_down(
The call expression.
"""
return call_intrin(
- ty,
- "tirx.gpu_warp_shuffle_down",
- mask,
- value,
- offset,
- width,
- warp_size,
- loc=loc,
+ "tirx.gpu_warp_shuffle_down", mask, value, offset, width, warp_size, loc=loc, ty=ty
)
@@ -1056,14 +1006,7 @@ def gpu_warp_shuffle_xor(
The call expression.
"""
return call_intrin(
- ty,
- "tirx.gpu_warp_shuffle_xor",
- mask,
- value,
- lane_mask,
- width,
- warp_size,
- loc=loc,
+ "tirx.gpu_warp_shuffle_xor", mask, value, lane_mask, width, warp_size, loc=loc, ty=ty
)
@@ -1075,7 +1018,7 @@ def gpu_warp_activemask(*, ty=None, loc: Location = UNKNOWN_LOC):
call : Expr
The call expression.
"""
- return call_intrin(ty, "tirx.gpu_warp_activemask", loc=loc)
+ return call_intrin("tirx.gpu_warp_activemask", loc=loc, ty=ty)
def ptr_byte_offset(data, byte_offset, *, ty, loc: Location = UNKNOWN_LOC):
@@ -1084,7 +1027,7 @@ def ptr_byte_offset(data, byte_offset, *, ty, loc: Location = UNKNOWN_LOC):
``byte_offset`` is always in bytes. ``ty`` specifies both the result
element type and storage scope.
"""
- return call_intrin(ty, "tirx.ptr_byte_offset", data, byte_offset, loc=loc)
+ return call_intrin("tirx.ptr_byte_offset", data, byte_offset, loc=loc, ty=ty)
def throw_last_error(*, ty=None, loc: Location = UNKNOWN_LOC):
@@ -1095,15 +1038,15 @@ def throw_last_error(*, ty=None, loc: Location = UNKNOWN_LOC):
ret : Expr
The return expression
"""
- return call_intrin(ty, "tirx.throw_last_error", loc=loc)
+ return call_intrin("tirx.throw_last_error", loc=loc, ty=ty)
-def vector_low(dtype, vec):
+def vector_low(vec, *, ty, loc: Location = UNKNOWN_LOC):
"""Get the low level half of the vector
Parameters
----------
- dtype : str
+ ty : str
The data type of the result.
vec : list
@@ -1114,15 +1057,15 @@ def vector_low(dtype, vec):
call : Expr
The call expression.
"""
- return call_intrin(dtype, "tirx.vector_low", vec)
+ return call_intrin("tirx.vector_low", vec, loc=loc, ty=ty)
-def vector_high(dtype, vec):
+def vector_high(vec, *, ty, loc: Location = UNKNOWN_LOC):
"""Get the high level half of the vector
Parameters
----------
- dtype : str
+ ty : str
The data type of the result.
vec : list
@@ -1133,10 +1076,10 @@ def vector_high(dtype, vec):
call : Expr
The call expression.
"""
- return call_intrin(dtype, "tirx.vector_high", vec)
+ return call_intrin("tirx.vector_high", vec, loc=loc, ty=ty)
-def vector_combine(dtype, vec1, vec2):
+def vector_combine(vec1, vec2, *, ty, loc: Location = UNKNOWN_LOC):
"""Concat two vectors
Parameters
@@ -1152,7 +1095,7 @@ def vector_combine(dtype, vec1, vec2):
call : Expr
The call expression.
"""
- return call_intrin(dtype, "tirx.vector_combine", vec1, vec2)
+ return call_intrin("tirx.vector_combine", vec1, vec2, loc=loc, ty=ty)
def gpu_dp4a(vec1, vec2, acc=0, **kwargs):
@@ -1177,12 +1120,12 @@ def gpu_dp4a(vec1, vec2, acc=0, **kwargs):
return Call("tirx.gpu_dp4a", [vec1, vec2, acc], **kwargs)
-def reinterpret(dtype, value, loc: Location = UNKNOWN_LOC) -> Expr:
+def reinterpret(value, *, ty, loc: Location = UNKNOWN_LOC) -> Expr:
"""Reinterpret a value as an exact primitive or pointer type.
Parameters
----------
- dtype : str or tvm_tirx.ir.Type
+ ty : str or tvm_tirx.ir.Type
The data type.
value : Expr
@@ -1194,15 +1137,11 @@ def reinterpret(dtype, value, loc: Location = UNKNOWN_LOC) -> Expr:
Returns
-------
value : tvm.Expr
- The reinterpret cast value of dtype.
+ The reinterpret cast value of ty.
"""
- if isinstance(dtype, str):
- dtype = (
- PtrType(tvm_tirx.ir.PrimType("void"))
- if dtype == "handle"
- else tvm_tirx.ir.PrimType(dtype)
- )
- return _ffi_api.reinterpret(dtype, value, loc) # type: ignore
+ if isinstance(ty, str):
+ ty = PtrType(tvm_tirx.ir.PrimType("void")) if ty == "handle" else tvm_tirx.ir.PrimType(ty)
+ return _ffi_api.reinterpret(ty, value, loc) # type: ignore
def gpu_thread_filter(var, pred, *, loc: Location = UNKNOWN_LOC, ty=None):
@@ -1221,7 +1160,7 @@ def gpu_thread_filter(var, pred, *, loc: Location = UNKNOWN_LOC, ty=None):
evaluated at runtime.
"""
- return call_intrin(ty, "tirx.gpu_thread_filter", var, pred, loc=loc)
+ return call_intrin("tirx.gpu_thread_filter", var, pred, loc=loc, ty=ty)
def gpu_active_thread_selector(var, pred, loc: Location = UNKNOWN_LOC, *, ty=None):
@@ -1231,7 +1170,7 @@ def gpu_active_thread_selector(var, pred, loc: Location = UNKNOWN_LOC, *, ty=Non
active domain for which ``pred`` is true. It is intended for compiler
metadata and should not survive to executable codegen.
"""
- return call_intrin(ty, "tirx.gpu_active_thread_selector", var, pred, loc=loc)
+ return call_intrin("tirx.gpu_active_thread_selector", var, pred, loc=loc, ty=ty)
def isnullptr(x, loc: Location = UNKNOWN_LOC, *, ty=None):
@@ -1250,7 +1189,7 @@ def isnullptr(x, loc: Location = UNKNOWN_LOC, *, ty=None):
y : Expr
The result.
"""
- return call_intrin(ty, "tirx.isnullptr", x, loc=loc) # type: ignore
+ return call_intrin("tirx.isnullptr", x, loc=loc, ty=ty) # type: ignore
def logaddexp(a, b, loc: Location = UNKNOWN_LOC):
@@ -1310,7 +1249,6 @@ def alloc_workspace(
The call expression.
"""
return call_intrin(
- ty,
"tirx.alloc_workspace",
device_type,
device_id,
@@ -1318,6 +1256,7 @@ def alloc_workspace(
dtype_code_hint,
dtype_bits_hint,
loc=loc,
+ ty=ty,
)
@@ -1340,17 +1279,10 @@ def free_workspace(device_type, device_id, ptr, *, ty=None, loc: Location = UNKN
call : Expr
The call expression.
"""
- return call_intrin(
- ty,
- "tirx.free_workspace",
- device_type,
- device_id,
- ptr,
- loc=loc,
- )
+ return call_intrin("tirx.free_workspace", device_type, device_id, ptr, loc=loc, ty=ty)
-def get_active_lane_mask(dtype, base, limit):
+def get_active_lane_mask(base, limit, *, ty, loc: Location = UNKNOWN_LOC):
"""
Calculate a predicate mask given an upper bound (limit) and a current value (base).
@@ -1359,7 +1291,7 @@ def get_active_lane_mask(dtype, base, limit):
Parameters
----------
- dtype : str
+ ty : str
The data type of the result.
base : Expr
@@ -1368,33 +1300,36 @@ def get_active_lane_mask(dtype, base, limit):
limit : Expr
An expression representing the limit.
"""
- return call_intrin(dtype, "tirx.get_active_lane_mask", base, limit)
+ return call_intrin("tirx.get_active_lane_mask", base, limit, loc=loc, ty=ty)
-def masked_load(dtype, tensor, *indices_and_mask):
+def masked_load(tensor, index, *args, ty=None, loc: Location = UNKNOWN_LOC):
"""Load vector lanes selected by a predicate mask.
Parameters
----------
- dtype : str
+ ty : str
The vector data type to load.
tensor : Var
The tensor to load.
- indices_and_mask : Expr
+ index : Expr
+ The first tensor index.
+
+ args : Expr
The tensor indices followed by a boolean lane mask. The mask must match the
lane count and scalability of the loaded vector.
Returns
-------
call : Expr
- A ``tirx.masked_load`` call with result type ``dtype``.
+ A ``tirx.masked_load`` call with result type ``ty``.
"""
- return call_intrin(dtype, "tirx.masked_load", tensor, *indices_and_mask)
+ return call_intrin("tirx.masked_load", tensor, index, *args, loc=loc, ty=ty)
-def masked_store(tensor, value, *indices_and_mask, ty=None, loc: Location = UNKNOWN_LOC):
+def masked_store(tensor, value, index, *args, ty=None, loc: Location = UNKNOWN_LOC):
"""Store vector lanes selected by a predicate mask.
Parameters
@@ -1405,7 +1340,10 @@ def masked_store(tensor, value, *indices_and_mask, ty=None, loc: Location = UNKN
value : Expr
The vector value to store.
- indices_and_mask : Expr
+ index : Expr
+ The first tensor index.
+
+ args : Expr
The tensor indices followed by a boolean lane mask. The mask must match the
lane count and scalability of ``value``.
@@ -1414,14 +1352,7 @@ def masked_store(tensor, value, *indices_and_mask, ty=None, loc: Location = UNKN
call : Expr
A void-typed ``tirx.masked_store`` call.
"""
- return call_intrin(
- ty,
- "tirx.masked_store",
- tensor,
- value,
- *indices_and_mask,
- loc=loc,
- )
+ return call_intrin("tirx.masked_store", tensor, value, index, *args, loc=loc, ty=ty)
def get_vscale_expr(dtype: str | tvm_ffi.dtype, min_size: int = 128) -> Expr:
@@ -1449,7 +1380,7 @@ def ignore_loop_partition(predicate, *, ty=None, loc: Location = UNKNOWN_LOC) ->
predicate : Expr
The annotated predicate expression.
"""
- return call_intrin(ty, "tirx.ignore_loop_partition", predicate, loc=loc)
+ return call_intrin("tirx.ignore_loop_partition", predicate, loc=loc, ty=ty)
def gpu_load_matrix_sync(
@@ -1499,7 +1430,6 @@ def gpu_load_matrix_sync(
The call expression.
"""
return call_intrin(
- ty,
"tirx.gpu_load_matrix_sync",
fragment,
m,
@@ -1510,6 +1440,7 @@ def gpu_load_matrix_sync(
stride,
layout,
loc=loc,
+ ty=ty,
)
@@ -1560,7 +1491,6 @@ def gpu_mma_sync(
The call expression.
"""
return call_intrin(
- ty,
"tirx.gpu_mma_sync",
fragment_d,
index_d,
@@ -1571,6 +1501,7 @@ def gpu_mma_sync(
fragment_c,
index_c,
loc=loc,
+ ty=ty,
)
@@ -1602,17 +1533,7 @@ def gpu_fill_fragment(fragment, m, n, k, index, value, *, ty=None, loc: Location
call : Expr
The call expression.
"""
- return call_intrin(
- ty,
- "tirx.gpu_fill_fragment",
- fragment,
- m,
- n,
- k,
- index,
- value,
- loc=loc,
- )
+ return call_intrin("tirx.gpu_fill_fragment", fragment, m, n, k, index, value, loc=loc, ty=ty)
def gpu_store_matrix_sync(
@@ -1662,7 +1583,6 @@ def gpu_store_matrix_sync(
The call expression.
"""
return call_intrin(
- ty,
"tirx.gpu_store_matrix_sync",
fragment,
m,
@@ -1673,9 +1593,10 @@ def gpu_store_matrix_sync(
stride,
layout,
loc=loc,
+ ty=ty,
)
def gpu_thread_return(*, ty=None, loc: Location = UNKNOWN_LOC):
"""Return from the current GPU thread without a function value."""
- return call_intrin(ty, "tirx.gpu_thread_return", loc=loc)
+ return call_intrin("tirx.gpu_thread_return", loc=loc, ty=ty)
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/frame.py b/tirx/python/tvm_tirx/tirx/script/ir_builder/frame.py
index d9703b3502..dd2816cbe2 100644
--- a/tirx/python/tvm_tirx/tirx/script/ir_builder/frame.py
+++ b/tirx/python/tvm_tirx/tirx/script/ir_builder/frame.py
@@ -18,14 +18,7 @@
from tvm_ffi import register_object as _register_object
-from tvm_tirx.script.ir_builder.frame import AssertFrame as AssertFrame
-from tvm_tirx.script.ir_builder.frame import ElseFrame as ElseFrame
-from tvm_tirx.script.ir_builder.frame import ForFrame as ForFrame
-from tvm_tirx.script.ir_builder.frame import IfFrame as IfFrame
-from tvm_tirx.script.ir_builder.frame import RegionFrame as RegionFrame
from tvm_tirx.script.ir_builder.frame import StmtFrame
-from tvm_tirx.script.ir_builder.frame import ThenFrame as ThenFrame
-from tvm_tirx.script.ir_builder.frame import WhileFrame as WhileFrame
@_register_object("script.ir_builder.tirx.FunctionFrame")
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/ir.py b/tirx/python/tvm_tirx/tirx/script/ir_builder/ir.py
index f9f1a663e6..6bdee59694 100644
--- a/tirx/python/tvm_tirx/tirx/script/ir_builder/ir.py
+++ b/tirx/python/tvm_tirx/tirx/script/ir_builder/ir.py
@@ -23,10 +23,13 @@ import threading
from collections.abc import Callable
from typing import TYPE_CHECKING, Any, TypeVar
+import tvm_tirx
from tvm_tirx import DataType, ir
from tvm_tirx import ir as _ir
from tvm_tirx import tirx as tir
-from tvm_tirx.ir import Range, TensorRegion, Type
+
+# import tirx.expr for direct ir construction to pass structural_equal comparison
+from tvm_tirx.ir import FloatImm, IntImm, Range, TensorRegion, Type
from tvm_tirx.ir.location import UNKNOWN_LOC, Location
from tvm_tirx.ir.type import _init_type_api, _normalize_type
from tvm_tirx.runtime import MemoryScope
@@ -42,13 +45,7 @@ from tvm_tirx.target import Target
# pylint: disable=unused-import
from tvm_tirx.tirx import Expr, IndexMap, Var, is_tensor_var, tile
-
-# import tirx.expr for direct ir construction to pass structural_equal comparison
-from tvm_tirx.tirx.expr import (
- FloatImm,
- IntImm,
- TensorLoad,
-)
+from tvm_tirx.tirx.expr import TensorLoad
from tvm_tirx.tirx.layout import Axis, ComposeLayout, Iter, Layout, R, S, TileLayout
from tvm_tirx.tirx.thread_scope import ThreadScope
@@ -229,11 +226,11 @@ def alloc_tensor(
def normalize(value):
if isinstance(value, bool):
- return tir.IntImm("bool", int(value))
+ return tvm_tirx.ir.IntImm("bool", int(value))
if isinstance(value, int):
- return tir.IntImm("int32", value)
+ return tvm_tirx.ir.IntImm("int32", value)
if isinstance(value, float):
- return tir.FloatImm("float32", value)
+ return tvm_tirx.ir.FloatImm("float32", value)
return value
if attrs is None:
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py b/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py
index 0ca8e40f0f..fd6887e564 100644
--- a/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py
+++ b/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py
@@ -18,7 +18,6 @@
from __future__ import annotations
-import functools
from typing import Any
from tvm_tirx import ir
@@ -28,10 +27,11 @@ from tvm_tirx import tirx as tir
# pylint: disable=unused-import
from tvm_tirx.codegen import llvm_lookup_intrinsic_id
-from tvm_tirx.ir import Call, Var
+from tvm_tirx.ir import Call, CallEffectKind, Var
from tvm_tirx.ir.location import UNKNOWN_LOC, Location
from tvm_tirx.ir.prim import _ffi_api as _prim_ffi
from tvm_tirx.ir.prim import _ffi_api as _prim_ffi_api
+from tvm_tirx.ir.prim.vector_expr import Broadcast, Ramp, Shuffle
from tvm_tirx.script.ir_builder import base as _base
from tvm_tirx.script.ir_builder.base import IRBuilder
from tvm_tirx.script.ir_builder.base import auto_emit_void_call as _auto_emit_void_call
@@ -54,8 +54,6 @@ from tvm_tirx.tirx.expr import (
BitwiseNot,
BitwiseOr,
BitwiseXor,
- Broadcast,
- CallEffectKind,
Cast,
Div,
FloorDiv,
@@ -67,15 +65,12 @@ from tvm_tirx.tirx.expr import (
Mul,
Not,
Or,
- Ramp,
RShift,
Select,
- Shuffle,
Sub,
)
from tvm_tirx.tirx.op import CallFFIKernelAttr
-from . import _ffi_api
from .external_kernel import call_kernel as _call_kernel
call_kernel = _auto_emit_void_call(_call_kernel)
@@ -99,9 +94,13 @@ def _call_global(func: ir.GlobalVar, *args: Expr) -> Call:
return Call(func, args)
-def cast(value, dtype, loc: Location = UNKNOWN_LOC):
- """Cast an expression to the requested data type."""
- return _prim_ffi_api._cast(value, dtype, loc) # type: ignore[attr-defined]
+def cast(value, ty, *, loc: Location = UNKNOWN_LOC):
+ """Cast an expression to the requested data type.
+
+ The result type may be passed positionally as ``cast(value, ty)`` or
+ explicitly as ``cast(value, ty=ty)``. The source location is keyword-only.
+ """
+ return _prim_ffi_api._cast(value, ty, loc) # type: ignore[attr-defined]
def Let( # pylint: disable=invalid-name
@@ -114,7 +113,7 @@ def Let( # pylint: disable=invalid-name
return tir.Let(var, value, expr)
-def min(a: Expr, b: Expr) -> Expr: # pylint: disable=redefined-builtin
+def min(a: Expr, b: Expr, loc: Location = UNKNOWN_LOC) -> Expr: # pylint: disable=redefined-builtin
"""Compute the minimum value of two expressions.
Parameters
@@ -125,15 +124,18 @@ def min(a: Expr, b: Expr) -> Expr: # pylint: disable=redefined-builtin
b : Expr
The right hand operand
+ loc : Location, optional
+ The location of the expression in the source code.
+
Returns
-------
res : Expr
The result expression.
"""
- return _ffi_api.min(a, b) # type: ignore[attr-defined] # pylint: disable=no-member
+ return _prim_ffi_api._OpMin(a, b, loc) # type: ignore[attr-defined]
-def max(a: Expr, b: Expr) -> Expr: # pylint: disable=redefined-builtin
+def max(a: Expr, b: Expr, loc: Location = UNKNOWN_LOC) -> Expr: # pylint: disable=redefined-builtin
"""Compute the maximum value of two expressions.
Parameters
@@ -144,22 +146,15 @@ def max(a: Expr, b: Expr) -> Expr: # pylint: disable=redefined-builtin
b : Expr
The right hand operand
+ loc : Location, optional
+ The location of the expression in the source code.
+
Returns
-------
res : Expr
The result expression.
"""
- return _ffi_api.max(a, b) # type: ignore[attr-defined] # pylint: disable=no-member
-
-
-def _llvm_result_type(func):
- """Keep symbolic intrinsic-name conversion when spelling the result as ty."""
-
- @functools.wraps(func)
- def wrapped(name, *args, ty, loc: Location = UNKNOWN_LOC):
- return func(ty, name, *args, loc=loc)
-
- return wrapped
+ return _prim_ffi_api._OpMax(a, b, loc) # type: ignore[attr-defined]
class WebGPUNamespace:
@@ -571,13 +566,13 @@ call_extern = _auto_emit_void_call(_ir.op._make_op_api(_ir.Op.get("tirx.call_ext
@_auto_emit_void_call
def call_intrin(func_name, *args, ty, attrs=None, loc: Location = UNKNOWN_LOC):
"""Call an intrinsic with an explicit result type."""
- return _tir_op.call_intrin(ty, func_name, *args, attrs=attrs, loc=loc)
+ return _tir_op.call_intrin(func_name, *args, attrs=attrs, loc=loc, ty=ty)
-call_llvm_intrin = _auto_emit_void_call(_llvm_result_type(_tir_op.call_llvm_intrin))
+call_llvm_intrin = _auto_emit_void_call(_tir_op.call_llvm_intrin)
-call_llvm_pure_intrin = _auto_emit_void_call(_llvm_result_type(_tir_op.call_llvm_pure_intrin))
+call_llvm_pure_intrin = _auto_emit_void_call(_tir_op.call_llvm_pure_intrin)
call_pure_extern = _auto_emit_void_call(
@@ -601,7 +596,7 @@ get_active_lane_mask = _auto_emit_void_call(
)
-masked_load = _auto_emit_void_call(_ir.op._make_op_api(_ir.Op.get("tirx.masked_load"), __name__))
+masked_load = _auto_emit_void_call(_tir_op.masked_load)
masked_store = _auto_emit_void_call(_tir_op.masked_store)
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py b/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
index c989c7a702..a0fd6bcdbd 100644
--- a/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
+++ b/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
@@ -34,9 +34,11 @@ import tvm_tirx
# isort: on
from tvm_tirx import ir as _ir
from tvm_tirx import tirx as _tir
-from tvm_tirx.ir import is_prim_expr
+from tvm_tirx.ir import IntImm, is_prim_expr
from tvm_tirx.ir.type import _PrimTypeArrayAnnotation
+from tvm_tirx.script.ir_builder import _ffi_api as _shared_ffi_api
from tvm_tirx.script.ir_builder import base as _base
+from tvm_tirx.script.ir_builder import frame as _shared_frame
from tvm_tirx.script.ir_builder.base import AlreadyEmitted
from tvm_tirx.script.ir_builder.base import IRBuilder as _IRBuilder
from tvm_tirx.script.ir_builder.stmt import (
@@ -85,9 +87,6 @@ from tvm_tirx.script.ir_builder.stmt import (
while_ as while_,
)
from tvm_tirx.tirx import Expr
-from tvm_tirx.tirx.expr import (
- IntImm,
-)
from . import _ffi_api, frame
from . import ir as _native
@@ -134,7 +133,7 @@ def function(
"""
if private is not None:
is_private = private
- return _ffi_api.Function(is_private, persistent) # type: ignore[attr-defined] # pylint: disable=no-member
+ return _ffi_api.Function(is_private, persistent, False) # type: ignore[attr-defined] # pylint: disable=no-member
def function_(
@@ -149,11 +148,7 @@ def function_(
Private/persistent options pass to the native TIRx function frame.
The same frame supports declaration and body entry.
"""
- native = (
- _ffi_api.DeclFunction(private, persistent)
- if decl
- else _ffi_api.Function(private, persistent)
- )
+ native = _ffi_api.Function(private, persistent, decl)
return _base.at_(loc, native)
@@ -365,7 +360,7 @@ def set_mutable_cell_(
elif (
_tir.is_tensor_var(target)
and len(target.ty.shape) == 1
- and isinstance(target.ty.shape[0], _tir.IntImm)
+ and isinstance(target.ty.shape[0], tvm_tirx.ir.IntImm)
and target.ty.shape[0].value == 1
):
return _base.at_(loc, tensor_store(target, [0], value))
@@ -489,7 +484,7 @@ def tensor_store(
def for_(
iterable: Any, *, names: str | Sequence[str] | None = None, loc: _Loc = None
-) -> frame.ForFrame:
+) -> _shared_frame.ForFrame:
"""Implements :func:`tvm_tirx.script.ir_builder.parser_protocol.for_`.
A single native loop returns its scalar Var; multiple loops return their
@@ -497,13 +492,13 @@ def for_(
"""
if isinstance(iterable, _python.range):
iterable = serial(iterable.start, iterable.stop, step=iterable.step)
- if not isinstance(iterable, frame.ForFrame):
+ if not isinstance(iterable, _shared_frame.ForFrame):
raise TypeError("A primitive for loop requires an iteration specification")
iterable.set_names(names)
return _base.at_(loc, iterable)
-def range_(*args: Any, annotations: dict[str, Any] | None = None) -> frame.ForFrame:
+def range_(*args: Any, annotations: dict[str, Any] | None = None) -> _shared_frame.ForFrame:
"""Implements :func:`tvm_tirx.script.ir_builder.parser_protocol.range_`."""
if len(args) == 1:
# serial constructs the omitted zero in the stop expression's dtype.
@@ -526,12 +521,12 @@ def _for(
step: Expr | None = None,
dtype: str | None = None,
annotations: dict[str, Any] | None = None,
-) -> frame.ForFrame:
+) -> _shared_frame.ForFrame:
if stop is None:
stop = start
# Preserve the endpoint dtype when the lower bound is omitted.
start = IntImm(start.ty, 0) if is_prim_expr(start) else 0
- return _ffi_api.For(kind, start, stop, step, dtype, annotations)
+ return _shared_ffi_api.For(kind, start, stop, step, dtype, annotations)
def serial(
@@ -542,7 +537,7 @@ def serial(
step: Expr | None = None,
unroll: bool | int | None = None,
dtype: str | None = None,
-) -> frame.ForFrame:
+) -> _shared_frame.ForFrame:
"""The serial For statement.
Parameters
@@ -560,9 +555,9 @@ def serial(
The optional step value of iteration.
unroll : bool or int, optional
- If True, adds ``{"pragma_unroll": True}`` annotation, which asks CUDA codegen
+ If True, adds ``{"tirx.pragma_unroll": True}`` annotation, which asks CUDA codegen
to emit ``#pragma unroll`` while preserving the loop as a C++ ``for``.
- If False, adds ``{"disable_unroll": True}`` annotation.
+ If False, adds ``{"tirx.disable_unroll": True}`` annotation.
If a positive integer, emits ``#pragma unroll N``. Boolean values are
handled separately from integers, so ``False`` keeps disabling unrolling.
@@ -573,20 +568,20 @@ def serial(
Returns
-------
- res : frame.ForFrame
+ res : _shared_frame.ForFrame
The ForFrame.
"""
if unroll is not None:
annotations = dict(annotations) if annotations else {}
if isinstance(unroll, bool):
if unroll:
- annotations["pragma_unroll"] = True
+ annotations["tirx.pragma_unroll"] = True
else:
- annotations["disable_unroll"] = True
+ annotations["tirx.disable_unroll"] = True
elif isinstance(unroll, int):
if unroll < 1:
raise ValueError("unroll must be a positive integer")
- annotations["pragma_unroll"] = unroll
+ annotations["tirx.pragma_unroll"] = unroll
else:
raise TypeError("unroll must be a bool, a positive integer, or None")
return _for(_ir.ForKind.DEFAULT, start, stop, step=step, dtype=dtype, annotations=annotations)
@@ -599,7 +594,7 @@ def parallel(
annotations: dict[str, Any] | None = None,
step: Expr | None = None,
dtype: str | None = None,
-) -> frame.ForFrame:
+) -> _shared_frame.ForFrame:
"""The parallel For statement.
Parameters
@@ -612,7 +607,7 @@ def parallel(
annotations : Dict[str, Any]
The optional annotations of the For statement. On CPU,
- ``{"parallel_stride_pattern": True}`` assigns iterations cyclically:
+ ``{"codegen.parallel_stride_pattern": True}`` assigns iterations cyclically:
worker ``t`` executes ``t, t + P, t + 2 * P, ...`` for ``P`` workers.
Absent or false selects contiguous chunks. Each loop selects its own
policy. When migrating ``pragma_parallel_stride_pattern``, annotate
@@ -628,7 +623,7 @@ def parallel(
Returns
-------
- res : frame.ForFrame
+ res : _shared_frame.ForFrame
The ForFrame.
"""
return _for(_ir.ForKind.PARALLEL, start, stop, step=step, dtype=dtype, annotations=annotations)
@@ -641,7 +636,7 @@ def vectorized(
annotations: dict[str, Any] | None = None,
step: Expr | None = None,
dtype: str | None = None,
-) -> frame.ForFrame:
+) -> _shared_frame.ForFrame:
"""The vectorized For statement.
Parameters
@@ -664,7 +659,7 @@ def vectorized(
Returns
-------
- res : frame.ForFrame
+ res : _shared_frame.ForFrame
The ForFrame.
"""
return _for(
@@ -679,7 +674,7 @@ def unroll(
annotations: dict[str, Any] | None = None,
step: Expr | None = None,
dtype: str | None = None,
-) -> frame.ForFrame:
+) -> _shared_frame.ForFrame:
"""The unrolled For statement.
Parameters
@@ -702,7 +697,7 @@ def unroll(
Returns
-------
- res : frame.ForFrame
+ res : _shared_frame.ForFrame
The ForFrame.
"""
return _for(_ir.ForKind.UNROLLED, start, stop, step=step, dtype=dtype, annotations=annotations)
@@ -715,7 +710,7 @@ def device_entry(
backend_config=None,
attrs=None,
body_params=None,
-) -> frame.RegionFrame:
+) -> _shared_frame.RegionFrame:
"""Enter a device kernel with independent CUDA launch and compile settings.
LaunchConfig values are ordinary region operands. BackendConfig supplies
@@ -746,7 +741,7 @@ def device_entry(
def device_context(
device_type: Expr, device_id: Expr, *, attrs=None, body_params=None
-) -> frame.RegionFrame:
+) -> _shared_frame.RegionFrame:
"""Supply lexical device context for allocation and packed-call lowering.
This region does not change the active runtime device.
@@ -756,19 +751,19 @@ def device_context(
)
-def compute_scope(name: str, *, attrs=None, body_params=None) -> frame.RegionFrame:
+def compute_scope(name: str, *, attrs=None, body_params=None) -> _shared_frame.RegionFrame:
"""Outline the body as a named CPU compute helper."""
return region("tirx.compute_scope", [name], attrs=attrs, body_params=body_params)
-def parallel_launch(*, attrs=None, body_params=None) -> frame.RegionFrame:
+def parallel_launch(*, attrs=None, body_params=None) -> _shared_frame.RegionFrame:
"""Launch a CPU worker team around parallel loops and team barriers."""
return region("tirx.parallel_launch", [], attrs=attrs, body_params=body_params)
def launch_thread(
thread_tag: str, extent: Expr, *, attrs=None, body_params=None
-) -> frame.RegionFrame:
+) -> _shared_frame.RegionFrame:
"""Launch a hardware or virtual thread with a fresh lexical variable.
The extent determines the variable's scalar integer type. Tags starting with
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/triton.py b/tirx/python/tvm_tirx/tirx/script/ir_builder/triton.py
index 41f6c3a061..33ae1d87f4 100644
--- a/tirx/python/tvm_tirx/tirx/script/ir_builder/triton.py
+++ b/tirx/python/tvm_tirx/tirx/script/ir_builder/triton.py
@@ -23,6 +23,7 @@ import triton
from packaging import version
from triton.runtime.jit import type_canonicalisation_dict
+import tvm_tirx
from tvm_tirx import tirx
from tvm_tirx.ir import PrimType, PtrType, is_prim_expr
from tvm_tirx.runtime import Module
@@ -138,5 +139,5 @@ class TritonKernel(BaseKernel):
if size is not None:
if size != 0:
raise ValueError(f"Triton kernels requiring {scratch}={size} are not supported")
- kernel_args.append(tirx.reinterpret("handle", tirx.IntImm("uint64", 0)))
+ kernel_args.append(tirx.reinterpret(tvm_tirx.ir.IntImm("uint64", 0), ty="handle"))
return compiled, kernel_args
diff --git a/tirx/python/tvm_tirx/tirx/tile/instruction.py b/tirx/python/tvm_tirx/tirx/tile/instruction.py
index c44c2ceb5a..91ed508c62 100644
--- a/tirx/python/tvm_tirx/tirx/tile/instruction.py
+++ b/tirx/python/tvm_tirx/tirx/tile/instruction.py
@@ -30,7 +30,9 @@ import tvm_ffi
from tvm_tirx.ir import (
Attrs,
Call,
+ CallEffectKind,
Expr,
+ IntImm,
Op,
PrimType,
PtrType,
@@ -43,7 +45,6 @@ from tvm_tirx.ir import (
)
from tvm_tirx.ir.location import UNKNOWN_LOC
from tvm_tirx.ir.op import register_op_attr
-from tvm_tirx.tirx.expr import IntImm
from tvm_tirx.tirx.thread_scope import ThreadScope
_REQUIRED = object()
@@ -78,7 +79,8 @@ class Instruction:
return SPECS[self.name]._factory
from .dispatch import run_dispatch
- register_op_attr(self.name, "TCallEffectKind", 3)
+ tvm_ffi.get_global_func("ir.RegisterOp")(self.name, "Tile instruction")
+ register_op_attr(self.name, "TCallEffectKind", CallEffectKind.UpdateState)
register_op_attr(self.name, "TFixedReturnType", PrimType("void"))
register_op_attr(self.name, "FTileOpDispatch", run_dispatch)
op = Op.get(self.name)
diff --git a/tirx/src/backend/cuda/runtime/cuda_device_api.cc b/tirx/src/backend/cuda/runtime/cuda_device_api.cc
index 36caa14e8c..c72d56b773 100644
--- a/tirx/src/backend/cuda/runtime/cuda_device_api.cc
+++ b/tirx/src/backend/cuda/runtime/cuda_device_api.cc
@@ -372,7 +372,7 @@ class CUDATimerObj : public TimerObj {
TVM_FFI_CHECK_CUDA_ERROR(cudaEventCreate(&start_));
TVM_FFI_CHECK_CUDA_ERROR(cudaEventCreate(&stop_));
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.cuda.CUDATimerNode", CUDATimerObj, TimerObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.cuda.CUDATimer", CUDATimerObj, TimerObj);
private:
cudaEvent_t start_;
diff --git a/tirx/src/backend/cuda/transforms/bind_backend_config.cc b/tirx/src/backend/cuda/transforms/bind_backend_config.cc
index 95c3d2dcd8..3534825f5f 100644
--- a/tirx/src/backend/cuda/transforms/bind_backend_config.cc
+++ b/tirx/src/backend/cuda/transforms/bind_backend_config.cc
@@ -192,7 +192,7 @@ class HelperCallCollector : public StmtExprVisitor {
Pass SpecializeEntryHelpers() {
auto transform = [](IRModule mod, PassContext ctx) {
- IRModule result({}, mod->source_map, mod->attrs, mod->global_infos);
+ IRModule result({}, mod->attrs, mod->global_infos);
UniqueNameSupply names(mod->functions.begin(), mod->functions.end(),
[](const auto& kv) { return kv.first->name_hint; });
std::unordered_set<const GlobalVarNode*> originals;
@@ -237,7 +237,7 @@ Pass SpecializeEntryHelpers() {
Pass SpecializeDeviceHelpers() {
auto transform = [](IRModule mod, PassContext ctx) {
- IRModule result({}, mod->source_map, mod->attrs, mod->global_infos);
+ IRModule result({}, mod->attrs, mod->global_infos);
UniqueNameSupply names(mod->functions.begin(), mod->functions.end(),
[](const auto& kv) { return kv.first->name_hint; });
std::map<std::string, ffi::ObjectPtr<DeviceHelperSpecializer>> groups;
diff --git a/tirx/src/backend/cuda/transforms/lower_iket.cc b/tirx/src/backend/cuda/transforms/lower_iket.cc
index 146cb52e33..b65be5d52a 100644
--- a/tirx/src/backend/cuda/transforms/lower_iket.cc
+++ b/tirx/src/backend/cuda/transforms/lower_iket.cc
@@ -22,6 +22,7 @@
* \brief Lower frontend-only TIRx IKET annotations to CUDA tracing helpers.
*/
+#include <tvm/backend/cuda/attr.h>
#include <tvm/backend/cuda/op/iket.h>
#include <tvm/ffi/reflection/registry.h>
#include <tvm/ir/function.h>
@@ -1177,7 +1178,7 @@ class InstrumentOfficialKernel : public StmtExprMutator {
};
bool IketEnabled(const IRModule& module) {
- if (module->HasNonzeroAttr(tvm::backend::cuda::attr::kIKetEnabled)) return true;
+ if (module->HasNonzeroAttr(tvm::backend::cuda::attr::kIKetEnabled.name)) return true;
const char* child_enable = std::getenv("TVM_IKET_INJECTED_CHILD_ENABLE");
const char* injection = std::getenv("CUDA_INJECTION64_PATH");
const char* injection_config = std::getenv("IKET_INJECTION_CONFIG");
diff --git a/tirx/src/backend/metal/runtime/metal_device_api.mm b/tirx/src/backend/metal/runtime/metal_device_api.mm
index 0cd0bc1094..fad1addf76 100644
--- a/tirx/src/backend/metal/runtime/metal_device_api.mm
+++ b/tirx/src/backend/metal/runtime/metal_device_api.mm
@@ -426,7 +426,7 @@ class MetalTimerObj : public TimerObj {
[mtl_dev_ sampleTimestamps:&stop_cpu_time_ gpuTimestamp:&stop_gpu_time_];
}
virtual int64_t SyncAndGetElapsedNanos() { return stop_gpu_time_ - start_gpu_time_; }
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.metal.MetalTimerNode", MetalTimerObj, TimerObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.metal.MetalTimer", MetalTimerObj, TimerObj);
private:
Device dev_;
diff --git a/tirx/src/backend/opencl/runtime/opencl_common.h b/tirx/src/backend/opencl/runtime/opencl_common.h
index b89fb1ab3b..434d84e4fd 100644
--- a/tirx/src/backend/opencl/runtime/opencl_common.h
+++ b/tirx/src/backend/opencl/runtime/opencl_common.h
@@ -609,7 +609,7 @@ class OpenCLTimerObj : public TimerObj {
static size_t count_timer_execs;
static std::vector<size_t> event_start_idxs;
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.opencl.OpenCLTimerNode", OpenCLTimerObj, TimerObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.opencl.OpenCLTimer", OpenCLTimerObj, TimerObj);
private:
int64_t duration;
diff --git a/tirx/src/backend/rocm/runtime/rocm_device_api.cc b/tirx/src/backend/rocm/runtime/rocm_device_api.cc
index 2d71a34665..9508b04f1b 100644
--- a/tirx/src/backend/rocm/runtime/rocm_device_api.cc
+++ b/tirx/src/backend/rocm/runtime/rocm_device_api.cc
@@ -311,7 +311,7 @@ class ROCMTimerObj : public TimerObj {
ROCM_CALL(hipEventCreate(&start_));
ROCM_CALL(hipEventCreate(&stop_));
}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.rocm.ROCMTimerNode", ROCMTimerObj, TimerObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.rocm.ROCMTimer", ROCMTimerObj, TimerObj);
private:
hipEvent_t start_;
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_timer.h b/tirx/src/backend/vulkan/runtime/vulkan_timer.h
index 24daf615ca..c46d3cd58f 100644
--- a/tirx/src/backend/vulkan/runtime/vulkan_timer.h
+++ b/tirx/src/backend/vulkan/runtime/vulkan_timer.h
@@ -65,7 +65,7 @@ class VulkanTimerObj : public TimerObj {
*/
int64_t SyncAndGetElapsedNanos() override;
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.vulkan.VulkanTimerNode", VulkanTimerObj, TimerObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.vulkan.VulkanTimer", VulkanTimerObj, TimerObj);
private:
Device dev_; ///< The TVM device being used.
diff --git a/tirx/src/codegen/c/codegen_c_host.cc b/tirx/src/codegen/c/codegen_c_host.cc
index 8f9d74ee11..708079aa46 100644
--- a/tirx/src/codegen/c/codegen_c_host.cc
+++ b/tirx/src/codegen/c/codegen_c_host.cc
@@ -391,10 +391,6 @@ ffi::Module BuildCHost(IRModule mod, Target target) {
cg.Init(output_ssa, emit_asserts, emit_fwd_func_decl, target->str(), devices);
cg.SetConstantsByteAlignment(target->GetAttr<int64_t>("constants-byte-alignment").value_or(16));
- auto is_aot_executor_fn = [](const Function& func) -> bool {
- return func->GetAttr<bool>(tvm::codegen::attr::kRunnerFunction, false).value();
- };
-
std::vector<std::pair<GlobalVar, Function>> funcs;
for (auto [gvar, base_func] : mod->functions) {
TVM_FFI_ICHECK(base_func->IsInstance<FunctionNode>()) << "CodegenCHost: Can only take Function";
@@ -402,12 +398,9 @@ ffi::Module BuildCHost(IRModule mod, Target target) {
funcs.push_back({gvar, function});
}
- // Sort functions
- auto sort_key = [&is_aot_executor_fn](const auto& kv) {
- return std::tuple{is_aot_executor_fn(kv.second), kv.first->name_hint};
- };
- std::sort(funcs.begin(), funcs.end(), [&sort_key](const auto& kv_a, const auto& kv_b) {
- return sort_key(kv_a) < sort_key(kv_b);
+ // Sort functions by name for deterministic output.
+ std::sort(funcs.begin(), funcs.end(), [](const auto& kv_a, const auto& kv_b) {
+ return kv_a.first->name_hint < kv_b.first->name_hint;
});
for (const auto& [gvar, function] : funcs) {
diff --git a/tirx/src/codegen/llvm/codegen_cpu.cc b/tirx/src/codegen/llvm/codegen_cpu.cc
index 64722f2718..98cd256969 100644
--- a/tirx/src/codegen/llvm/codegen_cpu.cc
+++ b/tirx/src/codegen/llvm/codegen_cpu.cc
@@ -1192,7 +1192,7 @@ void CodeGenCPU::Dispatch_(const ForNode* op) {
parallel_env_.in_parallel_loop = true;
PrimExpr end = IsZero(op->min) ? op->extent : analyzer_->Simplify(op->min + op->extent);
bool stride_pattern = false;
- if (auto it = op->annotations.find(tvm::codegen::attr::kParallelStridePattern);
+ if (auto it = op->annotations.find(tvm::codegen::attr::kParallelStridePattern.name);
it != op->annotations.end()) {
ffi::Any annotation = (*it).second;
if (auto value = annotation.as<bool>()) {
diff --git a/tirx/src/ir/attrs.cc b/tirx/src/ir/attrs.cc
index b58c183c7a..9054c74e14 100644
--- a/tirx/src/ir/attrs.cc
+++ b/tirx/src/ir/attrs.cc
@@ -30,9 +30,4 @@ TVM_FFI_STATIC_INIT_BLOCK() { DictAttrsNode::RegisterReflection(); }
TVM_FFI_STATIC_INIT_BLOCK() { tvm::ffi::reflection::ObjectDef<AttrsNode>(); }
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("ir.DictAttrsGetDict", [](DictAttrs attrs) { return attrs->dict; });
-}
-
} // namespace tvm
diff --git a/tirx/src/ir/env_func.cc b/tirx/src/ir/env_func.cc
index e6f2a2948b..27d57cd3de 100644
--- a/tirx/src/ir/env_func.cc
+++ b/tirx/src/ir/env_func.cc
@@ -64,13 +64,10 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def_packed("ir.EnvFuncCall",
- [](ffi::PackedArgs args, ffi::Any* rv) {
- EnvFunc env = args[0].cast<EnvFunc>();
- TVM_FFI_ICHECK_GE(args.size(), 1);
- env->func.CallPacked(args.Slice(1), rv);
- })
- .def("ir.EnvFuncGetFunction", [](const EnvFunc& n) { return n->func; });
+ refl::GlobalDef().def_packed("ir.EnvFuncCall", [](ffi::PackedArgs args, ffi::Any* rv) {
+ EnvFunc env = args[0].cast<EnvFunc>();
+ TVM_FFI_ICHECK_GE(args.size(), 1);
+ env->func.CallPacked(args.Slice(1), rv);
+ });
}
} // namespace tvm
diff --git a/tirx/src/ir/expr.cc b/tirx/src/ir/expr.cc
index 7a074fed3c..c19c0027cd 100644
--- a/tirx/src/ir/expr.cc
+++ b/tirx/src/ir/expr.cc
@@ -784,19 +784,22 @@ Expr LambdaExprNode::Apply(const ffi::Array<Expr>& arguments) const {
.cast<Expr>();
}
-LambdaExpr::LambdaExpr(ffi::Array<Var> vars, Expr body) : StagingExpr(ffi::UnsafeInit{}) {
+LambdaExpr::LambdaExpr(ffi::Array<Var> vars, Expr body, Location loc)
+ : StagingExpr(ffi::UnsafeInit{}) {
auto n = ffi::make_object<LambdaExprNode>(std::move(body));
ffi::Array<Type> types;
for (const Var& var : vars) types.push_back(var->ty);
n->ty = FuncType(types, n->body->ty);
n->vars = std::move(vars);
+ n->loc = std::move(loc);
data_ = std::move(n);
}
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("ir.LambdaExpr",
- [](ffi::Array<Var> vars, Expr body) { return LambdaExpr(vars, body); });
+ refl::GlobalDef().def("ir.LambdaExpr", [](ffi::Array<Var> vars, Expr body, Location loc) {
+ return LambdaExpr(vars, body, loc);
+ });
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -879,14 +882,6 @@ PrimExpr::PrimExpr(int32_t value) : PrimExpr(IntImm::Int32(value)) {}
PrimExpr::PrimExpr(float value) : PrimExpr(FloatImm(PrimType::Float(32), value)) {}
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("relax.Tuple", [](ffi::Array<Expr> fields, Location loc) { return Tuple(fields, loc); })
- .def("relax.TupleGetItem",
- [](Expr tuple, int index, Location loc) { return TupleGetItem(tuple, index, loc); });
-}
-
// Constants
GenericConst::GenericConst(ffi::Any value, Type ty, Location loc) : Constant(ffi::UnsafeInit{}) {
TVM_FFI_CHECK(!ty.as<MissingType>().has_value(), TypeError)
@@ -1241,7 +1236,8 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.attr(ffi::type_attr::kStructuralMaybeInplaceMutate,
ffi::FStructuralMutate::FromNative<&GlobalVarMaybeInplaceMutate>());
- refl::GlobalDef().def("ir.GlobalVar", [](ffi::String name) { return GlobalVar(name); });
+ refl::GlobalDef().def("ir.GlobalVar",
+ [](ffi::String name, Location loc) { return GlobalVar(name, loc); });
}
// Call construction intentionally does not validate: passes and raw script
@@ -1300,14 +1296,6 @@ TVM_FFI_STATIC_INIT_BLOCK() {
[](const Call& call) { return Call::ReinferType(call.get()); });
}
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("ir.DebugPrint", [](ffi::ObjectRef ref) {
- std::stringstream ss;
- ss << ref;
- return ss.str();
- });
- // Note: kRepr for GlobalVarNode is registered in script/printer/script_printer.cc.
-}
+// Note: kRepr for GlobalVarNode is registered in script/printer/script_printer.cc.
} // namespace tvm
diff --git a/tirx/src/ir/function.cc b/tirx/src/ir/function.cc
index 92a8119157..47ff266a59 100644
--- a/tirx/src/ir/function.cc
+++ b/tirx/src/ir/function.cc
@@ -31,7 +31,6 @@ namespace tvm {
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
refl::GlobalDef()
- .def("ir.BaseFunc_Attrs", [](BaseFunc func) { return func->attrs; })
.def("ir.BaseFuncCopy", [](BaseFunc func) { return func; })
.def("ir.BaseFuncWithAttr",
[](ffi::RValueRef<BaseFunc> func_ref, ffi::String key, Any value) -> BaseFunc {
diff --git a/tirx/src/ir/location.cc b/tirx/src/ir/location.cc
index 8189f4c6f5..04c08cb547 100644
--- a/tirx/src/ir/location.cc
+++ b/tirx/src/ir/location.cc
@@ -32,11 +32,6 @@
namespace tvm {
-TVM_FFI_STATIC_INIT_BLOCK() {
- SourceObj::RegisterReflection();
- SourceMapObj::RegisterReflection();
-}
-
ffi::ObjectPtr<SourceNameNode> GetSourceNameNode(const ffi::String& name) {
// always return pointer as the reference can change as map re-allocate.
// or use another level of indirection by creating a unique_ptr
@@ -155,69 +150,4 @@ TVM_FFI_STATIC_INIT_BLOCK() {
});
}
-/*! \brief Construct a source from a string. */
-Source::Source(SourceName src_name, std::string source) {
- auto n = ffi::make_object<SourceObj>(std::move(src_name));
- n->source = std::move(source);
-
- int index = 0;
- int length = 0;
- n->line_map.push_back({index, length});
- // NB(@jroesch):
- std::string source_str = n->source;
- for (auto c : source_str) {
- if (c == '\n') {
- // Record the length of the line.
- n->line_map.back().second = length;
- // Bump past the newline.
- index += 1;
- // Record the start of the next line, and put placeholder for length.
- n->line_map.push_back({index, 0});
- // Reset length to zero.
- length = 0;
- } else {
- length += 1;
- index += 1;
- }
- }
- n->line_map.back().second = length;
-
- data_ = n;
-}
-
-tvm::ffi::String Source::GetLine(int line) {
- VLOG(1) << "Source::GetLine: line=" << line;
- TVM_FFI_ICHECK(line - 1 < static_cast<int64_t>((*this)->line_map.size()))
- << "requested line: " << line << "at index: " << (line - 1)
- << "line_map size: " << (*this)->line_map.size() << "source: " << (*this)->source;
-
- // Adjust for zero indexing, now have (line_start, line_length);
- auto range = (*this)->line_map.at(line - 1);
- int line_start = range.first;
- int line_length = range.second;
- VLOG(1) << "Source::GetLine: line_start=" << line_start << " line_length=" << line_length;
- // TODO(@jroesch): expose substring on tvm::ffi::String.
- auto line_text = std::string((*this)->source).substr(line_start, line_length);
- VLOG(1) << "Source::GetLine: line_text=" << line_text;
- return line_text;
-}
-
-SourceMap::SourceMap(ffi::Map<SourceName, Source> source_map) {
- auto n = ffi::make_object<SourceMapObj>();
- n->source_map = std::move(source_map);
- data_ = std::move(n);
-}
-
-void SourceMap::Add(const Source& source) { (*this)->source_map.Set(source->source_name, source); }
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("SourceMapAdd", [](SourceMap map, ffi::String name, ffi::String content) {
- auto src_name = SourceName::Get(name);
- Source source(src_name, content);
- map.Add(source);
- return src_name;
- });
-}
-
} // namespace tvm
diff --git a/tirx/src/ir/module.cc b/tirx/src/ir/module.cc
index 0bbf65d7f4..b140a46589 100644
--- a/tirx/src/ir/module.cc
+++ b/tirx/src/ir/module.cc
@@ -37,12 +37,11 @@
namespace tvm {
-IRModule::IRModule(tvm::ffi::Map<GlobalVar, BaseFunc> functions, SourceMap source_map,
- DictAttrs attrs, ffi::Map<ffi::String, ffi::Array<GlobalInfo>> global_infos) {
+IRModule::IRModule(tvm::ffi::Map<GlobalVar, BaseFunc> functions, DictAttrs attrs,
+ ffi::Map<ffi::String, ffi::Array<GlobalInfo>> global_infos) {
auto n = ffi::make_object<IRModuleNode>();
n->functions = std::move(functions);
n->global_var_map_ = {};
- n->source_map = source_map;
n->attrs = std::move(attrs);
n->global_infos = std::move(global_infos);
@@ -129,7 +128,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
}
}();
- return IRModule(funcs, {}, dict_attrs, global_infos);
+ return IRModule(funcs, dict_attrs, global_infos);
});
}
@@ -220,7 +219,7 @@ void IRModuleNode::Update(const IRModule& mod) {
}
IRModule IRModuleNode::ShallowCopy() {
- return IRModule(this->functions, this->source_map, this->attrs, this->global_infos);
+ return IRModule(this->functions, this->attrs, this->global_infos);
}
IRModule IRModule::FromExpr(const Expr& expr,
@@ -256,19 +255,19 @@ IRModule IRModule::FromExpr(const Expr& expr,
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
refl::GlobalDef()
- .def("ir.Module_Clone",
+ .def("ir.IRModuleClone",
[](IRModule mod) -> IRModule {
IRModule clone = mod;
clone.CopyOnWrite();
return clone;
})
- .def("ir.Module_Add",
+ .def("ir.IRModuleAdd",
[](IRModule mod, GlobalVar var, ffi::ObjectRef val, bool update) -> IRModule {
TVM_FFI_ICHECK(val->IsInstance<BaseFuncNode>());
mod->Add(var, val.as_or_throw<BaseFunc>(), update);
return mod;
})
- .def("ir.Module_Remove",
+ .def("ir.IRModuleRemove",
[](IRModule mod, ffi::Variant<ffi::String, GlobalVar> var) -> IRModule {
GlobalVar gvar = [&]() {
if (auto opt = var.as<GlobalVar>()) {
@@ -282,7 +281,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
mod->Remove(gvar);
return mod;
})
- .def("ir.Module_Contains",
+ .def("ir.IRModuleContains",
[](IRModule mod, ffi::Variant<ffi::String, GlobalVar> var) -> bool {
if (auto opt = var.as<GlobalVar>()) {
return mod->functions.count(opt.value());
@@ -292,35 +291,35 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TVM_FFI_THROW(InternalError) << "Variant didn't contain any of the allowed types";
}
})
- .def_method("ir.Module_GetGlobalVar", &IRModuleNode::GetGlobalVar)
- .def_method("ir.Module_GetGlobalVars", &IRModuleNode::GetGlobalVars)
- .def_method("ir.Module_ContainGlobalVar", &IRModuleNode::ContainGlobalVar)
- .def("ir.Module_Lookup", [](IRModule mod, GlobalVar var) { return mod->Lookup(var); })
- .def("ir.Module_Lookup_str", [](IRModule mod, ffi::String var) { return mod->Lookup(var); })
- .def("ir.Module_FromExpr", &IRModule::FromExpr)
- .def("ir.Module_Update", [](IRModule mod, IRModule from) { mod->Update(from); })
- .def("ir.Module_UpdateFunction",
+ .def_method("ir.IRModuleGetGlobalVar", &IRModuleNode::GetGlobalVar)
+ .def_method("ir.IRModuleGetGlobalVars", &IRModuleNode::GetGlobalVars)
+ .def_method("ir.IRModuleContainGlobalVar", &IRModuleNode::ContainGlobalVar)
+ .def("ir.IRModuleLookup", [](IRModule mod, GlobalVar var) { return mod->Lookup(var); })
+ .def("ir.IRModuleLookupStr", [](IRModule mod, ffi::String var) { return mod->Lookup(var); })
+ .def("ir.IRModuleFromExpr", &IRModule::FromExpr)
+ .def("ir.IRModuleUpdate", [](IRModule mod, IRModule from) { mod->Update(from); })
+ .def("ir.IRModuleUpdateFunction",
[](IRModule mod, GlobalVar gv, BaseFunc func) { mod->Update(gv, func); })
- .def("ir.Module_UpdateGlobalInfo",
+ .def("ir.IRModuleUpdateGlobalInfo",
[](IRModule mod, ffi::String name, ffi::Array<GlobalInfo> global_info) {
mod->UpdateGlobalInfo(name, global_info);
})
- .def("ir.Module_GetAttrs", [](IRModule mod) -> ffi::ObjectRef { return mod->GetAttrs(); })
- .def("ir.Module_WithAttr",
+ .def("ir.IRModuleWithAttr",
[](ffi::RValueRef<IRModule> mod, ffi::String key, ffi::Any value) -> IRModule {
return WithAttr(*std::move(mod), key, value);
})
- .def("ir.Module_WithoutAttr",
+ .def("ir.IRModuleWithoutAttr",
[](ffi::RValueRef<IRModule> mod, ffi::String key) -> IRModule {
return WithoutAttr(*std::move(mod), key);
})
- .def("ir.Module_WithAttrs",
+ .def("ir.IRModuleWithAttrs",
[](ffi::RValueRef<IRModule> mod, ffi::Map<ffi::String, ffi::Any> attr_map) -> IRModule {
return WithAttrs(*std::move(mod), attr_map);
})
- .def("ir.Module_GetAttr", [](IRModule mod, ffi::String key) -> ffi::Optional<ffi::ObjectRef> {
- return mod->GetAttr<ffi::ObjectRef>(key);
- });
+ .def("ir.IRModuleGetAttr",
+ [](IRModule mod, ffi::String key) -> ffi::Optional<ffi::ObjectRef> {
+ return mod->GetAttr<ffi::ObjectRef>(key);
+ });
}
} // namespace tvm
diff --git a/tirx/src/ir/op.cc b/tirx/src/ir/op.cc
index f53903044e..f2533bfd37 100644
--- a/tirx/src/ir/op.cc
+++ b/tirx/src/ir/op.cc
@@ -235,12 +235,6 @@ void OpNode::RegisterReflection() {
.def_ro("ty_args_info", &OpNode::ty_args_info, refl::AttachFieldFlag::SEqHashIgnore())
.def_ro("var_args_info", &OpNode::var_args_info, refl::AttachFieldFlag::SEqHashIgnore())
.def_ro("var_ty_args_info", &OpNode::var_ty_args_info, refl::AttachFieldFlag::SEqHashIgnore())
- .def_static("get", &Op::Get,
- "get(op_name: str) -> Op\n\nReturn the canonical named Op; raise AttributeError "
- "if unregistered.")
- .def_static(
- "list_op_names", &Op::ListNames,
- "list_op_names() -> list[str]\n\nReturn registered operator names in unspecified order.")
.def(
"get_attr",
[](Op op, ffi::String name) {
@@ -332,11 +326,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TVM_FFI_CHECK(!OpRegistry::Global()->Contains(name), AttributeError)
<< "Operator " << name << " is registered before";
OpDef(name, doc);
- })
- .def("ir.RegisterOpAttr", [](ffi::String name, ffi::String key, ffi::Any value, bool override) {
- OpDef(name)
- .set_attr(key, value, override);
- });
+ });
// clang-format on
}
diff --git a/tirx/src/ir/prim/op.cc b/tirx/src/ir/prim/op.cc
index aeea8bee76..8153c442d5 100644
--- a/tirx/src/ir/prim/op.cc
+++ b/tirx/src/ir/prim/op.cc
@@ -731,12 +731,6 @@ PrimExpr bitwise_neg(PrimExpr a, Location loc) {
return prim::BitwiseNot(a, loc);
}
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("prim.bitwise_not",
- [](PrimExpr a, Location loc) { return bitwise_neg(a, loc); });
-}
-
PrimExpr prim::IntegerAbs(PrimExpr x, Location loc) {
if (x.ty().MatchesCode(DLDataTypeCode::kDLInt)) {
if (const IntImmNode* px = x.as<IntImmNode>()) {
@@ -778,7 +772,6 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.DEF_MAKE_BINARY_OP(_OpSub, sub)
.DEF_MAKE_BINARY_OP(_OpMul, mul)
.DEF_MAKE_BINARY_OP(_OpDiv, div)
- .DEF_MAKE_BINARY_OP(_OpMod, truncmod)
.DEF_MAKE_BINARY_OP(_OpIndexDiv, indexdiv)
.DEF_MAKE_BINARY_OP(_OpIndexMod, indexmod)
.DEF_MAKE_BINARY_OP(_OpFloorDiv, floordiv)
@@ -804,7 +797,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
}
// ceil
-PrimExpr ceil(PrimExpr x, Location loc) {
+PrimExpr prim::ceil(PrimExpr x, Location loc) {
if (x.ty().MatchesCode(DLDataTypeCode::kDLInt, DLDataTypeCode::kDLUInt,
DLDataTypeCode::kDLBool)) {
return x;
@@ -814,7 +807,7 @@ PrimExpr ceil(PrimExpr x, Location loc) {
return Call(x.ty(), prim::ceil_op(), {x}, {}, {}, loc).as_or_throw<PrimExpr>();
}
-PrimExpr log2(PrimExpr x, Location loc) {
+PrimExpr prim::log2(PrimExpr x, Location loc) {
PrimType x_ty = x.ty();
if (x_ty.MatchesElementType(DLDataTypeCode::kDLBfloat, 16)) {
PrimType f32_ty = x_ty.IsScalableVector() ? PrimType::ScalableVector(DLDataTypeCode::kDLFloat,
@@ -853,7 +846,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
Location loc) { return prim::cast(value, dtype, loc); })
.def("prim.min_value", static_cast<PrimExpr (*)(PrimType, Location)>(&prim::min_value))
.def("prim.likely", tvm::likely)
- .def("prim.ceil", tvm::ceil);
+ .def("prim.ceil", prim::ceil);
}
} // namespace tvm
diff --git a/tirx/src/ir/type.cc b/tirx/src/ir/type.cc
index d9ac420a02..d10c33a3fa 100644
--- a/tirx/src/ir/type.cc
+++ b/tirx/src/ir/type.cc
@@ -257,7 +257,6 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.attr(ffi::type_attr::kStructuralMutate, ffi::FStructuralMutate::FromNative<&TypeMutate>())
.attr(ffi::type_attr::kStructuralMaybeInplaceMutate,
ffi::FStructuralMutate::FromNative<&TypeMaybeInplaceMutate>());
- refl::GlobalDef().def("ir.TypeMissing", []() { return Type::Missing(); });
}
MissingType::MissingType() : Type(ffi::UnsafeInit{}) {
diff --git a/tirx/src/runtime/device_api.cc b/tirx/src/runtime/device_api.cc
index a94b7f28ee..70500a92df 100644
--- a/tirx/src/runtime/device_api.cc
+++ b/tirx/src/runtime/device_api.cc
@@ -154,23 +154,23 @@ void DeviceAPI::SyncStreamFromTo(Device dev, TVMStreamHandle event_src, TVMStrea
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
refl::GlobalDef()
- .def("runtime.Device_StreamCreate",
+ .def("runtime.DeviceStreamCreate",
[](DLDevice dev) {
return reinterpret_cast<int64_t>(DeviceAPIManager::Get(dev)->CreateStream(dev));
})
- .def("runtime.Device_StreamFree",
+ .def("runtime.DeviceStreamFree",
[](DLDevice dev, int64_t stream) {
DeviceAPIManager::Get(dev)->FreeStream(dev, reinterpret_cast<TVMStreamHandle>(stream));
})
- .def("runtime.Device_SetStream",
+ .def("runtime.DeviceSetStream",
[](DLDevice dev, int64_t stream) {
DeviceAPIManager::Get(dev)->SetStream(dev, reinterpret_cast<TVMStreamHandle>(stream));
})
- .def("runtime.Device_StreamSync",
+ .def("runtime.DeviceStreamSync",
[](DLDevice dev, int64_t stream) {
DeviceAPIManager::Get(dev)->StreamSync(dev, reinterpret_cast<TVMStreamHandle>(stream));
})
- .def("runtime.Device_StreamSyncFromTo", [](DLDevice dev, int64_t src, int64_t dst) {
+ .def("runtime.DeviceStreamSyncFromTo", [](DLDevice dev, int64_t src, int64_t dst) {
DeviceAPIManager::Get(dev)->SyncStreamFromTo(dev, reinterpret_cast<TVMStreamHandle>(src),
reinterpret_cast<TVMStreamHandle>(dst));
});
@@ -179,20 +179,13 @@ TVM_FFI_STATIC_INIT_BLOCK() {
// set device api
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("runtime.GetDeviceAttr",
- [](int device_type, int device_id, ffi::String name) {
- DLDevice dev{static_cast<DLDeviceType>(device_type), device_id};
- DeviceAPI* api = DeviceAPI::Get(dev, name == "exist");
- if (api == nullptr) return ffi::Any(false);
- return api->GetAttr(dev, name);
- })
- .def("runtime.TVMSetStream", [](int device_type, int device_id, void* stream) {
- Device dev;
- dev.device_type = static_cast<DLDeviceType>(device_type);
- dev.device_id = device_id;
- DeviceAPIManager::Get(dev)->SetStream(dev, stream);
- });
+ refl::GlobalDef().def("runtime.GetDeviceAttr",
+ [](int device_type, int device_id, ffi::String name) {
+ DLDevice dev{static_cast<DLDeviceType>(device_type), device_id};
+ DeviceAPI* api = DeviceAPI::Get(dev, name == "exist");
+ if (api == nullptr) return ffi::Any(false);
+ return api->GetAttr(dev, name);
+ });
}
} // namespace runtime
} // namespace tvm
@@ -220,18 +213,35 @@ int TVMBackendGetDeviceIndex(int device_type, int* out_device_index) {
TVM_FFI_SAFE_CALL_END();
}
-void* TVMBackendAllocWorkspace(int device_type, int device_id, uint64_t size, int dtype_code_hint,
- int dtype_bits_hint) {
+namespace {
+
+int AllocWorkspaceSafe(int device_type, int device_id, uint64_t size, int dtype_code_hint,
+ int dtype_bits_hint, void** out) {
+ TVM_FFI_SAFE_CALL_BEGIN();
DLDevice dev{static_cast<DLDeviceType>(device_type), device_id};
TVM_FFI_CHECK_LE(size, std::numeric_limits<size_t>::max(), ValueError)
<< "Workspace size exceeds addressable memory";
DLDataType type_hint{static_cast<uint8_t>(dtype_code_hint), static_cast<uint8_t>(dtype_bits_hint),
1};
- return DeviceAPI::Get(dev)->AllocWorkspace(dev, static_cast<size_t>(size), type_hint);
+ *out = DeviceAPI::Get(dev)->AllocWorkspace(dev, static_cast<size_t>(size), type_hint);
+ TVM_FFI_SAFE_CALL_END();
+}
+
+} // namespace
+
+void* TVMBackendAllocWorkspace(int device_type, int device_id, uint64_t size, int dtype_code_hint,
+ int dtype_bits_hint) {
+ void* ptr = nullptr;
+ if (AllocWorkspaceSafe(device_type, device_id, size, dtype_code_hint, dtype_bits_hint, &ptr) !=
+ 0) {
+ return nullptr;
+ }
+ return ptr;
}
int TVMBackendFreeWorkspace(int device_type, int device_id, void* ptr) {
+ TVM_FFI_SAFE_CALL_BEGIN();
DLDevice dev{static_cast<DLDeviceType>(device_type), device_id};
DeviceAPI::Get(dev)->FreeWorkspace(dev, ptr);
- return 0;
+ TVM_FFI_SAFE_CALL_END();
}
diff --git a/tirx/src/runtime/tensor.cc b/tirx/src/runtime/tensor.cc
index 9b3a262b15..6e7f0fca31 100644
--- a/tirx/src/runtime/tensor.cc
+++ b/tirx/src/runtime/tensor.cc
@@ -19,8 +19,9 @@
/*!
* \file tensor.cc
- * \brief Tensor container infratructure.
+ * \brief Tensor container infrastructure.
*/
+#include <tvm/ffi/endian.h>
#include <tvm/ffi/error.h>
#include <tvm/ffi/extra/base64.h>
#include <tvm/ffi/extra/serialization.h>
@@ -29,11 +30,11 @@
#include <tvm/runtime/base.h>
#include <tvm/runtime/device_api.h>
#include <tvm/runtime/tensor.h>
-#include <tvm/support/base64.h>
#include <tvm/support/bytes_io.h>
#include <algorithm>
#include <limits>
+#include <vector>
#include "tvm/ffi/dtype.h"
@@ -44,9 +45,8 @@ void CopyToBytes(ffi::TensorView source, void* data, size_t nbytes, TVMStreamHan
const DLTensor* handle = ffi::AnyView(source).cast<DLTensor*>();
TVM_FFI_ICHECK(data != nullptr || nbytes == 0);
size_t arr_size = ffi::GetDataSize(*handle);
- TVM_FFI_ICHECK_EQ(arr_size, nbytes) << "ArrayCopyToBytes: size mismatch";
- TVM_FFI_ICHECK(ffi::IsContiguous(*handle))
- << "ArrayCopyToBytes only support contiguous array for now";
+ TVM_FFI_ICHECK_EQ(arr_size, nbytes) << "CopyToBytes: size mismatch";
+ TVM_FFI_ICHECK(ffi::IsContiguous(*handle)) << "CopyToBytes only supports contiguous tensors";
DLTensor to;
to.data = const_cast<void*>(data);
@@ -67,9 +67,8 @@ void CopyFromBytes(ffi::TensorView destination, const void* data, size_t nbytes,
const DLTensor* handle = ffi::AnyView(destination).cast<DLTensor*>();
TVM_FFI_ICHECK(data != nullptr || nbytes == 0);
size_t arr_size = ffi::GetDataSize(*handle);
- TVM_FFI_ICHECK_EQ(arr_size, nbytes) << "ArrayCopyToBytes: size mismatch";
- TVM_FFI_ICHECK(ffi::IsContiguous(*handle))
- << "ArrayCopyToBytes only support contiguous array for now";
+ TVM_FFI_ICHECK_EQ(arr_size, nbytes) << "CopyFromBytes: size mismatch";
+ TVM_FFI_ICHECK(ffi::IsContiguous(*handle)) << "CopyFromBytes only supports contiguous tensors";
DLTensor from;
from.data = const_cast<void*>(data);
@@ -176,8 +175,7 @@ void CopyFromTo(ffi::TensorView source, ffi::TensorView destination, TVMStreamHa
const DLTensor* to = ffi::AnyView(destination).cast<DLTensor*>();
size_t from_size = ffi::GetDataSize(*from);
size_t to_size = ffi::GetDataSize(*to);
- TVM_FFI_ICHECK_EQ(from_size, to_size)
- << "TVMTensorCopyFromTo: The size in bytes must exactly match.";
+ TVM_FFI_ICHECK_EQ(from_size, to_size) << "CopyFromTo: The size in bytes must exactly match.";
TVM_FFI_ICHECK(from->device.device_type == to->device.device_type ||
from->device.device_type == kDLCPU || to->device.device_type == kDLCPU ||
@@ -194,6 +192,80 @@ void CopyFromTo(ffi::TensorView source, ffi::TensorView destination, TVMStreamHa
stream);
}
+namespace {
+
+/*! \brief Swap the byte order of every scalar lane stored in a packed buffer. */
+void SwapTensorBytes(void* data, DLDataType dtype, size_t nbytes) {
+ // Sub-byte and single-byte lanes have no byte order.
+ if (dtype.bits <= 8) return;
+ size_t lane_bytes = dtype.bits / 8;
+ ffi::ByteSwap(data, lane_bytes, nbytes / lane_bytes);
+}
+
+} // namespace
+
+void SaveTensor(ffi::TensorView source, support::Stream* strm) {
+ const DLTensor* tensor = ffi::AnyView(source).cast<DLTensor*>();
+ uint64_t header = kTVMTensorMagic, reserved = 0;
+ strm->Write(header);
+ strm->Write(reserved);
+ // Serialized tensors are always recorded as CPU tensors, so they can be loaded on
+ // machines without the source device. Callers copy the result to the target device.
+ Device cpu_dev{kDLCPU, 0};
+ strm->Write(cpu_dev);
+ strm->Write(tensor->ndim);
+ strm->Write(tensor->dtype);
+ strm->WriteArray(tensor->shape, tensor->ndim);
+ size_t data_size = ffi::GetDataSize(*tensor);
+ int64_t data_byte_size = static_cast<int64_t>(data_size);
+ strm->Write(data_byte_size);
+
+ if (TVM_FFI_IO_NO_ENDIAN_SWAP && tensor->device.device_type == kDLCPU &&
+ ffi::IsContiguous(*tensor) && tensor->byte_offset == 0) {
+ strm->Write(tensor->data, data_size);
+ } else {
+ std::vector<uint8_t> bytes(data_size);
+ CopyToBytes(source, bytes.data(), data_size);
+ if (!TVM_FFI_IO_NO_ENDIAN_SWAP) {
+ SwapTensorBytes(bytes.data(), tensor->dtype, data_size);
+ }
+ strm->Write(bytes.data(), data_size);
+ }
+}
+
+ffi::Tensor LoadTensor(support::Stream* strm) {
+ uint64_t header, reserved;
+ TVM_FFI_CHECK(strm->Read(&header), ValueError) << "Invalid DLTensor file format";
+ TVM_FFI_CHECK(strm->Read(&reserved), ValueError) << "Invalid DLTensor file format";
+ TVM_FFI_CHECK(header == kTVMTensorMagic, ValueError) << "Invalid DLTensor file format";
+ Device dev;
+ int ndim;
+ DLDataType dtype;
+ TVM_FFI_CHECK(strm->Read(&dev), ValueError) << "Invalid DLTensor file format";
+ TVM_FFI_CHECK(strm->Read(&ndim), ValueError) << "Invalid DLTensor file format";
+ TVM_FFI_CHECK(strm->Read(&dtype), ValueError) << "Invalid DLTensor file format";
+ TVM_FFI_CHECK_EQ(dev.device_type, kDLCPU, ValueError)
+ << "Invalid DLTensor device: can only save as CPU tensor";
+ TVM_FFI_CHECK_GE(ndim, 0, ValueError) << "Invalid DLTensor file format";
+ std::vector<int64_t> shape(ndim);
+ if (ndim != 0) {
+ TVM_FFI_CHECK(strm->ReadArray(shape.data(), ndim), ValueError)
+ << "Invalid DLTensor file format";
+ }
+ ffi::Tensor ret = Empty(ffi::Shape(shape), dtype, dev);
+ size_t data_size = ffi::GetDataSize(*ret.GetDLTensorPtr());
+ int64_t data_byte_size;
+ TVM_FFI_CHECK(strm->Read(&data_byte_size), ValueError) << "Invalid DLTensor file format";
+ TVM_FFI_CHECK_EQ(data_byte_size, static_cast<int64_t>(data_size), ValueError)
+ << "Invalid DLTensor file format";
+ TVM_FFI_CHECK_EQ(strm->Read(ret.GetDLTensorPtr()->data, data_size), data_size, ValueError)
+ << "Invalid DLTensor file format: truncated data";
+ if (!TVM_FFI_IO_NO_ENDIAN_SWAP) {
+ SwapTensorBytes(ret.GetDLTensorPtr()->data, dtype, data_size);
+ }
+ return ret;
+}
+
} // namespace runtime
} // namespace tvm
@@ -206,24 +278,20 @@ TVM_FFI_STATIC_INIT_BLOCK() {
[](const tvm::ffi::TensorObj* node) {
std::string result;
tvm::support::BytesOutStream mstrm(&result);
- tvm::support::Base64OutStream b64strm(&mstrm);
- tvm::runtime::SaveTensor(node, &b64strm);
- b64strm.Finish();
- return tvm::ffi::String(std::move(result));
+ tvm::runtime::SaveTensor(node, &mstrm);
+ return tvm::ffi::Base64Encode(tvm::ffi::Bytes(result));
})
.def(tvm::ffi::type_attr::kDataFromJson.name, [](const std::string& blob) {
- tvm::support::BytesInStream mstrm(blob);
- tvm::support::Base64InStream b64strm(&mstrm);
- b64strm.InitPosition();
- return tvm::runtime::LoadTensor(&b64strm);
+ tvm::ffi::Bytes bytes = tvm::ffi::Base64Decode(blob);
+ tvm::support::BytesInStream mstrm(bytes.data(), bytes.size());
+ return tvm::runtime::LoadTensor(&mstrm);
});
refl::GlobalDef()
- .def("runtime.TVMTensorAllocWithScope", Empty)
- .def("runtime.TVMTensorCreateView", CreateView)
- .def("runtime.TVMTensorCopyFromBytes",
+ .def("runtime.TensorAllocWithScope", Empty)
+ .def("runtime.TensorCreateView", CreateView)
+ .def("runtime.TensorCopyFromBytes",
[](DLTensor* arr, void* data, size_t nbytes) { CopyFromBytes(arr, data, nbytes); })
- .def("runtime.TVMTensorCopyToBytes",
+ .def("runtime.TensorCopyToBytes",
[](DLTensor* arr, void* data, size_t nbytes) { CopyToBytes(arr, data, nbytes); })
- .def("runtime.TVMTensorCopyFromTo",
- [](DLTensor* from, DLTensor* to) { CopyFromTo(from, to); });
+ .def("runtime.TensorCopyFromTo", [](DLTensor* from, DLTensor* to) { CopyFromTo(from, to); });
}
diff --git a/tirx/src/runtime/timer.cc b/tirx/src/runtime/timer.cc
index fc257a1ffe..16014401b8 100644
--- a/tirx/src/runtime/timer.cc
+++ b/tirx/src/runtime/timer.cc
@@ -56,7 +56,7 @@ class DefaultTimerObj : public TimerObj {
virtual ~DefaultTimerObj() {}
explicit DefaultTimerObj(Device dev) : device_(dev) {}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.DefaultTimerNode", DefaultTimerObj, TimerObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.DefaultTimer", DefaultTimerObj, TimerObj);
private:
std::chrono::high_resolution_clock::time_point start_;
@@ -74,7 +74,7 @@ class CPUTimerObj : public TimerObj {
virtual void Stop() { duration_ = std::chrono::high_resolution_clock::now() - start_; }
virtual int64_t SyncAndGetElapsedNanos() { return duration_.count(); }
virtual ~CPUTimerObj() {}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.CPUTimerNode", CPUTimerObj, TimerObj);
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.CPUTimer", CPUTimerObj, TimerObj);
private:
std::chrono::high_resolution_clock::time_point start_;
@@ -115,10 +115,10 @@ Timer Timer::Start(Device dev) {
}
}
-ffi::Function WrapTimeEvaluator(ffi::Function pf, Device dev, int number, int repeat,
- int min_repeat_ms, int limit_zero_time_iterations,
- int cooldown_interval_ms, int repeats_to_cooldown,
- int cache_flush_bytes, ffi::Function f_preproc) {
+static ffi::Function WrapTimeEvaluator(ffi::Function pf, Device dev, int number, int repeat,
+ int min_repeat_ms, int limit_zero_time_iterations,
+ int cooldown_interval_ms, int repeats_to_cooldown,
+ int cache_flush_bytes, ffi::Function f_preproc) {
TVM_FFI_ICHECK(pf != nullptr);
auto ftimer = [pf, dev, number, repeat, min_repeat_ms, limit_zero_time_iterations,
@@ -268,7 +268,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
repeats_to_cooldown, cache_flush_bytes, f_preproc_name)
.cast<ffi::Function>();
})
- .def_packed("cache_flush_cpu_non_first_arg",
+ .def_packed("runtime.CacheFlushCPUArguments",
[](ffi::PackedArgs args, ffi::Any* rv) { CPUCacheFlush(1, args); });
}
diff --git a/tirx/src/script/ir_builder/frame.cc b/tirx/src/script/ir_builder/frame.cc
index dcbef97236..5ce320eeb3 100644
--- a/tirx/src/script/ir_builder/frame.cc
+++ b/tirx/src/script/ir_builder/frame.cc
@@ -109,7 +109,7 @@ void IRModuleFrameObj::ExitWithScope() {
IRBuilder builder = IRBuilder::Current();
TVM_FFI_CHECK(!builder->result.has_value(), ValueError) << "Builder.result has already been set";
auto dict_attrs = DictAttrs(attrs);
- builder->result = tvm::IRModule(func_map, {}, dict_attrs, global_infos);
+ builder->result = tvm::IRModule(func_map, dict_attrs, global_infos);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -172,7 +172,7 @@ void ForFrameObj::SetNames(
}
TVM_FFI_STATIC_INIT_BLOCK() {
- tvm::ffi::reflection::GlobalDef().def_method("script.ir_builder.tirx.ForFrameSetNames",
+ tvm::ffi::reflection::GlobalDef().def_method("script.ir_builder.ForFrameSetNames",
&ForFrameObj::SetNames);
}
diff --git a/tirx/src/script/ir_builder/ir.cc b/tirx/src/script/ir_builder/ir.cc
index 84b2580ed0..63bc243222 100644
--- a/tirx/src/script/ir_builder/ir.cc
+++ b/tirx/src/script/ir_builder/ir.cc
@@ -380,24 +380,24 @@ TVM_FFI_STATIC_INIT_BLOCK() {
// Preserve the historical FFI entry points with one shared implementation.
TVM_FFI_STATIC_INIT_BLOCK() {
ffi::reflection::GlobalDef()
- .def("script.ir_builder.tirx.For", For)
- .def("script.ir_builder.tirx.Grid", Grid)
- .def("script.ir_builder.tirx.Assert", Assert)
- .def("script.ir_builder.tirx.Bind", Bind)
- .def("script.ir_builder.tirx.While", While)
- .def("script.ir_builder.tirx.Return", Return)
- .def("script.ir_builder.tirx.Break", Break)
- .def("script.ir_builder.tirx.Continue", Continue)
- .def("script.ir_builder.tirx.If", If)
- .def("script.ir_builder.tirx.Then", Then)
- .def("script.ir_builder.tirx.Else", Else)
- .def("script.ir_builder.tirx.Region", Region)
- .def("script.ir_builder.tirx.Evaluate", Evaluate);
+ .def("script.ir_builder.For", For)
+ .def("script.ir_builder.Grid", Grid)
+ .def("script.ir_builder.Assert", Assert)
+ .def("script.ir_builder.Bind", Bind)
+ .def("script.ir_builder.While", While)
+ .def("script.ir_builder.Return", Return)
+ .def("script.ir_builder.Break", Break)
+ .def("script.ir_builder.Continue", Continue)
+ .def("script.ir_builder.If", If)
+ .def("script.ir_builder.Then", Then)
+ .def("script.ir_builder.Else", Else)
+ .def("script.ir_builder.Region", Region)
+ .def("script.ir_builder.Evaluate", Evaluate);
}
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("script.ir_builder.tirx.AddToParent",
+ refl::GlobalDef().def("script.ir_builder.AddToParent",
[](tvm::Stmt stmt) { AddToParent(std::move(stmt)); });
}
diff --git a/tirx/src/script/printer/doc_printer.cc b/tirx/src/script/printer/doc_printer.cc
index 98bb2e1059..98fb0bd6a9 100644
--- a/tirx/src/script/printer/doc_printer.cc
+++ b/tirx/src/script/printer/doc_printer.cc
@@ -22,10 +22,10 @@
#include <tvm/ffi/function.h>
#include <tvm/ffi/reflection/accessor.h>
#include <tvm/ffi/reflection/registry.h>
+#include <tvm/ffi/string.h>
#include <tvm/ir/object_functor.h>
#include <tvm/ir/prim/expr.h>
#include <tvm/script/printer/printer.h>
-#include <tvm/support/str_escape.h>
#include <algorithm>
#include <cmath>
@@ -113,6 +113,9 @@ class DocPrinter {
*/
void PrintDoc(const Doc& doc);
+ /*! \brief Render and quote an expression, preserving its diagnostic spans. */
+ void PrintExprString(const ExprDoc& doc);
+
/*!
* \brief Virtual method to print a LiteralDoc
*/
@@ -297,6 +300,9 @@ class DocPrinter {
private:
void MarkSpan(const ByteSpan& span, const AccessPath& path);
+ // Nested string expressions defer their spans until escaping establishes final offsets.
+ std::vector<std::pair<ByteSpan, AccessPath>>* pending_string_spans_{nullptr};
+
/*! \brief Options to customize certain aspects of the output */
PrinterConfig options_;
@@ -666,6 +672,10 @@ void DocPrinter::PrintDoc(const Doc& doc) {
}
void DocPrinter::MarkSpan(const ByteSpan& span, const AccessPath& path) {
+ if (pending_string_spans_ != nullptr) {
+ pending_string_spans_->emplace_back(span, path);
+ return;
+ }
int n = path_to_underline_.size();
for (int i = 0; i < n; ++i) {
AccessPath p = path_to_underline_[i];
@@ -683,81 +693,24 @@ void DocPrinter::MarkSpan(const ByteSpan& span, const AccessPath& path) {
namespace {
/*!
- * \brief Escape an ExprStringDoc child while preserving final output positions.
+ * \brief Buffer a complete expression before UTF-8-aware escaping.
*
- * ExprStringDoc must print its child through the active PythonDocPrinter so that the child's
- * precedence, printer configuration, and source-path bookkeeping stay in the current traversal.
- * However, escaping after printing into a temporary buffer would make PrintDoc record positions
- * in that unescaped buffer, rather than the final Python source. This scoped adapter instead
- * replaces the output stream's buffer only while the child is printed. It escapes each write and
- * forwards it immediately to the original final buffer; the caller emits the surrounding quotes
- * outside the scope so that only the child is transformed.
- *
- * The adapter owns neither the output stream nor its original buffer. Both outlive this stack
- * object. The constructor saves the original buffer in destination_ and installs this adapter;
- * the destructor restores the original buffer before the caller continues writing to the stream.
- *
- * PrintDoc uses tellp() before and after every child to record source spans. tellp() reaches
- * seekoff(0, cur, out), which is the only seek this adapter accepts and delegates directly to the
- * original buffer. Because that buffer already contains the preceding output and advances by the
- * escaped byte count, child spans use absolute positions in the final source, including any
- * expansion introduced by StrEscape.
- *
- * A raw newline violates the one-line expression-string contract. xsputn records its presence
- * while still escaping and forwarding the write, and the caller checks saw_newline() before
- * completing the literal. On every exit path, including exception unwinding, the noexcept
- * destructor restores the original buffer.
+ * Child tellp() positions refer to this buffer. PrintExprString translates the deferred
+ * source spans after escaping and restores the destination even if printing throws.
*/
-class ScopedExprStringEscapeBuf : public std::streambuf {
+class ScopedExprStringBuffer {
public:
- explicit ScopedExprStringEscapeBuf(std::ostream* output)
- : output_(output), destination_(output->rdbuf()) {
- output_->rdbuf(this);
- }
-
- ~ScopedExprStringEscapeBuf() noexcept { output_->rdbuf(destination_); }
-
- ScopedExprStringEscapeBuf(const ScopedExprStringEscapeBuf&) = delete;
- ScopedExprStringEscapeBuf& operator=(const ScopedExprStringEscapeBuf&) = delete;
-
- bool saw_newline() const { return saw_newline_; }
-
- protected:
- std::streamsize xsputn(const char* data, std::streamsize count) final {
- if (count <= 0) return 0;
- saw_newline_ = saw_newline_ || std::find(data, data + count, '\n') != data + count;
- // StrEscape is byte-wise, so each write can be transformed independently and forwarded
- // without retaining or copying the complete output. Report consumed input bytes, not the
- // potentially larger number of escaped bytes written to the destination.
- std::string escaped = support::StrEscape(data, static_cast<size_t>(count));
- destination_->sputn(escaped.data(), escaped.size());
- return count;
- }
-
- int_type overflow(int_type ch) final {
- if (traits_type::eq_int_type(ch, traits_type::eof())) {
- return traits_type::not_eof(ch);
- }
- char value = traits_type::to_char_type(ch);
- return xsputn(&value, 1) == 1 ? ch : traits_type::eof();
- }
-
- int sync() final { return destination_->pubsync(); }
-
- pos_type seekoff(off_type offset, std::ios_base::seekdir direction,
- std::ios_base::openmode mode) final {
- // Support the current-position query used by tellp(), preserving the destination's absolute
- // escaped offset. ExprStringDoc rendering never needs to reposition the output sequence.
- if (offset == 0 && direction == std::ios_base::cur && (mode & std::ios_base::out)) {
- return destination_->pubseekoff(offset, direction, mode);
- }
- return pos_type(off_type(-1));
- }
+ explicit ScopedExprStringBuffer(std::ostream* output)
+ : output_(output), destination_(output->rdbuf(&buffer_)) {}
+ ~ScopedExprStringBuffer() noexcept { output_->rdbuf(destination_); }
+ ScopedExprStringBuffer(const ScopedExprStringBuffer&) = delete;
+ ScopedExprStringBuffer& operator=(const ScopedExprStringBuffer&) = delete;
+ std::string str() const { return buffer_.str(); }
private:
+ std::stringbuf buffer_;
std::ostream* output_;
std::streambuf* destination_;
- bool saw_newline_{false};
};
ffi::String RenderInvisiblePathInfo(const ffi::String& script,
@@ -1088,6 +1041,41 @@ class PythonDocPrinter : public DocPrinter {
bool is_last_stmt_{false};
};
+void DocPrinter::PrintExprString(const ExprDoc& doc) {
+ size_t start_pos = output_.tellp();
+ std::vector<std::pair<ByteSpan, AccessPath>> spans;
+ auto* previous_spans = pending_string_spans_;
+ std::string text;
+ {
+ ScopedExprStringBuffer buffer(&output_);
+ pending_string_spans_ = &spans;
+ try {
+ PrintDoc(doc);
+ text = buffer.str();
+ } catch (...) {
+ pending_string_spans_ = previous_spans;
+ throw;
+ }
+ pending_string_spans_ = previous_spans;
+ }
+ TVM_FFI_ICHECK(text.find('\n') == std::string::npos)
+ << "An expression rendered inside a Python string literal must be one line";
+ output_ << ffi::EscapedStringPy(text);
+ // Prefix lengths include the opening quote and exclude the closing quote. Every source
+ // span ends at a Doc boundary, after the complete UTF-8 text for that child was printed.
+ std::map<size_t, size_t> offsets;
+ auto escaped_offset = [&](size_t offset) {
+ auto [it, inserted] = offsets.emplace(offset, 0);
+ if (inserted) {
+ it->second = start_pos + ffi::EscapedStringPy(text.substr(0, offset)).size() - 1;
+ }
+ return it->second;
+ };
+ for (const auto& [span, path] : spans) {
+ MarkSpan({escaped_offset(span.first), escaped_offset(span.second)}, path);
+ }
+}
+
void PythonDocPrinter::PrintTypedDoc(const LiteralDoc& doc) {
const ffi::Any& value = doc->value;
if (value == nullptr) {
@@ -1129,22 +1117,13 @@ void PythonDocPrinter::PrintTypedDoc(const LiteralDoc& doc) {
}
} else if (const auto opt_str = value.as<ffi::String>()) {
- output_ << "\"" << support::StrEscape((*opt_str).data(), (*opt_str).size()) << "\"";
+ output_ << ffi::EscapedStringPy(*opt_str);
} else {
TVM_FFI_THROW(TypeError) << "Unsupported literal value type: " << value.GetTypeKey();
}
}
-void PythonDocPrinter::PrintTypedDoc(const ExprStringDoc& doc) {
- this->output_ << '"';
- {
- ScopedExprStringEscapeBuf escaping_scope(&this->output_);
- this->PrintDoc(doc->value);
- TVM_FFI_ICHECK(!escaping_scope.saw_newline())
- << "An expression rendered inside a Python string literal must be one line";
- }
- this->output_ << '"';
-}
+void PythonDocPrinter::PrintTypedDoc(const ExprStringDoc& doc) { PrintExprString(doc->value); }
void PythonDocPrinter::PrintTypedDoc(const IdDoc& doc) { output_ << doc->name; }
diff --git a/tirx/src/script/printer/doc_translator.cc b/tirx/src/script/printer/doc_translator.cc
index cb3c48df17..cddaf50fe7 100644
--- a/tirx/src/script/printer/doc_translator.cc
+++ b/tirx/src/script/printer/doc_translator.cc
@@ -240,23 +240,6 @@ TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = ffi::reflection;
refl::ObjectDef<DocTranslatorObj>();
refl::EnsureTypeAttrColumn(tvm::script::printer::type_attr::kDocTranslate);
- refl::GlobalDef()
- .def("script.printer.DocTranslate",
- [](ffi::AnyView ir, ffi::Map<ffi::String, ffi::Any> extra_config) {
- return DocTranslate(ir, nullptr, std::move(extra_config));
- })
- .def_method("script.printer.Translate", &DocTranslatorObj::Translate)
- .def_method("script.printer.Emit", &DocTranslatorObj::Emit)
- .def_method("script.printer.VarGetOrAllocId", &DocTranslatorObj::VarGetOrAllocId)
- .def_method("script.printer.GetImplicitDefs", &DocTranslatorObj::GetImplicitDefs)
- .def_method("script.printer.AllocId", &DocTranslatorObj::AllocId)
- .def_method("script.printer.BeginVarScope", &DocTranslatorObj::BeginVarScope)
- .def_method("script.printer.EndVarScope", &DocTranslatorObj::EndVarScope)
- .def_method("script.printer.BeginDocScope", &DocTranslatorObj::BeginDocScope)
- .def_method("script.printer.EndDocScope", &DocTranslatorObj::EndDocScope)
- .def("script.printer.WithDocScope", [](const DocTranslator& d, const ffi::Function& fn) {
- return d->WithDocScope([&]() { fn(); });
- });
}
} // namespace printer
diff --git a/tirx/src/script/printer/printer.cc b/tirx/src/script/printer/printer.cc
index feeacc432c..2d4f2d3eba 100644
--- a/tirx/src/script/printer/printer.cc
+++ b/tirx/src/script/printer/printer.cc
@@ -364,7 +364,7 @@ ffi::String RenderScript(const ffi::ObjectRef& obj, const PrinterConfig& config)
for (size_t suffix = 1; used.count(loader); ++suffix)
loader = "tvm_tirx_" + std::to_string(suffix);
ffi::String json = ffi::json::Stringify(
- ffi::ToJSONGraph(metadata, ffi::json::Object{{"tvm_version", TVM_VERSION}}), 2);
+ ffi::ToJSONGraph(metadata, ffi::json::Object{{"tvm_tirx_version", TVM_TIRX_VERSION}}), 2);
block.value()->stmts.insert(block.value()->stmts.begin(),
AssignDoc(metadata_id.value(),
IdDoc(loader)
diff --git a/tirx/src/sym/analyzer.cc b/tirx/src/sym/analyzer.cc
index 89a4f8b2ce..4aa8144e63 100644
--- a/tirx/src/sym/analyzer.cc
+++ b/tirx/src/sym/analyzer.cc
@@ -354,14 +354,13 @@ TVM_FFI_STATIC_INIT_BLOCK() {
[](Analyzer analyzer, const PrimExpr& expr, int strength) {
return analyzer->CanProve(expr, static_cast<ProofStrength>(strength));
})
- .def("sym.EnterAllowUintAsIndex",
+ .def("sym.AnalyzerEnterAllowUintAsIndex",
[]() {
// With has a noexcept(false) destructor, so it cannot use make_shared.
auto ctx = std::shared_ptr<With<AllowUIntAsIndex>>(new With<AllowUIntAsIndex>());
return ffi::Function::FromPacked(
[ctx](ffi::PackedArgs, ffi::Any*) mutable { ctx.reset(); });
})
- .def("sym.GetAllowUintAsIndex", &AllowUIntAsIndex::Enabled)
.def("sym.AnalyzerSetMaximumRewriteSteps",
[](Analyzer analyzer, int64_t maximum) {
analyzer->rewrite_simplify.SetMaximumRewriteSteps(maximum);
diff --git a/tirx/src/sym/bound_deducer.cc b/tirx/src/sym/bound_deducer.cc
index 6afbeaca1e..29b35df3d1 100644
--- a/tirx/src/sym/bound_deducer.cc
+++ b/tirx/src/sym/bound_deducer.cc
@@ -29,7 +29,6 @@
#include <tvm/sym/analyzer.h>
#include <tvm/sym/bound.h>
-#include <unordered_map>
#include <unordered_set>
#include <vector>
@@ -82,9 +81,8 @@ class BoundDeducer : public tvm::ExprFunctor<void(const Expr&)> {
public:
friend class BoundDeduceInputChecker;
friend class Converter;
- BoundDeducer(PrimExpr target, PrimExpr expr,
- const std::unordered_map<const VarNode*, IntSet>& hint_map,
- const std::unordered_map<const VarNode*, IntSet>& relax_map)
+ BoundDeducer(PrimExpr target, PrimExpr expr, const ffi::Map<Var, IntSet>& hint_map,
+ const ffi::Map<Var, IntSet>& relax_map)
: target_(target), expr_(expr), hint_map_(hint_map), relax_map_(relax_map) {}
void Deduce();
@@ -228,8 +226,8 @@ class BoundDeducer : public tvm::ExprFunctor<void(const Expr&)> {
CompareOp ReverseOp(CompareOp comp_op);
PrimExpr target_;
PrimExpr expr_;
- const std::unordered_map<const VarNode*, IntSet>& hint_map_;
- const std::unordered_map<const VarNode*, IntSet>& relax_map_;
+ const ffi::Map<Var, IntSet>& hint_map_;
+ const ffi::Map<Var, IntSet>& relax_map_;
ExprIntSetMap expr_map_;
std::vector<const ffi::Object*> path_;
size_t iter_{0};
@@ -372,9 +370,8 @@ void BoundDeducer::Relax() {
result_ = (comp_op == kGreater) ? b.max() : b.min();
}
-IntSet DeduceBound(PrimExpr v, PrimExpr e,
- const std::unordered_map<const VarNode*, IntSet>& hint_map,
- const std::unordered_map<const VarNode*, IntSet>& relax_map) {
+IntSet DeduceBound(PrimExpr v, PrimExpr e, const ffi::Map<Var, IntSet>& hint_map,
+ const ffi::Map<Var, IntSet>& relax_map) {
BoundDeducer d(v, e, hint_map, relax_map);
d.Deduce();
if (!d.success_) return IntSet::Nothing();
@@ -390,26 +387,11 @@ IntSet DeduceBound(PrimExpr v, PrimExpr e,
return IntSet::Interval(min, max);
}
-// assuming e >= 0, deduce the bound of variable from it.
-// return empty set to represent deduce failure.
-IntSet DeduceBound(PrimExpr v, PrimExpr e, const ffi::Map<Var, IntSet>& hint_map,
- const ffi::Map<Var, IntSet>& relax_map) {
- std::unordered_map<const VarNode*, IntSet> hmap;
- for (auto kv : hint_map) {
- hmap.emplace(kv.first.get(), kv.second);
- }
- std::unordered_map<const VarNode*, IntSet> rmap;
- for (auto kv : relax_map) {
- rmap.emplace(kv.first.get(), kv.second);
- }
- return DeduceBound(v, e, hmap, rmap);
-}
-
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
refl::GlobalDef().def("sym.DeduceBound",
- [](PrimExpr v, PrimExpr cond, const ffi::Map<Var, IntSet> hint_map,
- const ffi::Map<Var, IntSet> relax_map) {
+ [](PrimExpr v, PrimExpr cond, const ffi::Map<Var, IntSet>& hint_map,
+ const ffi::Map<Var, IntSet>& relax_map) {
return DeduceBound(v, cond, hint_map, relax_map);
});
}
diff --git a/tirx/src/sym/int_set.cc b/tirx/src/sym/int_set.cc
index 44804a0c6e..2d5a7e5167 100644
--- a/tirx/src/sym/int_set.cc
+++ b/tirx/src/sym/int_set.cc
@@ -1027,14 +1027,6 @@ IntSet Intersect(const ffi::Array<IntSet>& sets) {
return IntervalSet(ana->Simplify(x->min_value), ana->Simplify(x->max_value));
}
-ffi::Map<Var, IntSet> ConvertDomMap(const std::unordered_map<const VarNode*, IntSet>& dom_map) {
- ffi::Map<Var, IntSet> dmap;
- for (auto kv : dom_map) {
- dmap.Set(ffi::GetRef<Var>(kv.first), kv.second);
- }
- return dmap;
-}
-
IntSet EvalSet(PrimExpr e, const ffi::Map<Var, IntSet>& dom_map) {
Analyzer ana;
return IntervalSetEvaluator(ana.get(), dom_map, {}, false).Eval(e);
@@ -1052,10 +1044,6 @@ IntSet IntSet::Vector(PrimExpr x) {
}
}
-IntSet EvalSet(PrimExpr e, const std::unordered_map<const VarNode*, IntSet>& dom_map) {
- return EvalSet(e, ConvertDomMap(dom_map));
-}
-
IntSet EvalSet(Range r, const ffi::Map<Var, IntSet>& dom_map) {
Analyzer ana;
PrimType min_ty = r->min.ty();
@@ -1070,10 +1058,6 @@ IntSet EvalSet(Range r, const ffi::Map<Var, IntSet>& dom_map) {
return res;
}
-IntSet EvalSet(Range r, const std::unordered_map<const VarNode*, IntSet>& dom_map) {
- return EvalSet(r, ConvertDomMap(dom_map));
-}
-
ffi::Array<IntSet> EvalSet(const ffi::Array<Range>& region, const ffi::Map<Var, IntSet>& dom_map) {
Analyzer ana;
IntervalSetEvaluator m(ana.get(), dom_map);
@@ -1086,10 +1070,9 @@ ffi::Array<IntSet> EvalSet(const ffi::Array<Range>& region, const ffi::Map<Var,
return result;
}
-IntSet EvalSet(IntSet s, const std::unordered_map<const VarNode*, IntSet>& dom_map) {
+IntSet EvalSet(IntSet s, const ffi::Map<Var, IntSet>& dom_map) {
Analyzer ana;
- auto dmap = ConvertDomMap(dom_map);
- IntervalSetEvaluator m(ana.get(), dmap);
+ IntervalSetEvaluator m(ana.get(), dom_map);
const IntervalSetObj* s_int = s.as<IntervalSetObj>();
PrimExpr vmax = s_int->HasUpperBound() ? m.Eval(s_int->max_value).max() : s_int->max_value;
PrimExpr vmin = s_int->HasLowerBound() ? m.Eval(s_int->min_value).min() : s_int->min_value;
@@ -1110,11 +1093,9 @@ class SubExprIntervalSetEvaluator : public IntervalSetEvaluator {
ExprIntSetMap expr_map;
};
-ExprIntSetMap EvalSetForEachSubExpr(PrimExpr e,
- const std::unordered_map<const VarNode*, IntSet>& dom_map) {
+ExprIntSetMap EvalSetForEachSubExpr(PrimExpr e, const ffi::Map<Var, IntSet>& dom_map) {
Analyzer ana;
- auto dmap = ConvertDomMap(dom_map);
- SubExprIntervalSetEvaluator m(ana.get(), dmap);
+ SubExprIntervalSetEvaluator m(ana.get(), dom_map);
m.Eval(e);
return m.expr_map;
}
@@ -1264,11 +1245,8 @@ ffi::Array<IntSet> EstimateRegionUpperBound(const ffi::Array<Range>& region,
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
refl::GlobalDef()
- .def("sym.intset_single_point", IntSet::SinglePoint)
- .def("sym.intset_vector", IntSet::Vector)
- .def("sym.intset_interval", IntSet::Interval)
- .def_method("sym.IntervalSetGetMin", &IntSet::min)
- .def_method("sym.IntervalSetGetMax", &IntSet::max)
+ .def("sym.IntSetSinglePoint", IntSet::SinglePoint)
+ .def("sym.IntSetVector", IntSet::Vector)
.def_method("sym.IntSetIsNothing", &IntSet::IsNothing)
.def_method("sym.IntSetIsEverything", &IntSet::IsEverything)
.def("sym.EstimateRegionLowerBound",
diff --git a/tirx/src/sym/iter_affine_map.cc b/tirx/src/sym/iter_affine_map.cc
index a398685ad9..8627bbf609 100644
--- a/tirx/src/sym/iter_affine_map.cc
+++ b/tirx/src/sym/iter_affine_map.cc
@@ -1615,8 +1615,8 @@ TVM_FFI_STATIC_INIT_BLOCK() {
refl::GlobalDef().def(
"sym.DetectIterMap",
[](const ffi::Array<PrimExpr>& indices, const ffi::Map<PrimVar, Range>& input_iters,
- const PrimExpr& input_pred, int check_level, bool simplify_trivial_iterators,
- ffi::Optional<Analyzer> opt_analyzer) {
+ const PrimExpr& input_pred, int check_level, ffi::Optional<Analyzer> opt_analyzer,
+ bool simplify_trivial_iterators) {
Analyzer ana = opt_analyzer.has_value() ? opt_analyzer.value() : Analyzer();
return DetectIterMap(indices, input_iters, input_pred, IterMapLevel(check_level), ana,
simplify_trivial_iterators);
@@ -2331,8 +2331,8 @@ TVM_FFI_STATIC_INIT_BLOCK() {
refl::GlobalDef().def(
"sym.IterMapSimplify",
[](const ffi::Array<PrimExpr>& indices, const ffi::Map<PrimVar, Range>& input_iters,
- const PrimExpr& input_pred, int check_level, bool simplify_trivial_iterators,
- ffi::Optional<Analyzer> opt_analyzer) {
+ const PrimExpr& input_pred, int check_level, ffi::Optional<Analyzer> opt_analyzer,
+ bool simplify_trivial_iterators) {
Analyzer ana = opt_analyzer.has_value() ? opt_analyzer.value() : Analyzer();
return IterMapSimplify(indices, input_iters, input_pred, IterMapLevel(check_level), ana,
simplify_trivial_iterators);
@@ -2677,7 +2677,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
"sym.SubspaceDivide",
[](const ffi::Array<PrimExpr>& bindings, const ffi::Map<PrimVar, Range>& root_iters,
const ffi::Array<PrimVar>& sub_iters, const PrimExpr& predicate, int check_level,
- bool simplify_trivial_iterators, ffi::Optional<Analyzer> opt_analyzer) {
+ ffi::Optional<Analyzer> opt_analyzer, bool simplify_trivial_iterators) {
Analyzer ana = opt_analyzer.has_value() ? opt_analyzer.value() : Analyzer();
return SubspaceDivide(bindings, root_iters, sub_iters, predicate, IterMapLevel(check_level),
ana, simplify_trivial_iterators);
diff --git a/tirx/src/target/target.cc b/tirx/src/target/target.cc
index 1505f7edff..e0fcabfa90 100644
--- a/tirx/src/target/target.cc
+++ b/tirx/src/target/target.cc
@@ -133,16 +133,6 @@ Target::Target(Target target, ffi::Optional<Target> host) {
data_ = std::move(n);
}
-Target::Target(TargetKind kind, ffi::Optional<ffi::ObjectRef> host, ffi::String tag,
- ffi::Array<ffi::String> keys, ffi::Map<ffi::String, ffi::Any> attrs) {
- auto data = ffi::make_object<TargetObj>(std::move(kind));
- data->host = std::move(host);
- data->tag = std::move(tag);
- data->keys = std::move(keys);
- data->attrs = std::move(attrs);
- data_ = std::move(data);
-}
-
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
TargetObj::RegisterReflection();
diff --git a/tirx/src/tirx/analysis/verify_memory.cc b/tirx/src/tirx/analysis/verify_memory.cc
index e98fbd4b00..6ccf246df4 100644
--- a/tirx/src/tirx/analysis/verify_memory.cc
+++ b/tirx/src/tirx/analysis/verify_memory.cc
@@ -209,7 +209,7 @@ bool VerifyMemory(const Function& func) { return VerifyMemory_(func).size() == 0
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("tirx.analysis.verify_memory", VerifyMemory);
+ refl::GlobalDef().def("tirx.analysis.VerifyMemory", VerifyMemory);
}
namespace transform {
diff --git a/tirx/src/tirx/ir/data_type_rewriter.h b/tirx/src/tirx/ir/data_type_rewriter.h
index afba09ee5f..76dc434a96 100644
--- a/tirx/src/tirx/ir/data_type_rewriter.h
+++ b/tirx/src/tirx/ir/data_type_rewriter.h
@@ -21,8 +21,8 @@
* \file data_type_rewriter.h
* \brief Rewrite the data type of expressions.
*/
-#ifndef TVM_TIR_IR_DATA_TYPE_REWRITER_H_
-#define TVM_TIR_IR_DATA_TYPE_REWRITER_H_
+#ifndef TVM_TIRX_IR_DATA_TYPE_REWRITER_H_
+#define TVM_TIRX_IR_DATA_TYPE_REWRITER_H_
#include <tvm/tirx/stmt_functor.h>
@@ -161,4 +161,4 @@ class IndexDataTypeNormalizer : public IndexDataTypeRewriter {
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_IR_DATA_TYPE_REWRITER_H_
+#endif // TVM_TIRX_IR_DATA_TYPE_REWRITER_H_
diff --git a/tirx/src/tirx/ir/index_map.cc b/tirx/src/tirx/ir/index_map.cc
index 28fb38565c..892d063bb9 100644
--- a/tirx/src/tirx/ir/index_map.cc
+++ b/tirx/src/tirx/ir/index_map.cc
@@ -252,9 +252,9 @@ ffi::Array<Range> IndexMapNode::MapRanges(const ffi::Array<Range>& ranges,
// For example, [N] mapped through i=>[i//4,i%4] should have shape
// [ceildiv(N,4), 4]. However, for N<4, this method instead
// results in a shape [1, N].
- std::unordered_map<const VarNode*, sym::IntSet> dom_map;
+ ffi::Map<Var, sym::IntSet> dom_map;
for (size_t i = 0; i < initial_indices.size(); i++) {
- dom_map.insert_or_assign(initial_indices[i].get(), sym::IntSet::FromRange(ranges[i]));
+ dom_map.Set(initial_indices[i], sym::IntSet::FromRange(ranges[i]));
}
for (const auto& final_index : final_indices) {
diff --git a/tirx/src/tirx/ir/ir_mutator_with_analyzer.cc b/tirx/src/tirx/ir/ir_mutator_with_analyzer.cc
index 870575226c..ffb8c7d708 100644
--- a/tirx/src/tirx/ir/ir_mutator_with_analyzer.cc
+++ b/tirx/src/tirx/ir/ir_mutator_with_analyzer.cc
@@ -227,7 +227,7 @@ UnchangedOr<Stmt> StmtExprMutatorWithAnalyzer::Mutate_(const RegionStmtNode* op,
}
// Native CUDA coordinates are ordinary calls. Their bounds come from the
// enclosing launch configuration, including when no variable binds them.
- if (auto description = op->attrs->dict.Get(tvm::backend::cuda::attr::kLaunchFields)) {
+ if (auto description = op->attrs->dict.Get(tvm::backend::cuda::attr::kLaunchFields.name)) {
auto fields = description->as_or_throw<ffi::Array<ffi::String>>();
for (size_t i = 0; i < fields.size(); ++i) {
std::string field(fields[i]);
diff --git a/tirx/src/tirx/op/region.cc b/tirx/src/tirx/op/region.cc
index 4c0878ddca..76e92f69de 100644
--- a/tirx/src/tirx/op/region.cc
+++ b/tirx/src/tirx/op/region.cc
@@ -60,6 +60,17 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.set_native_fn_attr<&ValidateBuiltinRegion>(tvm::op_attr::kRegionValidate);
}
+void ValidateDeviceScopeRegion(const RegionStmtNode* region) {
+ TVM_FFI_CHECK(region->result_vars.empty(), ValueError)
+ << region->op->name << " expects no results";
+}
+TVM_FFI_STATIC_INIT_BLOCK() {
+ OpDef("tirx.device_scope", "Internal host/device splitting boundary.")
+ .signature(sig::var_args<Expr>("launch_values"), sig::call_attrs<DictAttrsNode>())
+ .set_native_fn_attr<&RegionNoBodyParams>(tvm::op_attr::kRegionGetBodyParams)
+ .set_native_fn_attr<&ValidateDeviceScopeRegion>(tvm::op_attr::kRegionValidate);
+}
+
const Op& device_entry_op() {
static const Op op = Op::Get("tirx.device_entry");
return op;
@@ -68,7 +79,7 @@ const Op& device_entry_op() {
void ValidateDeviceEntry(const RegionStmtNode* region) {
TVM_FFI_CHECK(region->result_vars.empty() && region->body_params.empty(), ValueError)
<< "device_entry expects no results or body parameters";
- if (auto fields = region->attrs->dict.Get(tvm::backend::cuda::attr::kLaunchFields)) {
+ if (auto fields = region->attrs->dict.Get(tvm::backend::cuda::attr::kLaunchFields.name)) {
TVM_FFI_CHECK_EQ(fields->as_or_throw<ffi::Array<ffi::String>>().size(), region->args.size(),
ValueError)
<< "device_entry launch fields must describe every configuration operand";
diff --git a/tirx/src/tirx/script/ir_builder/ir.cc b/tirx/src/tirx/script/ir_builder/ir.cc
index 85d008ecce..98dd69a759 100644
--- a/tirx/src/tirx/script/ir_builder/ir.cc
+++ b/tirx/src/tirx/script/ir_builder/ir.cc
@@ -60,10 +60,11 @@ tvm::tirx::TensorType TensorTypeDecl(ffi::Array<PrimExpr> shape, PrimType dtype,
} // namespace
-FunctionFrame Function(bool is_private, bool persistent) {
+FunctionFrame Function(bool is_private, bool persistent, bool is_declaration) {
ffi::ObjectPtr<FunctionFrameObj> n = ffi::make_object<FunctionFrameObj>();
n->name = std::nullopt;
n->is_private = is_private;
+ n->is_declaration = is_declaration;
n->args.clear();
n->ret_type = std::nullopt;
n->attrs = {};
@@ -71,12 +72,6 @@ FunctionFrame Function(bool is_private, bool persistent) {
return FunctionFrame(n);
}
-FunctionFrame DeclFunction(bool is_private, bool persistent) {
- FunctionFrame frame = Function(is_private, persistent);
- frame->is_declaration = true;
- return frame;
-}
-
Var Arg(ffi::String name, Var var) {
FunctionFrame frame = FindFunctionFrame("T.Arg");
details::Namer::Name(var, name);
@@ -233,13 +228,13 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TVM_FFI_CHECK_GE(bytes, 0, ValueError);
const auto& frames = IRBuilder::Current()->frames;
for (auto it = frames.rbegin(); it != frames.rend(); ++it) {
- if (auto region = (*it).as<RegionFrame>();
+ if (auto region = (*it).as<ir::RegionFrame>();
region && region.value()->op->name == "tirx.device_entry") {
auto attrs = region.value()->attrs->dict;
- int64_t previous = attrs.Get(tvm::backend::cuda::attr::kSmemRequired)
+ int64_t previous = attrs.Get(tvm::backend::cuda::attr::kSmemRequired.name)
.value_or(int64_t{0})
.cast<int64_t>();
- attrs.Set(tvm::backend::cuda::attr::kSmemRequired, std::max(previous, bytes));
+ attrs.Set(tvm::backend::cuda::attr::kSmemRequired.name, std::max(previous, bytes));
region.value()->attrs = DictAttrs(attrs);
return;
}
@@ -248,7 +243,6 @@ TVM_FFI_STATIC_INIT_BLOCK() {
})
.def("script.ir_builder.tirx.TensorType", TensorTypeDecl)
.def("script.ir_builder.tirx.Function", Function)
- .def("script.ir_builder.tirx.DeclFunction", DeclFunction)
.def("script.ir_builder.tirx.Arg",
[](ffi::String name, ffi::ObjectRef obj) -> ffi::ObjectRef {
using namespace tvm::tirx;
@@ -266,132 +260,12 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.def("script.ir_builder.tirx.Ptr", Ptr);
}
-#define TVM_TMP_STR(x) #x
-
-#define TVM_FFI_REFL_DEF_GLOBAL_SIZE(Prefix, DType) \
- def(Prefix TVM_TMP_STR(8), DType##8) \
- .def(Prefix TVM_TMP_STR(16), DType##16) \
- .def(Prefix TVM_TMP_STR(32), DType##32) \
- .def(Prefix TVM_TMP_STR(64), DType##64)
-
-#define TVM_FFI_REFL_DEF_GLOBAL_LANES(Prefix, Func) \
- def(Prefix TVM_TMP_STR(x4), Func##x4) \
- .def(Prefix TVM_TMP_STR(x8), Func##x8) \
- .def(Prefix TVM_TMP_STR(x16), Func##x16) \
- .def(Prefix TVM_TMP_STR(x32), Func##x32) \
- .def(Prefix TVM_TMP_STR(x64), Func##x64)
-
-#define TVM_FFI_REFL_DEF_GLOBAL_SIZES_LANES(Prefix, DType) \
- TVM_FFI_REFL_DEF_GLOBAL_LANES(Prefix TVM_TMP_STR(8), DType##8) \
- .TVM_FFI_REFL_DEF_GLOBAL_LANES(Prefix TVM_TMP_STR(16), DType##16) \
- .TVM_FFI_REFL_DEF_GLOBAL_LANES(Prefix TVM_TMP_STR(32), DType##32) \
- .TVM_FFI_REFL_DEF_GLOBAL_LANES(Prefix TVM_TMP_STR(64), DType##64)
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.BFloat16", BFloat16)
- .TVM_FFI_REFL_DEF_GLOBAL_SIZE("script.ir_builder.tirx.Float", Float)
- .TVM_FFI_REFL_DEF_GLOBAL_SIZE("script.ir_builder.tirx.UInt", UInt)
- .TVM_FFI_REFL_DEF_GLOBAL_SIZE("script.ir_builder.tirx.Int", Int)
- .TVM_FFI_REFL_DEF_GLOBAL_SIZES_LANES("script.ir_builder.tirx.Float", Float)
- .TVM_FFI_REFL_DEF_GLOBAL_SIZES_LANES("script.ir_builder.tirx.UInt", UInt)
- .TVM_FFI_REFL_DEF_GLOBAL_SIZES_LANES("script.ir_builder.tirx.Int", Int)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.BFloat16", BFloat16);
-}
-
-// Float8 variants
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float8E3M4", Float8E3M4)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float8E3M4", Float8E3M4);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float8E4M3", Float8E4M3)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float8E4M3", Float8E4M3);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float8E4M3B11FNUZ", Float8E4M3B11FNUZ)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float8E4M3B11FNUZ", Float8E4M3B11FNUZ);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float8E4M3FN", Float8E4M3FN)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float8E4M3FN", Float8E4M3FN);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float8E4M3FNUZ", Float8E4M3FNUZ)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float8E4M3FNUZ", Float8E4M3FNUZ);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float8E5M2", Float8E5M2)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float8E5M2", Float8E5M2);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float8E5M2FNUZ", Float8E5M2FNUZ)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float8E5M2FNUZ", Float8E5M2FNUZ);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float8E8M0FNU", Float8E8M0FNU)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float8E8M0FNU", Float8E8M0FNU);
-}
-
-// Float6 variants
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float6E2M3FN", Float6E2M3FN)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float6E2M3FN", Float6E2M3FN);
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float6E3M2FN", Float6E3M2FN)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float6E3M2FN", Float6E3M2FN);
-}
-
-// Float4 variant
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("script.ir_builder.tirx.Float4E2M1FN", Float4E2M1FN)
- .TVM_FFI_REFL_DEF_GLOBAL_LANES("script.ir_builder.tirx.Float4E2M1FN", Float4E2M1FN);
-}
-
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
refl::GlobalDef()
- .def("script.ir_builder.tirx.Boolean", Boolean)
.def("script.ir_builder.tirx.Handle",
static_cast<Var (*)(ffi::Optional<PrimType>, runtime::MemoryScope)>(Handle))
- .def("script.ir_builder.tirx.TensorMap", TensorMap)
- .def("script.ir_builder.tirx.Void", Void)
- .def("script.ir_builder.tirx.min",
- [](PrimExpr a, PrimExpr b) -> PrimExpr { return tvm::min(a, b); })
- .def("script.ir_builder.tirx.max",
- [](PrimExpr a, PrimExpr b) -> PrimExpr { return tvm::max(a, b); });
+ .def("script.ir_builder.tirx.TensorMap", TensorMap);
}
} // namespace tirx
diff --git a/tirx/src/tirx/tile/lower.cc b/tirx/src/tirx/tile/lower.cc
index 6f8cfabc49..3e133d1525 100644
--- a/tirx/src/tirx/tile/lower.cc
+++ b/tirx/src/tirx/tile/lower.cc
@@ -242,7 +242,7 @@ class TileDispatcher : public StmtExprMutator {
launch_params_.clear();
cluster_bounds_.clear();
variable_cluster_ = false;
- native_launch_ = entry_node->attrs->dict.count(tvm::backend::cuda::attr::kLaunchFields);
+ native_launch_ = entry_node->attrs->dict.count(tvm::backend::cuda::attr::kLaunchFields.name);
TVM_FFI_CHECK(is_first_block || !native_launch_, ValueError)
<< "Nested CUDA device_entry regions are not supported";
if (native_launch_) PrepareCudaLaunchParams(entry_node);
@@ -533,7 +533,7 @@ class TileDispatcher : public StmtExprMutator {
void PrepareCudaLaunchParams(const RegionStmtNode* entry) {
TVM_FFI_CHECK(target_->kind->name == "cuda", ValueError)
<< "CUDA LaunchConfig requires a CUDA target";
- auto fields = entry->attrs->dict.at(tvm::backend::cuda::attr::kLaunchFields)
+ auto fields = entry->attrs->dict.at(tvm::backend::cuda::attr::kLaunchFields.name)
.as_or_throw<ffi::Array<ffi::String>>();
TVM_FFI_ICHECK_EQ(fields.size(), entry->args.size());
for (size_t i = 0; i < fields.size(); ++i) {
diff --git a/tirx/src/tirx/transform/dtype_conversion.h b/tirx/src/tirx/transform/dtype_conversion.h
index e33e9dbb3a..bde31635ff 100644
--- a/tirx/src/tirx/transform/dtype_conversion.h
+++ b/tirx/src/tirx/transform/dtype_conversion.h
@@ -21,8 +21,8 @@
* \file dtype_conversion.h
* \brief Header file of data type conversion routines.
*/
-#ifndef TVM_TIR_TRANSFORM_DTYPE_CONVERSION_H_
-#define TVM_TIR_TRANSFORM_DTYPE_CONVERSION_H_
+#ifndef TVM_TIRX_TRANSFORM_DTYPE_CONVERSION_H_
+#define TVM_TIRX_TRANSFORM_DTYPE_CONVERSION_H_
#include <tvm/ir/prim/op.h>
#include <tvm/tirx/stmt.h>
@@ -209,4 +209,4 @@ PrimExpr DTypeConversion(PrimExpr src_value, PrimType tgt_dtype,
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_TRANSFORM_DTYPE_CONVERSION_H_
+#endif // TVM_TIRX_TRANSFORM_DTYPE_CONVERSION_H_
diff --git a/tirx/src/tirx/transform/force_narrow_index_to_i32.cc b/tirx/src/tirx/transform/force_narrow_index_to_i32.cc
index f00dba975f..eeb9c5ba57 100644
--- a/tirx/src/tirx/transform/force_narrow_index_to_i32.cc
+++ b/tirx/src/tirx/transform/force_narrow_index_to_i32.cc
@@ -117,7 +117,7 @@ Pass ForceNarrowIndexToInt32() {
auto pass_func = [](Function f, IRModule m, PassContext ctx) {
return ForceNarrowIndexToInt32(f);
};
- return CreateFunctionPass(pass_func, 0, "tirx.NarrowDataType");
+ return CreateFunctionPass(pass_func, 0, "tirx.ForceNarrowIndexToInt32");
}
TVM_FFI_STATIC_INIT_BLOCK() {
diff --git a/tirx/src/tirx/transform/ir_utils.h b/tirx/src/tirx/transform/ir_utils.h
index 7a6680f86e..1a8dcfc269 100644
--- a/tirx/src/tirx/transform/ir_utils.h
+++ b/tirx/src/tirx/transform/ir_utils.h
@@ -21,8 +21,8 @@
* \file ir_utils.h
* \brief Helper functions to construct and compose IR nodes.
*/
-#ifndef TVM_TIR_TRANSFORM_IR_UTILS_H_
-#define TVM_TIR_TRANSFORM_IR_UTILS_H_
+#ifndef TVM_TIRX_TRANSFORM_IR_UTILS_H_
+#define TVM_TIRX_TRANSFORM_IR_UTILS_H_
#include <tvm/ir/function.h>
#include <tvm/ir/prim/expr.h>
@@ -69,4 +69,4 @@ Stmt ConvertSSA(Stmt stmt);
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_TRANSFORM_IR_UTILS_H_
+#endif // TVM_TIRX_TRANSFORM_IR_UTILS_H_
diff --git a/tirx/src/tirx/transform/remove_no_op.cc b/tirx/src/tirx/transform/remove_no_op.cc
index 641634b891..e693b3bfd4 100644
--- a/tirx/src/tirx/transform/remove_no_op.cc
+++ b/tirx/src/tirx/transform/remove_no_op.cc
@@ -33,8 +33,6 @@
#include <tvm/tirx/stmt_functor_with_analyzer.h>
#include <tvm/tirx/transform.h>
-#include <unordered_map>
-
#include "../../sym/const_fold.h"
#include "ir_utils.h"
@@ -125,10 +123,9 @@ class NoOpRemover : public StmtExprMutatorWithAnalyzer {
analyzer_->CanProve(extent_range.max() <= 0)) {
return Evaluate(0);
}
- var_range_map_.insert_or_assign(op->loop_var.get(),
- sym::IntSet::FromMinExtent(op->min, op->extent));
+ var_range_map_.Set(op->loop_var, sym::IntSet::FromMinExtent(op->min, op->extent));
Stmt stmt = Parent::Mutate_(op, inplace_mode).ValueOrUnchanged(ffi::GetRef<Stmt>(op));
- var_range_map_.erase(op->loop_var.get());
+ var_range_map_.erase(op->loop_var);
op = stmt.as<ForNode>();
if (IsZero(op->extent)) {
return Evaluate(0);
@@ -240,7 +237,7 @@ class NoOpRemover : public StmtExprMutatorWithAnalyzer {
return SeqStmt(stmts);
}
- std::unordered_map<const VarNode*, sym::IntSet> var_range_map_;
+ ffi::Map<Var, sym::IntSet> var_range_map_;
bool ignore_profiler_call_{false};
};
diff --git a/tirx/src/tirx/transform/remove_no_op.h b/tirx/src/tirx/transform/remove_no_op.h
index 7022d3be28..9cd114bea2 100644
--- a/tirx/src/tirx/transform/remove_no_op.h
+++ b/tirx/src/tirx/transform/remove_no_op.h
@@ -21,8 +21,8 @@
* \file remove_no_op.h
* \brief Helper functions to construct and compose IR nodes.
*/
-#ifndef TVM_TIR_TRANSFORM_REMOVE_NO_OP_H_
-#define TVM_TIR_TRANSFORM_REMOVE_NO_OP_H_
+#ifndef TVM_TIRX_TRANSFORM_REMOVE_NO_OP_H_
+#define TVM_TIRX_TRANSFORM_REMOVE_NO_OP_H_
#include <tvm/sym/analyzer.h>
#include <tvm/tirx/stmt.h>
@@ -45,4 +45,4 @@ Stmt RemoveNoOp(Stmt stmt, const sym::Analyzer& analyzer, bool ignore_profiler_c
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_TRANSFORM_REMOVE_NO_OP_H_
+#endif // TVM_TIRX_TRANSFORM_REMOVE_NO_OP_H_
diff --git a/tirx/src/tirx/transform/split_host_device.cc b/tirx/src/tirx/transform/split_host_device.cc
index 34b63e1102..2842f695e4 100644
--- a/tirx/src/tirx/transform/split_host_device.cc
+++ b/tirx/src/tirx/transform/split_host_device.cc
@@ -53,22 +53,6 @@
namespace tvm {
namespace tirx {
-namespace {
-static ffi::Array<Var> RegionNoBodyParams(const CallNode*) { return {}; }
-
-void ValidateDeviceScopeRegion(const RegionStmtNode* region) {
- TVM_FFI_CHECK(region->result_vars.empty(), ValueError)
- << region->op->name << " expects no results";
-}
-} // namespace
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- OpDef("tirx.device_scope", "Internal host/device splitting boundary.")
- .signature(sig::var_args<Expr>("launch_values"), sig::call_attrs<DictAttrsNode>())
- .set_native_fn_attr<&RegionNoBodyParams>(tvm::op_attr::kRegionGetBodyParams)
- .set_native_fn_attr<&ValidateDeviceScopeRegion>(tvm::op_attr::kRegionValidate);
-}
-
// Device-region annotation
class DeviceRegionAnnotater : public StmtExprMutator {
@@ -275,7 +259,7 @@ class HostDeviceSplitter : public StmtExprMutator {
device_func = WithAttr(std::move(device_func), tvm::attr::kNumInputs, num_inputs);
}
GlobalVar kernel_symbol_global = var_supply_();
- if (region->attrs->dict.count(tvm::backend::cuda::attr::kLaunchFields)) {
+ if (region->attrs->dict.count(tvm::backend::cuda::attr::kLaunchFields.name)) {
Stmt launch = MakeCudaKernelLaunch(kernel_symbol_global, &device_func, call_args, region);
(*device_mod_)->Add(kernel_symbol_global, device_func);
return launch;
@@ -588,15 +572,15 @@ class GlobalVarCallCollector : public StmtExprVisitor {
Stmt MakeCudaKernelLaunch(const GlobalVar& symbol, Function* func, ffi::Array<Expr> args,
const RegionStmtNode* region) {
- auto fields = region->attrs->dict.at(tvm::backend::cuda::attr::kLaunchFields)
+ auto fields = region->attrs->dict.at(tvm::backend::cuda::attr::kLaunchFields.name)
.as_or_throw<ffi::Array<ffi::String>>();
ffi::Array<Expr> values = region->args;
- auto kernel_attrs = region->attrs->dict.at(tvm::backend::cuda::attr::kKernelAttrs)
+ auto kernel_attrs = region->attrs->dict.at(tvm::backend::cuda::attr::kKernelAttrs.name)
.as_or_throw<ffi::Map<ffi::String, int64_t>>();
auto info = DeviceInfoCollector::Collect(symbol, *func, true);
ffi::Array<Stmt> host_stmts;
auto required_bytes = info.dynamic_smem_requirement;
- if (auto pool_bytes = region->attrs->dict.Get(tvm::backend::cuda::attr::kSmemRequired)) {
+ if (auto pool_bytes = region->attrs->dict.Get(tvm::backend::cuda::attr::kSmemRequired.name)) {
PrimExpr pool = IntImm::Int64(pool_bytes->cast<int64_t>());
required_bytes = required_bytes ? prim::Max(required_bytes.value(), pool) : pool;
}
@@ -609,7 +593,7 @@ Stmt MakeCudaKernelLaunch(const GlobalVar& symbol, Function* func, ffi::Array<Ex
}
if (index < 0) {
TVM_FFI_CHECK(!prim::IsZero(bytes) ||
- region->attrs->dict.count(tvm::backend::cuda::attr::kSmemRequired),
+ region->attrs->dict.count(tvm::backend::cuda::attr::kSmemRequired.name),
ValueError)
<< "A shared.dyn placeholder requires LaunchConfig.dynamic_smem_bytes or "
"SMEMPool.commit()";
@@ -647,9 +631,9 @@ Stmt MakeCudaKernelLaunch(const GlobalVar& symbol, Function* func, ffi::Array<Ex
*func =
WithAttrs(std::move(*func), {{tvm::attr::kCallingConv, tvm::CallingConv::kDeviceKernelLaunch},
{tvm::attr::kGlobalSymbol, symbol->name_hint},
- {tvm::backend::cuda::attr::kLaunchFields, fields},
- {tvm::backend::cuda::attr::kKernelAttrs, kernel_attrs},
- {tvm::backend::cuda::attr::kLaunchDimensions, dimensions}});
+ {tvm::backend::cuda::attr::kLaunchFields.name, fields},
+ {tvm::backend::cuda::attr::kKernelAttrs.name, kernel_attrs},
+ {tvm::backend::cuda::attr::kLaunchDimensions.name, dimensions}});
auto attrs = ffi::make_object<CallFFIKernelAttr>();
attrs->launch_fields = fields;
attrs->kernel_attrs = kernel_attrs;
diff --git a/tirx/src/tirx/transform/tvm_ffi_binder.h b/tirx/src/tirx/transform/tvm_ffi_binder.h
index 7a5b9f02d8..46f323f8b1 100644
--- a/tirx/src/tirx/transform/tvm_ffi_binder.h
+++ b/tirx/src/tirx/transform/tvm_ffi_binder.h
@@ -25,8 +25,8 @@
* packed function arguments. The caller (make_packed_api.cc) creates
* an TVMFFIABIBuilder and calls DecodeParam(i) for each parameter.
*/
-#ifndef TVM_TIR_TRANSFORM_TVM_FFI_BINDER_H_
-#define TVM_TIR_TRANSFORM_TVM_FFI_BINDER_H_
+#ifndef TVM_TIRX_TRANSFORM_TVM_FFI_BINDER_H_
+#define TVM_TIRX_TRANSFORM_TVM_FFI_BINDER_H_
#include <tvm/ffi/reflection/access_path.h>
#include <tvm/ir/prim/expr.h>
@@ -421,4 +421,4 @@ class TVMFFIABIBuilder {
} // namespace tirx
} // namespace tvm
-#endif // TVM_TIR_TRANSFORM_TVM_FFI_BINDER_H_
+#endif // TVM_TIRX_TRANSFORM_TVM_FFI_BINDER_H_
diff --git a/tirx/tests/cpp/runtime/backend_workspace_test.cc b/tirx/tests/cpp/runtime/backend_workspace_test.cc
new file mode 100644
index 0000000000..3f6284e14c
--- /dev/null
+++ b/tirx/tests/cpp/runtime/backend_workspace_test.cc
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <tvm/ffi/error.h>
+#include <tvm/runtime/c_backend_api.h>
+
+namespace tvm {
+namespace runtime {
+namespace {
+
+// A device type with no registered device API in this test binary.
+constexpr int kUnavailableDeviceType = kDLHexagon;
+
+} // namespace
+
+TEST(BackendWorkspace, AllocAndFreeOnCPU) {
+ void* ptr = TVMBackendAllocWorkspace(kDLCPU, 0, 64, kDLFloat, 32);
+ ASSERT_NE(ptr, nullptr);
+ EXPECT_EQ(TVMBackendFreeWorkspace(kDLCPU, 0, ptr), 0);
+}
+
+TEST(BackendWorkspace, AllocFailureIsReportedThroughCAPI) {
+ void* ptr = TVMBackendAllocWorkspace(kUnavailableDeviceType, 0, 64, kDLFloat, 32);
+ EXPECT_EQ(ptr, nullptr);
+ ffi::Error error = ffi::details::MoveFromSafeCallRaised();
+ EXPECT_FALSE(error.message().empty());
+}
+
+TEST(BackendWorkspace, FreeFailureIsReportedThroughCAPI) {
+ int dummy = 0;
+ EXPECT_EQ(TVMBackendFreeWorkspace(kUnavailableDeviceType, 0, &dummy), -1);
+ ffi::Error error = ffi::details::MoveFromSafeCallRaised();
+ EXPECT_FALSE(error.message().empty());
+}
+
+} // namespace runtime
+} // namespace tvm
diff --git a/tirx/tests/cpp/runtime/tensor_io_test.cc b/tirx/tests/cpp/runtime/tensor_io_test.cc
new file mode 100644
index 0000000000..bdbcd5bacc
--- /dev/null
+++ b/tirx/tests/cpp/runtime/tensor_io_test.cc
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <tvm/ffi/extra/serialization.h>
+#include <tvm/ffi/reflection/accessor.h>
+#include <tvm/runtime/tensor.h>
+#include <tvm/support/bytes_io.h>
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+namespace tvm {
+namespace runtime {
+namespace {
+
+std::string Save(const ffi::Tensor& tensor) {
+ std::string buffer;
+ support::BytesOutStream strm(&buffer);
+ SaveTensor(tensor, &strm);
+ return buffer;
+}
+
+ffi::Tensor Load(const std::string& buffer) {
+ support::BytesInStream strm(buffer);
+ return LoadTensor(&strm);
+}
+
+void ExpectRoundTrip(DLDataType dtype, std::vector<int64_t> shape) {
+ ffi::Tensor tensor = Empty(ffi::Shape(shape), dtype, Device{kDLCPU, 0});
+ size_t nbytes = ffi::GetDataSize(*tensor.GetDLTensorPtr());
+ auto* data = static_cast<uint8_t*>(tensor.GetDLTensorPtr()->data);
+ for (size_t i = 0; i < nbytes; ++i) data[i] = static_cast<uint8_t>(i * 7 + 1);
+
+ ffi::Tensor loaded = Load(Save(tensor));
+ const DLTensor* out = loaded.GetDLTensorPtr();
+ EXPECT_EQ(out->dtype, dtype);
+ ASSERT_EQ(out->ndim, static_cast<int>(shape.size()));
+ for (size_t i = 0; i < shape.size(); ++i) EXPECT_EQ(out->shape[i], shape[i]);
+ ASSERT_EQ(ffi::GetDataSize(*out), nbytes);
+ EXPECT_EQ(std::memcmp(out->data, data, nbytes), 0);
+}
+
+} // namespace
+
+TEST(TensorIO, RoundTripScalarDType) { ExpectRoundTrip(DLDataType{kDLFloat, 32, 1}, {2, 3}); }
+
+TEST(TensorIO, RoundTripVectorLanes) { ExpectRoundTrip(DLDataType{kDLFloat, 32, 4}, {5}); }
+
+TEST(TensorIO, RoundTripSubByteDType) { ExpectRoundTrip(DLDataType{kDLInt, 4, 1}, {6}); }
+
+TEST(TensorIO, JsonPreservesBase64Payload) {
+ // Golden payloads from the stream encoding, covering both padding sizes and no padding.
+ const char* expected[] = {
+ "P6G0lvBAXt0AAAAAAAAAAAEAAAAAAAAAAQAAAAEIAQABAAAAAAAAAAEAAAAAAAAAAA==",
+ "P6G0lvBAXt0AAAAAAAAAAAEAAAAAAAAAAQAAAAEIAQACAAAAAAAAAAIAAAAAAAAAAIA=",
+ "P6G0lvBAXt0AAAAAAAAAAAEAAAAAAAAAAQAAAAEIAQADAAAAAAAAAAMAAAAAAAAAAID/",
+
+ };
+ auto to_json = ffi::reflection::TypeAttrColumn(
+ ffi::type_attr::kDataToJson)[ffi::TensorObj::RuntimeTypeIndex()]
+ .cast<ffi::Function>();
+ auto from_json = ffi::reflection::TypeAttrColumn(
+ ffi::type_attr::kDataFromJson)[ffi::TensorObj::RuntimeTypeIndex()]
+ .cast<ffi::Function>();
+ const uint8_t data[] = {0, 128, 255};
+ for (int64_t size = 1; size <= 3; ++size) {
+ ffi::Tensor tensor = Empty(ffi::Shape({size}), DLDataType{kDLUInt, 8, 1}, Device{kDLCPU, 0});
+ std::memcpy(tensor.GetDLTensorPtr()->data, data, size);
+ ffi::String encoded = to_json(tensor).cast<ffi::String>();
+ EXPECT_EQ(encoded, expected[size - 1]);
+ auto loaded = from_json(encoded).cast<ffi::Tensor>();
+ EXPECT_EQ(loaded.dtype(), tensor.dtype());
+ ASSERT_EQ(loaded.shape()[0], size);
+ EXPECT_EQ(std::memcmp(loaded.GetDLTensorPtr()->data, data, size), 0);
+ }
+}
+
+TEST(TensorIO, RejectsTruncatedData) {
+ ffi::Tensor tensor = Empty(ffi::Shape({4}), DLDataType{kDLInt, 32, 1}, Device{kDLCPU, 0});
+ std::memset(tensor.GetDLTensorPtr()->data, 0, ffi::GetDataSize(*tensor.GetDLTensorPtr()));
+ std::string buffer = Save(tensor);
+ buffer.pop_back();
+ EXPECT_THROW(Load(buffer), ffi::Error);
+}
+
+} // namespace runtime
+} // namespace tvm
diff --git a/tirx/tests/cpp/script/string_escape_test.cc b/tirx/tests/cpp/script/string_escape_test.cc
new file mode 100644
index 0000000000..16f301a650
--- /dev/null
+++ b/tirx/tests/cpp/script/string_escape_test.cc
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <tvm/ffi/function.h>
+#include <tvm/script/printer/config.h>
+#include <tvm/script/printer/doc.h>
+
+namespace tvm {
+namespace script {
+namespace printer {
+namespace {
+
+ffi::String Render(const Doc& doc, const PrinterConfig& config = PrinterConfig()) {
+ return (*ffi::Function::GetGlobal("script.printer.DocToPythonScript"))(doc, config)
+ .cast<ffi::String>();
+}
+
+TEST(StringEscape, UnicodeExpressionAndNestedQuotes) {
+ EXPECT_EQ(Render(ExprStringDoc(IdDoc("é中😀"), std::nullopt)), "\"\\u00e9\\u4e2d\\U0001f600\"");
+ ExprStringDoc inner(IdDoc("é"), std::nullopt);
+ EXPECT_EQ(Render(ExprStringDoc(inner, std::nullopt)), "\"\\\"\\\\u00e9\\\"\"");
+}
+
+TEST(StringEscape, ExpressionUnderlineUsesEscapedOffsets) {
+ auto path = AccessPath::Root()->Attr("value");
+ IdDoc value("é中");
+ value->source_paths.push_back(path);
+ ExprStringDoc quoted(ListDoc({IdDoc("prefix"), value}), std::nullopt);
+ PrinterConfig config(
+ {{"path_to_underline", ffi::Array<AccessPath>{path}}, {"render_invisible_path_info", false}});
+ EXPECT_EQ(Render(quoted, config), "\"[prefix, \\u00e9\\u4e2d]\"\n ^^^^^^^^^^^^");
+}
+
+TEST(StringEscape, NestedExpressionUnderlineUsesEscapedOffsets) {
+ auto path = AccessPath::Root()->Attr("value");
+ IdDoc value("é");
+ value->source_paths.push_back(path);
+ ExprStringDoc inner(value, std::nullopt);
+ ExprStringDoc outer(inner, std::nullopt);
+ PrinterConfig config(
+ {{"path_to_underline", ffi::Array<AccessPath>{path}}, {"render_invisible_path_info", false}});
+ EXPECT_EQ(Render(outer, config), "\"\\\"\\\\u00e9\\\"\"\n ^^^^^^^");
+}
+
+} // namespace
+} // namespace printer
+} // namespace script
+} // namespace tvm
diff --git a/tirx/tests/cpp/sym/domain_map_test.cc b/tirx/tests/cpp/sym/domain_map_test.cc
new file mode 100644
index 0000000000..bf2c8ec451
--- /dev/null
+++ b/tirx/tests/cpp/sym/domain_map_test.cc
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <tvm/ir/prim/op.h>
+#include <tvm/sym/analyzer.h>
+#include <tvm/sym/bound.h>
+#include <tvm/sym/int_set.h>
+
+namespace tvm {
+namespace sym {
+namespace {
+
+void ExpectInterval(const IntSet& result, int min, int max) {
+ Analyzer analyzer;
+ EXPECT_TRUE(analyzer->CanProveEqual(result.min(), min));
+ EXPECT_TRUE(analyzer->CanProveEqual(result.max(), max));
+}
+
+TEST(DomainMap, EvalSetOverloads) {
+ PrimVar x("x");
+ const ffi::Map<Var, IntSet> domains{{x, IntSet::Interval(2, 5)}};
+ PrimExpr expr = x + 1;
+ Range range = Range::FromMinExtent(x, 3);
+ ExpectInterval(EvalSet(expr, domains), 3, 6);
+ ExpectInterval(EvalSet(IntSet::Interval(x, x + 2), domains), 2, 7);
+ ExpectInterval(EvalSet(range, domains), 2, 7);
+ auto region = EvalSet(ffi::Array<Range>{range}, domains);
+ ASSERT_EQ(region.size(), 1);
+ ExpectInterval(region[0], 2, 7);
+ auto subexpressions = EvalSetForEachSubExpr(expr, domains);
+ ExpectInterval(subexpressions.at(expr), 3, 6);
+ ExpectInterval(subexpressions.at(x), 2, 5);
+ ExpectInterval(domains.at(x), 2, 5);
+}
+
+TEST(DomainMap, DeduceBoundWithRelaxation) {
+ PrimVar x("x"), y("y");
+ const ffi::Map<Var, IntSet> hints{{y, IntSet::Interval(2, 5)}};
+ const ffi::Map<Var, IntSet> relaxed{{y, IntSet::Interval(2, 5)}};
+ auto bound = DeduceBound(x, x + y < 10, hints, relaxed);
+ Analyzer analyzer;
+ EXPECT_TRUE(analyzer->CanProveEqual(bound.max(), 4));
+ ExpectInterval(hints.at(y), 2, 5);
+ ExpectInterval(relaxed.at(y), 2, 5);
+}
+
+} // namespace
+} // namespace sym
+} // namespace tvm
diff --git a/tirx/tests/python/backend/cuda/codegen/test_basic.py b/tirx/tests/python/backend/cuda/codegen/test_basic.py
index 2e3323961b..6701fb1a39 100644
--- a/tirx/tests/python/backend/cuda/codegen/test_basic.py
+++ b/tirx/tests/python/backend/cuda/codegen/test_basic.py
@@ -117,7 +117,7 @@ def test_cuda_bf16_vectorize_add(*, backend_config):
def check_cuda(n, lanes):
vec_dtype = f"bfloat16x{lanes}"
num_blocks = n // num_thread
- one = tvm_tirx.tirx.Broadcast(tvm_tirx.tirx.const(1, "bfloat16"), lanes)
+ one = tvm_tirx.ir.prim.vector_expr.Broadcast(tvm_tirx.tirx.const(1, "bfloat16"), lanes)
@I.ir_module
class Module:
diff --git a/tirx/tests/python/backend/vulkan/codegen/test_basic.py b/tirx/tests/python/backend/vulkan/codegen/test_basic.py
index c1ca392ff3..e823a2b2b7 100644
--- a/tirx/tests/python/backend/vulkan/codegen/test_basic.py
+++ b/tirx/tests/python/backend/vulkan/codegen/test_basic.py
@@ -343,7 +343,7 @@ def test_vectorized_index_ramp():
"""Test vectorized copy with ramp indices (load N values, write to N locations)"""
target = {"kind": "vulkan", "from_device": 0}
n = 4
- ramp_index = tvm_tirx.tirx.Ramp(0, 1, 4)
+ ramp_index = tvm_tirx.ir.prim.vector_expr.Ramp(0, 1, 4)
@I.ir_module
class Module:
@@ -381,8 +381,8 @@ def test_vectorized_index_broadcast():
"""Test broadcast index (load 1 value, write to N locations)"""
target = {"kind": "vulkan", "from_device": 0}
n = 4
- broadcast_index = tvm_tirx.tirx.Broadcast(0, 4)
- ramp_index = tvm_tirx.tirx.Ramp(0, 1, 4)
+ broadcast_index = tvm_tirx.ir.prim.vector_expr.Broadcast(0, 4)
+ ramp_index = tvm_tirx.ir.prim.vector_expr.Ramp(0, 1, 4)
@I.ir_module
class Module:
diff --git a/tirx/tests/python/codegen/c/test_basic.py b/tirx/tests/python/codegen/c/test_basic.py
index 027bf312ae..28349fb7d9 100644
--- a/tirx/tests/python/codegen/c/test_basic.py
+++ b/tirx/tests/python/codegen/c/test_basic.py
@@ -259,7 +259,7 @@ def test_local_alloc_buffer_uses_plain_c_pointer():
def test_vector_pointer_uses_byte_offset():
buffer = tvm_tirx.tirx.decl_tensor((8,), "float32x2", name="A")
pointer = tvm_tirx.tirx.ptr_byte_offset(buffer.data, 16, ty=buffer.data.ty)
- body = tvm_tirx.ir.Evaluate(tvm_tirx.tirx.call_extern("void", "consume", pointer))
+ body = tvm_tirx.ir.Evaluate(tvm_tirx.tirx.call_extern("consume", pointer, ty="void"))
func = tvm_tirx.tirx.Function([buffer], body).with_attr("global_symbol", "main")
source = tvm_tirx.tirx.compile(
diff --git a/tirx/tests/python/ir/test_attrs.py b/tirx/tests/python/ir/test_attrs.py
index 306341427a..10ffba2095 100644
--- a/tirx/tests/python/ir/test_attrs.py
+++ b/tirx/tests/python/ir/test_attrs.py
@@ -24,6 +24,7 @@ import tvm_tirx
def test_dict_attrs():
dattr = tvm_tirx.ir.make_node("ir.DictAttrs", x=1, y=10, name="xyz", padding=(0, 0))
assert dattr.x == 1
+ assert dattr.dict["x"] == 1
datrr = tvm_tirx.ir.load_json(tvm_tirx.ir.save_json(dattr))
assert dattr.name == "xyz"
assert isinstance(dattr, tvm_tirx.ir.DictAttrs)
@@ -34,6 +35,19 @@ def test_dict_attrs():
assert len(dattr.items()) == 4
+def test_dict_attrs_dictionary_entry():
+ attrs = tvm_tirx.ir.make_node(
+ "ir.DictAttrs", dict={"nested": 1}, label="entry", type_key="metadata"
+ )
+ assert set(attrs.keys()) == {"dict", "label", "type_key"}
+ assert attrs["dict"]["nested"] == 1
+ assert attrs["label"] == "entry"
+ assert attrs["type_key"] == "metadata"
+ module = tvm_tirx.IRModule(attrs={"type_key": "metadata"})
+ assert module.attrs["type_key"] == "metadata"
+ assert len(tvm_tirx.ir.make_node("ir.DictAttrs")) == 0
+
+
def test_attrs_equal():
dattr0 = tvm_tirx.ir.make_node("ir.DictAttrs", x=1, y=[10, 20])
dattr1 = tvm_tirx.ir.make_node("ir.DictAttrs", y=[10, 20], x=1)
@@ -115,6 +129,21 @@ def test_op_set_signature_checks_counts_without_types_or_attrs():
assert call.attrs is not None
+def test_generated_op_api_constructs_dictionary_attrs():
+ name = "test.python_dict_attrs_api"
+ tvm_tirx.ir._ffi_api.RegisterOp(name, "Dictionary attribute API test")
+ op = tvm_tirx.ir.Op.get(name)
+ op.set_signature(args=[])
+ op.set_attrs_type_key("ir.DictAttrs")
+ tvm_tirx.ir.register_op_attr(name, "TFixedReturnType", tvm_tirx.ir.PrimType("int32"))
+ api = tvm_tirx.ir.op._make_op_api(op, __name__)
+ assert len(api().attrs) == 0
+ call = api(label="preserved", axis=2)
+ assert call.attrs["label"] == "preserved"
+ assert call.attrs["axis"] == 2
+ assert call.ty == tvm_tirx.ir.PrimType("int32")
+
+
if __name__ == "__main__":
test_dict_attrs()
test_attrs_equal()
diff --git a/tirx/tests/python/ir/test_expr_layout.py b/tirx/tests/python/ir/test_expr_layout.py
new file mode 100644
index 0000000000..ef40a8e3f3
--- /dev/null
+++ b/tirx/tests/python/ir/test_expr_layout.py
@@ -0,0 +1,80 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""Shared expression modules and call effect values."""
+
+import importlib
+
+import tvm_ffi
+
+from tvm_tirx import ir
+from tvm_tirx.ir import CallEffectKind, FloatImm, IntImm
+from tvm_tirx.ir.prim.vector_expr import Broadcast, Ramp, Shuffle
+from tvm_tirx.ir.unique_name_supply import UniqueNameSupply
+
+
+def test_scalar_expression_constructors():
+ integer = IntImm(ir.PrimType("int32"), 3)
+ floating = FloatImm(ir.PrimType("float32"), 2.5)
+ assert int(integer) == 3
+ assert bool(integer)
+ assert not bool(IntImm("int32", 0))
+ assert bool(integer == 3)
+ assert bool(integer != 4)
+ assert float(floating) == 2.5
+ for value in (integer, floating):
+ assert type(ir.load_json(ir.save_json(value))) is type(value)
+
+
+def test_vector_expression_constructors():
+ ramp = Ramp(0, 1, 4)
+ broadcast = Broadcast(3, 4)
+ shuffled = Shuffle([ramp, broadcast], [0, 5, 2, 7])
+ for value in (ramp, broadcast, shuffled):
+ restored = ir.load_json(ir.save_json(value))
+ assert type(restored) is type(value)
+ assert tvm_ffi.structural_equal(restored, value)
+
+
+def test_expression_module_locations():
+ assert ir.IntImm is IntImm
+ assert ir.FloatImm is FloatImm
+ assert ir.CallEffectKind is CallEffectKind
+ assert IntImm.__module__ == FloatImm.__module__ == "tvm_tirx.ir.expr"
+ for cls in (Ramp, Broadcast, Shuffle):
+ assert cls.__module__ == "tvm_tirx.ir.prim.vector_expr"
+ assert UniqueNameSupply.__module__ == "tvm_tirx.ir.unique_name_supply"
+ for module_name in ("tvm_tirx.ir.prim.expr", "tvm_tirx.tirx.expr", "tvm_tirx.tirx"):
+ module = importlib.import_module(module_name)
+ for name in ("IntImm", "FloatImm", "Ramp", "Broadcast", "Shuffle", "CallEffectKind"):
+ assert not hasattr(module, name)
+
+
+def test_call_effect_kind_values_and_ffi_conversion():
+ assert {kind.name: kind.value for kind in CallEffectKind} == {
+ "ExprAnnotation": 0,
+ "Pure": 1,
+ "ReadState": 2,
+ "UpdateState": 3,
+ "SpecialCallArg": 4,
+ "EmbedInfo": 5,
+ "ControlJump": 6,
+ }
+ assert CallEffectKind.Opaque is CallEffectKind.UpdateState
+ for kind in CallEffectKind:
+ attrs = ir.DictAttrs(dict={"effect": kind})
+ assert int(attrs["effect"]) == kind.value
diff --git a/tirx/tests/python/ir/test_json.py b/tirx/tests/python/ir/test_json.py
index 7f6a75f317..776005f69d 100644
--- a/tirx/tests/python/ir/test_json.py
+++ b/tirx/tests/python/ir/test_json.py
@@ -83,9 +83,6 @@ def test_var_name_legacy_json_graph_rewrite(legacy_json, expected_type, var_inde
original = json.loads(legacy_json)
expected = copy.deepcopy(original)
- for node in expected["nodes"]:
- if node["type"] == "tirx.Add":
- node["type"] = "ir.prim.Add"
expected["nodes"][var_index]["type"] = expected_type
fields = expected["nodes"][var_index]["data"]
if "name_hint" in fields:
@@ -150,14 +147,14 @@ def test_var_name_legacy_json_load(legacy_json, expected_type):
@pytest.mark.parametrize(
"value",
[
- tvm_tirx.ir.prim.IntImm("int32", 1) + tvm_tirx.ir.prim.IntImm("int32", 10),
+ tvm_tirx.ir.IntImm("int32", 1) + tvm_tirx.ir.IntImm("int32", 10),
*[
- tvm_tirx.ir.prim.FloatImm(dtype, value)
+ tvm_tirx.ir.FloatImm(dtype, value)
for dtype in ("float32", "float64")
for value in (float("inf"), float("-inf"))
],
- tvm_tirx.ir.prim.min_value("float32"),
- tvm_tirx.ir.prim.max_value("float32"),
+ tvm_tirx.ir.prim.min_value(ty="float32"),
+ tvm_tirx.ir.prim.max_value(ty="float32"),
tvm_ffi.core.String("xyz"),
tvm_ffi.core.String("xy\x01z"),
],
@@ -175,13 +172,13 @@ def test_json_containers():
objects = tvm_tirx.runtime.convert({a: 2, b: 3})
assert a in objects and b in dict(objects.items())
assert len(objects) == 2
- assert tvm_tirx.ir.prim.Add(a, tvm_tirx.ir.prim.IntImm("int32", 1)) not in objects
+ assert tvm_tirx.ir.prim.Add(a, tvm_tirx.ir.IntImm("int32", 1)) not in objects
assert set(objects) == set(objects.keys()) == {a, b}
assert set(objects.values()) == {2, 3}
restored = tvm_tirx.ir.load_json(tvm_tirx.ir.save_json(objects))
assert {key.name: value for key, value in restored.items()} == {"a": 2, "b": 3}
- x = tvm_tirx.ir.prim.IntImm("int32", 1)
- z = tvm_tirx.ir.prim.Add(x, tvm_tirx.ir.prim.IntImm("int32", 10))
+ x = tvm_tirx.ir.IntImm("int32", 1)
+ z = tvm_tirx.ir.prim.Add(x, tvm_tirx.ir.IntImm("int32", 10))
graph = [{"z": z, "x": x}]
saved = tvm_tirx.ir.save_json(graph)
restored = tvm_tirx.ir.load_json(saved)
@@ -194,7 +191,7 @@ def test_json_containers():
@pytest.mark.parametrize("dtype", ["int32", tvm_ffi.core.String("int32")])
def test_make_node_default_location(dtype):
value = tvm_tirx.ir.make_node("ir.IntImm", ty=tvm_tirx.ir.PrimType(dtype), value=10)
- assert isinstance(value, tvm_tirx.ir.prim.IntImm)
+ assert isinstance(value, tvm_tirx.ir.IntImm)
assert value.value == 10
assert set(dir(value.__class__)) <= set(dir(value))
assert value.loc.same_as(tvm_tirx.ir.UnknownLoc())
diff --git a/tirx/tests/python/ir/test_module.py b/tirx/tests/python/ir/test_module.py
index 84515c9756..893b282e16 100644
--- a/tirx/tests/python/ir/test_module.py
+++ b/tirx/tests/python/ir/test_module.py
@@ -17,8 +17,8 @@
import pytest
import tvm_tirx
-from tvm_tirx.ir.supply import UniqueNameSupply
from tvm_tirx.ir.transform.instrument import PrintAfterAll, PrintBeforeAll
+from tvm_tirx.ir.unique_name_supply import UniqueNameSupply
@pytest.mark.parametrize(
diff --git a/tirx/tests/python/script/test_error_handling.py b/tirx/tests/python/script/test_error_handling.py
index e9c228b154..5b30938456 100644
--- a/tirx/tests/python/script/test_error_handling.py
+++ b/tirx/tests/python/script/test_error_handling.py
@@ -28,6 +28,7 @@ import pytest
# ruff: noqa: F841
from minilang import Value
+import tvm_tirx
from tvm_tirx import ir
from tvm_tirx.ir import prim
from tvm_tirx.script import ir as I
@@ -285,7 +286,7 @@ def test_nested_function_failure_preserves_error_and_recovers(located_language):
("outer_before", outer.params[0], outer.params[0], 1),
("inner", outer.params[0], inner.params[0], 2),
]
- M.node = lambda value: prim.IntImm("int32", value)
+ M.node = lambda value: tvm_tirx.ir.IntImm("int32", value)
@M.function
def recovered(value: M.Tensor((2,))):
diff --git a/tirx/tests/python/script/test_ir_builder.py b/tirx/tests/python/script/test_ir_builder.py
index 5a2445de91..180d8d7054 100644
--- a/tirx/tests/python/script/test_ir_builder.py
+++ b/tirx/tests/python/script/test_ir_builder.py
@@ -18,6 +18,7 @@
import pytest
+import tvm_tirx
from tvm_tirx import ir
from tvm_tirx.ir.base import assert_structural_equal
from tvm_tirx.script import ir_builder as I
@@ -66,7 +67,7 @@ def test_attach_loc_normalizes_full_stack_and_preserves_identity():
outer = _source_loc("definition.py", 1, end_line=10)
inner = _source_loc("definition.py", 3)
leaf = _source_loc("leaf.py", 5)
- node = ir.prim.IntImm("int32", 1)
+ node = tvm_tirx.ir.IntImm("int32", 1)
with IRBuilder() as ib:
with ib.with_loc(caller), ib.with_loc(outer), ib.with_loc(ir.UnknownLoc()):
with ib.with_loc(ir.CallSiteLoc(inner, caller)):
@@ -79,7 +80,7 @@ def test_attach_loc_preserves_shared_prefix_and_receipt_identity():
caller = _source_loc("caller.py", 2)
callee = _source_loc("definition.py", 3)
- node = ir.prim.IntImm("int32", 1)
+ node = tvm_tirx.ir.IntImm("int32", 1)
receipt = AlreadyEmitted(node)
container = [node]
with IRBuilder() as ib:
@@ -97,7 +98,7 @@ def test_unknown_attachment_and_scope_exception_restore_context():
caller = _source_loc("caller.py", 2)
callee = _source_loc("definition.py", 3)
- node = ir.prim.IntImm("int32", 1)
+ node = tvm_tirx.ir.IntImm("int32", 1)
with IRBuilder() as ib:
assert ib._attach_loc(node) is node
assert isinstance(node.loc, ir.UnknownLoc)
@@ -109,7 +110,7 @@ def test_unknown_attachment_and_scope_exception_restore_context():
raise RuntimeError("scope failure")
ib._attach_loc(node)
assert node.loc.same_as(caller)
- untouched = ir.prim.IntImm("int32", 2)
+ untouched = tvm_tirx.ir.IntImm("int32", 2)
ib._attach_loc(untouched)
assert isinstance(untouched.loc, ir.UnknownLoc)
assert not IRBuilder.is_in_scope()
diff --git a/tirx/tests/python/script/test_printer_doc.py b/tirx/tests/python/script/test_printer_doc.py
index 4c849f5e57..514211079c 100644
--- a/tirx/tests/python/script/test_printer_doc.py
+++ b/tirx/tests/python/script/test_printer_doc.py
@@ -136,8 +136,8 @@ EXPR_CASES = {
"str": (LiteralDoc("test"), '"test"'),
"str-quote": (LiteralDoc('""'), r'"\"\""'),
"str-escape": (LiteralDoc("\n\t\\test\r"), r'"\n\t\\test\r"'),
- # TODO: fix the roundatrippable problem caused by utf8
- "str-utf8": pytest.param(LiteralDoc("\x88"), r'"\x88"', marks=pytest.mark.xfail),
+ "str-utf8": (LiteralDoc("\x88"), r'"\u0088"'),
+ "str-unicode": (LiteralDoc("é中😀"), r'"\u00e9\u4e2d\U0001f600"'),
"int": (LiteralDoc(-1), "-1"),
"float": (LiteralDoc(3.25), "3.25"),
"id": (IdDoc("test"), "test"),
diff --git a/tirx/tests/python/script/test_source_locations.py b/tirx/tests/python/script/test_source_locations.py
index be712835fc..e59e94c2f7 100644
--- a/tirx/tests/python/script/test_source_locations.py
+++ b/tirx/tests/python/script/test_source_locations.py
@@ -20,7 +20,6 @@ Fileless documentation execution also recovers the correct decorated class sourc
from __future__ import annotations
-# Script-local assignments are observed through the constructed IR.
import ast
import inspect
import sys
@@ -29,8 +28,9 @@ from types import ModuleType
import pytest
from minilang import Value
+# Script-local assignments are observed through the constructed IR.
+import tvm_tirx
from tvm_tirx import ir
-from tvm_tirx.ir import prim
from tvm_tirx.script import ir as I
... 2210 lines suppressed ...
(tvm) 04/12: [REFACTOR] Separate TIRx compiler and runtime deployment APIs (#20763)
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 341e3fd7f5fc779f3bd216472c262d8d17428bf3
Author: Tianqi Chen <tq...@users.noreply.github.com>
AuthorDate: Fri Oct 16 14:12:53 2026 -0400
[REFACTOR] Separate TIRx compiler and runtime deployment APIs (#20763)
Expose component-based build and link configuration through
`tvm-tirx-config` and name the compiler library `libtvm_tirx_compiler`.
Move export and JIT orchestration into `codegen.Executable`, use FFI
modules directly in the runtime, and keep object/archive linking
explicit in compiler and RPC consumers. Move benchmarking policy to the
parent runtime while retaining the small device timer interface and
backend providers in TIRx.
---
tirx/CMakeLists.txt | 31 +-
tirx/cmake/modules/ClangFlags.cmake | 2 +-
tirx/cmake/modules/Logging.cmake | 4 +-
tirx/cmake/tvm_tirx-config.cmake | 6 +-
tirx/include/tvm/runtime/base.h | 2 +-
tirx/include/tvm/runtime/timer.h | 64 +---
tirx/pyproject.toml | 3 +
tirx/python/tvm_tirx/__init__.py | 3 +-
tirx/python/tvm_tirx/base.py | 8 +-
.../tvm_tirx/{codegen.py => codegen/__init__.py} | 4 +-
.../{runtime/module.py => codegen/executable.py} | 351 ++++++---------------
tirx/python/tvm_tirx/config.py | 209 +++++++++---
tirx/python/tvm_tirx/runtime/__init__.py | 43 ++-
tirx/python/tvm_tirx/runtime/executable.py | 175 ----------
tirx/python/tvm_tirx/support/cc.py | 6 +-
tirx/python/tvm_tirx/support/ndk.py | 4 +-
tirx/python/tvm_tirx/tirx/_compile.py | 4 +-
tirx/src/runtime/timer.cc | 276 ----------------
tirx/tests/cpp/CMakeLists.txt | 2 +-
.../test_validate_runtime_library.py | 43 ++-
.../python/backend/cuda/codegen/test_fastmath.py | 2 +-
tirx/tests/python/codegen/c/test_basic.py | 6 +-
tirx/tests/python/codegen/test_executable.py | 145 +++++++++
tirx/tests/python/conftest.py | 78 +++++
tirx/tests/python/runtime/test_module.py | 152 +--------
tirx/tests/python/runtime/test_tirx_config.py | 46 ++-
tirx/tests/python/support/test_config.py | 130 +++++++-
tirx/tests/python/tirx/iket/test_profiler.py | 5 +-
28 files changed, 784 insertions(+), 1020 deletions(-)
diff --git a/tirx/CMakeLists.txt b/tirx/CMakeLists.txt
index 683377e4da..4001e955d9 100644
--- a/tirx/CMakeLists.txt
+++ b/tirx/CMakeLists.txt
@@ -223,31 +223,31 @@ include(cmake/modules/ROCM.cmake)
include(cmake/modules/LLVM.cmake)
include(cmake/modules/contrib/Z3.cmake)
include(cmake/modules/Git.cmake)
-# ######### Target: `tvm_tirx` ##########
+# ######### Target: `tvm_tirx_compiler` ##########
-add_library(tvm_tirx_objs OBJECT ${COMPILER_SRCS})
-target_link_libraries(tvm_tirx_objs PUBLIC tvm_tirx_header)
+add_library(tvm_tirx_compiler_objs OBJECT ${COMPILER_SRCS})
+target_link_libraries(tvm_tirx_compiler_objs PUBLIC tvm_tirx_header)
if(TARGET tvm_llvm_header)
- target_link_libraries(tvm_tirx_objs PRIVATE tvm_llvm_header)
+ target_link_libraries(tvm_tirx_compiler_objs PRIVATE tvm_llvm_header)
endif()
if(MSVC)
- target_compile_definitions(tvm_tirx_objs PRIVATE TVM_TIRX_EXPORTS TVM_FFI_EXPORTS)
+ target_compile_definitions(tvm_tirx_compiler_objs PRIVATE TVM_TIRX_EXPORTS TVM_FFI_EXPORTS)
endif()
-add_library(tvm_tirx SHARED $<TARGET_OBJECTS:tvm_tirx_objs>)
-add_library(tvm_tirx::shared ALIAS tvm_tirx)
-target_link_libraries(tvm_tirx PUBLIC tvm_runtime tvm_tirx_header)
-target_link_libraries(tvm_tirx PRIVATE ${TVM_LINKER_LIBS})
+add_library(tvm_tirx_compiler SHARED $<TARGET_OBJECTS:tvm_tirx_compiler_objs>)
+add_library(tvm_tirx_compiler::shared ALIAS tvm_tirx_compiler)
+target_link_libraries(tvm_tirx_compiler PUBLIC tvm_runtime tvm_tirx_header)
+target_link_libraries(tvm_tirx_compiler PRIVATE ${TVM_LINKER_LIBS})
# Avoid GNU ld relaxation of LLVM's GOT calls into incorrect direct calls.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT "${TVM_TIRX_USE_LLVM}" MATCHES ${IS_FALSE_PATTERN})
- target_link_options(tvm_tirx PRIVATE "-Wl,--no-relax" "-Wl,--as-needed")
+ target_link_options(tvm_tirx_compiler PRIVATE "-Wl,--no-relax" "-Wl,--as-needed")
endif()
include(cmake/modules/Logging.cmake)
include(cmake/modules/ClangFlags.cmake)
# ######### Library configuration ##########
-foreach(_target tvm_runtime_objs tvm_tirx_objs tvm_runtime tvm_runtime_static tvm_tirx)
+foreach(_target tvm_runtime_objs tvm_tirx_compiler_objs tvm_runtime tvm_runtime_static tvm_tirx_compiler)
tvm_tirx_configure_target(${_target})
tvm_ffi_add_prefix_map(${_target} "${CMAKE_CURRENT_SOURCE_DIR}")
endforeach()
@@ -255,7 +255,7 @@ foreach(_target IN LISTS TVM_RUNTIME_BACKEND_LIBS)
tvm_ffi_add_prefix_map(${_target}_objs "${CMAKE_CURRENT_SOURCE_DIR}")
tvm_ffi_add_prefix_map(${_target} "${CMAKE_CURRENT_SOURCE_DIR}")
endforeach()
-foreach(_target tvm_runtime tvm_tirx ${TVM_RUNTIME_BACKEND_LIBS})
+foreach(_target tvm_runtime tvm_tirx_compiler ${TVM_RUNTIME_BACKEND_LIBS})
if(TVM_TIRX_BUILD_PYTHON_MODULE)
if(APPLE)
set_property(TARGET ${_target} APPEND PROPERTY INSTALL_RPATH "@loader_path/../../tvm_ffi/lib")
@@ -284,7 +284,7 @@ foreach(_header IN LISTS _headers)
endforeach()
# Libraries
-install(TARGETS tvm_tirx_header tvm_tirx tvm_runtime tvm_runtime_static
+install(TARGETS tvm_tirx_header tvm_tirx_compiler tvm_runtime tvm_runtime_static
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT tvm_tirx
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT tvm_tirx
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT tvm_tirx)
@@ -297,6 +297,11 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils/"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/tvm_tirx/utils"
COMPONENT tvm_tirx FILES_MATCHING PATTERN "Find*.cmake")
+if(NOT TVM_TIRX_BUILD_PYTHON_MODULE)
+ install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_tirx/config.py"
+ DESTINATION "${CMAKE_INSTALL_BINDIR}" RENAME tvm-tirx-config COMPONENT tvm_tirx)
+endif()
+
# Python package artifacts and licenses
if(TVM_TIRX_BUILD_PYTHON_MODULE)
foreach(_extra_lib IN LISTS TVM_TIRX_PACKAGE_EXTRA_LIBS)
diff --git a/tirx/cmake/modules/ClangFlags.cmake b/tirx/cmake/modules/ClangFlags.cmake
index f296165726..b8a6cddb60 100644
--- a/tirx/cmake/modules/ClangFlags.cmake
+++ b/tirx/cmake/modules/ClangFlags.cmake
@@ -82,7 +82,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-Wno-gnu-anonymous-struct
-Wno-nested-anon-types
)
- target_compile_options(tvm_tirx_objs PRIVATE $<$<COMPILE_LANGUAGE:CXX>: ${warning_opts}>)
+ target_compile_options(tvm_tirx_compiler_objs PRIVATE $<$<COMPILE_LANGUAGE:CXX>: ${warning_opts}>)
target_compile_options(tvm_runtime_objs PRIVATE $<$<COMPILE_LANGUAGE:CXX>: ${warning_opts}>)
diff --git a/tirx/cmake/modules/Logging.cmake b/tirx/cmake/modules/Logging.cmake
index df7f2a7b7f..df8b3955d7 100644
--- a/tirx/cmake/modules/Logging.cmake
+++ b/tirx/cmake/modules/Logging.cmake
@@ -21,9 +21,9 @@ include(FindPackageHandleStandardArgs)
if(TVM_TIRX_USE_CUSTOM_LOGGING)
# Set and propagate TVM_LOG_CUSTOMIZE flag is custom logging has been requested
- target_compile_definitions(tvm_tirx_objs PUBLIC TVM_LOG_CUSTOMIZE=1)
+ target_compile_definitions(tvm_tirx_compiler_objs PUBLIC TVM_LOG_CUSTOMIZE=1)
target_compile_definitions(tvm_runtime_objs PUBLIC TVM_LOG_CUSTOMIZE=1)
- target_compile_definitions(tvm_tirx PUBLIC TVM_LOG_CUSTOMIZE=1)
+ target_compile_definitions(tvm_tirx_compiler PUBLIC TVM_LOG_CUSTOMIZE=1)
target_compile_definitions(tvm_runtime PUBLIC TVM_LOG_CUSTOMIZE=1)
target_compile_definitions(tvm_runtime_static INTERFACE TVM_LOG_CUSTOMIZE=1)
endif()
diff --git a/tirx/cmake/tvm_tirx-config.cmake b/tirx/cmake/tvm_tirx-config.cmake
index 4ef057cd43..118342b0ef 100644
--- a/tirx/cmake/tvm_tirx-config.cmake
+++ b/tirx/cmake/tvm_tirx-config.cmake
@@ -38,7 +38,7 @@ if(NOT TARGET tvm_tirx::header)
target_include_directories(tvm_tirx::header INTERFACE "${tvm_tirx_INCLUDE_DIR}")
endif()
-foreach(_library tvm_runtime tvm_tirx)
+foreach(_library tvm_runtime tvm_tirx_compiler)
if(TARGET ${_library}::shared)
continue()
endif()
@@ -50,7 +50,7 @@ foreach(_library tvm_runtime tvm_tirx)
set_target_properties(${_library}::shared PROPERTIES IMPORTED_IMPLIB "${_implib}")
endif()
target_link_libraries(${_library}::shared INTERFACE tvm_tirx::header)
- if(_library STREQUAL "tvm_tirx")
- target_link_libraries(tvm_tirx::shared INTERFACE tvm_runtime::shared)
+ if(_library STREQUAL "tvm_tirx_compiler")
+ target_link_libraries(tvm_tirx_compiler::shared INTERFACE tvm_runtime::shared)
endif()
endforeach()
diff --git a/tirx/include/tvm/runtime/base.h b/tirx/include/tvm/runtime/base.h
index d4e7e6e20c..0848fff40c 100644
--- a/tirx/include/tvm/runtime/base.h
+++ b/tirx/include/tvm/runtime/base.h
@@ -77,7 +77,7 @@
#define TVM_DLL_EXPORT __attribute__((visibility("default")))
#endif
-// Core IR, TIRx and shared compiler infrastructure live in libtvm_tirx.
+// Core IR, TIRx and shared compiler infrastructure live in libtvm_tirx_compiler.
#ifndef TVM_TIRX_DLL
#if defined(__EMSCRIPTEN__)
#define TVM_TIRX_DLL EMSCRIPTEN_KEEPALIVE
diff --git a/tirx/include/tvm/runtime/timer.h b/tirx/include/tvm/runtime/timer.h
index 07abab3b0d..684098c32d 100644
--- a/tirx/include/tvm/runtime/timer.h
+++ b/tirx/include/tvm/runtime/timer.h
@@ -19,15 +19,12 @@
/*!
* \file tvm/runtime/timer.h
- * \brief Runtime timer primitives: Timer, TimerObj.
+ * \brief Device timer interface and object reference.
*/
#ifndef TVM_RUNTIME_TIMER_H_
#define TVM_RUNTIME_TIMER_H_
-#include <tvm/ffi/function.h>
-#include <tvm/runtime/base.h>
-#include <tvm/runtime/device_api.h>
-#include <tvm/runtime/tensor.h>
+#include <tvm/ffi/object.h>
namespace tvm {
namespace runtime {
@@ -76,63 +73,6 @@ class TimerObj : public ffi::Object {
*/
class Timer : public ffi::ObjectRef {
public:
- /*!
- * \brief Get a device specific timer.
- * \param dev The device to time.
- * \return A `Timer` that has already been started.
- *
- * Use this function to time runtime of arbitrary regions of code on a specific
- * device. The code that you want to time should be running on the device
- * otherwise the timer will not return correct results. This is a lower level
- * interface than TimeEvaluator and only runs the timed code once
- * (TimeEvaluator runs the code multiple times).
- *
- * A default timer is used if a device specific one does not exist. This
- * timer performs synchronization between the device and CPU, which can lead
- * to overhead in the reported results.
- *
- * Example usage:
- * \code{.cpp}
- * Timer t = Timer::Start(Device::cpu());
- * my_long_running_function();
- * t->Stop();
- * ... // some more computation
- * int64_t nanosecs = t->SyncAndGetElapsedNanos() // elapsed time in nanoseconds
- * \endcode
- *
- * To add a new device-specific timer, register a new function
- * "runtime.timer.my_device" (where `my_device` is the `DeviceName` of your
- * device). This function should accept a `Device` and return a new `Timer`
- * that has already been started.
- *
- * For example, this is how the CPU timer is implemented:
- * \code{.cpp}
- * class CPUTimerObj : public TimerObj {
- * public:
- * virtual void Start() { start_ = std::chrono::high_resolution_clock::now(); }
- * virtual void Stop() { duration_ = std::chrono::high_resolution_clock::now() - start_; }
- * virtual int64_t SyncAndGetElapsedNanos() { return duration_.count(); }
- * virtual ~CPUTimerObj() {}
- *
- * static constexpr const char* _type_key = "runtime.CPUTimerObj";
- * TVM_FFI_DECLARE_OBJECT_INFO_FINAL(CPUTimerObj, TimerObj);
- *
- * private:
- * std::chrono::high_resolution_clock::time_point start_;
- * std::chrono::duration<int64_t, std::nano> duration_;
- * };
- *
- *
- * TVM_FFI_STATIC_INIT_BLOCK() {
- * namespace refl = tvm::ffi::reflection;
- * refl::GlobalDef().def("runtime.timer.cpu", [](Device dev) {
- * return Timer(ffi::UnsafeInit{}, ffi::make_object<CPUTimerObj>());
- * });
- * }
- * \endcode
- */
- static TVM_RUNTIME_DLL Timer Start(Device dev);
-
explicit Timer(ffi::UnsafeInit tag, ffi::ObjectPtr<TimerObj> n) : ffi::ObjectRef(tag) {
data_ = std::move(n);
}
diff --git a/tirx/pyproject.toml b/tirx/pyproject.toml
index 9043a5163e..4ef79dcb0c 100644
--- a/tirx/pyproject.toml
+++ b/tirx/pyproject.toml
@@ -51,6 +51,9 @@ dependencies = [
"packaging",
]
+[project.scripts]
+tvm-tirx-config = "tvm_tirx.config:__main__"
+
[project.optional-dependencies]
torch = ["torch"]
cuda = ["cuda-bindings"]
diff --git a/tirx/python/tvm_tirx/__init__.py b/tirx/python/tvm_tirx/__init__.py
index a66f56d844..fcdeb1f0bd 100644
--- a/tirx/python/tvm_tirx/__init__.py
+++ b/tirx/python/tvm_tirx/__init__.py
@@ -19,13 +19,14 @@
"""TVM: Open Deep Learning Compiler Stack."""
import sys
+import os
from typing import TYPE_CHECKING
def _is_config_mode():
"""Keep the configuration CLI independent of native library loading."""
argv = getattr(sys, "orig_argv", ())
- return any(
+ return os.path.basename(sys.argv[0]) in ("tvm-tirx-config", "tvm-tirx-config.exe") or any(
arg == "-m" and argv[index + 1 : index + 2] == ["tvm_tirx.config"]
for index, arg in enumerate(argv)
)
diff --git a/tirx/python/tvm_tirx/base.py b/tirx/python/tvm_tirx/base.py
index 8bc62431c2..17c4a05b7b 100644
--- a/tirx/python/tvm_tirx/base.py
+++ b/tirx/python/tvm_tirx/base.py
@@ -35,7 +35,7 @@ from . import libinfo
_RUNTIME_ONLY = os.environ.get("TVM_USE_RUNTIME_LIB") == "1"
# Handles of the core libraries actually loaded, keyed by basename
-# (e.g. ``{"tvm_runtime": <CDLL>, "tvm_tirx": <CDLL>}``). Downstream /
+# (e.g. ``{"tvm_runtime": <CDLL>, "tvm_tirx_compiler": <CDLL>}``). Downstream /
# autoloaded extensions can inspect this to skip duplicate libraries
# (``"tvm_runtime" in _LOADED_LIBS``) and obtain the loaded handle.
_LOADED_LIBS = {}
@@ -51,14 +51,14 @@ if not _RUNTIME_ONLY:
_lib_paths = [Path(_LOADED_LIBS["tvm_runtime"]._name).resolve().parent]
try:
tvm_ffi_libinfo._find_library_by_basename(
- "tvm_tirx", "tvm_tirx", extra_lib_paths=_lib_paths
+ "tvm_tirx", "tvm_tirx_compiler", extra_lib_paths=_lib_paths
)
except RuntimeError:
# A runtime-only installation need not contain the compiler library.
_RUNTIME_ONLY = True
else:
- _LOADED_LIBS["tvm_tirx"] = load_lib_ctypes(
- "tvm_tirx", "tvm_tirx", "RTLD_LOCAL", extra_lib_paths=_lib_paths
+ _LOADED_LIBS["tvm_tirx_compiler"] = load_lib_ctypes(
+ "tvm_tirx", "tvm_tirx_compiler", "RTLD_LOCAL", extra_lib_paths=_lib_paths
)
if _RUNTIME_ONLY:
diff --git a/tirx/python/tvm_tirx/codegen.py b/tirx/python/tvm_tirx/codegen/__init__.py
similarity index 98%
rename from tirx/python/tvm_tirx/codegen.py
rename to tirx/python/tvm_tirx/codegen/__init__.py
index ba3b2036f0..afc5fc7c3f 100644
--- a/tirx/python/tvm_tirx/codegen.py
+++ b/tirx/python/tvm_tirx/codegen/__init__.py
@@ -18,7 +18,9 @@
from tvm_ffi import Array, get_global_func
-from .target import Target
+from tvm_tirx.target import Target
+
+from .executable import Executable, load_static_library
def build_module(mod, target):
diff --git a/tirx/python/tvm_tirx/runtime/module.py b/tirx/python/tvm_tirx/codegen/executable.py
similarity index 52%
rename from tirx/python/tvm_tirx/runtime/module.py
rename to tirx/python/tvm_tirx/codegen/executable.py
index 0743a45f50..674b47c127 100644
--- a/tirx/python/tvm_tirx/runtime/module.py
+++ b/tirx/python/tvm_tirx/codegen/executable.py
@@ -14,100 +14,106 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-# ruff: noqa: F401
-
-# pylint: disable=invalid-name, unused-import, import-outside-toplevel, inconsistent-return-statements
-"""Runtime Module namespace."""
+"""Compiler-owned export and JIT orchestration for ordinary FFI modules."""
import json
import os
-import struct
-from collections.abc import Sequence
+from collections.abc import Callable
+from typing import Any
-import numpy as np
-from tvm_ffi import (
- Module as _Module,
-)
+from tvm_ffi import Function, Module, load_module
from tvm_ffi import libinfo as tvm_ffi_libinfo
-from tvm_ffi import (
- load_module as _load_module,
-)
-from tvm_ffi import (
- register_object as _register_object,
-)
-from tvm_ffi import (
- system_lib,
-)
import tvm_tirx.libinfo
from tvm_tirx.base import _RUNTIME_ONLY
+from tvm_tirx.runtime import _ffi_api
+from tvm_tirx.support import utils as _utils
+
+
+class Executable:
+ """The executable object generated by `tvm.compile`."""
+
+ def __init__(self, mod: Module):
+ """Initialize the Executable object."""
+ self.mod: Module = mod
+ self._jitted_mod: Module | None = None
-from . import _ffi_api
+ def __getitem__(self, name: str) -> Function:
+ """Get the Function from the jitted module."""
+ return self.jit().get_function(name, query_imports=True)
+ def __call__(self, *args, **kwargs) -> Any:
+ """Call the executable."""
+ return self.jit().main(*args, **kwargs)
-class BenchmarkResult:
- """Runtimes from benchmarking"""
+ def jit(
+ self,
+ *,
+ fcompile: Callable[[str, list[str], dict[str, Any]], None] | None = None,
+ addons: list[str] | None = None,
+ force_recompile: bool = False,
+ **kwargs,
+ ) -> Module:
+ """Just-in-time compile and link the modules.
- def __init__(self, results: Sequence[float]):
- """Construct a new BenchmarkResult from a sequence of runtimes.
+ The Executable returned by tvm.compile may not be directly
+ runnable as they may contain CUDA source files and objects that
+ are yet to be compiled and linked.
+ This function helps to create a runtime.Module for these cases.
Parameters
----------
- results : Sequence[float]
- Raw times from benchmarking
+ fcompile : function(target, file_list, kwargs), optional
+ The compilation function to use create the final library object during
+
+ addons : list of str, optional
+ Additional object files to link against.
+
+ force_recompile : bool, optional
+ If True, force a recompile of the module.
+
+ kwargs : dict, optional
+ Additional arguments passed to fcompile
+
+ Returns
+ -------
+ rt_mod: tvm_ffi.Module
+ A runnable runtime module that can be passed to VirtualMachine.
+
+ Examples
+ --------
+ .. code:: python
+
+ ex = tvm.compile(mod, target)
+ rt_mod = ex.jit()
- Attributes
- ----------
- min : float
- Minimum runtime in seconds of all results.
- mean : float
- Mean runtime in seconds of all results. If py:meth:`Module.time_evaluator` or
- `benchmark` is called with `number` > 0, then each result is already the mean of a
- `number` of runtimes, so this becomes the mean of means.
- median : float
- Median runtime in seconds of all results. If py:meth:`Module.time_evaluator` is called
- with `number` > 0, then each result is already the mean of a `number` of runtimes, so
- this becomes the median of means.
- max : float
- Maximum runtime in seconds of all results. If py:meth:`Module.time_evaluator` is called
- with `number` > 0, then each result is already the mean of a `number` of runtimes, so
- this becomes the maximum of those means.
- std : float
- Standard deviation in seconds of runtimes. If py:meth:`Module.time_evaluator` is called
- with `number` > 0, then each result is already the mean of a `number` of runtimes, so
- this becomes the standard deviation of means.
- results : Sequence[float]
- The collected runtimes (in seconds). This may be a series of mean runtimes if
- py:meth:`Module.time_evaluator` or `benchmark` was run with `number` > 1.
"""
- self.results = results
- self.mean = np.mean(self.results)
- self.std = np.std(self.results)
- self.median = np.median(self.results)
- self.min = np.min(self.results)
- self.max = np.max(self.results)
-
- def __repr__(self):
- return (
- f"BenchmarkResult(min={self.min}, mean={self.mean}, median={self.median}, "
- f"max={self.max}, std={self.std}, results={self.results})"
- )
-
- def __str__(self):
- return (
- f"Execution time summary:\n"
- f"{'mean (ms)':^12} {'median (ms)':^12} {'max (ms)':^12} "
- f"{'min (ms)':^12} {'std (ms)':^12}\n"
- f"{self.mean * 1000:^12.4f} {self.median * 1000:^12.4f} {self.max * 1000:^12.4f} "
- f"{self.min * 1000:^12.4f} {self.std * 1000:^12.4f}"
- " "
- )
-
-
-# override the Module class in ffi.Module
-@_register_object("ffi.Module")
-class Module(_Module):
- """Runtime Module."""
+
+ # If the module is already jitted and we don't want to force a recompile,
+ # return the cached module
+ if self._jitted_mod is not None and not force_recompile:
+ return self._jitted_mod
+
+ # TODO(tvm-team): Update runtime.Module interface
+ # to query these properties as bitmask.
+ def _not_runnable(x):
+ return x.kind in ("c", "static_library")
+
+ # pylint:disable = protected-access
+ not_runnable_list = self._collect_from_import_tree(_not_runnable)
+
+ # everything is runnable, directly return mod.
+ if len(not_runnable_list) == 0:
+ return self.mod
+
+ # found source module, or other not runnable modules need to be export and load
+ # TODO(tvm-team): Support runnable but not exportable module.
+ # by collecting the link and allow export_library skip those modules.
+ workspace_dir = _utils.tempdir()
+ dso_path = workspace_dir.relpath("exported.so")
+ self.export_library(dso_path, fcompile=fcompile, addons=addons, **kwargs)
+ self._jitted_mod = load_module(dso_path)
+ return self._jitted_mod
def _collect_from_import_tree(self, filter_func):
"""Helper function to collect modules from the tree matching a filter_func, then return it.
@@ -125,8 +131,8 @@ class Module(_Module):
"""
visited, stack, dso_modules = set(), [], []
# append root module
- visited.add(self)
- stack.append(self)
+ visited.add(self.mod)
+ stack.append(self.mod)
while stack:
module = stack.pop()
assert module.is_compilation_exportable() or module.is_binary_serializable(), (
@@ -226,7 +232,7 @@ class Module(_Module):
if workspace_dir is None:
temp = _utils.tempdir()
workspace_dir = temp.temp_dir
- files = addons if addons else []
+ files = list(addons) if addons else []
is_system_lib = False
has_c_module = False
system_lib_prefix = None
@@ -282,24 +288,24 @@ class Module(_Module):
if getattr(fcompile, "need_system_lib", False) and not is_system_lib:
raise ValueError(f"{fcompile!s} need --system-lib option")
- if self.imports:
+ if self.mod.imports:
pack_lib_prefix = system_lib_prefix if system_lib_prefix else ""
if fpack_imports is not None:
- path_out = fpack_imports(self, is_system_lib, pack_lib_prefix, workspace_dir)
+ path_out = fpack_imports(self.mod, is_system_lib, pack_lib_prefix, workspace_dir)
files.append(path_out)
elif _ffi_api.RuntimeEnabled("llvm") and llvm_target:
path_obj = os.path.join(
workspace_dir, f"{pack_lib_prefix}devc.{global_object_format}"
)
_ffi_api.ModulePackImportsToObjectFile(
- self, is_system_lib, llvm_target, path_obj, pack_lib_prefix
+ self.mod, is_system_lib, llvm_target, path_obj, pack_lib_prefix
)
files.append(path_obj)
else:
path_cc = os.path.join(workspace_dir, f"{pack_lib_prefix}devc.c")
with open(path_cc, "w") as f:
- f.write(_ffi_api.ModulePackImportsToC(self, is_system_lib, pack_lib_prefix))
+ f.write(_ffi_api.ModulePackImportsToC(self.mod, is_system_lib, pack_lib_prefix))
files.append(path_cc)
# The imports could contain a c module but the object format could be tar
@@ -320,186 +326,9 @@ class Module(_Module):
return fcompile(file_name, files, **kwargs)
- def time_evaluator(
- self,
- func_name,
- dev,
- number=10,
- repeat=1,
- min_repeat_ms=0,
- limit_zero_time_iterations=100,
- cooldown_interval_ms=0,
- repeats_to_cooldown=1,
- cache_flush_bytes=0,
- f_preproc="",
- ):
- """Get an evaluator that measures time cost of running function.
-
- Parameters
- ----------
- func_name: str
- The name of the function in the module.
-
- dev: Device
- The device we should run this function on.
-
- number: int
- The number of times to run this function for taking average.
- We call these runs as one `repeat` of measurement.
-
- repeat: int, optional
- The number of times to repeat the measurement.
- In total, the function will be invoked (1 + number x repeat) times,
- where the first one is warm up and will be discarded.
- The returned result contains `repeat` costs,
- each of which is an average of `number` costs.
-
- min_repeat_ms: int, optional
- The minimum duration of one `repeat` in milliseconds.
- By default, one `repeat` contains `number` runs. If this parameter is set,
- the parameters `number` will be dynamically adjusted to meet the
- minimum duration requirement of one `repeat`.
- i.e., When the run time of one `repeat` falls below this time, the `number` parameter
- will be automatically increased.
-
- limit_zero_time_iterations: int, optional
- The maximum number of repeats when measured time is equal to 0.
- It helps to avoid hanging during measurements.
-
- cooldown_interval_ms: int, optional
- The cooldown interval in milliseconds between the number of repeats defined by
- `repeats_to_cooldown`.
-
- repeats_to_cooldown: int, optional
- The number of repeats before the cooldown is activated.
-
- cache_flush_bytes: int, optional
- The number of bytes to flush from the cache before each repeat.
-
- f_preproc: str, optional
- The preprocess function name we want to execute before executing the time evaluator.
-
- Note
- ----
- The function will be invoked (1 + number x repeat) times,
- with the first call discarded in case there is lazy initialization.
-
- Returns
- -------
- ftimer : function
- The function that takes same argument as func and returns a BenchmarkResult.
- The ProfileResult reports `repeat` time costs in seconds.
- """
- feval = _ffi_api.ModuleTimeEvaluator(
- self,
- func_name,
- dev,
- number,
- repeat,
- min_repeat_ms,
- limit_zero_time_iterations,
- cooldown_interval_ms,
- repeats_to_cooldown,
- cache_flush_bytes,
- f_preproc,
- )
-
- def evaluator(*args):
- """Internal wrapped evaluator."""
- # Wrap feval so we can add more stats in future.
- blob = feval(*args)
- fmt = "@" + ("d" * repeat)
- results = struct.unpack(fmt, blob)
- return BenchmarkResult(results)
-
- return evaluator
-
-
-def load_module(path):
- """Load module from file.
-
- Parameters
- ----------
- path : str
- The path to the module file.
-
- Returns
- -------
- module : runtime.Module
- The loaded module
-
- Note
- ----
- This function will automatically call
- cc.create_shared if the path is in format .o or .tar
- """
- if os.path.isfile(path):
- path = os.path.realpath(path)
- else:
- raise ValueError(f"cannot find file {path}")
-
- # High level handling for .o and .tar file.
- # We support this to be consistent with RPC module load.
- if path.endswith(".o"):
- # Extra dependencies during runtime.
- from tvm_tirx.support import cc as _cc
-
- _cc.create_shared(path + ".so", path)
- path += ".so"
- elif path.endswith(".tar"):
- # Extra dependencies during runtime.
- from tvm_tirx.support import cc as _cc
- from tvm_tirx.support import tar as _tar
- from tvm_tirx.support import utils as _utils
-
- tar_temp = _utils.tempdir(custom_path=path.replace(".tar", ""))
- _tar.untar(path, tar_temp.temp_dir)
- files = [tar_temp.relpath(x) for x in tar_temp.listdir()]
- _cc.create_shared(path + ".so", files)
- path += ".so"
- # Redirect to the load API
- return _load_module(path)
-
def load_static_library(path, func_names):
"""Load the .o library at path which implements functions with func_names.
Unlike the generic load_module the result will remain as a static_library
and will not be relinked on-the-fly into a .so library."""
return _ffi_api.ModuleLoadStaticLibrary(path, func_names)
-
-
-def enabled(target):
- """Whether module runtime is enabled for target
-
- Parameters
- ----------
- target : str or Dict[str, Any] or tvm_tirx.target.Target
- The target device type.
-
- Returns
- -------
- enabled : bool
- Whether runtime is enabled.
-
- Examples
- --------
- The following code checks if gpu is enabled.
-
- >>> tvm_tirx.runtime.enabled("gpu")
- """
- if isinstance(target, dict):
- target = target.get("kind", "")
- elif hasattr(target, "kind"):
- target = target.kind.name
- return _ffi_api.RuntimeEnabled(target)
-
-
-def num_threads() -> int:
- """Get the number of threads in use by the TVM runtime.
-
- Returns
- -------
- int
- Number of threads in use.
- """
- return _ffi_api.NumThreads()
diff --git a/tirx/python/tvm_tirx/config.py b/tirx/python/tvm_tirx/config.py
index de55764a37..466a30fe14 100644
--- a/tirx/python/tvm_tirx/config.py
+++ b/tirx/python/tvm_tirx/config.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -21,13 +22,26 @@ there with an exact library directory, independently of Python package search.
"""
import argparse
+import importlib.machinery
+import importlib.util
import json
+import os
+import shlex
import sys
from pathlib import Path
__version__ = "0.1.0a0"
-_LIBRARY_NAMES = ("tvm_tirx", "tvm_runtime")
+_LIBRARY_NAMES = ("tvm_tirx_compiler", "tvm_runtime")
+_COMPONENTS = {
+ "compiler": "tvm_tirx_compiler",
+ "runtime": "tvm_runtime",
+ "cuda": "tvm_runtime_cuda",
+ "metal": "tvm_runtime_metal",
+ "opencl": "tvm_runtime_opencl",
+ "vulkan": "tvm_runtime_vulkan",
+ "rocm": "tvm_runtime_rocm",
+}
def _find_prefix(start: Path) -> Path:
@@ -38,19 +52,25 @@ def _find_prefix(start: Path) -> Path:
def _paths(prefix: Path | None, library_dir: Path | None) -> tuple[Path, Path]:
+ explicit_prefix = prefix is not None
if library_dir is not None:
library_dir = library_dir.resolve()
prefix = prefix.resolve() if prefix is not None else _find_prefix(library_dir)
else:
prefix = prefix.resolve() if prefix is not None else _find_prefix(Path(__file__).parent)
library_dir = prefix / "lib"
- for candidate in (prefix / "lib", prefix / "lib64", prefix / "build/lib"):
+ candidates = [prefix / "lib", prefix / "lib64", prefix / "build/lib"]
+ if prefix.name == "tirx":
+ candidates.append(prefix.parent / "build/lib")
+ if not explicit_prefix and os.environ.get("TVM_TIRX_LIBRARY_PATH"):
+ candidates.insert(0, Path(os.environ["TVM_TIRX_LIBRARY_PATH"]))
+ for candidate in candidates:
if all(
any(
(candidate / filename).is_file()
for filename in (f"lib{name}.so", f"lib{name}.dylib", f"{name}.dll")
)
- for name in _LIBRARY_NAMES
+ for name in ("tvm_runtime",)
):
library_dir = candidate
break
@@ -59,11 +79,11 @@ def _paths(prefix: Path | None, library_dir: Path | None) -> tuple[Path, Path]:
return prefix, library_dir
-def _libraries(library_dir: Path, platform: str) -> dict[str, dict[str, str]]:
+def _libraries(library_dir: Path, platform: str, names=_LIBRARY_NAMES) -> dict[str, dict[str, str]]:
libraries = {}
windows = platform in ("Windows", "win32")
apple = platform in ("Darwin", "iOS", "darwin")
- for name in _LIBRARY_NAMES:
+ for name in names:
if windows:
filenames = (f"{name}.dll",)
elif apple:
@@ -102,47 +122,162 @@ def configuration(
}
+def _ffi_info():
+ """Read the selected FFI package's pure Python helper without importing its runtime."""
+ spec = importlib.machinery.PathFinder.find_spec("tvm_ffi")
+ if spec is None or spec.origin is None:
+ raise RuntimeError("Cannot find the matching apache-tvm-ffi Python package")
+ helper = Path(spec.origin).parent / "libinfo.py"
+ spec = importlib.util.spec_from_file_location("_tvm_ffi_libinfo", helper)
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ return module
+
+
+def _available(library_dir, platform):
+ available = []
+ for component, name in _COMPONENTS.items():
+ try:
+ _libraries(library_dir, platform, (name,))
+ except RuntimeError:
+ continue
+ available.append(component)
+ return available
+
+
+def _link_inputs(library_dir, platform, components):
+ available = _available(library_dir, platform)
+ selected = list(dict.fromkeys(components or ["all"]))
+ if "all" in selected:
+ selected = [*available, *(name for name in selected if name != "all")]
+ for name in selected:
+ if name != "ffi" and name not in available:
+ raise RuntimeError(
+ f"Component '{name}' is unavailable; available: {' '.join(available)} ffi"
+ )
+ # Dependents precede their dependencies even if the command line lists runtime first.
+ ordered = [name for name in selected if name not in ("runtime", "ffi")]
+ if any(name != "ffi" for name in selected):
+ ordered.append("runtime")
+ libraries = _libraries(library_dir, platform, [_COMPONENTS[name] for name in ordered])
+ ffi = _ffi_info()
+ ffi_library = (
+ ffi.find_windows_implib() if platform in ("Windows", "win32") else ffi.find_libtvm_ffi()
+ )
+ return [
+ *(Path(lib["implib"] or lib["location"]) for lib in libraries.values()),
+ Path(ffi_library),
+ ]
+
+
def __main__() -> None:
- """Print installed include, library, or CMake package paths."""
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument("--prefix", type=Path, help="Use this exact installation prefix")
- parser.add_argument("--library-dir", type=Path, help="Use this exact native library directory")
- parser.add_argument("--platform", default=sys.platform, help=argparse.SUPPRESS)
- outputs = parser.add_mutually_exclusive_group()
- outputs.add_argument(
- "--includedir", action="store_true", help="Print the public include directory"
+ """Print LLVM-style component configuration without loading native libraries."""
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ epilog="Components default to all available components. Examples: --libs runtime; "
+ "--libs runtime cuda; --libs compiler. Shared linking is the default.",
)
- outputs.add_argument("--libdir", action="store_true", help="Print the native library directory")
- outputs.add_argument(
- "--libfiles", action="store_true", help="Print library files, one per line"
+ parser.add_argument("components", nargs="*", help="Components to link (default: all)")
+ parser.add_argument("--install-prefix", type=Path, help="Query this exact installation prefix")
+ parser.add_argument(
+ "--library-dir", type=Path, help="Query this exact native library directory"
)
- outputs.add_argument(
- "--cmakedir", action="store_true", help="Print the CMake package directory"
+ parser.add_argument("--platform", default=sys.platform, help=argparse.SUPPRESS)
+ outputs = (
+ "version",
+ "prefix",
+ "includedir",
+ "libdir",
+ "cmakedir",
+ "components",
+ "cflags",
+ "cxxflags",
+ "ldflags",
+ "libs",
+ "libnames",
+ "libfiles",
+ "json",
)
- outputs.add_argument(
- "--json", action="store_true", help="Print all consumer configuration as JSON"
+ for output in outputs:
+ parser.add_argument("--" + output, dest="show_" + output, action="store_true")
+ mode = parser.add_mutually_exclusive_group()
+ mode.add_argument("--link-shared", action="store_true", help="Use shared libraries (default)")
+ mode.add_argument(
+ "--link-static", action="store_true", help="Require a complete static closure"
)
args = parser.parse_args()
- if not any((args.includedir, args.libdir, args.libfiles, args.cmakedir, args.json)):
+ if not any(getattr(args, "show_" + output) for output in outputs):
parser.print_help()
return
try:
- if args.json or args.libfiles:
- result = configuration(args.prefix, args.library_dir, args.platform)
- if args.json:
- print(json.dumps(result))
- else:
- for library in result["libraries"].values():
- print(library["implib"] or library["location"])
- else:
- prefix, library_dir = _paths(args.prefix, args.library_dir)
- if args.includedir:
- print(prefix / "include")
- elif args.libdir:
- print(library_dir)
- else:
- print(library_dir / "cmake/tvm_tirx")
- except RuntimeError as error:
+ if args.link_static:
+ raise RuntimeError(
+ "Static linking is unavailable: this package does not provide a "
+ "complete static dependency closure (including TVM FFI and its dependencies)"
+ )
+ if args.show_version:
+ print(__version__)
+ if all(not getattr(args, "show_" + output) for output in outputs if output != "version"):
+ return
+ prefix, library_dir = _paths(args.install_prefix, args.library_dir)
+ paths = {
+ "prefix": prefix,
+ "includedir": prefix / "include",
+ "libdir": library_dir,
+ "cmakedir": library_dir / "cmake/tvm_tirx",
+ }
+ if not paths["cmakedir"].is_dir() and (prefix / "cmake/tvm_tirx-config.cmake").is_file():
+ paths["cmakedir"] = prefix / "cmake"
+ for output, path in paths.items():
+ if getattr(args, "show_" + output):
+ print(path)
+ if args.show_components:
+ print(" ".join([*_available(library_dir, args.platform), "ffi"]))
+ if args.show_json:
+ print(json.dumps(configuration(prefix, library_dir, args.platform)))
+ if args.show_cflags or args.show_cxxflags:
+ ffi = _ffi_info()
+ includes = dict.fromkeys(
+ [str(prefix / "include"), ffi.find_include_path(), ffi.find_dlpack_include_path()]
+ )
+ flags = [*("-I" + path for path in includes), "-DTVM_INDEX_DEFAULT_I64=1"]
+ if args.show_cflags:
+ print(shlex.join(flags))
+ if args.show_cxxflags:
+ print(shlex.join([*flags, "-std=c++20"]))
+ if any((args.show_ldflags, args.show_libs, args.show_libnames, args.show_libfiles)):
+ libraries = _link_inputs(library_dir, args.platform, args.components)
+ apple = args.platform in ("Darwin", "iOS", "darwin")
+ if args.show_ldflags:
+ print(
+ shlex.join(
+ [
+ "-L" + str(path)
+ for path in dict.fromkeys(lib.parent for lib in libraries)
+ ]
+ )
+ )
+ if args.show_libnames:
+ print(shlex.join([lib.name for lib in libraries]))
+ if args.show_libfiles:
+ print(shlex.join([str(lib) for lib in libraries]))
+ if args.show_libs:
+ if apple:
+ flags = [
+ flag
+ for lib in libraries
+ for flag in ("-Xlinker", "-needed_library", "-Xlinker", str(lib))
+ ]
+ elif args.platform.startswith("linux") or args.platform == "Linux":
+ flags = [
+ "-Wl,--push-state,--no-as-needed",
+ *map(str, libraries),
+ "-Wl,--pop-state",
+ ]
+ else:
+ raise RuntimeError(f"--libs retention flags are unsupported on {args.platform}")
+ print(shlex.join(flags))
+ except (RuntimeError, OSError) as error:
parser.exit(1, f"{error}\n")
diff --git a/tirx/python/tvm_tirx/runtime/__init__.py b/tirx/python/tvm_tirx/runtime/__init__.py
index b9eebb95ff..aa8f098b9d 100644
--- a/tirx/python/tvm_tirx/runtime/__init__.py
+++ b/tirx/python/tvm_tirx/runtime/__init__.py
@@ -17,19 +17,54 @@
# under the License.
"""TVM runtime namespace."""
-from tvm_ffi import convert, Object
+from tvm_ffi import convert, Object, Module, load_module, system_lib
from tvm_ffi._dtype import dtype as DataType, DataTypeCode
# class exposures
from .device import Device
from .memory_scope import MemoryScope
from ._tensor import Tensor, tensor, empty
-from .module import Module
-from .executable import Executable
# function exposures
from ._tensor import device, cpu, cuda, opencl, vulkan, metal
from ._tensor import vpi, rocm, ext_dev, from_dlpack
-from .module import load_module, enabled, system_lib, load_static_library, num_threads
+from . import _ffi_api
from tvm_ffi import Shape as ShapeTuple
+
+
+def enabled(target):
+ """Whether module runtime is enabled for target
+
+ Parameters
+ ----------
+ target : str or Dict[str, Any] or tvm_tirx.target.Target
+ The target device type.
+
+ Returns
+ -------
+ enabled : bool
+ Whether runtime is enabled.
+
+ Examples
+ --------
+ The following code checks if gpu is enabled.
+
+ >>> tvm_tirx.runtime.enabled("gpu")
+ """
+ if isinstance(target, dict):
+ target = target.get("kind", "")
+ elif hasattr(target, "kind"):
+ target = target.kind.name
+ return _ffi_api.RuntimeEnabled(target)
+
+
+def num_threads() -> int:
+ """Get the number of threads in use by the TVM runtime.
+
+ Returns
+ -------
+ int
+ Number of threads in use.
+ """
+ return _ffi_api.NumThreads()
diff --git a/tirx/python/tvm_tirx/runtime/executable.py b/tirx/python/tvm_tirx/runtime/executable.py
deleted file mode 100644
index 56e1a3f482..0000000000
--- a/tirx/python/tvm_tirx/runtime/executable.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# pylint: disable=invalid-name, no-member
-
-"""Executable object for TVM Runtime"""
-
-from collections.abc import Callable
-from typing import Any
-
-from tvm_ffi import Function
-
-import tvm_tirx
-from tvm_tirx.support import utils as _utils
-
-from . import Module
-
-
-class Executable:
- """The executable object generated by `tvm.compile`."""
-
- def __init__(self, mod: Module):
- """Initialize the Executable object."""
- self.mod: Module = mod
- self._jitted_mod: Module | None = None
-
- def __getitem__(self, name: str) -> Function:
- """Get the Function from the jitted module."""
- return self.jit().get_function(name, query_imports=True)
-
- def __call__(self, *args, **kwargs) -> Any:
- """Call the executable."""
- return self.jit().main(*args, **kwargs)
-
- def jit(
- self,
- *,
- fcompile: Callable[[str, list[str], dict[str, Any]], None] | None = None,
- addons: list[str] | None = None,
- force_recompile: bool = False,
- **kwargs,
- ) -> Module:
- """Just-in-time compile and link the modules.
-
- The Executable returned by tvm.compile may not be directly
- runnable as they may contain CUDA source files and objects that
- are yet to be compiled and linked.
- This function helps to create a runtime.Module for these cases.
-
- Parameters
- ----------
- fcompile : function(target, file_list, kwargs), optional
- The compilation function to use create the final library object during
-
- addons : list of str, optional
- Additional object files to link against.
-
- force_recompile : bool, optional
- If True, force a recompile of the module.
-
- kwargs : dict, optional
- Additional arguments passed to fcompile
-
- Returns
- -------
- rt_mod: tvm_tirx.runtime.Module
- A runnable runtime module that can be passed to VirtualMachine.
-
- Examples
- --------
- .. code:: python
-
- ex = tvm.compile(mod, target)
- rt_mod = ex.jit()
-
- """
-
- # If the module is already jitted and we don't want to force a recompile,
- # return the cached module
- if self._jitted_mod is not None and not force_recompile:
- return self._jitted_mod
-
- # TODO(tvm-team): Update runtime.Module interface
- # to query these properties as bitmask.
- def _not_runnable(x):
- return x.kind in ("c", "static_library")
-
- # pylint:disable = protected-access
- not_runnable_list = self.mod._collect_from_import_tree(_not_runnable)
-
- # everything is runnable, directly return mod.
- if len(not_runnable_list) == 0:
- return self.mod
-
- # found source module, or other not runnable modules need to be export and load
- # TODO(tvm-team): Support runnable but not exportable module.
- # by collecting the link and allow export_library skip those modules.
- workspace_dir = _utils.tempdir()
- dso_path = workspace_dir.relpath("exported.so")
- self.export_library(dso_path, fcompile=fcompile, addons=addons, **kwargs)
- self._jitted_mod = tvm_tirx.runtime.load_module(dso_path)
- return self._jitted_mod
-
- def export_library(
- self,
- file_name,
- *,
- fcompile=None,
- addons=None,
- workspace_dir=None,
- **kwargs,
- ):
- """
- Export the module and all imported modules into a single device library.
-
- This function only works on host LLVM modules, other runtime::Module
- subclasses will work with this API but they must support implement
- the save and load mechanisms of modules completely including saving
- from streams and files. This will pack your non-shared library module
- into a single shared library which can later be loaded by TVM.
-
- Parameters
- ----------
- file_name : str
- The name of the shared library.
-
- fcompile : function(target, file_list, kwargs), optional
- The compilation function to use create the final library object during
- export.
-
- For example, when fcompile=_cc.create_shared, or when it is not supplied but
- module is "llvm," this is used to link all produced artifacts
- into a final dynamic library.
-
- This behavior is controlled by the type of object exported.
- If fcompile has attribute object_format, will compile host library
- to that format. Otherwise, will use default format "o".
-
- addons : list of str, optional
- Additional object files to link against.
-
- workspace_dir : str, optional
- The path of the directory used to create the intermediate
- artifacts when exporting the module.
- If this is not provided a temporary dir will be created.
-
- kwargs : dict, optional
- Additional arguments passed to fcompile
-
- Returns
- -------
- result of fcompile() : unknown, optional
- If the compilation function returns an artifact it would be returned via
- export_library, if any.
- """
- return self.mod.export_library(
- file_name,
- fcompile=fcompile,
- addons=addons,
- workspace_dir=workspace_dir,
- **kwargs,
- )
diff --git a/tirx/python/tvm_tirx/support/cc.py b/tirx/python/tvm_tirx/support/cc.py
index 476a9b9b97..5080bc308c 100644
--- a/tirx/python/tvm_tirx/support/cc.py
+++ b/tirx/python/tvm_tirx/support/cc.py
@@ -296,14 +296,16 @@ def cross_compiler(
from tvm_tirx.support import cc, ndk
# export using arm gcc
+ from tvm_tirx.codegen import Executable
+
mod = build_runtime_module()
- mod.export_library(path_dso,
+ Executable(mod).export_library(path_dso,
fcompile=cc.cross_compiler("arm-linux-gnueabihf-gcc"))
# specialize ndk compilation options.
specialized_ndk = cc.cross_compiler(
ndk.create_shared,
["--sysroot=/path/to/sysroot", "-shared", "-fPIC", "-lm"])
- mod.export_library(path_dso, fcompile=specialized_ndk)
+ Executable(mod).export_library(path_dso, fcompile=specialized_ndk)
"""
base_options = [] if options is None else options
kwargs = {}
diff --git a/tirx/python/tvm_tirx/support/ndk.py b/tirx/python/tvm_tirx/support/ndk.py
index 85b6ecb92f..b525abef2a 100644
--- a/tirx/python/tvm_tirx/support/ndk.py
+++ b/tirx/python/tvm_tirx/support/ndk.py
@@ -159,8 +159,10 @@ def get_global_symbol_section_map(path, *, nm=None) -> dict[str, str]:
@register_global_func("s_tir.meta_schedule.builder.export_ndk")
def _ndk_export(mod):
+ from tvm_tirx.codegen import Executable # pylint: disable=import-outside-toplevel
+
tmp_dir = tempfile.mkdtemp()
binary_name = "tmp_binary.so"
binary_path = Path(tmp_dir) / binary_name
- mod.export_library(binary_path, fcompile=create_shared)
+ Executable(mod).export_library(binary_path, fcompile=create_shared)
return str(binary_path)
diff --git a/tirx/python/tvm_tirx/tirx/_compile.py b/tirx/python/tvm_tirx/tirx/_compile.py
index 6d2a6f18b1..f88c114ee2 100644
--- a/tirx/python/tvm_tirx/tirx/_compile.py
+++ b/tirx/python/tvm_tirx/tirx/_compile.py
@@ -22,8 +22,8 @@ from tvm_ffi import DLDeviceType
import tvm_tirx
from tvm_tirx import ir
+from tvm_tirx.codegen import Executable
from tvm_tirx.ir.module import IRModule
-from tvm_tirx.runtime import Executable
from tvm_tirx.target import Target
from tvm_tirx.tirx import Function
@@ -180,7 +180,7 @@ def compile( # pylint: disable=redefined-builtin
Returns
-------
- tvm_tirx.runtime.Executable
+ tvm_tirx.codegen.Executable
An executable combining both host and device code.
"""
# Convert Function to IRModule
diff --git a/tirx/src/runtime/timer.cc b/tirx/src/runtime/timer.cc
deleted file mode 100644
index 16014401b8..0000000000
--- a/tirx/src/runtime/timer.cc
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file src/runtime/timer.cc
- * \brief Runtime timer primitives: Timer, WrapTimeEvaluator.
- */
-
-#include <tvm/ffi/extra/module.h>
-#include <tvm/ffi/function.h>
-#include <tvm/ffi/reflection/registry.h>
-#include <tvm/runtime/c_backend_api.h>
-#include <tvm/runtime/device_api.h>
-#include <tvm/runtime/logging.h>
-#include <tvm/runtime/timer.h>
-
-#include <chrono>
-#include <mutex>
-#include <set>
-#include <sstream>
-#include <thread>
-#if defined(_M_X64) || defined(__x86_64__)
-#include <immintrin.h>
-#endif
-
-namespace tvm {
-namespace runtime {
-
-class DefaultTimerObj : public TimerObj {
- public:
- virtual void Start() {
- DeviceAPI::Get(device_)->StreamSync(device_, nullptr);
- start_ = std::chrono::high_resolution_clock::now();
- }
- virtual void Stop() {
- DeviceAPI::Get(device_)->StreamSync(device_, nullptr);
- duration_ = std::chrono::high_resolution_clock::now() - start_;
- }
- virtual int64_t SyncAndGetElapsedNanos() { return duration_.count(); }
- virtual ~DefaultTimerObj() {}
-
- explicit DefaultTimerObj(Device dev) : device_(dev) {}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.DefaultTimer", DefaultTimerObj, TimerObj);
-
- private:
- std::chrono::high_resolution_clock::time_point start_;
- std::chrono::duration<int64_t, std::nano> duration_;
- Device device_;
-};
-
-static Timer DefaultTimer(Device dev) {
- return Timer(ffi::UnsafeInit{}, ffi::make_object<DefaultTimerObj>(dev));
-}
-
-class CPUTimerObj : public TimerObj {
- public:
- virtual void Start() { start_ = std::chrono::high_resolution_clock::now(); }
- virtual void Stop() { duration_ = std::chrono::high_resolution_clock::now() - start_; }
- virtual int64_t SyncAndGetElapsedNanos() { return duration_.count(); }
- virtual ~CPUTimerObj() {}
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("runtime.CPUTimer", CPUTimerObj, TimerObj);
-
- private:
- std::chrono::high_resolution_clock::time_point start_;
- std::chrono::duration<int64_t, std::nano> duration_;
-};
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef().def("runtime.timer.cpu", [](Device dev) {
- return Timer(ffi::UnsafeInit{}, ffi::make_object<CPUTimerObj>());
- });
-}
-
-Timer Timer::Start(Device dev) {
- // Function-local statics: thread-safe lazy init (C++11 magic statics),
- // visible only to this function.
- static std::set<DLDeviceType> seen_devices;
- static std::mutex seen_devices_lock;
- auto f = tvm::ffi::Function::GetGlobal(std::string("runtime.timer.") +
- DLDeviceType2Str(dev.device_type));
- if (!f.has_value()) {
- {
- std::lock_guard<std::mutex> lock(seen_devices_lock);
- if (seen_devices.find(dev.device_type) == seen_devices.end()) {
- LOG(WARNING)
- << "No timer implementation for " << DLDeviceType2Str(dev.device_type)
- << ", using default timer instead. It may be inaccurate or have extra overhead.";
- seen_devices.insert(dev.device_type);
- }
- }
- Timer t = DefaultTimer(dev);
- t->Start();
- return t;
- } else {
- Timer t = f->operator()(dev).cast<Timer>();
- t->Start();
- return t;
- }
-}
-
-static ffi::Function WrapTimeEvaluator(ffi::Function pf, Device dev, int number, int repeat,
- int min_repeat_ms, int limit_zero_time_iterations,
- int cooldown_interval_ms, int repeats_to_cooldown,
- int cache_flush_bytes, ffi::Function f_preproc) {
- TVM_FFI_ICHECK(pf != nullptr);
-
- auto ftimer = [pf, dev, number, repeat, min_repeat_ms, limit_zero_time_iterations,
- cooldown_interval_ms, repeats_to_cooldown, cache_flush_bytes,
- f_preproc](const ffi::AnyView* args, int num_args, ffi::Any* rv) mutable {
- ffi::Any temp;
- std::ostringstream os;
- // skip first time call, to activate lazy compilation components.
- pf.CallPacked(args, num_args, &temp);
-
- // allocate two large arrays to flush L2 cache
- ffi::Optional<ffi::Tensor> arr1, arr2;
- if (cache_flush_bytes > 0) {
- arr1 = tvm::runtime::Empty({cache_flush_bytes / 4}, {kDLInt, 32, 1}, dev);
- arr2 = tvm::runtime::Empty({cache_flush_bytes / 4}, {kDLInt, 32, 1}, dev);
- }
-
- DeviceAPI::Get(dev)->StreamSync(dev, nullptr);
-
- for (int i = 0; i < repeat; ++i) {
- if (f_preproc != nullptr) {
- f_preproc.CallPacked(args, num_args, &temp);
- }
- double duration_ms = 0.0;
- int absolute_zero_times = 0;
- do {
- if (duration_ms > 0.0) {
- const double golden_ratio = 1.618;
- number = static_cast<int>(
- std::max((min_repeat_ms / (duration_ms / number) + 1), number * golden_ratio));
- }
- if (cache_flush_bytes > 0) {
- tvm::runtime::CopyFromTo(arr2.value().GetDLTensorPtr(), arr1.value().GetDLTensorPtr());
- }
- DeviceAPI::Get(dev)->StreamSync(dev, nullptr);
- // start timing
- Timer t = Timer::Start(dev);
- for (int j = 0; j < number; ++j) {
- pf.CallPacked(args, num_args, &temp);
- }
- t->Stop();
- int64_t t_nanos = t->SyncAndGetElapsedNanos();
- if (t_nanos == 0) absolute_zero_times++;
- duration_ms = t_nanos / 1e6;
- } while (duration_ms < min_repeat_ms && absolute_zero_times < limit_zero_time_iterations);
-
- double speed = duration_ms / 1e3 / number;
- os.write(reinterpret_cast<char*>(&speed), sizeof(speed));
-
- if (cooldown_interval_ms > 0 && (i % repeats_to_cooldown) == 0) {
- std::this_thread::sleep_for(std::chrono::milliseconds(cooldown_interval_ms));
- }
- }
-
- std::string blob = os.str();
- // return the time.
- *rv = ffi::Bytes(std::move(blob));
- };
- return ffi::Function::FromPacked(ftimer);
-}
-
-/*!
- * \brief Flush the cache.
- * \param addr The address of data we want to flush
- * \param len The length of data
- */
-/*
- * When we are in the tuning of TVM, we will make TVM occupy
- * the cache fully and doesn't flush it during iteration.
- * This has problems then in e2e testing, since arrays that
- * we assume exist in cache (ie. weights) are evicted during e2e runs,
- * which leads to lower performance.
- */
-inline void CPUCacheFlushImpl(const char* addr, unsigned int len) {
-#if (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__))
-
-#if defined(__aarch64__)
- size_t ctr_el0 = 0;
- asm volatile("mrs %0, ctr_el0" : "=r"(ctr_el0));
- const size_t cache_line = 4 << ((ctr_el0 >> 16) & 15);
-#else
- const size_t cache_line = 64;
-#endif
-
- if (addr == nullptr || len <= 0) {
- return;
- }
-
- for (uintptr_t uptr = (uintptr_t)addr & ~(cache_line - 1); uptr < (uintptr_t)addr + len;
- uptr += cache_line) {
-#if defined(__aarch64__)
- asm volatile("dc civac, %0\n\t" : : "r"(reinterpret_cast<const void*>(uptr)) : "memory");
-#else
- _mm_clflush(reinterpret_cast<const void*>(uptr));
-#endif
- }
-
-#if defined(__aarch64__)
- asm volatile("dmb ishst" : : : "memory");
-#endif
-
-#endif
-}
-
-inline void CPUCacheFlush(int begin_index, const ffi::PackedArgs& args) {
- for (int i = begin_index; i < args.size(); i++) {
- CPUCacheFlushImpl(static_cast<char*>((args[i].cast<DLTensor*>()->data)),
- ffi::GetDataSize(*(args[i].cast<DLTensor*>())));
- }
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
- namespace refl = tvm::ffi::reflection;
- refl::GlobalDef()
- .def("runtime.LocalTimeEvaluator",
- [](ffi::Optional<ffi::Module> opt_mod, std::string name, int device_type, int device_id,
- int number, int repeat, int min_repeat_ms, int limit_zero_time_iterations,
- int cooldown_interval_ms, int repeats_to_cooldown, int cache_flush_bytes,
- std::string f_preproc_name) {
- Device dev{static_cast<DLDeviceType>(device_type), device_id};
- auto pf = opt_mod.has_value() ? opt_mod.value()->GetFunction(name)
- : ffi::Function::GetGlobal(name);
- TVM_FFI_ICHECK(pf.has_value()) << "Cannot find " << name;
- ffi::Function f_preproc;
- if (!f_preproc_name.empty()) {
- f_preproc = ffi::Function::GetGlobalRequired(f_preproc_name);
- }
- return WrapTimeEvaluator(*pf, dev, number, repeat, min_repeat_ms,
- limit_zero_time_iterations, cooldown_interval_ms,
- repeats_to_cooldown, cache_flush_bytes, f_preproc);
- })
- .def("runtime.ModuleTimeEvaluator",
- [](ffi::Module mod, std::string name, ffi::AnyView device, int number, int repeat,
- int min_repeat_ms, int limit_zero_time_iterations, int cooldown_interval_ms,
- int repeats_to_cooldown, int cache_flush_bytes, std::string f_preproc_name) {
- if (std::string(mod->kind()) == "rpc") {
- return ffi::Function::GetGlobalRequired("rpc.ModuleTimeEvaluator")(
- mod, name, device, number, repeat, min_repeat_ms,
- limit_zero_time_iterations, cooldown_interval_ms, repeats_to_cooldown,
- cache_flush_bytes, f_preproc_name)
- .cast<ffi::Function>();
- }
- auto dev = device.cast<DLDevice>();
- return ffi::Function::GetGlobalRequired("runtime.LocalTimeEvaluator")(
- mod, name, static_cast<int>(dev.device_type), dev.device_id, number, repeat,
- min_repeat_ms, limit_zero_time_iterations, cooldown_interval_ms,
- repeats_to_cooldown, cache_flush_bytes, f_preproc_name)
- .cast<ffi::Function>();
- })
- .def_packed("runtime.CacheFlushCPUArguments",
- [](ffi::PackedArgs args, ffi::Any* rv) { CPUCacheFlush(1, args); });
-}
-
-} // namespace runtime
-} // namespace tvm
diff --git a/tirx/tests/cpp/CMakeLists.txt b/tirx/tests/cpp/CMakeLists.txt
index f1fae95c49..95802d605b 100644
--- a/tirx/tests/cpp/CMakeLists.txt
+++ b/tirx/tests/cpp/CMakeLists.txt
@@ -38,7 +38,7 @@ endif()
include(GoogleTest)
file(GLOB_RECURSE _test_sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.cc")
add_executable(tirx_cpptest ${_test_sources})
-target_link_libraries(tirx_cpptest PRIVATE tvm_tirx ${_gtest_targets} ${CMAKE_DL_LIBS})
+target_link_libraries(tirx_cpptest PRIVATE tvm_tirx_compiler ${_gtest_targets} ${CMAKE_DL_LIBS})
if(TVM_TIRX_USE_THREADS)
target_link_libraries(tirx_cpptest PRIVATE Threads::Threads)
endif()
diff --git a/tirx/tests/python/all-platform-minimal-test/test_validate_runtime_library.py b/tirx/tests/python/all-platform-minimal-test/test_validate_runtime_library.py
index d076481def..ea92272ea6 100644
--- a/tirx/tests/python/all-platform-minimal-test/test_validate_runtime_library.py
+++ b/tirx/tests/python/all-platform-minimal-test/test_validate_runtime_library.py
@@ -14,21 +14,24 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-"""Post-install checks for a built TVM wheel.
+"""Post-install runtime and AOT checks.
These live in ``tests/python/all-platform-minimal-test`` so the standard suite and
the cibuildwheel ``test-command`` run a single pytest invocation. The assertions
-here are wheel-specific things the rest of the suite cannot check -- that LLVM is
+for wheel packaging check things the rest of the suite cannot check -- that LLVM is
enabled (the other LLVM test merely *skips* when LLVM is absent) and that the CUDA
runtime library got bundled -- so each is gated behind a ``TVM_WHEEL_EXPECT_*`` env
var and SKIPS unless that var is set. cibuildwheel sets the vars (see
``CIBW_TEST_ENVIRONMENT`` in ``.github/actions/build-wheel-for-publish``); ordinary
source-build CI (e.g. ``main.yml``) leaves them unset, so these tests skip there and
-never fail a non-wheel / non-LLVM / non-CUDA build.
+never fail a non-wheel / non-LLVM / non-CUDA build. The CPU AOT case also runs
+on Linux/macOS source builds with LLVM enabled.
"""
import glob
import os
+import subprocess
+import sys
from pathlib import Path
import pytest
@@ -54,3 +57,37 @@ def test_cuda_runtime_present():
str(libdir / "tvm_runtime_cuda.*")
)
assert present, "CUDA runtime expected but not bundled in tvm/lib"
+
+
+def test_cpu_aot(tmp_path):
+ if sys.platform not in ("linux", "darwin") or not tvm_tirx.runtime.enabled("llvm"):
+ pytest.skip("CPU AOT requires Linux/macOS and LLVM")
+ from tvm_tirx.script import tirx as T
+
+ @T.function
+ def add_one(A: T.Tensor((16,), "int32", align=4), B: T.Tensor((16,), "int32", align=4)):
+ for i in range(16):
+ B[i] = A[i] + 1
+
+ module = tvm_tirx.tirx.compile(add_one, target="llvm")
+ path = tmp_path / "model.so"
+ module.export_library(path)
+ subprocess.run(
+ [
+ sys.executable,
+ "-c",
+ """
+import sys
+import numpy as np
+import tvm_ffi
+module = tvm_ffi.load_module(sys.argv[1])
+a = np.arange(16, dtype="int32")
+b = np.empty_like(a)
+module["add_one"](tvm_ffi.from_dlpack(a), tvm_ffi.from_dlpack(b))
+np.testing.assert_array_equal(b, a + 1)
+assert "tvm" not in sys.modules and "tvm_tirx" not in sys.modules
+""",
+ str(path),
+ ],
+ check=True,
+ )
diff --git a/tirx/tests/python/backend/cuda/codegen/test_fastmath.py b/tirx/tests/python/backend/cuda/codegen/test_fastmath.py
index c8bfdc2858..ad420eb38b 100644
--- a/tirx/tests/python/backend/cuda/codegen/test_fastmath.py
+++ b/tirx/tests/python/backend/cuda/codegen/test_fastmath.py
@@ -26,8 +26,8 @@ import pytest
import tvm_tirx
import tvm_tirx.testing
import tvm_tirx.tirx as tirx
+from tvm_tirx.codegen import Executable
from tvm_tirx.ir.module import IRModule
-from tvm_tirx.runtime.executable import Executable
from tvm_tirx.script import tirx as T
from tvm_tirx.support.nvcc import have_fp16
from tvm_tirx.testing import env
diff --git a/tirx/tests/python/codegen/c/test_basic.py b/tirx/tests/python/codegen/c/test_basic.py
index 28349fb7d9..9dd738f428 100644
--- a/tirx/tests/python/codegen/c/test_basic.py
+++ b/tirx/tests/python/codegen/c/test_basic.py
@@ -230,7 +230,7 @@ def test_workspace_allocation_cast():
assert "((float*)TVMBackendAllocWorkspace(" in built.inspect_source()
temp = utils.tempdir()
- built.export_library(temp.relpath("workspace.so"))
+ tvm_tirx.codegen.Executable(built).export_library(temp.relpath("workspace.so"))
def test_local_alloc_buffer_uses_plain_c_pointer():
@@ -248,7 +248,7 @@ def test_local_alloc_buffer_uses_plain_c_pointer():
temp = utils.tempdir()
path_dso = temp.relpath("local_alloc.so")
- built.export_library(path_dso)
+ tvm_tirx.codegen.Executable(built).export_library(path_dso)
loaded = tvm_tirx.runtime.load_module(path_dso)
data = tvm_tirx.runtime.tensor(np.array([1.0], dtype="float32"))
@@ -288,7 +288,7 @@ def test_if_then_else_avoids_extraneous_parentheses():
temp = utils.tempdir()
path_dso = temp.relpath("if_then_else.so")
- built.export_library(path_dso)
+ tvm_tirx.codegen.Executable(built).export_library(path_dso)
loaded = tvm_tirx.runtime.load_module(path_dso)
a = tvm_tirx.runtime.tensor(np.arange(8, dtype="int32"))
diff --git a/tirx/tests/python/codegen/test_executable.py b/tirx/tests/python/codegen/test_executable.py
new file mode 100644
index 0000000000..c34036065b
--- /dev/null
+++ b/tirx/tests/python/codegen/test_executable.py
@@ -0,0 +1,145 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Executable export, JIT, and static import coverage."""
+
+import shlex
+import subprocess
+import sys
+
+import pytest
+
+import tvm_tirx
+import tvm_tirx.testing
+from tvm_tirx.codegen import Executable
+from tvm_tirx.script import tirx as T
+from tvm_tirx.support import cc
+from tvm_tirx.testing import env
+
+
+def test_import_static_library(source_module, native_compile_options, tmp_path):
+ source = tmp_path / "other.cc"
+ source.write_text(
+ "#include <tvm/ffi/function.h>\n"
+ "int other() { return 17; }\n"
+ "TVM_FFI_DLL_EXPORT_TYPED_FUNC(other, other);\n"
+ )
+ obj = tmp_path / "other.o"
+ cc.create_shared(str(obj), [str(source)], options=["-c", *native_compile_options])
+ imported = tvm_tirx.codegen.load_static_library(str(obj), ["other"])
+ assert imported.implements_function("other")
+ assert imported.is_compilation_exportable()
+ source_module.import_module(imported)
+ path = tmp_path / "combined.so"
+ Executable(source_module).export_library(str(path), options=native_compile_options)
+ loaded = tvm_tirx.runtime.load_module(str(path))
+ assert loaded.kind == "library"
+ assert len(loaded.imports) == 0
+ for name, expected in (("answer", 42), ("other", 17)):
+ assert loaded.implements_function(name)
+ assert loaded.get_function(name)() == expected
+ assert not loaded.is_compilation_exportable()
+
+
+def test_executable_init(source_module):
+ executable = Executable(source_module)
+ assert executable.mod is source_module
+ assert executable._jitted_mod is None
+
+
+def test_executable_getitem(source_module, native_compile_options):
+ executable = Executable(source_module)
+ executable.jit(options=native_compile_options)
+ assert executable["answer"]() == 42
+
+
+def test_executable_jit_already_runnable(native_library):
+ module = tvm_tirx.runtime.load_module(str(native_library))
+ executable = Executable(module)
+ assert executable.jit() is module
+ assert executable.jit(force_recompile=True) is module
+ assert executable["answer"]() == 42
+
+
+def test_executable_jit_force_recompile(source_module, native_compile_options):
+ executable = Executable(source_module)
+ first = executable.jit(options=native_compile_options)
+ assert executable.jit() is first
+ rebuilt = executable.jit(force_recompile=True, options=native_compile_options)
+ assert rebuilt is not first
+ assert first["answer"]() == rebuilt["answer"]() == 42
+
+
+@pytest.mark.parametrize("use_workspace", [False, True])
+def test_executable_export_library(source_module, native_compile_options, tmp_path, use_workspace):
+ kwargs = {"options": native_compile_options}
+ if use_workspace:
+ workspace = tmp_path / "workspace"
+ workspace.mkdir()
+ kwargs["workspace_dir"] = str(workspace)
+ path = tmp_path / "module.so"
+ Executable(source_module).export_library(str(path), **kwargs)
+ assert path.is_file()
+ assert tvm_tirx.runtime.load_module(str(path))["answer"]() == 42
+
+
+@pytest.mark.gpu
+def test_cuda_aot(tmp_path):
+ if sys.platform != "linux" or not env.has_cuda() or not tvm_tirx.runtime.enabled("llvm"):
+ pytest.skip("CUDA AOT requires Linux CUDA and an LLVM host compiler")
+ pytest.importorskip("torch")
+
+ @T.function
+ def add_one(A: T.Tensor((16,), "int32"), B: T.Tensor((16,), "int32")):
+ with T.launch_thread("blockIdx.x", 1):
+ with T.launch_thread("threadIdx.x", 16) as i:
+ B[i] = A[i] + 1
+
+ module = tvm_tirx.tirx.compile(add_one, target=tvm_tirx.target.Target("cuda", host="llvm"))
+ path = tmp_path / "model.so"
+ options = shlex.split(
+ subprocess.check_output(
+ [sys.executable, "-m", "tvm_tirx.config", "--ldflags", "--libs", "runtime", "cuda"],
+ text=True,
+ )
+ )
+ library_dir = subprocess.check_output(
+ [sys.executable, "-m", "tvm_tirx.config", "--libdir"], text=True
+ ).strip()
+ module.export_library(path, options=[*options, "-Wl,-rpath," + library_dir])
+ subprocess.run(
+ [
+ sys.executable,
+ "-c",
+ """
+import sys
+import torch
+import tvm_ffi
+module = tvm_ffi.load_module(sys.argv[1])
+a = torch.arange(16, dtype=torch.int32, device="cuda")
+b = torch.empty_like(a)
+module["add_one"](a, b)
+torch.testing.assert_close(b, a + 1)
+assert "tvm" not in sys.modules and "tvm_tirx" not in sys.modules
+""",
+ str(path),
+ ],
+ check=True,
+ )
+
+
+if __name__ == "__main__":
+ tvm_tirx.testing.main()
diff --git a/tirx/tests/python/conftest.py b/tirx/tests/python/conftest.py
new file mode 100644
index 0000000000..42a3cb04b1
--- /dev/null
+++ b/tirx/tests/python/conftest.py
@@ -0,0 +1,78 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Shared native module fixtures for runtime and code generation coverage."""
+
+import pytest
+
+
+@pytest.fixture(scope="module")
+def native_source():
+ return r"""
+#include <tvm/ffi/container/tensor.h>
+#include <tvm/ffi/function.h>
+void add_one(tvm::ffi::TensorView a, tvm::ffi::TensorView b) {
+ for (int64_t i = 0; i < a.size(0); ++i) {
+ static_cast<float*>(b.data_ptr())[i] = static_cast<float*>(a.data_ptr())[i] + 1;
+ }
+}
+int64_t answer() { return 42; }
+void callback(tvm::ffi::Function func) { func(); }
+TVM_FFI_DLL_EXPORT_TYPED_FUNC(main, add_one);
+TVM_FFI_DLL_EXPORT_TYPED_FUNC(answer, answer);
+TVM_FFI_DLL_EXPORT_TYPED_FUNC(callback, callback);
+"""
+
+
+@pytest.fixture(scope="module")
+def native_compile_options():
+ import tvm_ffi
+
+ return [
+ "-std=c++17",
+ "-I" + tvm_ffi.libinfo.find_include_path(),
+ "-I" + tvm_ffi.libinfo.find_dlpack_include_path(),
+ ]
+
+
+@pytest.fixture
+def source_module(native_source):
+ import tvm_tirx
+
+ return tvm_tirx.runtime._ffi_api.CSourceModuleCreate(
+ native_source, "cc", ["main", "answer", "callback"], None
+ )
+
+
+@pytest.fixture(scope="module")
+def native_object(tmp_path_factory, native_source, native_compile_options):
+ from tvm_tirx.support import cc
+
+ directory = tmp_path_factory.mktemp("runtime_module")
+ source = directory / "module.cc"
+ source.write_text(native_source)
+ path = directory / "module.o"
+ cc.create_shared(str(path), [str(source)], options=["-c", *native_compile_options])
+ return path
+
+
+@pytest.fixture(scope="module")
+def native_library(native_object):
+ from tvm_tirx.support import cc
+
+ path = native_object.with_suffix(".so")
+ cc.create_shared(str(path), [str(native_object)])
+ return path
diff --git a/tirx/tests/python/runtime/test_module.py b/tirx/tests/python/runtime/test_module.py
index c1dc2bc86b..dbcc77d73a 100644
--- a/tirx/tests/python/runtime/test_module.py
+++ b/tirx/tests/python/runtime/test_module.py
@@ -14,12 +14,11 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-"""Runtime module loading, properties, exports, timing, and Executable wrappers."""
+"""Runtime and FFI module loading and properties."""
import os
import subprocess
import sys
-import time
import numpy as np
import pytest
@@ -27,62 +26,9 @@ import tvm_ffi
import tvm_tirx
import tvm_tirx.testing
-from tvm_tirx.runtime import Executable
-from tvm_tirx.runtime.module import BenchmarkResult
from tvm_tirx.support import cc
-@pytest.fixture(scope="module")
-def native_source():
- return r"""
-#include <tvm/ffi/container/tensor.h>
-#include <tvm/ffi/function.h>
-void add_one(tvm::ffi::TensorView a, tvm::ffi::TensorView b) {
- for (int64_t i = 0; i < a.size(0); ++i) {
- static_cast<float*>(b.data_ptr())[i] = static_cast<float*>(a.data_ptr())[i] + 1;
- }
-}
-int64_t answer() { return 42; }
-void callback(tvm::ffi::Function func) { func(); }
-TVM_FFI_DLL_EXPORT_TYPED_FUNC(main, add_one);
-TVM_FFI_DLL_EXPORT_TYPED_FUNC(answer, answer);
-TVM_FFI_DLL_EXPORT_TYPED_FUNC(callback, callback);
-"""
-
-
-@pytest.fixture(scope="module")
-def native_compile_options():
- return [
- "-std=c++17",
- "-I" + tvm_ffi.libinfo.find_include_path(),
- "-I" + tvm_ffi.libinfo.find_dlpack_include_path(),
- ]
-
-
-@pytest.fixture
-def source_module(native_source):
- return tvm_tirx.runtime._ffi_api.CSourceModuleCreate(
- native_source, "cc", ["main", "answer", "callback"], None
- )
-
-
-@pytest.fixture(scope="module")
-def native_object(tmp_path_factory, native_source, native_compile_options):
- directory = tmp_path_factory.mktemp("runtime_module")
- source = directory / "module.cc"
- source.write_text(native_source)
- path = directory / "module.o"
- cc.create_shared(str(path), [str(source)], options=["-c", *native_compile_options])
- return path
-
-
-@pytest.fixture(scope="module")
-def native_library(native_object):
- path = native_object.with_suffix(".so")
- cc.create_shared(str(path), [str(native_object)])
- return path
-
-
@pytest.fixture(scope="module")
def system_library_source(native_source):
return (
@@ -101,6 +47,11 @@ static RegisterSystemLibrary register_system_library;
def test_module_properties(source_module, native_library):
+ assert tvm_tirx.runtime.Module is tvm_ffi.Module
+ assert tvm_tirx.runtime.load_module is tvm_ffi.load_module
+ assert tvm_tirx.runtime.system_lib is tvm_ffi.system_lib
+ assert not hasattr(source_module, "export_library")
+ assert not hasattr(source_module, "time_evaluator")
assert source_module.is_binary_serializable()
assert not source_module.is_runnable()
assert source_module.is_compilation_exportable()
@@ -141,30 +92,6 @@ np.testing.assert_equal(b.numpy(), a.numpy() + 1)
)
-def test_import_static_library(source_module, native_compile_options, tmp_path):
- source = tmp_path / "other.cc"
- source.write_text(
- "#include <tvm/ffi/function.h>\n"
- "int other() { return 17; }\n"
- "TVM_FFI_DLL_EXPORT_TYPED_FUNC(other, other);\n"
- )
- obj = tmp_path / "other.o"
- cc.create_shared(str(obj), [str(source)], options=["-c", *native_compile_options])
- imported = tvm_tirx.runtime.load_static_library(str(obj), ["other"])
- assert imported.implements_function("other")
- assert imported.is_compilation_exportable()
- source_module.import_module(imported)
- path = tmp_path / "combined.so"
- source_module.export_library(str(path), options=native_compile_options)
- loaded = tvm_tirx.runtime.load_module(str(path))
- assert loaded.kind == "library"
- assert len(loaded.imports) == 0
- for name, expected in (("answer", 42), ("other", 17)):
- assert loaded.implements_function(name)
- assert loaded.get_function(name)() == expected
- assert not loaded.is_compilation_exportable()
-
-
@pytest.mark.skipif(sys.platform == "win32", reason="system library registration on Unix")
def test_system_library(system_library_source, native_compile_options, tmp_path):
source = tmp_path / "system.cc"
@@ -194,72 +121,5 @@ np.testing.assert_equal(b.numpy(), a.numpy() + 1)
)
-def test_min_repeat_ms(native_library):
- calls = []
-
- def callback():
- time.sleep(0.1)
- calls.append(1)
-
- module = tvm_tirx.runtime.load_module(str(native_library))
- module.time_evaluator("callback", tvm_tirx.cpu(), number=1, repeat=1)(callback)
- assert len(calls) == 2
- module.time_evaluator("callback", tvm_tirx.cpu(), number=1, repeat=1, min_repeat_ms=1000)(
- callback
- )
- assert len(calls) > 12
-
-
-def test_benchmark_result():
- result = BenchmarkResult([1, 2, 2, 5])
- assert result.mean == 2.5
- assert result.median == 2.0
- assert result.min == 1
- assert result.max == 5
- assert result.std == 1.5
-
-
-def test_executable_init(source_module):
- executable = Executable(source_module)
- assert executable.mod is source_module
- assert executable._jitted_mod is None
-
-
-def test_executable_getitem(source_module, native_compile_options):
- executable = Executable(source_module)
- executable.jit(options=native_compile_options)
- assert executable["answer"]() == 42
-
-
-def test_executable_jit_already_runnable(native_library):
- module = tvm_tirx.runtime.load_module(str(native_library))
- executable = Executable(module)
- assert executable.jit() is module
- assert executable.jit(force_recompile=True) is module
- assert executable["answer"]() == 42
-
-
-def test_executable_jit_force_recompile(source_module, native_compile_options):
- executable = Executable(source_module)
- first = executable.jit(options=native_compile_options)
- assert executable.jit() is first
- rebuilt = executable.jit(force_recompile=True, options=native_compile_options)
- assert rebuilt is not first
- assert first["answer"]() == rebuilt["answer"]() == 42
-
-
-@pytest.mark.parametrize("use_workspace", [False, True])
-def test_executable_export_library(source_module, native_compile_options, tmp_path, use_workspace):
- kwargs = {"options": native_compile_options}
- if use_workspace:
- workspace = tmp_path / "workspace"
- workspace.mkdir()
- kwargs["workspace_dir"] = str(workspace)
- path = tmp_path / "module.so"
- Executable(source_module).export_library(str(path), **kwargs)
- assert path.is_file()
- assert tvm_tirx.runtime.load_module(str(path))["answer"]() == 42
-
-
if __name__ == "__main__":
tvm_tirx.testing.main()
diff --git a/tirx/tests/python/runtime/test_tirx_config.py b/tirx/tests/python/runtime/test_tirx_config.py
index 648ef0309a..ae68e8799f 100644
--- a/tirx/tests/python/runtime/test_tirx_config.py
+++ b/tirx/tests/python/runtime/test_tirx_config.py
@@ -17,8 +17,11 @@
"""The config command must work without importing native runtime dependencies."""
import os
+import shlex
+import shutil
import subprocess
import sys
+import sysconfig
from pathlib import Path
import tvm_tirx
@@ -35,7 +38,7 @@ def test_config_without_native_imports(tmp_path):
" raise AssertionError(fullname)\n"
"sys.meta_path.insert(0, BlockNative())\n"
"def audit(event, args):\n"
- " if event == 'ctypes.dlopen': raise AssertionError(args)\n"
+ " if event == 'ctypes.dlopen' and args[0] is not None: raise AssertionError(args)\n"
"sys.addaudithook(audit)\n"
)
env = dict(os.environ)
@@ -45,14 +48,39 @@ def test_config_without_native_imports(tmp_path):
str(Path(tvm_tirx.__file__).parent.parent),
)
)
- command = [sys.executable, "-m", "tvm_tirx.config"]
- include = subprocess.check_output([*command, "--includedir"], env=env, text=True).strip()
- assert (Path(include) / "tvm" / "runtime").is_dir()
- libraries = subprocess.check_output([*command, "--libfiles"], env=env, text=True).splitlines()
- assert len(libraries) == 2
- assert all(Path(library).is_file() for library in libraries)
- cmake_dir = subprocess.check_output([*command, "--cmakedir"], env=env, text=True).strip()
- assert (Path(cmake_dir) / "tvm_tirx-config.cmake").is_file()
+ for entry in ("module", "console"):
+ command = [sys.executable, "-m", "tvm_tirx.config"]
+ if entry == "console":
+ executable = Path(sysconfig.get_path("scripts")) / "tvm-tirx-config"
+ if not executable.is_file():
+ continue
+ command = [str(executable)]
+ include = subprocess.check_output([*command, "--includedir"], env=env, text=True).strip()
+ assert (Path(include) / "tvm" / "runtime").is_dir()
+ libraries = subprocess.check_output(
+ [*command, "--libfiles", "runtime"], env=env, text=True
+ ).strip()
+ libraries = shlex.split(libraries)
+ assert len(libraries) == 2
+ assert all(Path(library).is_file() for library in libraries)
+ cmake_dir = subprocess.check_output([*command, "--cmakedir"], env=env, text=True).strip()
+ assert (Path(cmake_dir) / "tvm_tirx-config.cmake").is_file()
+ if shutil.which("c++") and sys.platform != "win32":
+ _check_config_public_headers_compile()
+
+
+def _check_config_public_headers_compile():
+ flags = shlex.split(
+ subprocess.check_output(
+ [sys.executable, "-m", "tvm_tirx.config", "--cxxflags", "runtime"], text=True
+ )
+ )
+ subprocess.run(
+ ["c++", *flags, "-x", "c++", "-fsyntax-only", "-"],
+ input="#include <tvm/runtime/base.h>\n#include <tvm/ffi/container/tensor.h>\n",
+ text=True,
+ check=True,
+ )
if __name__ == "__main__":
diff --git a/tirx/tests/python/support/test_config.py b/tirx/tests/python/support/test_config.py
index 76788bc50f..009847d985 100644
--- a/tirx/tests/python/support/test_config.py
+++ b/tirx/tests/python/support/test_config.py
@@ -19,10 +19,12 @@
import importlib.util
import json
import os
+import shlex
import shutil
import subprocess
import sys
from pathlib import Path
+from types import SimpleNamespace
import pytest
@@ -39,14 +41,21 @@ def _installation(prefix, libdir="lib", windows=False):
library_dir = prefix / libdir
cmake_dir = library_dir / "cmake/tvm_tirx"
cmake_dir.mkdir(parents=True)
- for name in ("tvm_tirx", "tvm_runtime"):
+ for name in ("tvm_tirx_compiler", "tvm_runtime"):
filenames = (f"{name}.dll", f"{name}.lib") if windows else (f"lib{name}.so",)
for filename in filenames:
(library_dir / filename).touch()
return library_dir
-def test_exact_library_directory_and_relocation(tmp_path):
+def test_exact_library_directory_and_relocation(tmp_path, monkeypatch, capsys):
+ _check_component_closure_and_artifacts(tmp_path / "closure", monkeypatch)
+ for platform in ("linux", "darwin"):
+ _check_cli_link_flags_and_raw_inputs(tmp_path / platform, monkeypatch, capsys, platform)
+ _check_unavailable_static_is_not_silently_shared(tmp_path / "static")
+ _check_runtime_only_lib64_and_explicit_prefix_ignore_environment(
+ tmp_path / "runtime", monkeypatch
+ )
prefix = tmp_path / "native install"
libdir = _installation(prefix, "lib/x86_64-linux-gnu")
(libdir / "libtvm_runtime_static.a").touch()
@@ -54,7 +63,7 @@ def test_exact_library_directory_and_relocation(tmp_path):
(libdir / "libtvm_ffi.so").touch()
result = config.configuration(library_dir=libdir, platform="Linux")
assert result["include_dir"] == str(prefix / "include")
- assert set(result["libraries"]) == {"tvm_tirx", "tvm_runtime"}
+ assert set(result["libraries"]) == {"tvm_tirx_compiler", "tvm_runtime"}
assert set(result) == {"version", "include_dir", "library_dir", "cmake_dir", "libraries"}
moved = tmp_path / "relocated"
shutil.copytree(prefix, moved)
@@ -70,7 +79,7 @@ def test_prefix_selects_installed_lib64(tmp_path):
result = config.configuration(prefix=prefix, platform="Linux")
assert result["library_dir"] == str(libdir)
result = subprocess.run(
- [sys.executable, str(_CONFIG_PATH), "--prefix", str(prefix), "--cmakedir"],
+ [sys.executable, str(_CONFIG_PATH), "--install-prefix", str(prefix), "--cmakedir"],
check=True,
text=True,
capture_output=True,
@@ -80,14 +89,14 @@ def test_prefix_selects_installed_lib64(tmp_path):
config.configuration(library_dir=prefix / "lib", platform="Linux")
-@pytest.mark.parametrize("name", ["tvm_tirx", "tvm_runtime"])
+@pytest.mark.parametrize("name", ["tvm_tirx_compiler", "tvm_runtime"])
def test_windows_library_pairing(tmp_path, name):
libdir = _installation(tmp_path / "windows", windows=True)
(libdir / "tvm_runtime_static.lib").touch()
(libdir / "tvm_runtime_cuda.dll").touch()
(libdir / "tvm_runtime_cuda.lib").touch()
result = config.configuration(library_dir=libdir, platform="Windows")
- assert set(result["libraries"]) == {"tvm_tirx", "tvm_runtime"}
+ assert set(result["libraries"]) == {"tvm_tirx_compiler", "tvm_runtime"}
assert result["libraries"][name] == {
"location": str(libdir / f"{name}.dll"),
"implib": str(libdir / f"{name}.lib"),
@@ -115,7 +124,7 @@ def test_module_cli_without_native_dependencies(tmp_path):
env = os.environ.copy()
env["PYTHONPATH"] = str(_CONFIG_PATH.parents[1])
result = subprocess.run(
- [sys.executable, "-S", "-m", "tvm_tirx.config", "--prefix", str(prefix), "--json"],
+ [sys.executable, "-S", "-m", "tvm_tirx.config", "--install-prefix", str(prefix), "--json"],
cwd=tmp_path,
env=env,
check=True,
@@ -143,10 +152,10 @@ find_package(tvm_tirx CONFIG REQUIRED)
get_property(imported DIRECTORY PROPERTY IMPORTED_TARGETS)
list(FILTER imported EXCLUDE REGEX "^Python::")
list(SORT imported)
-if(NOT "${imported}" STREQUAL "tvm_runtime::shared;tvm_tirx::header;tvm_tirx::shared")
+if(NOT "${imported}" STREQUAL "tvm_runtime::shared;tvm_tirx::header;tvm_tirx_compiler::shared")
message(FATAL_ERROR "Unexpected imported targets: ${imported}")
endif()
-foreach(target tvm_tirx::header tvm_tirx::shared tvm_runtime::shared)
+foreach(target tvm_tirx::header tvm_tirx_compiler::shared tvm_runtime::shared)
get_target_property(links ${target} INTERFACE_LINK_LIBRARIES)
if(links MATCHES "ffi|OpenMP|Threads")
message(FATAL_ERROR "Unexpected implicit dependency: ${links}")
@@ -170,3 +179,106 @@ endforeach()
text=True,
capture_output=True,
)
+
+
+def _check_component_closure_and_artifacts(tmp_path, monkeypatch):
+ libdir = _installation(tmp_path / "install")
+ for filename in ("libtvm_runtime_cuda.so", "libtvm_runtime_metal.so", "libtvm_ffi.so"):
+ (libdir / filename).touch()
+ monkeypatch.setattr(
+ config,
+ "_ffi_info",
+ lambda: SimpleNamespace(find_libtvm_ffi=lambda: str(libdir / "libtvm_ffi.so")),
+ )
+
+ def names(components):
+ return [path.name for path in config._link_inputs(libdir, "linux", components)]
+
+ assert names(["runtime", "cuda", "runtime", "ffi"]) == [
+ "libtvm_runtime_cuda.so",
+ "libtvm_runtime.so",
+ "libtvm_ffi.so",
+ ]
+ assert names(["compiler"]) == ["libtvm_tirx_compiler.so", "libtvm_runtime.so", "libtvm_ffi.so"]
+ assert names([]) == names(["all"])
+ assert len(names([])) == len(set(names([])))
+ assert names(["ffi"]) == ["libtvm_ffi.so"]
+ with pytest.raises(RuntimeError, match="Component 'missing' is unavailable"):
+ names(["missing"])
+
+
+def _check_cli_link_flags_and_raw_inputs(tmp_path, monkeypatch, capsys, platform):
+ prefix = tmp_path / "native prefix"
+ libdir = _installation(prefix)
+ suffix = "dylib" if platform == "darwin" else "so"
+ for name in ("tvm_runtime", "tvm_tirx_compiler", "tvm_ffi"):
+ (libdir / f"lib{name}.{suffix}").touch()
+ monkeypatch.setattr(
+ config,
+ "_ffi_info",
+ lambda: SimpleNamespace(find_libtvm_ffi=lambda: str(libdir / f"libtvm_ffi.{suffix}")),
+ )
+
+ def run(*options):
+ monkeypatch.setattr(
+ sys,
+ "argv",
+ [
+ "tvm-tirx-config",
+ "--install-prefix",
+ str(prefix),
+ "--platform",
+ platform,
+ *options,
+ "runtime",
+ ],
+ )
+ config.__main__()
+ return shlex.split(capsys.readouterr().out)
+
+ inputs = run("--libfiles")
+ assert inputs == [
+ str(libdir / f"libtvm_runtime.{suffix}"),
+ str(libdir / f"libtvm_ffi.{suffix}"),
+ ]
+ assert run("--libnames") == [Path(path).name for path in inputs]
+ assert run("--ldflags") == ["-L" + str(libdir)]
+ flags = run("--libs", "--link-shared")
+ if platform == "linux":
+ assert flags == ["-Wl,--push-state,--no-as-needed", *inputs, "-Wl,--pop-state"]
+ else:
+ assert flags == [
+ flag for path in inputs for flag in ("-Xlinker", "-needed_library", "-Xlinker", path)
+ ]
+
+
+def _check_unavailable_static_is_not_silently_shared(tmp_path):
+ prefix = tmp_path / "install"
+ libdir = _installation(prefix)
+ (libdir / "libtvm_runtime_static.a").touch()
+ result = subprocess.run(
+ [
+ sys.executable,
+ str(_CONFIG_PATH),
+ "--install-prefix",
+ str(prefix),
+ "--link-static",
+ "--libs",
+ "runtime",
+ ],
+ capture_output=True,
+ text=True,
+ )
+ assert result.returncode != 0
+ assert "complete static dependency closure" in result.stderr
+ assert not result.stdout
+
+
+def _check_runtime_only_lib64_and_explicit_prefix_ignore_environment(tmp_path, monkeypatch):
+ prefix = tmp_path / "runtime-only"
+ libdir = _installation(prefix, "lib64")
+ (libdir / "libtvm_tirx_compiler.so").unlink()
+ unrelated = _installation(tmp_path / "unrelated")
+ monkeypatch.setenv("TVM_TIRX_LIBRARY_PATH", str(unrelated))
+ assert config._paths(prefix, None) == (prefix, libdir)
+ assert config._available(libdir, "linux") == ["runtime"]
diff --git a/tirx/tests/python/tirx/iket/test_profiler.py b/tirx/tests/python/tirx/iket/test_profiler.py
index 8669194de2..c4a549a3c7 100644
--- a/tirx/tests/python/tirx/iket/test_profiler.py
+++ b/tirx/tests/python/tirx/iket/test_profiler.py
@@ -33,6 +33,7 @@ import pytest
import tvm_tirx
from tvm_tirx.backend.cuda import transforms as cuda_transforms
+from tvm_tirx.codegen import Executable
from tvm_tirx.script import tirx as T
from tvm_tirx.testing import env
from tvm_tirx.tirx.cuda.iket import IketProfiler
@@ -305,7 +306,7 @@ def _compile(func, *, target=TARGET):
def _cuda_source(executable):
- modules = executable.mod._collect_from_import_tree( # pylint: disable=protected-access
+ modules = Executable(executable.mod)._collect_from_import_tree( # pylint: disable=protected-access
lambda module: module.kind == "cuda"
)
assert len(modules) == 1
@@ -789,7 +790,7 @@ def test_multi_kernel_module_has_no_tvm_control_plane():
assert "__iket_evt_decl_a_1_attrs" in source
assert "__iket_evt_decl_b_2_attrs" in source
assert "plain_entry_kernel" in source
- for module in executable.mod._collect_from_import_tree(lambda _module: True):
+ for module in Executable(executable.mod)._collect_from_import_tree(lambda _module: True):
for control_name in (
"__tvm_iket_get_metadata",
"__tvm_iket_set_context",
(tvm) 08/12: [META] Add ASF configuration and standalone FFI submodule mapping
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 9a242ed23eb89267072dc4900b859f08d020d40f
Author: tqchen <ti...@gmail.com>
AuthorDate: Fri Oct 16 02:36:17 2026 +0000
[META] Add ASF configuration and standalone FFI submodule mapping
---
.asf.yaml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
.gitmodules | 3 +++
2 files changed, 51 insertions(+)
diff --git a/.asf.yaml b/.asf.yaml
new file mode 100644
index 0000000000..d46f0ba488
--- /dev/null
+++ b/.asf.yaml
@@ -0,0 +1,48 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+github:
+ description: "Open ML Compiler Foundation"
+ homepage: https://tvm.apache.org/
+ labels:
+ - tvm
+ - compiler
+ - tirx
+ - gpu
+
+ features:
+ issues: true
+ projects: true
+
+ protected_branches:
+ main:
+ required_pull_request_reviews:
+ required_approving_review_count: 1
+
+ enabled_merge_buttons:
+ squash: true
+ squash_commit_message: PR_TITLE_AND_DESC
+ merge: false
+ merge_commit_message: DEFAULT
+ rebase: false
+
+notifications:
+ commits: commits@tvm.apache.org
+ issues: discuss-archive@tvm.apache.org
+ pullrequests: discuss-archive@tvm.apache.org
+ jobs: discuss-archive@tvm.apache.org
+ discussions: discuss-archive@tvm.apache.org
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000..8fc9e209d6
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "3rdparty/tvm-ffi"]
+ path = 3rdparty/tvm-ffi
+ url = https://github.com/apache/tvm-ffi
(tvm) 06/12: [TIRx] Simplify Python APIs and configuration discovery (#20766)
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 80d645d82403170018c27e65c323a226433f8e3b
Author: Tianqi Chen <tq...@users.noreply.github.com>
AuthorDate: Fri Oct 16 16:25:56 2026 -0400
[TIRx] Simplify Python APIs and configuration discovery (#20766)
Organize TIRx's Python APIs by moving IndexMap into its own module and
LLVM helpers under `codegen.llvm`. Use the existing s_tir attribute
checks directly, remove the empty dialect backend package, and place
public operator declarations before private helpers.
Centralize configuration discovery in `libinfo.py` and share it with
package and native configuration commands. Replace legacy exception
classes with builtin exceptions while retaining FFI error messages and
subprocess cleanup. Remove the environment-probe test module and move
wheel library validation into the runtime suite with updated packaging
and CI selectors.
---
tirx/CMakeLists.txt | 9 +-
.../__init__.py => cmake/tvm-tirx-config.in} | 10 +-
tirx/pyproject.toml | 2 +-
tirx/python/tvm_tirx/__init__.py | 28 +-
tirx/python/tvm_tirx/backend/metal/target_tags.py | 4 +-
tirx/python/tvm_tirx/codegen/__init__.py | 204 +------------
.../tvm_tirx/codegen/{__init__.py => llvm.py} | 72 +----
tirx/python/tvm_tirx/config.py | 152 +---------
tirx/python/tvm_tirx/error.py | 126 --------
tirx/python/tvm_tirx/ir/op.py | 230 +++++++-------
tirx/python/tvm_tirx/libinfo.py | 149 ++++++++-
tirx/python/tvm_tirx/support/clang.py | 2 +-
tirx/python/tvm_tirx/support/rocm.py | 2 +-
tirx/python/tvm_tirx/testing/env.py | 8 +-
tirx/python/tvm_tirx/tirx/__init__.py | 4 +-
tirx/python/tvm_tirx/tirx/function.py | 297 +-----------------
.../tvm_tirx/tirx/{function.py => index_map.py} | 169 +----------
tirx/python/tvm_tirx/tirx/op/__init__.py | 4 +-
tirx/python/tvm_tirx/tirx/script/ir_builder/op.py | 2 +-
.../tirx/script/ir_builder/parser_protocol.py | 2 +-
.../python/backend/metal/codegen/test_basic.py | 12 +-
.../python/backend/webgpu/codegen/test_basic.py | 20 +-
tirx/tests/python/codegen/llvm/test_aarch64.py | 36 +--
tirx/tests/python/codegen/llvm/test_basic.py | 22 +-
tirx/tests/python/codegen/llvm/test_riscv.py | 2 +-
.../python/codegen/llvm/test_scalable_vector.py | 8 +-
tirx/tests/python/codegen/llvm/test_x86.py | 2 +-
.../test_validate_wheel_library.py} | 4 +-
tirx/tests/python/script/test_basic_usage.py | 4 +-
tirx/tests/python/support/test_config.py | 11 +-
.../tests/python/target/test_llvm_features_info.py | 34 +--
tirx/tests/python/target/test_riscv_features.py | 6 +-
tirx/tests/python/target/test_x86_features.py | 8 +-
tirx/tests/python/testing/test_env.py | 332 ---------------------
.../tirx/analysis/test_check_well_defined.py | 24 +-
tirx/tests/python/tirx/base/test_imm_values.py | 4 +-
.../python/tirx/base/test_scalable_datatype.py | 8 +-
tirx/tests/python/tirx/codegen/test_cuda.py | 6 +-
tirx/tests/python/tirx/codegen/test_hopper.py | 2 +-
tirx/tests/python/tirx/codegen/test_ptx_addr.py | 4 +-
tirx/tests/python/tirx/codegen/test_ptx_dialect.py | 2 +-
tirx/tests/python/tirx/script/test_basic_usage.py | 8 +-
tirx/tests/python/tirx/test_cuda_backend_config.py | 2 +-
tirx/tests/python/tirx/tile/test_dispatcher.py | 2 +-
.../tests/python/tirx/transform/test_lower_tirx.py | 2 +-
.../python/tirx/transform/test_make_packed_api.py | 4 +-
.../tirx/transform/test_split_host_device.py | 2 +-
tirx/tests/python/tirx/transform/test_vectorize.py | 16 +-
48 files changed, 448 insertions(+), 1615 deletions(-)
diff --git a/tirx/CMakeLists.txt b/tirx/CMakeLists.txt
index 4001e955d9..d2581b2b5f 100644
--- a/tirx/CMakeLists.txt
+++ b/tirx/CMakeLists.txt
@@ -292,14 +292,19 @@ install(TARGETS tvm_tirx_header tvm_tirx_compiler tvm_runtime tvm_runtime_static
# CMake package and dependency helpers
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/tvm_tirx-config.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_tirx/config.py"
+ "${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_tirx/libinfo.py"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/tvm_tirx" COMPONENT tvm_tirx)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils/"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/tvm_tirx/utils"
COMPONENT tvm_tirx FILES_MATCHING PATTERN "Find*.cmake")
if(NOT TVM_TIRX_BUILD_PYTHON_MODULE)
- install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_tirx/config.py"
- DESTINATION "${CMAKE_INSTALL_BINDIR}" RENAME tvm-tirx-config COMPONENT tvm_tirx)
+ file(RELATIVE_PATH TVM_TIRX_CONFIG_PREFIX_RELATIVE
+ "${CMAKE_INSTALL_FULL_BINDIR}" "${CMAKE_INSTALL_PREFIX}")
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/tvm-tirx-config.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/tvm-tirx-config" @ONLY)
+ install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/tvm-tirx-config"
+ DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT tvm_tirx)
endif()
# Python package artifacts and licenses
diff --git a/tirx/python/tvm_tirx/tirx/backend/__init__.py b/tirx/cmake/tvm-tirx-config.in
similarity index 69%
rename from tirx/python/tvm_tirx/tirx/backend/__init__.py
rename to tirx/cmake/tvm-tirx-config.in
index 6f5333629f..ebe607d13e 100644
--- a/tirx/python/tvm_tirx/tirx/backend/__init__.py
+++ b/tirx/cmake/tvm-tirx-config.in
@@ -1,3 +1,4 @@
+#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -14,4 +15,11 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-"""TIRx backend compatibility package."""
+"""Run the configuration helper installed with the native CMake package."""
+
+import runpy
+from pathlib import Path
+
+prefix = (Path(__file__).resolve().parent / "@TVM_TIRX_CONFIG_PREFIX_RELATIVE@").resolve()
+config = runpy.run_path(str(prefix / "@CMAKE_INSTALL_LIBDIR@" / "cmake/tvm_tirx/config.py"))
+config["__main__"]()
diff --git a/tirx/pyproject.toml b/tirx/pyproject.toml
index 4ef79dcb0c..333c1e8696 100644
--- a/tirx/pyproject.toml
+++ b/tirx/pyproject.toml
@@ -143,7 +143,7 @@ markers = [
skip = "*-win32 *-manylinux_i686 *-musllinux*"
build-verbosity = 1
test-requires = ["pytest", "numpy"]
-test-command = "python -I -c \"import importlib.util; assert importlib.util.find_spec('tvm') is None\" && python -I -m pytest -vvs {package}/tests/python/all-platform-minimal-test {package}/tests/python/runtime/test_tensor.py {package}/tests/python/ir/test_type.py {package}/tests/python/script/test_ir_builder.py {package}/tests/python/codegen/llvm/test_basic.py::test_llvm_vadd_pipeline {package}/tests/python/codegen/gpu_common/test_allreduce.py::test_allreduce_sum_compile"
+test-command = "python -I -c \"import importlib.util; assert importlib.util.find_spec('tvm') is None\" && python -I -m pytest -vvs {package}/tests/python/runtime/test_validate_wheel_library.py {package}/tests/python/runtime/test_tensor.py {package}/tests/python/ir/test_type.py {package}/tests/python/script/test_ir_builder.py {package}/tests/python/codegen/llvm/test_basic.py::test_llvm_vadd_pipeline {package}/tests/python/codegen/gpu_common/test_allreduce.py::test_allreduce_sum_compile"
[tool.cibuildwheel.linux]
repair-wheel-command = "auditwheel repair --exclude libtvm_ffi.so --exclude libtvm_runtime_cuda.so --exclude 'libcuda.so.*' --exclude 'libcudart.so.*' --exclude 'libnvrtc.so.*' --exclude 'libnvrtc-builtins.so.*' -w {dest_dir} {wheel}"
diff --git a/tirx/python/tvm_tirx/__init__.py b/tirx/python/tvm_tirx/__init__.py
index fcdeb1f0bd..8244906d9c 100644
--- a/tirx/python/tvm_tirx/__init__.py
+++ b/tirx/python/tvm_tirx/__init__.py
@@ -49,9 +49,6 @@ if TYPE_CHECKING or not _is_config_mode():
from .runtime._tensor import vpi, rocm, ext_dev, hexagon
from .runtime import DataType, DataTypeCode
- # tvm.error
- from . import error
-
# tvm.ir
from .ir import IRModule, transform
from . import ir
@@ -83,35 +80,12 @@ if TYPE_CHECKING or not _is_config_mode():
# Side-effect imports: register CUDA/ROCm FFI callbacks at TVM startup
from .support import rocm as _rocm, nvcc as _nvcc
- # NOTE: This file should be python2 compatible so we can
- # raise proper error message when user run the package using
- # an older version of the python
-
- def _should_print_backtrace():
- in_pytest = "PYTEST_CURRENT_TEST" in os.environ
- tvm_backtrace = os.environ.get("TVM_BACKTRACE", "0")
-
- try:
- tvm_backtrace = bool(int(tvm_backtrace))
- except ValueError:
- raise ValueError(
- f"invalid value for TVM_BACKTRACE {tvm_backtrace}, please set to 0 or 1."
- )
-
- return in_pytest or tvm_backtrace
-
def tvm_wrap_excepthook(exception_hook):
"""Wrap given excepthook with TVM additional work."""
def wrapper(exctype, value, trbk):
"""Clean subprocesses when TVM is interrupted."""
- if exctype is error.DiagnosticError and not _should_print_backtrace():
- # TODO(@jroesch): consider moving to C++?
- print(
- "note: run with `TVM_BACKTRACE=1` environment variable to display a backtrace."
- )
- else:
- exception_hook(exctype, value, trbk)
+ exception_hook(exctype, value, trbk)
if hasattr(multiprocessing, "active_children"):
# pylint: disable=not-callable
diff --git a/tirx/python/tvm_tirx/backend/metal/target_tags.py b/tirx/python/tvm_tirx/backend/metal/target_tags.py
index 30f406c963..b1073c0e1e 100644
--- a/tirx/python/tvm_tirx/backend/metal/target_tags.py
+++ b/tirx/python/tvm_tirx/backend/metal/target_tags.py
@@ -23,9 +23,9 @@ _METAL_HOST_TRIPLE = "arm64-apple-macos"
def _register_metal_tag(name, max_threads, shared_mem, warp_size, mcpu):
try:
- from tvm_tirx.codegen import llvm_is_valid_cpu
+ from tvm_tirx.codegen import llvm
- if not llvm_is_valid_cpu(mcpu, _METAL_HOST_TRIPLE):
+ if not llvm.is_valid_cpu(mcpu, _METAL_HOST_TRIPLE):
return
except Exception: # pylint: disable=broad-except
pass # LLVM not available; register unconditionally
diff --git a/tirx/python/tvm_tirx/codegen/__init__.py b/tirx/python/tvm_tirx/codegen/__init__.py
index afc5fc7c3f..5396028ac1 100644
--- a/tirx/python/tvm_tirx/codegen/__init__.py
+++ b/tirx/python/tvm_tirx/codegen/__init__.py
@@ -20,6 +20,7 @@ from tvm_ffi import Array, get_global_func
from tvm_tirx.target import Target
+from . import llvm
from .executable import Executable, load_static_library
@@ -65,206 +66,3 @@ def target_has_features(cpu_features, target=None):
for feat in cpu_features:
has_feats &= get_global_func("codegen.target_has_feature")(feat, target)
return has_feats
-
-
-def llvm_lookup_intrinsic_id(name):
- """Lookup LLVM intrinsic id by name.
-
- Parameters
- ----------
- name : str
- The name of the intrinsic.
-
- Returns
- -------
- intrin_id : int
- The intrinsic id.
- """
- return get_global_func("codegen.llvm_lookup_intrinsic_id")(name)
-
-
-def llvm_get_intrinsic_name(intrin_id: int) -> str:
- """Get the name of an intrinsic for a given id.
-
- Parameters
- ----------
- intrin_id : int
- The id of the intrinsic.
-
- Returns
- -------
- name : str
- The name of the intrinsic.
- """
- return get_global_func("codegen.llvm_get_intrinsic_name")(intrin_id)
-
-
-def llvm_get_system_x86_vendor():
- """Get system x86 vendor info.
-
- Parameters
- ----------
-
- Returns
- -------
- vendor : str
- The current system's cpu vendor.
- """
- return get_global_func("codegen.llvm_get_system_x86_vendor")()
-
-
-def llvm_get_system_triple():
- """Get system host triple.
-
- Parameters
- ----------
-
- Returns
- -------
- triple : str
- The current system's triple.
- """
- return get_global_func("codegen.llvm_get_system_triple")()
-
-
-def llvm_get_system_cpu():
- """Get system host cpu name.
-
- Parameters
- ----------
-
- Returns
- -------
- cpu_name : str
- The current system's cpu name.
- """
- return get_global_func("codegen.llvm_get_system_cpu")()
-
-
-def llvm_get_targets():
- """Get LLVM target list.
-
- Parameters
- ----------
-
- Returns
- -------
- llvm_targets : list[str]
- List of available LLVM targets.
- """
- return get_global_func("codegen.llvm_get_targets")()
-
-
-def llvm_get_cpu_archlist(target=None):
- """Get CPU architectures for the target's `-mtriple`.
-
- Parameters
- ----------
- target : Target
- The TVM target.
-
- Returns
- -------
- cpu_archlist : list[str]
- List of available CPU architectures.
- """
- assert isinstance(target, Target) or target is None
- return get_global_func("codegen.llvm_get_cpu_archlist")(target)
-
-
-def llvm_get_cpu_features(target=None):
- """Get CPU features for the target's `-mtriple` and `-mcpu` and considering `-mattr`.
-
- Parameters
- ----------
- target : Target
- The TVM target.
-
- Returns
- -------
- cpu_features : list[str]
- List of available CPU features.
- """
- assert isinstance(target, Target) or target is None
- feature_map = get_global_func("codegen.llvm_get_cpu_features")(target)
- return set(feature_map.keys())
-
-
-def llvm_cpu_has_features(cpu_features, target=None):
- """Check CPU features for the target's `-mtriple` and `-mcpu` and considering `-mattr`.
-
- Parameters
- ----------
- target : Target
- The TVM target.
- cpu_features : str or Array
- CPU Feature(s) to check.
-
- Returns
- -------
- has_features : bool
- True if target CPU has the feature(s).
- """
- assert isinstance(target, Target) or target is None
- assert isinstance(cpu_features, Array | list | tuple | str)
- has_feats = True
- cpu_features = [cpu_features] if isinstance(cpu_features, str) else cpu_features
- for feat in cpu_features:
- has_feats &= get_global_func("codegen.llvm_cpu_has_feature")(feat, target)
- return has_feats
-
-
-def llvm_get_vector_width(target=None):
- """Get vector width from LLVM target's `-mtriple` and `-mcpu` and considering `-mattr`.
-
- Parameters
- ----------
- target : Target
- The TVM target.
-
- Returns
- -------
- vector_width : int
- Vector with of target in number of bits, -1 on error.
- """
- assert isinstance(target, Target) or target is None
- return get_global_func("codegen.llvm_get_vector_width")(target)
-
-
-def llvm_is_valid_cpu(cpu, triple):
- """Check if a CPU name is valid for the given LLVM triple.
-
- Parameters
- ----------
- cpu : str
- The CPU name to check (e.g. "apple-m1").
- triple : str
- The LLVM target triple (e.g. "arm64-apple-macos").
-
- Returns
- -------
- is_valid : bool
- True if the CPU name is recognized by LLVM for the given triple.
- """
- return get_global_func("codegen.llvm_is_valid_cpu")(cpu, triple)
-
-
-def llvm_version_major(allow_none=False):
- """Get the major LLVM version.
-
- Parameters
- ----------
- allow_none : bool
- Whether do we allow none.
-
- Returns
- -------
- major : int
- The major LLVM version.
- """
- try:
- return get_global_func("codegen.llvm_version_major")()
- except (ValueError, AttributeError):
- if allow_none:
- return None
- raise RuntimeError("LLVM version is not available, please check if you built TVM with LLVM")
diff --git a/tirx/python/tvm_tirx/codegen/__init__.py b/tirx/python/tvm_tirx/codegen/llvm.py
similarity index 75%
copy from tirx/python/tvm_tirx/codegen/__init__.py
copy to tirx/python/tvm_tirx/codegen/llvm.py
index afc5fc7c3f..8734fea963 100644
--- a/tirx/python/tvm_tirx/codegen/__init__.py
+++ b/tirx/python/tvm_tirx/codegen/llvm.py
@@ -14,60 +14,14 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-"""Code generation related functions."""
+"""LLVM code generation and target information."""
from tvm_ffi import Array, get_global_func
from tvm_tirx.target import Target
-from .executable import Executable, load_static_library
-
-def build_module(mod, target):
- """Build IRModule into Module.
-
- Parameters
- ----------
- mod : tvm_tirx.IRModule
- The ir module.
-
- target : str
- The target module type.
-
- Returns
- -------
- module : runtime.Module
- The corresponding module.
- """
- target = Target(target) if isinstance(target, str) else target
- return get_global_func("codegen.Build")(mod, target)
-
-
-def target_has_features(cpu_features, target=None):
- """Check CPU features for the target's `-mtriple` and `-mcpu` and `-mattr`.
-
- Parameters
- ----------
- target : Target
- The TVM target.
- cpu_features : str or Array
- CPU Feature(s) to check.
-
- Returns
- -------
- has_features : bool
- True if target has the feature(s).
- """
- assert isinstance(target, Target) or target is None
- assert isinstance(cpu_features, Array | list | tuple | str)
- has_feats = True
- cpu_features = [cpu_features] if isinstance(cpu_features, str) else cpu_features
- for feat in cpu_features:
- has_feats &= get_global_func("codegen.target_has_feature")(feat, target)
- return has_feats
-
-
-def llvm_lookup_intrinsic_id(name):
+def lookup_intrinsic_id(name):
"""Lookup LLVM intrinsic id by name.
Parameters
@@ -83,7 +37,7 @@ def llvm_lookup_intrinsic_id(name):
return get_global_func("codegen.llvm_lookup_intrinsic_id")(name)
-def llvm_get_intrinsic_name(intrin_id: int) -> str:
+def get_intrinsic_name(intrin_id: int) -> str:
"""Get the name of an intrinsic for a given id.
Parameters
@@ -99,7 +53,7 @@ def llvm_get_intrinsic_name(intrin_id: int) -> str:
return get_global_func("codegen.llvm_get_intrinsic_name")(intrin_id)
-def llvm_get_system_x86_vendor():
+def get_system_x86_vendor():
"""Get system x86 vendor info.
Parameters
@@ -113,7 +67,7 @@ def llvm_get_system_x86_vendor():
return get_global_func("codegen.llvm_get_system_x86_vendor")()
-def llvm_get_system_triple():
+def get_system_triple():
"""Get system host triple.
Parameters
@@ -127,7 +81,7 @@ def llvm_get_system_triple():
return get_global_func("codegen.llvm_get_system_triple")()
-def llvm_get_system_cpu():
+def get_system_cpu():
"""Get system host cpu name.
Parameters
@@ -141,7 +95,7 @@ def llvm_get_system_cpu():
return get_global_func("codegen.llvm_get_system_cpu")()
-def llvm_get_targets():
+def get_targets():
"""Get LLVM target list.
Parameters
@@ -155,7 +109,7 @@ def llvm_get_targets():
return get_global_func("codegen.llvm_get_targets")()
-def llvm_get_cpu_archlist(target=None):
+def get_cpu_archlist(target=None):
"""Get CPU architectures for the target's `-mtriple`.
Parameters
@@ -172,7 +126,7 @@ def llvm_get_cpu_archlist(target=None):
return get_global_func("codegen.llvm_get_cpu_archlist")(target)
-def llvm_get_cpu_features(target=None):
+def get_cpu_features(target=None):
"""Get CPU features for the target's `-mtriple` and `-mcpu` and considering `-mattr`.
Parameters
@@ -190,7 +144,7 @@ def llvm_get_cpu_features(target=None):
return set(feature_map.keys())
-def llvm_cpu_has_features(cpu_features, target=None):
+def cpu_has_features(cpu_features, target=None):
"""Check CPU features for the target's `-mtriple` and `-mcpu` and considering `-mattr`.
Parameters
@@ -214,7 +168,7 @@ def llvm_cpu_has_features(cpu_features, target=None):
return has_feats
-def llvm_get_vector_width(target=None):
+def get_vector_width(target=None):
"""Get vector width from LLVM target's `-mtriple` and `-mcpu` and considering `-mattr`.
Parameters
@@ -231,7 +185,7 @@ def llvm_get_vector_width(target=None):
return get_global_func("codegen.llvm_get_vector_width")(target)
-def llvm_is_valid_cpu(cpu, triple):
+def is_valid_cpu(cpu, triple):
"""Check if a CPU name is valid for the given LLVM triple.
Parameters
@@ -249,7 +203,7 @@ def llvm_is_valid_cpu(cpu, triple):
return get_global_func("codegen.llvm_is_valid_cpu")(cpu, triple)
-def llvm_version_major(allow_none=False):
+def version_major(allow_none=False):
"""Get the major LLVM version.
Parameters
diff --git a/tirx/python/tvm_tirx/config.py b/tirx/python/tvm_tirx/config.py
index 466a30fe14..da829bb6dc 100644
--- a/tirx/python/tvm_tirx/config.py
+++ b/tirx/python/tvm_tirx/config.py
@@ -22,88 +22,21 @@ there with an exact library directory, independently of Python package search.
"""
import argparse
-import importlib.machinery
import importlib.util
import json
-import os
import shlex
import sys
from pathlib import Path
-__version__ = "0.1.0a0"
-
-_LIBRARY_NAMES = ("tvm_tirx_compiler", "tvm_runtime")
-_COMPONENTS = {
- "compiler": "tvm_tirx_compiler",
- "runtime": "tvm_runtime",
- "cuda": "tvm_runtime_cuda",
- "metal": "tvm_runtime_metal",
- "opencl": "tvm_runtime_opencl",
- "vulkan": "tvm_runtime_vulkan",
- "rocm": "tvm_runtime_rocm",
-}
-
-
-def _find_prefix(start: Path) -> Path:
- for candidate in (start, *start.parents):
- if (candidate / "include/tvm/runtime/base.h").is_file():
- return candidate
- raise RuntimeError(f"Cannot find TIRx public headers above {start}")
-
-
-def _paths(prefix: Path | None, library_dir: Path | None) -> tuple[Path, Path]:
- explicit_prefix = prefix is not None
- if library_dir is not None:
- library_dir = library_dir.resolve()
- prefix = prefix.resolve() if prefix is not None else _find_prefix(library_dir)
- else:
- prefix = prefix.resolve() if prefix is not None else _find_prefix(Path(__file__).parent)
- library_dir = prefix / "lib"
- candidates = [prefix / "lib", prefix / "lib64", prefix / "build/lib"]
- if prefix.name == "tirx":
- candidates.append(prefix.parent / "build/lib")
- if not explicit_prefix and os.environ.get("TVM_TIRX_LIBRARY_PATH"):
- candidates.insert(0, Path(os.environ["TVM_TIRX_LIBRARY_PATH"]))
- for candidate in candidates:
- if all(
- any(
- (candidate / filename).is_file()
- for filename in (f"lib{name}.so", f"lib{name}.dylib", f"{name}.dll")
- )
- for name in ("tvm_runtime",)
- ):
- library_dir = candidate
- break
- if not (prefix / "include/tvm/runtime/base.h").is_file():
- raise RuntimeError(f"Cannot find TIRx public headers in {prefix / 'include'}")
- return prefix, library_dir
-
-
-def _libraries(library_dir: Path, platform: str, names=_LIBRARY_NAMES) -> dict[str, dict[str, str]]:
- libraries = {}
- windows = platform in ("Windows", "win32")
- apple = platform in ("Darwin", "iOS", "darwin")
- for name in names:
- if windows:
- filenames = (f"{name}.dll",)
- elif apple:
- filenames = (f"lib{name}.dylib", f"lib{name}.so")
- else:
- filenames = (f"lib{name}.so",)
- location = next((library_dir / f for f in filenames if (library_dir / f).is_file()), None)
- if location is None:
- raise RuntimeError(f"Cannot find TIRx library {name} in {library_dir}")
- implib = ""
- if windows:
- import_names = (f"{name}.lib", f"lib{name}.dll.a")
- import_library = next(
- (library_dir / f for f in import_names if (library_dir / f).is_file()), None
- )
- if import_library is None:
- raise RuntimeError(f"Missing import library for {location}")
- implib = str(import_library)
- libraries[name] = {"location": str(location), "implib": implib}
- return libraries
+if __package__:
+ from . import libinfo
+else:
+ # The native CMake package installs the pure Python helper beside this file.
+ spec = importlib.util.spec_from_file_location(
+ "_tvm_tirx_libinfo", Path(__file__).with_name("libinfo.py")
+ )
+ libinfo = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(libinfo)
def configuration(
@@ -112,62 +45,7 @@ def configuration(
platform: str = sys.platform,
) -> dict:
"""Return the public include and core shared-library paths for one installation."""
- prefix, library_dir = _paths(prefix, library_dir)
- return {
- "version": __version__,
- "include_dir": str(prefix / "include"),
- "library_dir": str(library_dir),
- "cmake_dir": str(library_dir / "cmake/tvm_tirx"),
- "libraries": _libraries(library_dir, platform),
- }
-
-
-def _ffi_info():
- """Read the selected FFI package's pure Python helper without importing its runtime."""
- spec = importlib.machinery.PathFinder.find_spec("tvm_ffi")
- if spec is None or spec.origin is None:
- raise RuntimeError("Cannot find the matching apache-tvm-ffi Python package")
- helper = Path(spec.origin).parent / "libinfo.py"
- spec = importlib.util.spec_from_file_location("_tvm_ffi_libinfo", helper)
- module = importlib.util.module_from_spec(spec)
- spec.loader.exec_module(module)
- return module
-
-
-def _available(library_dir, platform):
- available = []
- for component, name in _COMPONENTS.items():
- try:
- _libraries(library_dir, platform, (name,))
- except RuntimeError:
- continue
- available.append(component)
- return available
-
-
-def _link_inputs(library_dir, platform, components):
- available = _available(library_dir, platform)
- selected = list(dict.fromkeys(components or ["all"]))
- if "all" in selected:
- selected = [*available, *(name for name in selected if name != "all")]
- for name in selected:
- if name != "ffi" and name not in available:
- raise RuntimeError(
- f"Component '{name}' is unavailable; available: {' '.join(available)} ffi"
- )
- # Dependents precede their dependencies even if the command line lists runtime first.
- ordered = [name for name in selected if name not in ("runtime", "ffi")]
- if any(name != "ffi" for name in selected):
- ordered.append("runtime")
- libraries = _libraries(library_dir, platform, [_COMPONENTS[name] for name in ordered])
- ffi = _ffi_info()
- ffi_library = (
- ffi.find_windows_implib() if platform in ("Windows", "win32") else ffi.find_libtvm_ffi()
- )
- return [
- *(Path(lib["implib"] or lib["location"]) for lib in libraries.values()),
- Path(ffi_library),
- ]
+ return libinfo.configuration(prefix, library_dir, platform)
def __main__() -> None:
@@ -216,10 +94,10 @@ def __main__() -> None:
"complete static dependency closure (including TVM FFI and its dependencies)"
)
if args.show_version:
- print(__version__)
+ print(libinfo.__version__)
if all(not getattr(args, "show_" + output) for output in outputs if output != "version"):
return
- prefix, library_dir = _paths(args.install_prefix, args.library_dir)
+ prefix, library_dir = libinfo._paths(args.install_prefix, args.library_dir)
paths = {
"prefix": prefix,
"includedir": prefix / "include",
@@ -232,11 +110,11 @@ def __main__() -> None:
if getattr(args, "show_" + output):
print(path)
if args.show_components:
- print(" ".join([*_available(library_dir, args.platform), "ffi"]))
+ print(" ".join([*libinfo._available(library_dir, args.platform), "ffi"]))
if args.show_json:
print(json.dumps(configuration(prefix, library_dir, args.platform)))
if args.show_cflags or args.show_cxxflags:
- ffi = _ffi_info()
+ ffi = libinfo._ffi_info()
includes = dict.fromkeys(
[str(prefix / "include"), ffi.find_include_path(), ffi.find_dlpack_include_path()]
)
@@ -246,7 +124,7 @@ def __main__() -> None:
if args.show_cxxflags:
print(shlex.join([*flags, "-std=c++20"]))
if any((args.show_ldflags, args.show_libs, args.show_libnames, args.show_libfiles)):
- libraries = _link_inputs(library_dir, args.platform, args.components)
+ libraries = libinfo._link_inputs(library_dir, args.platform, args.components)
apple = args.platform in ("Darwin", "iOS", "darwin")
if args.show_ldflags:
print(
diff --git a/tirx/python/tvm_tirx/error.py b/tirx/python/tvm_tirx/error.py
deleted file mode 100644
index e1a5fdd9b2..0000000000
--- a/tirx/python/tvm_tirx/error.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-"""Structured error classes in TVM.
-
-Each error class takes an error message as its input.
-See the example sections for suggested message conventions.
-To make the code more readable, we recommended developers to
-copy the examples and raise errors with the same message convention.
-
-.. note::
-
- Please also refer to :ref:`error-handling-guide`.
-"""
-
-from tvm_ffi import register_error
-
-
-@register_error
-class InternalError(RuntimeError):
- """Internal error in the system.
-
- Examples
- --------
- .. code :: c++
-
- // Example code C++
- LOG(FATAL) << "InternalError: internal error detail.";
-
- .. code :: python
-
- # Example code in python
- raise InternalError("internal error detail")
- """
-
-
-@register_error
-class RPCError(RuntimeError):
- """Error thrown by the remote server handling the RPC call."""
-
-
-@register_error
-class RPCSessionTimeoutError(RPCError, TimeoutError):
- """Error thrown by the remote server when the RPC session has expired."""
-
-
-@register_error
-class OpError(RuntimeError):
- """Base class of all operator errors in frontends."""
-
-
-@register_error
-class OpNotImplemented(OpError, NotImplementedError):
- """Operator is not implemented.
-
- Example
- -------
- .. code:: python
-
- raise OpNotImplemented(
- "Operator {} is not supported in {} frontend".format(
- missing_op, frontend_name))
- """
-
-
-@register_error
-class OpAttributeRequired(OpError, AttributeError):
- """Required attribute is not found.
-
- Example
- -------
- .. code:: python
-
- raise OpAttributeRequired(
- "Required attribute {} not found in operator {}".format(
- attr_name, op_name))
- """
-
-
-@register_error
-class OpAttributeInvalid(OpError, AttributeError):
- """Attribute value is invalid when taking in a frontend operator.
-
- Example
- -------
- .. code:: python
-
- raise OpAttributeInvalid(
- "Value {} in attribute {} of operator {} is not valid".format(
- value, attr_name, op_name))
- """
-
-
-@register_error
-class OpAttributeUnImplemented(OpError, NotImplementedError):
- """Attribute is not supported in a certain frontend.
-
- Example
- -------
- .. code:: python
-
- raise OpAttributeUnImplemented(
- "Attribute {} is not supported in operator {}".format(
- attr_name, op_name))
- """
-
-
-@register_error
-class DiagnosticError(RuntimeError):
- """Error diagnostics were reported during the execution of a pass.
-
- See the configured diagnostic renderer for detailed error information.
- """
diff --git a/tirx/python/tvm_tirx/ir/op.py b/tirx/python/tvm_tirx/ir/op.py
index 7773e33129..e9c5ac10ca 100644
--- a/tirx/python/tvm_tirx/ir/op.py
+++ b/tirx/python/tvm_tirx/ir/op.py
@@ -30,121 +30,6 @@ from . import _ffi_api
from .expr import Expr
-def _make_op_api(op, module_name):
- """Build a callable whose operands and result are governed by its Op."""
- from .attrs import make_node # pylint: disable=import-outside-toplevel
- from .expr import Call # pylint: disable=import-outside-toplevel
-
- def call(
- *args,
- attrs=None,
- ty_args=None,
- loc: Location = UNKNOWN_LOC,
- ty=None,
- **kwargs,
- ):
- # Bind named operands using the registered signature, without inventing
- # defaults or interpreting arbitrary Python wrapper signatures.
- is_region = op.get_attr("FRegionGetBodyParams") is not None
- body_params = kwargs.pop("body_params", None) if is_region else None
- operands = list(args)
- for index, info in enumerate(op.args_info):
- if index < len(args):
- if info.name in kwargs:
- raise TypeError(f"{op.name}: multiple values for {info.name!r}")
- elif info.name in kwargs:
- operands.append(kwargs.pop(info.name))
- else:
- raise TypeError(f"{op.name}: missing operand {info.name!r}")
- if kwargs or (attrs is None and op.attrs_type_key):
- if not op.attrs_type_key:
- raise TypeError(f"{op.name}: unexpected keyword operands {tuple(kwargs)}")
- if attrs is not None:
- raise TypeError(f"{op.name}: cannot mix attrs with attribute keywords")
- attrs = make_node(op.attrs_type_key, **kwargs)
- if is_region:
- from tvm_tirx.script.ir_builder.stmt import region
-
- if (
- ty is not None
- or ty_args is not None
- or not isinstance(loc, Location)
- or not loc.same_as(UNKNOWN_LOC)
- ):
- raise TypeError(
- f"{op.name}: region builders do not accept ty, ty_args or an explicit loc"
- )
- return region(op, operands, body_params=body_params, attrs=attrs)
- return Call(op, operands, attrs=attrs, ty_args=ty_args, loc=loc, ty=ty)
-
- call.__name__ = op.name.rsplit(".", 1)[-1]
- call.__module__ = module_name
- call.__doc__ = op.doc or f"Construct a call to {op.name}."
- return call
-
-
-def _init_op_api(namespace, target_module_name=None, *, wrapper=None):
- """Initialize registered Op callables in an already loaded Python module.
-
- Like :func:`tvm_ffi.init_ffi_api`, the registry prefix comes first and the
- target defaults to that module name. For example, a backend module uses
- ``_init_op_api("tirx.cuda", __name__)``. Dotted suffixes require existing
- module or SimpleNamespace containers; underscores are ordinary name parts.
-
- Generated functions accept registered positional/named operands plus
- ``attrs``, ``ty_args``, ``loc`` and ``ty``.
- Region operations construct a RegionFrame and accept ``body_params`` instead
- of Call result/type arguments.
- Omitting the result invokes an available Op inference hook; without one,
- Call retains a missing type.
- Explicit results and inference errors are preserved; Call.validate checks
- the operator contract separately. Attribute
- keywords construct the registered attrs schema, when one is declared.
-
- Existing Python callables retain ownership of their names; only missing
- exposures are generated. Existing functions must accept printed calls or
- have an appropriate exceptional printer hook. Non-callable collisions fail
- before any functions are installed. An optional ``wrapper`` adapts newly
- generated Call constructors at export time; existing exposures and region
- builders are untouched.
- Returns None.
- """
- if not namespace or any(
- not part.isidentifier() or keyword.iskeyword(part) for part in namespace.split(".")
- ):
- raise ValueError(f"Invalid Op namespace {namespace!r}")
- target = sys.modules[target_module_name or namespace]
- pending = []
- destinations = set()
- for name in sorted(Op.list_op_names()):
- if not name.startswith(namespace + "."):
- continue
- parts = name[len(namespace) + 1 :].split(".")
- if any(not part.isidentifier() or keyword.iskeyword(part) for part in parts):
- raise ValueError(f"Op {name!r} has no Python attribute spelling")
- container = target
- for part in parts[:-1]:
- container = vars(container).get(part)
- if not isinstance(container, ModuleType | SimpleNamespace):
- raise ValueError(f"Op {name!r} requires an existing namespace at {part!r}")
- destination = (id(container), parts[-1])
- if destination in destinations:
- raise ValueError(f"Op {name!r} aliases another exposure destination")
- destinations.add(destination)
- op = Op.get(name)
- if parts[-1] in vars(container):
- current = vars(container)[parts[-1]]
- if not callable(current):
- raise ValueError(f"Op {name!r} conflicts with an existing Python attribute")
- else:
- call = _make_op_api(op, target.__name__)
- if wrapper is not None and op.get_attr("FRegionGetBodyParams") is None:
- call = wrapper(call)
- pending.append((container, parts[-1], call))
- for container, name, call in pending:
- setattr(container, name, call)
-
-
@tvm_ffi.register_object("ir.Op")
class Op(Expr):
"""Primitive operator in the IR."""
@@ -280,3 +165,118 @@ def register_op_attr(op_name, attr_key, value=None, override=False):
return v
return _register(value) if value is not None else _register
+
+
+def _make_op_api(op, module_name):
+ """Build a callable whose operands and result are governed by its Op."""
+ from .attrs import make_node # pylint: disable=import-outside-toplevel
+ from .expr import Call # pylint: disable=import-outside-toplevel
+
+ def call(
+ *args,
+ attrs=None,
+ ty_args=None,
+ loc: Location = UNKNOWN_LOC,
+ ty=None,
+ **kwargs,
+ ):
+ # Bind named operands using the registered signature, without inventing
+ # defaults or interpreting arbitrary Python wrapper signatures.
+ is_region = op.get_attr("FRegionGetBodyParams") is not None
+ body_params = kwargs.pop("body_params", None) if is_region else None
+ operands = list(args)
+ for index, info in enumerate(op.args_info):
+ if index < len(args):
+ if info.name in kwargs:
+ raise TypeError(f"{op.name}: multiple values for {info.name!r}")
+ elif info.name in kwargs:
+ operands.append(kwargs.pop(info.name))
+ else:
+ raise TypeError(f"{op.name}: missing operand {info.name!r}")
+ if kwargs or (attrs is None and op.attrs_type_key):
+ if not op.attrs_type_key:
+ raise TypeError(f"{op.name}: unexpected keyword operands {tuple(kwargs)}")
+ if attrs is not None:
+ raise TypeError(f"{op.name}: cannot mix attrs with attribute keywords")
+ attrs = make_node(op.attrs_type_key, **kwargs)
+ if is_region:
+ from tvm_tirx.script.ir_builder.stmt import region
+
+ if (
+ ty is not None
+ or ty_args is not None
+ or not isinstance(loc, Location)
+ or not loc.same_as(UNKNOWN_LOC)
+ ):
+ raise TypeError(
+ f"{op.name}: region builders do not accept ty, ty_args or an explicit loc"
+ )
+ return region(op, operands, body_params=body_params, attrs=attrs)
+ return Call(op, operands, attrs=attrs, ty_args=ty_args, loc=loc, ty=ty)
+
+ call.__name__ = op.name.rsplit(".", 1)[-1]
+ call.__module__ = module_name
+ call.__doc__ = op.doc or f"Construct a call to {op.name}."
+ return call
+
+
+def _init_op_api(namespace, target_module_name=None, *, wrapper=None):
+ """Initialize registered Op callables in an already loaded Python module.
+
+ Like :func:`tvm_ffi.init_ffi_api`, the registry prefix comes first and the
+ target defaults to that module name. For example, a backend module uses
+ ``_init_op_api("tirx.cuda", __name__)``. Dotted suffixes require existing
+ module or SimpleNamespace containers; underscores are ordinary name parts.
+
+ Generated functions accept registered positional/named operands plus
+ ``attrs``, ``ty_args``, ``loc`` and ``ty``.
+ Region operations construct a RegionFrame and accept ``body_params`` instead
+ of Call result/type arguments.
+ Omitting the result invokes an available Op inference hook; without one,
+ Call retains a missing type.
+ Explicit results and inference errors are preserved; Call.validate checks
+ the operator contract separately. Attribute
+ keywords construct the registered attrs schema, when one is declared.
+
+ Existing Python callables retain ownership of their names; only missing
+ exposures are generated. Existing functions must accept printed calls or
+ have an appropriate exceptional printer hook. Non-callable collisions fail
+ before any functions are installed. An optional ``wrapper`` adapts newly
+ generated Call constructors at export time; existing exposures and region
+ builders are untouched.
+ Returns None.
+ """
+ if not namespace or any(
+ not part.isidentifier() or keyword.iskeyword(part) for part in namespace.split(".")
+ ):
+ raise ValueError(f"Invalid Op namespace {namespace!r}")
+ target = sys.modules[target_module_name or namespace]
+ pending = []
+ destinations = set()
+ for name in sorted(Op.list_op_names()):
+ if not name.startswith(namespace + "."):
+ continue
+ parts = name[len(namespace) + 1 :].split(".")
+ if any(not part.isidentifier() or keyword.iskeyword(part) for part in parts):
+ raise ValueError(f"Op {name!r} has no Python attribute spelling")
+ container = target
+ for part in parts[:-1]:
+ container = vars(container).get(part)
+ if not isinstance(container, ModuleType | SimpleNamespace):
+ raise ValueError(f"Op {name!r} requires an existing namespace at {part!r}")
+ destination = (id(container), parts[-1])
+ if destination in destinations:
+ raise ValueError(f"Op {name!r} aliases another exposure destination")
+ destinations.add(destination)
+ op = Op.get(name)
+ if parts[-1] in vars(container):
+ current = vars(container)[parts[-1]]
+ if not callable(current):
+ raise ValueError(f"Op {name!r} conflicts with an existing Python attribute")
+ else:
+ call = _make_op_api(op, target.__name__)
+ if wrapper is not None and op.get_attr("FRegionGetBodyParams") is None:
+ call = wrapper(call)
+ pending.append((container, parts[-1], call))
+ for container, name, call in pending:
+ setattr(container, name, call)
diff --git a/tirx/python/tvm_tirx/libinfo.py b/tirx/python/tvm_tirx/libinfo.py
index 79345f706b..cbe13ae515 100644
--- a/tirx/python/tvm_tirx/libinfo.py
+++ b/tirx/python/tvm_tirx/libinfo.py
@@ -18,11 +18,12 @@
from __future__ import annotations
+import importlib.machinery
+import importlib.util
import os
+import sys
from pathlib import Path
-from tvm_ffi import libinfo as tvm_ffi_libinfo
-
def _rel_top_directory() -> Path:
"""Top directory in the installed (wheel) layout: ``python/tvm_tirx/``."""
@@ -72,17 +73,17 @@ def find_libtvm_runtime() -> str:
RuntimeError
If the runtime library cannot be found.
"""
- candidate = tvm_ffi_libinfo._find_library_by_basename(
+ candidate = _ffi_info()._find_library_by_basename(
"tvm_tirx", "tvm_runtime", extra_lib_paths=package_lib_paths()
)
- if ret := tvm_ffi_libinfo._resolve_and_validate([candidate], cond=lambda _: True):
+ if ret := _ffi_info()._resolve_and_validate([candidate], cond=lambda _: True):
return ret
raise RuntimeError("Cannot find libtvm_runtime")
def find_include_path() -> str:
"""Return the path to TVM's own ``include/`` directory."""
- if ret := tvm_ffi_libinfo._resolve_and_validate(
+ if ret := _ffi_info()._resolve_and_validate(
paths=[
_rel_top_directory() / "include",
_dev_top_directory() / "include",
@@ -94,3 +95,141 @@ def find_include_path() -> str:
__version__ = "0.1.0a0"
+
+
+_LIBRARY_NAMES = ("tvm_tirx_compiler", "tvm_runtime")
+_COMPONENTS = {
+ "compiler": "tvm_tirx_compiler",
+ "runtime": "tvm_runtime",
+ "cuda": "tvm_runtime_cuda",
+ "metal": "tvm_runtime_metal",
+ "opencl": "tvm_runtime_opencl",
+ "vulkan": "tvm_runtime_vulkan",
+ "rocm": "tvm_runtime_rocm",
+}
+
+
+def _find_prefix(start: Path) -> Path:
+ for candidate in (start, *start.parents):
+ if (candidate / "include/tvm/runtime/base.h").is_file():
+ return candidate
+ raise RuntimeError(f"Cannot find TIRx public headers above {start}")
+
+
+def _paths(prefix: Path | None, library_dir: Path | None) -> tuple[Path, Path]:
+ explicit_prefix = prefix is not None
+ if library_dir is not None:
+ library_dir = library_dir.resolve()
+ prefix = prefix.resolve() if prefix is not None else _find_prefix(library_dir)
+ else:
+ prefix = prefix.resolve() if prefix is not None else _find_prefix(Path(__file__).parent)
+ library_dir = prefix / "lib"
+ candidates = [prefix / "lib", prefix / "lib64", prefix / "build/lib"]
+ if prefix.name == "tirx":
+ candidates.append(prefix.parent / "build/lib")
+ if not explicit_prefix and os.environ.get("TVM_TIRX_LIBRARY_PATH"):
+ candidates.insert(0, Path(os.environ["TVM_TIRX_LIBRARY_PATH"]))
+ for candidate in candidates:
+ if all(
+ any(
+ (candidate / filename).is_file()
+ for filename in (f"lib{name}.so", f"lib{name}.dylib", f"{name}.dll")
+ )
+ for name in ("tvm_runtime",)
+ ):
+ library_dir = candidate
+ break
+ if not (prefix / "include/tvm/runtime/base.h").is_file():
+ raise RuntimeError(f"Cannot find TIRx public headers in {prefix / 'include'}")
+ return prefix, library_dir
+
+
+def _libraries(library_dir: Path, platform: str, names=_LIBRARY_NAMES) -> dict[str, dict[str, str]]:
+ libraries = {}
+ windows = platform in ("Windows", "win32")
+ apple = platform in ("Darwin", "iOS", "darwin")
+ for name in names:
+ if windows:
+ filenames = (f"{name}.dll",)
+ elif apple:
+ filenames = (f"lib{name}.dylib", f"lib{name}.so")
+ else:
+ filenames = (f"lib{name}.so",)
+ location = next((library_dir / f for f in filenames if (library_dir / f).is_file()), None)
+ if location is None:
+ raise RuntimeError(f"Cannot find TIRx library {name} in {library_dir}")
+ implib = ""
+ if windows:
+ import_names = (f"{name}.lib", f"lib{name}.dll.a")
+ import_library = next(
+ (library_dir / f for f in import_names if (library_dir / f).is_file()), None
+ )
+ if import_library is None:
+ raise RuntimeError(f"Missing import library for {location}")
+ implib = str(import_library)
+ libraries[name] = {"location": str(location), "implib": implib}
+ return libraries
+
+
+def configuration(
+ prefix: Path | None = None,
+ library_dir: Path | None = None,
+ platform: str = sys.platform,
+) -> dict:
+ """Return the public include and core shared-library paths for one installation."""
+ prefix, library_dir = _paths(prefix, library_dir)
+ return {
+ "version": __version__,
+ "include_dir": str(prefix / "include"),
+ "library_dir": str(library_dir),
+ "cmake_dir": str(library_dir / "cmake/tvm_tirx"),
+ "libraries": _libraries(library_dir, platform),
+ }
+
+
+def _ffi_info():
+ """Read the selected FFI package's pure Python helper without importing its runtime."""
+ spec = importlib.machinery.PathFinder.find_spec("tvm_ffi")
+ if spec is None or spec.origin is None:
+ raise RuntimeError("Cannot find the matching apache-tvm-ffi Python package")
+ helper = Path(spec.origin).parent / "libinfo.py"
+ spec = importlib.util.spec_from_file_location("_tvm_ffi_libinfo", helper)
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ return module
+
+
+def _available(library_dir, platform):
+ available = []
+ for component, name in _COMPONENTS.items():
+ try:
+ _libraries(library_dir, platform, (name,))
+ except RuntimeError:
+ continue
+ available.append(component)
+ return available
+
+
+def _link_inputs(library_dir, platform, components):
+ available = _available(library_dir, platform)
+ selected = list(dict.fromkeys(components or ["all"]))
+ if "all" in selected:
+ selected = [*available, *(name for name in selected if name != "all")]
+ for name in selected:
+ if name != "ffi" and name not in available:
+ raise RuntimeError(
+ f"Component '{name}' is unavailable; available: {' '.join(available)} ffi"
+ )
+ # Dependents precede their dependencies even if the command line lists runtime first.
+ ordered = [name for name in selected if name not in ("runtime", "ffi")]
+ if any(name != "ffi" for name in selected):
+ ordered.append("runtime")
+ libraries = _libraries(library_dir, platform, [_COMPONENTS[name] for name in ordered])
+ ffi = _ffi_info()
+ ffi_library = (
+ ffi.find_windows_implib() if platform in ("Windows", "win32") else ffi.find_libtvm_ffi()
+ )
+ return [
+ *(Path(lib["implib"] or lib["location"]) for lib in libraries.values()),
+ Path(ffi_library),
+ ]
diff --git a/tirx/python/tvm_tirx/support/clang.py b/tirx/python/tvm_tirx/support/clang.py
index c0763dfcd0..09120be9e5 100644
--- a/tirx/python/tvm_tirx/support/clang.py
+++ b/tirx/python/tvm_tirx/support/clang.py
@@ -44,7 +44,7 @@ def find_clang(required=True):
matches the major llvm version that built with tvm
"""
cc_list = []
- major = tvm_tirx.codegen.llvm_version_major(allow_none=True)
+ major = tvm_tirx.codegen.llvm.version_major(allow_none=True)
if major is not None:
cc_list += [f"clang-{major}.0"]
cc_list += [f"clang-{major}"]
diff --git a/tirx/python/tvm_tirx/support/rocm.py b/tirx/python/tvm_tirx/support/rocm.py
index 8da215a0fe..962b999787 100644
--- a/tirx/python/tvm_tirx/support/rocm.py
+++ b/tirx/python/tvm_tirx/support/rocm.py
@@ -49,7 +49,7 @@ def find_lld(required=True):
matches the major llvm version that built with tvm
"""
lld_list = []
- major = tvm_tirx.codegen.llvm_version_major(allow_none=True)
+ major = tvm_tirx.codegen.llvm.version_major(allow_none=True)
if major is not None:
lld_list += [f"ld.lld-{major}.0"]
lld_list += [f"ld.lld-{major}"]
diff --git a/tirx/python/tvm_tirx/testing/env.py b/tirx/python/tvm_tirx/testing/env.py
index 7e58d5c269..6ce5d3cd34 100644
--- a/tirx/python/tvm_tirx/testing/env.py
+++ b/tirx/python/tvm_tirx/testing/env.py
@@ -404,7 +404,7 @@ def has_nvcc_version(major: int, minor: int = 0, release: int = 0) -> bool:
def _llvm_version_major() -> int:
"""Return the major LLVM version, or 0 if LLVM is unavailable."""
try:
- return int(tvm_tirx.codegen.llvm_version_major())
+ return int(tvm_tirx.codegen.llvm.version_major())
except Exception: # pylint: disable=broad-except
return 0
@@ -451,7 +451,7 @@ def has_hexagon_toolchain() -> bool:
try:
return (
_runtime_enabled("llvm")
- and "hexagon" in tvm_tirx.codegen.llvm_get_targets()
+ and "hexagon" in tvm_tirx.codegen.llvm.get_targets()
and "HEXAGON_TOOLCHAIN" in os.environ
)
except Exception: # pylint: disable=broad-except
@@ -485,8 +485,8 @@ def _has_cpu_feature(features) -> bool:
"""True if the host CPU advertises the given LLVM target ``features``."""
try:
codegen = tvm_tirx.codegen
- cpu = codegen.llvm_get_system_cpu()
- triple = codegen.llvm_get_system_triple()
+ cpu = codegen.llvm.get_system_cpu()
+ triple = codegen.llvm.get_system_triple()
target = tvm_tirx.target.Target({"kind": "llvm", "mtriple": triple, "mcpu": cpu})
return bool(codegen.target_has_features(features, target))
except Exception: # pylint: disable=broad-except
diff --git a/tirx/python/tvm_tirx/tirx/__init__.py b/tirx/python/tvm_tirx/tirx/__init__.py
index c6653bfa1f..cbbde24567 100644
--- a/tirx/python/tvm_tirx/tirx/__init__.py
+++ b/tirx/python/tvm_tirx/tirx/__init__.py
@@ -44,7 +44,8 @@ from .expr import Select, TensorLoad
from .expr import Let
-from .function import Function, IndexMap, renew_def
+from .function import Function, renew_def
+from .index_map import IndexMap
from .op import call_packed_lowered, call_cpacked_lowered, register_intrin_lowering
from .op import call_packed, call_cpacked, call_intrin, call_pure_extern, call_extern
@@ -84,7 +85,6 @@ from .thread_scope import ThreadScope
from .layout import TileLayout, Layout, ComposeLayout
from . import transform
from . import analysis
-from . import backend
# Compiler-only submodules. Skip under `TVM_USE_RUNTIME_LIB=1` since they
# perform compiler-side FFI at module load (schema engine looks up
diff --git a/tirx/python/tvm_tirx/tirx/function.py b/tirx/python/tvm_tirx/tirx/function.py
index 2a7ce72203..daa9b20d30 100644
--- a/tirx/python/tvm_tirx/tirx/function.py
+++ b/tirx/python/tvm_tirx/tirx/function.py
@@ -17,20 +17,16 @@
# pylint: disable=unrecognized-inline-option
"""Function data types."""
-import collections
-import inspect
-from collections.abc import Callable, Mapping, Sequence
-from typing import Optional
+from collections.abc import Mapping, Sequence
import tvm_ffi
import tvm_tirx
import tvm_tirx.runtime
-from tvm_tirx.ir import BaseFunc, Range, Scriptable, SeqStmt, Stmt, Var
+from tvm_tirx.ir import BaseFunc, Scriptable, SeqStmt, Stmt, Var
from tvm_tirx.ir.location import UNKNOWN_LOC, Location
from tvm_tirx.runtime import Object
-from ..runtime._tensor import Tensor
from . import _ffi_api
from .expr import Expr
@@ -88,11 +84,6 @@ class Function(BaseFunc, Scriptable):
loc,
) # type: ignore
- @property
- def is_tirx(self):
- """Whether this primitive function uses the TIRx dialect."""
- return not bool(self.attrs.get("s_tir", False))
-
def with_body(self, new_body: Stmt | Sequence[Stmt] | None, loc: Location = UNKNOWN_LOC):
"""Create a new Function with the same set signatures but a new body.
@@ -191,287 +182,3 @@ def renew_def(func: Function) -> Function:
The function with fresh variable definitions.
"""
return _ffi_api.RenewDef(func)
-
-
-@tvm_ffi.register_object("tirx.IndexMap")
-class IndexMap(Object):
- """A mapping from multi-dimensional indices to another set of multi-dimensional indices
-
- Parameters
- ----------
- initial_indices : List[Var]
- Variables representing the indices prior to remapping.
- final_indices : List[Expr]
- Expressions defining the indices after remapping.
- inverse_index_map : Union[Callable, Optional[IndexMap]]
- The optional pre-defined inverse index map.
- When this is defined, IndexMap::Inverse will return the pre-defined inverse index map.
- Otherwise, the inverse index map will be computed on the fly.
- It is the user's responsibility to ensure the correctness of the pre-defined inverse
- index map.
- """
-
- initial_indices: list[Var]
- final_indices: list[Expr]
-
- def __init__(self, initial_indices, final_indices, inverse_index_map):
- if isinstance(inverse_index_map, Callable):
- inverse_index_map = IndexMap.from_func(inverse_index_map)
- self.__init_handle_by_constructor__(
- _ffi_api.IndexMap, initial_indices, final_indices, inverse_index_map
- )
-
- @staticmethod
- def from_func(
- mapping_function: Callable,
- ndim: int | None = None,
- inverse_index_map: Callable | Optional["IndexMap"] = None,
- *,
- index_dtype: str = "int64",
- ):
- """Create an index map from a function
-
- Parameters
- ----------
- mapping_function : Callable
-
- The function to map from source indices to target indices.
- The function should accept `tirx.Var` parameters and return
- a either a `tirx.Expr`, or a list of `tirx.Expr`.
- Returning a `tirx.Expr` is equivalent to returning a
- list of length 1 containing that `tirx.Expr`.
-
- ndim: Optional[int]
-
- The dimensionality of the tensor to which this
- transformation should be applied. If mapping_function uses
- variadic argument `*args`, `ndim` must be specified. If
- mapping_function does not use variadic arguments, ndim is
- optional.
-
- inverse_index_map : Union[Callable, Optional[IndexMap]]
- The optional pre-defined inverse index map.
- When this is defined, IndexMap::Inverse will return the pre-defined inverse index map.
- Otherwise, the inverse index map will be computed on the fly.
- It is the user's responsibility to ensure the correctness of the pre-defined inverse
- index map.
-
- index_dtype : str
- The default index dtype to use for input iters in the mapping function.
-
- Returns
- -------
- index_map: IndexMap
-
- Returns an IndexMap representing the `mapping_function`.
-
- """
- params = inspect.signature(mapping_function).parameters
-
- args = []
- var_arg_name = None
- kwargs = collections.OrderedDict()
-
- for name, param in params.items():
- if param.kind in [
- inspect.Parameter.POSITIONAL_ONLY,
- inspect.Parameter.POSITIONAL_OR_KEYWORD,
- ]:
- args.append(tvm_tirx.tirx.Var(name, index_dtype))
-
- elif param.kind == inspect.Parameter.VAR_POSITIONAL:
- var_arg_name = name
-
- elif param.kind == inspect.Parameter.KEYWORD_ONLY:
- kwargs[name] = tvm_tirx.tirx.Var(name, index_dtype)
-
- else:
- raise ValueError("transform_layout mapping may not have *args")
-
- # Now that all the named arguments have been collected,
- # everything that remains should go to the *args, if
- # specified.
- if var_arg_name is not None:
- assert ndim is not None, "ndim must be specified when *args is used"
- num_var_args = ndim - len(args) - len(kwargs)
- for i in range(num_var_args):
- args.append(tvm_tirx.tirx.Var(f"{var_arg_name}_{i}", index_dtype))
-
- mapping = mapping_function(*args, **kwargs)
-
- initial_indices = args + list(kwargs.values())
-
- final_indices = []
-
- if tvm_tirx.ir.is_prim_expr(mapping):
- is_iterable = False
- else:
- try:
- iter(mapping)
- is_iterable = True
- except TypeError:
- is_iterable = False
-
- if is_iterable:
- for val in mapping:
- if tvm_tirx.ir.is_prim_expr(val):
- final_indices.append(val)
- else:
- raise TypeError(
- "Expected mapping function to return tvm_tirx.ir.Expr "
- "or a list of tvm_tirx.ir.Expr. "
- f"Instead received {val} of type {type(val)}."
- )
- else:
- final_indices.append(mapping)
-
- return IndexMap(initial_indices, final_indices, inverse_index_map)
-
- def is_equivalent_to(self, other_map: "IndexMap", analyzer=None) -> bool:
- """Return if the index maps are equivalent.
-
- Parameters
- ----------
- other_map: IndexMap
-
- The IndexMap to which the comparison should be made.
-
- analyzer : Optional[tvm_tirx.sym.Analyzer]
-
- The analyzer to use while comparing the mapped indices. When
- provided, its accumulated bindings and constraints are reused so
- that maps that are only equivalent under those bindings can be
- proven equal.
-
- Returns
- -------
- is_equivalent: bool
-
- True if the two mappings represent the same
- transformation, otherwise False
- """
- if len(self.initial_indices) != len(other_map.initial_indices):
- return False
- if len(self.final_indices) != len(other_map.final_indices):
- return False
-
- if analyzer is None:
- analyzer = tvm_tirx.sym.Analyzer()
-
- mapped_other_final_indices = other_map.map_indices(self.initial_indices, analyzer=analyzer)
- for self_index, other_index in zip(self.final_indices, mapped_other_final_indices):
- if not analyzer.can_prove_equal(self_index, other_index):
- return False
-
- return True
-
- def map_indices(self, indices: list[Expr], analyzer=None) -> list[Expr]:
- """Apply the index map to a set of indices
-
- Parameters
- ----------
- indices : List[Expr]
- The indices to be mapped
- analyzer : Optional[tvm_tirx.sym.Analyzer]
- The analyzer to use while simplifying mapped indices.
-
- Returns
- -------
- result : List[Expr]
- The mapped indices
- """
- return _ffi_api.IndexMapMapIndices(self, indices, analyzer)
-
- def map_shape(self, shape: list[Expr], analyzer=None) -> list[Expr]:
- """Apply the index map to a tensor shape
-
- Parameters
- ----------
- shape : List[Expr]
- The tensor shape to be mapped
- analyzer : Optional[tvm_tirx.sym.Analyzer]
- The analyzer to use while simplifying mapped shape expressions.
-
- Returns
- -------
- result : List[Expr]
- The mapped shape
- """
- return _ffi_api.IndexMapMapShape(self, shape, analyzer)
-
- def map_tensor(self, arr_src: Tensor) -> Tensor:
- """Apply thie index map to transform the layout of the input Tensor
-
- Parameters
- ----------
- arr_src : runtime.Tensor
- The Tensor to be transformed
-
- Returns
- -------
- arr_dst : runtime.Tensor
- The transformed Tensor
- """
- return _ffi_api.IndexMapMapTensor(self, arr_src)
-
- def inverse(self, shape: list[Range | Expr], analyzer=None) -> "IndexMap":
- """Return the inverse of the map
-
- Throws an error if the function is not bijective.
-
- Parameters
- ----------
- shape: List[Union[Range,Expr]]
-
- The region over which the inverse should be determined.
- Used for validating that the mapping is bijective over
- this range.
- analyzer : Optional[tvm_tirx.sym.Analyzer]
- The analyzer to use while deriving and validating the inverse.
-
- Returns
- -------
- inverse : IndexMap
-
- The inverse
- """
-
- shape = [dim if isinstance(dim, Range) else Range(0, dim) for dim in shape]
- return _ffi_api.IndexMapInverse(self, shape, analyzer)
-
- def non_surjective_inverse(
- self, shape: list[Range | Expr], analyzer=None
- ) -> tuple["IndexMap", Expr]:
- """Return the inverse of the map
-
- Can be applied to transformations that introduce padding.
-
- Parameters
- ----------
- shape: List[Union[Range,Expr]]
-
- The region over which the inverse should be determined.
- Used for determining the predicate.
- analyzer : Optional[tvm_tirx.sym.Analyzer]
- The analyzer to use while deriving the inverse and padding predicate.
-
- Returns
- -------
- result : Tuple[IndexMap, Expr]
-
- The inverse, and a predicate for which the inverse maps to
- a valid index in the input range.
-
- Examples
- --------
-
- .. code-block:: python
-
- index_map = IndexMap.from_func(lambda i: [i//4, i%4])
- inverse_map, predicate = index_map.non_surjective_inverse([14])
- assert inverse_map.is_equivalent_to(IndexMap.from_func(lambda j,k: [4*j + k])
- print(predicate) # Prints "(axis0==3) && (axis2 >= 2)"
- """
-
- shape = [dim if isinstance(dim, Range) else Range(0, dim) for dim in shape]
- return _ffi_api.IndexMapNonSurjectiveInverse(self, shape, analyzer)
diff --git a/tirx/python/tvm_tirx/tirx/function.py b/tirx/python/tvm_tirx/tirx/index_map.py
similarity index 69%
copy from tirx/python/tvm_tirx/tirx/function.py
copy to tirx/python/tvm_tirx/tirx/index_map.py
index 2a7ce72203..0ddc175520 100644
--- a/tirx/python/tvm_tirx/tirx/function.py
+++ b/tirx/python/tvm_tirx/tirx/index_map.py
@@ -15,182 +15,21 @@
# specific language governing permissions and limitations
# under the License.
# pylint: disable=unrecognized-inline-option
-"""Function data types."""
+"""Mappings between multi-dimensional indices."""
import collections
import inspect
-from collections.abc import Callable, Mapping, Sequence
+from collections.abc import Callable
from typing import Optional
import tvm_ffi
import tvm_tirx
-import tvm_tirx.runtime
-from tvm_tirx.ir import BaseFunc, Range, Scriptable, SeqStmt, Stmt, Var
-from tvm_tirx.ir.location import UNKNOWN_LOC, Location
+from tvm_tirx.ir import Expr, Range, Var
from tvm_tirx.runtime import Object
+from tvm_tirx.runtime._tensor import Tensor
-from ..runtime._tensor import Tensor
from . import _ffi_api
-from .expr import Expr
-
-
-@tvm_ffi.register_object("tirx.Function")
-class Function(BaseFunc, Scriptable):
- """A function declaration expression.
-
- Parameters
- ----------
- params: List[Union[tvm_tirx.tirx.Var, tvm_tirx.tirx.Var]]
- List of input parameters to the function.
-
- body: Stmt | Sequence[Stmt] | None
- The body of the function, or None for a declaration.
-
- ret_type: tvm_tirx.ir.Type
- The return type annotation of the function.
-
- attrs: Optional[tvm.Attrs]
- Attributes of the function, can be None
-
- loc : Location, optional
- The location of this itervar in the source code.
- """
-
- body: SeqStmt | None
-
- def __init__(
- self,
- params,
- body: Stmt | Sequence[Stmt] | None,
- ret_type=None,
- attrs=None,
- loc: Location = UNKNOWN_LOC,
- ):
- if ret_type is None:
- ret_type = tvm_tirx.ir.Type.missing()
- param_list = []
- for x in params:
- x = tvm_tirx.runtime.convert(x) if not isinstance(x, Object) else x
- if not isinstance(x, Var):
- raise TypeError("params can only contain Var or Var")
- param_list.append(x)
-
- if attrs is None:
- attrs = tvm_tirx.ir.make_node("ir.DictAttrs")
-
- self.__init_handle_by_constructor__(
- _ffi_api.Function,
- param_list,
- body,
- ret_type,
- attrs,
- loc,
- ) # type: ignore
-
- @property
- def is_tirx(self):
- """Whether this primitive function uses the TIRx dialect."""
- return not bool(self.attrs.get("s_tir", False))
-
- def with_body(self, new_body: Stmt | Sequence[Stmt] | None, loc: Location = UNKNOWN_LOC):
- """Create a new Function with the same set signatures but a new body.
-
- Parameters
- ----------
- new_body : Stmt | Sequence[Stmt] | None
- The new body, or None for a declaration.
-
- loc : Location, optional
- The location of this itervar in the source code.
-
- Returns
- -------
- new_func : Function
- The created new function.
- """
- return Function(
- self.params,
- new_body,
- ret_type=self.ret_type,
- attrs=self.attrs,
- loc=loc,
- )
-
- def specialize(self, param_map: Mapping[Var, Expr | Var]):
- """Specialize parameters of Function
-
- Parameters
- ----------
-
- param_map : Mapping[Var, Union[Expr, Var]]
- The mapping from function params to the instance
-
- Examples
- --------
- We can define a TIRX function with symbolic shape:
-
- .. code-block:: python
-
- from __future__ import annotations
-
- @T.function
- def mem_copy(
- A: T.Tensor((m, n), "float32"),
- B: T.Tensor((m, n), "float32"),
- m: T.int32,
- n: T.int32,
- ) -> None:
-
- for i, j in T.grid(m, n):
- B[i, j] = A[i, j]
-
- Then we can make it specialized with given shapes or tensors.
-
- .. code-block:: python
-
- a, _, m, n = mem_copy.params
- func = mem_copy.specialize({a: tirx.decl_tensor((16, 16))})
- # or
- func = mem_copy.specialize({n: 16, m: 16})
-
- The specialized function:
-
- .. code-block:: python
-
- @T.function
- def mem_copy_16_16(
- A: T.Tensor((16, 16), "float32"), B: T.Tensor((16, 16), "float32")
- ) -> None:
-
- for i, j in T.grid(16, 16):
- B[i, j] = A[i, j]
-
- Returns
- -------
- func : Function
- The new function with parameter specialized
- """
- return _ffi_api.Specialize(self, param_map) # type: ignore
-
-
-def renew_def(func: Function) -> Function:
- """Renew variable definitions and remap their uses in a function.
-
- Definition regions follow the registered structural hooks. Free variables
- and function attributes are preserved, and the function signature is rebuilt.
-
- Parameters
- ----------
- func : Function
- The function to renew.
-
- Returns
- -------
- Function
- The function with fresh variable definitions.
- """
- return _ffi_api.RenewDef(func)
@tvm_ffi.register_object("tirx.IndexMap")
diff --git a/tirx/python/tvm_tirx/tirx/op/__init__.py b/tirx/python/tvm_tirx/tirx/op/__init__.py
index a167f8cb62..9ba7b024e5 100644
--- a/tirx/python/tvm_tirx/tirx/op/__init__.py
+++ b/tirx/python/tvm_tirx/tirx/op/__init__.py
@@ -515,7 +515,7 @@ def call_llvm_intrin(name, *args, ty, loc: Location = UNKNOWN_LOC):
from tvm_tirx import codegen
if isinstance(name, str):
- llvm_id = codegen.llvm_lookup_intrinsic_id(name)
+ llvm_id = codegen.llvm.lookup_intrinsic_id(name)
elif isinstance(name, IntImm):
llvm_id = name.value
else:
@@ -559,7 +559,7 @@ def call_llvm_pure_intrin(name, *args, ty, loc: Location = UNKNOWN_LOC):
from tvm_tirx import codegen
if isinstance(name, str):
- llvm_id = codegen.llvm_lookup_intrinsic_id(name)
+ llvm_id = codegen.llvm.lookup_intrinsic_id(name)
elif isinstance(name, IntImm):
llvm_id = name.value
else:
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py b/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py
index fd6887e564..e788d7d90c 100644
--- a/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py
+++ b/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py
@@ -26,7 +26,7 @@ from tvm_tirx import tirx as _tir
from tvm_tirx import tirx as tir
# pylint: disable=unused-import
-from tvm_tirx.codegen import llvm_lookup_intrinsic_id
+from tvm_tirx.codegen.llvm import lookup_intrinsic_id as llvm_lookup_intrinsic_id
from tvm_tirx.ir import Call, CallEffectKind, Var
from tvm_tirx.ir.location import UNKNOWN_LOC, Location
from tvm_tirx.ir.prim import _ffi_api as _prim_ffi
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py b/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
index a0fd6bcdbd..8ef324f802 100644
--- a/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
+++ b/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
@@ -203,7 +203,7 @@ def check_well_formed_(function: _tir.Function) -> None:
def _check_module_well_formed(module: _ir.IRModule) -> None:
"""Validate completed functions belonging to the TIRx dialect."""
for function in module.functions.values():
- if isinstance(function, _tir.Function) and function.is_tirx:
+ if isinstance(function, _tir.Function) and not function.attrs.get("s_tir", False):
check_well_formed_(function)
diff --git a/tirx/tests/python/backend/metal/codegen/test_basic.py b/tirx/tests/python/backend/metal/codegen/test_basic.py
index d582ef1cc0..dc8934d83c 100644
--- a/tirx/tests/python/backend/metal/codegen/test_basic.py
+++ b/tirx/tests/python/backend/metal/codegen/test_basic.py
@@ -316,7 +316,7 @@ def test_bound_symbolic_stack_allocation(bounded):
assert "thread float scratch[128]" in source
else:
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="Metal allocation extent requires a finite compile-time upper bound",
):
_build_metal(Module)
@@ -363,7 +363,7 @@ def test_allocation_bound_does_not_substitute_buffer_load(scope, bounded):
assert "scratch[31] =" in source
else:
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="Metal allocation extent requires a finite compile-time upper bound",
):
_build_metal(Module)
@@ -411,7 +411,7 @@ def test_unbounded_symbolic_stack_allocation_rejected():
T.evaluate(scratch[0])
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="Metal allocation extent requires a finite compile-time upper bound",
):
_build_metal(Module)
@@ -436,7 +436,7 @@ def test_unbounded_uint64_symbolic_stack_allocation_rejected():
T.evaluate(scratch[0])
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="Metal allocation extent requires a finite compile-time upper bound",
):
_build_metal(Module)
@@ -461,7 +461,7 @@ def test_nonpositive_stack_allocation_rejected(extent):
T.evaluate(scratch.data)
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="Metal allocation extent requires a positive compile-time upper bound",
):
_build_metal(Module)
@@ -493,7 +493,7 @@ def test_stack_allocation_element_count_overflow_rejected():
T.evaluate(scratch.data)
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="Metal allocation element count is too large to represent",
):
_build_metal(Module)
diff --git a/tirx/tests/python/backend/webgpu/codegen/test_basic.py b/tirx/tests/python/backend/webgpu/codegen/test_basic.py
index 6dc852436d..20bc5b7595 100644
--- a/tirx/tests/python/backend/webgpu/codegen/test_basic.py
+++ b/tirx/tests/python/backend/webgpu/codegen/test_basic.py
@@ -100,7 +100,7 @@ def test_bound_symbolic_allocation(scope, bounded):
assert len(re.findall(declaration + r"\s+\w+\s*:\s*array<f32,\s*128>;", source)) == 2
else:
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="WebGPU allocation extent requires a finite compile-time upper bound",
):
_build_webgpu(Module)
@@ -146,7 +146,7 @@ def test_allocation_bound_does_not_substitute_buffer_load(scope, bounded):
assert "scratch[31" in source
else:
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="WebGPU allocation extent requires a finite compile-time upper bound",
):
_build_webgpu(Module)
@@ -177,7 +177,7 @@ def test_bound_symbolic_workgroup_allocation_respects_target_limit(target_limit)
assert re.search(r"var<workgroup>\s+\w+\s*:\s*array<f32,\s*128>;", source)
else:
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match=r"WebGPU workgroup allocations use 512 bytes, .* supports only 496 bytes",
):
_build_webgpu(Module, target)
@@ -201,7 +201,7 @@ def test_unbounded_symbolic_stack_allocation_rejected():
T.evaluate(scratch[0])
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="WebGPU allocation extent requires a finite compile-time upper bound",
):
_build_webgpu(Module)
@@ -225,7 +225,7 @@ def test_nonpositive_stack_allocation_rejected(extent):
T.evaluate(scratch.data)
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="WebGPU allocation extent requires a positive compile-time upper bound",
):
_build_webgpu(Module)
@@ -256,7 +256,7 @@ def test_stack_allocation_element_count_overflow_rejected():
T.evaluate(scratch.data)
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match="WebGPU allocation element count is too large to represent",
):
_build_webgpu(Module)
@@ -282,9 +282,7 @@ def test_stack_allocation_byte_size_overflow_rejected():
)
T.evaluate(scratch.data)
- with pytest.raises(
- tvm_tirx.error.InternalError, match="WebGPU allocation byte size is too large to represent"
- ):
+ with pytest.raises(RuntimeError, match="WebGPU allocation byte size is too large to represent"):
_build_webgpu(Module)
@@ -327,7 +325,7 @@ def test_total_workgroup_allocation_above_target_limit_rejected():
second[0] = 2.0
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match=r"WebGPU workgroup allocations use 32784 bytes, .* supports only 32768 bytes",
):
_build_webgpu(Module)
@@ -352,7 +350,7 @@ def test_workgroup_allocation_accounts_for_declaration_alignment():
second[0] = 2.0
with pytest.raises(
- tvm_tirx.error.InternalError,
+ RuntimeError,
match=r"WebGPU workgroup allocations use 32 bytes, .* supports only 16 bytes",
):
_build_webgpu(Module, {"kind": "webgpu", "max_shared_memory_per_block": 16})
diff --git a/tirx/tests/python/codegen/llvm/test_aarch64.py b/tirx/tests/python/codegen/llvm/test_aarch64.py
index 0e98e3e6a7..1db9d6540e 100644
--- a/tirx/tests/python/codegen/llvm/test_aarch64.py
+++ b/tirx/tests/python/codegen/llvm/test_aarch64.py
@@ -24,13 +24,13 @@ import re
import pytest
import tvm_tirx
-from tvm_tirx.codegen import llvm_version_major
+from tvm_tirx.codegen import llvm
from tvm_tirx.script import ir as I
from tvm_tirx.script import tirx as T
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -68,7 +68,7 @@ def test_mul(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -106,7 +106,7 @@ def test_add(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -144,7 +144,7 @@ def test_sub(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -181,7 +181,7 @@ def test_muladd(dtype):
assembly,
)
- if llvm_version_major() >= 18 and dtype in ("float", "float16"):
+ if llvm.version_major() >= 18 and dtype in ("float", "float16"):
# Newer LLVM cost models (observed with LLVM 20) prefer a fixed-width
# NEON main loop over a scalable SVE loop for floating-point fmuladd
# on generic AArch64 targets, so also accept the NEON form.
@@ -193,7 +193,7 @@ def test_muladd(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -235,7 +235,7 @@ def test_max(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -277,7 +277,7 @@ def test_min(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -315,7 +315,7 @@ def test_div(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype", ["uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64"]
@@ -352,7 +352,7 @@ def test_mod(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -393,7 +393,7 @@ def test_eq(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype",
@@ -434,7 +434,7 @@ def test_neq(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype", ["uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64"]
@@ -471,7 +471,7 @@ def test_or(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype", ["uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64"]
@@ -508,7 +508,7 @@ def test_and(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.parametrize(
"dtype", ["uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64"]
@@ -541,7 +541,7 @@ def test_not(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
+ llvm.version_major() < 15, reason="Test requires an LLVM version of at least 15 to target SVE"
)
@pytest.mark.xfail(
reason="Awaiting llvm support for gathered loads",
@@ -578,7 +578,7 @@ def test_memcpy(dtype):
@pytest.mark.skipif(
- llvm_version_major() < 13,
+ llvm.version_major() < 13,
reason="Function attribute vscale_range() is not supported in earlier versions of LLVM",
)
@pytest.mark.parametrize(
@@ -589,7 +589,7 @@ def test_memcpy(dtype):
# Since LLVM 19, SVE/SVE2 are optional extensions of Armv9.0-A, so
# "+v9a" no longer implies "+sve" and no vscale_range() is added:
# https://releases.llvm.org/19.1.0/docs/ReleaseNotes.html#changes-to-the-aarch64-backend
- ("+v9a", llvm_version_major() < 19),
+ ("+v9a", llvm.version_major() < 19),
("+sme", True),
],
)
diff --git a/tirx/tests/python/codegen/llvm/test_basic.py b/tirx/tests/python/codegen/llvm/test_basic.py
index e786094d86..3d41c705b1 100644
--- a/tirx/tests/python/codegen/llvm/test_basic.py
+++ b/tirx/tests/python/codegen/llvm/test_basic.py
@@ -25,7 +25,7 @@ import pytest
import tvm_tirx
import tvm_tirx.testing
-from tvm_tirx.codegen import llvm_get_intrinsic_name, llvm_lookup_intrinsic_id
+from tvm_tirx.codegen import llvm
from tvm_tirx.script import ir as I
from tvm_tirx.script import tirx as T
from tvm_tirx.support import utils
@@ -46,9 +46,7 @@ def test_duplicate_function_global_symbol_diagnostic():
T.func_attr({"global_symbol": "dup_symbol", "tirx.noalias": True})
A[0] = T.float32(2)
- with pytest.raises(
- tvm_tirx.error.InternalError, match="Duplicate Function global_symbol 'dup_symbol'"
- ) as err:
+ with pytest.raises(RuntimeError, match="Duplicate Function global_symbol 'dup_symbol'") as err:
tvm_tirx.tirx.compile(Module, target="llvm")
assert "first_unique_key" in str(err.value)
assert "second_unique_key" in str(err.value)
@@ -98,8 +96,8 @@ def test_llvm_void_intrin():
@pytest.mark.skipif(not env.has_llvm(), reason="need llvm")
def test_llvm_intrinsic_id():
orig_name = "llvm.x86.sse2.pmadd.wd"
- intrin_id = llvm_lookup_intrinsic_id(orig_name)
- name = llvm_get_intrinsic_name(intrin_id)
+ intrin_id = llvm.lookup_intrinsic_id(orig_name)
+ name = llvm.get_intrinsic_name(intrin_id)
assert orig_name == name
@@ -107,7 +105,7 @@ def test_llvm_intrinsic_id():
def test_llvm_overloaded_intrin():
# Name lookup for overloaded intrinsics in LLVM 4- requires a name
# that includes the overloaded types.
- if tvm_tirx.codegen.llvm_version_major() < 5:
+ if tvm_tirx.codegen.llvm.version_major() < 5:
return
# int1 is the type for the is_zero_undef parameter
@@ -448,7 +446,7 @@ def test_alignment():
return True
return False
- if tvm_tirx.codegen.llvm_version_major() >= 5:
+ if tvm_tirx.codegen.llvm.version_major() >= 5:
assert has_param_alignment()
# Check for assume intrinsics. This isn't 100% accurate, since it just
@@ -681,9 +679,9 @@ def test_dwarf_debug_information():
C[i0_0 * 4 + i0_1] = A[i0_0 * 4 + i0_1] + B[i0_0 * 4 + i0_1]
def check_llvm_object():
- if tvm_tirx.codegen.llvm_version_major() < 5:
+ if tvm_tirx.codegen.llvm.version_major() < 5:
return
- if tvm_tirx.codegen.llvm_version_major() > 6:
+ if tvm_tirx.codegen.llvm.version_major() > 6:
return
# build two functions
mod = tvm_tirx.IRModule(
@@ -719,9 +717,9 @@ def test_dwarf_debug_information():
assert re.search(r"""DW_AT_name.*fadd2""", str(output))
def check_llvm_ir():
- if tvm_tirx.codegen.llvm_version_major() < 5:
+ if tvm_tirx.codegen.llvm.version_major() < 5:
return
- if tvm_tirx.codegen.llvm_version_major() > 6:
+ if tvm_tirx.codegen.llvm.version_major() > 6:
return
# build two functions
mod = tvm_tirx.IRModule(
diff --git a/tirx/tests/python/codegen/llvm/test_riscv.py b/tirx/tests/python/codegen/llvm/test_riscv.py
index 5ff26a28d0..4182e84925 100644
--- a/tirx/tests/python/codegen/llvm/test_riscv.py
+++ b/tirx/tests/python/codegen/llvm/test_riscv.py
@@ -118,7 +118,7 @@ def test_rvv_vscale_llvm_dbginfo(target):
redsum = T.call_llvm_intrin( 'llvm.riscv.vfredusum', T.Broadcast(T.float32(0.0), T.vscale() * 2), prod, zero, T.uint64(7), T.uint64(8), ty='float32xvscalex2')
# fmt: on
- # tvm.error.InternalError: Can't fetch the lanes of a scalable vector at a compile time.
+ # tvm.RuntimeError: Can't fetch the lanes of a scalable vector at a compile time.
with tvm_tirx.target.Target(target):
f = tvm_tirx.tirx.compile(rvv_with_vscale, target).mod
diff --git a/tirx/tests/python/codegen/llvm/test_scalable_vector.py b/tirx/tests/python/codegen/llvm/test_scalable_vector.py
index 8bb365a728..0e703fbc4a 100644
--- a/tirx/tests/python/codegen/llvm/test_scalable_vector.py
+++ b/tirx/tests/python/codegen/llvm/test_scalable_vector.py
@@ -25,12 +25,12 @@ import pytest
import tvm_tirx
import tvm_tirx.testing
-from tvm_tirx.codegen import llvm_version_major
+from tvm_tirx.codegen import llvm
from tvm_tirx.script import tirx as T
@pytest.mark.skipif(
- llvm_version_major() < 11, reason="Vscale is not supported in earlier versions of LLVM"
+ llvm.version_major() < 11, reason="Vscale is not supported in earlier versions of LLVM"
)
@pytest.mark.parametrize(
"target",
@@ -63,7 +63,7 @@ def test_codegen_vscale(target):
@pytest.mark.skipif(
- llvm_version_major() < 11, reason="Vscale is not supported in earlier versions of LLVM"
+ llvm.version_major() < 11, reason="Vscale is not supported in earlier versions of LLVM"
)
@pytest.mark.parametrize(
"target",
@@ -96,7 +96,7 @@ def test_scalable_buffer_load_store(target):
@pytest.mark.skipif(
- llvm_version_major() < 11, reason="Vscale is not supported in earlier versions of LLVM"
+ llvm.version_major() < 11, reason="Vscale is not supported in earlier versions of LLVM"
)
@pytest.mark.parametrize(
"target",
diff --git a/tirx/tests/python/codegen/llvm/test_x86.py b/tirx/tests/python/codegen/llvm/test_x86.py
index 4c92a3722c..ea32df9b35 100644
--- a/tirx/tests/python/codegen/llvm/test_x86.py
+++ b/tirx/tests/python/codegen/llvm/test_x86.py
@@ -25,7 +25,7 @@ from tvm_tirx.script import ir as I
from tvm_tirx.script import tirx as T
from tvm_tirx.testing import env
-llvm_version = tvm_tirx.codegen.llvm_version_major()
+llvm_version = tvm_tirx.codegen.llvm.version_major()
machine = platform.machine()
if machine not in ["x86_64", "AMD64", "amd64"]:
diff --git a/tirx/tests/python/all-platform-minimal-test/test_validate_runtime_library.py b/tirx/tests/python/runtime/test_validate_wheel_library.py
similarity index 96%
rename from tirx/tests/python/all-platform-minimal-test/test_validate_runtime_library.py
rename to tirx/tests/python/runtime/test_validate_wheel_library.py
index ea92272ea6..eb0a5cc52d 100644
--- a/tirx/tests/python/all-platform-minimal-test/test_validate_runtime_library.py
+++ b/tirx/tests/python/runtime/test_validate_wheel_library.py
@@ -14,9 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-"""Post-install runtime and AOT checks.
+"""Post-install wheel library and AOT checks.
-These live in ``tests/python/all-platform-minimal-test`` so the standard suite and
+These live in ``tests/python/runtime`` so the standard suite and
the cibuildwheel ``test-command`` run a single pytest invocation. The assertions
for wheel packaging check things the rest of the suite cannot check -- that LLVM is
enabled (the other LLVM test merely *skips* when LLVM is absent) and that the CUDA
diff --git a/tirx/tests/python/script/test_basic_usage.py b/tirx/tests/python/script/test_basic_usage.py
index 458d6d2e2c..ecfdda3171 100644
--- a/tirx/tests/python/script/test_basic_usage.py
+++ b/tirx/tests/python/script/test_basic_usage.py
@@ -28,7 +28,7 @@ import pytest
from minilang import Value
import tvm_tirx
-from tvm_tirx import DataType, error, ir
+from tvm_tirx import DataType, ir
from tvm_tirx.ir import prim
from tvm_tirx.ir._overload_prim_expr import EqualOp
from tvm_tirx.script import ir as I
@@ -291,7 +291,7 @@ def test_loop_control_validation_preserves_valid_and_unchecked_ir():
invalid = tirx.Function(params=[], body=tvm_tirx.ir.Break())
ir.assert_structural_equal(invalid.body, tvm_tirx.ir.SeqStmt([tvm_tirx.ir.Break()]))
assert not tirx.analysis.verify_well_formed(invalid, assert_mode=False)
- with pytest.raises(error.InternalError, match="requires an enclosing loop"):
+ with pytest.raises(RuntimeError, match="requires an enclosing loop"):
tirx.analysis.verify_well_formed(invalid)
@T.function
diff --git a/tirx/tests/python/support/test_config.py b/tirx/tests/python/support/test_config.py
index 009847d985..f689b3bbaa 100644
--- a/tirx/tests/python/support/test_config.py
+++ b/tirx/tests/python/support/test_config.py
@@ -139,6 +139,7 @@ def test_cmake_targets_without_ffi(tmp_path):
libdir = _installation(tmp_path / "install")
cmake_dir = libdir / "cmake/tvm_tirx"
shutil.copy2(_CONFIG_PATH, cmake_dir / "config.py")
+ shutil.copy2(_CONFIG_PATH.with_name("libinfo.py"), cmake_dir / "libinfo.py")
shutil.copy2(
_CONFIG_PATH.parents[2] / "cmake/tvm_tirx-config.cmake",
cmake_dir / "tvm_tirx-config.cmake",
@@ -186,13 +187,13 @@ def _check_component_closure_and_artifacts(tmp_path, monkeypatch):
for filename in ("libtvm_runtime_cuda.so", "libtvm_runtime_metal.so", "libtvm_ffi.so"):
(libdir / filename).touch()
monkeypatch.setattr(
- config,
+ config.libinfo,
"_ffi_info",
lambda: SimpleNamespace(find_libtvm_ffi=lambda: str(libdir / "libtvm_ffi.so")),
)
def names(components):
- return [path.name for path in config._link_inputs(libdir, "linux", components)]
+ return [path.name for path in config.libinfo._link_inputs(libdir, "linux", components)]
assert names(["runtime", "cuda", "runtime", "ffi"]) == [
"libtvm_runtime_cuda.so",
@@ -214,7 +215,7 @@ def _check_cli_link_flags_and_raw_inputs(tmp_path, monkeypatch, capsys, platform
for name in ("tvm_runtime", "tvm_tirx_compiler", "tvm_ffi"):
(libdir / f"lib{name}.{suffix}").touch()
monkeypatch.setattr(
- config,
+ config.libinfo,
"_ffi_info",
lambda: SimpleNamespace(find_libtvm_ffi=lambda: str(libdir / f"libtvm_ffi.{suffix}")),
)
@@ -280,5 +281,5 @@ def _check_runtime_only_lib64_and_explicit_prefix_ignore_environment(tmp_path, m
(libdir / "libtvm_tirx_compiler.so").unlink()
unrelated = _installation(tmp_path / "unrelated")
monkeypatch.setenv("TVM_TIRX_LIBRARY_PATH", str(unrelated))
- assert config._paths(prefix, None) == (prefix, libdir)
- assert config._available(libdir, "linux") == ["runtime"]
+ assert config.libinfo._paths(prefix, None) == (prefix, libdir)
+ assert config.libinfo._available(libdir, "linux") == ["runtime"]
diff --git a/tirx/tests/python/target/test_llvm_features_info.py b/tirx/tests/python/target/test_llvm_features_info.py
index 4eb07fd99d..df2b9643d0 100644
--- a/tirx/tests/python/target/test_llvm_features_info.py
+++ b/tirx/tests/python/target/test_llvm_features_info.py
@@ -20,7 +20,7 @@ import tvm_tirx
from tvm_tirx import codegen
from tvm_tirx.target import Target
-LLVM_VERSION = codegen.llvm_version_major()
+LLVM_VERSION = codegen.llvm.version_major()
def test_llvm_targets(capfd):
@@ -29,27 +29,27 @@ def test_llvm_targets(capfd):
##
# check blank results
- assert len(codegen.llvm_get_targets())
- assert len(codegen.llvm_get_system_cpu())
- assert len(codegen.llvm_get_system_triple())
- assert len(codegen.llvm_get_system_x86_vendor())
+ assert len(codegen.llvm.get_targets())
+ assert len(codegen.llvm.get_system_cpu())
+ assert len(codegen.llvm.get_system_triple())
+ assert len(codegen.llvm.get_system_x86_vendor())
# check ffi vs python
assert (
- codegen.llvm_get_system_cpu() == tvm_tirx.get_global_func("codegen.llvm_get_system_cpu")()
+ codegen.llvm.get_system_cpu() == tvm_tirx.get_global_func("codegen.llvm_get_system_cpu")()
)
assert (
- codegen.llvm_get_system_triple()
+ codegen.llvm.get_system_triple()
== tvm_tirx.get_global_func("codegen.llvm_get_system_triple")()
)
assert (
- codegen.llvm_get_system_x86_vendor()
+ codegen.llvm.get_system_x86_vendor()
== tvm_tirx.get_global_func("codegen.llvm_get_system_x86_vendor")()
)
- assert str(codegen.llvm_get_targets()) == str(
+ assert str(codegen.llvm.get_targets()) == str(
tvm_tirx.get_global_func("codegen.llvm_get_targets")()
)
- tvm_tirx.codegen.llvm_get_cpu_features(
+ tvm_tirx.codegen.llvm.get_cpu_features(
tvm_tirx.target.Target({"kind": "llvm", "mtriple": "x86_64-linux-gnu", "mcpu": "dummy"})
)
expected_str = (
@@ -86,7 +86,7 @@ def test_target_features(min_llvm_version, llvm_target, cpu_arch, cpu_features,
## legalize llvm_target
##
- assert llvm_target in codegen.llvm_get_targets()
+ assert llvm_target in codegen.llvm.get_targets()
##
## legalize cpu_arch
@@ -94,11 +94,11 @@ def test_target_features(min_llvm_version, llvm_target, cpu_arch, cpu_features,
### with context
with target:
- assert cpu_arch in codegen.llvm_get_cpu_archlist()
+ assert cpu_arch in codegen.llvm.get_cpu_archlist()
### no context but with expicit target
- assert cpu_arch in codegen.llvm_get_cpu_archlist(target)
+ assert cpu_arch in codegen.llvm.get_cpu_archlist(target)
# check ffi vs python
- assert str(codegen.llvm_get_cpu_archlist(target)) == str(
+ assert str(codegen.llvm.get_cpu_archlist(target)) == str(
tvm_tirx.get_global_func("codegen.llvm_get_cpu_archlist")(target)
)
@@ -108,11 +108,11 @@ def test_target_features(min_llvm_version, llvm_target, cpu_arch, cpu_features,
### with context
with target:
- assert codegen.llvm_cpu_has_features(cpu_features) == is_supported
+ assert codegen.llvm.cpu_has_features(cpu_features) == is_supported
### no context but with expicit target
- assert codegen.llvm_cpu_has_features(cpu_features, target) == is_supported
+ assert codegen.llvm.cpu_has_features(cpu_features, target) == is_supported
# check ffi vs python
for feat in cpu_features:
- assert str(codegen.llvm_cpu_has_features(feat, target)) == str(
+ assert str(codegen.llvm.cpu_has_features(feat, target)) == str(
tvm_tirx.get_global_func("codegen.llvm_cpu_has_feature")(feat, target)
)
diff --git a/tirx/tests/python/target/test_riscv_features.py b/tirx/tests/python/target/test_riscv_features.py
index 3a805c4270..c81ca2e4c4 100644
--- a/tirx/tests/python/target/test_riscv_features.py
+++ b/tirx/tests/python/target/test_riscv_features.py
@@ -19,10 +19,10 @@ import pytest
import tvm_tirx
from tvm_tirx import codegen
-from tvm_tirx.codegen import llvm_get_vector_width, target_has_features
+from tvm_tirx.codegen import llvm, target_has_features
from tvm_tirx.target import Target
-LLVM_VERSION = codegen.llvm_version_major()
+LLVM_VERSION = codegen.llvm.version_major()
# fmt: off
@@ -63,4 +63,4 @@ def test_riscv_rvv_features(min_llvm_version, tvm_target, vec_width):
return
with Target(tvm_target):
- assert llvm_get_vector_width() == vec_width
+ assert llvm.get_vector_width() == vec_width
diff --git a/tirx/tests/python/target/test_x86_features.py b/tirx/tests/python/target/test_x86_features.py
index d638d202c6..59da3b2015 100644
--- a/tirx/tests/python/target/test_x86_features.py
+++ b/tirx/tests/python/target/test_x86_features.py
@@ -22,7 +22,7 @@ from tvm_tirx import codegen
from tvm_tirx.codegen import target_has_features
from tvm_tirx.target import Target
-LLVM_VERSION = codegen.llvm_version_major()
+LLVM_VERSION = codegen.llvm.version_major()
# Some x86 features have been removed from upstream LLVM. Tests for these
# features only meaningfully run on LLVM versions that still recognise them.
@@ -197,7 +197,7 @@ def test_x86_target_features(min_llvm_version, tvm_target, x86_feature, is_suppo
try:
assert target_has_features(x86_feature) == is_supported
assert False
- except tvm_tirx.error.InternalError as e:
+ except RuntimeError as e:
msg = str(e)
assert msg.find("Check failed: (allow_not_defined) is false: Target context required") != -1
@@ -209,7 +209,7 @@ def test_x86_target_features(min_llvm_version, tvm_target, x86_feature, is_suppo
== is_supported
)
assert False
- except tvm_tirx.error.InternalError as e:
+ except RuntimeError as e:
msg = str(e)
assert (
msg.find("Check failed: (allow_not_defined) is false: Target context required")
@@ -253,4 +253,4 @@ def test_x86_target_features(min_llvm_version, tvm_target, x86_feature, is_suppo
) == is_supported
# check for feature in target's llvm full x86 CPU feature list
if (not list(Target(tvm_target).attrs.get("mattr", []))) and isinstance(x86_feature, str):
- assert (x86_feature in codegen.llvm_get_cpu_features()) == is_supported
+ assert (x86_feature in codegen.llvm.get_cpu_features()) == is_supported
diff --git a/tirx/tests/python/testing/test_env.py b/tirx/tests/python/testing/test_env.py
deleted file mode 100644
index 2f7105b6be..0000000000
--- a/tirx/tests/python/testing/test_env.py
+++ /dev/null
@@ -1,332 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-"""Tests for the thin ``tvm_tirx.testing.env`` capability probes."""
-
-import subprocess
-import sys
-import textwrap
-from types import SimpleNamespace
-
-import pytest
-
-import tvm_tirx
-import tvm_tirx.testing
-from tvm_tirx.testing import env
-
-# Probes that take no arguments and must return a plain bool without raising.
-_BOOL_PROBES = [
- # runtime device
- env.has_cuda,
- env.has_rocm,
- env.has_vulkan,
- env.has_metal,
- env.has_opencl,
- env.has_nvptx,
- env.has_llvm,
- env.has_gpu,
- # build support
- env.has_cudnn,
- env.has_cublas,
- env.has_nccl,
- env.has_hipblas,
- env.has_nvshmem,
- # version / capability
- env.has_matrixcore,
- env.has_cudagraph,
- # toolchain / environment
- env.has_hexagon,
- env.has_hexagon_toolchain,
- env.has_adreno_opencl,
- # cpu features
- env.has_x86_vnni,
- env.has_x86_avx512,
- # host architecture
-]
-
-
-@pytest.mark.parametrize("probe", _BOOL_PROBES, ids=lambda p: p.__name__)
-def test_probe_returns_bool(probe):
- """Every probe returns a real bool and never raises during collection/run."""
- assert isinstance(probe(), bool)
-
-
-def test_has_cuda_implies_device():
- """has_cuda() requires a device (it also requires the kind to be enabled)."""
- if env.has_cuda():
- assert tvm_tirx.cuda().exist
-
-
-def test_has_gpu_is_raw_any_device():
- """has_gpu() is the disjunction of the raw device checks (no target gating)."""
- any_device = (
- env._device_exists("cuda") # pylint: disable=protected-access
- or env._device_exists("rocm") # pylint: disable=protected-access
- or env._device_exists("opencl") # pylint: disable=protected-access
- or env._device_exists("metal") # pylint: disable=protected-access
- or env._device_exists("vulkan") # pylint: disable=protected-access
- )
- assert env.has_gpu() == any_device
-
-
-def test_target_enabled_respects_tvm_test_targets(monkeypatch):
- """A device kind excluded from TVM_TEST_TARGETS is reported as not enabled."""
- env._target_enabled.cache_clear() # pylint: disable=protected-access
- monkeypatch.setenv("TVM_TEST_TARGETS", "cuda;llvm")
- try:
- assert env._target_enabled("cuda") # pylint: disable=protected-access
- assert env._target_enabled("llvm") # pylint: disable=protected-access
- assert not env._target_enabled("opencl") # pylint: disable=protected-access
- assert not env._target_enabled("metal") # pylint: disable=protected-access
- finally:
- env._target_enabled.cache_clear() # pylint: disable=protected-access
-
-
-def test_cuda_compute_is_monotonic():
- """has_cuda_compute is monotone in the requested version."""
- if not env.has_cuda():
- # Without a CUDA device every query is False, including the (0, 0) floor.
- assert not env.has_cuda_compute(1, 0)
- assert not env.has_cuda_compute(0, 0)
- return
- # A device that satisfies (major, minor) also satisfies anything lower.
- assert env.has_cuda_compute(1, 0)
- assert env.has_cuda_compute(0, 0)
-
-
-@pytest.mark.parametrize(
- ("compute_version", "expected"),
- [
- ("8.0", "sm_80"),
- ("9.0", "sm_90a"),
- ("10.0", "sm_100a"),
- ("10.3", "sm_103a"),
- ("invalid", None),
- ],
-)
-def test_cuda_arch_from_compute_version(compute_version, expected):
- assert env._cuda_arch_from_compute_version(compute_version) == expected
-
-
-def test_has_cuda_arch_matches_detected_device():
- actual = env.cuda_arch()
- if actual is None:
- assert not env.has_cuda_arch("sm_100a")
- else:
- assert env.has_cuda_arch(actual)
-
-
-def test_cuda_arch_uses_requested_device(monkeypatch):
- class Device:
- exist = True
- compute_version = "10.3"
-
- requested = []
-
- def cuda(device_id):
- requested.append(device_id)
- return Device()
-
- env.cuda_arch.cache_clear()
- monkeypatch.setattr(tvm_tirx, "cuda", cuda)
- try:
- assert env.cuda_arch(7) == "sm_103a"
- assert requested == [7]
- finally:
- env.cuda_arch.cache_clear()
-
-
-def test_has_multi_gpu_is_bool():
- assert isinstance(env.has_multi_gpu(), bool)
- assert isinstance(env.has_multi_gpu(1), bool)
- # Requiring a single device is at least as permissive as requiring two.
- assert env.has_multi_gpu(1) or not env.has_multi_gpu(2)
-
-
-def test_llvm_min_version_is_monotone():
- if not env.has_llvm():
- assert not env.has_llvm_min_version(1)
- return
- # An LLVM that satisfies a higher floor also satisfies a lower one.
- assert env.has_llvm_min_version(1)
-
-
-def test_probes_are_memoized():
- """Probes are cached so the driver/subprocess is hit once per process."""
- env.has_cuda()
- info = env._device_exists.cache_info() # pylint: disable=protected-access
- assert info.hits + info.misses >= 1
-
-
-@pytest.fixture
-def clear_env_cache():
- probes = (
- env._target_enabled,
- env._runtime_enabled,
- env._device_exists,
- env.build_flag_enabled,
- env._llvm_version_major,
- env.has_hexagon_toolchain,
- env.has_hexagon,
- )
- for probe in probes:
- probe.cache_clear()
- yield
- for probe in probes:
- probe.cache_clear()
-
-
-def test_unavailable_selected_target_does_not_enable_llvm(monkeypatch, clear_env_cache):
- monkeypatch.setenv("TVM_TEST_TARGETS", "cuda")
- monkeypatch.setattr(tvm_tirx.runtime, "enabled", lambda kind: kind == "llvm")
-
- def unexpected_device_lookup(target):
- pytest.fail(f"Excluded or unavailable target was probed: {target}")
-
- monkeypatch.setattr(tvm_tirx, "device_from_target", unexpected_device_lookup)
- assert not tvm_tirx.testing.device_enabled("cuda")
- assert not tvm_tirx.testing.device_enabled("llvm")
-
-
-@pytest.mark.parametrize("target_form", ["string", "dict", "target"])
-def test_device_enabled_accepts_target_forms(monkeypatch, clear_env_cache, target_form):
- monkeypatch.setenv("TVM_TEST_TARGETS", '{"kind": "llvm"};cuda')
- monkeypatch.setattr(tvm_tirx.runtime, "enabled", lambda kind: kind == "llvm")
- monkeypatch.setattr(tvm_tirx, "device_from_target", lambda target: SimpleNamespace(exist=True))
- target = {
- "string": "llvm -num-cores=2",
- "dict": {"kind": "llvm", "num-cores": 2},
- "target": tvm_tirx.target.Target({"kind": "llvm", "num-cores": 2}),
- }[target_form]
- assert tvm_tirx.testing.device_enabled(target)
-
-
-@pytest.mark.parametrize("kind", ["llvm", "cuda"])
-@pytest.mark.parametrize(
- ("runtime_enabled", "device_exists", "expected"),
- [(False, True, False), (True, False, False), (True, True, True)],
-)
-def test_device_enabled_requires_runtime_and_device(
- monkeypatch, clear_env_cache, kind, runtime_enabled, device_exists, expected
-):
- # In particular, the CPU can exist even when LLVM was not built.
- monkeypatch.setenv("TVM_TEST_TARGETS", kind)
- monkeypatch.setattr(tvm_tirx.runtime, "enabled", lambda target: runtime_enabled)
- monkeypatch.setattr(
- tvm_tirx, "device_from_target", lambda target: SimpleNamespace(exist=device_exists)
- )
- assert tvm_tirx.testing.device_enabled(kind) is expected
-
-
-@pytest.mark.parametrize("cudnn_available", [None, False, True])
-def test_device_enabled_cudnn_runtime_probe(monkeypatch, clear_env_cache, cudnn_available):
- monkeypatch.setenv("TVM_TEST_TARGETS", '{"kind": "cuda", "libs": ["cudnn"]}')
- monkeypatch.setattr(tvm_tirx.runtime, "enabled", lambda kind: True)
- monkeypatch.setattr(tvm_tirx, "device", lambda *args: SimpleNamespace(exist=True))
- monkeypatch.setattr(tvm_tirx.support, "libinfo", lambda: {"USE_CUDNN": "ON"})
- exists = None if cudnn_available is None else lambda: cudnn_available
- monkeypatch.setattr(tvm_tirx, "get_global_func", lambda name, allow_missing: exists)
- assert tvm_tirx.testing.device_enabled("cuda") is (cudnn_available is True)
-
-
-@pytest.mark.parametrize(
- ("runtime", "toolchain", "llvm_target", "serial", "can_compile", "can_run"),
- [
- (False, True, True, True, True, False),
- (True, False, True, True, False, False),
- (True, True, False, True, False, False),
- (True, True, True, False, True, False),
- (True, True, True, True, True, True),
- (True, True, None, True, False, False),
- ],
-)
-def test_hexagon_environment_requirements(
- monkeypatch, clear_env_cache, runtime, toolchain, llvm_target, serial, can_compile, can_run
-):
- monkeypatch.setenv("TVM_TEST_TARGETS", "hexagon")
- for variable, present in (
- ("HEXAGON_TOOLCHAIN", toolchain),
- ("ANDROID_SERIAL_NUMBER", serial),
- ):
- if present:
- monkeypatch.setenv(variable, "test-value")
- else:
- monkeypatch.delenv(variable, raising=False)
- monkeypatch.setattr(
- tvm_tirx.runtime,
- "enabled",
- lambda kind: runtime if kind == "hexagon" else llvm_target is not None,
- )
- monkeypatch.setattr(
- tvm_tirx.codegen, "llvm_get_targets", lambda: ["hexagon"] if llvm_target else []
- )
- assert env.has_hexagon_toolchain() is can_compile
- assert env.has_hexagon() is can_run
-
-
-def test_core_testing_imports_without_domain_modules():
- # Let TVM finish its own startup, then make the domain modules unavailable to testing.
- code = textwrap.dedent(
- """
- import os
- import sys
- import tvm_tirx
-
- for module in list(sys.modules):
- if module == "tvm_tirx.testing" or module.startswith("tvm_tirx.testing."):
- del sys.modules[module]
- if hasattr(tvm_tirx, "testing"):
- del tvm_tirx.testing
-
- for name in ("te", "contrib", "s_tir"):
- prefix = "tvm_tirx." + name
- for module in list(sys.modules):
- if module == prefix or module.startswith(prefix + "."):
- sys.modules[module] = None
- sys.modules[prefix] = None
- if hasattr(tvm_tirx, name):
- delattr(tvm_tirx, name)
-
- import tvm_tirx.testing
- from tvm_tirx.testing import env
-
- tvm_tirx.testing.assert_allclose([1], [1])
- tvm_tirx.runtime.enabled = lambda kind: True
- tvm_tirx.codegen.llvm_get_targets = lambda: ["hexagon"]
- os.environ["HEXAGON_TOOLCHAIN"] = "test-toolchain"
- os.environ["ANDROID_SERIAL_NUMBER"] = "test-device"
- assert env.has_hexagon_toolchain()
- assert env.has_hexagon()
- """
- )
- subprocess.run([sys.executable, "-c", code], check=True, capture_output=True, text=True)
-
-
-# --- demonstration of the target idiom -------------------------------------
-#
-# The standard gating idiom: a plain registered pytest marker (for ``-m``
-# selection) plus a skipif backed by a thin env probe (for runtime gating).
-
-
-@pytest.mark.gpu
-@pytest.mark.skipif(not env.has_cuda(), reason="need cuda")
-def test_thin_cuda_idiom():
- dev = tvm_tirx.cuda()
- assert dev.exist
-
-
-if __name__ == "__main__":
- tvm_tirx.testing.main()
diff --git a/tirx/tests/python/tirx/analysis/test_check_well_defined.py b/tirx/tests/python/tirx/analysis/test_check_well_defined.py
index 6545216b5d..5e35f9ff2e 100644
--- a/tirx/tests/python/tirx/analysis/test_check_well_defined.py
+++ b/tirx/tests/python/tirx/analysis/test_check_well_defined.py
@@ -66,7 +66,7 @@ def test_error_for_out_of_scope_usage():
func = tvm_tirx.tirx.Function([], body)
with pytest.raises(
- (ValueError, tvm_tirx.error.InternalError),
+ (ValueError, RuntimeError),
match="Invalid use of undefined variable i at .* no longer in-scope.",
):
tvm_tirx.tirx.analysis.verify_well_formed(func)
@@ -84,7 +84,7 @@ def test_error_for_nested_rebind_usage():
T.evaluate(i)
with pytest.raises(
- (ValueError, tvm_tirx.error.InternalError),
+ (ValueError, RuntimeError),
match="ill-formed, due to multiple nested definitions of variable i",
):
tvm_tirx.tirx.analysis.verify_well_formed(func)
@@ -108,7 +108,7 @@ def test_error_for_repeated_binding():
T.evaluate(i)
with pytest.raises(
- (ValueError, tvm_tirx.error.InternalError),
+ (ValueError, RuntimeError),
match="multiple nested definitions of variable i",
):
tvm_tirx.tirx.analysis.verify_well_formed(func)
@@ -131,9 +131,7 @@ def test_error_for_cross_function_reuse():
T.bind(42, var=i)
T.evaluate(i)
- with pytest.raises(
- (ValueError, tvm_tirx.error.InternalError), match="multiple definitions of variable i"
- ):
+ with pytest.raises((ValueError, RuntimeError), match="multiple definitions of variable i"):
tvm_tirx.tirx.analysis.verify_well_formed(mod)
@@ -177,7 +175,7 @@ def test_reuse_of_region_parameter_across_functions_is_ill_formed():
A[threadIdx_x] = A[threadIdx_x] + T.float32(1)
with pytest.raises(
- (ValueError, tvm_tirx.error.InternalError),
+ (ValueError, RuntimeError),
match="multiple definitions of variable threadIdx_x",
):
tvm_tirx.tirx.analysis.verify_well_formed(mod)
@@ -222,7 +220,7 @@ def test_error_message_without_previous_definition_location():
T.bind(99, var=x) # This should trigger the error
T.evaluate(x)
- with pytest.raises((ValueError, tvm_tirx.error.InternalError)) as exc_info:
+ with pytest.raises((ValueError, RuntimeError)) as exc_info:
tvm_tirx.tirx.analysis.verify_well_formed(func, assert_mode=True)
error_msg = str(exc_info.value)
@@ -247,7 +245,7 @@ def test_error_message_with_previous_definition_location():
T.bind(99, var=x) # This should trigger the error
T.evaluate(x)
- with pytest.raises((ValueError, tvm_tirx.error.InternalError)) as exc_info:
+ with pytest.raises((ValueError, RuntimeError)) as exc_info:
tvm_tirx.tirx.analysis.verify_well_formed(func, assert_mode=True)
error_msg = str(exc_info.value)
@@ -278,7 +276,7 @@ def test_sequential_redefinition_with_location():
T.bind(2, var=x) # This should trigger the error
T.evaluate(x)
- with pytest.raises((ValueError, tvm_tirx.error.InternalError)) as exc_info:
+ with pytest.raises((ValueError, RuntimeError)) as exc_info:
tvm_tirx.tirx.analysis.verify_well_formed(func, assert_mode=True)
error_msg = str(exc_info.value)
@@ -349,7 +347,7 @@ def test_tensor_load_asserted_type_matches_source_and_indices():
malformed = tvm_tirx.ir.load_json(json.dumps(graph))
assert not tvm_tirx.tirx.analysis.verify_well_formed(malformed, assert_mode=False)
- with pytest.raises(tvm_tirx.error.InternalError, match="asserts result type"):
+ with pytest.raises(RuntimeError, match="asserts result type"):
tvm_tirx.tirx.analysis.verify_well_formed(malformed)
@@ -368,13 +366,13 @@ def test_tensor_load_malformed_indices_return_false_without_asserting():
rank_mismatch_indices.pop()
rank_mismatch = tvm_tirx.ir.load_json(json.dumps(rank_mismatch_graph))
assert not tvm_tirx.tirx.analysis.verify_well_formed(rank_mismatch, assert_mode=False)
- with pytest.raises(tvm_tirx.error.InternalError, match="indexes 2-dimensional tensor"):
+ with pytest.raises(RuntimeError, match="indexes 2-dimensional tensor"):
tvm_tirx.tirx.analysis.verify_well_formed(rank_mismatch)
indices[0], indices[1] = indices[1], indices[0]
non_final_vector = tvm_tirx.ir.load_json(json.dumps(graph))
assert not tvm_tirx.tirx.analysis.verify_well_formed(non_final_vector, assert_mode=False)
- with pytest.raises(tvm_tirx.error.InternalError, match="only the final index"):
+ with pytest.raises(RuntimeError, match="only the final index"):
tvm_tirx.tirx.analysis.verify_well_formed(non_final_vector)
diff --git a/tirx/tests/python/tirx/base/test_imm_values.py b/tirx/tests/python/tirx/base/test_imm_values.py
index f267b63bce..1eb03c33cd 100644
--- a/tirx/tests/python/tirx/base/test_imm_values.py
+++ b/tirx/tests/python/tirx/base/test_imm_values.py
@@ -59,8 +59,8 @@ def test_tir_invalid_intimm(dtype, literals):
for l in literals:
# Out-of-range positive literals raise a builtin ValueError from
# the IntImm range check; negative-into-unsigned raises an
- # InternalError ("cannot make uint from negative value") which is a
- # RuntimeError subclass. Accept either.
+ # InternalError ("cannot make uint from negative value") mapped to
+ # RuntimeError. Accept either.
with pytest.raises((RuntimeError, ValueError)):
tirx.const(l, dtype)
diff --git a/tirx/tests/python/tirx/base/test_scalable_datatype.py b/tirx/tests/python/tirx/base/test_scalable_datatype.py
index 45bb8f4553..a5a11a9759 100644
--- a/tirx/tests/python/tirx/base/test_scalable_datatype.py
+++ b/tirx/tests/python/tirx/base/test_scalable_datatype.py
@@ -19,7 +19,7 @@ import pytest
import tvm_tirx
from tvm_tirx import tirx
-from tvm_tirx.codegen import llvm_version_major
+from tvm_tirx.codegen import llvm
from tvm_tirx.script import tirx as T
"""
@@ -36,11 +36,11 @@ def test_create_scalable_data_type_python_api():
# the old name from the intrinsic table:
# https://releases.llvm.org/20.1.0/docs/ReleaseNotes.html
_STEPVECTOR_NAME = (
- "llvm.stepvector" if llvm_version_major() >= 20 else "llvm.experimental.stepvector"
+ "llvm.stepvector" if llvm.version_major() >= 20 else "llvm.experimental.stepvector"
)
-@pytest.mark.skipif(llvm_version_major() < 13, reason="Stepvector intrinsic was added in LLVM 13.")
+@pytest.mark.skipif(llvm.version_major() < 13, reason="Stepvector intrinsic was added in LLVM 13.")
def test_create_scalable_tir_intrin():
intrin = tirx.call_llvm_intrin(_STEPVECTOR_NAME, ty="int32xvscalex4")
assert intrin.ty.dtype == "int32xvscalex4"
@@ -49,7 +49,7 @@ def test_create_scalable_tir_intrin():
)
-@pytest.mark.skipif(llvm_version_major() < 13, reason="Stepvector intrinsic was added in LLVM 13.")
+@pytest.mark.skipif(llvm.version_major() < 13, reason="Stepvector intrinsic was added in LLVM 13.")
def test_tvm_script_create_scalable_tir_intrin():
@T.function
def my_func():
diff --git a/tirx/tests/python/tirx/codegen/test_cuda.py b/tirx/tests/python/tirx/codegen/test_cuda.py
index 3918130d40..1bb95ed34e 100644
--- a/tirx/tests/python/tirx/codegen/test_cuda.py
+++ b/tirx/tests/python/tirx/codegen/test_cuda.py
@@ -187,9 +187,7 @@ def test_legacy_tensorcore_ops_require_downstream_codegen(op_name):
"global_symbol", "main"
)
target = tvm_tirx.target.Target({"kind": "cuda", "arch": "sm_80"})
- with pytest.raises(
- tvm_tirx.error.InternalError, match="Unresolved call.*" + re.escape(call.op.name)
- ):
+ with pytest.raises(RuntimeError, match="Unresolved call.*" + re.escape(call.op.name)):
tvm_tirx.get_global_func("target.build.cuda")(tvm_tirx.IRModule.from_expr(func), target)
@@ -204,7 +202,7 @@ def test_warp_storage_requires_explicit_local_layout(target_kind):
output[0] = fragment[0]
target = tvm_tirx.target.Target(target_kind)
- with pytest.raises(tvm_tirx.error.InternalError, match="warp storage is unsupported"):
+ with pytest.raises(RuntimeError, match="warp storage is unsupported"):
tvm_tirx.get_global_func("target.build." + target_kind)(
tvm_tirx.IRModule.from_expr(main), target
)
diff --git a/tirx/tests/python/tirx/codegen/test_hopper.py b/tirx/tests/python/tirx/codegen/test_hopper.py
index 23cbff0d9c..fad00405a7 100644
--- a/tirx/tests/python/tirx/codegen/test_hopper.py
+++ b/tirx/tests/python/tirx/codegen/test_hopper.py
@@ -608,7 +608,7 @@ def test_cp_async_bulk_tensor_global_to_shared_unicast(dtype, inputs):
],
)
def test_tensormap_encode_tiled_runtime_validation(shape, dtype, encode_args, error_msg):
- with pytest.raises(tvm_tirx.error.InternalError, match=error_msg):
+ with pytest.raises(RuntimeError, match=error_msg):
_run_tensormap_encode(shape, dtype, encode_args)
diff --git a/tirx/tests/python/tirx/codegen/test_ptx_addr.py b/tirx/tests/python/tirx/codegen/test_ptx_addr.py
index 5d9cf124ee..e4bf18de4b 100644
--- a/tirx/tests/python/tirx/codegen/test_ptx_addr.py
+++ b/tirx/tests/python/tirx/codegen/test_ptx_addr.py
@@ -225,9 +225,7 @@ def test_ptx_addr_unrolled_expression_and_dynamic_rejection():
T.ptx.ld.global_.b32(value, T.ptx.addr(src.data, i * 4))
for func in (thread_dynamic, loop_dynamic):
- with pytest.raises(
- (ValueError, tvm_tirx.error.InternalError), match="must become a compile-time"
- ):
+ with pytest.raises((ValueError, RuntimeError), match="must become a compile-time"):
_cuda_source(func)
diff --git a/tirx/tests/python/tirx/codegen/test_ptx_dialect.py b/tirx/tests/python/tirx/codegen/test_ptx_dialect.py
index df7c3438ba..a30a0e516a 100644
--- a/tirx/tests/python/tirx/codegen/test_ptx_dialect.py
+++ b/tirx/tests/python/tirx/codegen/test_ptx_dialect.py
@@ -1842,7 +1842,7 @@ def test_ptx_logic_shift_dispatch():
d = T.local_scalar("uint32")
T.ptx.lop3.b32(d, A[0], A[0], A[0], A[0])
- with pytest.raises((ValueError, tvm_tirx.error.InternalError), match="compile-time constants"):
+ with pytest.raises((ValueError, RuntimeError), match="compile-time constants"):
_cuda_source(lut_runtime)
@T.function
diff --git a/tirx/tests/python/tirx/script/test_basic_usage.py b/tirx/tests/python/tirx/script/test_basic_usage.py
index 7d8dce025f..b2c048f047 100644
--- a/tirx/tests/python/tirx/script/test_basic_usage.py
+++ b/tirx/tests/python/tirx/script/test_basic_usage.py
@@ -229,7 +229,7 @@ from tvm_tirx.script import tirx as T
def func():
x: T.handle = T.int64(0)
"""
- with pytest.raises(tvm_tirx.error.InternalError):
+ with pytest.raises(RuntimeError):
from_source(src_handle)
# 3. Banned: non-PrimType annotation without T.let
@@ -240,7 +240,7 @@ from tvm_tirx.ir import PtrType, PrimType
def func():
x: T.Var(name="x", ty=PtrType(PrimType("float16"))) = T.int64(0)
"""
- with pytest.raises(tvm_tirx.error.InternalError):
+ with pytest.raises(RuntimeError):
from_source(src_ptr)
# 4. An explicit mutable scalar declaration retains updates — round-trip
@@ -571,14 +571,14 @@ def test_thread_return_is_distinct_from_function_return():
def test_loop_control_validation_preserves_valid_and_unchecked_ir():
# Invalid loop placement must be rejected, while disabled checks preserve the original IR.
- from tvm_tirx import error, ir, tirx
+ from tvm_tirx import ir, tirx
invalid = tirx.Function(params=[], body=tvm_tirx.ir.Break())
# Direct construction retains the native statement for an explicit verifier pass.
ir.assert_structural_equal(invalid.body, tvm_tirx.ir.SeqStmt([tvm_tirx.ir.Break()]))
assert not tirx.analysis.verify_well_formed(invalid, assert_mode=False)
- with pytest.raises(error.InternalError, match="requires an enclosing loop"):
+ with pytest.raises(RuntimeError, match="requires an enclosing loop"):
tirx.analysis.verify_well_formed(invalid)
@T.function
diff --git a/tirx/tests/python/tirx/test_cuda_backend_config.py b/tirx/tests/python/tirx/test_cuda_backend_config.py
index 1eaba7425a..b8b044eee9 100644
--- a/tirx/tests/python/tirx/test_cuda_backend_config.py
+++ b/tirx/tests/python/tirx/test_cuda_backend_config.py
@@ -599,7 +599,7 @@ def test_legacy_payloads():
current = old_binary + string(snapshot.encode())
assert load(current).inspect_source("backend_config") == snapshot
for malformed in (old_binary + b"x", current[:-1], current + b"x"):
- with pytest.raises(tvm_tirx.error.InternalError):
+ with pytest.raises(RuntimeError):
load(malformed)
diff --git a/tirx/tests/python/tirx/tile/test_dispatcher.py b/tirx/tests/python/tirx/tile/test_dispatcher.py
index c4c0ce11d6..eeb9000aec 100644
--- a/tirx/tests/python/tirx/tile/test_dispatcher.py
+++ b/tirx/tests/python/tirx/tile/test_dispatcher.py
@@ -158,7 +158,7 @@ def test_residual_tile_call_is_rejected():
call.op.name, "FTileOpDispatch", lambda call, context: Function([], Evaluate(0))
)
# Dispatch expands statement-boundary Calls; other positions must be rejected.
- with pytest.raises(tvm_tirx.error.InternalError, match="Failed to lower the TIRx program"):
+ with pytest.raises(RuntimeError, match="Failed to lower the TIRx program"):
_lower(Return(call))
diff --git a/tirx/tests/python/tirx/transform/test_lower_tirx.py b/tirx/tests/python/tirx/transform/test_lower_tirx.py
index 51335b0bab..d27649f222 100644
--- a/tirx/tests/python/tirx/transform/test_lower_tirx.py
+++ b/tirx/tests/python/tirx/transform/test_lower_tirx.py
@@ -897,7 +897,7 @@ def test_lower_layout():
@pytest.mark.parametrize(
"target,error,message",
[
- (None, tvm_tirx.error.InternalError, "Target context required"),
+ (None, RuntimeError, "Target context required"),
("cuda", RuntimeError, "An explicit layout is required for shared tensors"),
],
ids=["missing-target", "missing-shared-layout"],
diff --git a/tirx/tests/python/tirx/transform/test_make_packed_api.py b/tirx/tests/python/tirx/transform/test_make_packed_api.py
index 19367b4014..b7d807a8f7 100644
--- a/tirx/tests/python/tirx/transform/test_make_packed_api.py
+++ b/tirx/tests/python/tirx/transform/test_make_packed_api.py
@@ -692,9 +692,7 @@ def test_return_from_parallel_scope_is_rejected():
for i in T.parallel(2):
return i
- with pytest.raises(
- tvm_tirx.error.InternalError, match="Return cannot be used in parallel scope"
- ):
+ with pytest.raises(RuntimeError, match="Return cannot be used in parallel scope"):
tvm_tirx.tirx.transform.MakePackedAPI()(Before)
diff --git a/tirx/tests/python/tirx/transform/test_split_host_device.py b/tirx/tests/python/tirx/transform/test_split_host_device.py
index c08edbc037..0fb2059989 100644
--- a/tirx/tests/python/tirx/transform/test_split_host_device.py
+++ b/tirx/tests/python/tirx/transform/test_split_host_device.py
@@ -169,7 +169,7 @@ def test_device_kernel_nonzero_return_is_rejected():
)
return 1
- with pytest.raises(tvm_tirx.error.InternalError, match="successful return"):
+ with pytest.raises(RuntimeError, match="successful return"):
tvm_tirx.tirx.transform.SplitHostDevice()(Before)
diff --git a/tirx/tests/python/tirx/transform/test_vectorize.py b/tirx/tests/python/tirx/transform/test_vectorize.py
index d1f42b8b77..7093fbe203 100644
--- a/tirx/tests/python/tirx/transform/test_vectorize.py
+++ b/tirx/tests/python/tirx/transform/test_vectorize.py
@@ -18,7 +18,7 @@ import pytest
import tvm_tirx
import tvm_tirx.testing
-from tvm_tirx.codegen import llvm_version_major
+from tvm_tirx.codegen import llvm
from tvm_tirx.script import ir as I
from tvm_tirx.script import tirx as T
@@ -84,7 +84,7 @@ def test_vectorize_vector_scalable_error():
A[T.ramp(j * 4, 1, 4)] = T.Broadcast(T.float32(1), 4)
error_msg = "Creating scalable vectors from existing vectors is not supported."
- with pytest.raises(tvm_tirx.error.InternalError, match=error_msg):
+ with pytest.raises(RuntimeError, match=error_msg):
tvm_tirx.tirx.transform.VectorizeLoop()(Module)
@@ -97,7 +97,7 @@ def test_vectorize_vector_scalable_error2():
A[j] = T.Broadcast(T.float32(1), T.vscale() * 4)
error_msg = "Vectorizing over scalable tensor elements is not supported in vectorizer."
- with pytest.raises(tvm_tirx.error.InternalError, match=error_msg):
+ with pytest.raises(RuntimeError, match=error_msg):
tvm_tirx.tirx.transform.VectorizeLoop()(Module)
@@ -113,7 +113,7 @@ def test_vectorize_vector_scalable_error3():
)
error_msg = "Vectorizing over existing scalable vectors is not supported."
- with pytest.raises(tvm_tirx.error.InternalError, match=error_msg):
+ with pytest.raises(RuntimeError, match=error_msg):
tvm_tirx.tirx.transform.VectorizeLoop()(Module)
@@ -129,7 +129,7 @@ def test_vectorize_vector_scalable_error4():
)
error_msg = "Creating scalable vectors from existing vectors is not supported."
- with pytest.raises(tvm_tirx.error.InternalError, match=error_msg):
+ with pytest.raises(RuntimeError, match=error_msg):
tvm_tirx.tirx.transform.VectorizeLoop()(Module)
@@ -509,7 +509,7 @@ def test_illegal_extent():
A[j] = 3
error_msg = r"Failed to vectorize loop with extent n for target None"
- with pytest.raises(tvm_tirx.error.InternalError, match=error_msg):
+ with pytest.raises(RuntimeError, match=error_msg):
tvm_tirx.tirx.transform.VectorizeLoop()(Mod)
@@ -523,7 +523,7 @@ def test_illegal_vscale_in_non_sve_compilation():
A[j] = 13
msg = "Failed to vectorize loop with extent T.vscale\\(\\) \\* 4 for target"
- with pytest.raises(tvm_tirx.error.InternalError, match=msg):
+ with pytest.raises(RuntimeError, match=msg):
tvm_tirx.tirx.transform.VectorizeLoop()(Mod)
@@ -877,7 +877,7 @@ def test_vectorize_llvm_pure_intrin_fail(extent, vec_str, target):
# LLVM 20 added vector support for llvm.lround/llvm.llround. The IR Verifier's
# "Intrinsic does not support vectors" check was removed in release/20.x, so
# compilation only fails on LLVM <= 19.
- if llvm_version_major() >= 20:
+ if llvm.version_major() >= 20:
tvm_tirx.tirx.compile(mod, target=target)
else:
with pytest.raises(Exception, match="Intrinsic does not support vectors"):
(tvm) 12/12: [DOCS] Add standalone TIRx Python API scaffold
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 6a4f354cf444c9ff9bd534cee49f5d9c66152542
Author: tqchen <ti...@gmail.com>
AuthorDate: Fri Oct 16 02:33:56 2026 +0000
[DOCS] Add standalone TIRx Python API scaffold
---
docs/.gitignore | 19 ++++++++++
docs/conf.py | 28 +++++++++++++++
docs/index.rst | 28 +++++++++++++++
docs/reference/python/index.rst | 78 +++++++++++++++++++++++++++++++++++++++++
docs/requirements.txt | 19 ++++++++++
5 files changed, 172 insertions(+)
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000000..fabfa51909
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+_build/
+reference/python/generated/
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000000..208c27c6ea
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import sys
+from pathlib import Path
+
+sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "python"))
+
+project = "Apache TVM TIRx"
+author = "Apache TVM Community"
+extensions = ["sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinx.ext.napoleon"]
+autosummary_generate = True
+exclude_patterns = ["_build"]
+html_theme = "sphinx_book_theme"
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000000..5abf08212f
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,28 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+.. http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+Apache TVM TIRx Documentation
+==============================
+
+Table of Contents
+-----------------
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Reference
+
+ reference/python/index.rst
diff --git a/docs/reference/python/index.rst b/docs/reference/python/index.rst
new file mode 100644
index 0000000000..6c5442af57
--- /dev/null
+++ b/docs/reference/python/index.rst
@@ -0,0 +1,78 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+.. http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+Python API
+==========
+
+.. automodule:: tvm_tirx
+ :no-members:
+
+.. currentmodule:: tvm_tirx
+
+.. contents:: Table of Contents
+ :local:
+ :depth: 2
+
+IR
+--
+
+.. autosummary::
+ :toctree: generated/
+
+ ir.IRModule
+ ir.Expr
+ ir.Stmt
+
+TIRx
+----
+
+.. autosummary::
+ :toctree: generated/
+
+ tirx.Function
+ tirx.Var
+ tirx.TensorType
+ tirx.decl_tensor
+ tirx.IndexMap
+ tirx.Layout
+ tirx.TileLayout
+ tirx.compile
+
+Target
+------
+
+.. autosummary::
+ :toctree: generated/
+
+ target.Target
+
+Runtime
+-------
+
+.. autosummary::
+ :toctree: generated/
+
+ runtime.Tensor
+ runtime.Module
+
+Code Generation
+---------------
+
+.. autosummary::
+ :toctree: generated/
+
+ codegen.Executable
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 0000000000..bad902409b
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+sphinx>=7
+sphinx-book-theme
(tvm) 09/12: [META] Add repository ignore rules and release keys
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit b2e6e56471aa5ea8e7117dfe4d45adf50fc4400e
Author: tqchen <ti...@gmail.com>
AuthorDate: Fri Oct 16 02:36:17 2026 +0000
[META] Add repository ignore rules and release keys
---
.gitignore | 292 +++++++++++++++++++++++
KEYS | 762 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1054 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..b3c8bf941d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,292 @@
+
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+*.S
+# C extensions
+*.so
+*.ll
+.npm
+# Distribution / packaging
+.Python
+env/
+build/
+build-*/
+!.github/actions/build-*/
+!.github/actions/build-*/action.yml
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+.conda/
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Generated by python/gen_requirements.py
+python/requirements/*.txt
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*,cover
+.hypothesis/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+docs/_staging/
+
+# PyBuilder
+/target/
+
+# IPython Notebook
+.ipynb_checkpoints
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# dotenv
+.env
+
+# virtualenv
+venv/
+ENV/
+
+# Spyder project settings
+.spyderproject
+
+# Rope project settings
+.ropeproject
+*~
+*.pyc
+*~
+config.mk
+CMakeUserPresets.json
+Win32
+*.dir
+perf
+*.wasm
+.emscripten
+
+## IOS
+DerivedData/
+
+## Java
+*.class
+jvm/*/target/
+jvm/*/*/target/
+jvm/native/*/generated
+jvm/native/src/main/native/org_apache_tvm_native_c_api.h
+*.worksheet
+*.idea
+*.iml
+*.classpath
+*.project
+*.settings
+*/node_modules/
+
+## Various settings
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata/
+.pkl_memoize_*
+
+.emscripten*
+.m2
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+## Other
+*.moved-aside
+*.xccheckout
+*.xcscmblueprint
+.DS_Store
+tags
+cscope*
+*.lock
+
+# vim temporary files
+*.swp
+*.swo
+
+# TVM generated code
+perf
+.bash_history
+*.json
+!tests/python/tirx/iket/oracle/iket_official_cutlass_4_6_0_oracle.json
+*.params
+*.ro
+*.onnx
+*.h5
+synset.txt
+cat.jpg
+cat.png
+docs.tgz
+cat.png
+*.mlmodel
+tvm_u.*
+tvm_t.*
+# Mac OS X
+.DS_Store
+
+# Jetbrain
+.idea
+.ipython
+.jupyter
+.nv
+.pylint.d
+.python_history
+.pytest_cache
+.local
+cmake-build-debug
+
+# Visual Studio
+.vs
+
+# Visual Studio Code
+.vscode
+
+# tmp file
+.nfs*
+
+# keys
+*.pem
+*.p12
+*.pfx
+*.cer
+*.crt
+*.der
+
+# patch sentinel
+patched.txt
+
+# Python type checking
+.mypy_cache/
+.pyre/
+
+# pipenv files
+Pipfile
+Pipfile.lock
+
+# conda package artifacts
+conda/Dockerfile.cuda*
+conda/pkg
+.node_repl_history
+# nix files
+.envrc
+*.nix
+
+# Docker files
+.sudo_as_admin_successful
+
+# Downloaded models/datasets
+.tvm_test_data
+.dgl
+.caffe2
+
+# Local docs build
+_docs/
+jvm/target
+.config/configstore/
+
+
+# Local tvm-site checkout
+tvm-site/
+
+# Test sample data files
+!tests/python/ci/sample_prs/*.json
+
+# Used in CI to communicate between Python and Jenkins
+.docker-image-names/
+
+# Printed TIR code on disk
+*.tir
+
+# GDB history file
+.gdb_history
+
+# Less command history file
+.lesshst
+
+# Agent tracking files
+LOG.md
+STATUS.md
+
+# Local editable-install artifacts (pip install -e .)
+python/tvm_ffi/
+# Generated by setuptools_scm at build time
+python/tvm/_version.py
+python/bin/
+python/typing_extensions.py
+python/*.dist-info/
+pytest-of-bohanhou/
diff --git a/KEYS b/KEYS
new file mode 100644
index 0000000000..c5297eb911
--- /dev/null
+++ b/KEYS
@@ -0,0 +1,762 @@
+This file contains the PGP keys of various developers.
+Please don't use them for email unless you have to. Their main
+purpose is code signing.
+
+Examples of importing this file in your keystore:
+ gpg --import KEYS.txt
+ (need pgp and other examples here)
+
+Examples of adding your key to this file:
+ pgp -kxa <your name> and append it to this file.
+ (pgpk -ll <your name> && pgpk -xa <your name>) >> this file.
+ (gpg --list-sigs <your name>
+ && gpg --armor --export <your name>) >> this file.
+
+-----------------------------------------------------------------------------------
+pub rsa4096 2019-11-15 [SC]
+ EF52D68AD5276994249816836754EA97C55E3DEB
+uid [ultimate] Tianqi Chen (CODE SIGNING KEY) <tq...@apache.org>
+sig 3 6754EA97C55E3DEB 2019-11-15 Tianqi Chen (CODE SIGNING KEY) <tq...@apache.org>
+sub rsa4096 2019-11-15 [E]
+sig 6754EA97C55E3DEB 2019-11-15 Tianqi Chen (CODE SIGNING KEY) <tq...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBF3OK24BEADD4hxjrsgb4jIDIACHS15X+5YP/YaUF5UDDQs/bNn/xGJGVl4/
+4sJ6qKZcvMDrWTmnNItYBuaHi1qhGvlcASBekm/9PU2U8lZmAF1lZkKIIYZkX+If
+s8PEYurE8cDr65orrdsFF8Zwb+u6x+gMsHNivsU2Kn3xbQjGmeW44UA+aaXzcJp6
+sVk3aX5DypoYJNBmbASyOjZVWkcrJ+NKEfJ1dKtka5/siqOjuvCd8NT5dJVhZbm3
+Sf8iclEMqog1LhdI/FhE2fB3C5hJkzcinq2v55qDaGqsL+qgT7agf9b4t0EgjbVh
+cs6jlCglad+Oz27BQIjt06HE1OB5T/Gxa080FK4JZMpxZJ5tDA2/7DQM2MyN84z/
+s62JuBJnsrzr4w8D/QcAyzAmyzAqvxLR/aqLgJTIcQiw6AenHovKkNbEQOBYE2T5
+ms7uVO2E2Tv42J4Te4OKhpId9mK+7elCLvOb2DfAJDdYxDN9c8dJTls+G6xmv0h9
+bb2+QRjkpDiFeu1hKNEe0/ST/YXDfRYpKl+1t/QZ+JccLgEdEwuo/IQ1e4POH2h0
+Zqvy7TR5obeTf0TvmLzW+i3s1oUkmSAnQEncSGnGnlugYk0BLuMMi9Fhx6qcC5pC
+cA3nsRqFKebtnpop+m+psFkmd//xKSXJt9IYVEbQVNiUKm9uYq6RxZEAmQARAQAB
+tDJUaWFucWkgQ2hlbiAoQ09ERSBTSUdOSU5HIEtFWSkgPHRxY2hlbkBhcGFjaGUu
+b3JnPokCTgQTAQgAOBYhBO9S1orVJ2mUJJgWg2dU6pfFXj3rBQJdzituAhsDBQsJ
+CAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEGdU6pfFXj3rVJIQALBArXEaFDdTw8wl
+65nPLU6+QPc6eMn7mz6BDp1V7xL6Lq1GbArLpmQHIFhfQ/5Qmg80wuFBU1CNSRHd
+tdZq3v8tB9Txvhy6bLQ+IijWH/TxSEPqnrkNsWBQLqAygDC5O3Ook/T6B5kuc176
+Kz+w+YhzPS5hoPfJK6xGoKDNlkhmI/EnUjAq459VNpXeoeemiydzvApiCHH0VfOj
+XnmgAJsAJA21EfT5Wuh/WODsf0HkaXB0xoWZfE/ugIQBLhZi9nUTYgwU2r4a+v4A
+4C2T1OyJ3mDU+Oi/z6d0WJvsIrLCFcF4Q7b/6+MGkgLDGlsEKK2LZMrulGzQ1QY/
+O4ck3dVDseqT2urplrTamDIh1IQmOt1FqMFwugdjfQwJ5HQeX6IeUGZei2Av/IZR
+8Vw5Wxtm1Aksz3Js6iP3QmAh7txDUKO+eT5zLSXBoPmkleLnvCdtlvwaSNCAudHw
+12h10IV286OetJvyyjmh/q/30sKNGiuucLMzPMwtLNW/j3cts3fqRHIHxepT6m94
+FoYIlwVu4afiGgSi/7cN4p9GgfwnFGeETd25pgNG0KdXbVWniO1dTEKzOtvtuPYK
+Y88ZAfdOgj4dyeI9ZnJV8RaZvpImDPVHGQm69/071jBxyWZnVi/YtOm+DjHfw0Vi
+uiUdzoIb54oWW8tbiNg/nfiLUaJBuQINBF3OK24BEAC9W8Cwubu4Dpr4m0IIrLF5
+zRRqQm9QIcEC0QHf6w1c2NWQTJP+MQY/jZLjtKw5yCQDghT+qsil2p8xCM0EqRd6
+6NqxsAoweTCoV0MwolQv5T3KuP54SlNWjO+6gT73LkKuOHoIyy5cS9pIITlExHy+
+XHtfQi1keDpWUEyvSRG9slu1DcxAeo6nFEpCuoQ+xx/lrCMxDlyZJCDhj2fXs2hK
+8oKLV5NbIuifbXbCiOvZUdBHk0yLCEc6wNsVR30yLijSiPCKsAPcsG0PjQnz3eTb
+0czq+6g50zUVOTioUghIlZ1DhCsxQGnlxoLY71pnmc7qVszdXPV2Mp7/KSIhDJFQ
+LN0enDVz9aRXfpEK3SifxaPVNd61O/BGziza+XCK5qpEQL95UM2NdQCWixYmIOJE
+k95tpnagtNupMkrY6WEa0CjVBzF1kdr5WpeUd6w85rA/opcqpQ8yLmvpyJ4tXZhN
+7oAWZSUzyB904FMswUEhaS7pEJIlACeFcPwm31Jv/637gw1CopZpDxDUaW5/boG5
+9Gp9D/GV2gyMrHAcwA1gZSbmolv5ZYcnUmwTPijVNZ+o70HBbvbNZqziPgy9G+L/
+oGBkY/fpg7qfaGtAbOUbx1ck04CbafSUQIxpCG8in6zwrIRnn4uj6q4wIZ8SnvQ0
+h3Ug0DmdsxvB/xdfillH/QARAQABiQI2BBgBCAAgFiEE71LWitUnaZQkmBaDZ1Tq
+l8VePesFAl3OK24CGwwACgkQZ1Tql8VePeuZ1Q//csRsGDKNrW5e0EitEcfPZ0PC
+teEw7A16dniXiCQF39KxxLzjCjUq7U8iWNm7bn1zdXcSVYZow+i5hFWXgZLKTKep
+tQoocJmQ7kPV5oiTBewFy9T4BICUekj/EhXhSz1wxb3GSc+uHL2IUlFkixTY4k4B
+9zq49gkNkTM02Or3quu1ZWAgeol1BSyV0tcI1h3M0OXtrN6idLyzQJFRyMYtzfwp
+Pd2+hdaKAl8mKANs/GMJni3QvyVXzuJxMP6SNOFx4mWj0UVFVZvosv1lLXDesvwY
+sNZmz5IkfuU4DHz1ZzZc3sThkpBdBiadvyKtNsenNh5nEXtwVhpiFf3IdZAvG7Ks
+7i3Fx1/ObbvxMCWeFoB6oP/swHr9i6dqntiJoB6Gl5y1ye3qte8PiNuwRVhz+YOK
+58Ga3wWMvODpi2AgSFv7cd1OFXXsoonORfmpcfAp+h6dIr/ttQMP2929/NoX3Cs4
+/pXoG9L5EOpMfj0Q24sAGW8VzuCAHL3e7QSijFuSHZxz9oe4C28/mAY+KP0dif0Q
+O3rq4kpqlhseyzcRyE1LWBvzuCeSTui2OPmyivFY57TOPnMHm5sXVby1VUiwm0B0
+RgBtZDRLv765lAFGtp43sccZ7zfRaKhkVmzh3bAZ62nJyQNGw0TWg96Pf7Kjb0Bv
+ha8fS9ysWDy/Ye65MP4=
+=MSiP
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa4096 2018-02-07 [SC]
+ F42C1A6E634C105E8D985105CA751254E97B9FE4
+uid [ultimate] Yizhi Liu <li...@apache.org>
+sig 3 CA751254E97B9FE4 2018-02-07 Yizhi Liu <li...@apache.org>
+sub rsa4096 2018-02-07 [E]
+sig CA751254E97B9FE4 2018-02-07 Yizhi Liu <li...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBFboMe8BCADLHoUiTXPKpDQXXkJ8VWi2iekYYReMrkKgBaQv5nlYww2va1fV
+9VcVGAlrlZ2XFXa1xVF/LwnfPXtg0xD+lL/6FQJlL+esdosDP2E4Gu1AQMyuOS3J
+1Dy/iMidI9XJFhoPikDkXBjcMQiVBABP6Goc6da3oFkDf4dnBUGbUI6SOzNsiJxq
+IQ/JkICZ/8HfbJk3nIiAVfyuqCrHxWqL8JWM/SwWcjaZDRFFgCp5SAQbv9+xqEpE
+GYcJ0bP/PFgyyLBlWS1vsnrlxVZf0fsnNrYHDcYA7Q7iiVjaHR426zea4nUm/72+
+9cF8QpE+JVFf/uhf1SpJ9cnvgSa9lKU+9EjPABEBAAG0H1lpemhpIExpdSA8amF2
+ZWxpbmpzQGdtYWlsLmNvbT6JATgEEwECACIFAlboMe8CGwMGCwkIBwMCBhUIAgkK
+CwQWAgMBAh4BAheAAAoJEIlV2E4gyasMy20H/3508Rr+JvptnVMQQ0OzOhMiYdp3
+Pv3M3ES2lFa22AJKLg3snSIJj1ros7ZyWEZWdOSQocWF+Q1+xX54pEeRfcHuDHfv
+QZPeYzVspteHS3rZZ51o4f7GyLbMY1sUEqJAzMne965Z029HXSUOjfcD/4gTOi0y
+fnlb+HVcAtGA+Q+kU2R8FG43F5+BWfo0dGLev9cEAcW18sz6u/rmkc1ZHPsC0LG8
++ZR3SEbMznXMe6RGbVurHOw/LpQsf5K+u7J3lb9fk0kXmp+NzZxybPU9XEmC6eH4
+kj3fJCbycBdscW0lDVk0eWL2z4TAQdI5Er88P1RnwCM6eQo0ljjj2pNqnW65AQ0E
+Vugx7wEIAMFm7Im7iOL7rEYmJKcNvANSeL08AE12pHt5g2+8pd10m9oiyyAYAU/i
+Ogar7mmNXGBxXy9gsgxUwGuFixv/nj9ts8+GNGi7pLGfYWdsD4P9LYtzZR7VHpOZ
++taIjqsgTvNtGCuqdX6uWCMJKgQ3kNl9cuzFQeQkAcCjrc4mJky69OcKCJvgJ+bd
+76TgxKeeX47jz0Rpi+0qf3CFxc8Ey306BXraf4RThsE6ySBWvZxgYBgdTKOqHyNI
+3DRnIHOXwXMu+k3yCPpUUJBfkSLQ4WP1fllSJvO/MzVSZTbdXA9jZFKv/q2cyMMW
+gm/Z4dxGv1M3dYcJZTNkW0hxWEYn900AEQEAAYkBHwQYAQIACQUCVugx7wIbDAAK
+CRCJVdhOIMmrDJq4B/4+85Dqx+sPfA59duYx4EI4zAn/c/EIBi1iNtu1KxFdDOR2
+JZSaM4JCAdCoe4Y8W0euwZa3UeO0F+4fqXOjiFri2+l+JLdtdeAwApMSDNmjqHez
+WrLF0QEZ+f2cErTQ3ZhAhxNO31RWN4okTMaZYgqZkMhM/C732AFAdk3Ryc4Phz1z
+T60414x6iwNOy3d7QvnsFZqH3yViYkNf09cn+onWsUhM8AM9dWG/uA1cF7u5UMAn
+L7jeE3ner9eTyJ+FfzjLS7N2XyfGlEdzaQ6b9vH4WfBBixSLbNWEaQEEFNqyBMB1
+HBUJtd/3SWWQZY0MMpGUIRaTGsrXCHrr5aqkUHUEmQENBFnwWJ0BCADbZIs3nd+L
+MWCYQK1badVHpzNBRYlbKl6TDsrxUje32/d5FhJ0Sq2yP0hSm5ggfVqt9Pl9Pz+M
+tv8cY/gC0Gkod22iNEvn/V3Y/+tXepsuiXD+cyGWuAc4kbN6kHBmCHKpRHpbO2NO
+AFm5cKJEVu9yiBBxz/bA8HeD/HjmIPnZfTBADxl6qu+s0YTaDT+N9c1M4JDDB6zJ
++iYCrv23R1SvoBssSaEZbQD5+bW4efPslOwjAysG8r7CDrJA8aXSJfudMKu5Zxku
+TMzVkWGWj0VnEHRkHVqagZvXHc6gkprlKh+XEaj1+qsa3anORbEEaeeBLCEvyLW2
+j7mYRJ//cWyLABEBAAGJAR8EIAECAAkFAlp6jHkCHQMACgkQOnCfbyuG6dYCoggA
+hTCfDHYSdAVUx/H+45Gbnurdi/PDmpKIom2HaGF2ur1+uR/rCumPCXoV2EuQNntD
+CxvXsWDhTEf/coOAfJ3WiF0b4AzDOuHa3+YOGHBD6/rPMDtFkorc8EQhoqrOvOn9
+8bJBetXVqmZjX3Mwg4aii9Xn4b3G3D4YaMXHiXuH+lOa5YU0oMze3hzMCh22ZMl/
+IQqZY9B2cc1q8gXjtK4JN5k8etD4U+uOBZVlWyDrbD2jMC4GCXeiAVESsh99Aes2
+yc8B/jhDfLF4LvYW72AHkNlLzmdEs1w3x1CHMP7k2sS+QznTTtmNZ3wonaDj1fdu
+ne+Wf1vUtLKs2DLT8Av767Q1WWl6aGkgTGl1IChZaXpoaSBMaXUgYXQgQXBhY2hl
+KSA8bGl1eWl6aGlAYXBhY2hlLm9yZz6JATgEEwECACIFAlnwWJ0CGwMGCwkIBwMC
+BhUIAgkKCwQWAgMBAh4BAheAAAoJEDpwn28rhunWdTUH/0j9HOIKyj368ImHr7WL
+CRKi6E9OwN24JP/sD2PMxq5DK7vlGRumQ7qvvDU3DuR13EmzEBpTY6IQagShvH8E
+EaV9r5cXmKnISAqGcL+Xe9HyJm4ANMLsTjhX9WkDFYluVfujVHSWq8jz9KDGB6Qw
+dpmHWfHNVZGKK/TmINwL7K+HKcSntH35tL+NrnbbpMU/XnICdXd8ZvVhVGFpCJy/
+4Deq2zu7qeVaAmRLdwo4wr5EZqvWDgr4iIYHTsKsM2qQbfe7zArXi1oyO0vyncER
+5sAmaP1iSEPp8zaTslDEDfd3Vv1c0Kegyss//l4O11mzXJkFPLYD+EnaXsmkzLjw
+udS5AQ0EWfBYnQEIAJ9YYPa3T7ENm+lOyJDW0Z9MCWs/TfH+MNx7CGIf7UiPtCgY
+AMBz3wDeQIfMkU//21U6he84FGiEk8CRvxXgsQ5jTNCt5BYD2g3/FsriEG1QiLLJ
+sURsfacMc5YkWojbSELF4Eqs6yFt52rb9I7cpWA0/HIBpW1IzD11BB2BS0qPvx7d
++emKwbO+ZR/xyb+xKVcd8NMR/gIKBiMZY2fxqyOK235aRd6Qnfp2XnbgKFdiZN9j
+A+xo0hPkGeUAhRKZfzdVP/kVzZZTiASUilRNen9RmfEvQiMQlgNrhHwrHKKifz2E
+BR85HyLVraEDLQq6hPVBYZlf1h5TX4SBL9X8AsUAEQEAAYkBHwQYAQIACQUCWfBY
+nQIbDAAKCRA6cJ9vK4bp1nO7B/9VfccO6yvoT7oYFMuXsJK2NTUoBID6PDFQjDLX
+ml54xoNwJmBw4eU7WWKoha9GPha0VCce/9Rlj9vUQxoMA9Jt0oj3Vu3OwQiGdkay
+I0cKhYVAMDtaCdCoha7iW8pd6C/zGKSBvSKwdxxe+mD8+jE4+LWRTDvuUhQBfBH6
+uEJNus48gdYIDfPqujcn1coGeLzc4TeKUOd6qKhbY5rGL7JTxaNJ7O64ffNaplUP
+w67vt0J2iNdRJglaFippQq29dYTfdpddnlrZnMYjD1M3FmnpCEOWQQKT3Kz/KYGd
+iy2XFfGsSWm9s/+3VyEC5Y85iqfhYoWkISuWS6uOpUwf2F1zmQINBFp6j2ABEADO
+07fnGhxTkPfmRsJS65Cif6ywUVRl2ZXKi/N7DjKJdl+Ej5lGOaw5cExaP0RD5iT5
+ZCAzfUS7UFULybEcbqgnm/RzaCrz9mx3gLa8Jx9XncagwJQU9GbvJxzlX8itgY9v
+ezK1q7Ec/iwCA66suzLeY8cA68EvWwmjR/1WlE9W/gov9mSlCu7QRIP9DuUHyL9Z
+ZtYTwYTKsSaRCTv42xvkxAQ/ifinYZn31uQmW41Gqt2YFNWlfp1uA97dmyAKcIeO
+CkvpQyChspJLIcA5lQrH6RV+oyuhRoSw/ZXPwdRXS1+79arCe1vsMUeZPzkzSXcr
+pkzROOzVx1WlXR8WYcWtaXkPsgn7Icym0ngnwRbuY0JACT2F8MWgBlC3LQj0mrhC
+cr26v9ettcmeulmuY/WLIi9oDtgq2yHSbz2na+qbPRd5vDS1i+nD62xvejZXC7xI
+naoyB0f6QYpgXQKyEFO/uCUGFXCBwYAPe4XwkNozR1GmOTKP9ZnriJax/BIPva5J
+iqK5pkqOxuiGuPNdW7Bj/HvQr7F1s5LoG+Q8YSVo/KEJ2oo3IwU6FWZwq+KY/bVT
+O3fRCBD7Fgu8Eu9zw8ANIvpuq+BDo3yoUCoS83Ok+favH0K/jwBVFyu+/rnJc4wn
+7Px9/zdniaSTuxK6pAyTiUtVy6Gp73Roik5Dhu3nqwARAQABtB9ZaXpoaSBMaXUg
+PGxpdXlpemhpQGFwYWNoZS5vcmc+iQJOBBMBCAA4FiEE9CwabmNMEF6NmFEFynUS
+VOl7n+QFAlp6j2ACGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQynUSVOl7
+n+TMiA/+LB2vDz8ZzMRTwlnWxxhiKU8+P5QEvC7sgwg6REiqjEfo+Abcf/erRzMS
+nX0G4G6xauty4NDtieUI3X/mDKUS96yqo8Ij5NO02ltI0isG6edlyyjrs01yiGHN
+KjTDkU1f1Af+wW8/h9By6cf2x4u9VWfSUjzwkcrr1qorP0AU1cSXVDJNxnKKHbds
+BlVC7UkUX1ZMBQq3inFIox5y1cSL34joUGRcyFtqZDoTvYMIZgAiJJw1JmpQU2bt
+e3T1/70j6za81/09ev/kN9HIfeK2Mh0IVTttvBdggmQZHhKq5tL70v93RUoCaRmJ
+CvyUTaSe1o57phzOeUj8FmFhvqugnrtfYaygdvjrOZYXo5R18jXiQG0lNQPuxh9V
+r6dca85aP12yB6kK8/d+09PaEtirqwW32YcoNeiHtPWvEIastcO+bAE6OKFWHE+3
+mYKr2m4hAH6CWDOa+x6p9JyciTKxEgaaXcj/q458r2S79iMeJknzLKw9zLPjHAm0
+tb45x893xnjNSSDd8DhjwwwZKCt/pZs2E0pyp08DF1a8uCIdoQ0s4eo5Yr7tJxGp
+AWgd/VcrlHBmmGdqdMMUhS02BjuyVDXc+T3fbE1a5QIpHoqjl7lyeY+VLnOUt9Y+
+RyWKsDONsB3QcuMRaQQWGf7eeILMIZ+Y33qpt0/55qLbzsEY/265Ag0EWnqPYAEQ
+AMLE3QGCRBZU4nGKyOIpIsWpolG8f5vnAZJwsC6g4ya3odsHuUknDo7Puhp7RCIx
+HuEtSBTf+20nFifX7GCgHAKn/mGWDk9mNWmsGpVzXcHNO0TKTod6V9FE5SC3CVgg
+K8U1PesXh0PoV2AMWq1AmzWJyivHFRefuPilu+NVRE/Mj6ZWbs3ApixMml/0S1Y7
+L5btNjG1DCZbs6i70nSuUXXXM/D0jkCYljYf8wtruzj1MN97NZP2nvGjyBkGw9tN
+xyWYirZ5jJOlzbee4rags9agxETrZ4z9S3QAFcQaKNI32HyuSJELgIcx5U/uB2f1
+9GQX/33kk26OrTAW6INUCRK6ji2y0F8IxfrHd0WXj/RFrV/okQyEai5x8oC1+Rik
+62CEnI9EfL/WU/toHtSeFBfNrtTKa3WiXnQDfHmJBe1wfvOmM3QjH2ApPBwUXXbl
+m7wBCPEjQJs+B0FIrlpJdN+KaGMMSHsz90f9QMF6GH/pgDPG7K1IBsP3ZqDzJi7C
+LnLTAf0FreLuKLix349Y4X603uNd6Fx6vK3BGWB3ZyH7D1vCMBBytDdb66nmQQ3Q
+ZjJBU8FCGuBwd8q32bVKbIOQTQiMUbUGe3xZozC82mB3glEUCO46OElD0j56GC3X
+GVK4utPexIX9hcQ+uSXStrwhgHd76/iFCsb1F9wR16EVABEBAAGJAjYEGAEIACAW
+IQT0LBpuY0wQXo2YUQXKdRJU6Xuf5AUCWnqPYAIbDAAKCRDKdRJU6Xuf5KqtEADH
+xHPTbl1lT/QZZ+Y+SSuDpPF4uMjUP1TPyt6LGK9O/C0raIxabpCtuit9VPwcubH/
+krVQxqIkje1rI6kjl/+krrwnnNhjUozoQh4y0e90atgu9phoQGjb12vhl5P95OB/
+YX8ZRJ2Bt7aSTfZiUUbL0OwwgontgLFNyz9/FNp/9eSrxOcoMazkt5D6SrW0IBW9
+l5SZeNDc9yYw0CMg/5YZ5Rv++APgXHWc/WjuDMHje7hi2VFM12VXF+gWQZy842n5
+IQzRPx7Pav32iByN00qKLNUUIwgoEQwZMStC9xjooGSmqOVUWnMYBLiUgNTySgOh
+u73hZVo8VNpOseatlaIRGC2ukn8AF5TlXMKf7O9L24x6bp3Bd7M5KUNCUDgwn0mj
+VjsGEcT41Rc9XtglB7aLTiKhE/LqGi1f+BQolr6nGLEQ+oVub3bqratmjAE7Pw7B
+yzup78JPVMt8vNdjwGYg3yHW4atLS1qUQ9VNYo2l4b+DxcCvFxV/mAfa+07j1Z9E
+p4/Pw35uanSfOo0ylGmHp/h9yh27vrF1EzwshB7DlJoo5KfnIxR3jVTKye+UerEt
+N8yATW8CRIKO3IobUfLMDdPCLO7uzoW95cI35Y0l8JgK2NeU6tVZptP5mDogeAbq
+8PlimrXuzG9Bokct2SOO6Z51i6rSDo/ALj440EvWNw==
+=1xfH
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa4096 2020-09-24 [SC]
+ 6A0D4938D8C052C759AE2460ED03B26E4FC3509F
+uid [ultimate] Ziheng Jiang <zi...@apache.org>
+sig 3 ED03B26E4FC3509F 2020-09-24 Ziheng Jiang <zi...@apache.org>
+sub rsa4096 2020-09-24 [E]
+sig ED03B26E4FC3509F 2020-09-24 Ziheng Jiang <zi...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBF9tEiUBEAC90om00alNSupM78ZZYMdwKZnJLIhAD22YARntVNVBuD9Znpuo
+BAYwjrWdAi/npwN+r+Pd7Oz6fMBCmB3e4tsrPnBzauGb6aKgjBMHcVEx0p1197kk
+WcGuKt4FNlHYfmc2sOOQre2GcIVOU1XuK8tAhgca78aorAlMtOqq+/ASnKcjRSjW
+0AOzlEKfaGVgst2UO7Fc/w59S3/qv1vBGKnlqLvsJU7kNR1gFotqsGAee5Vu7alQ
+WiHFJbW9ujLTPu7m8enFVuBGFkPsW89Yl/0mXnAKZFFNCHIQ9gkT+1bvZhx8ViJL
+4UeqG7wnSLSSIQz2UPBJYV5stxNtd9HS08Tfviv37shd1SSprFLoQDk87j7wF60b
+AR5IjbVgdprpmVNncO5pnyZwXXWVi7ZyiMSaW6wg+lkeQMGflxgL+05xOafJYgO6
+UepXqu1mc7Q4eVUyft/EPmdyvlg7Fo4T4Db2PnstonkZCyLogdaaJRuxCc0AR/O1
+oNaodrdjqydXVnP3d/gJ5gj78zeMPVbGbzwhpIwhfDouxftaU5zc6prBsMgY/os6
+XMe9bNZWpOLXZrmo/ovaiebmxT5ZYuFRGdeRl1/Y5CWE6Q9JM8euwKuskNQ4G0aY
+fVQ61Cxg4hmrnsv9YFAjf9PPWhpFHvILQoGSs3HbJCLFPphKf37gzfiZMQARAQAB
+tCBaaWhlbmcgSmlhbmcgPHppaGVuZ0BhcGFjaGUub3JnPokCTgQTAQgAOBYhBGoN
+STjYwFLHWa4kYO0Dsm5Pw1CfBQJfbRIlAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4B
+AheAAAoJEO0Dsm5Pw1CfBl0P/R04MxtqC4aI0fpdwmed55kGunL1W65phBgcOrDL
+58cv5dKJzUmfSUXw3QANcFSn9Q9Z2clj+a2aiGKV5cUiWN0Ny7y6wd3aVOXlRHHy
+f30aDO5Ug5RDYbcChTpen+kq9qDXSr/NxXYLWvhobMeXfiA9Priv49fFWEr17Kai
+NOuoix/eWA5WpnPMf/Rz4HibKcX/izXTW0NOH54jn+4P9M4ZwWbn0AXKoq2i3zF2
+vZavCStcscrfs+kihtEVvwUkyrmSIblIUdkPNxeo/jx7N9Fbu2zXbhl5JiBmBUMJ
+XyFUOBSUDUzA5EvWwXp0yatULOoCH/LIyt+lLdkyfDjsKmAavGf9CcFHVyDIG95N
+34/jECPwwVVkbauE0XYOwenOh+Be1goOA6nidB4QT/rGns7zvCNG8+3ttwA4aiE5
+3GrVWXiPaEMaoM56Phscek30GoLjB2gjvwgwa9oGTDYTu8Z4ifLk8qq8ij9uEG7V
+cKns+1C3ZvfdKi8SmOzj/v9krOi8N4YW03YS2Oq/cGPD/SttoMTOCPxi0PLR7uqy
+YXugsebxlJlXBNTeZx+iiKmkrsILjEd8pUChw79crtH2SGOPqIv1BsqObstLV04r
+iiywruqLRIGlsr8BtepCeEfzW9nJRw7W2571t7oD7QbkdCJ4WUyhMJH73+7KFEE2
+fKL5uQINBF9tEiUBEACmMcP8/zm88BmyhDjWV3ZrZ9cn0N3JJfSONt0AcyE5TZ2y
+20DnHkp3/lNK6EC0k7twtcce/cnKDbXQ/IpuJZwReq5SgmCoGbBZShjALtVCzQRm
+pSA6Wl0JBfw36/IdKUuf8LZtENqp3jgQkkT3TA+/bCh1KQLDYFoVQjUBLiWCDHiL
+iBV5L/PH97l93hkxbSDXrBemQRbr+xhA2TzwcmrjnscNCAXkwU9f1Ygh8zDHSJKB
+g7Ln+ot6QsPhNQEQWhju5xfAn9+kO8OWSAZF/lJTT2Wy+spDBP1ZnviQadWPj5HL
+n4G1qe4QWl08E9FtqVKC7r1YYzT4DlTU2AQ0bJqdvAtojX9ji2Hp4ov8xYPHzy3a
+ZRdDYNWN6i0mbpzj8SYojyEG5cy2j+nzGOYTEdpwW8pG2aCwRvnO+UqXNM3UyQk3
+9Tyfyzw6m9mlq9zaw/nfvOIA6Ns2QR5+UbplkpwVMqMAzZNyEV2wPe9B195MN6tq
+KcznzawD/W1ORccOxrpBXhN3sJSc5n8Uy5pHUHg9B/TdCSLpr7tqqS34gB+AcSUL
+NxjdLn72JHKxCp/wpg3Z4bmY5n/bh/D7Ovt7LP1D/MW9wiR3ls/PtNAK4+SV6oqt
+G1MNS0QgAitovF8dpmX+/zPKax7baZiJY/sDr9crfRvd6e+HYA3yDo08Z44MTwAR
+AQABiQI2BBgBCAAgFiEEag1JONjAUsdZriRg7QOybk/DUJ8FAl9tEiUCGwwACgkQ
+7QOybk/DUJ9Txw/+NXL6cKEIm4NQrBc0RmX37sELc5UnvpycV663OiPF9qHE9iML
+EUt/LBxrGUarplOA66EIkmmnekUgS8ujjhGOw152nSuZTgoPxX4ub6PI7Hi5lmqI
+ZtEpp8VoI+XxAdA5ecN5QNP7P/ovSIZwXvIF00YXqGp6keXi/qdYkylt4s6zLDiL
+ocfOZWt994JVIl30gogkw4PmcWx+PKXos+Hq1La7iZUn1pT5kEsN+fHpnh42sAGZ
+dhb+puB5tczhVJhL553Z6rh4BABd1DqAZihwelkRRvQUp0Fqgc2oxty5o5pdHZdS
+ulomOqGgERHsrtwzqD/n3iep3z22LiitZHsKZ0OoHl9e1YsvdsL5rImEz/FdWwgl
+muO2ZjY2KhuovFROCsGVgw3b9gzIjtE8FWE6wSz6qzKihBbI8YPtQqGJgnX2A01m
+AkfpGPb8430OghDCQFsrWkuTjmSw42ys1lALbK2yQGRuOCq0dIml1QdE6JfU8ceW
+QY1dhH7xpHQxlr9Tcv+enCc4UzCJOnXgkVUnD/u+TqKL9GoSFu6KQrC7jyvfY9t8
+Elf2ReXYVK/jGUePdDFurp+3KFlAHFuen2VZTcNZaUWoYoI84VDEh8/oPEPfzveJ
+/GhL5vbglB0H0aG8SVMaTfzr+nXHUVyOSrlYYk34O7bSimVrX6XDGPZpsXE=
+=nhJ/
+-----END PGP PUBLIC KEY BLOCK-----
+pub 4096R/D75EFD4B 2020-09-24
+uid Zhi Chen <zh...@apache.org>
+sig 3 D75EFD4B 2020-09-24 Zhi Chen <zh...@apache.org>
+sub 4096R/285DD7CB 2020-09-24
+sig D75EFD4B 2020-09-24 Zhi Chen <zh...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBF9tJNABEADpv6LjNjEkb62cIXKHLcg0vugPgGzui+cR/YyJc0zNMPnQNnvD
+D0VisV+vdorYDmXMLRhGC4KbD6vmoFnriBJrdKYpl0geV8Uzw3S3Ecyh4ELK1ayD
+aVpyE5A+73LbLTSnnmfonXcWdW03hZe8ilKc8vapvibCMQ7SVvEJ8nHHd/YmAteL
+6HNLfTkm/pBZ2MxX0k2Cm0qX4UnERKEWFPGjXWViRaMLWl2ufIocA0KXWRRgiprb
+FwMUTUCjWiPE5L6/8OKjKHdIv0gKi3WeMPYpN0PNTclqlZ5YAbxuSOnuRXmw4D8d
+bnM/V+Hq4s0VQLMItbdGX1pmiJmHsXRygjgvZV6giusNge0KWcKEUvJaU0wOOyTC
+luAgqWo54pMDHEd8561uvSishgG5/ePDNTdouR05J4MOl8cVBFrPwqPvymk/Wztt
+qsYXiZhJ1vdMD1X4UUNYg3peDHsIZWdNIQTcEgRSArSahOlM5dyjSLFbHj2gjWES
+pP8EqmkTn1/nRUaFvhZCX1r37GYYbHH8iD58omG38eVW4uOIyz3nwl5DxUO2+4it
+NGigNoDQ7c2OMn/F7P9m3juxhx2hyaR5nTDm48ZaUbMUFbfWqTIhPBSqP9qZr/8g
+72zY1AkvPPOfgGChJ7/XGnyzf94C6DtDJQgubjnNsZCHGQyNdPAz3F7U3QARAQAB
+tBpaaGkgQ2hlbiA8emhpY0BhcGFjaGUub3JnPokCOAQTAQIAIgUCX20k0AIbAwYL
+CQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQn77L09de/Uu8Rg//aoDx5Sus1FQ+
+BIctSl7gc/grs6rHYFPi6d/ZH0vXbsa1c5oARVAJd+gnhrG0Lylmf0kbcixriNwT
+iVoo32CyA3VnT7vT46moRCe9UQBuEjIYWo1YiAXq5we7stsWqwpCDhR/h7weuhXR
+Rr4nIzLnFEBzvLcuqorVL3xTkisnu3u3i8XQsPbLkQQXohP0BWJoBZKN+VEGciWD
+26rriDeGw7ew5L4qJe7AKwS9Zt0jQoiEINp/CtINOrNNIhDxaKy6AwW/1wohVOtq
+TG7kyU+zgtYV7+nZpXT62lKn3rOsX6OxsEU9IPqrCRMW2WExxUJ1w6iUBUcxwlUz
+QbVdCRLMfR8HE/BgFVQLP8ESka2gH/tcFEp+tsv7p47wsrs9NbIaL+yYWQFat5r0
+h5ynjFAFmc89weC5h/bVKv/W0Hrt5YZmWxVjiSPZW13eDQ00PliJTyMlIGxsboQG
+3k0+MxH+bpj8VK5cfnbTDg77eiX2XYyGuV4Vs5Yv+y3qiShD/nGJKNrKk6LaF75f
+hwzxEv04tBdNVKjYm9IY64pg+3e916vTpVrhkU3+frzQPr5SYKr/v1vYnknADgn5
+TYdtSKoWx6D98JWllNcOhfYw3auiF4f1E47yJ00JFVvNQzlVDaqeGWbRj9DMt590
+BDkAVsr+//2SrmjYvr/Q/b1EVC3nwxC5Ag0EX20k0AEQALaqrORp/Y/GHDgGxYfF
+Wu4YNwN4W3JCFKVu7s7yC4T7ndcGrn4MEq0b3kuJeucl8UO9IGEILokQzOHadPDm
+2mvUYzzZULgUCRQZTUpU4AhKgbh4eB6LMcxiIRVDaCO/xg2+dFyry7+kk/gpZSy2
+HCot0jvFCDFOxXk6WRCycy/EXuWvZyKMm7Bp+CViX9UoV/S9VkdaxFbSCBWdfmTn
+d1QT+GivOLxY8xy21VO5qugnH7nEvcnbniF8zqprpJlgvM8MRW9voFCZg3UOjpDI
+cT4foqX+h8FL6BxLKMrYEAx0rdYdn0weaptqkdDc0BAz561q9bcprOmIIEapQ7yE
+N9vcUt2i2/Op/CQsKs2dZx13RtHhDCJ2awZ/eiKdMowJKx0dNOdsBVK49TKYSt6G
+jQiIKaFB+x4ta6IWDVq8v8zctaDI2ud4OR0kvwP9A4rbuC3k3P+4ojo0OoUO1Ais
+g3wSX+bHtOrXQVPuJiSaKp/zJShiSH1k7DCgqPav5SuF+fnuIJ95yLPdDlmxKqDS
+JxlCaWgWX6j622zTxJLlm5YgedBi1wKx6BqLdKE1Lvv8As/VwFMxDv9smDwVaMlD
+rrwPc3/BT2ES1Pqp1CmgZKVmQ0/4UvvIOe5MeNI5pQ7NBO+0rTN+JkANEVSxTi/u
+Ne4tPZk7C/Y5iQvAIYq5BZUJABEBAAGJAh8EGAECAAkFAl9tJNACGwwACgkQn77L
+09de/UuLYxAA1T1YT5e5BoxjVm1WvwDmg8Vagwj1E1ZVBWG2H0/uL5ew+7/4Jy4C
+iy5DZOdGUbF7hIH0J6Kn/UJGXyRPQh3rMk/hwaColpA6AjrV8LxMjPwgjgUWzBMK
+NlhSsGj4UE84tblGL65boDaGeJKYbRU4b9Rw8nx3jQOrSk7xwmLW8qJYyQIgUKPv
+hLhq4Ni4pfxDkKOa2GT58Yg8wadN/ZB38q9r2cU33XjyJo9AeWeeqYS4LZvc1mDu
+DUV3C+RJpNh8+njYSYeO5G8CrQljvUYVWaylL51HPVcRfc+9u+uPfdf4pdcng4Rj
+U1LyQQX+JaiukZsX0xXk2CiWSAhWfP3i92baX00SeFkNXxVmUVFjr+WkEPun+EVs
+4cnJUHqgH2dkAU3WAChGnI9gJEa63gyN8N4IbTmQnLOnyFt57jmtfMrRGpU/BqFN
+b3FNtmtnms9QjqrOr8QxFG78jfNluuEIslP0ul0fbwovItpZxLF3cIPr9M+irKEv
+9w0IxAzfZ1IPpl7EltKVK+gN9Wt99Lqkx/kJHw5R/HTUuM6FxjL+1PGWYybhuU9n
+Q2YsCQ/Br0XhJvC+i6OYgCI1iGLINTe9wjsi2ei8ZI+2G9XY62sN0orIIjIadns+
+8WGuWI9h3RBLY7aFMLpl02cXrsOiMcXC1Uk/e6e14Xpu+Y6IG4KKkUM=
+=GEwA
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa4096 2021-11-10 [SC]
+ C5E5C09030E7BD32DF9A67CE35ABC9676004ADAE
+uid [ultimate] Junru Shao <ju...@apache.org>
+sig 3 35ABC9676004ADAE 2021-11-10 Junru Shao <ju...@apache.org>
+sub rsa4096 2021-11-10 [E]
+sig 35ABC9676004ADAE 2021-11-10 Junru Shao <ju...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGGL/BwBEAC8krTtoeZUNgWVTEBZ8Gm77xwy0W1NjpqY6+cT01xW1vlsjMBl
+MoR2bGA8aR+vNERI/CfRN8uyplWyoCK7fbnk0Rcd81nvdMqYiXWg55PetJ+oPm+B
+8j26ssUe+Umg0cwa4ZUbdmicSSlousjR75XlasanrGggn1iH0ltiwvkyxKIlppo9
+UTgh6Db3sK3i+hNrwZmMliG03CpdZqh9luCQD2KaHhL2v63fzEo2mKJLHFQGYmRR
+dkCvF8GNEkoyVbOVRY+jnZ97C6U4XigAwwqi7kBp9QJ5DE7xzjXwCOS2QNUzvdjF
+/OE3zTVJmx5qSD9i5u69A3iXBEfVd19gCDiJIkOttgfNgKy+atK+Bmc5iM9aizCA
+jZQAt0uOsPXzNkiiiJoTp6egvt05F/7Z/cy+UQZb+GQNRqMr+8Z77QjH1fAAB8qz
+q+Z/W6Gazws+CiqkVrvMUKCIj3AxHWeiUDwD1KGap3WkpocEuJ2IXuYUlySDIFXv
+Iigm0a0KFt8Ex4cfz3GNS6eH0bjHn6YIebIQIRRYI4kozy/JMAYJ78Tx8Rp0WY38
+85PXQZazHRriVttc8YrnK8uAHjN01COOyGkwYp20Xqw7dOoYCnbhObYvoDDHRtMm
+2O7TtK6sfnyWhL9ZRGOWyqoIw+4TIh+sS0z1dj7oyWeSaPHTCbj/7CneZwARAQAB
+tCFKdW5ydSBTaGFvIDxqdW5ydXNoYW9AYXBhY2hlLm9yZz6JAk4EEwEKADgWIQTF
+5cCQMOe9Mt+aZ841q8lnYAStrgUCYYv8HAIbAwULCQgHAgYVCgkICwIEFgIDAQIe
+AQIXgAAKCRA1q8lnYAStrinMD/96v0V5JOtvT2+NzkxyoZPFw/1H/jtAoCAm2IUq
+PhUGibAPztREBcbr40I8l8bLghvN3PyNFop/TY7uxwzTzJrST1eZxML6x75pw6QK
+2dbY0fFV3SEucDd8mCtVk/5F5ZWd7pXfYq4HVIcSikL0RbKHEl7N8fCRQHBQ63OA
+MugeAnTfGhppQHLJQtN9iKx4iHt5aH38MMlhlzfqEwjMEfCm0OnnEWjLbjQgCFTU
+1llnQEWxT1kwsiHKNvuTSuLrSP5SHsE/VGixLWUw3YzvDFrP5pmnY7XRz4jAynrS
+QIoKnb6WtKCuos1Ym9gZIqXlPKZWfL93FBqD+lmHBMoPIVlubAOGR5scRd7sWhDd
+ECnRWQZmIQ4b6g8dmcFQ/vC+1G75hr3EZEZHX6F3tS4lLHZ9NxiKK49ctD6UIJVP
+4FIAOY+lB1LDVRObm4KuQ9sLO60p7Bh3xqEzqDZRLwO+z3vo7nQl+F+SwWRcI2tN
+BrDaM+MDIrBiwPH79Ehi7r4fFVqzmHDvqa0eBjUnVx9g6AnlR91/4QX9ZLt+rUlg
+ufJC35fUSJpRLLWUIAto8veLv7rd5mwbeocnncAXlx3+rN9NDEiFqeNeijLfv9bb
+VXa7f1+vfyTn+ZrxB6vGM76bzZosJUWBhrVcq6Pv0Llxowy11z8tMBgALoKnwPhQ
+KyBcNbkCDQRhi/wcARAAqA2X+BDf2aUFaMdSOGfxTf3y/moLREw0xw4zfGzpeMjY
+ln+GrziX/+3bdwiDw8fwbe/r6M7jRW+66ndzI8J3qz6mpZpYbSUYdSpThqn2M/Pn
+cwFjzP9hn5436MoiO+EPz7dukmXq1+a7L7arQUdpQ+LReFg31M8uDiaKmOGBibGw
+2NmyD9NRsWsWn4thn4lu4ir1tSfgkSlSJPQyGF22Y1h6I5serjAbLqrXFG8+ziKv
+HBXofYvQEnHynPzByJUy1CxAKojyvR+ARiSfhW2EOlB5USLjjGvgIKBko912EYU1
+s2GblBPkdBgHpMaVq4+uUdQcAvOpsscsoMMB3GQdhnMHrZGMjN+fPbMer4w721yo
+495IOFGE97XSiO/1CPpVzIOPzl+QpSuRdl/GlKr30+vEUwTSXUYEbYSRMCofiRvv
+63g6+dC0aN/8yVmnXCbehPu2EOmD5kl4VwrIADy7D1vIpXqetfIXPToovJo1wc/m
+ZNXDXDnEImP2vQMuIb8pF/G66yfIiFTkvlORp3uA+G3wujnqq7eouseBx3vC7gap
+fsSLqnMTCtZgh+qrogbeQzTNSVBQ4K6i1Ipbq+ti/ebRSMBf4WXeByD5Sk2+K1vo
+5njW/8yXgg4zxpHdZo+s2RtpIzYQjjQFRFstR6RbBdcl7H348arvQiucyeYmK80A
+EQEAAYkCNgQYAQoAIBYhBMXlwJAw570y35pnzjWryWdgBK2uBQJhi/wcAhsMAAoJ
+EDWryWdgBK2uNdAQAI1FtRJ4mI6EOLjk9L9b/P3l5X0VY68c6eMMRc53goRr6cMj
+1DlEGMSrFZ/uxadpVhdr7XZSUJy2CP8XwL7MOzkzGdshki1CgqECkkm4PPjBYUlJ
+/aNPcQuaz7C6DF4X190Q81dCWG3nFzN1jJ8th+IRzTT6y1xJzMoslqeXqNf5sHyT
+3tPkgLNcoFvUBmLglGlWOiuiWSkI+FFi+azGzgplPPWQiFEf47N5iEyhOLJYFkF+
+fR0u056EdTLV2pMqKU+9OEbB0gO8c2+hNXj3O/g+d2GsszrxHzLWwiX2haLfAcD8
+Eu8HBTp6nIa+q7kEAhhEoT3KPGTvIKFEtKzQmW9qa9XtEXjLHnmrMURGw1epVsE4
+/c1u5BughEZi3yw+yupnkRa7uR/IJw6Iw27OHYg9fyqMkGvfT0se9JTgud9GYggA
+iaibIEq6K1sKjTE6Mk6KyGuQR6OrI7DB9HueFG6GP4UpZHXMdgqvlYXtn7iKTz8s
+H/r/Ge2qzbQOFfJgZ/pI/7LL65XlgAbsSo79neztm6ExN5u9QBkpjsKYk2Gj8eny
+vDrH4rzP6lkvLqCpCnOI+NHvmTpHI6XCi7XmQzBnBI7YDlNAuyx0axhkMCZs0bFx
+lFYYlF0zWyTPNpVGZj3hMWq1mpsBOY4SWtN2T5gLoCGEPrgrZn1Gc4xFHnve
+=jNCy
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa4096 2021-11-10 [SC]
+ 43C2306EBED3D533F2CFBA8A2C75E5A496C80880
+uid [ultimate] Wuwei Lin <wu...@apache.org>
+sig 3 2C75E5A496C80880 2021-11-10 Wuwei Lin <wu...@apache.org>
+sub rsa4096 2021-11-10 [E]
+sig 2C75E5A496C80880 2021-11-10 Wuwei Lin <wu...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGGMC8kBEAC0Gto+SCmuyo1CxQQkUwjkSgaU8eIkTNTHi3sCCZLC8nz1W7XY
+Ksf/QgZQxdA1mrI41M5OWgg5fh0iySP6aU/C/WPCm6ebe4/VAo2BTJy4a2TgM3pg
+LEd63mWj8XUAXLiQY2yju3PhkY3DCfVwghc81qqm21Ny2uGYe3w56N3OSOGUnrp2
+1zcALDvYhE00fszbPlDtpZ+YRB1Xf/NBEd7TW3fLzrDP5MqdhUt0TtdpfW+at6Op
+6xW3uXWWbfkXYFMaM6xdatzqovMwPMMyUi1mnPRLL1i3toezm7GSAdgWHxlZBNEU
+lyyg122NuDhx5Rbri4qHTUdiM5ZwxhuehJGRV1QmpRG2n6XVjgtEICL0NjoFTcVv
+g/9EqSLKKmXo2qF/ubMepngX9nDcSlLLH5zQe2hvup3FSGep+SLJ8+sMjf01H/Vo
+KiTPAN/C4LRsWiJTfHrUANminORo6+FMrqougk3QVd1X7X0MQFtxV5JPj5A0YdE2
+YkJAVMCOi/YGtBpktodZBpChMojjjlb0QyWo0YCLUcBIoA/Y6vCm1Z5CRYzUdvWt
+SS94viKXpNJQaSospoxk1uWeEXM6Sj4/J52HGv86gP8EZwcbSjE6yRydokgB9qyW
+nuIWEKFiDl74heAL1wtpk+aS3UVjb2dInnpALmNzNMl1UYwJszViTraz0QARAQAB
+tBxXdXdlaSBMaW4gPHd1d2VpQGFwYWNoZS5vcmc+iQJSBBMBCAA8FiEEQ8Iwbr7T
+1TPyz7qKLHXlpJbICIAFAmGMC8kCGwMFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4H
+AheAAAoJECx15aSWyAiAKlIP/RhCvkX4evnIlgDTNVt7W/XMFUua638mAj3p752M
+FnH7FU/OTySE5wc/P4LJI7kNBLC9doF6RSpjrE87lSBRhYyPU7LVlTX5j5xbt3HD
+nVZWe1XAj3wORR9mYDJaUABCY21qLBY2WGDeI3qGAQ5vjw/13HoYZAKcsQ9T8FN6
+FM+T6endSJUkqKSNLw+PiUAqosqI3ZgbShleD9jdwHzNqldwGWV47wJCS1UoOfnu
+2I63EluPhOO+F44KXs0mAoEQqeqpuA4oXeyGhkbePR4xGIqqCDev1Gpr3KXDE0SH
+4blXbKIEqWUYU3lU3/uUs8noaARkaNYkvfyNxKXXnyVqKFAPEZkGU+Nwp4VrtVp1
+wlqmnebzxVDWpxrkQrtr2sNDSYbJPC5fQqx4DyWctPNGWDRKmac25dW5JSbkFkVY
+nBqFu464LNMtNS3RUL6cegFcV6Put+wYdqzV27BOaU0nnPGOrf2zDsVZdg6msfNB
+eN/gABzRgW1iCuCItkwv2uDlabW/S6EV3Rkz9EVXNNoiPC6OwjVZAPvbB5tzmA9y
+gCAsUWYjWH0VR5HuNmUIu76pDuGQVz7dk3xq6P+KF7LhX07oq5wAcBjxD66tKFIj
+dIMfnJqu3Uy4UkF7cExg+IlZYsYyC2nBb0o8qDI+eVCEN5iLR+fr3OFKswhqFdMt
+VWGcuQINBGGMC8kBEAChBfP599l60dioP51mR4s10mifMY/Ot+E8z8oAvvq0bQky
+6Y+BcOWghHQ9dKsJ+UIQJhQHGKMVqgoVIy4rC+nVXcN5tLec4b8pKESJuLdcQ7P9
+1j03v31XvbpNmAUuUKl0xEkrHsRUlL9yfC6M8/PnZm9FImJmQWCageyl+T/zlDzy
+LnZwQ7ko7mCF3haRBqCTuYpT6ICuZ0Pg/itVuje8WNkFH+kPH4Z6JlTboNoVf/UP
+xcQYrnCwRtoQPdJb0jz2pTjKqtBirrKewVPE4meoZnUK6Q+h+yx36jTM9IqvP59F
+/sW3kkQuHVKZj22qSyILBHxFJ1qjndjkIe5IX6w4bqXIEZWgXBJJggYqeBqytWhb
+mx836Hf6oR6wlytG8M0NgkMMziPzK6hpns9swIdcPngHLn6XyNT7WxLZwMmh2xEd
+P53qzyo8HAl3uIUQzz9QabOvUyEiw4PNaxyuqpPvyhXcmlRjfSs6NRceYyhXdUTA
+lcKKMsZwNZ/i/rYYME5eVtEpRKmc6ZnbDRk+2la2RdJikRVzP4LAUut+yi5n/cal
+qKW4685BC/aDmCWmQLAGZtSxWNBeTMnp5NpvVG/5LLSBHuraJePiOORXpFCdIira
+BWsrHj1AfP831Byj53MMHS8C5Xr5J5JiQWKhxd5ASWPu4DjT3kAkRVZrvvpPfQAR
+AQABiQI2BBgBCAAgFiEEQ8Iwbr7T1TPyz7qKLHXlpJbICIAFAmGMC8kCGwwACgkQ
+LHXlpJbICIB7EhAAg2uspz5Vsw6QK76ipdkSAgUHeZU0MU3/af6qqrkseB1hAnck
+E6fb1hUeRy4o5550eREgMi0uJDTqAoXvZ01oIKrfdZOsr1xLPHRrziBDvmSZVQmt
+tIoMuEDhD8Pf7PNVemAIKQLqoleHeXKSlc1FP6DKcAIJK7jvIkb1alO9r9gXTQrM
+8rHY4KSRh545HtZva6gBZjk+RfpQu6Sg/dMlwlDxTpoH0QjNalwzHD09sK9DrpOf
+OhdTb3dYMBAMPyPWudUW0JbHhlJMqykCWdMSN5FxQIDcz4N4sH3idclOqBWzQq8Z
+igf4cdBGaegHPGxOEMRdAKDOkVxP2ZwxJBLUFBThD/CfGRGhnwNTYoNpaPPekRPW
+7Yg2JCnqI2pVGQBETX57J3wcQDb/TXQ7VP+ZttHMkGkU7IGoBdlzu9hhPapUs032
+Fy5AYoRozj9SuLKGbqy7VkvtEVZ7TeKaZO34fEJ3uRkDTHx0TQtqwvs1b3U1fWJj
+o7469h/jBIPHJojx088Om0pMv91xJ7nQ3xukgVw9C0DZfmBX3xd2bNbyfugT8rqQ
+A1PPxm4/KsXX/IZZOuM/tlT0vAahQsvXMNUVMg7v/PWuB6V47UdenKpXd10oloF7
+MMtVW5sxG8OoBpUIhJUCtYTlwGCyGWSR7+rsHSR2HydLk1RWcYNI3XgJ0ng=
+=+gLd
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa3072 2022-07-12 [SC] [expires: 2024-07-11]
+ B3C6A14C13B8C6727BC2FD2F07FA463F1C926F48
+uid [ultimate] David Riazati <dr...@apache.org>
+sig 3 07FA463F1C926F48 2022-07-12 David Riazati <dr...@apache.org>
+sub rsa3072 2022-07-12 [E] [expires: 2024-07-11]
+sig 07FA463F1C926F48 2022-07-12 David Riazati <dr...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQGNBGLNzqUBDAC9p7OMYiiVHTQIIUr1/fDXaJ3sJ0rlkaPQJpPBrtuqGjN5utDu
+26BWQqPxx36aABw44UmTRwV4UNf+3McYSJoCODfVpHOKsKk0Ql5CDzG3Ngpdu9ZR
+UxV6s2DNHkSUjpd5vRfZF09WnQ0WITEhKz8Wnm82B/NkvRmTzYqlpP+zOT3+WPFh
+5maMPOP0bvEfiT22zQqOOyKraYPrtf5ZBSip1fYohOlyS/aJcqOChMuKMOBVrxqH
+9EmHjEkN0a+nAdWnGmCoGZONsD4ifXL17AUOaGSpEko6Nj7nXyTKI0laBhj6f8uw
+v8M3xDBkIm7oiTuwrCeDa4e9YtP6Vzvj6MxrpNIMN0XRs/DRYH0lgTI1Zv/0SzkO
+OAa9tOCiq95jkMjZik/vyQ55WwkMgYDmngsP/PBEW2ztdVLoLeal2p4HNfBM1BQO
+RFOGnurR2Vmy1jGPyfpuBNMyjRgFC43s7SLiTYKCi1QxyY5u6dRgjIxkG+jyiY3B
+GFMAtPt5iJHUox0AEQEAAbQjRGF2aWQgUmlhemF0aSA8ZHJpYXphdGlAYXBhY2hl
+Lm9yZz6JAdQEEwEKAD4WIQSzxqFME7jGcnvC/S8H+kY/HJJvSAUCYs3OpQIbAwUJ
+A8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRAH+kY/HJJvSJHEC/wMgDH/
+jBI6AciNp9sPv2p8tFRDywq2nUOameYFaIMq1r644IAzUUU3PSACMT1lCxGjFFsE
+vJYx1GORrpqjwArrK1D3zZ0yb4X38DFAU+7DTGEKzKoz3h+Ka0GyOe90CI/KqqWL
+XNeePwvOzIWhZ0U8vqUkgXwHyfG1dwocEx5A1zlTeznkth2AnRELnjhFcj28V2VX
+dUQmZ8qOYxXtjSk9xJtQ/BbARiNINeKqzG1aPWgjTtFFp3UTl/jWCr5RBlWMA+BU
+N9alE/ozRPx89Uilz2reaC7xX8tHv5F+P7SPVwMhJyYQ7F577CtM0b4vTu4U15wE
+VlWF25ymTbSt5kam9jFbeR0Zkc0/LuLEdGWRGbDFI9Hj1rGeBejTm+PjwK3TidDn
+KbvpUgvseNfqUQPcbjEsuwYVUtR/LEeQxt2tK/odQwWlHR7BQApFhV7VSJVP99Fp
+YNFN7AsiD7+k4fOl5Qeq/t6X7x+gXMkxsRvtJMwB/fTAWbuBxdQBdIkP/KC5AY0E
+Ys3OpQEMALhC8woP92ONpgRKHhH3s65cY4EYLhfhkbOqU8KcbPJX0qx1gM68jWqm
+aCvez9KO+aB2jEyWG65XsOJXM6RqFtgvFMKG+ETLIgPydqt9l4f5AhnrPXmrxf7l
+b8unuFMyoga7DyKnB6hQzEVqZgbKR+U6lWaoFtGTFYlaOdUz268OErrW3592frh0
+VKTdCyBdGPfiwKnzL4+LjU7SuiI9r1nBH5ZYicGmgOKQHP0KQRUy66Cq0S7p0rpp
+9owbh2FHkXJ0bryl7AMV5JurEk0FSA483qQjyqHEQCSKVySgUBBFw9UPH0LkUbYv
+jk43VFoUYexlJ47KFIRJdQZdLyyqsSy0xzqiCQXFwQPECIFHN/GTMuAHcaCfah/z
+u4KDkqArzNzG1pl/DYVuaMo9LmBtzB7kfxPKcvm0atp6WHydcQ92N9ZU9z2zBh7T
+u6Akzl+eONsix7F0oldwtG7Glic+1HafyyjhZfV8o6r7rYURnsotDfdzYjpL/xWe
+xWkUSv2GbwARAQABiQG8BBgBCgAmFiEEs8ahTBO4xnJ7wv0vB/pGPxySb0gFAmLN
+zqUCGwwFCQPCZwAACgkQB/pGPxySb0g+0wv+MQO/9mVo4eblTeFMLpLlU1tbDXIF
+n5bDxbd1ekq/fKLrWZpT+MQGprGMXbgTehgeBIMvFvANLr2KHUb4HpXTX1GceVHv
+A5uN/JQ+/H+IF3SoipcFPDR67uESVSZQfrky6HG8M9hH4OPdW4LbyEBke13Z2LlK
+sQWJFznDnqCqmvLDvvliGBGhMM3RvTn5upgA47gwcJ1Z4xZU+k1nyhAiAgxGxpjO
+rtj/Dv7r7gdnDBo5omu0fQLqulSY1UeHsOQXlkR6zMOMDdKgybcScQHQhta0Hcs+
+DWxpfJ92vH/3wGchSA1f0Fp2WCiQ/wp7sfe1esShDN12AwlpDBjK583d0R+DLpVY
+8DbRCdvtwIN2f5KD+LhBbBX66AADVKVRIPgGDRGxc85X06nVWOQGHrGD+tCjxBNM
+aLLvg9K8HxeWTvQvowCAyFJo4NfIrS/7gMm5JcWMAqVFJ+IVxZNxZUIYV0VBC/AN
+rSSBN90DWxIgPhlAqgO0ofkbPSVwF/9i7nd3
+=XBuV
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa4096 2022-10-10 [SC]
+ 1B63BD2FFF5E515DA1BEF393C9A56ABD5CCA3EB8
+uid [ultimate] Andrew Zhao Luo <an...@apache.org>
+sig 3 C9A56ABD5CCA3EB8 2022-10-10 Andrew Zhao Luo <an...@apache.org>
+sub rsa4096 2022-10-10 [E]
+sig C9A56ABD5CCA3EB8 2022-10-10 Andrew Zhao Luo <an...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGNEkfMBEAC4sFi6Msfxtv4pahjdp+nmfwprEemP0inI4yiuT9m5eEzc4/0/
+EwPHw4Kwx4SQypxSJXqMnxSI97w/54LW0Gob9hzRwcCLCe4zPR9YnJQ0JQo5yrjE
+zo9JvgyIGtGhM6rUTSMcCIO3eYb4Ogwe99DoWMz4w2NA9wB3nzkA2zL4VpaM3Ou/
+F54xlMLE7ht0EralHcHZUuSmvpzm43lScE6LwypFecNvfoBdiJJ5rGxbFMKJRGeF
+GGCZPuLy3EBrPbHe8cjWfgBKNj3XTl8B8YO5oEIZZPCpo3ML8DuD1Mf93PCk8Hd/
+yr9U7VMOXrEEZpTjGOEl3oL+5VVUFFBDs2tuxeBMExC90sEkoXDtJCRkSlHHBWZy
+tzTqwN9GcLe1N5YKwEphhnmN7tp5rLEJXdUasJ4RlWQHZqVJddDELLb595FYgZMe
+2dBXKbXrn8NvJBJf5yeLkSJh9gdkdtXwX/YN4D70LYKLz9+XZqhg3iPLAdrY+xVN
+lHtCZDKLSHpNHWPcqnBIcOre6ucBJu52S3ZoVtH/CCQrBkuVpXWSjnL1wCw1Djyx
+cNSVSVR9/yZQTgcWQh1zmErQEC9mmUrhTJ19IJ4bpseWgyhIETzuSYZ0Xm7c3eT9
+FrogP/D/uCWwfb5DJUIIFBh3fkEMCSEpc4TPIjulpJL3i3FaLLN4hYURKwARAQAB
+tCpBbmRyZXcgWmhhbyBMdW8gPGFuZHJld3poYW9sdW9AYXBhY2hlLm9yZz6JAk4E
+EwEKADgWIQQbY70v/15RXaG+85PJpWq9XMo+uAUCY0SR8wIbAwULCQgHAgYVCgkI
+CwIEFgIDAQIeAQIXgAAKCRDJpWq9XMo+uFYoD/4oALh+pdsnFwbyx1ycf3lLExwE
+vMrmr+hMrodQqoqQ7bt+anYzA78v0HD3U7zsLSqhIhYE34Ib3fB5Rv7z6DcNP6pl
+RUH7QU4DOyePRPRx/xYz5R3OkqVKrV7RUdzgXOn+5mujTJiRYzRbNyexg88dJVWK
+eQCiNyW9j8M/+5a/+gWjehxyvSmoSv1fEFUDV7hjIinSApWyMm0Q8tzoqxPmuaTE
+ll15VkgWx2t3bjQtfPCeft1eZ7Tb84k/PRN7JRFVEZYul4MtRSrJTDO1E5ewZ2qH
+PV/2JQPQMFKpaDEMseoGk6/O9I76sLjTIjQ7mfFOnEBiMph2BCF/cpMufxLnE2WC
+GyTCGVB+BPgvQ9kvD6rFTAHyiWetHA5Z0v/TYUYAPYIATk4N0Hop/2fx4NK4vWeX
+ehjvgPzp65vRPAHiIh7JJM4yt95yMdSpo7sUuduefyMf5FgzBpjaXTb2nI5NsUOr
+Ohh6MjaZWt1tZoNj7X81IILJJk4HDkDLpTsi8dDLPRzuHw7iNb9U0bn6cSqFW8JZ
+M+U1t6jpdJ9hEDlBiJPZbH3Ndky+ZyDoQQ6zp2mGbgkrT6soFzIi2zQ55qEpnMNM
+QpxR17BTJAJO6JEPIHhdovU/VDg8ho7blbhNFY/L8o72Q4RAnLW36rRBx+dsExHn
+Gn6OvtU24FhEfPlWyrkCDQRjRJHzARAAvdG8QPkyHtnV4SyAgaMp6lIm31OglXQO
+LFue4Xnv/UsUzXY8am281dnF7IbccnmxFxxlJq32lIav+L77I5wQUd/DuY3zj37b
+RddyskOuK7m1skMXnBgJFUlfwE9H6ypr+HPy05VAnp5zsqelXhvIoJmioTFysmgi
+IFZTUfV9RPp6ohO18r4Vdgyn0a/p+hCoNuxdjlZUSZ4WgY3b+11d+wcudUu2zfwc
+LSuXpsp30+tox5vcn82fANux0fnxbpc8Ic00XlEQCeUphF9NxhBPGnPRQV12rBpT
+eo+bOUp2UN3dEPgnYGWLBt8uuxVOr5XE1AwwlIokSdoS8zGVR8JPk+32PEW07Q4R
+8t0J/MFacFlvHHpWkBBStXU2pzzLs+AX5qO7s6XekqpXdb261vSEd86jH6ndqIo0
+KSSPlUmBi4FAKHKZIUhdSM0waR9CJQfYUWGqXLJpaKqKTojqIuXQWh4S343H9IRg
+n5nbihuiko8UrrzofNBb0TXfPOnYYjCB3cFTVQzIFl05aNGs5HQGLX0wbqD7+kfP
+m79b6p5SWLoNLmGNLj0dDcBelw+nAPhbOIn1rohwdPPJt5gU05BPv++X6CzmqFEA
+pVx01HXnbX62P2HT2V5YavLPw/R0FrXOB4ZWKH/tg+BPMBqS+E5eifadvVvKH/8w
+rc0Q1UwYxB8AEQEAAYkCNgQYAQoAIBYhBBtjvS//XlFdob7zk8mlar1cyj64BQJj
+RJHzAhsMAAoJEMmlar1cyj64hjMP/juNX8sFXlNCyR/HHKHwpfzn+nj6vVz3RgJi
+OFhf7HYAKh37yMizF3pN7ueyV55BBiiISQNbxf5eLh6yCJ2NGkun+mTKPow5CAyB
+yFS/z6zmlGduL+L8flI0Pao0UJgryhDUYkNrR5/PkZ4ksPKyI3sLlaoOPvIQAlk2
+aw1BI8RzTo05Y9OHralpFV0Nvufjvc9R0Q0934216M7NNK8nUSxXWeztM0yBHEIi
+V+/XY821F+yO2aBhHqnpQeJ1+6bc3UB7sbt8xA91rJ40Kw7TS4FGbTzQyXKRBMKY
+LoZVF61lRUoAFY4Fh+dRKAEel8ZnBhyHEyh5NCUWkHJNWxpPnl/XIVJZ3BbFbtfT
+W/CeWBEAkrJnCl5CfpXUyZRWYk2uwR1tA7apV+zJpaPwojnY5s+2IhMPrTdkxsNR
+zA4jpYkRVEwqy4LuLLbiVnTPba6y8DBiQ4by1m1CKJJJ09BMUKff5v1xSerONLBM
+uEKTrz3MJLLh1sZWkTO04K2VarbWoCygydcrxc9PNOuISq2mn+g2kzVhnUG45YnQ
+RRveMKZ6+uqGzsSYwp+lHNNso0ey94qgwy4qubT++rLZZ5eVqBSUWCsGoEayDBOQ
+v9YZLKL6qfuWuYN7rDdY1c82kPPmjaSkpXiPP7q6v8vUOGhnMFOAUNfxwpXP5Hs9
+/lFRrVmO
+=rAtV
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub rsa4096 2023-02-02 [SC]
+ 466390C69A21ABAE77DC63F128D4862222B8EC31
+uid [ultimate] Leandro Nunes <le...@apache.org>
+sig 3 28D4862222B8EC31 2023-02-02 Leandro Nunes <le...@apache.org>
+sub rsa4096 2023-02-02 [E]
+sig 28D4862222B8EC31 2023-02-02 Leandro Nunes <le...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGPbm2QBEADvJpyP/sRJeI5GtkZ49uUeICGce22kzl2GtcB5eOTOJB2M3rJq
+AwhdhLr1P4uIKJh3EySW5lozmY//rSwlh7lpdTmu0+o0+03UBTseKUFVGMGMdy22
+7jzOkHjViYFXl9db/BgnAz/d9AmYgTzlhTwW5kv2gl89ifrNyywome9N5CmhjzHB
+5HDo47i88GQ7auLNP2DmGyAnl3Fg+B8BIVCQJchQbWRMktZUj2HfNhLT6sGMKDHb
+HoPM0rzHAR9ZzOUxaCSadbJXP2v61BJ2pdVW17PB8UcXnFwCy5aax6Rn+WfNl3aD
+Oj2junnBfXvqxc5GYDrporcB5+zIFYb+Ec5Mz2daWRDiEsYcmM1V9g6yb1XsxYyT
+cKWhMbOlBBMJyvd38GbJuI+yraURQWLN2WyajWogD8icnaEeq2iamiIDqZ8yiLec
+3TbHsl43i6UJOCJhww6SCuvaaLz3XKNVmt8m+PLmFAqjt5O5zy4cE4JGGt0U2ckQ
+vlZdP6fIfPDCh2FALlohKL6s8B8mUB1QdFJGgzK4S/0+TwA2Pm+2lE6PNQ6SBNzO
+Whfvb43Sll0Eb9xO1ehjE50Vv0lMn+0q8PrDL1FpRFtpqYMRUjLEDWAv6fBUBlJ2
+PrQaTLA90om8gG2sb7p1ocRc3UJdosDLVw9t/X0go70Cw+UVha7LuTgawQARAQAB
+tCNMZWFuZHJvIE51bmVzIDxsZWFuZHJvbkBhcGFjaGUub3JnPokCUQQTAQgAOxYh
+BEZjkMaaIauud9xj8SjUhiIiuOwxBQJj25tkAhsDBQsJCAcCAiICBhUKCQgLAgQW
+AgMBAh4HAheAAAoJECjUhiIiuOwxt00QAMGaQDaC//6Vm8P8WeEBBTKGGeQhVaDI
+E6JSSpKg7f+x263S6BAGAuJ7/kR+0vg4MjxcQ928PDaE+6mciqFctKCag1DNDSAv
+DHrbZo8u3fAjZsLG+BZU00nCITlITTFS2stHo8DRpYTvpP30OkW7X72mkJONu+CE
+902nivcsfA6tZUXENEiJFddjxy02o0hKDRCpcn+85yEIFCs8HAGHdhWeacpbhnc/
+/CYrJBeCEzANJmK8pdDkcc0bOfSd6PjcbSErhQtXydYHdcrGMCsD+pfoO9wyh3VG
+h9yb9OXGS0iuK9ZIqLe1S2Qdcd1DcNhQRpFIly1ryUxXtY2db5RhpZ2dPuKTD6v7
+TnBVGwCzhmLJGG61WDRwyAGRZ6ja17gy5SGWzBaZRvVlp3d+AA8mtkxJQenrB0eE
+Ch1YghlHU9KGPRl6krdHImIST4/FJKHHdA96jY/nMOtlN07kXaZqPLByQXQ6P8lB
+UPtJzTT9/yOvt8y82HDy+HFnwrR9W3111tIMTDsz6iYqA3kigk+kCMSSipIyE2g8
+KcpfnE0cHZeWgZBRN3WC/+T7fDEGQdxp9Bx+Hx1bW333ecMao6XcN32JWGn8Xg3h
+IRjFWF8g2kowKSKlKRPD/DRCNu3tG3N4JFAUIQvHZWd+2MAayi7vVMZlQql8t4Ns
+BTxcyrhiKnm2uQINBGPbm2QBEADRhLbjhAtn80vDB0WD/OITbXSV5zLYqtQNgoLb
+RD6bLMX7QVH3U/UOdlEo8RV5jlG9qRW9qF7tTPiWIr0Fyvb83qskGPRxO0xPrll3
+wqo2xqRQdSbyFPt0vNSLj9qQdXSNUenTQXoBkQgLnr/zENKN//NTavvSLmmZL9YD
++O2Oe/hcxMNrRtvMYo77l3mfIGWSBQRiP9IPjdOQZjP645CozD8dsocUDtrgmvuR
+plG3PpFJidF+72aW0J2/hbNms2uDL6fEf6Nno9Bd3dqLLXSIp2I4iSodqp0IRWs8
+gPOritMLHWVy0tFsE+xOJpjLVDAMZTqkwkPHeB1By6x30ra4m6uaost4WyGt1mRZ
+zxYk3JJ+YKt232pQJLv9z3cuH37g0XuYWLCmUj6Hl6GyLvTW8NltsBq9xRWXc1il
+t4P8DgZoBPGpVWxqN0gUaWxiFzjfJl0CeYfd1qSojUVSlh/BDvMPPjo8RX0wBBjV
+hL9r/naBfMdOs/9ZiqBnGUUe2xICLUr0yrxLsEXvXMNEflTI5jNuYCrllqay2ZOS
+lUrL9B4eTLO44k0lFt/Omh+fGgxlFYkmQT5C/JGjxes4llUXuK/z2uVSX/8RwF7f
+YyHFrMUZnI6sKn6L/ula/Tlw2vHu4RkeLtB76ytxID39bn7AZAzU/I+SLMHkT6L+
+Jzs0cQARAQABiQI2BBgBCAAgFiEERmOQxpohq6533GPxKNSGIiK47DEFAmPbm2QC
+GwwACgkQKNSGIiK47DE27RAA39cv2uS59dscLAlsuQ1uYhXRWyFY6sQ9Q+EeqsbE
+kQRUDsRFbJC88b8wdCjYPlVK/X4qr8NMtCS5GVUXQQvHgabf/xlzwZsBIHX05KaP
+J0Pwpvns2Z0cYpZUO6oBLt3MclIx9uUDU34fBE3x4QkTjx919K/aV/h4UfyfLlas
+FwWd9jpCkh4SLH7BwAB598Bm0zbKIjLccqT4pg6pOXB72YWvO7jee6DBlPSvwqLC
+PVSg4dDemSghdAAI2QDLCEf2m6JLdNKIElG52vKK5zEb/DW5TZnHdfGC/+hrxa+Y
+ZzKDOvZVgCqh+b8PGQgFkAiY55qmsiGSTt5xmkOdnMMK+Vnr69RDwrkP0wpXKeV0
+QU/LWos45t1YsvMa0ZpO202CoYcyJ4uPkpMeTM3NCu4mpZtLEf73If/aKM3E2DB7
+76XtOm9p22qRXZmXj45sBQ4/hFNSxWrOxIMIDACSfbMt0sp0wlZku0yXx54UIrRP
+g4dZ8lcqaRNBG3mb6OxcX7wXb3krbjETds1yzNhDimS4fND2JMThmqRNhvdbKaPy
+eEwpq1kq8iSi4BFiOc1j6rKwIkJVlTJu/BBxs3aSo2qV+/KD7A+sTZm/oXulLFAG
+FnADTX552Ddc8qX/P4jyhEA6h94c1RWUuMi8dVTDnClEOfjaSZ6cikte6UjON2V5
+tO0=
+=PI53
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa4096 2023-05-05 [SC]
+ 664EF29634C05669C3DCF83106D051CA84EF3749
+uid [ultimate] Siyuan Feng (CODE SIGNING KEY) <sy...@apache.org>
+sig 3 06D051CA84EF3749 2023-05-05 Siyuan Feng (CODE SIGNING KEY) <sy...@apache.org>
+sub rsa4096 2023-05-05 [E]
+sig 06D051CA84EF3749 2023-05-05 Siyuan Feng (CODE SIGNING KEY) <sy...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGRUb34BEACyedBJjD2tYY86mIr1OR42eR+w0dvh/cECgp4UIm5QG6z9YXrU
+KjHtv426uKCloYiWU5+b8ASPMbtP5q1rvrRKQuapbDBN2qlS7E/PScFHDK50ydOA
+v8melfp8pWLW48kE5EeSdvhF8U2QzEqT6EYmNIExLYjSV1+Jck40DbVL+ak/4clB
+Qv/l0DW2Fw1u6GAKaNgnWgZDhc3os176rS0ERzflZeF+rqskYSb8Uy37vBB9By64
+edIsaxxOEqvpJfa2Ar/6vDnBplYSfMHq9kqs0vuAVu0r7Dadl199oVMmUwBPD4uq
+IVaWoetCbR+DpVIZZ74i4kOH47xfh3kZ5zvWo5E+PL4XH/6us5tp+nAnCjhthxY2
+tpBBZo7M4qgwNOxk/3zsysZPYPhQaZUx7/LBaApOhyWrmQYrtZpvNjHsoEToHtDj
+wCSwDxf2c6mrncnmKg6UfsWSEiIiPcsYqXkp2Bh4xKzdI54qCt8LTPGKjTPj4FO/
+EccT5Ad8+lOKSOIugbNmECEbpVUhrlDa/yYtkosHbnQZFgBBaa+RCsRdbGpuuc+E
+hqEpvwbPq0J8zPJpKmyeu/S5gWww29ix39J+F5ZxjQZBSUUPRsnCwHDdkgFBlDdK
+ZeQqlKjr7Mfp+LlI+7HIIxO9HOPN3WIjFyWPm10d6cWHN7MDxMySP8l1+wARAQAB
+tDJTaXl1YW4gRmVuZyAoQ09ERSBTSUdOSU5HIEtFWSkgPHN5ZmVuZ0BhcGFjaGUu
+b3JnPokCTgQTAQoAOBYhBGZO8pY0wFZpw9z4MQbQUcqE7zdJBQJkVG9+AhsDBQsJ
+CAcDBRUKCQgLBRYCAwEAAh4FAheAAAoJEAbQUcqE7zdJsZQP/0EX1XKFDF37c8cI
+jQEeQ44Z3F5C6cxM7X9efqLQzDgvVRR525qjpM9uk/usUdKupwwX0GkJQu+JbRus
+jFCi9RaOO88+w7ihS4qOFcXV0CXHxxSKkKfKU7DZhEprJtyQ1QE38gWlHKB/E6Y+
+oJy9EKMZMXP28gj/tUT56IABI6X+b1BSTT5PV8QURkkTPDVQDpWo/AmtPdei2bvd
+KnTZGAjxv98rMYvjJUGMPx8oA3cqDRlIltgSyXlwht8Ig/wbUzW/oRmzLk3TdeoE
+42/QHTLjfDlSm72V2B67QToYo/URIxJimUvg4/+VT8ByLxPzkL3jYkDh6K87JaB3
+9XO8HjNCH/xfZtMSQjmApInpk7VjDVhDC4Dlf5t41pUK5KvGsU7eLAE0jL/R/aA8
+z5pvf3afLK3Bpj2zKvy2rFkRmCKIS7mycogBUdOk4GT8ZoLDuaTmUcbfx9H4/9Zw
+UYWCw6cJzD3qICqCcszlfW+99b92JddCU5ITMfwuWuY/OX/LfpwibAjzor2TFWya
+CVI7kkQj9C0vcbpxgCMd4HRMV9p2CQUkvPEKfaPg+kzJC1Yz87DC6aSrLIzVvcIj
+LZ2yOzR4QIeTS6hRsMmQRGPZO0KFres4760BiUCH0gid6LWDNq2YTXqdNu1ffQXe
+PV8Risr23rrxOTJqlYX3GF+Xd7C1uQINBGRUb34BEAC2q4MdKGYgsl9BpvOA7TnN
+kBtc8Gmg+DOdjBhG5BCo6h6U15RxfIvSikRi0Sz3F3YZymGKIeJp8ug6brY4KWjA
+7dtwqlvnthyWa0mPrgHZvkIM86URO5wSvRMXx1x/qWJ8BrOoCDji+fmC3uI9IbY5
+RvkzHACYz4duZM54ZlhM6lOL3TtgF2OyXod2MFwuC5WAAPuqAG5MF+gNdf5JA+p2
+RfDIGeZNOWQVWi9CrHWt8fC80WG/7r6Ta84yV6KTfqhsXToFZICVXt2BEg7K/UzI
+Ip7Zf5rKsDT0iDxtiJIbwFBbTS0hE3ICrPWVHPNRVsqp3wHDkjjnt0aPL+G938i/
+dzOwHZIf9nPjIrX94DvPpOXGrHsW6JyMHZ/3diROpWy7DzplW2i/wVftzkhT4GSN
+xARgLJM/iZriOMYvHafpOm5OxkfFzeJpnjZrRTJKNCAQFbdxI9pzR/2ingvZekUs
+FYcauQVuL1MbamEhf7pRXHOS0bOPAONpeXl7aNAH4jf8x/3iRHRQYcpGRT1ESddO
+/swv+Cj2qj80vzF/oT/QMWrWDGHIiriRDSf1WpFHVqzki1jY6znrw6EvGsowbzha
+kGC9dRzLm8P1aCwjjsU1J82yEKA4oHwAX6rlkRkWVUkTMk3G1coandbgcbnI6ngG
+7V932RapIOZB06rh/6mGgQARAQABiQI2BBgBCgAgFiEEZk7yljTAVmnD3PgxBtBR
+yoTvN0kFAmRUb34CGwwACgkQBtBRyoTvN0kLfg/+JOmX8SZLksdEo4H5KmeHVOQk
+EpWlFk/SmSoxV1k+kz68B5gxBPWQwRj61cGoBFKdvP2s3BSnKy7+iow0uwh6KIy0
+zMooEOqCr/kEeFLxq79kFzxwwDSkzUO1UwGWCzVGj4V3UCq72xt2r3mJxRLNijTr
+JJFe6+pLFXRbgrZ5ulWGxkiZRK007fPqtkretLiTyUXcJzU6HBUi0/pnyA2B0mWL
+E0HO0TdOPIDTH/t2vtLZNhWl2T0lbjtdL7IcPAKQoNd07GyK1pPGpLQqP5gRrpFR
+zrbslqRvKtpVjL5iPQCtv8Tc9ovOIQVRXzuXm9W1OtgFVYH2GQe+vbpYhLL7dOfF
+Cwo6YLQnc2DRLAffy6G5weLJYYE52gMzb8z++Ys0A+XBkuVvHX1EBeyWy+OSuFSl
+Aujm/jMMgK7dtNIHXgtVGEAKKJb4amc1wsZ9dmUyf1UyFxWlDUEaLq8+5Ut8a+tW
+pTwwQLAXPVElpi32gLDP2rvHzIw1Hs0MpoxwOOjH/QCeRQ/V3acAUVv1JX96On0t
+NqlR/Q5S24ktyC1uy9oLdIZmgllKUb8i6s6+XSkWRata3HTsfySDXMdntZV1Zrjx
+WTgrESErlqNLN5ZTTW/1jBELJCfJKxgHUip+Yo6qNZoWwNLP1BaIcoA3miSG3DXf
+wS/UuN04NxDy7V6mPXE=
+=MTba
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa4096 2024-01-15 [SC]
+ A4D9228E55761E665BF01CBB5CE869CB7DEC048C
+uid [ultimate] Star Yuan (CODE SIGNING KEY) <ys...@apache.org>
+sig 3 5CE869CB7DEC048C 2024-01-15 Star Yuan (CODE SIGNING KEY) <ys...@apache.org>
+sub rsa4096 2024-01-15 [E]
+sig 5CE869CB7DEC048C 2024-01-15 Star Yuan (CODE SIGNING KEY) <ys...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGWlStcBEADaslyfbUNARhWftJoRAChoak0cFU6NxahhvyZfyTGtSuwuHNDD
+2eyvhnDIaYXVClxoNgikiQ5Nkd1jtbA4rFCw6Pdbq+98fkpcr8N4o+jlbpu6Ff3j
+dJ2Qu000MV5qe9FZ4QasdfglJElvizgfNbJv/Fz1ERl/BS1U0c7lyQF9jGGh7EY2
+1y+JFp5OMG6A9SpfaOd+iOw5/cfCQk8+sHQC4dp3hOJPK4NLvjotK+hlOhRsF7gU
+goYYT2IP56kPQb6U/Uiv4/R6HbKugzqSMl6BMwAb9uG6UX0xUfAA8ciHoaITCJCQ
+9e/jGWnDnqYlAMNqLkHEmW7THxJ3hHXcac/Z1C3PeLDJU0rpTxDcjuYkM5jFCu7H
+TgT7lWBP/PyAAVSsLqMQbLJOWm0a14tb/oRoeYr/B2prIbJY5qJBM1nherKGMg0G
+7Oqugo6A1VqgUxg7Chj73PledaNwvm5Lxpl6D+wPDSifhlz0vnwOCMoOon0pTjK4
+DXDEXnEXZtzkZgXI6g7AkVyt0gkqyUi+01ibmlBfcVHh3PVvU4oNdkaywQd5s29R
+DsA4WOqt9cLv+iqIzM1juygfR6ooA1jHDIyIPmmC/kOrcxKXEFvIGXDDCbXAvdXc
+uXgZeZqI3pbKjQaU3fF8HwJ956HTM8rywtVGH9BWRl/i6qn5sq9CcukcuQARAQAB
+tDBTdGFyIFl1YW4gKENPREUgU0lHTklORyBLRVkpIDx5c2gzMjlAYXBhY2hlLm9y
+Zz6JAk4EEwEKADgWIQSk2SKOVXYeZlvwHLtc6GnLfewEjAUCZaVK1wIbAwULCQgH
+AgYVCgkICwIEFgIDAQIeAQIXgAAKCRBc6GnLfewEjBAiD/0cfaYfQ0DL7CPsP0lS
+yezPDDTnDPIo//G1cuSYG0gnXQ1SpbJSzDE7deew+P506/sWFneOY5Kuv6DuSE8J
+nM6vv1EYR4/9x/XstA4F04lQPngKKBV+UKrWj8zIA2Drn345Ece1150bWvrUD7mT
++ps1gfe8SGYpOmR/kRc8qra2zizcWBC1Dl4qd+RcY7Ac6Cu3G/JG2KvZnrUSVev9
+nzSl2V0JtFVIla2odSJqv0Zdj5E2vLvQd3Dxbf3BODCdL3iQqxrQhj+0T3QLEhPg
+y2XOtqW7a96XosoQ44wUiHaS5LwFViG8LoiPADtSdXYb8m4FtMfB8t4mzXVqBjpz
+2csMqOnNvo7bctfpJkjM14UKib39MR2wUv9fD6Qa+OAAIeXGTQH+wlXmlYjji9+A
+4tgq/+d75qUC/tyHSgbZLNXobHF8v77g60cBvFXVL02W53xhVDZP4gwu5iSSN8BJ
+a2hqwo4UO53mRUNkwFZONYxJE7MhLl22r08eu0xNYhoGtpHzDVoyHg26+2FUgFDd
+TNsdqjMyJ+3GXEE3PdKVDTj9To+RoHLuCczk5uvtFYGhseRwIWbVhmTLKUL+wgSa
++b90slkv+CBJvLjvKbVCmCLXwiH8Cx+MZSu0oM5v8fbHuWOhkb7bJd1V+U7qV/OA
+CCqBICt64F+ooQ0oEdC0oLvr2LkCDQRlpUrXARAA1DKsF2ZNUdPIn4VcsjRk/+qF
+13VC9SaqMp+J+8m1XTIeXdr27uUa2vT4j8pAM4gwMVkpEqE0rmHK+S1SeEAlcizC
+Bvp7vvso/glcOg9Sgt9PXvvEDPL/Hnsn1+3YX+Gye4cOTiDDgVW1RKcgGj9Xsir+
+5BS9Secj5CGo92cuaqIo/mMjxGlsuW/LvTU5qQhz7aOaBibe5EHPlGMqM6XJN0BZ
+MHRfBiGDs2n/egMnTPL0JcTlAeird+yxDPULKzhQWkd8rfQKpwcRiY6IcYFHlWdM
+VhZkXNRrxh6+q3rR7FKmxlvG/12YyT6Y1BocGLgROzKIeoEp+6vsU5LJ90jy82ig
+oGSHwNjm2RRukjV3eebovl1dCo6IaI/j4idCv7NlcBnln/Unk4YOZbneMT5r+3Zy
+Q4azLB8KHfHOrUwAxRAGPygdLtqbjs4mF45HDe6h3IOVoiOQlZNpesrwEumlK+Il
+taU0T8hfxyMpIcTLUZpIddSxo0sVby2XZ+z00En3JvtqbpRcfA87thxpsE7uHxwT
+YT8mPPDxo1R4I4LSzsDnekD8EB/7woz4n5I1RBoPB1LSoo0B2os+4vHGkiwZ0TN0
+ICcUYdM623Bv2wJQbVKEDvwjHZTkotjLx7R2lyqMRwFYrMXHxevOfbARJQCqrcY2
+ouLzQme9rE5MPQbKj2cAEQEAAYkCNgQYAQoAIBYhBKTZIo5Vdh5mW/Acu1zoact9
+7ASMBQJlpUrXAhsMAAoJEFzoact97ASMNsIP/3tlsvwUVfy19lUjxWT4rPw2GGz8
+lbPiaetgigK1F1rlzYnIVo32Fcj/GNNwWEdxxEzeaQR/AJmZLWB8sBDThoTGeSDK
+fjKXeDjZh+ElpIKWyk7f3ddHN2TpBz698kZ7fYCciRE9T4d3xgbqx2rCfupxUFSj
+lxLFRkasByJnLdAZI50NZjW838IHMaGsvgbWEqRuvKZOES6gFhrK1NTSxj5iuiHk
+Uxj1KzMhOW+m1eZ0pQcCVXJDY6KYhmrZzw9q6kzSO9ukmS5yRf0EnD7Fsca4iIXP
+Y28xs3zBxYHV4IGU1PtcIwNewmTnjnEy0apHPz0zDplHi1meXuhA7bBMjs/AouJg
+6FIDNSQqDuFXufqvVQ6LZZgob+LklMAoGcka4/5ZLPjipj5SWNeZZunJujSqWK7f
+KJaIfn7ILXqxjaTFrjBN3cm60rO1+zEektrjtWMmSBn0L76pY2ucenrqewruYYdD
+12VQra/6QAS5R0HG8gzOfsZcrHaiIuLoTbsOgnqLVcdb9lO7f3oMbKPwejZ5yhyz
+SraXHvmixlhf4uUYwsWyhw3UgHrv1psB8Z9NfdH9/T2BvRg0qy6ZmI0n0OagPNgz
+v+SZrqrWkSjyPdl6j7x8EmePfNidqw/CnncYI2rEVSmP28W0Uhg5JLgroGYmycv6
+HeZaRpYvkV8UNmnE
+=BtHq
+-----END PGP PUBLIC KEY BLOCK-----
+pub rsa4096 2024-03-10 [SC]
+ 298A8AA3D25AFD95D5C89C63C8815953907B66AD
+uid [ultimate] Ruihang Lai (CODE SIGNING KEY) <ru...@apache.org>
+sig 3 C8815953907B66AD 2024-03-10 [self-signature]
+sub rsa4096 2024-03-10 [E]
+sig C8815953907B66AD 2024-03-10 [self-signature]
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGXt0EYBEADZTOhlwl9kdTQZz/Opt7Kso4OtZ0LqdT9O1wvB2VYODsOXjc00
+DRwbwB1K2hVjVPGJpe9aAz+BMOfxox+Ncs5a4x97xn360gKra32mvfsAnQD+g0aU
+TmVWU/bhQvPSjlEYrUrvkcGClJ5QipxUWb31HNle15PJBB06XShA4GLBIhElMR2S
+6H0EkghpWhfqnAjDXrEBTVsLm2wUFQUXXdqG5+CxtSKi3ywxkMyrPS5ubnylQDlg
+lkQkAKtzcGcyMGoTEuP/oh7LnUOFbzoUF8lg87Y3z3ERzxntmrTfNQhkHBI6izgk
+mTAmUjnm9wpgr7NyTv6HRa5UVVoDmvENxDaYa1FHt+N8NLQPHZp4Ty5tsUpcY2fl
+1FGS1Kmao6cHZFJy65eUPrC96PrLCN7OTL1GblVlFzsMcjLBUxXvTs/nsFcAIMZl
+OQrpEnjRKyXE3gKLQd1On+aI7oZknND0K4cJMy7n99R62/yC2UFodGG8hNxwTO2l
+5nEfpYBq8hOfgWRqnhoJTJybowzv+aK0Gq/52cPxi69xEZEyGXf0XD5XMmfzmrun
+lNRRogq4WBPdT7bRZUHJS6ytVg7TuS4LEhlualxasNi8PkZuGHXssUOXSbY8Gjyd
+IJIdvTjkClTobCiJFyC72fBcRQVaCRZAVaAlzIUXDHVTEddB44IPXqrboQARAQAB
+tDRSdWloYW5nIExhaSAoQ09ERSBTSUdOSU5HIEtFWSkgPHJ1aWhhbmdsQGFwYWNo
+ZS5vcmc+iQJOBBMBCgA4FiEEKYqKo9Ja/ZXVyJxjyIFZU5B7Zq0FAmXt0EYCGwMF
+CwkIBwMFFQoJCAsFFgIDAQACHgUCF4AACgkQyIFZU5B7Zq1lghAAt5H5wX1/2CIj
+Gq4P17OZxmwkgxEP7E88PNu3s0AAFkk0qokuzy7fozGsQxjPdWUOqmZo+CdGQLn8
+kdUX19OQKC31alMzUKBOVecHezWAdMurb+s6rgXcwk+bMTgrg+i5Xhx0D+JjvYrC
+GOHPaxdvF4/rypvPakBrk+ELt04AzHGEN1bGlSMXTrhgtAB60+bpDSqSk4gR6U11
+ks+iv463YhC2oOiSPQpWOlXHBBr976doLVCJnQpare6cdR+8ZZead1qlIRmVSL7A
+r2/oEFHyVjGD0IRHP48xdHUlpG6crZwCr9hbsvoCxl4X6Td90SaM9EU9SL9uqQuh
+xgh5WPGwYpbotYKpRApkJ5bdnaRhxwRWwS3tSAY8O952vDxkU6YIAGQhGg8sEI/i
+W+DjlvzTK3ttXBXp2L3PM+jq6xyUxJbdaxfH0sFb4cVNQ1zrqBUe1VVZNqG5RRo3
+kRmsIWts7Nhu918bDKzJF5OM+Npk41mxG5X8t0FC0rc8sdea4AGcbg3/4IBaXGwk
+k96J7FCmj9lgKVAZLxUjNgyeTJEG5uXSXxdqmsbv5Hc6GEyixcIvKAyXoGGnYKqs
+9NqPynF139I9cjCKRwJfujtH/gCQ7Tr9i8j936sF0S4oSEZxB1TtYzwsxIgnDbyo
+LZp0IYiRmWGeI5cpuQvOQ48Hoa6szZK5Ag0EZe3QRgEQALjd80At9uYE+qJM++ZR
+vQ1np3p05pUQKvkiG3DUHKZi3ojypeIiyXod1+OQ1+VE4dlAU+XjlptebBa7nl6G
+7eMV4sqAbRe25BLYfrbmszfGDij0+T2k2WHaWYDY8QT0IOjAGpdB2KTymiGIcTLv
+zWlFdd0Y+3Pd8zBweCDOp6igDEnbzOj7uAAosZ9OI6Ufti5JZZGxCGbzENjqve0r
+wUTI/f4X11sJakTxw0k0sEJcUlKyylXbpTetgPurbec5YhboAoTRDjA8R6r+jrmu
+LGmP9tDRviGCou1VnOnTtS6ojr/7y7X6eX1gGCqWdLwMFde+aZyhJTfmVrYGDMh0
+m02rEUGkYnn/O79dXn8EbWsXnypVgW4DDzQAXH2b3m9b4pUsQrBfmXvtQQH2id18
+TD4IodtfZQKyjex8RBt5iYL+fQs/WfP3EP0sBlKVN4wllK5CzqRc5OvgxiZdajwX
+crjAC4DMHPfSfmKuIFDTXRvKU3/rITCZwoFEzrrHCVLS+KqcJyc7G5FPGuJNpN2N
+o1HGTU9qjeXIGy12CluJqqCR0EnD61yUhqVo8WndOjIFtPoef3qKRqAfxwZSe85X
+yKHi0mVpb1JwqZM6jVDYVZksG1E10sAkhsiidanM59jmydIIq5C3ouvFN2ioSPMK
+appJeRf1nGYaQeHdc+7kUHr9ABEBAAGJAjYEGAEKACAWIQQpioqj0lr9ldXInGPI
+gVlTkHtmrQUCZe3QRgIbDAAKCRDIgVlTkHtmrbaAEADD/HWvPbwwmEt9pnUYBppj
+mV9086uxJ8Pk+R8f5Mt17xkhC1wEhEuwo++uA569uGUQjPXiuUK93laHL3Y8ov/H
+yYyQaNtFuoH3P83MinErXixTZ830x7eBabOpSZnm4GngUxUusUJfhrdznsHJTZ4z
+xnBwnrXxAU1o3EVa9Wiy5m4bZiNoezw8P0lUbYUFWESD02n7kp7X7xdJ5w1F9p2O
+xiclqs3LxsXdCQHtArsgPm9HPsoaJwjH2npZo0lc+214rm/d0LNjbLNz/riZui2H
+Q3uVXxUSSO00vAmDUmYAU5Ym4E3eOsmZ9WSaS6QZPh77ATPGV7SVix32/fH0hgR1
+53Hpt9WKoavnNiNJHY05Ee1F4mbhOxKpr1lPPh5vK7vktn0ax+CwXY02izuT7SbE
+Lgr+7cLYMrH/+Uu5JZRx0/4e2qCM4CU8gSwh8zl49VykvcIeS4gc8lyH13Hbr29C
+DRwDSEzQ/xvG1Br1PJoqgtoz97+lNmMxNZv6NXLVe2OTiPAFJZfV2MCvd1rFN+2t
+xDAUVNrnujLQRhYBSxtwfxmU1uOAnZ+cQVfOjefvZ7paGoIRHR3bDFuFJgzscrqA
+zLCYllQ1hBsiHn1VM9W0v4lN1uKH/4xRegIoxbRp6VDqQzbGUxeTzayotRc+ZMf/
+2KO2FSofA649SDc2HheDeQ==
+=yNdl
+-----END PGP PUBLIC KEY BLOCK-----
(tvm) 05/12: [TIRx] Clarify overload sets, leaf ownership, and terminal throws (#20765)
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 8a10be0a14b770909c29fa93613fef769fffe599
Author: Tianqi Chen <tq...@users.noreply.github.com>
AuthorDate: Fri Oct 16 15:36:20 2026 -0400
[TIRx] Clarify overload sets, leaf ownership, and terminal throws (#20765)
TIRx visitors and code generators intentionally override only part of
their base overload sets. Expose the remaining overloads and mark the
private analyzer implementations as leaf types.
Make terminal FFI throw paths explicit so MSVC can recognize that those
paths cannot return. This preserves the existing dispatch and exception
behavior while addressing the focused Clang and MSVC warnings.
---
tirx/include/tvm/ir/transform.h | 1 +
tirx/include/tvm/script/printer/doc_translator.h | 1 +
tirx/src/backend/cuda/codegen/codegen_cuda_host.cc | 2 ++
tirx/src/backend/cuda/transforms/bind_backend_config.cc | 2 ++
tirx/src/backend/cuda/transforms/lower_iket.cc | 4 ++++
tirx/src/codegen/c/codegen_c.h | 1 +
tirx/src/codegen/llvm/codegen_cpu.cc | 1 +
tirx/src/codegen/llvm/codegen_llvm.h | 1 +
tirx/src/codegen/llvm/codegen_x86_64.cc | 2 ++
tirx/src/ir/prim/math.cc | 1 +
tirx/src/ir/prim/op.cc | 2 ++
tirx/src/sym/const_int_bound.cc | 2 +-
tirx/src/sym/modular_set.cc | 3 ++-
tirx/src/sym/z3_prover.cc | 2 +-
tirx/src/tirx/analysis/check_well_formed.cc | 1 +
tirx/src/tirx/transform/narrow_datatype.cc | 2 ++
tirx/src/tirx/transform/vectorize_loop.cc | 4 ++++
17 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/tirx/include/tvm/ir/transform.h b/tirx/include/tvm/ir/transform.h
index b08c6d8d4f..0d7763e677 100644
--- a/tirx/include/tvm/ir/transform.h
+++ b/tirx/include/tvm/ir/transform.h
@@ -177,6 +177,7 @@ class PassContext : public ffi::ObjectRef {
TVM_FFI_THROW(AttributeError)
<< "Expect config " << key << " to have type " << type_str << ", but instead get "
<< ffi::details::AnyUnsafe::GetMismatchTypeInfo<ValueType>(value);
+ TVM_FFI_UNREACHABLE();
} else {
return *opt_val;
}
diff --git a/tirx/include/tvm/script/printer/doc_translator.h b/tirx/include/tvm/script/printer/doc_translator.h
index 283fa81d55..202c85938b 100644
--- a/tirx/include/tvm/script/printer/doc_translator.h
+++ b/tirx/include/tvm/script/printer/doc_translator.h
@@ -477,6 +477,7 @@ inline ffi::Optional<ExprDoc> DocTranslatorObj::DefaultTranslate(ffi::AnyView va
? std::string("printer has no Doc hook for ") +
value.GetTypeKey()
: "printer Doc hook must be a native pointer or ffi.Function");
+ TVM_FFI_UNREACHABLE();
}
} // namespace printer
diff --git a/tirx/src/backend/cuda/codegen/codegen_cuda_host.cc b/tirx/src/backend/cuda/codegen/codegen_cuda_host.cc
index 6103dfffe9..968061a9fc 100644
--- a/tirx/src/backend/cuda/codegen/codegen_cuda_host.cc
+++ b/tirx/src/backend/cuda/codegen/codegen_cuda_host.cc
@@ -47,6 +47,8 @@ namespace codegen {
class CodeGenCUDAHost : public CodeGenCHost {
public:
+ using CodeGenCHost::Dispatch_;
+
void Init(Target target) {
CodeGenCHost::Init(false, true, true, target->str(), {});
// Retain C-host wrapper initialization, with an FFI/CUDA-only prelude.
diff --git a/tirx/src/backend/cuda/transforms/bind_backend_config.cc b/tirx/src/backend/cuda/transforms/bind_backend_config.cc
index 3534825f5f..4acc81980e 100644
--- a/tirx/src/backend/cuda/transforms/bind_backend_config.cc
+++ b/tirx/src/backend/cuda/transforms/bind_backend_config.cc
@@ -112,6 +112,8 @@ class DeviceHelperSpecializer : public StmtExprMutator {
std::unordered_set<const GlobalVarNode*> originals;
private:
+ using StmtExprMutator::Mutate_;
+
UnchangedOr<Stmt> Mutate_(const RegionStmtNode* op, InplaceMode inplace_mode) final {
if (op->op->name != "tirx.device_entry") {
return StmtExprMutator::Mutate_(op, inplace_mode);
diff --git a/tirx/src/backend/cuda/transforms/lower_iket.cc b/tirx/src/backend/cuda/transforms/lower_iket.cc
index b65be5d52a..b51dabc7fe 100644
--- a/tirx/src/backend/cuda/transforms/lower_iket.cc
+++ b/tirx/src/backend/cuda/transforms/lower_iket.cc
@@ -577,6 +577,8 @@ class StripIket : public StmtExprMutator {
explicit StripIket(TokenTensorSet token_tensors) : token_tensors_(std::move(token_tensors)) {}
private:
+ using StmtExprMutator::Mutate_;
+
UnchangedOr<Stmt> Mutate_(const BindNode* alloc, InplaceMode inplace_mode) final {
if (const auto* call = alloc->value.as<CallNode>(); call &&
call->op.same_as(tirx::alloc_tensor_op()) &&
@@ -1083,6 +1085,8 @@ class InstrumentOfficialKernel : public StmtExprMutator {
}
private:
+ using StmtExprMutator::Mutate_;
+
const Declaration& Lookup(DeclarationKind kind, const CallNode* call) const {
DeclarationKey key{kind, GetName(call)};
auto it = info_.declarations.find(key);
diff --git a/tirx/src/codegen/c/codegen_c.h b/tirx/src/codegen/c/codegen_c.h
index 9732a57323..68a97e54a5 100644
--- a/tirx/src/codegen/c/codegen_c.h
+++ b/tirx/src/codegen/c/codegen_c.h
@@ -64,6 +64,7 @@ class CodeGenC : public tvm::ExprFunctor<void(const Expr&, std::ostream&)>,
public CodeGenSourceBase {
public:
using tvm::ExprFunctor<void(const Expr&, std::ostream&)>::Dispatch;
+ using tvm::ExprFunctor<void(const Expr&, std::ostream&)>::Dispatch_;
using StmtFunctor::Dispatch;
/*!
diff --git a/tirx/src/codegen/llvm/codegen_cpu.cc b/tirx/src/codegen/llvm/codegen_cpu.cc
index 98cd256969..60688548cd 100644
--- a/tirx/src/codegen/llvm/codegen_cpu.cc
+++ b/tirx/src/codegen/llvm/codegen_cpu.cc
@@ -411,6 +411,7 @@ CodeGenLLVM::TypedPointer CodeGenCPU::CreateStructRefPtr(Type type, llvm::Value*
}
default:
TVM_FFI_THROW(InternalError) << "unknown field code";
+ TVM_FFI_UNREACHABLE();
}
}
diff --git a/tirx/src/codegen/llvm/codegen_llvm.h b/tirx/src/codegen/llvm/codegen_llvm.h
index 0cfc685db2..f9bdbf8e00 100644
--- a/tirx/src/codegen/llvm/codegen_llvm.h
+++ b/tirx/src/codegen/llvm/codegen_llvm.h
@@ -95,6 +95,7 @@ class CodeGenLLVM : public tvm::ExprFunctor<llvm::Value*(const Expr&)>,
public StmtFunctor<void(const Stmt&)> {
public:
using tvm::ExprFunctor<llvm::Value*(const Expr&)>::Dispatch;
+ using tvm::ExprFunctor<llvm::Value*(const Expr&)>::Dispatch_;
using StmtFunctor::Dispatch;
CodeGenLLVM(); // Do not make it default here.
diff --git a/tirx/src/codegen/llvm/codegen_x86_64.cc b/tirx/src/codegen/llvm/codegen_x86_64.cc
index b929823d03..e638a725be 100644
--- a/tirx/src/codegen/llvm/codegen_x86_64.cc
+++ b/tirx/src/codegen/llvm/codegen_x86_64.cc
@@ -43,6 +43,8 @@ namespace codegen {
class CodeGenX86_64 final : public CodeGenCPU {
public:
+ using CodeGenCPU::Dispatch_;
+
llvm::Value* Dispatch_(const prim::CastNode* op) override;
private:
diff --git a/tirx/src/ir/prim/math.cc b/tirx/src/ir/prim/math.cc
index 5cc173d98e..ffd57eb52b 100644
--- a/tirx/src/ir/prim/math.cc
+++ b/tirx/src/ir/prim/math.cc
@@ -251,6 +251,7 @@ PrimExpr infinity(PrimType value_ty, Location loc) {
}
}
TVM_FFI_THROW(InternalError) << "Cannot decide infinity for type " << dtype;
+ TVM_FFI_UNREACHABLE();
}
PrimExpr pow(PrimExpr x, PrimExpr y, Location loc) {
diff --git a/tirx/src/ir/prim/op.cc b/tirx/src/ir/prim/op.cc
index 8153c442d5..438f56a50e 100644
--- a/tirx/src/ir/prim/op.cc
+++ b/tirx/src/ir/prim/op.cc
@@ -243,6 +243,7 @@ PrimExpr max_value(PrimType value_ty, Location loc) {
return FloatImm(value_ty, 6.0, loc);
}
TVM_FFI_THROW(InternalError) << "Cannot decide max_value for type" << dtype;
+ TVM_FFI_UNREACHABLE();
}
PrimExpr min_value(PrimType value_ty, Location loc) {
@@ -297,6 +298,7 @@ PrimExpr min_value(PrimType value_ty, Location loc) {
return FloatImm(value_ty, -6.0, loc);
}
TVM_FFI_THROW(InternalError) << "Cannot decide min_value for type" << dtype;
+ TVM_FFI_UNREACHABLE();
}
PrimExpr cast(PrimExpr value, PrimType t, Location loc) {
diff --git a/tirx/src/sym/const_int_bound.cc b/tirx/src/sym/const_int_bound.cc
index 85f5078612..b5c9c1e55b 100644
--- a/tirx/src/sym/const_int_bound.cc
+++ b/tirx/src/sym/const_int_bound.cc
@@ -92,7 +92,7 @@ struct ConstIntBoundAnalyzer::Entry {
}
};
-class ConstIntBoundAnalyzer::Impl
+class ConstIntBoundAnalyzer::Impl final
: public tvm::ExprFunctor<ConstIntBoundAnalyzer::Entry(const Expr&)> {
public:
explicit Impl(AnalyzerObj* parent) : parent_(parent) {}
diff --git a/tirx/src/sym/modular_set.cc b/tirx/src/sym/modular_set.cc
index fd63276a39..d765747f29 100644
--- a/tirx/src/sym/modular_set.cc
+++ b/tirx/src/sym/modular_set.cc
@@ -134,7 +134,8 @@ struct ModularSetAnalyzer::Entry {
}
};
-class ModularSetAnalyzer::Impl : public tvm::ExprFunctor<ModularSetAnalyzer::Entry(const Expr&)> {
+class ModularSetAnalyzer::Impl final
+ : public tvm::ExprFunctor<ModularSetAnalyzer::Entry(const Expr&)> {
public:
explicit Impl(AnalyzerObj* parent) : parent_(parent) {}
diff --git a/tirx/src/sym/z3_prover.cc b/tirx/src/sym/z3_prover.cc
index 105f7dbd47..ef3be241a0 100644
--- a/tirx/src/sym/z3_prover.cc
+++ b/tirx/src/sym/z3_prover.cc
@@ -102,7 +102,7 @@ struct Namespace {
} // namespace
-class Z3Prover::Impl : tvm::ExprFunctor<z3::expr(const Expr&)> {
+class Z3Prover::Impl final : tvm::ExprFunctor<z3::expr(const Expr&)> {
public:
using Base = tvm::ExprFunctor<z3::expr(const Expr&)>;
using Self = Z3Prover::Impl;
diff --git a/tirx/src/tirx/analysis/check_well_formed.cc b/tirx/src/tirx/analysis/check_well_formed.cc
index 2af95fd149..0efa2fad1d 100644
--- a/tirx/src/tirx/analysis/check_well_formed.cc
+++ b/tirx/src/tirx/analysis/check_well_formed.cc
@@ -585,6 +585,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TVM_FFI_THROW(InternalError)
<< "Expected VerifyWellFormed argument to be a Function or IRModule, but found "
<< obj->GetTypeKey();
+ TVM_FFI_UNREACHABLE();
}
});
}
diff --git a/tirx/src/tirx/transform/narrow_datatype.cc b/tirx/src/tirx/transform/narrow_datatype.cc
index 72df52004a..c721ea7f26 100644
--- a/tirx/src/tirx/transform/narrow_datatype.cc
+++ b/tirx/src/tirx/transform/narrow_datatype.cc
@@ -75,6 +75,8 @@ using sym::ConstIntBound;
// Otherwise, `var` is not narrowed, that is, `vmap[var] = var.dtype.bits()`
class DataTypeVisitor final : public StmtExprVisitor {
public:
+ using StmtExprVisitor::Visit_;
+
explicit DataTypeVisitor(int target_bits) : bits_(target_bits), target_bits_(target_bits) {}
ffi::Optional<VisitInterrupt> Visit(ffi::AnyView expr) final {
diff --git a/tirx/src/tirx/transform/vectorize_loop.cc b/tirx/src/tirx/transform/vectorize_loop.cc
index 5d0d540d32..579cf642c3 100644
--- a/tirx/src/tirx/transform/vectorize_loop.cc
+++ b/tirx/src/tirx/transform/vectorize_loop.cc
@@ -219,6 +219,8 @@ class TryPredicateTensorAccesses : public StmtExprMutator {
}
private:
+ using StmtExprMutator::Mutate_;
+
UnchangedOr<PrimExpr> Mutate_(const TensorLoadNode* op, InplaceMode inplace_mode) final {
auto load = StmtExprMutator::Mutate_(op, inplace_mode)
.ValueOrUnchanged(ffi::GetRef<PrimExpr>(op))
@@ -340,6 +342,8 @@ class TryPredicateTensorAccesses : public StmtExprMutator {
//
class VecAllocAccess : public StmtExprMutator {
public:
+ using StmtExprMutator::Mutate_;
+
VecAllocAccess(const VarNode* buf, Var var, PrimExpr var_lanes)
: buf_(buf), var_(var), var_lanes_(var_lanes) {}
(tvm) 11/12: [CI] Add standalone TIRx build, wheel, and docs pipelines
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 8bfc5bd764f37f6a3a58f8ebea553d0740c7af6b
Author: tqchen <ti...@gmail.com>
AuthorDate: Fri Oct 16 02:31:09 2026 +0000
[CI] Add standalone TIRx build, wheel, and docs pipelines
Build pinned FFI and TIRx wheels from the standalone root and run CPU,
GPU, ARM, Windows, and macOS jobs.
Build the Python API documentation alongside GPU tests using the built
wheels, and publish only the tirx site subtree from an explicitly enabled
main pipeline. Validate the archive revision and publication scope.
Run the existing lint workflow on standalone branch pushes.
Share environment setup, CPU detection, and release wheel builds through
composite actions adapted to the standalone repository layout.
---
.github/actions/build-wheel-for-publish/action.yml | 148 +++++
.../detect-env-vars/action.yml} | 39 +-
.github/actions/setup/action.yml | 62 ++
.github/workflows/lint.yml | 2 +-
.github/workflows/main.yml | 139 +++++
.github/workflows/publish_wheel.yml | 218 +++++++
ci/jenkins/.gitignore | 1 +
.../task_build_arm.sh => ci/jenkins/artifacts.py | 21 +-
.../jenkins/docker-images.ini | 14 +-
ci/jenkins/generated/arm_jenkinsfile.groovy | 46 ++
ci/jenkins/generated/common.groovy | 386 ++++++++++++
ci/jenkins/generated/cpu_jenkinsfile.groovy | 64 ++
ci/jenkins/generated/gpu_jenkinsfile.groovy | 144 +++++
ci/jenkins/scripts/determine_docker_images.py | 156 +++++
ci/jenkins/scripts/git_skip_ci.py | 100 +++
ci/jenkins/scripts/git_skip_ci_globs.py | 76 +++
.../lint.yml => ci/jenkins/scripts/http_utils.py | 35 +-
.../jenkins/scripts/retry.sh | 26 +-
ci/jenkins/scripts/s3.py | 243 ++++++++
.../jenkins/scripts/show_node_info.sh | 29 +-
.../lint.yml => ci/wheel/build-environment.yaml | 51 +-
ci/wheel/manylinux_build_libtvm_runtime_cuda.sh | 64 ++
ci/wheel/windows_build_libtvm_runtime_cuda.bat | 99 +++
docker/bash.sh | 669 +++++++++++++++++++++
tests/scripts/task_build_arm.sh | 5 +-
tests/scripts/task_build_cpu.sh | 5 +-
tests/scripts/task_build_gpu.sh | 5 +-
.../{task_build_arm.sh => task_build_gpu_other.sh} | 13 +-
...d_arm.sh => task_install_build_dependencies.sh} | 12 +-
.../{task_build_arm.sh => task_python_docs.sh} | 12 +-
.../{task_build_arm.sh => task_python_unittest.sh} | 10 +-
...uild_arm.sh => task_python_unittest_gpuonly.sh} | 21 +-
...ild_arm.sh => test_task_install_dist_wheels.sh} | 11 +-
33 files changed, 2800 insertions(+), 126 deletions(-)
diff --git a/.github/actions/build-wheel-for-publish/action.yml b/.github/actions/build-wheel-for-publish/action.yml
new file mode 100644
index 0000000000..3207675deb
--- /dev/null
+++ b/.github/actions/build-wheel-for-publish/action.yml
@@ -0,0 +1,148 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Build TIRx Wheel
+description: >
+ Build and test the standalone LLVM-enabled apache-tvm-tirx wheel for a given OS/architecture
+ combination using cibuildwheel.
+
+inputs:
+ arch:
+ description: "Target architecture for cibuildwheel (e.g., x86_64, aarch64, arm64, AMD64)"
+ required: true
+ build:
+ description: "cibuildwheel build selector (e.g., cp310-manylinux_x86_64)"
+ required: true
+ cmake_defines:
+ description: "Feature CMake defines that vary by wheel (e.g. -DTVM_TIRX_USE_METAL=ON on macOS)"
+ required: false
+ default: ""
+ include_cuda_runtime:
+ description: "Set to 1 to build and inject the CUDA runtime library (Linux only)"
+ required: false
+ default: "0"
+
+runs:
+ using: "composite"
+ steps:
+ # Single source of truth for the LLVM toolchain version, shared by the cache
+ # key and the conda install steps below.
+ - name: Set LLVM version
+ shell: bash
+ run: echo "LLVM_VERSION=22.1.0" >> "$GITHUB_ENV"
+
+ - name: Prepare LLVM cache path (Unix)
+ if: runner.os != 'Windows'
+ shell: bash
+ run: |
+ set -eux
+ sudo mkdir -p /opt/llvm
+ sudo chown -R "$(whoami)" /opt/llvm
+
+ # ---- Cache LLVM prefix ----
+ - name: Cache LLVM
+ uses: actions/cache@v5.0.5
+ id: llvm-cache
+ with:
+ path: ${{ runner.os == 'Windows' && 'C:/opt/llvm' || '/opt/llvm' }}
+ key: tirx-wheel-llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ inputs.arch }}-v6
+
+ # ---- Install LLVM via conda (cache miss only) ----
+ - name: Setup conda
+ if: steps.llvm-cache.outputs.cache-hit != 'true'
+ uses: conda-incubator/setup-miniconda@v4.0.1
+ continue-on-error: true
+ id: conda1
+ with:
+ miniforge-version: latest
+ conda-remove-defaults: true
+
+ - name: Setup conda (retry with tar.bz2)
+ if: steps.llvm-cache.outputs.cache-hit != 'true' && steps.conda1.outcome == 'failure'
+ uses: conda-incubator/setup-miniconda@v4.0.1
+ with:
+ miniforge-version: latest
+ use-only-tar-bz2: true
+ conda-remove-defaults: true
+
+ - name: Install LLVM (Unix)
+ if: steps.llvm-cache.outputs.cache-hit != 'true' && runner.os != 'Windows'
+ shell: bash -l {0}
+ run: |
+ set -eux
+ if [[ "${RUNNER_OS}" == "Linux" ]]; then
+ sudo mkdir -p /opt/llvm
+ sudo chown -R "$(whoami)" /opt/llvm
+ fi
+ conda create -q -p /opt/llvm -c conda-forge \
+ "llvmdev=${LLVM_VERSION}" "clangdev=${LLVM_VERSION}" "compiler-rt=${LLVM_VERSION}" zlib zstd-static libxml2-devel \
+ -y
+
+ - name: Install LLVM (Windows)
+ if: steps.llvm-cache.outputs.cache-hit != 'true' && runner.os == 'Windows'
+ shell: cmd /C call {0}
+ run: |
+ call conda create -q -p C:\opt\llvm -c conda-forge llvmdev=%LLVM_VERSION% zlib zstd-static libxml2-devel -y
+
+ # The {project} placeholder is not expanded inside CIBW_ENVIRONMENT values, so
+ # compute the forward-slash host path here (the Windows analog of the Linux
+ # /project hardcode).
+ - name: Compute CUDA sidecar path (Windows)
+ if: runner.os == 'Windows' && inputs.include_cuda_runtime == '1'
+ shell: bash
+ run: echo "TVM_CUDA_EXTRA_LIB=$(cygpath -m "$(pwd)")/build-wheel-cuda/lib/tvm_runtime_cuda.dll" >> "$GITHUB_ENV"
+
+ # ---- Build and test wheels ----
+ - name: Build and test TIRx core wheel
+ uses: pypa/cibuildwheel@294735312765b09d24a2fbec22660ce817587d55 # v4.1.0
+ with:
+ package-dir: .
+ output-dir: wheelhouse
+ env:
+ CIBW_BUILD: ${{ inputs.build }}
+ CIBW_ARCHS_LINUX: ${{ inputs.arch }}
+ CIBW_ARCHS_MACOS: ${{ inputs.arch }}
+ CIBW_ARCHS_WINDOWS: ${{ inputs.arch }}
+ # Linux builds run in cibuildwheel's default manylinux_2_28 container;
+ # bind-mount the cached LLVM prefix into it. Ignored on macOS/Windows,
+ # which build without a container.
+ CIBW_CONTAINER_ENGINE: "docker; create_args: --volume /opt/llvm:/opt/llvm:ro"
+ # Each per-OS block carries the toolchain location (conda LLVM prefix +
+ # llvm-config path), the universal static-link policy (TVM_TIRX_USE_LLVM --link-static
+ # and ZLIB_USE_STATIC_LIBS), and the CUDA sidecar. Feature defines that vary by
+ # wheel (e.g. TVM_TIRX_USE_METAL on macOS) come from the matrix via inputs.cmake_defines.
+ # One explicit block per build platform (macOS / Linux / Windows); cibuildwheel
+ # env overrides replace rather than merge, so there is no shared base block.
+ CIBW_ENVIRONMENT_MACOS: >-
+ CMAKE_PREFIX_PATH="/opt/llvm"
+ CMAKE_ARGS="-DTVM_TIRX_USE_LLVM='/opt/llvm/bin/llvm-config --link-static' -DZLIB_USE_STATIC_LIBS=ON -DCMAKE_PREFIX_PATH=/opt/llvm ${{ inputs.cmake_defines }}"
+ CIBW_ENVIRONMENT_LINUX: >-
+ CMAKE_PREFIX_PATH="/opt/llvm"
+ LIBRARY_PATH="/opt/llvm/lib"
+ CMAKE_ARGS="-DTVM_TIRX_USE_LLVM='/opt/llvm/bin/llvm-config --link-static' -DZLIB_USE_STATIC_LIBS=ON -DCMAKE_PREFIX_PATH=/opt/llvm ${{ inputs.cmake_defines }} -DTVM_TIRX_PACKAGE_EXTRA_LIBS=/project/build-wheel-cuda/lib/libtvm_runtime_cuda.so"
+ CIBW_ENVIRONMENT_WINDOWS: >-
+ CMAKE_PREFIX_PATH="C:/opt/llvm/Library"
+ PATH="C:/opt/llvm/Library/bin;$PATH"
+ CMAKE_ARGS="-DTVM_TIRX_USE_LLVM='C:/opt/llvm/Library/bin/llvm-config.exe --link-static' -DZLIB_USE_STATIC_LIBS=ON -DCMAKE_PREFIX_PATH=C:/opt/llvm/Library ${{ inputs.cmake_defines }} -DTVM_TIRX_PACKAGE_EXTRA_LIBS=${{ env.TVM_CUDA_EXTRA_LIB }}"
+ # Turns the wheel-specific assertions in
+ # tests/python/runtime/test_validate_wheel_library.py
+ # ON (they skip unless these are set). Every published wheel is LLVM-enabled,
+ # so TVM_WHEEL_EXPECT_LLVM is always "1"; the CUDA runtime is only bundled on
+ # the CUDA wheels, so TVM_WHEEL_EXPECT_CUDA_RUNTIME is "0" for CPU wheels.
+ CIBW_TEST_ENVIRONMENT: >-
+ TVM_WHEEL_EXPECT_LLVM="1"
+ TVM_WHEEL_EXPECT_CUDA_RUNTIME="${{ inputs.include_cuda_runtime }}"
diff --git a/.github/workflows/lint.yml b/.github/actions/detect-env-vars/action.yml
similarity index 53%
copy from .github/workflows/lint.yml
copy to .github/actions/detect-env-vars/action.yml
index a9bff51f3b..afd9efeaad 100644
--- a/.github/workflows/lint.yml
+++ b/.github/actions/detect-env-vars/action.yml
@@ -15,27 +15,26 @@
# specific language governing permissions and limitations
# under the License.
-name: Lint
+name: Detect Environment Variables
+description: Detects environment variables such as CPU count and sets them as outputs.
+runs:
+ using: "composite"
+ steps:
+ - name: Run Python to detect environment variables
+ shell: python
+ id: detect
+ run: |
+ import multiprocessing, os
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
+ output_file = open(os.environ.get("GITHUB_OUTPUT"), "a")
-permissions:
- contents: read
+ def write_env_var(name, value):
+ output_file.write(f"{name}={value}\n")
+ print(f"Detected environment variable: {name}={value}")
-concurrency:
- group: Lint-${{ github.event.pull_request.number || github.sha }}
- cancel-in-progress: true
+ write_env_var("cpu_count", multiprocessing.cpu_count())
-jobs:
- lint:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6.0.2
- with:
- fetch-depth: 0
- fetch-tags: true
- - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
+outputs:
+ cpu_count:
+ description: "The number of CPU cores"
+ value: ${{ steps.detect.outputs.cpu_count }}
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
new file mode 100644
index 0000000000..5ca6414215
--- /dev/null
+++ b/.github/actions/setup/action.yml
@@ -0,0 +1,62 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Setup TVM CI environment
+description: Set up the cached conda build environment and install tvm-ffi.
+
+runs:
+ using: "composite"
+ steps:
+ - uses: actions/cache@v5.0.5
+ env:
+ CACHE_NUMBER: 2
+ with:
+ path: ~/conda_pkgs_dir
+ key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('ci/wheel/build-environment.yaml') }}
+ - uses: conda-incubator/setup-miniconda@v4.0.1
+ continue-on-error: true
+ id: conda1
+ with:
+ activate-environment: tvm-build
+ channel-priority: strict
+ environment-file: ci/wheel/build-environment.yaml
+ auto-activate-base: false
+ miniforge-version: latest
+ python-version: "3.10"
+ conda-remove-defaults: true
+ - uses: conda-incubator/setup-miniconda@v4.0.1
+ if: steps.conda1.outcome == 'failure'
+ with:
+ activate-environment: tvm-build
+ channel-priority: strict
+ environment-file: ci/wheel/build-environment.yaml
+ auto-activate-base: false
+ miniforge-version: latest
+ use-only-tar-bz2: true
+ python-version: "3.10"
+ conda-remove-defaults: true
+ - name: Conda info
+ shell: pwsh
+ run: |
+ mamba info
+ mamba list
+ mamba info --envs
+ mamba list --name base
+ - name: Install tvm-ffi pip package
+ shell: bash -l {0}
+ run: |
+ pip install -v ./3rdparty/tvm-ffi
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index a9bff51f3b..8ac5f2f9f5 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -19,7 +19,7 @@ name: Lint
on:
push:
- branches: [main]
+ branches: [main, tirx-standalone-root]
pull_request:
branches: [main]
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000000..f2e16fab34
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,139 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# GH actions.
+# We use it to cover windows and mac builds
+# Jenkins is still the primary CI
+
+name: CI
+
+on:
+ push:
+ branches:
+ - main
+ - tirx-standalone-root # Temporary standalone branch validation.
+ pull_request:
+ branches:
+ - main
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+concurrency:
+ group: CI-${{ github.event.pull_request.number || github.sha }}
+ cancel-in-progress: true
+
+jobs:
+ MacOS:
+ if: >-
+ ${{ github.repository == 'apache/tvm' ||
+ (github.repository == 'tqchen/tvm-dev' && github.ref == 'refs/heads/tirx-standalone-root') }}
+ runs-on: macOS-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+ with:
+ submodules: 'recursive'
+ - uses: ./.github/actions/setup
+ - name: Detect environment variables
+ id: env_vars
+ uses: ./.github/actions/detect-env-vars
+ - name: Build TIRx wheels
+ shell: bash -l {0}
+ env:
+ CMAKE_BUILD_PARALLEL_LEVEL: ${{ steps.env_vars.outputs.cpu_count }}
+ run: |
+ set -euxo pipefail
+ pip install "scikit-build-core>=0.11" "setuptools-scm>=8"
+ export CMAKE_ARGS="-DTVM_TIRX_USE_LLVM=ON -DTVM_TIRX_USE_METAL=ON -DTVM_TIRX_BUILD_TESTS=OFF"
+ pip wheel --no-deps -w dist . -v
+ pip install --no-deps --force-reinstall dist/apache_tvm_tirx-*.whl
+ - name: Install TIRx from wheels
+ shell: bash -l {0}
+ run: |
+ set -euxo pipefail
+ export TVM_FFI_VERSION="$(python -c 'from importlib.metadata import version; print(version("apache-tvm-ffi"))')"
+ pip install psutil cloudpickle ml_dtypes numpy packaging scipy typing_extensions
+ # --no-deps: this package requires apache-tvm-ffi>=0.1.14.post1, and the source-built core
+ # versions as 0.1.dev1+g<sha> from the shallow checkout, which is < 0.1.0 under PEP 440.
+ # Without it pip replaces the source-matched core with a PyPI build.
+ pip install --no-deps apache-tvm-ffi-orcjit==0.1.2
+ # Keep the source-matched tvm-ffi installed by the setup steps.
+ pip install --no-deps dist/*.whl
+ python - <<'PY'
+ import os
+ from importlib.metadata import requires, version
+
+ assert version("apache-tvm-ffi") == os.environ["TVM_FFI_VERSION"]
+ assert version("apache-tvm-tirx") == "0.1.0a0"
+ assert "apache-tvm-ffi>=0.1.15rc0" in requires("apache-tvm-tirx")
+ assert "apache-tvm-ffi-orcjit==0.1.2" in requires("apache-tvm-tirx")
+ PY
+
+ - name: Test
+ shell: bash -l {0}
+ run: >-
+ python -m pytest -v tests/python/runtime/test_validate_wheel_library.py tests/python/script
+ - name: Minimal Metal Compile-Only
+ shell: bash -l {0}
+ run: |
+ set -euxo pipefail
+ python -m pytest -v -s 'tests/python/codegen/gpu_common/test_allreduce.py::test_allreduce_sum_compile'
+ python -m pytest -v -s 'tests/python/backend/metal/codegen/test_basic.py::test_func_with_trailing_pod_params'
+ - name: Minimal Metal Compile-and-Run
+ shell: bash -l {0}
+ run: |
+ set -euxo pipefail
+ python -m pytest -v -s tests/python/backend/metal
+ python -m pytest -v -s 'tests/python/codegen/gpu_common/test_intrinsics.py'
+ python -m pytest -v -s 'tests/python/codegen/gpu_common/test_allreduce.py::test_allreduce_sum[dims0-metal]'
+
+ Windows:
+ if: >-
+ ${{ github.repository == 'apache/tvm' ||
+ (github.repository == 'tqchen/tvm-dev' && github.ref == 'refs/heads/tirx-standalone-root') }}
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+ with:
+ submodules: 'recursive'
+ - uses: ./.github/actions/setup
+ - name: Detect environment variables
+ id: env_vars
+ uses: ./.github/actions/detect-env-vars
+ - name: Build and install TIRx
+ shell: cmd /C call {0}
+ env:
+ CMAKE_BUILD_PARALLEL_LEVEL: ${{ steps.env_vars.outputs.cpu_count }}
+ run: |
+ pip install "scikit-build-core>=0.11" "setuptools-scm>=8" || exit /b 1
+ set CMAKE_ARGS=-DTVM_TIRX_USE_LLVM=ON -DTVM_TIRX_BUILD_TESTS=OFF
+ pip wheel --no-deps -w dist . -v || exit /b 1
+ for %%w in (dist\apache_tvm_tirx-*.whl) do (
+ pip install --no-deps --force-reinstall "%%w" || exit /b 1
+ )
+ - name: Install test dependencies
+ shell: cmd /C call {0}
+ run: |
+ pip install psutil cloudpickle ml_dtypes numpy packaging scipy typing_extensions || exit /b 1
+ rem --no-deps keeps the source-built apache-tvm-ffi (versioned below 0.1.14.post1 from the
+ rem shallow checkout) from being replaced by a PyPI build.
+ pip install --no-deps apache-tvm-ffi-orcjit==0.1.2 || exit /b 1
+ - name: Test
+ shell: cmd /C call {0}
+ run: >-
+ python -m pytest -v tests/python/runtime/test_validate_wheel_library.py tests/python/script
diff --git a/.github/workflows/publish_wheel.yml b/.github/workflows/publish_wheel.yml
new file mode 100644
index 0000000000..3f97192c29
--- /dev/null
+++ b/.github/workflows/publish_wheel.yml
@@ -0,0 +1,218 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Publish TIRx wheels
+
+on:
+ workflow_dispatch:
+ inputs:
+ tag:
+ description: "Tag, branch, or SHA to build"
+ required: true
+ type: string
+ publish_repository:
+ description: "Where to publish after the wheel build succeeds"
+ required: true
+ default: "none"
+ type: choice
+ options:
+ - none
+ - pypi
+
+permissions:
+ contents: read
+
+# CI runners are ephemeral, so pip's HTTP cache buys nothing and a stale
+# preinstalled cache (e.g. on the macOS image) only produces noisy
+# "Cache entry deserialization failed" warnings. Disable it everywhere.
+env:
+ PIP_NO_CACHE_DIR: "1"
+
+jobs:
+ # Build the CUDA runtime sidecar once per arch and upload it as an artifact that
+ # build_wheels bundles. The Linux legs build inside the official manylinux_2_28
+ # CUDA image (CUDA toolkit preinstalled, see pypa/manylinux) -- the same glibc
+ # baseline cibuildwheel targets for the wheel -- so the sidecar stays
+ # ABI-compatible with the wheel's libtvm_runtime.so regardless of the exact tag.
+ build_cuda_runtime:
+ name: ${{ matrix.name }}
+ runs-on: ${{ matrix.os }}
+ container: ${{ matrix.container }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: "CUDA runtime sidecar (Linux x86_64, manylinux_2_28)"
+ os: ubuntu-latest
+ container: quay.io/manylinux_cuda/manylinux_2_28_x86_64_cuda13_1:latest
+ arch: x86_64
+ script: ci/wheel/manylinux_build_libtvm_runtime_cuda.sh
+ lib: build-wheel-cuda/lib/libtvm_runtime_cuda.so
+ - name: "CUDA runtime sidecar (Linux aarch64, manylinux_2_28)"
+ os: ubuntu-24.04-arm
+ container: quay.io/manylinux_cuda/manylinux_2_28_aarch64_cuda13_1:latest
+ arch: aarch64
+ script: ci/wheel/manylinux_build_libtvm_runtime_cuda.sh
+ lib: build-wheel-cuda/lib/libtvm_runtime_cuda.so
+ - name: "CUDA runtime sidecar (Windows AMD64)"
+ os: windows-2022
+ container: ""
+ arch: AMD64
+ script: ci/wheel/windows_build_libtvm_runtime_cuda.bat
+ lib: build-wheel-cuda/lib/tvm_runtime_cuda.dll
+ steps:
+ # The containerized Linux legs check out as root; mark the tree safe so git
+ # (submodule init in checkout) does not bail on "dubious ownership".
+ - name: Mark workspace safe for git
+ if: runner.os == 'Linux'
+ shell: bash
+ run: git config --global --add safe.directory '*'
+
+ - name: Checkout source
+ uses: actions/checkout@v6.0.2
+ with:
+ ref: ${{ inputs.tag }}
+ submodules: recursive
+ fetch-depth: 1
+ fetch-tags: true
+
+ # Windows has no manylinux interpreter; the script's pip install needs one.
+ - name: Set up Python (Windows host)
+ if: runner.os == 'Windows'
+ uses: actions/setup-python@v6.2.0
+ with:
+ python-version: "3.10"
+
+ - name: Build CUDA runtime sidecar (Unix)
+ if: runner.os != 'Windows'
+ shell: bash
+ run: bash ${{ matrix.script }}
+
+ - name: Build CUDA runtime sidecar (Windows)
+ if: runner.os == 'Windows'
+ shell: cmd
+ run: call ${{ matrix.script }}
+
+ - name: Upload CUDA runtime sidecar
+ uses: actions/upload-artifact@v7.0.1
+ with:
+ name: tirx-cuda-runtime-${{ matrix.arch }}
+ path: ${{ matrix.lib }}
+ if-no-files-found: error
+
+ build_wheels:
+ name: ${{ matrix.name }}
+ # All-or-nothing: a failed sidecar leg blocks the whole wheel matrix (a publish
+ # needs the complete 4-wheel set anyway).
+ needs: [build_cuda_runtime]
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: "Linux x86_64 wheel with CUDA runtime (manylinux_2_28)"
+ os: ubuntu-latest
+ arch: x86_64
+ build: cp310-manylinux_x86_64
+ include_cuda_runtime: "1"
+ artifact_suffix: linux-x86_64-manylinux_2_28
+ - name: "Linux aarch64 wheel with CUDA runtime (manylinux_2_28)"
+ os: ubuntu-24.04-arm
+ arch: aarch64
+ build: cp310-manylinux_aarch64
+ include_cuda_runtime: "1"
+ artifact_suffix: linux-aarch64-manylinux_2_28
+ - name: "macOS arm64 wheel with Metal"
+ os: macos-14
+ arch: arm64
+ build: cp310-macosx_arm64
+ include_cuda_runtime: "0"
+ artifact_suffix: macos-arm64
+ cmake_defines: "-DTVM_TIRX_USE_METAL=ON"
+ - name: "Windows AMD64 wheel with CUDA runtime"
+ os: windows-2022
+ arch: AMD64
+ build: cp310-win_amd64
+ include_cuda_runtime: "1"
+ artifact_suffix: windows-amd64
+ steps:
+ - name: Checkout source
+ uses: actions/checkout@v6.0.2
+ with:
+ ref: ${{ inputs.tag }}
+ submodules: recursive
+ # Preserve the source history and tags for reproducible release builds.
+ fetch-depth: 0
+ fetch-tags: true
+
+ # Land the sidecar where -DTVM_TIRX_PACKAGE_EXTRA_LIBS / cibuildwheel's /project
+ # mount expects it. Skipped on CPU-only rows (macOS).
+ - name: Download CUDA runtime sidecar
+ if: ${{ matrix.include_cuda_runtime == '1' }}
+ uses: actions/download-artifact@v8.0.1
+ with:
+ name: tirx-cuda-runtime-${{ matrix.arch }}
+ path: build-wheel-cuda/lib
+
+ - name: Build and test TIRx core wheel
+ uses: ./.github/actions/build-wheel-for-publish
+ with:
+ arch: ${{ matrix.arch }}
+ build: ${{ matrix.build }}
+ cmake_defines: ${{ matrix.cmake_defines }}
+ include_cuda_runtime: ${{ matrix.include_cuda_runtime }}
+
+ - name: Upload wheel artifact
+ uses: actions/upload-artifact@v7.0.1
+ with:
+ name: tirx-wheel-${{ matrix.artifact_suffix }}
+ path: wheelhouse/*.whl
+ if-no-files-found: error
+
+ upload_pypi:
+ name: Upload package distributions
+ needs: [build_wheels]
+ if: ${{ inputs.publish_repository != 'none' }}
+ runs-on: ubuntu-latest
+ environment: ${{ inputs.publish_repository }}
+ permissions:
+ id-token: write
+ attestations: write
+ steps:
+ - uses: actions/download-artifact@v8.0.1
+ with:
+ pattern: tirx-wheel-*
+ path: dist
+ merge-multiple: true
+
+ # Print wheel sizes for visibility only. We do not fail on the PyPI 100 MB
+ # limit here -- the publish step's upload would surface that error directly.
+ - name: Print wheel sizes
+ shell: bash
+ run: ls -alh dist/*.whl
+
+ - name: Generate artifact attestation for wheels
+ uses: actions/attest-build-provenance@v4.1.0
+ with:
+ subject-path: dist/*
+
+ - name: Publish package distributions to PyPI
+ if: ${{ inputs.publish_repository == 'pypi' }}
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
+ with:
+ attestations: true
+ verbose: true
diff --git a/ci/jenkins/.gitignore b/ci/jenkins/.gitignore
new file mode 100644
index 0000000000..3d2dbd4b63
--- /dev/null
+++ b/ci/jenkins/.gitignore
@@ -0,0 +1 @@
+/_venv
diff --git a/tests/scripts/task_build_arm.sh b/ci/jenkins/artifacts.py
old mode 100755
new mode 100644
similarity index 66%
copy from tests/scripts/task_build_arm.sh
copy to ci/jenkins/artifacts.py
index cb85fea9ea..7ad2a1287e
--- a/tests/scripts/task_build_arm.sh
+++ b/ci/jenkins/artifacts.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -15,11 +15,18 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+"""Named standalone CI artifacts; uploads expand globs."""
-set -euxo pipefail
+import sys
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+ARTIFACTS = {"wheels": ["dist/*.whl"]}
+
+if __name__ == "__main__":
+ paths = []
+ for name in sys.argv[1:]:
+ if name not in ARTIFACTS:
+ print(f"unknown bundle: {name}", file=sys.stderr)
+ sys.exit(1)
+ paths.extend(ARTIFACTS[name])
+ for p in paths:
+ print(p)
diff --git a/tests/scripts/task_build_arm.sh b/ci/jenkins/docker-images.ini
old mode 100755
new mode 100644
similarity index 77%
copy from tests/scripts/task_build_arm.sh
copy to ci/jenkins/docker-images.ini
index cb85fea9ea..fbd96a1770
--- a/tests/scripts/task_build_arm.sh
+++ b/ci/jenkins/docker-images.ini
@@ -1,4 +1,3 @@
-#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -16,10 +15,9 @@
# specific language governing permissions and limitations
# under the License.
-set -euxo pipefail
-
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+# This data file is read during when Jenkins runs job to determine docker images.
+[jenkins]
+ci_tag: 20260705-142349-cfb98e93
+ci_arm: tlcpack/ci-arm:%(ci_tag)s
+ci_cpu: tlcpack/ci-cpu:%(ci_tag)s
+ci_gpu: tlcpack/ci-gpu:%(ci_tag)s
diff --git a/ci/jenkins/generated/arm_jenkinsfile.groovy b/ci/jenkins/generated/arm_jenkinsfile.groovy
new file mode 100644
index 0000000000..19703571e7
--- /dev/null
+++ b/ci/jenkins/generated/arm_jenkinsfile.groovy
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// Reject untrusted helper edits before allocating nodes or running pipeline steps.
+def helper_source
+try {
+ helper_source = readTrusted('ci/jenkins/generated/common.groovy')
+} catch (Throwable ex) {
+ echo 'Jenkinsfile changes must be pushed to an upstream branch. ' +
+ 'arm/pr-head will fail for these changes; check arm/branch status instead.'
+ throw ex
+}
+ci = evaluate(helper_source)
+ci.start()
+
+stage('Build') {
+ ci.with_node(instance: 'ARM-GRAVITON3-SPOT', retry_instance: 'ARM-GRAVITON3',
+ name: 'BUILD: arm', folder: 'tvm/build-arm', variables: ['PLATFORM=arm']) {
+ ci.docker_init(images.ci_arm)
+ withEnv(ci.build_environment()) {
+ sh(
+ script: """${docker_run} ${images.ci_arm} bash -euo pipefail -c '
+ source ./tests/scripts/task_install_build_dependencies.sh
+ ./tests/scripts/task_build_arm.sh
+ '""",
+ label: 'Build arm wheels and C++ tests',
+ )
+ }
+ ci.upload_artifacts('arm', '--path "dist/*.whl"')
+
+ }
+}
diff --git a/ci/jenkins/generated/common.groovy b/ci/jenkins/generated/common.groovy
new file mode 100644
index 0000000000..f994d6cae3
--- /dev/null
+++ b/ci/jenkins/generated/common.groovy
@@ -0,0 +1,386 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
+
+// ------ Config ------
+// Keep image names aligned with docker-images.ini. Tags are resolved in prepare.
+image_platforms = [ci_arm: 'ARM', ci_cpu: 'CPU', ci_gpu: 'GPU']
+// Resolve Hub inputs through the caller account ECR cache; false keeps public names.
+enable_docker_hub_cache = true
+max_time = 180
+// Temporarily bypass image sccache wrappers and inherited compiler launchers.
+docker_run = 'docker/bash.sh --env CI --env PLATFORM --env TEST_STEP_NAME' +
+ ' --env CC=/usr/bin/gcc --env CXX=/usr/bin/g++' +
+ ' --env CMAKE_C_COMPILER_LAUNCHER= --env CMAKE_CXX_COMPILER_LAUNCHER='
+s3_bucket = 'tvm-jenkins-artifacts-prod'
+jenkins_scripts_root = 'ci/jenkins/scripts'
+
+// ------ Runtime state ------
+images = image_platforms.collectEntries { name, platform -> [(name): ''] }
+source_images = [:]
+upstream_revision = null
+s3_prefix = "tvm/${env.BRANCH_NAME}/${env.BUILD_NUMBER}"
+
+properties([parameters(image_platforms.collect { name, platform ->
+ string(name: "${name}_param", defaultValue: '')
+})])
+
+// Shared utilities; platform Jenkinsfiles own stages, parallel groups and commands.
+
+def per_exec_ws(folder) {
+ return "workspace/exec_${env.EXECUTOR_NUMBER}/" + folder
+}
+
+def update_upstream_revision(git_ref) {
+ if (upstream_revision == null) {
+ upstream_revision = sh(
+ script: "git log -1 ${git_ref} --format=\'%H\'",
+ label: 'Determine upstream revision',
+ returnStdout: true,
+ ).trim()
+ }
+}
+
+def merge_with_target() {
+ def target = env.CHANGE_TARGET
+ sh (
+ script: "git fetch origin ${target}",
+ label: "Fetch target branch ${target}",
+ )
+ update_upstream_revision("FETCH_HEAD")
+ sh (
+ script: "git -c user.name=TVM-Jenkins -c user.email=jenkins@tvm.apache.org merge ${upstream_revision}",
+ label: "Merge to origin/${target}"
+ )
+}
+
+def checkout_trusted_files() {
+ // trust everything from branch builds
+ if (env.BRANCH_NAME == null || !env.BRANCH_NAME.startsWith('PR-')) {
+ return;
+ }
+
+ // Host helpers can access credentials; always use the pinned target version.
+ sh(
+ script: "git checkout ${upstream_revision} ${jenkins_scripts_root}/. ci/jenkins/artifacts.py",
+ label: 'Check out trusted files',
+ )
+}
+
+def init_git() {
+ retry(5) {
+ checkout scm
+ }
+
+ // Add more info about job node
+ sh (
+ script: './ci/jenkins/scripts/show_node_info.sh',
+ label: 'Show executor node info',
+ )
+
+ // Determine merge commit to use for all stages
+ if (env.CHANGE_TARGET) {
+ // This is a PR build, so merge with the latest of the PR's target branch
+ // (e.g. main or a release branch like v0.25.0).
+ merge_with_target()
+ } else {
+ // This is a branch build (main or a release branch). Only set
+ // upstream_revision to HEAD and skip merging to avoid a race with another
+ // commit merged to the branch.
+ update_upstream_revision("HEAD")
+ }
+
+ sh(
+ script: """
+ set -eux
+ . ${jenkins_scripts_root}/retry.sh
+ retry 3 timeout 5m git submodule update --init --recursive -f --jobs 0
+ """,
+ label: 'Update git submodules',
+ )
+ checkout_trusted_files()
+}
+
+// Apply only after Hub selection and job overrides; inputs stay public image names.
+def docker_hub_image(image, cache) {
+ if (!cache || !image) return image
+
+ def path = image
+ if (image.contains('/')) {
+ def host = image.substring(0, image.indexOf('/'))
+ if (host in ['docker.io', 'index.docker.io', 'registry-1.docker.io']) {
+ path = image.substring(image.indexOf('/') + 1)
+ } else if (host.contains('.') || host.contains(':') || host == 'localhost') {
+ return image
+ }
+ }
+ if (!path.contains('/')) path = "library/${path}"
+ return "${cache}/${path}"
+}
+
+def ecr_registry(image) {
+ def registry = image.tokenize('/')[0]
+ return registry ==~ /[0-9]{12}\.dkr\.ecr\.[a-z0-9-]+\.amazonaws\.com(\.cn)?/ ? registry : null
+}
+
+def ecr_pull(full_name) {
+ def registry = ecr_registry(full_name)
+ def region = registry.tokenize('.')[3]
+ withEnv(["AWS_DEFAULT_REGION=${region}", "AWS_ECR_REPO=${registry}"]) {
+ try {
+ sh(
+ script: '''
+ set -eux
+ aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ECR_REPO
+ ''',
+ label: 'Log in to ECR'
+ )
+ sh(
+ script: """
+ set -eux
+ . ${jenkins_scripts_root}/retry.sh
+ retry 5 docker pull ${full_name}
+ """,
+ label: 'Pull image from ECR'
+ )
+ } finally {
+ sh(
+ script: 'docker logout $AWS_ECR_REPO',
+ label: 'Clean up login credentials'
+ )
+ }
+ }
+}
+
+def cancel_previous_build() {
+ // cancel previous build if it is not on main.
+ if (env.BRANCH_NAME != 'main') {
+ def buildNumber = env.BUILD_NUMBER as int
+ // Milestone API allows us to cancel previous build
+ // with the same milestone number
+ if (buildNumber > 1) milestone(buildNumber - 1)
+ milestone(buildNumber)
+ }
+}
+
+def is_last_build() {
+ // check whether it is last build
+ try {
+ return currentBuild.number == currentBuild.rawBuild.project.getLastBuild().number
+ } catch (Throwable ex) {
+ echo 'Error during check is_last_build ' + ex.toString()
+ return false
+ }
+}
+
+def should_skip_ci(pr_number) {
+ if (env.BRANCH_NAME == null || !env.BRANCH_NAME.startsWith('PR-')) {
+ // never skip CI on build sourced from a branch
+ return false
+ }
+ glob_skip_ci_code = sh (
+ returnStatus: true,
+ script: "./${jenkins_scripts_root}/git_skip_ci_globs.py",
+ label: 'Check if CI should be skipped due to changed files',
+ )
+ if (glob_skip_ci_code == 0) {
+ return true
+ }
+ withCredentials([string(
+ credentialsId: 'tvm-bot-jenkins-reader',
+ variable: 'GITHUB_TOKEN',
+ )]) {
+ // Exit code of 1 means run full CI (or the script had an error, so run
+ // full CI just in case). Exit code of 0 means skip CI.
+ git_skip_ci_code = sh (
+ returnStatus: true,
+ script: "./${jenkins_scripts_root}/git_skip_ci.py --pr '${pr_number}'",
+ label: 'Check if CI should be skipped',
+ )
+ }
+ return git_skip_ci_code == 0
+}
+
+def prepare(node_type) {
+ stage('Prepare') {
+ node(node_type) {
+ ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/prepare") {
+ init_git()
+
+ images.keySet().each { name ->
+ images[name] = sh(
+ script: "python3 ${jenkins_scripts_root}/determine_docker_images.py --lookup-only ${name}",
+ returnStdout: true,
+ label: "Read image tag for ${name}",
+ ).trim()
+ }
+ if (env.DETERMINE_DOCKER_IMAGES == 'yes') {
+ sh(
+ script: "./${jenkins_scripts_root}/determine_docker_images.py ${images.keySet().join(' ')}",
+ label: 'Decide whether to use tlcpack or tlcpackstaging for Docker images',
+ )
+ images.keySet().each { name ->
+ images[name] = sh(
+ script: "cat .docker-image-names/${name}",
+ label: "Find docker image name for ${name}",
+ returnStdout: true,
+ ).trim()
+ }
+ }
+ def cache = ''
+ if (enable_docker_hub_cache) {
+ def aws_account_id = sh(
+ returnStdout: true,
+ script: 'aws sts get-caller-identity --query Account --output text',
+ label: 'Get AWS ID'
+ ).trim()
+ cache = "${aws_account_id}.dkr.ecr.us-west-2.amazonaws.com/docker-hub"
+ }
+ images.keySet().each { name ->
+ source_images[name] = params["${name}_param"] ?: images[name]
+ images[name] = docker_hub_image(source_images[name], cache)
+ }
+ sh(
+ script: 'echo "Docker images being used in this build:"\n' +
+ images.collect { name, image -> "echo \" ${name} = ${image}\"" }.join('\n'),
+ label: 'Docker image names',
+ )
+
+ skip_ci = should_skip_ci(env.CHANGE_ID)
+ }
+ }
+ }
+}
+
+def retry_latest(ex, body) {
+ echo 'Exception during SPOT run ' + ex.toString()
+ if (!is_last_build()) {
+ echo 'Exit since it is not last build'
+ throw ex
+ }
+ echo 'Retry on-demand given it is last build'
+ currentBuild.result = 'SUCCESS'
+ // Do not catch failure of the on-demand retry.
+ body()
+}
+
+// Public entry points.
+
+// with_node(instance: 'CPU-SPOT', retry_instance: 'CPU', name: 'Build',
+// folder: 'tvm/build', variables: ['PLATFORM=cpu']) { docker_init(image); ... }
+// name marks skipped stages; folder isolates executor workspaces; variables is optional.
+// Skip before allocation/setup. Each attempt checks out sources, then times the body.
+// Keep docker_init explicit in the body. Omit retry_instance for a single attempt;
+// otherwise failures, including interruptions, retry only for the newest build.
+def with_node(options, body) {
+ if (skip_ci) {
+ Utils.markStageSkippedForConditional(options.name)
+ return
+ }
+ def run = { instance ->
+ node(instance) {
+ ws(per_exec_ws(options.folder)) {
+ init_git()
+ timeout(time: max_time, unit: 'MINUTES') {
+ withEnv(options.variables ?: []) { body() }
+ }
+ }
+ }
+ }
+ try {
+ run(options.instance)
+ } catch (Throwable ex) {
+ if (!options.retry_instance) throw ex
+ // Preserve the original newest-build retry policy, including interruptions.
+ // Failures from the single on-demand attempt propagate without another retry.
+ retry_latest(ex) { run(options.retry_instance) }
+ }
+}
+
+// upload_artifacts('cpu', '--artifact wheels')
+// Or select paths: '--path "build/*.whl"'. Options pass unchanged to s3.py.
+// Registry artifacts and explicit paths are mutually exclusive; repeat one-value flags.
+// Upload globs are sorted/deduplicated; download_artifacts(tag) copies the whole saved prefix.
+def upload_artifacts(tag, options) {
+ sh(
+ script: "./${jenkins_scripts_root}/s3.py --action upload --bucket ${s3_bucket} --prefix ${s3_prefix}/${tag} ${options}",
+ label: 'Upload artifacts to S3',
+ )
+}
+
+def download_artifacts(tag) {
+ sh(
+ script: "./${jenkins_scripts_root}/s3.py --action download --bucket ${s3_bucket} --prefix ${s3_prefix}/${tag}",
+ label: 'Download artifacts from S3',
+ )
+}
+
+def docker_init(image) {
+ // Forget compiler wrappers cached before the temporary sccache bypass.
+ sh 'rm -f build/CMakeCache.txt 3rdparty/tvm-ffi/build/CMakeCache.txt'
+ // Clear out all Docker images that aren't going to be used
+ sh(
+ script: """
+ set -eux
+ docker image ls --all
+ IMAGES=\$(docker image ls --all --format '{{.Repository}}:{{.Tag}} {{.ID}}')
+
+ echo -e "Found images:\\n\$IMAGES"
+ echo "\$IMAGES" | { grep -vE '${image}' || test \$? = 1; } | { xargs docker rmi || test \$? = 123; }
+
+ docker image ls --all
+ """,
+ label: 'Clean old Docker images',
+ )
+
+ if (ecr_registry(image)) {
+ ecr_pull(image)
+ } else {
+ sh(
+ script: """
+ set -eux
+ . ${jenkins_scripts_root}/retry.sh
+ retry 5 docker pull ${image}
+ """,
+ label: 'Pull docker image',
+ )
+ }
+}
+
+// Preparation retries Exceptions unconditionally; Errors and cancellation of the
+// previous build are deliberately outside this fallback.
+def start() {
+ cancel_previous_build()
+ try {
+ prepare('CPU-SMALL-SPOT')
+ } catch (Exception ex) {
+ prepare('CPU-SMALL')
+ }
+}
+
+// Preserve caller limits, otherwise share the node among its executors.
+def build_environment() {
+ def parallel_limit = env.CMAKE_BUILD_PARALLEL_LEVEL ?: sh(
+ script: 'n=$(( $(getconf _NPROCESSORS_ONLN) / ${CI_NUM_EXECUTORS:-1} )); if [ "$n" -lt 1 ]; then n=1; fi; echo "$n"',
+ returnStdout: true,
+ label: 'Determine build parallelism',
+ ).trim()
+ return ["CMAKE_BUILD_PARALLEL_LEVEL=${parallel_limit}"]
+}
+
+return this
diff --git a/ci/jenkins/generated/cpu_jenkinsfile.groovy b/ci/jenkins/generated/cpu_jenkinsfile.groovy
new file mode 100644
index 0000000000..d487846a0b
--- /dev/null
+++ b/ci/jenkins/generated/cpu_jenkinsfile.groovy
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// Reject untrusted helper edits before allocating nodes or running pipeline steps.
+def helper_source
+try {
+ helper_source = readTrusted('ci/jenkins/generated/common.groovy')
+} catch (Throwable ex) {
+ echo 'Jenkinsfile changes must be pushed to an upstream branch. ' +
+ 'cpu/pr-head will fail for these changes; check cpu/branch status instead.'
+ throw ex
+}
+ci = evaluate(helper_source)
+ci.start()
+
+stage('Build') {
+ ci.with_node(instance: 'CPU-SPOT', retry_instance: 'CPU',
+ name: 'BUILD: CPU', folder: 'tvm/build-cpu', variables: ['PLATFORM=cpu']) {
+ ci.docker_init(images.ci_cpu)
+ withEnv(ci.build_environment()) {
+ sh(
+ script: """${docker_run} ${images.ci_cpu} bash -euo pipefail -c '
+ source ./tests/scripts/task_install_build_dependencies.sh
+ ./tests/scripts/task_build_cpu.sh
+ '""",
+ label: 'Build cpu wheels and C++ tests',
+ )
+ }
+ ci.upload_artifacts('cpu', '--path "dist/*.whl"')
+
+ }
+}
+
+stage('Test') {
+ parallel('unittest: CPU': {
+ ci.with_node(instance: 'CPU-SPOT', retry_instance: 'CPU',
+ name: 'unittest: CPU', folder: 'tvm/ut-python-cpu',
+ variables: ['PLATFORM=cpu', 'TEST_STEP_NAME=unittest: CPU']) {
+ ci.docker_init(images.ci_cpu)
+ ci.download_artifacts('cpu')
+ sh (
+ script: """${docker_run} ${images.ci_cpu} bash -euo pipefail -c '
+ source ./tests/scripts/test_task_install_dist_wheels.sh
+ ./tests/scripts/task_python_unittest.sh
+ '""",
+ label: 'Run Python unit tests',
+ )
+ }
+ })
+}
diff --git a/ci/jenkins/generated/gpu_jenkinsfile.groovy b/ci/jenkins/generated/gpu_jenkinsfile.groovy
new file mode 100644
index 0000000000..c5854e010b
--- /dev/null
+++ b/ci/jenkins/generated/gpu_jenkinsfile.groovy
@@ -0,0 +1,144 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// Reject untrusted helper edits before allocating nodes or running pipeline steps.
+def helper_source
+try {
+ helper_source = readTrusted('ci/jenkins/generated/common.groovy')
+} catch (Throwable ex) {
+ echo 'Jenkinsfile changes must be pushed to an upstream branch. ' +
+ 'gpu/pr-head will fail for these changes; check gpu/branch status instead.'
+ throw ex
+}
+ci = evaluate(helper_source)
+ci.start()
+
+stage('Build') {
+ ci.with_node(instance: 'CPU-SPOT', retry_instance: 'CPU',
+ name: 'BUILD: GPU', folder: 'tvm/build-gpu', variables: ['PLATFORM=gpu']) {
+ ci.docker_init(images.ci_gpu)
+ withEnv(ci.build_environment()) {
+ sh(
+ script: """${docker_run} --no-gpu ${images.ci_gpu} bash -euo pipefail -c '
+ source ./tests/scripts/task_install_build_dependencies.sh
+ ./tests/scripts/task_build_gpu.sh
+ '""",
+ label: 'Build gpu',
+ )
+ }
+ ci.upload_artifacts('gpu', '--path "dist/*.whl"')
+
+ // Check the compiler-only GPU configuration after publishing the test build.
+ sh 'rm -rf build'
+ withEnv(ci.build_environment()) {
+ sh(
+ script: "${docker_run} --no-gpu ${images.ci_gpu} ./tests/scripts/task_build_gpu_other.sh",
+ label: 'Build gpu_other',
+ )
+ }
+ }
+}
+
+parallel(
+ 'Test': {
+ stage('Test') {
+ ci.with_node(instance: 'GPU-SPOT', retry_instance: 'GPU',
+ name: 'unittest: GPU', folder: 'tvm/ut-python-gpu',
+ variables: ['PLATFORM=gpu', 'TEST_STEP_NAME=unittest: GPU']) {
+ ci.docker_init(images.ci_gpu)
+ ci.download_artifacts('gpu')
+ sh(
+ script: """${docker_run} ${images.ci_gpu} bash -euo pipefail -c '
+ source ./tests/scripts/test_task_install_dist_wheels.sh
+ ./tests/scripts/task_python_unittest_gpuonly.sh
+ '""",
+ label: 'Run Python GPU unit tests',
+ )
+ }
+ }
+ },
+ 'Docs': {
+ stage('Docs') {
+ ci.with_node(instance: 'CPU-SPOT', retry_instance: 'CPU',
+ name: 'Docs', folder: 'tvm/tirx-docs', variables: ['PLATFORM=gpu']) {
+ ci.docker_init(images.ci_gpu)
+ ci.download_artifacts('gpu')
+ sh(
+ script: "${docker_run} --no-gpu ${images.ci_gpu} ./tests/scripts/task_python_docs.sh",
+ label: 'Build TIRx API documentation',
+ )
+ ci.upload_artifacts('docs', '--path docs.tgz')
+ }
+ }
+ },
+)
+
+stage('Deploy Docs') {
+ if (env.BRANCH_NAME == 'main' && !env.CHANGE_ID && env.DOCS_DEPLOY_ENABLED == 'yes') {
+ ci.with_node(instance: 'CPU', name: 'Deploy Docs', folder: 'tvm/deploy-tirx-docs') {
+ ci.download_artifacts('docs')
+ // Keep credential-bearing deployment in the trusted Jenkinsfile.
+ sh(
+ script: '''
+ set -eu
+ SOURCE_COMMIT=$(git rev-parse HEAD)
+ rm -rf tvm-site
+ git clone --branch asf-site --depth=1 https://github.com/apache/tvm-site.git tvm-site
+ cd tvm-site
+ git log -1 --format='Site base: %H'
+ rm -rf tirx
+ mkdir tirx
+ tar -xzf ../docs.tgz -C tirx
+ test -s tirx/index.html
+ test "$(cat tirx/commit_hash)" = "$SOURCE_COMMIT"
+ git config user.name tvm-bot
+ git config user.email 95660001+tvm-bot@users.noreply.github.com
+ git add -f -- tirx
+ test -z "$(git diff --cached --name-only -- . ':!:tirx')"
+ git diff --cached --shortstat
+ git diff --cached --name-only | sed -n '1,20p'
+ if ! git diff --cached --quiet; then
+ git commit --quiet -m "deploying tirx docs ($(cat tirx/commit_hash))" -- tirx
+ fi
+ git log -1 --format='Docs preview commit: %H'
+ ''',
+ label: 'Update tvm-site/tirx',
+ )
+ withCredentials([string(credentialsId: 'docs-push-token', variable: 'GITHUB_TOKEN')]) {
+ sh(
+ script: '''
+ set +x
+ set -eu
+ cd tvm-site
+ auth=$(printf 'x-access-token:%s' "$GITHUB_TOKEN" | base64 | tr -d '\\n')
+ for attempt in 1 2 3; do
+ if git -c http.extraHeader="Authorization: Basic $auth" push origin HEAD:asf-site; then
+ exit 0
+ fi
+ if [ "$attempt" = 3 ]; then
+ exit 1
+ fi
+ sleep 2
+ git pull --rebase origin asf-site
+ done
+ ''',
+ label: 'Publish TIRx documentation to apache/tvm-site',
+ )
+ }
+ }
+ }
+}
diff --git a/ci/jenkins/scripts/determine_docker_images.py b/ci/jenkins/scripts/determine_docker_images.py
new file mode 100755
index 0000000000..9802ea784f
--- /dev/null
+++ b/ci/jenkins/scripts/determine_docker_images.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python3
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ruff: noqa: E501
+import argparse
+import configparser
+import datetime
+import json
+import logging
+import urllib.error
+from pathlib import Path
+from typing import Any
+
+from http_utils import get
+
+REPO_ROOT = Path(__file__).resolve().parents[3]
+
+DOCKER_API_BASE = "https://hub.docker.com/v2/"
+PAGE_SIZE = 25
+TEST_DATA = None
+IMAGE_TAGS_FILE = REPO_ROOT / "ci" / "jenkins" / "docker-images.ini"
+TVM_CI_ECR = "477529581014.dkr.ecr.us-west-2.amazonaws.com"
+
+
+def docker_api(url: str, use_pagination: bool = False) -> dict[str, Any]:
+ """
+ Run a paginated fetch from the public Docker Hub API
+ """
+ if TEST_DATA is not None:
+ if url not in TEST_DATA:
+ raise urllib.error.HTTPError(url, 404, "Not found", {}, None)
+ return TEST_DATA[url]
+ pagination = ""
+ if use_pagination:
+ pagination = f"?page_size={PAGE_SIZE}&page=1"
+ url = DOCKER_API_BASE + url + pagination
+ r, headers = get(url)
+ reset = headers.get("x-ratelimit-reset")
+ if reset is not None:
+ reset = datetime.datetime.fromtimestamp(int(reset))
+ reset = reset.isoformat()
+ logging.info(
+ f"Docker API Rate Limit: {headers.get('x-ratelimit-remaining')} / {headers.get('x-ratelimit-limit')} (reset at {reset})"
+ )
+ return r
+
+
+def image_exists(spec: str) -> bool:
+ name, tag = spec.split(":")
+ try:
+ r = docker_api(f"repositories/{name}/tags/{tag}")
+ logging.debug(f"Image exists, got response: {json.dumps(r, indent=2)}")
+ return True
+ except urllib.error.HTTPError as e:
+ # Image was not found
+ logging.debug(e)
+ return False
+
+
+def lookup_image_tag(name: str) -> str:
+ """Resolve image ``name`` (e.g. ``ci_cpu``) to its tag string from the ini.
+
+ Pure ini read — no Docker Hub query, no tlcpackstaging fallback. Used by
+ ``docker/bash.sh`` for local-dev image-name shortcuts where the
+ full Hub-existence check is unnecessary.
+ """
+ config = configparser.ConfigParser()
+ config.read(IMAGE_TAGS_FILE)
+ return config.get("jenkins", name)
+
+
+if __name__ == "__main__":
+ logging.basicConfig(
+ format="[%(filename)s:%(lineno)d %(levelname)s] %(message)s", level=logging.INFO
+ )
+ parser = argparse.ArgumentParser(
+ description="Writes out Docker images names to be used to .docker-image-names/"
+ )
+ parser.add_argument(
+ "--lookup-only",
+ metavar="NAME",
+ help="Print the tag for NAME from the ini and exit (no Docker Hub query, no fallback).",
+ )
+ parser.add_argument(
+ "--testing-docker-data",
+ help="(testing only) JSON data to mock response from Docker Hub API",
+ )
+ parser.add_argument(
+ "--testing-images-data",
+ help=f"(testing only) JSON data to mock contents of {IMAGE_TAGS_FILE}",
+ )
+ parser.add_argument(
+ "--base-dir",
+ default=".docker-image-names",
+ help="(testing only) Folder to write image names to",
+ )
+ args, other = parser.parse_known_args()
+
+ if args.lookup_only:
+ print(lookup_image_tag(args.lookup_only))
+ raise SystemExit(0)
+
+ name_dir = Path(args.base_dir)
+
+ if args.testing_images_data:
+ repo_image_tags = json.loads(args.testing_images_data)
+ else:
+ config = configparser.ConfigParser()
+ config.read(IMAGE_TAGS_FILE)
+ repo_image_tags = {}
+ for name in other:
+ repo_image_tags[name] = config.get("jenkins", name)
+
+ images = {}
+ for name in other:
+ images[name] = repo_image_tags[name]
+
+ if args.testing_docker_data is not None:
+ TEST_DATA = json.loads(args.testing_docker_data)
+
+ logging.info(f"Checking if these images exist in tlcpack: {images}")
+
+ name_dir.mkdir(exist_ok=True)
+ images_to_use = {}
+ for filename, spec in images.items():
+ if spec.startswith(TVM_CI_ECR):
+ logging.info(f"{spec} is from ECR")
+ images_to_use[filename] = spec
+ elif image_exists(spec):
+ logging.info(f"{spec} found in tlcpack")
+ images_to_use[filename] = spec
+ else:
+ logging.info(f"{spec} not found in tlcpack, using tlcpackstaging")
+ part, tag = spec.split(":")
+ user, repo = part.split("/")
+ tlcpackstaging_tag = f"tlcpackstaging/{repo.replace('-', '_')}:{tag}"
+ images_to_use[filename] = tlcpackstaging_tag
+
+ for filename, image in images_to_use.items():
+ logging.info(f"Writing image {image} to {name_dir / filename}")
+ with open(name_dir / filename, "w") as f:
+ f.write(image)
diff --git a/ci/jenkins/scripts/git_skip_ci.py b/ci/jenkins/scripts/git_skip_ci.py
new file mode 100755
index 0000000000..f7c84923f9
--- /dev/null
+++ b/ci/jenkins/scripts/git_skip_ci.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import argparse
+import json
+import logging
+import os
+import re
+import subprocess
+from urllib import request
+
+
+def parse_remote(remote: str) -> tuple[str, str]:
+ """
+ Get a GitHub (user, repo) pair out of a git remote
+ """
+ if remote.startswith("https://"):
+ # Parse HTTP remote
+ parts = remote.split("/")
+ if len(parts) < 2:
+ raise RuntimeError(f"Unable to parse remote '{remote}'")
+ user, repo = parts[-2], parts[-1].replace(".git", "")
+ else:
+ # Parse SSH remote
+ m = re.search(r":(.*)/(.*)\.git", remote)
+ if m is None or len(m.groups()) != 2:
+ raise RuntimeError(f"Unable to parse remote '{remote}'")
+ user, repo = m.groups()
+
+ user = os.getenv("DEBUG_USER", user)
+ repo = os.getenv("DEBUG_REPO", repo)
+ return user, repo
+
+
+def git(command, **kwargs):
+ command = ["git", *command]
+ logging.info(f"Running {command}")
+ proc = subprocess.run(command, stdout=subprocess.PIPE, encoding="utf-8", **kwargs)
+ if proc.returncode != 0:
+ raise RuntimeError(f"Command failed {command}:\nstdout:\n{proc.stdout}")
+ return proc.stdout.strip()
+
+
+if __name__ == "__main__":
+ help = "Exits with 0 if CI should be skipped, 1 otherwise"
+ parser = argparse.ArgumentParser(description=help)
+ parser.add_argument("--pr", required=True)
+ parser.add_argument("--remote", default="origin", help="ssh remote to parse")
+ parser.add_argument(
+ "--pr-title", help="(testing) PR title to use instead of fetching from GitHub"
+ )
+ args = parser.parse_args()
+ logging.basicConfig(
+ format="[%(filename)s:%(lineno)d %(levelname)s] %(message)s", level=logging.INFO
+ )
+
+ branch = git(["rev-parse", "--abbrev-ref", "HEAD"])
+ log = git(["log", "--format=%s", "-1"])
+
+ # Check the PR's title (don't check this until everything else passes first)
+ def check_pr_title():
+ remote = git(["config", "--get", f"remote.{args.remote}.url"])
+ user, repo = parse_remote(remote)
+
+ if args.pr_title:
+ title = args.pr_title
+ else:
+ req = request.Request(
+ f"https://api.github.com/repos/{user}/{repo}/pulls/{args.pr}",
+ headers={"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"},
+ )
+ with request.urlopen(req) as response:
+ pr = json.loads(response.read())
+ title = pr["title"]
+ logging.info(f"pr title: {title}")
+ tags = [tag.strip() for tag in re.findall(r"\[(.*?)\]", title)]
+ logging.info(f"Found title tags: {tags}")
+ return "skip ci" in tags
+
+ if args.pr != "null" and args.pr.strip() != "" and branch != "main" and check_pr_title():
+ logging.info("PR title starts with '[skip ci]', skipping...")
+ exit(0)
+ else:
+ logging.info(f"Not skipping CI:\nargs.pr: {args.pr}\nbranch: {branch}\ncommit: {log}")
+ exit(1)
diff --git a/ci/jenkins/scripts/git_skip_ci_globs.py b/ci/jenkins/scripts/git_skip_ci_globs.py
new file mode 100755
index 0000000000..f7fc0860ec
--- /dev/null
+++ b/ci/jenkins/scripts/git_skip_ci_globs.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ruff: noqa: E501
+
+import argparse
+import fnmatch
+
+from git_skip_ci import git
+
+globs = [
+ "*.md",
+ ".github/*",
+ ".asf.yaml",
+ ".gitignore",
+ "LICENSE",
+ "NOTICE",
+ "KEYS",
+ "tests/lint/*",
+ ".pre-commit-config.yaml",
+]
+
+
+def match_any(f: str) -> str | None:
+ for glob in globs:
+ if fnmatch.fnmatch(f, glob):
+ return glob
+ return None
+
+
+if __name__ == "__main__":
+ help = "Exits with code 1 if a change only touched files, indicating that CI could be skipped for this changeset"
+ parser = argparse.ArgumentParser(description=help)
+ parser.add_argument("--files", help="(testing only) comma separated list of files to check")
+ args = parser.parse_args()
+ print(args)
+ if args.files is not None:
+ diff = [x for x in args.files.split(",") if x.strip() != ""]
+ else:
+ diff = git(["diff", "--no-commit-id", "--name-only", "-r", "origin/main"])
+ diff = diff.split("\n")
+ diff = [d.strip() for d in diff]
+ diff = [d for d in diff if d != ""]
+
+ print(f"Changed files:\n{diff}")
+
+ if len(diff) == 0:
+ print("Found no changed files, skipping CI")
+ exit(0)
+
+ print(f"Checking with globs:\n{globs}")
+
+ for file in diff:
+ match = match_any(file)
+ if match is None:
+ print(f"{file} did not match any globs, running CI")
+ exit(1)
+ else:
+ print(f"{file} matched glob {match}")
+
+ print("All files matched a glob, skipping CI")
+ exit(0)
diff --git a/.github/workflows/lint.yml b/ci/jenkins/scripts/http_utils.py
similarity index 60%
copy from .github/workflows/lint.yml
copy to ci/jenkins/scripts/http_utils.py
index a9bff51f3b..05e1b71f24 100644
--- a/.github/workflows/lint.yml
+++ b/ci/jenkins/scripts/http_utils.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -15,27 +16,19 @@
# specific language governing permissions and limitations
# under the License.
-name: Lint
+import json
+import logging
+from typing import Any
+from urllib import request
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
-permissions:
- contents: read
+def get(url: str, headers: dict[str, str] | None = None) -> dict[str, Any]:
+ logging.info(f"Requesting GET to {url}")
+ if headers is None:
+ headers = {}
+ req = request.Request(url, headers=headers)
+ with request.urlopen(req) as response:
+ response_headers = {k: v for k, v in response.getheaders()}
+ response = json.loads(response.read())
-concurrency:
- group: Lint-${{ github.event.pull_request.number || github.sha }}
- cancel-in-progress: true
-
-jobs:
- lint:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6.0.2
- with:
- fetch-depth: 0
- fetch-tags: true
- - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
+ return response, response_headers
diff --git a/tests/scripts/task_build_arm.sh b/ci/jenkins/scripts/retry.sh
old mode 100755
new mode 100644
similarity index 63%
copy from tests/scripts/task_build_arm.sh
copy to ci/jenkins/scripts/retry.sh
index cb85fea9ea..933eb1aba6
--- a/tests/scripts/task_build_arm.sh
+++ b/ci/jenkins/scripts/retry.sh
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
+
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -16,10 +17,23 @@
# specific language governing permissions and limitations
# under the License.
-set -euxo pipefail
+set -eux
+
+retry() {
+ local max_retries=$1
+ shift
+ local n=0
+ until [ "$n" -ge "$max_retries" ]
+ do
+ "$@" && break
+ n=$((n+1))
+ if [ "$n" -eq "$max_retries" ]; then
+ echo "failed to update after attempt $n / $max_retries, giving up"
+ exit 1
+ fi
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+ WAIT=$(python3 -c 'import random; print(random.randint(30, 200))')
+ echo "failed to update $n / $max_retries, waiting $WAIT to try again"
+ sleep "$WAIT"
+ done
+}
diff --git a/ci/jenkins/scripts/s3.py b/ci/jenkins/scripts/s3.py
new file mode 100755
index 0000000000..25ae3f24af
--- /dev/null
+++ b/ci/jenkins/scripts/s3.py
@@ -0,0 +1,243 @@
+#!/usr/bin/env python3
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import argparse
+import glob
+import importlib.util
+import logging
+import re
+import subprocess
+from enum import Enum
+from pathlib import Path
+
+REPO_ROOT = Path(__file__).resolve().parents[3]
+
+ARTIFACTS_PY = REPO_ROOT / "ci" / "jenkins" / "artifacts.py"
+
+
+def load_artifacts():
+ """Load the ARTIFACTS dict from ci/jenkins/artifacts.py."""
+ spec = importlib.util.spec_from_file_location("artifacts", ARTIFACTS_PY)
+ mod = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(mod)
+ return mod.ARTIFACTS
+
+
+def resolve_artifacts(artifact_names: list[str]) -> list[str]:
+ """Resolve a list of artifact names to a flat list of file paths."""
+ artifacts = load_artifacts()
+ items = []
+ for name in artifact_names:
+ if name not in artifacts:
+ known = list(artifacts.keys())
+ logging.error(f"Unknown artifact '{name}'. Known artifacts: {known}")
+ raise SystemExit(1)
+ items.extend(artifacts[name])
+ return items
+
+
+def resolve_upload_items(items: list[str]) -> list[str]:
+ """Expand local artifact patterns once, preserving literal path handling."""
+ paths = set()
+ for item in items:
+ path = Path(item)
+ if glob.has_magic(item):
+ matches = glob.glob(item, root_dir=REPO_ROOT, recursive=True)
+ if not matches:
+ logging.warning("No artifacts matched pattern: %s", item)
+ paths.update(Path(match).as_posix() for match in matches)
+ else:
+ # Keep missing literal paths for the existing optional-artifact warning.
+ paths.add(path.as_posix())
+ directories = {Path(path) for path in paths if Path(path).is_dir()}
+ # Recursive directory copies already include descendants selected by other
+ # entries or overlapping patterns. Transfer each destination only once.
+ return sorted(
+ path for path in paths if not any(parent in directories for parent in Path(path).parents)
+ )
+
+
+RETRY_SCRIPT = REPO_ROOT / "ci" / "jenkins" / "scripts" / "retry.sh"
+S3_DOWNLOAD_REGEX = re.compile(r"download: s3://.* to (.*)")
+
+
+class Action(Enum):
+ UPLOAD = 1
+ DOWNLOAD = 2
+
+
+def show_md5(item: str) -> None:
+ if not Path(item).is_dir():
+ subprocess.run(["md5sum", item], check=True)
+
+
+def parse_output_files(stdout: str) -> list[str]:
+ """
+ Grab the list of downloaded files from the output of 'aws s3 cp'. Lines look
+ like:
+
+ download: s3://some/prefix/a_file.txt to a_file.txt
+ """
+ files = []
+ for line in stdout.split("\n"):
+ line = line.strip()
+ if line == "":
+ continue
+ m = S3_DOWNLOAD_REGEX.match(line)
+ if m:
+ files.append(m.groups()[0])
+
+ return files
+
+
+def chmod(files: list[str]) -> None:
+ """
+ S3 has no concept of file permissions so add them back in here to every file
+ """
+ # Add execute bit for downloads
+ to_chmod = [str(f) for f in files]
+ logging.info(f"Adding execute bit for files: {to_chmod}")
+ if len(to_chmod) > 0:
+ subprocess.run(["chmod", "+x", *to_chmod], check=True)
+
+
+def s3(source: str, destination: str, recursive: bool) -> list[str]:
+ """
+ Send or download the source to the destination in S3
+ """
+ # Retry each transfer independently; retain retry.sh's bounded random backoff.
+ command = [
+ "bash",
+ "-c",
+ '. "$1"; shift; retry 3 "$@"',
+ "s3",
+ str(RETRY_SCRIPT),
+ "aws",
+ "s3",
+ "cp",
+ "--no-progress",
+ ]
+ if recursive:
+ command.append("--recursive")
+ command.extend([source, destination])
+ logging.info("Copying %s to %s", source, destination)
+ with subprocess.Popen(command, stdout=subprocess.PIPE, text=True) as process:
+ output = []
+ for line in process.stdout:
+ print(line, end="", flush=True)
+ output.append(line)
+ stdout = "".join(output)
+ if process.wait():
+ raise subprocess.CalledProcessError(process.returncode, command, stdout)
+ return stdout
+
+
+if __name__ == "__main__":
+ logging.basicConfig(
+ format="[%(filename)s:%(lineno)d %(levelname)s] %(message)s", level=logging.INFO
+ )
+ help = "Uploads or downloads files from S3"
+ parser = argparse.ArgumentParser(description=help)
+ parser.add_argument("--action", help="either 'upload' or 'download'", required=True)
+ parser.add_argument("--bucket", help="s3 bucket", required=True)
+ parser.add_argument(
+ "--prefix", help="s3 bucket + tag (e.g. s3://tvm-ci-prod/PR-1234/cpu", required=True
+ )
+ parser.add_argument(
+ "--path",
+ dest="paths",
+ action="append",
+ help="repository-relative file, folder or upload glob pattern (repeatable)",
+ metavar="PATH",
+ )
+ parser.add_argument(
+ "--artifact",
+ "--bundle",
+ dest="artifacts",
+ action="append",
+ help="artifact name from ci/jenkins/artifacts.py (repeatable)",
+ metavar="NAME",
+ )
+ # Legacy --items accepts several paths and retains the last occurrence.
+ parser.add_argument("--items", nargs="+", help="files and folders to transfer")
+
+ args = parser.parse_args()
+ if args.artifacts is not None and (args.paths is not None or args.items is not None):
+ parser.error("--artifact/--bundle and --path/--items are mutually exclusive")
+
+ logging.info(args)
+
+ if Path.cwd() != REPO_ROOT:
+ logging.error(f"s3.py can only be executed from the repo root, instead was in {Path.cwd()}")
+ exit(1)
+
+ prefix = args.prefix.strip("/")
+ s3_path = f"s3://{args.bucket}/{prefix}"
+ logging.info(f"Using s3 path: {s3_path}")
+
+ if args.action == "upload":
+ action = Action.UPLOAD
+ elif args.action == "download":
+ action = Action.DOWNLOAD
+ else:
+ logging.error(f"Unsupported action: {args.action}")
+ exit(1)
+
+ if args.artifacts is not None:
+ items = resolve_artifacts(args.artifacts)
+ elif args.paths is not None or args.items is not None:
+ items = (args.paths or []) + (args.items or [])
+ else:
+ if args.action == "upload":
+ logging.error("Cannot upload without --path or --artifact")
+ exit(1)
+ else:
+ # Download the whole prefix
+ items = ["."]
+
+ if action == Action.UPLOAD:
+ items = resolve_upload_items(items)
+
+ for item in items:
+ if action == Action.DOWNLOAD:
+ source = s3_path
+ recursive = True
+ if item != ".":
+ source = s3_path + "/" + item
+ recursive = False
+ try:
+ stdout = s3(source=source, destination=item, recursive=recursive)
+ except Exception:
+ # Optional artifacts (e.g. per-backend device runtime DSOs) may not
+ # exist in S3 when the build config didn't produce them. Skip silently.
+ logging.warning(f"Download failed for {item}, skipping (may be optional)")
+ continue
+ files = parse_output_files(stdout)
+ chmod(files)
+ for file in files:
+ # Show md5 after downloading
+ show_md5(file)
+ elif action == Action.UPLOAD:
+ if not Path(item).exists():
+ logging.warning(f"The path doesn't exist: {item}")
+ continue
+ show_md5(item)
+ if Path(item).is_dir():
+ if len(list(Path(item).glob("**/*"))) == 0:
+ raise RuntimeError(f"Cannot upload empty folder with name: {item}")
+ s3(item, s3_path + "/" + item, recursive=Path(item).is_dir())
diff --git a/tests/scripts/task_build_arm.sh b/ci/jenkins/scripts/show_node_info.sh
similarity index 55%
copy from tests/scripts/task_build_arm.sh
copy to ci/jenkins/scripts/show_node_info.sh
index cb85fea9ea..af095ed453 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/ci/jenkins/scripts/show_node_info.sh
@@ -18,8 +18,27 @@
set -euxo pipefail
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+echo "===== JENKINS INFO ====="
+echo "NODE_NAME=$NODE_NAME"
+echo "EXECUTOR_NUMBER=$EXECUTOR_NUMBER"
+echo "WORKSPACE=$WORKSPACE"
+echo "BUILD_NUMBER=$BUILD_NUMBER"
+echo "WORKSPACE=$WORKSPACE"
+
+echo "===== EC2 INFO ====="
+function ec2_metadata() {
+ # See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html
+ curl -w '\n' -fsSL "http://169.254.169.254/latest/meta-data/$1" || echo failed
+}
+
+ec2_metadata ami-id
+ec2_metadata instance-id
+ec2_metadata instance-type
+ec2_metadata hostname
+ec2_metadata public-hostname
+
+echo "===== RUNNER INFO ====="
+df --human-readable
+lscpu
+free
+nvidia-smi 2>/dev/null || echo "CUDA not found"
diff --git a/.github/workflows/lint.yml b/ci/wheel/build-environment.yaml
similarity index 51%
copy from .github/workflows/lint.yml
copy to ci/wheel/build-environment.yaml
index a9bff51f3b..3b2c4dd167 100644
--- a/.github/workflows/lint.yml
+++ b/ci/wheel/build-environment.yaml
@@ -11,31 +11,32 @@
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
+# KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
-name: Lint
+# Build environment for TVM wheel building.
+# This environment provides the necessary dependencies for building TVM wheels.
+name: tvm-wheel-build
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
+# The conda channels to lookup the dependencies
+channels:
+ - conda-forge
-permissions:
- contents: read
-
-concurrency:
- group: Lint-${{ github.event.pull_request.number || github.sha }}
- cancel-in-progress: true
-
-jobs:
- lint:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6.0.2
- with:
- fetch-depth: 0
- fetch-tags: true
- - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
+# The packages to install to the environment
+dependencies:
+ # Core build tools
+ - cmake >=3.24
+ - ninja
+ - make
+ - llvmdev >=11
+ - python >=3.10
+ - pip
+ - git
+ - bzip2
+ - zlib
+ - zstd-static
+ - pytest
+ - numpy
+ - scipy
+ - cython
+ - libxml2-devel
diff --git a/ci/wheel/manylinux_build_libtvm_runtime_cuda.sh b/ci/wheel/manylinux_build_libtvm_runtime_cuda.sh
new file mode 100755
index 0000000000..7701a12f13
--- /dev/null
+++ b/ci/wheel/manylinux_build_libtvm_runtime_cuda.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Build libtvm_runtime_cuda.so inside a manylinux CUDA container, run by the
+# build_cuda_runtime CI job. The official quay.io/manylinux_cuda images ship
+# the CUDA toolkit preinstalled under /usr/local/cuda, but omit the libcuda
+# driver stub, so we install just cuda-driver-devel from the image's CUDA repo.
+# Builds the sidecar into build-wheel-cuda/lib/ for the wheel build to bundle.
+#
+# Usage: manylinux_build_libtvm_runtime_cuda.sh
+set -euxo pipefail
+
+repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
+build_dir="${repo_root}/build-wheel-cuda"
+parallel="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 4)"
+
+# The image ships the toolkit but not the libcuda driver stub; install it from
+# the image's CUDA repo so the sidecar links libcuda.so.1 (sync version with tag).
+dnf -y install cuda-driver-devel-13-1
+
+# Build the CUDA runtime sidecar with CUDA on and LLVM off, so it does not need
+# the LLVM prefix; the main CPU wheel links LLVM statically. The manylinux CUDA
+# image already ships cmake and make, and the build uses the default Makefiles
+# generator (no Ninja), so no build tools are installed here. Put the bundled
+# CPython and CUDA toolchain on PATH for the CMake configure and nvcc.
+export PATH="/opt/python/cp310-cp310/bin:/usr/local/cuda/bin:${PATH}"
+python -m pip install "apache-tvm-ffi>=0.1.15rc0"
+nvcc --version
+
+rm -rf "${build_dir}"
+# CMAKE_CUDA_COMPILER only tells CMake which nvcc to use; it does not affect the
+# resulting libtvm_runtime_cuda.so, which is built only from .cc host sources (no
+# .cu device code, so nvcc is never invoked for it). CMAKE_CUDA_ARCHITECTURES is
+# intentionally not set: it would be a no-op here for the same reason (verified --
+# the .so is byte-identical across arch values and carries no device code), and
+# modern CMake fills in a default so configure does not fail without it.
+cmake -S "${repo_root}" -B "${build_dir}" \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DTVM_TIRX_BUILD_TESTS=OFF \
+ -DTVM_TIRX_BUILD_PYTHON_MODULE=ON \
+ -DTVM_TIRX_USE_CUDA=/usr/local/cuda \
+ -DTVM_TIRX_USE_LLVM=OFF \
+ -DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc
+cmake --build "${build_dir}" --target tvm_runtime tvm_runtime_cuda --parallel "${parallel}"
+
+cuda_lib="${build_dir}/lib/libtvm_runtime_cuda.so"
+test -f "${cuda_lib}"
+patchelf --set-rpath '$ORIGIN' "${cuda_lib}"
+echo "CUDA runtime: ${cuda_lib}"
diff --git a/ci/wheel/windows_build_libtvm_runtime_cuda.bat b/ci/wheel/windows_build_libtvm_runtime_cuda.bat
new file mode 100644
index 0000000000..d4fa9f38e9
--- /dev/null
+++ b/ci/wheel/windows_build_libtvm_runtime_cuda.bat
@@ -0,0 +1,99 @@
+@echo off
+rem Licensed to the Apache Software Foundation (ASF) under one
+rem or more contributor license agreements. See the NOTICE file
+rem distributed with this work for additional information
+rem regarding copyright ownership. The ASF licenses this file
+rem to you under the Apache License, Version 2.0 (the
+rem "License"); you may not use this file except in compliance
+rem with the License. You may obtain a copy of the License at
+rem
+rem http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing,
+rem software distributed under the License is distributed on an
+rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem KIND, either express or implied. See the License for the
+rem specific language governing permissions and limitations
+rem under the License.
+rem
+rem Build tvm_runtime_cuda.dll on a Windows runner, run by the build_cuda_runtime
+rem CI job (on the host; unlike Linux there is no build container on Windows).
+rem Installs the pinned CUDA toolkit via conda and builds the sidecar into
+rem build-wheel-cuda\lib\ for the wheel build to bundle. Windows mirror of
+rem manylinux_build_libtvm_runtime_cuda.sh. Run with: shell: cmd.
+setlocal enableextensions
+
+rem repo root = this script's directory / ..\.. (native Windows paths; no cygpath).
+pushd "%~dp0..\.." || exit /b 1
+set "repo_root=%CD%"
+popd
+set "build_dir=%repo_root%\build-wheel-cuda"
+set "cuda_prefix=C:\opt\cuda"
+
+rem Locate conda: the runner ships Miniconda (exposed via %CONDA%) but it may not be
+rem on PATH in this shell.
+set "conda_exe=conda"
+where conda >nul 2>nul || set "conda_exe=%CONDA%\Scripts\conda.exe"
+
+rem Install the pinned CUDA toolkit via conda from the nvidia channel, mirroring the
+rem LLVM-via-conda install used elsewhere. The win-64 channel caps at 13.0.x, so this
+rem pins 13.0.2 -- slightly behind the Linux image's CUDA 13.1, which is harmless: the
+rem sidecar has no device code and links the CUDA runtime by soname only. The nvidia
+rem CDN occasionally returns a transient HTTP 5xx, so retry once; a half-finished first
+rem attempt can leave the prefix partially populated, so wipe it before retrying.
+if not exist "%cuda_prefix%\Library\bin\nvcc.exe" (
+ call "%conda_exe%" create -q -p "%cuda_prefix%" -c nvidia/label/cuda-13.0.2 cuda-toolkit -y
+ if errorlevel 1 (
+ if exist "%cuda_prefix%" rmdir /s /q "%cuda_prefix%"
+ call "%conda_exe%" create -q -p "%cuda_prefix%" -c nvidia/label/cuda-13.0.2 cuda-toolkit -y || exit /b 1
+ )
+)
+
+rem conda lays the Windows toolkit out under <prefix>\Library (bin\nvcc.exe,
+rem lib\x64\cudart.lib, include\...). Discover the root from nvcc.exe so TVM's
+rem FindCUDA MSVC branch resolves against the real layout instead of a hardcode.
+set "nvcc_exe="
+for /f "delims=" %%i in ('dir /s /b "%cuda_prefix%\nvcc.exe" 2^>nul') do if not defined nvcc_exe set "nvcc_exe=%%i"
+if not defined nvcc_exe ( echo nvcc.exe not found under %cuda_prefix% & exit /b 1 )
+rem cuda_root = dirname(dirname(nvcc)) = <prefix>\Library
+for %%i in ("%nvcc_exe%") do set "nvcc_bin=%%~dpi"
+pushd "%nvcc_bin%.." || exit /b 1
+set "cuda_root=%CD%"
+popd
+set "CUDA_PATH=%cuda_root%"
+
+python -m pip install -U pip cmake ninja "apache-tvm-ffi>=0.1.15rc0" || exit /b 1
+"%nvcc_exe%" --version || exit /b 1
+
+rem nvcc needs the MSVC host compiler (cl.exe), so locate VS via vswhere and run the
+rem cmake configure+build inside vcvars64 (this shell is not a VS Developer prompt).
+set "vswhere=C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
+set "vs_path="
+for /f "usebackq delims=" %%i in (`"%vswhere%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "vs_path=%%i"
+if not defined vs_path ( echo Visual Studio with VC tools not found & exit /b 1 )
+set "vcvars=%vs_path%\VC\Auxiliary\Build\vcvars64.bat"
+
+if exist "%build_dir%" rmdir /s /q "%build_dir%"
+
+rem CMAKE_CUDA_COMPILER only tells CMake which nvcc to use (load-bearing: the conda
+rem nvcc is not on PATH); it does not affect the resulting tvm_runtime_cuda.dll, which
+rem is built only from .cc host sources (no .cu device code). CMAKE_CUDA_ARCHITECTURES
+rem is intentionally not set -- a no-op for the same reason, and modern CMake fills a
+rem default. -allow-unsupported-compiler guards against the runner's MSVC being newer
+rem than the CUDA toolkit officially supports. The cmake command is kept on one line:
+rem `^` continuations in a batch file break on any trailing whitespace.
+rem CMake parses backslashes in string values as escapes (e.g. C:\opt -> invalid \o),
+rem so hand cmake forward-slash paths. cmd builtins (rmdir / if exist) keep backslashes.
+set "repo_root_fwd=%repo_root:\=/%"
+set "build_dir_fwd=%build_dir:\=/%"
+set "cuda_root_fwd=%cuda_root:\=/%"
+set "nvcc_fwd=%nvcc_exe:\=/%"
+
+call "%vcvars%" || exit /b 1
+cmake -S "%repo_root_fwd%" -B "%build_dir_fwd%" -G Ninja -DCMAKE_BUILD_TYPE=Release -DTVM_TIRX_BUILD_TESTS=OFF -DTVM_TIRX_BUILD_PYTHON_MODULE=ON -DTVM_TIRX_USE_CUDA="%cuda_root_fwd%" -DTVM_TIRX_USE_LLVM=OFF -DCMAKE_CUDA_COMPILER="%nvcc_fwd%" -DCMAKE_CUDA_FLAGS="-allow-unsupported-compiler" || exit /b 1
+cmake --build "%build_dir_fwd%" --target tvm_runtime tvm_runtime_cuda --config Release || exit /b 1
+
+if not exist "%build_dir%\lib\tvm_runtime_cuda.dll" ( echo tvm_runtime_cuda.dll was not produced & exit /b 1 )
+rem No patchelf/rpath step on Windows; delvewheel vendors dependencies at repair time.
+echo CUDA runtime: %build_dir%\lib\tvm_runtime_cuda.dll
+endlocal
diff --git a/docker/bash.sh b/docker/bash.sh
new file mode 100755
index 0000000000..ccd79a6379
--- /dev/null
+++ b/docker/bash.sh
@@ -0,0 +1,669 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+#
+# Start a bash, mount REPO_MOUNT_POINT to be current directory.
+#
+# Usage: docker/bash.sh [-i|--interactive] [--net=host] [-t|--tty]
+# [--shell SHELL] [--mount MOUNT_DIR]
+# [--repo-mount-point REPO_MOUNT_POINT]
+# [--dry-run] [--name NAME] [--privileged]
+# <DOCKER_IMAGE_NAME> [--] [COMMAND]
+#
+# Usage: docker/bash.sh <CONTAINER_NAME>
+# Starts an interactive session
+#
+# Usage2: docker/bash.sh [-i] <CONTAINER_NAME> [COMMAND]
+# Execute command in the docker image, default non-interactive
+# With -i, execute interactively.
+#
+
+set -euo pipefail
+
+##############################################
+### Section 1: Constants and defaults ###
+##############################################
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
+REPO_DIR="$(dirname "${SCRIPT_DIR}")"
+
+DRY_RUN=false
+INTERACTIVE=false
+TTY=false
+USE_NET_HOST=false
+USE_GPU=true
+DOCKER_IMAGE_NAME=
+COMMAND=bash
+MOUNT_DIRS=( )
+CONTAINER_NAME=
+USER_SHELL=
+
+# TODO(Lunderberg): Remove this if statement and always set to
+# "${REPO_DIR}". The consistent directory for Jenkins is currently
+# necessary to allow CMake build commands to run in CI after the build
+# steps.
+# TODO(https://github.com/apache/tvm/issues/11952):
+# Figure out a better way to keep the same path
+# between build and testing stages.
+if [[ -n "${JENKINS_HOME:-}" ]]; then
+ REPO_MOUNT_POINT=/workspace
+else
+ REPO_MOUNT_POINT="${REPO_DIR}"
+fi
+
+##############################################
+### Section 2: Helper functions ###
+##############################################
+
+function show_usage() {
+ cat <<EOF
+Usage: docker/bash.sh [-i|--interactive] [--net=host] [-t|--tty]
+ [--shell SHELL] [--cpus NUM_CPUS] [--mount MOUNT_DIR]
+ [--repo-mount-point REPO_MOUNT_POINT]
+ [--dry-run] [--name NAME]
+ <DOCKER_IMAGE_NAME> [--] [COMMAND]
+
+
+-h, --help
+
+ Display this help message.
+
+-i, --interactive
+
+ Start the docker session in interactive mode.
+
+-t, --tty
+
+ Start the docker session with a pseudo terminal (tty).
+
+--shell SHELL
+
+ Specify a shell (e.g. --shell zsh) to use instead of bash
+ when entering auto-interactive mode (no command or command
+ is "bash").
+
+--cpus NUM_CPUS
+
+ Limit the number of CPU cores to be used.
+
+--net=host
+
+ Expose servers run into the container to the host, passing the
+ "--net=host" argument through to docker. On MacOS, this is
+ instead passed as "-p 8888:8888" since the host networking driver
+ isn't supported.
+
+--mount MOUNT_DIR
+
+ Expose MOUNT_DIR as an additional mount point inside the docker
+ container. The mount point inside the container is the same as
+ the folder location outside the container. This option can be
+ specified multiple times.
+
+--repo-mount-point REPO_MOUNT_POINT
+
+ The directory inside the docker container at which the TVM
+ repository should be mounted, and is used as the workspace inside
+ the docker container.
+
+ If unspecified, the mount location depends on the environment. If
+ running inside Jenkins, the mount location will be /workspace.
+ Otherwise, the mount location of the repository will be the same
+ as the external location of the repository, to maintain
+ compatibility with git-worktree.
+
+--no-gpu
+
+ Do not use GPU device drivers even if using an CUDA Docker image
+
+--dry-run
+
+ Print the docker command to be run, but do not execute it.
+
+--build-dir BUILD_DIR
+
+ The build directory of TVM. This is appended to LD_LIBRARY_PATH
+
+--env
+
+ Pass an environment variable through to the container.
+
+--name
+
+ Set the name of the docker container, and the hostname that will
+ appear inside the container.
+
+--privileged
+
+ Give extended privileges to this container.
+
+DOCKER_IMAGE_NAME
+
+ The name of the docker container to be run. This can be an
+ explicit name of a docker image (e.g. "tlcpack/ci-gpu:v0.76") or
+ can be a shortcut as defined in the TVM Jenkinsfile
+ (e.g. "ci_gpu").
+
+COMMAND
+
+ The command to be run inside the docker container. If this is set
+ to "bash", the --interactive, --tty and --net=host flags are set.
+ If no command is specified, defaults to "bash". If the command
+ contains dash-prefixed arguments, the command should be preceded
+ by -- to indicate arguments that are not intended for bash.sh.
+
+Environment Variables:
+
+TVM_DEV_DOCKER_MOUNTS
+
+ Space-separated list of additional mount specifications.
+ Each entry is either:
+ /path/to/dir - bind mount at same path inside container
+ /src:/dst - bind mount src to dst inside container
+ Source paths are validated; missing sources are skipped with a warning.
+
+EOF
+}
+
+function parse_error() {
+ echo "$@" >&2
+ show_usage >&2
+ exit 1
+}
+
+# Detect if Docker daemon is running in rootless mode.
+# Uses DOCKER_IS_ROOTLESS env var as override (for CI), otherwise auto-detects.
+# Result is cached after first call.
+_ROOTLESS_CACHED=
+_ROOTLESS_RESULT=1
+function detect_rootless() {
+ if [ -n "${_ROOTLESS_CACHED}" ]; then
+ return $_ROOTLESS_RESULT
+ fi
+ _ROOTLESS_CACHED=1
+ if [ -n "${DOCKER_IS_ROOTLESS:-}" ]; then
+ # env var override for CI
+ _ROOTLESS_RESULT=0
+ return 0
+ fi
+ if docker info -f '{{.SecurityOptions}}' 2>/dev/null | grep -q "rootless"; then
+ _ROOTLESS_RESULT=0
+ return 0
+ fi
+ _ROOTLESS_RESULT=1
+ return 1
+}
+
+# Validate a mount source path exists, warn if missing.
+# Usage: validate_mount /path/to/source
+# Returns 0 if source exists, 1 if missing.
+function validate_mount() {
+ local src="$1"
+ if [ -e "$src" ]; then
+ return 0
+ else
+ echo "Warning: Mount source '$src' not found on host, skipping." >&2
+ return 1
+ fi
+}
+
+
+##############################################
+### Section 3: Argument parsing ###
+##############################################
+
+# Handle joined flags, such as interpreting -ih as -i -h. Either rewrites
+# the current argument if it is a joined argument, or shifts all arguments
+# otherwise. Should be called as "eval $break_joined_flag" where joined
+# flags are possible. Can't use a function definition, because it needs
+# to overwrite the parent scope's behavior.
+break_joined_flag='if (( ${#1} == 2 )); then shift; else set -- -"${1#-i}" "${@:2}"; fi'
+
+DOCKER_ENV=( )
+# Forward build settings selected by the caller without overriding explicit values.
+BUILD_ENV_VARS=(SCCACHE_BUCKET SCCACHE_REGION CMAKE_BUILD_PARALLEL_LEVEL
+ CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER)
+for build_var in "${BUILD_ENV_VARS[@]}"; do
+ if [ "${!build_var+x}" = "x" ]; then
+ DOCKER_ENV+=( --env "$build_var=${!build_var}" )
+ fi
+done
+DOCKER_FLAGS=( )
+
+while (( $# )); do
+ case "$1" in
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+
+ -i*|--interactive)
+ INTERACTIVE=true
+ eval $break_joined_flag
+ ;;
+
+ -t*|--tty)
+ TTY=true
+ if [[ "$1" == "--tty" ]]; then
+ shift
+ else
+ # Short form: -t or combined like -th
+ eval $break_joined_flag
+ fi
+ ;;
+
+ --shell)
+ if (( $# >= 2 )) && [[ -n "$2" ]]; then
+ USER_SHELL="$2"
+ shift 2
+ else
+ parse_error 'ERROR: --shell requires a non-empty argument'
+ fi
+ ;;
+
+ --cpus)
+ DOCKER_FLAGS+=(--cpus "$2")
+ shift 2
+ ;;
+
+ --net=host)
+ USE_NET_HOST=true
+ shift
+ ;;
+
+ --net)
+ DOCKER_FLAGS+=( --net "$2" )
+ shift 2
+ ;;
+
+ --mount)
+ if [[ -n "$2" ]]; then
+ MOUNT_DIRS+=("$2")
+ shift 2
+ else
+ parse_error 'ERROR: --mount requires a non-empty argument'
+ fi
+ ;;
+
+ --mount=?*)
+ MOUNT_DIRS+=("${1#*=}")
+ shift
+ ;;
+
+ --name)
+ if [[ -n "$2" ]]; then
+ CONTAINER_NAME="$2"
+ shift 2
+ else
+ parse_error 'ERROR: --name requires a non empty argument'
+ fi
+ ;;
+
+ --privileged)
+ DOCKER_FLAGS+=( "--privileged" )
+ shift 1
+ ;;
+
+ --env)
+ DOCKER_ENV+=( --env "$2" )
+ shift 2
+ ;;
+
+ --volume)
+ DOCKER_FLAGS+=( --volume "$2" )
+ shift 2
+ ;;
+
+ -e)
+ DOCKER_ENV+=( --env "$2" )
+ shift 2
+ ;;
+
+ -v)
+ DOCKER_FLAGS+=( --volume "$2" )
+ shift 2
+ ;;
+
+ --dry-run)
+ DRY_RUN=true
+ shift
+ ;;
+
+ --no-gpu)
+ USE_GPU=false
+ shift
+ ;;
+
+ --repo-mount-point)
+ if [[ -n "$2" ]]; then
+ REPO_MOUNT_POINT="$2"
+ shift 2
+ else
+ parse_error 'ERROR: --repo-mount-point requires a non-empty argument'
+ fi
+ ;;
+
+ --repo-mount-point=?*)
+ REPO_MOUNT_POINT="${1#*=}"
+ shift
+ ;;
+
+ --build-dir)
+ DOCKER_ENV+=( --env LD_LIBRARY_PATH=${REPO_MOUNT_POINT}/${2})
+ shift 2
+ ;;
+
+ --)
+ shift
+ COMMAND=( "$@" )
+ break
+ ;;
+
+ -*|--*)
+ echo "Error: Unknown flag: $1" >&2
+ echo " If this flag is intended to be passed to the" >&2
+ echo " docker command, please add -- before the docker" >&2
+ echo " command (e.g. docker/bash.sh ci_gpu -- build -j2)" >&2
+ show_usage >&2
+ exit 1
+ ;;
+
+ *)
+ # First positional argument is the image name, all
+ # remaining below to the COMMAND.
+ if [[ -z "${DOCKER_IMAGE_NAME}" ]]; then
+ DOCKER_IMAGE_NAME=$1
+ shift
+ else
+ COMMAND=( "$@" )
+ break
+ fi
+ ;;
+ esac
+done
+
+if [[ -z "${DOCKER_IMAGE_NAME}" ]]; then
+ echo "Error: Missing DOCKER_IMAGE_NAME" >&2
+ show_usage >&2
+fi
+
+# Smart defaults: "bash" command triggers interactive mode
+if [[ ${COMMAND[@]+"${COMMAND[@]}"} = bash ]]; then
+ INTERACTIVE=true
+ TTY=true
+fi
+
+
+##############################################
+### Section 4: Image resolution ###
+##############################################
+
+function lookup_image_spec() {
+ local image_spec
+ image_spec=$(python3 "${REPO_DIR}/ci/jenkins/scripts/determine_docker_images.py" \
+ --lookup-only "$1" 2>/dev/null) || return 0
+ printf '%s\n' "$image_spec"
+}
+
+DOCKER_MOUNT=( )
+DOCKER_DEVICES=( )
+# If the user gave a shortcut defined in the Jenkinsfile, use it.
+EXPANDED_SHORTCUT=$(lookup_image_spec "${DOCKER_IMAGE_NAME}")
+if [ -n "${EXPANDED_SHORTCUT}" ]; then
+ if [ "${CI+x}" == "x" ]; then
+ DOCKER_IMAGE_NAME="${EXPANDED_SHORTCUT}"
+ else
+ python3 "${REPO_DIR}/ci/jenkins/scripts/determine_docker_images.py" \
+ --base-dir "${REPO_DIR}/.docker-image-names" "$DOCKER_IMAGE_NAME" 2> /dev/null
+ DOCKER_IMAGE_NAME=$(cat "${REPO_DIR}/.docker-image-names/$DOCKER_IMAGE_NAME")
+ if [[ "$DOCKER_IMAGE_NAME" == *"tlcpackstaging"* ]]; then
+ echo "WARNING: resolved docker image to fallback tag in tlcpackstaging" >&2
+ fi
+ fi
+fi
+
+
+##############################################
+### Section 5: Mount construction ###
+##############################################
+
+# Working directories
+DOCKER_FLAGS+=( --workdir "${REPO_MOUNT_POINT}" )
+DOCKER_MOUNT+=( --volume "${REPO_DIR}":"${REPO_MOUNT_POINT}"
+ )
+
+# Expose external directories from --mount flags
+for MOUNT_DIR in ${MOUNT_DIRS[@]+"${MOUNT_DIRS[@]}"}; do
+ DOCKER_MOUNT+=( --volume "${MOUNT_DIR}:${MOUNT_DIR}" )
+done
+
+# Parse TVM_DEV_DOCKER_MOUNTS env var: space-separated mount specs
+# Each entry is either /path (same path) or /src:/dst
+if [[ -n "${TVM_DEV_DOCKER_MOUNTS:-}" ]]; then
+ for mount_spec in ${TVM_DEV_DOCKER_MOUNTS}; do
+ if [[ "$mount_spec" == *:* ]]; then
+ # src:dst format
+ mount_src="${mount_spec%%:*}"
+ if validate_mount "$mount_src"; then
+ DOCKER_MOUNT+=( --volume "$mount_spec" )
+ fi
+ else
+ # Same path format
+ if validate_mount "$mount_spec"; then
+ DOCKER_MOUNT+=( --volume "$mount_spec:$mount_spec" )
+ fi
+ fi
+ done
+fi
+
+# When running from a git worktree, also mount the original git dir.
+if [ -f "${REPO_DIR}/.git" ]; then
+ git_dir=$(cd ${REPO_DIR} && git rev-parse --git-common-dir)
+ if [ "${git_dir}" != "${REPO_DIR}/.git" ]; then
+ DOCKER_MOUNT+=( --volume "${git_dir}:${git_dir}" )
+ fi
+fi
+
+
+##############################################
+### Section 6: Environment construction ###
+##############################################
+
+# CI-specific environment variables
+DOCKER_ENV+=( --env CI_BUILD_HOME="${REPO_MOUNT_POINT}"
+ --env CI_BUILD_USER="$(id -u -n)"
+ --env CI_BUILD_UID="$(id -u)"
+ --env CI_BUILD_GROUP="$(id -g -n)"
+ --env CI_BUILD_GID="$(id -g)"
+ --env CI_PYTEST_ADD_OPTIONS="${CI_PYTEST_ADD_OPTIONS:-}"
+ --env CI_IMAGE_NAME="${DOCKER_IMAGE_NAME}"
+ )
+
+# Remove the container once it finishes running (--rm).
+DOCKER_FLAGS+=(--rm)
+
+# Share the PID namespace (--pid=host). The process inside does not
+# have pid 1 and SIGKILL is propagated to the process inside, allowing
+# jenkins to kill it if needed. This is only necessary for docker
+# daemons running as root.
+if ! detect_rootless; then
+ DOCKER_FLAGS+=(--pid=host)
+fi
+
+# Expose services running in container to the host.
+if $USE_NET_HOST; then
+ if [[ $(uname) == "Darwin" ]]; then
+ # Docker's host networking driver isn't supported on macOS.
+ # Use default bridge network and expose port for jupyter notebook.
+ DOCKER_FLAGS+=( -p 8888:8888 )
+ else
+ DOCKER_FLAGS+=(--net=host)
+ fi
+fi
+
+# Set up interactive sessions
+if ${INTERACTIVE}; then
+ DOCKER_FLAGS+=( --interactive )
+fi
+
+if ${TTY}; then
+ DOCKER_FLAGS+=( --tty )
+fi
+
+# Setup the docker name and the hostname inside the container
+if [[ ! -z "${CONTAINER_NAME}" ]]; then
+ DOCKER_FLAGS+=( --name ${CONTAINER_NAME} --hostname ${CONTAINER_NAME})
+fi
+
+# Pass any restrictions of allowed CUDA devices from the host to the
+# docker container.
+if [[ -n ${CUDA_VISIBLE_DEVICES:-} ]]; then
+ DOCKER_ENV+=( --env CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES}" )
+fi
+
+# Set TVM import path inside the docker image
+if [[ "${DOCKER_IMAGE_NAME}" == *"ci"* ]]; then
+ DOCKER_ENV+=( --env PYTHONPATH="${REPO_MOUNT_POINT}/python" )
+fi
+
+
+##############################################
+### Section 7: GPU/device setup ###
+##############################################
+
+DOCKER_BINARY=docker
+
+# Use --gpus all for GPU/CUDA containers
+if [[ "$USE_GPU" == "true" ]] && [[ "${DOCKER_IMAGE_NAME}" == *"gpu"* || "${DOCKER_IMAGE_NAME}" == *"cuda"* ]]; then
+ DOCKER_FLAGS+=( --gpus all )
+ DOCKER_ENV+=( --env NVIDIA_DRIVER_CAPABILITIES=compute,graphics,utility )
+fi
+
+# Add ROCm devices and set ROCM_ENABLED=1 which is used in the with_the_same_user script
+# to add the user to the video group
+if [[ "${DOCKER_IMAGE_NAME}" == *"rocm"* && -d "/dev/dri" ]]; then
+ DOCKER_DEVICES+=( --device=/dev/kfd --device=/dev/dri )
+ DOCKER_ENV+=( --env ROCM_ENABLED=1 )
+fi
+
+
+##############################################
+### Section 8: Entry command ###
+##############################################
+
+# Apply --shell override: when command is "bash" (auto-interactive)
+# and a custom shell was requested via --shell <name>, use that shell
+if [[ ${COMMAND[@]+"${COMMAND[@]}"} = bash ]] && [[ -n "$USER_SHELL" ]]; then
+ COMMAND=( "$USER_SHELL" )
+fi
+
+# Build the entry command
+if ! detect_rootless; then
+ # Prefer the image helper, with an inline fallback for images that previously
+ # obtained it from the host docker/ bind mount.
+ SAME_USER_SCRIPT=$(cat <<'SAME_USER_EOF'
+set -e
+if [ -f /docker/with_the_same_user ]; then
+ exec bash --login /docker/with_the_same_user "$@"
+fi
+
+# NOTE: sudo uses the env_reset option to reset environment variables to a secure bare minimum.
+# The --preserve-env option below passes those variables through to the invoked process; however,
+# this appears not to affect the environment used with execve, so we resolve the binary to run
+# in this file using the $PATH specified in the Dockerfile.
+COMMAND=( "$(which "$1")" )
+shift
+COMMAND=( "${COMMAND[@]}" "$@" )
+
+if ! touch /this_is_writable_file_system; then
+ echo "You can't write to your filesystem!"
+ echo "If you are in Docker you should check you do not have too many images" \
+ "with too many files in them. Docker has some issue with it."
+ exit 1
+else
+ rm /this_is_writable_file_system
+fi
+
+getent group "${CI_BUILD_GID}" || (
+ # Ensure "${CI_BUILD_GROUP}" is not already some other gid inside container.
+ if grep -q "^${CI_BUILD_GROUP}:" /etc/group; then
+ CI_BUILD_GROUP="${CI_BUILD_GROUP}2"
+ fi
+ addgroup --force-badname --gid "${CI_BUILD_GID}" "${CI_BUILD_GROUP}" >/dev/null)
+
+getent group tvm-venv || (addgroup tvm-venv >/dev/null)
+getent passwd "${CI_BUILD_UID}" || adduser --force-badname --gid "${CI_BUILD_GID}" --uid "${CI_BUILD_UID}" \
+ --gecos "${CI_BUILD_USER} (generated by with_the_same_user script)" \
+ --disabled-password --home "${CI_BUILD_HOME}" --quiet "${CI_BUILD_USER}"
+usermod -a -G sudo -G tvm-venv "${CI_BUILD_USER}"
+usermod -a -G sudo -G dialout "${CI_BUILD_USER}"
+
+# Add user to video group for ROCm
+if [[ ! -z "${ROCM_ENABLED-}" ]]; then
+ usermod -a -G video "${CI_BUILD_USER}"
+fi
+
+# This is a grotesque hack to get PYTEST_ADD_OPTS available to all task scripts.
+echo "${CI_BUILD_USER} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-nopasswd-sudo
+
+if [[ ! -z "${CUDA_VISIBLE_DEVICES-}" ]]; then
+ CUDA_ENV="CUDA_VISIBLE_DEVICES=${CUDA_VISIBLE_DEVICES}"
+else
+ CUDA_ENV=""
+fi
+
+sudo -u "#${CI_BUILD_UID}" --preserve-env \
+${CUDA_ENV} \
+PATH=${PATH} \
+LD_LIBRARY_PATH="${LD_LIBRARY_PATH-}" \
+PYTHONPATH="${PYTHONPATH-}" \
+CI_IMAGE_NAME="${CI_IMAGE_NAME-}" \
+HOME="${CI_BUILD_HOME-}" \
+"${COMMAND[@]}"
+SAME_USER_EOF
+ )
+ COMMAND=(bash --login -c "${SAME_USER_SCRIPT}" -- "${COMMAND[@]}")
+fi
+
+
+##############################################
+### Section 9: Final docker run ###
+##############################################
+
+# Print arguments.
+echo "REPO_DIR: ${REPO_DIR}"
+echo "DOCKER CONTAINER NAME: ${DOCKER_IMAGE_NAME}"
+echo ""
+
+echo Running \'${COMMAND[@]+"${COMMAND[@]}"}\' inside ${DOCKER_IMAGE_NAME}...
+
+DOCKER_CMD=(${DOCKER_BINARY} run
+ ${DOCKER_FLAGS[@]+"${DOCKER_FLAGS[@]}"}
+ ${DOCKER_ENV[@]+"${DOCKER_ENV[@]}"}
+ ${DOCKER_MOUNT[@]+"${DOCKER_MOUNT[@]}"}
+ ${DOCKER_DEVICES[@]+"${DOCKER_DEVICES[@]}"}
+ "${DOCKER_IMAGE_NAME}"
+ ${COMMAND[@]+"${COMMAND[@]}"}
+ )
+
+if ${DRY_RUN}; then
+ echo ${DOCKER_CMD[@]+"${DOCKER_CMD[@]}"}
+else
+ ${DOCKER_CMD[@]+"${DOCKER_CMD[@]}"}
+fi
diff --git a/tests/scripts/task_build_arm.sh b/tests/scripts/task_build_arm.sh
index cb85fea9ea..576687813f 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/tests/scripts/task_build_arm.sh
@@ -19,7 +19,10 @@
set -euxo pipefail
export CMAKE_ARGS="
+ -DTVM_TIRX_BUILD_TESTS=ON
-DTVM_TIRX_USE_LLVM=llvm-config-17
-DCMAKE_CXX_FLAGS=-Werror
"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist .
+
+./build/tirx_cpptest
diff --git a/tests/scripts/task_build_cpu.sh b/tests/scripts/task_build_cpu.sh
index 3583a06391..2e5e540097 100755
--- a/tests/scripts/task_build_cpu.sh
+++ b/tests/scripts/task_build_cpu.sh
@@ -19,7 +19,10 @@
set -euxo pipefail
export CMAKE_ARGS="
+ -DTVM_TIRX_BUILD_TESTS=ON
-DTVM_TIRX_USE_LLVM='/usr/bin/llvm-config-17 --link-static'
-DCMAKE_CXX_FLAGS='-Wno-error=range-loop-construct -Wno-error=comment'
"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist .
+
+./build/tirx_cpptest
diff --git a/tests/scripts/task_build_gpu.sh b/tests/scripts/task_build_gpu.sh
index 4eb7a17385..eb7129baba 100755
--- a/tests/scripts/task_build_gpu.sh
+++ b/tests/scripts/task_build_gpu.sh
@@ -19,6 +19,7 @@
set -euxo pipefail
export CMAKE_ARGS="
+ -DTVM_TIRX_BUILD_TESTS=ON
-DTVM_TIRX_USE_CUDA=ON
-DTVM_TIRX_USE_VULKAN=ON
-DTVM_TIRX_USE_OPENCL=ON
@@ -27,4 +28,6 @@ export CMAKE_ARGS="
-DCMAKE_CXX_FLAGS=-Werror
-DCMAKE_CUDA_ARCHITECTURES=75
"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist .
+
+./build/tirx_cpptest
diff --git a/tests/scripts/task_build_arm.sh b/tests/scripts/task_build_gpu_other.sh
similarity index 61%
copy from tests/scripts/task_build_arm.sh
copy to tests/scripts/task_build_gpu_other.sh
index cb85fea9ea..2ed4f1302c 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/tests/scripts/task_build_gpu_other.sh
@@ -16,10 +16,13 @@
# specific language governing permissions and limitations
# under the License.
+# This file is a compiler test to ensure that runtimes can compile
+# correctly, even if they aren't actively tested in the CI.
set -euxo pipefail
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+# Preserve the separate runtime-only GPU compile check.
+uv pip install --python python3 --no-deps --target build/python ./3rdparty/tvm-ffi
+export PYTHONPATH="$PWD/build/python"
+cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DTVM_TIRX_USE_OPENCL=ON -DTVM_TIRX_USE_ROCM=ON -DCMAKE_CXX_FLAGS=-Werror
+cmake --build build --target tvm_runtime tvm_runtime_opencl tvm_runtime_rocm
diff --git a/tests/scripts/task_build_arm.sh b/tests/scripts/task_install_build_dependencies.sh
similarity index 71%
copy from tests/scripts/task_build_arm.sh
copy to tests/scripts/task_install_build_dependencies.sh
index cb85fea9ea..2b84c57c7a 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/tests/scripts/task_install_build_dependencies.sh
@@ -18,8 +18,10 @@
set -euxo pipefail
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+rm -rf dist
+uv pip install --python python3 --target .local/python \
+ "scikit-build-core>=0.11,!=1.1.0" "setuptools-scm>=8" "cython>=3.2.8" "mlc-z3-static>=4.16.0"
+export PYTHONPATH="$PWD/.local/python"
+
+uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./3rdparty/tvm-ffi
+uv pip install --python python3 --target .local/python --no-deps --offline --reinstall dist/apache_tvm_ffi-*.whl
diff --git a/tests/scripts/task_build_arm.sh b/tests/scripts/task_python_docs.sh
similarity index 65%
copy from tests/scripts/task_build_arm.sh
copy to tests/scripts/task_python_docs.sh
index cb85fea9ea..21d205d26d 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/tests/scripts/task_python_docs.sh
@@ -18,8 +18,10 @@
set -euxo pipefail
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+source ./tests/scripts/test_task_install_dist_wheels.sh
+uv pip install --python python3 --target .local/python -r docs/requirements.txt
+export TVM_TIRX_LIBRARY_PATH="$PWD/.local/python/tvm_tirx/lib"
+rm -rf docs/_build docs/reference/python/generated
+python3 -m sphinx -E -a -b html -d docs/_build/doctrees -W --keep-going docs docs/_build/html
+git rev-parse HEAD > docs/_build/html/commit_hash
+tar -czf docs.tgz -C docs/_build/html .
diff --git a/tests/scripts/task_build_arm.sh b/tests/scripts/task_python_unittest.sh
similarity index 79%
copy from tests/scripts/task_build_arm.sh
copy to tests/scripts/task_python_unittest.sh
index cb85fea9ea..e71f603388 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/tests/scripts/task_python_unittest.sh
@@ -17,9 +17,9 @@
# under the License.
set -euxo pipefail
+export PYTEST_ADDOPTS="${CI_PYTEST_ADD_OPTIONS:-} ${PYTEST_ADDOPTS:-}"
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+if [ "$#" -eq 0 ]; then
+ set -- tests/python
+fi
+python3 -m pytest -vvs -n auto -o faulthandler_timeout=120 -m "${TVM_TEST_MARKER:-not gpu}" "$@"
diff --git a/tests/scripts/task_build_arm.sh b/tests/scripts/task_python_unittest_gpuonly.sh
similarity index 56%
copy from tests/scripts/task_build_arm.sh
copy to tests/scripts/task_python_unittest_gpuonly.sh
index cb85fea9ea..f283c8e8c8 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/tests/scripts/task_python_unittest_gpuonly.sh
@@ -18,8 +18,19 @@
set -euxo pipefail
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+# Every GPU test carries the `gpu` marker; the specific backend is gated by skipif.
+export TVM_TEST_MARKER="gpu"
+
+# Test most of the enabled runtimes here.
+# TODO: disabled opencl tests due to segmentation fault.
+export TVM_TEST_TARGETS='cuda;metal;rocm;nvptx'
+
+./tests/scripts/task_python_unittest.sh
+
+# Kept separate to avoid increasing time needed to run CI, testing
+# only minimal functionality of Vulkan runtime.
+export TVM_TEST_TARGETS='{"kind":"vulkan","from_device":0}'
+
+./tests/scripts/task_python_unittest.sh \
+ tests/python/backend/vulkan/codegen/test_basic.py \
+ tests/python/backend/vulkan/test_module_export.py
diff --git a/tests/scripts/task_build_arm.sh b/tests/scripts/test_task_install_dist_wheels.sh
similarity index 68%
copy from tests/scripts/task_build_arm.sh
copy to tests/scripts/test_task_install_dist_wheels.sh
index cb85fea9ea..2754924c83 100755
--- a/tests/scripts/task_build_arm.sh
+++ b/tests/scripts/test_task_install_dist_wheels.sh
@@ -18,8 +18,9 @@
set -euxo pipefail
-export CMAKE_ARGS="
- -DTVM_TIRX_USE_LLVM=llvm-config-17
- -DCMAKE_CXX_FLAGS=-Werror
-"
-uv build --wheel --no-build-isolation --offline --python python3 --out-dir dist ./tirx
+unset PYTHONPATH TVM_LIBRARY_PATH TVM_FFI_LIBRARY_PATH TVM_TIRX_LIBRARY_PATH
+export PYTHONNOUSERSITE=1
+uv pip install --python python3 --target .local/python --no-deps apache-tvm-ffi-orcjit==0.1.2
+uv pip install --python python3 --target .local/python --no-deps --offline --reinstall \
+ dist/apache_tvm_ffi-*.whl dist/apache_tvm_tirx-*.whl
+export PYTHONPATH="$PWD/.local/python"
(tvm) 07/12: [REFACTOR] Make standalone TIRx the repository root
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 54a62ddf4b42ac2d341e12227f1cb85e80edf22d
Author: tqchen <ti...@gmail.com>
AuthorDate: Fri Oct 16 02:50:25 2026 +0000
[REFACTOR] Make standalone TIRx the repository root
Relocate the compiler, runtime, Python package and tests to the root while retaining their filtered file history.
---
{tirx/3rdparty => 3rdparty}/compiler-rt/builtin_fp16.h | 0
{tirx/3rdparty => 3rdparty}/tvm-ffi | 0
tirx/CMakeLists.txt => CMakeLists.txt | 0
tirx/LICENSE => LICENSE | 0
tirx/NOTICE => NOTICE | 0
{tirx/cmake => cmake}/modules/CUDA.cmake | 0
{tirx/cmake => cmake}/modules/ClangFlags.cmake | 0
{tirx/cmake => cmake}/modules/Git.cmake | 0
{tirx/cmake => cmake}/modules/LLVM.cmake | 0
{tirx/cmake => cmake}/modules/Logging.cmake | 0
{tirx/cmake => cmake}/modules/Metal.cmake | 0
{tirx/cmake => cmake}/modules/OpenCL.cmake | 0
{tirx/cmake => cmake}/modules/OpenMP.cmake | 0
{tirx/cmake => cmake}/modules/ROCM.cmake | 0
{tirx/cmake => cmake}/modules/Vulkan.cmake | 0
{tirx/cmake => cmake}/modules/contrib/Z3.cmake | 0
{tirx/cmake => cmake}/tvm-tirx-config.in | 0
{tirx/cmake => cmake}/tvm_tirx-config.cmake | 0
{tirx/cmake => cmake}/utils/FindCUDA.cmake | 0
{tirx/cmake => cmake}/utils/FindLLVM.cmake | 0
{tirx/cmake => cmake}/utils/FindOpenCL.cmake | 0
{tirx/cmake => cmake}/utils/FindROCM.cmake | 0
{tirx/cmake => cmake}/utils/FindVulkan.cmake | 0
{tirx/cmake => cmake}/utils/Library.cmake | 0
{tirx/include => include}/tvm/backend/cuda/attr.h | 0
{tirx/include => include}/tvm/backend/cuda/op/iket.h | 0
{tirx/include => include}/tvm/backend/cuda/op/tcgen05.h | 0
{tirx/include => include}/tvm/backend/cuda/op/tensormap.h | 0
{tirx/include => include}/tvm/backend/cuda/op_attr_types.h | 0
{tirx/include => include}/tvm/backend/metal/op/cooperative_tensor.h | 0
{tirx/include => include}/tvm/backend/opencl/op/memory.h | 0
{tirx/include => include}/tvm/codegen/codegen.h | 0
{tirx/include => include}/tvm/codegen/intrin_rule.h | 0
{tirx/include => include}/tvm/ir/analysis.h | 0
{tirx/include => include}/tvm/ir/attrs.h | 0
{tirx/include => include}/tvm/ir/base_expr.h | 0
{tirx/include => include}/tvm/ir/cow.h | 0
{tirx/include => include}/tvm/ir/env_func.h | 0
{tirx/include => include}/tvm/ir/expr.h | 0
{tirx/include => include}/tvm/ir/expr_functor.h | 0
{tirx/include => include}/tvm/ir/function.h | 0
{tirx/include => include}/tvm/ir/global_info.h | 0
{tirx/include => include}/tvm/ir/location.h | 0
{tirx/include => include}/tvm/ir/module.h | 0
{tirx/include => include}/tvm/ir/object_functor.h | 0
{tirx/include => include}/tvm/ir/op.h | 0
{tirx/include => include}/tvm/ir/prim/expr.h | 0
{tirx/include => include}/tvm/ir/prim/op.h | 0
{tirx/include => include}/tvm/ir/prim/vector_expr.h | 0
{tirx/include => include}/tvm/ir/scope_stack.h | 0
{tirx/include => include}/tvm/ir/stmt.h | 0
{tirx/include => include}/tvm/ir/transform.h | 0
{tirx/include => include}/tvm/ir/type.h | 0
{tirx/include => include}/tvm/ir/unique_name_supply.h | 0
{tirx/include => include}/tvm/ir/with_context.h | 0
{tirx/include => include}/tvm/runtime/base.h | 0
{tirx/include => include}/tvm/runtime/c_backend_api.h | 0
{tirx/include => include}/tvm/runtime/device_api.h | 0
{tirx/include => include}/tvm/runtime/logging.h | 0
{tirx/include => include}/tvm/runtime/memory_scope.h | 0
{tirx/include => include}/tvm/runtime/tensor.h | 0
{tirx/include => include}/tvm/runtime/timer.h | 0
{tirx/include => include}/tvm/script/ir_builder/base.h | 0
{tirx/include => include}/tvm/script/ir_builder/frame.h | 0
{tirx/include => include}/tvm/script/ir_builder/ir.h | 0
{tirx/include => include}/tvm/script/printer/config.h | 0
{tirx/include => include}/tvm/script/printer/doc.h | 0
{tirx/include => include}/tvm/script/printer/doc_translator.h | 0
{tirx/include => include}/tvm/script/printer/printer.h | 0
{tirx/include => include}/tvm/script/printer/support.h | 0
{tirx/include => include}/tvm/support/bytes_io.h | 0
{tirx/include => include}/tvm/support/env.h | 0
{tirx/include => include}/tvm/support/file_utils.h | 0
{tirx/include => include}/tvm/support/gpu_thread_tag.h | 0
{tirx/include => include}/tvm/support/io.h | 0
{tirx/include => include}/tvm/support/ordered_map.h | 0
{tirx/include => include}/tvm/support/serializer.h | 0
{tirx/include => include}/tvm/sym/analyzer.h | 0
{tirx/include => include}/tvm/sym/bound.h | 0
{tirx/include => include}/tvm/sym/int_set.h | 0
{tirx/include => include}/tvm/sym/iter_affine_map.h | 0
{tirx/include => include}/tvm/sym/pattern.h | 0
{tirx/include => include}/tvm/target/config_schema.h | 0
{tirx/include => include}/tvm/target/target.h | 0
{tirx/include => include}/tvm/target/target_kind.h | 0
{tirx/include => include}/tvm/target/target_tag_registry.h | 0
{tirx/include => include}/tvm/tirx/analysis.h | 0
{tirx/include => include}/tvm/tirx/expr.h | 0
{tirx/include => include}/tvm/tirx/function.h | 0
{tirx/include => include}/tvm/tirx/index_map.h | 0
{tirx/include => include}/tvm/tirx/layout.h | 0
{tirx/include => include}/tvm/tirx/op/abi.h | 0
{tirx/include => include}/tvm/tirx/op/annotation.h | 0
{tirx/include => include}/tvm/tirx/op/cpu.h | 0
{tirx/include => include}/tvm/tirx/op/gpu.h | 0
{tirx/include => include}/tvm/tirx/op/math.h | 0
{tirx/include => include}/tvm/tirx/op/memory.h | 0
{tirx/include => include}/tvm/tirx/op/region.h | 0
{tirx/include => include}/tvm/tirx/op/vector.h | 0
{tirx/include => include}/tvm/tirx/op_attr_types.h | 0
{tirx/include => include}/tvm/tirx/script/ir_builder/frame.h | 0
{tirx/include => include}/tvm/tirx/script/ir_builder/ir.h | 0
{tirx/include => include}/tvm/tirx/stmt.h | 0
{tirx/include => include}/tvm/tirx/stmt_functor.h | 0
{tirx/include => include}/tvm/tirx/stmt_functor_with_analyzer.h | 0
{tirx/include => include}/tvm/tirx/tile/context.h | 0
{tirx/include => include}/tvm/tirx/tile/dispatch.h | 0
{tirx/include => include}/tvm/tirx/tile/op.h | 0
{tirx/include => include}/tvm/tirx/tile/thread_scope.h | 0
{tirx/include => include}/tvm/tirx/transform.h | 0
{tirx/include => include}/tvm/tirx/type.h | 0
{tirx/licenses => licenses}/LICENSE.builtin_fp16.txt | 0
tirx/pyproject.toml => pyproject.toml | 0
{tirx/python => python}/tvm_tirx/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/_autoload_backends.py | 0
{tirx/python => python}/tvm_tirx/backend/adreno/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/adreno/target_tags.py | 0
{tirx/python => python}/tvm_tirx/backend/config.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/axis.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/backend_config.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/codegen/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/codegen/header.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/codegen/registry.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/codegen/schema.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/codegen/types.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/codegen/utils.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/compiler.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/cpp/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/cpp/asm.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/cpp/builtins.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/cpp/descriptors.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/cpp/instrument.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/cpp/nvshmem.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/host.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/iket.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/lang/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/lang/alloc_pool.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/lang/clc.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/lang/pipeline.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/lang/tile_scheduler.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/launch/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/launch/_generated.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/launch/_impl.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/launch/generate.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/launch/table.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/layout.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/op.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/ptx/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/ptx/engine.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/ptx/gen_coverage.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/ptx/gen_helpers.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/ptx/gen_stubs.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/ptx/render.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/ptx/table.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/script.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/target_tags.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/thread_scope.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/exec_context.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/instructions.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/async_copy.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/common.py | 0
.../python => python}/tvm_tirx/backend/cuda/tile/patterns/descriptors.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/ewise.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/ldmatrix.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/memory.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/mma.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/register.py | 0
.../python => python}/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/tma.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/tmem.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/tile/patterns/tmem_copy.py | 0
{tirx/python => python}/tvm_tirx/backend/cuda/transforms/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/hexagon/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/hexagon/linker.py | 0
{tirx/python => python}/tvm_tirx/backend/hexagon/target_tags.py | 0
{tirx/python => python}/tvm_tirx/backend/loader.py | 0
{tirx/python => python}/tvm_tirx/backend/metal/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/metal/op.py | 0
{tirx/python => python}/tvm_tirx/backend/metal/script.py | 0
{tirx/python => python}/tvm_tirx/backend/metal/target_tags.py | 0
{tirx/python => python}/tvm_tirx/backend/opencl/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/opencl/script.py | 0
{tirx/python => python}/tvm_tirx/backend/rocm/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/axis.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/layout.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/op.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/pipeline.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/script.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/target_tags.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/thread_scope.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/binary/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/binary/default.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/binary/utils.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/common.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/compose_op/__init__.py | 0
.../tvm_tirx/backend/trn/tile/compose_op/binary_chain.py | 0
.../tvm_tirx/backend/trn/tile/compose_op/binary_reduce.py | 0
.../tvm_tirx/backend/trn/tile/compose_op/unary_reduce.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/compose_op/utils.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/copy/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/copy/default.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/dim_utils.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/gemm/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/gemm/default.py | 0
.../python => python}/tvm_tirx/backend/trn/tile/instruction_generator.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/instructions.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/private_alloc.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/reduction/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/reduction/utils.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/select/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/select/default.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/unary/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/unary/default.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/unary/utils.py | 0
.../python => python}/tvm_tirx/backend/trn/tile/unary/with_bias_scale.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/tile/workspace_utils.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/transform/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/trn/transform/naive_allocator.py | 0
.../tvm_tirx/backend/trn/transform/private_tensor_alloc.py | 0
{tirx/python => python}/tvm_tirx/backend/vulkan/__init__.py | 0
{tirx/python => python}/tvm_tirx/backend/webgpu/__init__.py | 0
{tirx/python => python}/tvm_tirx/base.py | 0
{tirx/python => python}/tvm_tirx/codegen/__init__.py | 0
{tirx/python => python}/tvm_tirx/codegen/executable.py | 0
{tirx/python => python}/tvm_tirx/codegen/llvm.py | 0
{tirx/python => python}/tvm_tirx/config.py | 0
{tirx/python => python}/tvm_tirx/ir/__init__.py | 0
{tirx/python => python}/tvm_tirx/ir/_constant.py | 0
{tirx/python => python}/tvm_tirx/ir/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/ir/_overload_prim_expr.py | 0
{tirx/python => python}/tvm_tirx/ir/_tensor_expr_overload.py | 0
{tirx/python => python}/tvm_tirx/ir/attrs.py | 0
{tirx/python => python}/tvm_tirx/ir/base.py | 0
{tirx/python => python}/tvm_tirx/ir/expr.py | 0
{tirx/python => python}/tvm_tirx/ir/function.py | 0
{tirx/python => python}/tvm_tirx/ir/global_info.py | 0
{tirx/python => python}/tvm_tirx/ir/json_compact.py | 0
{tirx/python => python}/tvm_tirx/ir/location.py | 0
{tirx/python => python}/tvm_tirx/ir/module.py | 0
{tirx/python => python}/tvm_tirx/ir/op.py | 0
{tirx/python => python}/tvm_tirx/ir/prim/__init__.py | 0
{tirx/python => python}/tvm_tirx/ir/prim/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/ir/prim/expr.py | 0
{tirx/python => python}/tvm_tirx/ir/prim/op.py | 0
{tirx/python => python}/tvm_tirx/ir/prim/vector_expr.py | 0
{tirx/python => python}/tvm_tirx/ir/stmt.py | 0
{tirx/python => python}/tvm_tirx/ir/transform/__init__.py | 0
{tirx/python => python}/tvm_tirx/ir/transform/_ffi_instrument_api.py | 0
{tirx/python => python}/tvm_tirx/ir/transform/_ffi_transform_api.py | 0
{tirx/python => python}/tvm_tirx/ir/transform/core.py | 0
{tirx/python => python}/tvm_tirx/ir/transform/instrument.py | 0
{tirx/python => python}/tvm_tirx/ir/type.py | 0
{tirx/python => python}/tvm_tirx/ir/unique_name_supply.py | 0
{tirx/python => python}/tvm_tirx/libinfo.py | 0
{tirx/python => python}/tvm_tirx/runtime/__init__.py | 0
{tirx/python => python}/tvm_tirx/runtime/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/runtime/_tensor.py | 0
{tirx/python => python}/tvm_tirx/runtime/device.py | 0
{tirx/python => python}/tvm_tirx/runtime/memory_scope.py | 0
{tirx/python => python}/tvm_tirx/script/__init__.py | 0
{tirx/python => python}/tvm_tirx/script/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/script/ir_builder/__init__.py | 0
{tirx/python => python}/tvm_tirx/script/ir_builder/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/script/ir_builder/base.py | 0
{tirx/python => python}/tvm_tirx/script/ir_builder/frame.py | 0
{tirx/python => python}/tvm_tirx/script/ir_builder/ir.py | 0
{tirx/python => python}/tvm_tirx/script/ir_builder/parser_protocol.py | 0
{tirx/python => python}/tvm_tirx/script/ir_builder/stmt.py | 0
{tirx/python => python}/tvm_tirx/script/ir_builder/tracing.py | 0
{tirx/python => python}/tvm_tirx/script/parser/__init__.py | 0
{tirx/python => python}/tvm_tirx/script/parser/entry.py | 0
{tirx/python => python}/tvm_tirx/script/parser/inspect_source.py | 0
{tirx/python => python}/tvm_tirx/script/parser/ir.py | 0
{tirx/python => python}/tvm_tirx/script/parser/jit_support.py | 0
{tirx/python => python}/tvm_tirx/script/parser/prescan.py | 0
{tirx/python => python}/tvm_tirx/script/parser/protocol_registry.py | 0
{tirx/python => python}/tvm_tirx/script/parser/transpile.py | 0
{tirx/python => python}/tvm_tirx/script/printer/__init__.py | 0
{tirx/python => python}/tvm_tirx/script/printer/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/script/printer/doc.py | 0
{tirx/python => python}/tvm_tirx/script/printer/doc_printer.py | 0
{tirx/python => python}/tvm_tirx/script/printer/highlight.py | 0
{tirx/python => python}/tvm_tirx/script/printer/scriptable.py | 0
{tirx/python => python}/tvm_tirx/script/tirx.pyi | 0
{tirx/python => python}/tvm_tirx/support/__init__.py | 0
{tirx/python => python}/tvm_tirx/support/cc.py | 0
{tirx/python => python}/tvm_tirx/support/clang.py | 0
{tirx/python => python}/tvm_tirx/support/libinfo.py | 0
{tirx/python => python}/tvm_tirx/support/ndk.py | 0
{tirx/python => python}/tvm_tirx/support/nvcc.py | 0
{tirx/python => python}/tvm_tirx/support/popen_pool.py | 0
{tirx/python => python}/tvm_tirx/support/popen_worker.py | 0
{tirx/python => python}/tvm_tirx/support/rocm.py | 0
{tirx/python => python}/tvm_tirx/support/tar.py | 0
{tirx/python => python}/tvm_tirx/support/utils.py | 0
{tirx/python => python}/tvm_tirx/support/xcode.py | 0
{tirx/python => python}/tvm_tirx/sym/__init__.py | 0
{tirx/python => python}/tvm_tirx/sym/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/sym/analyzer.py | 0
{tirx/python => python}/tvm_tirx/sym/bound.py | 0
{tirx/python => python}/tvm_tirx/sym/int_set.py | 0
{tirx/python => python}/tvm_tirx/sym/iter_affine_map.py | 0
{tirx/python => python}/tvm_tirx/sym/pattern.py | 0
{tirx/python => python}/tvm_tirx/sym/utils.py | 0
{tirx/python => python}/tvm_tirx/target/__init__.py | 0
{tirx/python => python}/tvm_tirx/target/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/target/detect_target.py | 0
{tirx/python => python}/tvm_tirx/target/tag.py | 0
{tirx/python => python}/tvm_tirx/target/tag_registry/__init__.py | 0
{tirx/python => python}/tvm_tirx/target/tag_registry/arm_cpu.py | 0
{tirx/python => python}/tvm_tirx/target/tag_registry/aws_cpu.py | 0
{tirx/python => python}/tvm_tirx/target/tag_registry/registry.py | 0
{tirx/python => python}/tvm_tirx/target/tag_registry/riscv_cpu.py | 0
{tirx/python => python}/tvm_tirx/target/target.py | 0
{tirx/python => python}/tvm_tirx/testing/__init__.py | 0
{tirx/python => python}/tvm_tirx/testing/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/testing/_pytest.py | 0
{tirx/python => python}/tvm_tirx/testing/env.py | 0
{tirx/python => python}/tvm_tirx/testing/locking.py | 0
{tirx/python => python}/tvm_tirx/testing/popen_pool.py | 0
{tirx/python => python}/tvm_tirx/testing/utils.py | 0
{tirx/python => python}/tvm_tirx/tirx/__init__.py | 0
{tirx/python => python}/tvm_tirx/tirx/_compile.py | 0
{tirx/python => python}/tvm_tirx/tirx/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/tirx/_tensor_view.py | 0
{tirx/python => python}/tvm_tirx/tirx/analysis/__init__.py | 0
{tirx/python => python}/tvm_tirx/tirx/analysis/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/tirx/analysis/analysis.py | 0
{tirx/python => python}/tvm_tirx/tirx/bench.py | 0
{tirx/python => python}/tvm_tirx/tirx/compilation_pipeline.py | 0
{tirx/python => python}/tvm_tirx/tirx/expr.py | 0
{tirx/python => python}/tvm_tirx/tirx/function.py | 0
{tirx/python => python}/tvm_tirx/tirx/index_map.py | 0
{tirx/python => python}/tvm_tirx/tirx/layout.py | 0
{tirx/python => python}/tvm_tirx/tirx/op/__init__.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/__init__.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/ir_builder/__init__.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/ir_builder/_ffi_api.py | 0
.../python => python}/tvm_tirx/tirx/script/ir_builder/external_kernel.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/ir_builder/frame.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/ir_builder/ir.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/ir_builder/op.py | 0
.../python => python}/tvm_tirx/tirx/script/ir_builder/parser_protocol.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/ir_builder/triton.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/ir_builder/utils.py | 0
{tirx/python => python}/tvm_tirx/tirx/script/jit.py | 0
{tirx/python => python}/tvm_tirx/tirx/tensor.py | 0
{tirx/python => python}/tvm_tirx/tirx/thread_scope.py | 0
{tirx/python => python}/tvm_tirx/tirx/tile/__init__.py | 0
{tirx/python => python}/tvm_tirx/tirx/tile/common.py | 0
{tirx/python => python}/tvm_tirx/tirx/tile/dispatch.py | 0
{tirx/python => python}/tvm_tirx/tirx/tile/instruction.py | 0
{tirx/python => python}/tvm_tirx/tirx/tile/views.py | 0
{tirx/python => python}/tvm_tirx/tirx/transform/__init__.py | 0
{tirx/python => python}/tvm_tirx/tirx/transform/_ffi_api.py | 0
{tirx/python => python}/tvm_tirx/tirx/transform/common.py | 0
{tirx/python => python}/tvm_tirx/tirx/transform/function_pass.py | 0
{tirx/python => python}/tvm_tirx/tirx/transform/transform.py | 0
{tirx/python => python}/tvm_tirx/tirx/type.py | 0
{tirx/src => src}/backend/cuda/codegen/codegen_cuda.cc | 0
{tirx/src => src}/backend/cuda/codegen/codegen_cuda.h | 0
{tirx/src => src}/backend/cuda/codegen/codegen_cuda_host.cc | 0
{tirx/src => src}/backend/cuda/codegen/cuda_fallback_module.cc | 0
{tirx/src => src}/backend/cuda/codegen/cuda_fallback_module.h | 0
{tirx/src => src}/backend/cuda/codegen/intrin_rule_cuda.cc | 0
{tirx/src => src}/backend/cuda/codegen/literal/cuda_half_t.h | 0
{tirx/src => src}/backend/cuda/codegen/literal/cuda_int8_t.h | 0
{tirx/src => src}/backend/cuda/codegen/llvm/codegen_nvptx.cc | 0
{tirx/src => src}/backend/cuda/codegen/llvm/intrin_rule_nvptx.cc | 0
{tirx/src => src}/backend/cuda/codegen/ptx.cc | 0
{tirx/src => src}/backend/cuda/codegen/target_kind.cc | 0
{tirx/src => src}/backend/cuda/launch/launch_attributes.h | 0
{tirx/src => src}/backend/cuda/launch/launch_config.h | 0
{tirx/src => src}/backend/cuda/launch/launch_fields.h | 0
{tirx/src => src}/backend/cuda/launch/launch_plan.h | 0
{tirx/src => src}/backend/cuda/launch/launch_source.h | 0
{tirx/src => src}/backend/cuda/layout/axis.cc | 0
{tirx/src => src}/backend/cuda/op/iket.cc | 0
{tirx/src => src}/backend/cuda/op/legacy.cc | 0
{tirx/src => src}/backend/cuda/op/target_builtin.cc | 0
{tirx/src => src}/backend/cuda/op/tcgen05.cc | 0
{tirx/src => src}/backend/cuda/op/tensormap.cc | 0
{tirx/src => src}/backend/cuda/runtime/cuda_device_api.cc | 0
{tirx/src => src}/backend/cuda/runtime/cuda_module.cc | 0
{tirx/src => src}/backend/cuda/tile/exec_analysis.cc | 0
{tirx/src => src}/backend/cuda/tile/exec_analysis.h | 0
{tirx/src => src}/backend/cuda/tile/exec_context.cc | 0
{tirx/src => src}/backend/cuda/tile/exec_context.h | 0
{tirx/src => src}/backend/cuda/tile/filter_canonical.cc | 0
{tirx/src => src}/backend/cuda/tile/filter_canonical.h | 0
{tirx/src => src}/backend/cuda/tile/thread_scope.cc | 0
{tirx/src => src}/backend/cuda/tile/thread_scope.h | 0
{tirx/src => src}/backend/cuda/transforms/bind_backend_config.cc | 0
{tirx/src => src}/backend/cuda/transforms/lower_iket.cc | 0
{tirx/src => src}/backend/hexagon/codegen/hexagon_fallback_module.cc | 0
{tirx/src => src}/backend/hexagon/codegen/hexagon_fallback_module.h | 0
{tirx/src => src}/backend/hexagon/codegen/llvm/codegen_hexagon.cc | 0
{tirx/src => src}/backend/hexagon/codegen/llvm/intrin_rule_hexagon.cc | 0
{tirx/src => src}/backend/hexagon/codegen/memory_scope.h | 0
{tirx/src => src}/backend/hexagon/codegen/target_kind.cc | 0
{tirx/src => src}/backend/metal/codegen/codegen_metal.cc | 0
{tirx/src => src}/backend/metal/codegen/codegen_metal.h | 0
{tirx/src => src}/backend/metal/codegen/intrin_rule_metal.cc | 0
{tirx/src => src}/backend/metal/codegen/metal_fallback_module.cc | 0
{tirx/src => src}/backend/metal/codegen/metal_fallback_module.h | 0
{tirx/src => src}/backend/metal/codegen/target_kind.cc | 0
{tirx/src => src}/backend/metal/op/cooperative_tensor.cc | 0
{tirx/src => src}/backend/metal/op/target_builtin.cc | 0
{tirx/src => src}/backend/metal/runtime/metal_common.h | 0
{tirx/src => src}/backend/metal/runtime/metal_device_api.mm | 0
{tirx/src => src}/backend/metal/runtime/metal_module.mm | 0
{tirx/src => src}/backend/opencl/codegen/codegen_opencl.cc | 0
{tirx/src => src}/backend/opencl/codegen/codegen_opencl.h | 0
{tirx/src => src}/backend/opencl/codegen/intrin_rule_opencl.cc | 0
{tirx/src => src}/backend/opencl/codegen/opencl_fallback_module.cc | 0
{tirx/src => src}/backend/opencl/codegen/opencl_fallback_module.h | 0
{tirx/src => src}/backend/opencl/codegen/target_kind.cc | 0
{tirx/src => src}/backend/opencl/memory_scope.h | 0
{tirx/src => src}/backend/opencl/op/memory.cc | 0
{tirx/src => src}/backend/opencl/runtime/opencl_common.h | 0
{tirx/src => src}/backend/opencl/runtime/opencl_device_api.cc | 0
{tirx/src => src}/backend/opencl/runtime/opencl_module.cc | 0
{tirx/src => src}/backend/opencl/runtime/opencl_wrapper/README.md | 0
{tirx/src => src}/backend/opencl/runtime/opencl_wrapper/opencl_wrapper.cc | 0
{tirx/src => src}/backend/opencl/runtime/source_utils.h | 0
{tirx/src => src}/backend/opencl/runtime/texture.h | 0
{tirx/src => src}/backend/rocm/codegen/llvm/codegen_amdgpu.cc | 0
{tirx/src => src}/backend/rocm/codegen/llvm/intrin_rule_rocm.cc | 0
{tirx/src => src}/backend/rocm/codegen/rocm_fallback_module.cc | 0
{tirx/src => src}/backend/rocm/codegen/rocm_fallback_module.h | 0
{tirx/src => src}/backend/rocm/codegen/target_kind.cc | 0
{tirx/src => src}/backend/rocm/runtime/rocm_common.h | 0
{tirx/src => src}/backend/rocm/runtime/rocm_device_api.cc | 0
{tirx/src => src}/backend/rocm/runtime/rocm_module.cc | 0
{tirx/src => src}/backend/trn/codegen/codegen_trn.cc | 0
{tirx/src => src}/backend/trn/codegen/codegen_trn.h | 0
{tirx/src => src}/backend/trn/codegen/target_kind.cc | 0
{tirx/src => src}/backend/trn/layout/axis.cc | 0
{tirx/src => src}/backend/trn/op/target_builtin.cc | 0
{tirx/src => src}/backend/trn/transform/lower_trainium_layout.cc | 0
{tirx/src => src}/backend/vulkan/codegen/build_vulkan.cc | 0
{tirx/src => src}/backend/vulkan/codegen/codegen_spirv.cc | 0
{tirx/src => src}/backend/vulkan/codegen/codegen_spirv.h | 0
{tirx/src => src}/backend/vulkan/codegen/intrin_rule_spirv.cc | 0
{tirx/src => src}/backend/vulkan/codegen/ir_builder.cc | 0
{tirx/src => src}/backend/vulkan/codegen/ir_builder.h | 0
{tirx/src => src}/backend/vulkan/codegen/spirv_support.cc | 0
{tirx/src => src}/backend/vulkan/codegen/spirv_support.h | 0
{tirx/src => src}/backend/vulkan/codegen/spirv_utils.cc | 0
{tirx/src => src}/backend/vulkan/codegen/spirv_utils.h | 0
{tirx/src => src}/backend/vulkan/codegen/target_kind.cc | 0
{tirx/src => src}/backend/vulkan/codegen/vulkan_fallback_module.cc | 0
{tirx/src => src}/backend/vulkan/codegen/vulkan_fallback_module.h | 0
{tirx/src => src}/backend/vulkan/runtime/README.md | 0
{tirx/src => src}/backend/vulkan/runtime/spirv_shader.h | 0
{tirx/src => src}/backend/vulkan/runtime/thread_map.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_amdrgp.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_amdrgp.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_buffer.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_buffer.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_common.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_common.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_device.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_device.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_device_api.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_device_api.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_instance.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_instance.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_module.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_stream.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_stream.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_timer.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_timer.h | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_wrapped_func.cc | 0
{tirx/src => src}/backend/vulkan/runtime/vulkan_wrapped_func.h | 0
{tirx/src => src}/backend/webgpu/codegen/codegen_webgpu.cc | 0
{tirx/src => src}/backend/webgpu/codegen/codegen_webgpu.h | 0
{tirx/src => src}/backend/webgpu/codegen/intrin_rule_webgpu.cc | 0
{tirx/src => src}/backend/webgpu/codegen/target_kind.cc | 0
{tirx/src => src}/backend/webgpu/codegen/webgpu_fallback_module.cc | 0
{tirx/src => src}/backend/webgpu/codegen/webgpu_fallback_module.h | 0
{tirx/src => src}/codegen/build_common.h | 0
{tirx/src => src}/codegen/c/codegen_c.cc | 0
{tirx/src => src}/codegen/c/codegen_c.h | 0
{tirx/src => src}/codegen/c/codegen_c_host.cc | 0
{tirx/src => src}/codegen/c/codegen_c_host.h | 0
{tirx/src => src}/codegen/c/codegen_params.cc | 0
{tirx/src => src}/codegen/c/codegen_params.h | 0
{tirx/src => src}/codegen/c/codegen_source_base.cc | 0
{tirx/src => src}/codegen/c/codegen_source_base.h | 0
{tirx/src => src}/codegen/c/source_module.cc | 0
{tirx/src => src}/codegen/c/target_kind.cc | 0
{tirx/src => src}/codegen/canonicalizer/arm_mprofile.cc | 0
{tirx/src => src}/codegen/canonicalizer/arm_mprofile.h | 0
{tirx/src => src}/codegen/codegen.cc | 0
{tirx/src => src}/codegen/intrin_rule.cc | 0
{tirx/src => src}/codegen/llvm/canonicalizer/arm_aprofile.cc | 0
{tirx/src => src}/codegen/llvm/canonicalizer/arm_aprofile.h | 0
{tirx/src => src}/codegen/llvm/canonicalizer/canonicalize.cc | 0
{tirx/src => src}/codegen/llvm/canonicalizer/canonicalize.h | 0
{tirx/src => src}/codegen/llvm/codegen_aarch64.cc | 0
{tirx/src => src}/codegen/llvm/codegen_arm.cc | 0
{tirx/src => src}/codegen/llvm/codegen_blob.cc | 0
{tirx/src => src}/codegen/llvm/codegen_blob.h | 0
{tirx/src => src}/codegen/llvm/codegen_cpu.cc | 0
{tirx/src => src}/codegen/llvm/codegen_cpu.h | 0
{tirx/src => src}/codegen/llvm/codegen_llvm.cc | 0
{tirx/src => src}/codegen/llvm/codegen_llvm.h | 0
{tirx/src => src}/codegen/llvm/codegen_params.cc | 0
{tirx/src => src}/codegen/llvm/codegen_params.h | 0
{tirx/src => src}/codegen/llvm/codegen_x86_64.cc | 0
{tirx/src => src}/codegen/llvm/intrin_rule_llvm.cc | 0
{tirx/src => src}/codegen/llvm/intrin_rule_llvm.h | 0
{tirx/src => src}/codegen/llvm/llvm_instance.cc | 0
{tirx/src => src}/codegen/llvm/llvm_instance.h | 0
{tirx/src => src}/codegen/llvm/llvm_module.cc | 0
{tirx/src => src}/codegen/llvm/llvm_module.h | 0
{tirx/src => src}/codegen/llvm/target_kind.cc | 0
{tirx/src => src}/codegen/module_export.cc | 0
{tirx/src => src}/ir/attrs.cc | 0
{tirx/src => src}/ir/env_func.cc | 0
{tirx/src => src}/ir/expr.cc | 0
{tirx/src => src}/ir/expr_functor.cc | 0
{tirx/src => src}/ir/function.cc | 0
{tirx/src => src}/ir/global_info.cc | 0
{tirx/src => src}/ir/instrument.cc | 0
{tirx/src => src}/ir/location.cc | 0
{tirx/src => src}/ir/module.cc | 0
{tirx/src => src}/ir/op.cc | 0
{tirx/src => src}/ir/prim/builtin.cc | 0
{tirx/src => src}/ir/prim/const_fold.h | 0
{tirx/src => src}/ir/prim/deep_equal.cc | 0
{tirx/src => src}/ir/prim/expr.cc | 0
{tirx/src => src}/ir/prim/int_operator.h | 0
{tirx/src => src}/ir/prim/math.cc | 0
{tirx/src => src}/ir/prim/op.cc | 0
{tirx/src => src}/ir/prim/op_utils.h | 0
{tirx/src => src}/ir/prim/symbolic_limits.cc | 0
{tirx/src => src}/ir/prim/vector_expr.cc | 0
{tirx/src => src}/ir/seq_stmt_mutate.h | 0
{tirx/src => src}/ir/side_effect.cc | 0
{tirx/src => src}/ir/stmt.cc | 0
{tirx/src => src}/ir/subscript_expr.cc | 0
{tirx/src => src}/ir/transform.cc | 0
{tirx/src => src}/ir/type.cc | 0
{tirx/src => src}/ir/unique_name_supply.cc | 0
{tirx/src => src}/runtime/builtin_fp16.cc | 0
{tirx/src => src}/runtime/cpu_device_api.cc | 0
{tirx/src => src}/runtime/device_api.cc | 0
{tirx/src => src}/runtime/launch_param.h | 0
{tirx/src => src}/runtime/logging.cc | 0
{tirx/src => src}/runtime/memory_scope.cc | 0
{tirx/src => src}/runtime/metadata.cc | 0
{tirx/src => src}/runtime/metadata.h | 0
{tirx/src => src}/runtime/module.cc | 0
{tirx/src => src}/runtime/pack_args.h | 0
{tirx/src => src}/runtime/static_library.cc | 0
{tirx/src => src}/runtime/static_library.h | 0
{tirx/src => src}/runtime/tensor.cc | 0
{tirx/src => src}/runtime/thread_pool.cc | 0
{tirx/src => src}/runtime/threading_backend.cc | 0
{tirx/src => src}/runtime/threading_backend.h | 0
{tirx/src => src}/runtime/workspace_pool.cc | 0
{tirx/src => src}/runtime/workspace_pool.h | 0
{tirx/src => src}/script/ir_builder/base.cc | 0
{tirx/src => src}/script/ir_builder/frame.cc | 0
{tirx/src => src}/script/ir_builder/ir.cc | 0
{tirx/src => src}/script/ir_builder/utils.h | 0
{tirx/src => src}/script/printer/config.cc | 0
{tirx/src => src}/script/printer/doc.cc | 0
{tirx/src => src}/script/printer/doc_printer.cc | 0
{tirx/src => src}/script/printer/doc_printer.h | 0
{tirx/src => src}/script/printer/doc_translator.cc | 0
{tirx/src => src}/script/printer/ir/call.cc | 0
{tirx/src => src}/script/printer/ir/ir.cc | 0
{tirx/src => src}/script/printer/ir/misc.cc | 0
{tirx/src => src}/script/printer/ir/prim_expr.cc | 0
{tirx/src => src}/script/printer/ir/prim_type.cc | 0
{tirx/src => src}/script/printer/ir/stmt.cc | 0
{tirx/src => src}/script/printer/ir/utils.cc | 0
{tirx/src => src}/script/printer/ir/utils.h | 0
{tirx/src => src}/script/printer/printer.cc | 0
{tirx/src => src}/script/printer/script_printer.cc | 0
{tirx/src => src}/script/printer/utils.h | 0
{tirx/src => src}/support/limits.h | 0
{tirx/src => src}/sym/analyzer.cc | 0
{tirx/src => src}/sym/bound_deducer.cc | 0
{tirx/src => src}/sym/canonical_simplify.cc | 0
{tirx/src => src}/sym/const_fold.h | 0
{tirx/src => src}/sym/const_int_bound.cc | 0
{tirx/src => src}/sym/constraint_extract.cc | 0
{tirx/src => src}/sym/constraint_extract.h | 0
{tirx/src => src}/sym/constraint_helpers.h | 0
{tirx/src => src}/sym/detect_linear_equation.cc | 0
{tirx/src => src}/sym/int_operator.h | 0
{tirx/src => src}/sym/int_set.cc | 0
{tirx/src => src}/sym/interval_set.h | 0
{tirx/src => src}/sym/iter_affine_map.cc | 0
{tirx/src => src}/sym/known_comparison_analyzer.cc | 0
{tirx/src => src}/sym/modular_set.cc | 0
{tirx/src => src}/sym/pattern_match.h | 0
{tirx/src => src}/sym/product_normal_form.h | 0
{tirx/src => src}/sym/rewrite_simplify.cc | 0
{tirx/src => src}/sym/rewrite_simplify.h | 0
{tirx/src => src}/sym/simplify_base.cc | 0
{tirx/src => src}/sym/simplify_base.h | 0
{tirx/src => src}/sym/z3_prover.cc | 0
{tirx/src => src}/target/target.cc | 0
{tirx/src => src}/target/target_kind.cc | 0
{tirx/src => src}/target/target_tag_registry.cc | 0
{tirx/src => src}/tirx/analysis/check_well_formed.cc | 0
{tirx/src => src}/tirx/analysis/expr_complexity.cc | 0
{tirx/src => src}/tirx/analysis/stmt_finding.cc | 0
{tirx/src => src}/tirx/analysis/undefined_vars.cc | 0
{tirx/src => src}/tirx/analysis/verify_memory.cc | 0
{tirx/src => src}/tirx/ir/data_type_rewriter.cc | 0
{tirx/src => src}/tirx/ir/data_type_rewriter.h | 0
{tirx/src => src}/tirx/ir/function.cc | 0
{tirx/src => src}/tirx/ir/index_map.cc | 0
{tirx/src => src}/tirx/ir/ir_mutator_with_analyzer.cc | 0
{tirx/src => src}/tirx/ir/ir_visitor_with_analyzer.cc | 0
{tirx/src => src}/tirx/ir/layout/axis_registry.cc | 0
{tirx/src => src}/tirx/ir/layout/axis_registry.h | 0
{tirx/src => src}/tirx/ir/layout/compose_layout.cc | 0
{tirx/src => src}/tirx/ir/layout/layout.cc | 0
{tirx/src => src}/tirx/ir/layout/tile_canonicalize.cc | 0
{tirx/src => src}/tirx/ir/layout/tile_core.cc | 0
{tirx/src => src}/tirx/ir/layout/tile_internal.h | 0
{tirx/src => src}/tirx/ir/layout/tile_tile_ops.cc | 0
{tirx/src => src}/tirx/ir/layout/utils.cc | 0
{tirx/src => src}/tirx/ir/layout/utils.h | 0
{tirx/src => src}/tirx/ir/specialize.cc | 0
{tirx/src => src}/tirx/ir/stmt.cc | 0
{tirx/src => src}/tirx/ir/stmt_functor.cc | 0
{tirx/src => src}/tirx/ir/tensor.cc | 0
{tirx/src => src}/tirx/ir/tensor_load.cc | 0
{tirx/src => src}/tirx/ir/transform.cc | 0
{tirx/src => src}/tirx/ir/type.cc | 0
{tirx/src => src}/tirx/op/abi.cc | 0
{tirx/src => src}/tirx/op/annotation.cc | 0
{tirx/src => src}/tirx/op/cpu.cc | 0
{tirx/src => src}/tirx/op/gpu.cc | 0
{tirx/src => src}/tirx/op/math.cc | 0
{tirx/src => src}/tirx/op/memory.cc | 0
{tirx/src => src}/tirx/op/region.cc | 0
{tirx/src => src}/tirx/op/vector.cc | 0
{tirx/src => src}/tirx/script/ir_builder/frame.cc | 0
{tirx/src => src}/tirx/script/ir_builder/ir.cc | 0
{tirx/src => src}/tirx/script/ir_builder/utils.h | 0
{tirx/src => src}/tirx/script/printer/block.cc | 0
{tirx/src => src}/tirx/script/printer/expr.cc | 0
{tirx/src => src}/tirx/script/printer/for_loop.cc | 0
{tirx/src => src}/tirx/script/printer/function.cc | 0
{tirx/src => src}/tirx/script/printer/ir.cc | 0
{tirx/src => src}/tirx/script/printer/stmt.cc | 0
{tirx/src => src}/tirx/script/printer/tensor.cc | 0
{tirx/src => src}/tirx/tile/context.cc | 0
{tirx/src => src}/tirx/tile/dispatch.cc | 0
{tirx/src => src}/tirx/tile/lower.cc | 0
{tirx/src => src}/tirx/tile/op.cc | 0
{tirx/src => src}/tirx/tile/thread_scope.cc | 0
{tirx/src => src}/tirx/transform/bind_target.cc | 0
{tirx/src => src}/tirx/transform/common_subexpr_elim.cc | 0
{tirx/src => src}/tirx/transform/decorate_device_scope.cc | 0
{tirx/src => src}/tirx/transform/dtype_conversion.cc | 0
{tirx/src => src}/tirx/transform/dtype_conversion.h | 0
{tirx/src => src}/tirx/transform/flatten_tensor.cc | 0
{tirx/src => src}/tirx/transform/flattened_tensor.h | 0
{tirx/src => src}/tirx/transform/force_narrow_index_to_i32.cc | 0
{tirx/src => src}/tirx/transform/function_utils.cc | 0
{tirx/src => src}/tirx/transform/hoist_if.cc | 0
{tirx/src => src}/tirx/transform/ir_utils.cc | 0
{tirx/src => src}/tirx/transform/ir_utils.h | 0
{tirx/src => src}/tirx/transform/lower_intrin.cc | 0
{tirx/src => src}/tirx/transform/lower_thread_allreduce.cc | 0
{tirx/src => src}/tirx/transform/lower_tirx.cc | 0
{tirx/src => src}/tirx/transform/lower_tirx_cleanup.cc | 0
{tirx/src => src}/tirx/transform/lower_tirx_dedup_tensormap.cc | 0
{tirx/src => src}/tirx/transform/lower_tvm_builtin.cc | 0
{tirx/src => src}/tirx/transform/make_packed_api.cc | 0
{tirx/src => src}/tirx/transform/narrow_datatype.cc | 0
{tirx/src => src}/tirx/transform/remove_no_op.cc | 0
{tirx/src => src}/tirx/transform/remove_no_op.h | 0
{tirx/src => src}/tirx/transform/renormalize_split_pattern.cc | 0
{tirx/src => src}/tirx/transform/skip_assert.cc | 0
{tirx/src => src}/tirx/transform/split_host_device.cc | 0
{tirx/src => src}/tirx/transform/stmt_simplify.cc | 0
{tirx/src => src}/tirx/transform/storage_rewrite.cc | 0
{tirx/src => src}/tirx/transform/tvm_ffi_binder.cc | 0
{tirx/src => src}/tirx/transform/tvm_ffi_binder.h | 0
{tirx/src => src}/tirx/transform/unroll_loop.cc | 0
{tirx/src => src}/tirx/transform/unsupported_dtype_legalize.cc | 0
{tirx/src => src}/tirx/transform/vectorize_loop.cc | 0
{tirx/tests => tests}/cpp/CMakeLists.txt | 0
{tirx/tests => tests}/cpp/ir/expr_functor_test.cc | 0
{tirx/tests => tests}/cpp/ir/op_signature_test.cc | 0
{tirx/tests => tests}/cpp/ir/tensor_load_test.cc | 0
{tirx/tests => tests}/cpp/runtime/backend_workspace_test.cc | 0
{tirx/tests => tests}/cpp/runtime/logging_test.cc | 0
{tirx/tests => tests}/cpp/runtime/memory_scope_test.cc | 0
{tirx/tests => tests}/cpp/runtime/tensor_io_test.cc | 0
{tirx/tests => tests}/cpp/script/string_escape_test.cc | 0
{tirx/tests => tests}/cpp/sym/domain_map_test.cc | 0
{tirx/tests => tests}/cpp/sym/pattern_match_test.cc | 0
{tirx/tests => tests}/cpp/target/config_schema_test.cc | 0
{tirx/tests => tests}/cpp/target/target_test.cc | 0
{tirx/tests => tests}/cpp/tirx/stmt_functor_test.cc | 0
{tirx/tests => tests}/cpp/tirx/tensor_var_test.cc | 0
{tirx/tests => tests}/cpp/tirx/thread_scope_test.cc | 0
{tirx/tests => tests}/python/backend/__init__.py | 0
{tirx/tests => tests}/python/backend/cuda/__init__.py | 0
{tirx/tests => tests}/python/backend/cuda/codegen/__init__.py | 0
{tirx/tests => tests}/python/backend/cuda/codegen/test_basic.py | 0
{tirx/tests => tests}/python/backend/cuda/codegen/test_fastmath.py | 0
{tirx/tests => tests}/python/backend/cuda/codegen/test_fp4.py | 0
{tirx/tests => tests}/python/backend/cuda/codegen/test_fp8.py | 0
{tirx/tests => tests}/python/backend/cuda/test_host_bundle.py | 0
{tirx/tests => tests}/python/backend/cuda/test_module_export.py | 0
{tirx/tests => tests}/python/backend/hexagon/__init__.py | 0
{tirx/tests => tests}/python/backend/hexagon/codegen/__init__.py | 0
{tirx/tests => tests}/python/backend/hexagon/codegen/test_basic.py | 0
{tirx/tests => tests}/python/backend/metal/__init__.py | 0
{tirx/tests => tests}/python/backend/metal/codegen/__init__.py | 0
{tirx/tests => tests}/python/backend/metal/codegen/test_basic.py | 0
{tirx/tests => tests}/python/backend/metal/test_compile_callback.py | 0
{tirx/tests => tests}/python/backend/metal/test_module_export.py | 0
{tirx/tests => tests}/python/backend/opencl/__init__.py | 0
{tirx/tests => tests}/python/backend/opencl/codegen/__init__.py | 0
{tirx/tests => tests}/python/backend/opencl/codegen/test_basic.py | 0
{tirx/tests => tests}/python/backend/opencl/test_module_export.py | 0
{tirx/tests => tests}/python/backend/rocm/__init__.py | 0
{tirx/tests => tests}/python/backend/rocm/codegen/__init__.py | 0
{tirx/tests => tests}/python/backend/rocm/codegen/test_basic.py | 0
{tirx/tests => tests}/python/backend/rocm/test_module_export.py | 0
{tirx/tests => tests}/python/backend/vulkan/__init__.py | 0
{tirx/tests => tests}/python/backend/vulkan/codegen/__init__.py | 0
{tirx/tests => tests}/python/backend/vulkan/codegen/test_basic.py | 0
{tirx/tests => tests}/python/backend/vulkan/test_module_export.py | 0
{tirx/tests => tests}/python/backend/webgpu/__init__.py | 0
{tirx/tests => tests}/python/backend/webgpu/codegen/__init__.py | 0
{tirx/tests => tests}/python/backend/webgpu/codegen/test_basic.py | 0
{tirx/tests => tests}/python/codegen/__init__.py | 0
{tirx/tests => tests}/python/codegen/c/__init__.py | 0
{tirx/tests => tests}/python/codegen/c/test_basic.py | 0
{tirx/tests => tests}/python/codegen/gpu_common/__init__.py | 0
{tirx/tests => tests}/python/codegen/gpu_common/test_allreduce.py | 0
{tirx/tests => tests}/python/codegen/gpu_common/test_device.py | 0
{tirx/tests => tests}/python/codegen/gpu_common/test_intrinsics.py | 0
{tirx/tests => tests}/python/codegen/llvm/__init__.py | 0
{tirx/tests => tests}/python/codegen/llvm/test_aarch64.py | 0
{tirx/tests => tests}/python/codegen/llvm/test_arm.py | 0
{tirx/tests => tests}/python/codegen/llvm/test_basic.py | 0
{tirx/tests => tests}/python/codegen/llvm/test_riscv.py | 0
{tirx/tests => tests}/python/codegen/llvm/test_scalable_vector.py | 0
{tirx/tests => tests}/python/codegen/llvm/test_x86.py | 0
{tirx/tests => tests}/python/codegen/test_argument_validation.py | 0
{tirx/tests => tests}/python/codegen/test_assert.py | 0
{tirx/tests => tests}/python/codegen/test_bool.py | 0
{tirx/tests => tests}/python/codegen/test_common.py | 0
{tirx/tests => tests}/python/codegen/test_executable.py | 0
{tirx/tests => tests}/python/codegen/test_extern.py | 0
{tirx/tests => tests}/python/codegen/test_static_init.py | 0
{tirx/tests => tests}/python/conftest.py | 0
{tirx/tests => tests}/python/ir/__init__.py | 0
{tirx/tests => tests}/python/ir/test_attrs.py | 0
{tirx/tests => tests}/python/ir/test_expr_layout.py | 0
{tirx/tests => tests}/python/ir/test_json.py | 0
{tirx/tests => tests}/python/ir/test_module.py | 0
{tirx/tests => tests}/python/ir/test_nonnullable.py | 0
{tirx/tests => tests}/python/ir/test_prim_expr_deep_equal.py | 0
{tirx/tests => tests}/python/ir/test_roundtrip_runtime_module.py | 0
{tirx/tests => tests}/python/ir/test_type.py | 0
{tirx/tests => tests}/python/runtime/__init__.py | 0
{tirx/tests => tests}/python/runtime/test_device_api.py | 0
{tirx/tests => tests}/python/runtime/test_memory_scope.py | 0
{tirx/tests => tests}/python/runtime/test_module.py | 0
{tirx/tests => tests}/python/runtime/test_tensor.py | 0
{tirx/tests => tests}/python/runtime/test_tirx_config.py | 0
{tirx/tests => tests}/python/runtime/test_validate_wheel_library.py | 0
{tirx/tests => tests}/python/script/conftest.py | 0
{tirx/tests => tests}/python/script/minilang.py | 0
{tirx/tests => tests}/python/script/test_basic_usage.py | 0
{tirx/tests => tests}/python/script/test_builder_void_emission.py | 0
{tirx/tests => tests}/python/script/test_cross_function_call.py | 0
{tirx/tests => tests}/python/script/test_dynamic_shape.py | 0
{tirx/tests => tests}/python/script/test_error_handling.py | 0
{tirx/tests => tests}/python/script/test_ir_builder.py | 0
{tirx/tests => tests}/python/script/test_jit_specialization.py | 0
{tirx/tests => tests}/python/script/test_meta_programming.py | 0
{tirx/tests => tests}/python/script/test_parser_entry.py | 0
{tirx/tests => tests}/python/script/test_printer_doc.py | 0
{tirx/tests => tests}/python/script/test_source_locations.py | 0
{tirx/tests => tests}/python/script/test_special_parser_protocol.py | 0
{tirx/tests => tests}/python/support/__init__.py | 0
{tirx/tests => tests}/python/support/test_ccache.py | 0
{tirx/tests => tests}/python/support/test_config.py | 0
{tirx/tests => tests}/python/support/test_nvcc.py | 0
{tirx/tests => tests}/python/support/test_popen_pool.py | 0
{tirx/tests => tests}/python/support/test_util.py | 0
{tirx/tests => tests}/python/sym/__init__.py | 0
{tirx/tests => tests}/python/sym/test_analyzer_object.py | 0
{tirx/tests => tests}/python/sym/test_const_int_bound.py | 0
{tirx/tests => tests}/python/sym/test_deduce_bound.py | 0
{tirx/tests => tests}/python/sym/test_detect_clip_bound.py | 0
{tirx/tests => tests}/python/sym/test_detect_linear_equation.py | 0
{tirx/tests => tests}/python/sym/test_intset.py | 0
{tirx/tests => tests}/python/sym/test_iter_affine_map.py | 0
{tirx/tests => tests}/python/sym/test_rewrite_simplify.py | 0
{tirx/tests => tests}/python/sym/test_simplify.py | 0
{tirx/tests => tests}/python/sym/test_z3.py | 0
{tirx/tests => tests}/python/target/__init__.py | 0
{tirx/tests => tests}/python/target/test_llvm_features_info.py | 0
{tirx/tests => tests}/python/target/test_parser_mprofile.py | 0
{tirx/tests => tests}/python/target/test_riscv_features.py | 0
{tirx/tests => tests}/python/target/test_x86_features.py | 0
{tirx/tests => tests}/python/testing/__init__.py | 0
{tirx/tests => tests}/python/tirx/__init__.py | 0
{tirx/tests => tests}/python/tirx/analysis/__init__.py | 0
{tirx/tests => tests}/python/tirx/analysis/test_check_well_defined.py | 0
{tirx/tests => tests}/python/tirx/analysis/test_undefined_vars.py | 0
{tirx/tests => tests}/python/tirx/base/__init__.py | 0
{tirx/tests => tests}/python/tirx/base/test_host_func.py | 0
{tirx/tests => tests}/python/tirx/base/test_imm_values.py | 0
{tirx/tests => tests}/python/tirx/base/test_index_map.py | 0
{tirx/tests => tests}/python/tirx/base/test_intrin.py | 0
{tirx/tests => tests}/python/tirx/base/test_nodes.py | 0
{tirx/tests => tests}/python/tirx/base/test_op_types.py | 0
{tirx/tests => tests}/python/tirx/base/test_ptx_cp_async.py | 0
{tirx/tests => tests}/python/tirx/base/test_ptx_griddepcontrol.py | 0
{tirx/tests => tests}/python/tirx/base/test_ptx_mma_sp.py | 0
{tirx/tests => tests}/python/tirx/base/test_ptx_scalar_f32_math.py | 0
{tirx/tests => tests}/python/tirx/base/test_scalable_datatype.py | 0
{tirx/tests => tests}/python/tirx/base/test_specialize.py | 0
{tirx/tests => tests}/python/tirx/base/test_tensor_type.py | 0
{tirx/tests => tests}/python/tirx/base/test_texture_scope.py | 0
{tirx/tests => tests}/python/tirx/codegen/__init__.py | 0
{tirx/tests => tests}/python/tirx/codegen/conftest.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_ampere.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_blackwell.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_cuda.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_cuda_cta_reduce.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_cuda_wait_until.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_cuda_warp_reduce.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_dsmem.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_hopper.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_nki.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_ptx_addr.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_ptx_cvt.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_ptx_dialect.py | 0
{tirx/tests => tests}/python/tirx/codegen/test_ptx_ld_st_ops.py | 0
.../python/tirx/codegen/test_tcgen05_descriptor_encoders.py | 0
{tirx/tests => tests}/python/tirx/conftest.py | 0
{tirx/tests => tests}/python/tirx/iket/__init__.py | 0
{tirx/tests => tests}/python/tirx/iket/iket_profile_workload.py | 0
{tirx/tests => tests}/python/tirx/iket/oracle/__init__.py | 0
.../python/tirx/iket/oracle/generate_iket_official_oracle.py | 0
.../python/tirx/iket/oracle/iket_official_cutlass_4_6_0_oracle.json | 0
{tirx/tests => tests}/python/tirx/iket/test_orchestration.py | 0
{tirx/tests => tests}/python/tirx/iket/test_profiler.py | 0
{tirx/tests => tests}/python/tirx/iket/verify_iket_official_patch.py | 0
{tirx/tests => tests}/python/tirx/layout_fixtures.py | 0
{tirx/tests => tests}/python/tirx/script/__init__.py | 0
{tirx/tests => tests}/python/tirx/script/test_basic_usage.py | 0
{tirx/tests => tests}/python/tirx/script/test_dynamic_shape.py | 0
{tirx/tests => tests}/python/tirx/script/test_error_handling.py | 0
{tirx/tests => tests}/python/tirx/script/test_gpu.py | 0
{tirx/tests => tests}/python/tirx/script/test_jit_specialization.py | 0
{tirx/tests => tests}/python/tirx/script/test_meta_programming.py | 0
{tirx/tests => tests}/python/tirx/script/test_printer_highlight.py | 0
.../python/tirx/script/test_printer_invisible_path_info.py | 0
{tirx/tests => tests}/python/tirx/script/test_printer_structural_equal.py | 0
{tirx/tests => tests}/python/tirx/script/test_printer_underlining.py | 0
{tirx/tests => tests}/python/tirx/script/test_source_locations.py | 0
{tirx/tests => tests}/python/tirx/script/test_tensors.py | 0
{tirx/tests => tests}/python/tirx/script/test_tracing.py | 0
{tirx/tests => tests}/python/tirx/test_alloc_pool.py | 0
{tirx/tests => tests}/python/tirx/test_axis_enum.py | 0
{tirx/tests => tests}/python/tirx/test_bench_utils.py | 0
{tirx/tests => tests}/python/tirx/test_compilation_pipeline.py | 0
{tirx/tests => tests}/python/tirx/test_control_flow.py | 0
{tirx/tests => tests}/python/tirx/test_cuda_arch_marker.py | 0
{tirx/tests => tests}/python/tirx/test_cuda_backend_config.py | 0
{tirx/tests => tests}/python/tirx/test_cuda_launch.py | 0
{tirx/tests => tests}/python/tirx/test_exec_context.py | 0
{tirx/tests => tests}/python/tirx/test_inline.py | 0
{tirx/tests => tests}/python/tirx/test_jit.py | 0
{tirx/tests => tests}/python/tirx/test_layout.py | 0
{tirx/tests => tests}/python/tirx/test_op.py | 0
{tirx/tests => tests}/python/tirx/test_op_namespace_cleanup.py | 0
{tirx/tests => tests}/python/tirx/test_roundtrip_namespaces.py | 0
{tirx/tests => tests}/python/tirx/test_tensor_data_reinfer_type.py | 0
{tirx/tests => tests}/python/tirx/test_thread_scope.py | 0
{tirx/tests => tests}/python/tirx/test_tile_namespace.py | 0
{tirx/tests => tests}/python/tirx/test_verifier.py | 0
{tirx/tests => tests}/python/tirx/tile/__init__.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/__init__.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/conftest.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_add_sub_mul_div.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_cp_async.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_cp_async_bulk.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_cp_async_bulk_tensor.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_cvt.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_ewise.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_explicit_patterns.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_fma.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_ld_st_cache_policy.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_ld_st_gmem_smem.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_ld_st_registers.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_ldmatrix_stmatrix.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_mma_sync.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_mov.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_pattern_groups.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_pattern_math.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_pattern_mma.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_pattern_transfers.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_tcgen05_cp.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_tcgen05_ld_st.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_tcgen05_mma.py | 0
{tirx/tests => tests}/python/tirx/tile/cuda/test_tcgen05_mma_codegen.py | 0
.../tests => tests}/python/tirx/tile/cuda/test_tcgen05_mma_ws_split_n.py | 0
{tirx/tests => tests}/python/tirx/tile/test_dispatcher.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/__init__.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/test_binary.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/test_compose_op.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/test_copy.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/test_gemm.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/test_private_alloc.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/test_reduction.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/test_select.py | 0
{tirx/tests => tests}/python/tirx/tile/trn/test_unary.py | 0
{tirx/tests => tests}/python/tirx/transform/__init__.py | 0
{tirx/tests => tests}/python/tirx/transform/test_bf16_legalize.py | 0
{tirx/tests => tests}/python/tirx/transform/test_common_subexpr_elim.py | 0
{tirx/tests => tests}/python/tirx/transform/test_convert_ssa.py | 0
{tirx/tests => tests}/python/tirx/transform/test_decorate_device_scope.py | 0
{tirx/tests => tests}/python/tirx/transform/test_flatten_tensor.py | 0
.../python/tirx/transform/test_force_narrow_index_to_i32.py | 0
{tirx/tests => tests}/python/tirx/transform/test_fp8_legalize.py | 0
{tirx/tests => tests}/python/tirx/transform/test_function_pass.py | 0
{tirx/tests => tests}/python/tirx/transform/test_helpers.py | 0
{tirx/tests => tests}/python/tirx/transform/test_hoist_if.py | 0
{tirx/tests => tests}/python/tirx/transform/test_lower_intrin.py | 0
{tirx/tests => tests}/python/tirx/transform/test_lower_tirx.py | 0
{tirx/tests => tests}/python/tirx/transform/test_lower_tvm_builtin.py | 0
{tirx/tests => tests}/python/tirx/transform/test_make_packed_api.py | 0
{tirx/tests => tests}/python/tirx/transform/test_naive_allocator.py | 0
{tirx/tests => tests}/python/tirx/transform/test_narrow_datatype.py | 0
.../python/tirx/transform/test_pointer_value_type_rewrite.py | 0
{tirx/tests => tests}/python/tirx/transform/test_remove_no_op.py | 0
.../python/tirx/transform/test_renormalize_split_pattern.py | 0
{tirx/tests => tests}/python/tirx/transform/test_simplify.py | 0
{tirx/tests => tests}/python/tirx/transform/test_split_host_device.py | 0
{tirx/tests => tests}/python/tirx/transform/test_storage_rewrite.py | 0
{tirx/tests => tests}/python/tirx/transform/test_unroll.py | 0
{tirx/tests => tests}/python/tirx/transform/test_vectorize.py | 0
{tirx/tests => tests}/python/tirx/utils.py | 0
{tirx/tests => tests}/scripts/task_build_arm.sh | 0
{tirx/tests => tests}/scripts/task_build_cpu.sh | 0
{tirx/tests => tests}/scripts/task_build_gpu.sh | 0
965 files changed, 0 insertions(+), 0 deletions(-)
diff --git a/tirx/3rdparty/compiler-rt/builtin_fp16.h b/3rdparty/compiler-rt/builtin_fp16.h
similarity index 100%
rename from tirx/3rdparty/compiler-rt/builtin_fp16.h
rename to 3rdparty/compiler-rt/builtin_fp16.h
diff --git a/tirx/3rdparty/tvm-ffi b/3rdparty/tvm-ffi
similarity index 100%
rename from tirx/3rdparty/tvm-ffi
rename to 3rdparty/tvm-ffi
diff --git a/tirx/CMakeLists.txt b/CMakeLists.txt
similarity index 100%
rename from tirx/CMakeLists.txt
rename to CMakeLists.txt
diff --git a/tirx/LICENSE b/LICENSE
similarity index 100%
rename from tirx/LICENSE
rename to LICENSE
diff --git a/tirx/NOTICE b/NOTICE
similarity index 100%
rename from tirx/NOTICE
rename to NOTICE
diff --git a/tirx/cmake/modules/CUDA.cmake b/cmake/modules/CUDA.cmake
similarity index 100%
rename from tirx/cmake/modules/CUDA.cmake
rename to cmake/modules/CUDA.cmake
diff --git a/tirx/cmake/modules/ClangFlags.cmake b/cmake/modules/ClangFlags.cmake
similarity index 100%
rename from tirx/cmake/modules/ClangFlags.cmake
rename to cmake/modules/ClangFlags.cmake
diff --git a/tirx/cmake/modules/Git.cmake b/cmake/modules/Git.cmake
similarity index 100%
rename from tirx/cmake/modules/Git.cmake
rename to cmake/modules/Git.cmake
diff --git a/tirx/cmake/modules/LLVM.cmake b/cmake/modules/LLVM.cmake
similarity index 100%
rename from tirx/cmake/modules/LLVM.cmake
rename to cmake/modules/LLVM.cmake
diff --git a/tirx/cmake/modules/Logging.cmake b/cmake/modules/Logging.cmake
similarity index 100%
rename from tirx/cmake/modules/Logging.cmake
rename to cmake/modules/Logging.cmake
diff --git a/tirx/cmake/modules/Metal.cmake b/cmake/modules/Metal.cmake
similarity index 100%
rename from tirx/cmake/modules/Metal.cmake
rename to cmake/modules/Metal.cmake
diff --git a/tirx/cmake/modules/OpenCL.cmake b/cmake/modules/OpenCL.cmake
similarity index 100%
rename from tirx/cmake/modules/OpenCL.cmake
rename to cmake/modules/OpenCL.cmake
diff --git a/tirx/cmake/modules/OpenMP.cmake b/cmake/modules/OpenMP.cmake
similarity index 100%
rename from tirx/cmake/modules/OpenMP.cmake
rename to cmake/modules/OpenMP.cmake
diff --git a/tirx/cmake/modules/ROCM.cmake b/cmake/modules/ROCM.cmake
similarity index 100%
rename from tirx/cmake/modules/ROCM.cmake
rename to cmake/modules/ROCM.cmake
diff --git a/tirx/cmake/modules/Vulkan.cmake b/cmake/modules/Vulkan.cmake
similarity index 100%
rename from tirx/cmake/modules/Vulkan.cmake
rename to cmake/modules/Vulkan.cmake
diff --git a/tirx/cmake/modules/contrib/Z3.cmake b/cmake/modules/contrib/Z3.cmake
similarity index 100%
rename from tirx/cmake/modules/contrib/Z3.cmake
rename to cmake/modules/contrib/Z3.cmake
diff --git a/tirx/cmake/tvm-tirx-config.in b/cmake/tvm-tirx-config.in
similarity index 100%
rename from tirx/cmake/tvm-tirx-config.in
rename to cmake/tvm-tirx-config.in
diff --git a/tirx/cmake/tvm_tirx-config.cmake b/cmake/tvm_tirx-config.cmake
similarity index 100%
rename from tirx/cmake/tvm_tirx-config.cmake
rename to cmake/tvm_tirx-config.cmake
diff --git a/tirx/cmake/utils/FindCUDA.cmake b/cmake/utils/FindCUDA.cmake
similarity index 100%
rename from tirx/cmake/utils/FindCUDA.cmake
rename to cmake/utils/FindCUDA.cmake
diff --git a/tirx/cmake/utils/FindLLVM.cmake b/cmake/utils/FindLLVM.cmake
similarity index 100%
rename from tirx/cmake/utils/FindLLVM.cmake
rename to cmake/utils/FindLLVM.cmake
diff --git a/tirx/cmake/utils/FindOpenCL.cmake b/cmake/utils/FindOpenCL.cmake
similarity index 100%
rename from tirx/cmake/utils/FindOpenCL.cmake
rename to cmake/utils/FindOpenCL.cmake
diff --git a/tirx/cmake/utils/FindROCM.cmake b/cmake/utils/FindROCM.cmake
similarity index 100%
rename from tirx/cmake/utils/FindROCM.cmake
rename to cmake/utils/FindROCM.cmake
diff --git a/tirx/cmake/utils/FindVulkan.cmake b/cmake/utils/FindVulkan.cmake
similarity index 100%
rename from tirx/cmake/utils/FindVulkan.cmake
rename to cmake/utils/FindVulkan.cmake
diff --git a/tirx/cmake/utils/Library.cmake b/cmake/utils/Library.cmake
similarity index 100%
rename from tirx/cmake/utils/Library.cmake
rename to cmake/utils/Library.cmake
diff --git a/tirx/include/tvm/backend/cuda/attr.h b/include/tvm/backend/cuda/attr.h
similarity index 100%
rename from tirx/include/tvm/backend/cuda/attr.h
rename to include/tvm/backend/cuda/attr.h
diff --git a/tirx/include/tvm/backend/cuda/op/iket.h b/include/tvm/backend/cuda/op/iket.h
similarity index 100%
rename from tirx/include/tvm/backend/cuda/op/iket.h
rename to include/tvm/backend/cuda/op/iket.h
diff --git a/tirx/include/tvm/backend/cuda/op/tcgen05.h b/include/tvm/backend/cuda/op/tcgen05.h
similarity index 100%
rename from tirx/include/tvm/backend/cuda/op/tcgen05.h
rename to include/tvm/backend/cuda/op/tcgen05.h
diff --git a/tirx/include/tvm/backend/cuda/op/tensormap.h b/include/tvm/backend/cuda/op/tensormap.h
similarity index 100%
rename from tirx/include/tvm/backend/cuda/op/tensormap.h
rename to include/tvm/backend/cuda/op/tensormap.h
diff --git a/tirx/include/tvm/backend/cuda/op_attr_types.h b/include/tvm/backend/cuda/op_attr_types.h
similarity index 100%
rename from tirx/include/tvm/backend/cuda/op_attr_types.h
rename to include/tvm/backend/cuda/op_attr_types.h
diff --git a/tirx/include/tvm/backend/metal/op/cooperative_tensor.h b/include/tvm/backend/metal/op/cooperative_tensor.h
similarity index 100%
rename from tirx/include/tvm/backend/metal/op/cooperative_tensor.h
rename to include/tvm/backend/metal/op/cooperative_tensor.h
diff --git a/tirx/include/tvm/backend/opencl/op/memory.h b/include/tvm/backend/opencl/op/memory.h
similarity index 100%
rename from tirx/include/tvm/backend/opencl/op/memory.h
rename to include/tvm/backend/opencl/op/memory.h
diff --git a/tirx/include/tvm/codegen/codegen.h b/include/tvm/codegen/codegen.h
similarity index 100%
rename from tirx/include/tvm/codegen/codegen.h
rename to include/tvm/codegen/codegen.h
diff --git a/tirx/include/tvm/codegen/intrin_rule.h b/include/tvm/codegen/intrin_rule.h
similarity index 100%
rename from tirx/include/tvm/codegen/intrin_rule.h
rename to include/tvm/codegen/intrin_rule.h
diff --git a/tirx/include/tvm/ir/analysis.h b/include/tvm/ir/analysis.h
similarity index 100%
rename from tirx/include/tvm/ir/analysis.h
rename to include/tvm/ir/analysis.h
diff --git a/tirx/include/tvm/ir/attrs.h b/include/tvm/ir/attrs.h
similarity index 100%
rename from tirx/include/tvm/ir/attrs.h
rename to include/tvm/ir/attrs.h
diff --git a/tirx/include/tvm/ir/base_expr.h b/include/tvm/ir/base_expr.h
similarity index 100%
rename from tirx/include/tvm/ir/base_expr.h
rename to include/tvm/ir/base_expr.h
diff --git a/tirx/include/tvm/ir/cow.h b/include/tvm/ir/cow.h
similarity index 100%
rename from tirx/include/tvm/ir/cow.h
rename to include/tvm/ir/cow.h
diff --git a/tirx/include/tvm/ir/env_func.h b/include/tvm/ir/env_func.h
similarity index 100%
rename from tirx/include/tvm/ir/env_func.h
rename to include/tvm/ir/env_func.h
diff --git a/tirx/include/tvm/ir/expr.h b/include/tvm/ir/expr.h
similarity index 100%
rename from tirx/include/tvm/ir/expr.h
rename to include/tvm/ir/expr.h
diff --git a/tirx/include/tvm/ir/expr_functor.h b/include/tvm/ir/expr_functor.h
similarity index 100%
rename from tirx/include/tvm/ir/expr_functor.h
rename to include/tvm/ir/expr_functor.h
diff --git a/tirx/include/tvm/ir/function.h b/include/tvm/ir/function.h
similarity index 100%
rename from tirx/include/tvm/ir/function.h
rename to include/tvm/ir/function.h
diff --git a/tirx/include/tvm/ir/global_info.h b/include/tvm/ir/global_info.h
similarity index 100%
rename from tirx/include/tvm/ir/global_info.h
rename to include/tvm/ir/global_info.h
diff --git a/tirx/include/tvm/ir/location.h b/include/tvm/ir/location.h
similarity index 100%
rename from tirx/include/tvm/ir/location.h
rename to include/tvm/ir/location.h
diff --git a/tirx/include/tvm/ir/module.h b/include/tvm/ir/module.h
similarity index 100%
rename from tirx/include/tvm/ir/module.h
rename to include/tvm/ir/module.h
diff --git a/tirx/include/tvm/ir/object_functor.h b/include/tvm/ir/object_functor.h
similarity index 100%
rename from tirx/include/tvm/ir/object_functor.h
rename to include/tvm/ir/object_functor.h
diff --git a/tirx/include/tvm/ir/op.h b/include/tvm/ir/op.h
similarity index 100%
rename from tirx/include/tvm/ir/op.h
rename to include/tvm/ir/op.h
diff --git a/tirx/include/tvm/ir/prim/expr.h b/include/tvm/ir/prim/expr.h
similarity index 100%
rename from tirx/include/tvm/ir/prim/expr.h
rename to include/tvm/ir/prim/expr.h
diff --git a/tirx/include/tvm/ir/prim/op.h b/include/tvm/ir/prim/op.h
similarity index 100%
rename from tirx/include/tvm/ir/prim/op.h
rename to include/tvm/ir/prim/op.h
diff --git a/tirx/include/tvm/ir/prim/vector_expr.h b/include/tvm/ir/prim/vector_expr.h
similarity index 100%
rename from tirx/include/tvm/ir/prim/vector_expr.h
rename to include/tvm/ir/prim/vector_expr.h
diff --git a/tirx/include/tvm/ir/scope_stack.h b/include/tvm/ir/scope_stack.h
similarity index 100%
rename from tirx/include/tvm/ir/scope_stack.h
rename to include/tvm/ir/scope_stack.h
diff --git a/tirx/include/tvm/ir/stmt.h b/include/tvm/ir/stmt.h
similarity index 100%
rename from tirx/include/tvm/ir/stmt.h
rename to include/tvm/ir/stmt.h
diff --git a/tirx/include/tvm/ir/transform.h b/include/tvm/ir/transform.h
similarity index 100%
rename from tirx/include/tvm/ir/transform.h
rename to include/tvm/ir/transform.h
diff --git a/tirx/include/tvm/ir/type.h b/include/tvm/ir/type.h
similarity index 100%
rename from tirx/include/tvm/ir/type.h
rename to include/tvm/ir/type.h
diff --git a/tirx/include/tvm/ir/unique_name_supply.h b/include/tvm/ir/unique_name_supply.h
similarity index 100%
rename from tirx/include/tvm/ir/unique_name_supply.h
rename to include/tvm/ir/unique_name_supply.h
diff --git a/tirx/include/tvm/ir/with_context.h b/include/tvm/ir/with_context.h
similarity index 100%
rename from tirx/include/tvm/ir/with_context.h
rename to include/tvm/ir/with_context.h
diff --git a/tirx/include/tvm/runtime/base.h b/include/tvm/runtime/base.h
similarity index 100%
rename from tirx/include/tvm/runtime/base.h
rename to include/tvm/runtime/base.h
diff --git a/tirx/include/tvm/runtime/c_backend_api.h b/include/tvm/runtime/c_backend_api.h
similarity index 100%
rename from tirx/include/tvm/runtime/c_backend_api.h
rename to include/tvm/runtime/c_backend_api.h
diff --git a/tirx/include/tvm/runtime/device_api.h b/include/tvm/runtime/device_api.h
similarity index 100%
rename from tirx/include/tvm/runtime/device_api.h
rename to include/tvm/runtime/device_api.h
diff --git a/tirx/include/tvm/runtime/logging.h b/include/tvm/runtime/logging.h
similarity index 100%
rename from tirx/include/tvm/runtime/logging.h
rename to include/tvm/runtime/logging.h
diff --git a/tirx/include/tvm/runtime/memory_scope.h b/include/tvm/runtime/memory_scope.h
similarity index 100%
rename from tirx/include/tvm/runtime/memory_scope.h
rename to include/tvm/runtime/memory_scope.h
diff --git a/tirx/include/tvm/runtime/tensor.h b/include/tvm/runtime/tensor.h
similarity index 100%
rename from tirx/include/tvm/runtime/tensor.h
rename to include/tvm/runtime/tensor.h
diff --git a/tirx/include/tvm/runtime/timer.h b/include/tvm/runtime/timer.h
similarity index 100%
rename from tirx/include/tvm/runtime/timer.h
rename to include/tvm/runtime/timer.h
diff --git a/tirx/include/tvm/script/ir_builder/base.h b/include/tvm/script/ir_builder/base.h
similarity index 100%
rename from tirx/include/tvm/script/ir_builder/base.h
rename to include/tvm/script/ir_builder/base.h
diff --git a/tirx/include/tvm/script/ir_builder/frame.h b/include/tvm/script/ir_builder/frame.h
similarity index 100%
rename from tirx/include/tvm/script/ir_builder/frame.h
rename to include/tvm/script/ir_builder/frame.h
diff --git a/tirx/include/tvm/script/ir_builder/ir.h b/include/tvm/script/ir_builder/ir.h
similarity index 100%
rename from tirx/include/tvm/script/ir_builder/ir.h
rename to include/tvm/script/ir_builder/ir.h
diff --git a/tirx/include/tvm/script/printer/config.h b/include/tvm/script/printer/config.h
similarity index 100%
rename from tirx/include/tvm/script/printer/config.h
rename to include/tvm/script/printer/config.h
diff --git a/tirx/include/tvm/script/printer/doc.h b/include/tvm/script/printer/doc.h
similarity index 100%
rename from tirx/include/tvm/script/printer/doc.h
rename to include/tvm/script/printer/doc.h
diff --git a/tirx/include/tvm/script/printer/doc_translator.h b/include/tvm/script/printer/doc_translator.h
similarity index 100%
rename from tirx/include/tvm/script/printer/doc_translator.h
rename to include/tvm/script/printer/doc_translator.h
diff --git a/tirx/include/tvm/script/printer/printer.h b/include/tvm/script/printer/printer.h
similarity index 100%
rename from tirx/include/tvm/script/printer/printer.h
rename to include/tvm/script/printer/printer.h
diff --git a/tirx/include/tvm/script/printer/support.h b/include/tvm/script/printer/support.h
similarity index 100%
rename from tirx/include/tvm/script/printer/support.h
rename to include/tvm/script/printer/support.h
diff --git a/tirx/include/tvm/support/bytes_io.h b/include/tvm/support/bytes_io.h
similarity index 100%
rename from tirx/include/tvm/support/bytes_io.h
rename to include/tvm/support/bytes_io.h
diff --git a/tirx/include/tvm/support/env.h b/include/tvm/support/env.h
similarity index 100%
rename from tirx/include/tvm/support/env.h
rename to include/tvm/support/env.h
diff --git a/tirx/include/tvm/support/file_utils.h b/include/tvm/support/file_utils.h
similarity index 100%
rename from tirx/include/tvm/support/file_utils.h
rename to include/tvm/support/file_utils.h
diff --git a/tirx/include/tvm/support/gpu_thread_tag.h b/include/tvm/support/gpu_thread_tag.h
similarity index 100%
rename from tirx/include/tvm/support/gpu_thread_tag.h
rename to include/tvm/support/gpu_thread_tag.h
diff --git a/tirx/include/tvm/support/io.h b/include/tvm/support/io.h
similarity index 100%
rename from tirx/include/tvm/support/io.h
rename to include/tvm/support/io.h
diff --git a/tirx/include/tvm/support/ordered_map.h b/include/tvm/support/ordered_map.h
similarity index 100%
rename from tirx/include/tvm/support/ordered_map.h
rename to include/tvm/support/ordered_map.h
diff --git a/tirx/include/tvm/support/serializer.h b/include/tvm/support/serializer.h
similarity index 100%
rename from tirx/include/tvm/support/serializer.h
rename to include/tvm/support/serializer.h
diff --git a/tirx/include/tvm/sym/analyzer.h b/include/tvm/sym/analyzer.h
similarity index 100%
rename from tirx/include/tvm/sym/analyzer.h
rename to include/tvm/sym/analyzer.h
diff --git a/tirx/include/tvm/sym/bound.h b/include/tvm/sym/bound.h
similarity index 100%
rename from tirx/include/tvm/sym/bound.h
rename to include/tvm/sym/bound.h
diff --git a/tirx/include/tvm/sym/int_set.h b/include/tvm/sym/int_set.h
similarity index 100%
rename from tirx/include/tvm/sym/int_set.h
rename to include/tvm/sym/int_set.h
diff --git a/tirx/include/tvm/sym/iter_affine_map.h b/include/tvm/sym/iter_affine_map.h
similarity index 100%
rename from tirx/include/tvm/sym/iter_affine_map.h
rename to include/tvm/sym/iter_affine_map.h
diff --git a/tirx/include/tvm/sym/pattern.h b/include/tvm/sym/pattern.h
similarity index 100%
rename from tirx/include/tvm/sym/pattern.h
rename to include/tvm/sym/pattern.h
diff --git a/tirx/include/tvm/target/config_schema.h b/include/tvm/target/config_schema.h
similarity index 100%
rename from tirx/include/tvm/target/config_schema.h
rename to include/tvm/target/config_schema.h
diff --git a/tirx/include/tvm/target/target.h b/include/tvm/target/target.h
similarity index 100%
rename from tirx/include/tvm/target/target.h
rename to include/tvm/target/target.h
diff --git a/tirx/include/tvm/target/target_kind.h b/include/tvm/target/target_kind.h
similarity index 100%
rename from tirx/include/tvm/target/target_kind.h
rename to include/tvm/target/target_kind.h
diff --git a/tirx/include/tvm/target/target_tag_registry.h b/include/tvm/target/target_tag_registry.h
similarity index 100%
rename from tirx/include/tvm/target/target_tag_registry.h
rename to include/tvm/target/target_tag_registry.h
diff --git a/tirx/include/tvm/tirx/analysis.h b/include/tvm/tirx/analysis.h
similarity index 100%
rename from tirx/include/tvm/tirx/analysis.h
rename to include/tvm/tirx/analysis.h
diff --git a/tirx/include/tvm/tirx/expr.h b/include/tvm/tirx/expr.h
similarity index 100%
rename from tirx/include/tvm/tirx/expr.h
rename to include/tvm/tirx/expr.h
diff --git a/tirx/include/tvm/tirx/function.h b/include/tvm/tirx/function.h
similarity index 100%
rename from tirx/include/tvm/tirx/function.h
rename to include/tvm/tirx/function.h
diff --git a/tirx/include/tvm/tirx/index_map.h b/include/tvm/tirx/index_map.h
similarity index 100%
rename from tirx/include/tvm/tirx/index_map.h
rename to include/tvm/tirx/index_map.h
diff --git a/tirx/include/tvm/tirx/layout.h b/include/tvm/tirx/layout.h
similarity index 100%
rename from tirx/include/tvm/tirx/layout.h
rename to include/tvm/tirx/layout.h
diff --git a/tirx/include/tvm/tirx/op/abi.h b/include/tvm/tirx/op/abi.h
similarity index 100%
rename from tirx/include/tvm/tirx/op/abi.h
rename to include/tvm/tirx/op/abi.h
diff --git a/tirx/include/tvm/tirx/op/annotation.h b/include/tvm/tirx/op/annotation.h
similarity index 100%
rename from tirx/include/tvm/tirx/op/annotation.h
rename to include/tvm/tirx/op/annotation.h
diff --git a/tirx/include/tvm/tirx/op/cpu.h b/include/tvm/tirx/op/cpu.h
similarity index 100%
rename from tirx/include/tvm/tirx/op/cpu.h
rename to include/tvm/tirx/op/cpu.h
diff --git a/tirx/include/tvm/tirx/op/gpu.h b/include/tvm/tirx/op/gpu.h
similarity index 100%
rename from tirx/include/tvm/tirx/op/gpu.h
rename to include/tvm/tirx/op/gpu.h
diff --git a/tirx/include/tvm/tirx/op/math.h b/include/tvm/tirx/op/math.h
similarity index 100%
rename from tirx/include/tvm/tirx/op/math.h
rename to include/tvm/tirx/op/math.h
diff --git a/tirx/include/tvm/tirx/op/memory.h b/include/tvm/tirx/op/memory.h
similarity index 100%
rename from tirx/include/tvm/tirx/op/memory.h
rename to include/tvm/tirx/op/memory.h
diff --git a/tirx/include/tvm/tirx/op/region.h b/include/tvm/tirx/op/region.h
similarity index 100%
rename from tirx/include/tvm/tirx/op/region.h
rename to include/tvm/tirx/op/region.h
diff --git a/tirx/include/tvm/tirx/op/vector.h b/include/tvm/tirx/op/vector.h
similarity index 100%
rename from tirx/include/tvm/tirx/op/vector.h
rename to include/tvm/tirx/op/vector.h
diff --git a/tirx/include/tvm/tirx/op_attr_types.h b/include/tvm/tirx/op_attr_types.h
similarity index 100%
rename from tirx/include/tvm/tirx/op_attr_types.h
rename to include/tvm/tirx/op_attr_types.h
diff --git a/tirx/include/tvm/tirx/script/ir_builder/frame.h b/include/tvm/tirx/script/ir_builder/frame.h
similarity index 100%
rename from tirx/include/tvm/tirx/script/ir_builder/frame.h
rename to include/tvm/tirx/script/ir_builder/frame.h
diff --git a/tirx/include/tvm/tirx/script/ir_builder/ir.h b/include/tvm/tirx/script/ir_builder/ir.h
similarity index 100%
rename from tirx/include/tvm/tirx/script/ir_builder/ir.h
rename to include/tvm/tirx/script/ir_builder/ir.h
diff --git a/tirx/include/tvm/tirx/stmt.h b/include/tvm/tirx/stmt.h
similarity index 100%
rename from tirx/include/tvm/tirx/stmt.h
rename to include/tvm/tirx/stmt.h
diff --git a/tirx/include/tvm/tirx/stmt_functor.h b/include/tvm/tirx/stmt_functor.h
similarity index 100%
rename from tirx/include/tvm/tirx/stmt_functor.h
rename to include/tvm/tirx/stmt_functor.h
diff --git a/tirx/include/tvm/tirx/stmt_functor_with_analyzer.h b/include/tvm/tirx/stmt_functor_with_analyzer.h
similarity index 100%
rename from tirx/include/tvm/tirx/stmt_functor_with_analyzer.h
rename to include/tvm/tirx/stmt_functor_with_analyzer.h
diff --git a/tirx/include/tvm/tirx/tile/context.h b/include/tvm/tirx/tile/context.h
similarity index 100%
rename from tirx/include/tvm/tirx/tile/context.h
rename to include/tvm/tirx/tile/context.h
diff --git a/tirx/include/tvm/tirx/tile/dispatch.h b/include/tvm/tirx/tile/dispatch.h
similarity index 100%
rename from tirx/include/tvm/tirx/tile/dispatch.h
rename to include/tvm/tirx/tile/dispatch.h
diff --git a/tirx/include/tvm/tirx/tile/op.h b/include/tvm/tirx/tile/op.h
similarity index 100%
rename from tirx/include/tvm/tirx/tile/op.h
rename to include/tvm/tirx/tile/op.h
diff --git a/tirx/include/tvm/tirx/tile/thread_scope.h b/include/tvm/tirx/tile/thread_scope.h
similarity index 100%
rename from tirx/include/tvm/tirx/tile/thread_scope.h
rename to include/tvm/tirx/tile/thread_scope.h
diff --git a/tirx/include/tvm/tirx/transform.h b/include/tvm/tirx/transform.h
similarity index 100%
rename from tirx/include/tvm/tirx/transform.h
rename to include/tvm/tirx/transform.h
diff --git a/tirx/include/tvm/tirx/type.h b/include/tvm/tirx/type.h
similarity index 100%
rename from tirx/include/tvm/tirx/type.h
rename to include/tvm/tirx/type.h
diff --git a/tirx/licenses/LICENSE.builtin_fp16.txt b/licenses/LICENSE.builtin_fp16.txt
similarity index 100%
rename from tirx/licenses/LICENSE.builtin_fp16.txt
rename to licenses/LICENSE.builtin_fp16.txt
diff --git a/tirx/pyproject.toml b/pyproject.toml
similarity index 100%
rename from tirx/pyproject.toml
rename to pyproject.toml
diff --git a/tirx/python/tvm_tirx/__init__.py b/python/tvm_tirx/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/__init__.py
rename to python/tvm_tirx/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/__init__.py b/python/tvm_tirx/backend/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/__init__.py
rename to python/tvm_tirx/backend/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/_autoload_backends.py b/python/tvm_tirx/backend/_autoload_backends.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/_autoload_backends.py
rename to python/tvm_tirx/backend/_autoload_backends.py
diff --git a/tirx/python/tvm_tirx/backend/adreno/__init__.py b/python/tvm_tirx/backend/adreno/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/adreno/__init__.py
rename to python/tvm_tirx/backend/adreno/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/adreno/target_tags.py b/python/tvm_tirx/backend/adreno/target_tags.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/adreno/target_tags.py
rename to python/tvm_tirx/backend/adreno/target_tags.py
diff --git a/tirx/python/tvm_tirx/backend/config.py b/python/tvm_tirx/backend/config.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/config.py
rename to python/tvm_tirx/backend/config.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/__init__.py b/python/tvm_tirx/backend/cuda/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/__init__.py
rename to python/tvm_tirx/backend/cuda/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/axis.py b/python/tvm_tirx/backend/cuda/axis.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/axis.py
rename to python/tvm_tirx/backend/cuda/axis.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/backend_config.py b/python/tvm_tirx/backend/cuda/backend_config.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/backend_config.py
rename to python/tvm_tirx/backend/cuda/backend_config.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/codegen/__init__.py b/python/tvm_tirx/backend/cuda/codegen/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/codegen/__init__.py
rename to python/tvm_tirx/backend/cuda/codegen/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/codegen/header.py b/python/tvm_tirx/backend/cuda/codegen/header.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/codegen/header.py
rename to python/tvm_tirx/backend/cuda/codegen/header.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/codegen/registry.py b/python/tvm_tirx/backend/cuda/codegen/registry.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/codegen/registry.py
rename to python/tvm_tirx/backend/cuda/codegen/registry.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/codegen/schema.py b/python/tvm_tirx/backend/cuda/codegen/schema.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/codegen/schema.py
rename to python/tvm_tirx/backend/cuda/codegen/schema.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/codegen/types.py b/python/tvm_tirx/backend/cuda/codegen/types.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/codegen/types.py
rename to python/tvm_tirx/backend/cuda/codegen/types.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/codegen/utils.py b/python/tvm_tirx/backend/cuda/codegen/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/codegen/utils.py
rename to python/tvm_tirx/backend/cuda/codegen/utils.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/compiler.py b/python/tvm_tirx/backend/cuda/compiler.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/compiler.py
rename to python/tvm_tirx/backend/cuda/compiler.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/__init__.py b/python/tvm_tirx/backend/cuda/cpp/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/cpp/__init__.py
rename to python/tvm_tirx/backend/cuda/cpp/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/asm.py b/python/tvm_tirx/backend/cuda/cpp/asm.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/cpp/asm.py
rename to python/tvm_tirx/backend/cuda/cpp/asm.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/builtins.py b/python/tvm_tirx/backend/cuda/cpp/builtins.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/cpp/builtins.py
rename to python/tvm_tirx/backend/cuda/cpp/builtins.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/descriptors.py b/python/tvm_tirx/backend/cuda/cpp/descriptors.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/cpp/descriptors.py
rename to python/tvm_tirx/backend/cuda/cpp/descriptors.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/instrument.py b/python/tvm_tirx/backend/cuda/cpp/instrument.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/cpp/instrument.py
rename to python/tvm_tirx/backend/cuda/cpp/instrument.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/cpp/nvshmem.py b/python/tvm_tirx/backend/cuda/cpp/nvshmem.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/cpp/nvshmem.py
rename to python/tvm_tirx/backend/cuda/cpp/nvshmem.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/host.py b/python/tvm_tirx/backend/cuda/host.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/host.py
rename to python/tvm_tirx/backend/cuda/host.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/iket.py b/python/tvm_tirx/backend/cuda/iket.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/iket.py
rename to python/tvm_tirx/backend/cuda/iket.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/lang/__init__.py b/python/tvm_tirx/backend/cuda/lang/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/lang/__init__.py
rename to python/tvm_tirx/backend/cuda/lang/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/lang/alloc_pool.py b/python/tvm_tirx/backend/cuda/lang/alloc_pool.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/lang/alloc_pool.py
rename to python/tvm_tirx/backend/cuda/lang/alloc_pool.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/lang/clc.py b/python/tvm_tirx/backend/cuda/lang/clc.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/lang/clc.py
rename to python/tvm_tirx/backend/cuda/lang/clc.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/lang/pipeline.py b/python/tvm_tirx/backend/cuda/lang/pipeline.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/lang/pipeline.py
rename to python/tvm_tirx/backend/cuda/lang/pipeline.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/lang/tile_scheduler.py b/python/tvm_tirx/backend/cuda/lang/tile_scheduler.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/lang/tile_scheduler.py
rename to python/tvm_tirx/backend/cuda/lang/tile_scheduler.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/launch/__init__.py b/python/tvm_tirx/backend/cuda/launch/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/launch/__init__.py
rename to python/tvm_tirx/backend/cuda/launch/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/launch/_generated.py b/python/tvm_tirx/backend/cuda/launch/_generated.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/launch/_generated.py
rename to python/tvm_tirx/backend/cuda/launch/_generated.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/launch/_impl.py b/python/tvm_tirx/backend/cuda/launch/_impl.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/launch/_impl.py
rename to python/tvm_tirx/backend/cuda/launch/_impl.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/launch/generate.py b/python/tvm_tirx/backend/cuda/launch/generate.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/launch/generate.py
rename to python/tvm_tirx/backend/cuda/launch/generate.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/launch/table.py b/python/tvm_tirx/backend/cuda/launch/table.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/launch/table.py
rename to python/tvm_tirx/backend/cuda/launch/table.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/layout.py b/python/tvm_tirx/backend/cuda/layout.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/layout.py
rename to python/tvm_tirx/backend/cuda/layout.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/op.py b/python/tvm_tirx/backend/cuda/op.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/op.py
rename to python/tvm_tirx/backend/cuda/op.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/__init__.py b/python/tvm_tirx/backend/cuda/ptx/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/ptx/__init__.py
rename to python/tvm_tirx/backend/cuda/ptx/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/engine.py b/python/tvm_tirx/backend/cuda/ptx/engine.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/ptx/engine.py
rename to python/tvm_tirx/backend/cuda/ptx/engine.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/gen_coverage.py b/python/tvm_tirx/backend/cuda/ptx/gen_coverage.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/ptx/gen_coverage.py
rename to python/tvm_tirx/backend/cuda/ptx/gen_coverage.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/gen_helpers.py b/python/tvm_tirx/backend/cuda/ptx/gen_helpers.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/ptx/gen_helpers.py
rename to python/tvm_tirx/backend/cuda/ptx/gen_helpers.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/gen_stubs.py b/python/tvm_tirx/backend/cuda/ptx/gen_stubs.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/ptx/gen_stubs.py
rename to python/tvm_tirx/backend/cuda/ptx/gen_stubs.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/render.py b/python/tvm_tirx/backend/cuda/ptx/render.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/ptx/render.py
rename to python/tvm_tirx/backend/cuda/ptx/render.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/ptx/table.py b/python/tvm_tirx/backend/cuda/ptx/table.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/ptx/table.py
rename to python/tvm_tirx/backend/cuda/ptx/table.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/script.py b/python/tvm_tirx/backend/cuda/script.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/script.py
rename to python/tvm_tirx/backend/cuda/script.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/target_tags.py b/python/tvm_tirx/backend/cuda/target_tags.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/target_tags.py
rename to python/tvm_tirx/backend/cuda/target_tags.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/thread_scope.py b/python/tvm_tirx/backend/cuda/thread_scope.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/thread_scope.py
rename to python/tvm_tirx/backend/cuda/thread_scope.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/__init__.py b/python/tvm_tirx/backend/cuda/tile/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/__init__.py
rename to python/tvm_tirx/backend/cuda/tile/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/exec_context.py b/python/tvm_tirx/backend/cuda/tile/exec_context.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/exec_context.py
rename to python/tvm_tirx/backend/cuda/tile/exec_context.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/instructions.py b/python/tvm_tirx/backend/cuda/tile/instructions.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/instructions.py
rename to python/tvm_tirx/backend/cuda/tile/instructions.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/__init__.py b/python/tvm_tirx/backend/cuda/tile/patterns/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/__init__.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/async_copy.py b/python/tvm_tirx/backend/cuda/tile/patterns/async_copy.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/async_copy.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/async_copy.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/common.py b/python/tvm_tirx/backend/cuda/tile/patterns/common.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/common.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/common.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/descriptors.py b/python/tvm_tirx/backend/cuda/tile/patterns/descriptors.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/descriptors.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/descriptors.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/ewise.py b/python/tvm_tirx/backend/cuda/tile/patterns/ewise.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/ewise.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/ewise.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/ldmatrix.py b/python/tvm_tirx/backend/cuda/tile/patterns/ldmatrix.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/ldmatrix.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/ldmatrix.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/memory.py b/python/tvm_tirx/backend/cuda/tile/patterns/memory.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/memory.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/memory.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/mma.py b/python/tvm_tirx/backend/cuda/tile/patterns/mma.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/mma.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/mma.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/register.py b/python/tvm_tirx/backend/cuda/tile/patterns/register.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/register.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/register.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py b/python/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/tcgen05_mma.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tma.py b/python/tvm_tirx/backend/cuda/tile/patterns/tma.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/tma.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/tma.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tmem.py b/python/tvm_tirx/backend/cuda/tile/patterns/tmem.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/tmem.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/tmem.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/tile/patterns/tmem_copy.py b/python/tvm_tirx/backend/cuda/tile/patterns/tmem_copy.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/tile/patterns/tmem_copy.py
rename to python/tvm_tirx/backend/cuda/tile/patterns/tmem_copy.py
diff --git a/tirx/python/tvm_tirx/backend/cuda/transforms/__init__.py b/python/tvm_tirx/backend/cuda/transforms/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/cuda/transforms/__init__.py
rename to python/tvm_tirx/backend/cuda/transforms/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/hexagon/__init__.py b/python/tvm_tirx/backend/hexagon/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/hexagon/__init__.py
rename to python/tvm_tirx/backend/hexagon/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/hexagon/linker.py b/python/tvm_tirx/backend/hexagon/linker.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/hexagon/linker.py
rename to python/tvm_tirx/backend/hexagon/linker.py
diff --git a/tirx/python/tvm_tirx/backend/hexagon/target_tags.py b/python/tvm_tirx/backend/hexagon/target_tags.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/hexagon/target_tags.py
rename to python/tvm_tirx/backend/hexagon/target_tags.py
diff --git a/tirx/python/tvm_tirx/backend/loader.py b/python/tvm_tirx/backend/loader.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/loader.py
rename to python/tvm_tirx/backend/loader.py
diff --git a/tirx/python/tvm_tirx/backend/metal/__init__.py b/python/tvm_tirx/backend/metal/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/metal/__init__.py
rename to python/tvm_tirx/backend/metal/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/metal/op.py b/python/tvm_tirx/backend/metal/op.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/metal/op.py
rename to python/tvm_tirx/backend/metal/op.py
diff --git a/tirx/python/tvm_tirx/backend/metal/script.py b/python/tvm_tirx/backend/metal/script.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/metal/script.py
rename to python/tvm_tirx/backend/metal/script.py
diff --git a/tirx/python/tvm_tirx/backend/metal/target_tags.py b/python/tvm_tirx/backend/metal/target_tags.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/metal/target_tags.py
rename to python/tvm_tirx/backend/metal/target_tags.py
diff --git a/tirx/python/tvm_tirx/backend/opencl/__init__.py b/python/tvm_tirx/backend/opencl/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/opencl/__init__.py
rename to python/tvm_tirx/backend/opencl/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/opencl/script.py b/python/tvm_tirx/backend/opencl/script.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/opencl/script.py
rename to python/tvm_tirx/backend/opencl/script.py
diff --git a/tirx/python/tvm_tirx/backend/rocm/__init__.py b/python/tvm_tirx/backend/rocm/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/rocm/__init__.py
rename to python/tvm_tirx/backend/rocm/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/__init__.py b/python/tvm_tirx/backend/trn/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/__init__.py
rename to python/tvm_tirx/backend/trn/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/axis.py b/python/tvm_tirx/backend/trn/axis.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/axis.py
rename to python/tvm_tirx/backend/trn/axis.py
diff --git a/tirx/python/tvm_tirx/backend/trn/layout.py b/python/tvm_tirx/backend/trn/layout.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/layout.py
rename to python/tvm_tirx/backend/trn/layout.py
diff --git a/tirx/python/tvm_tirx/backend/trn/op.py b/python/tvm_tirx/backend/trn/op.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/op.py
rename to python/tvm_tirx/backend/trn/op.py
diff --git a/tirx/python/tvm_tirx/backend/trn/pipeline.py b/python/tvm_tirx/backend/trn/pipeline.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/pipeline.py
rename to python/tvm_tirx/backend/trn/pipeline.py
diff --git a/tirx/python/tvm_tirx/backend/trn/script.py b/python/tvm_tirx/backend/trn/script.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/script.py
rename to python/tvm_tirx/backend/trn/script.py
diff --git a/tirx/python/tvm_tirx/backend/trn/target_tags.py b/python/tvm_tirx/backend/trn/target_tags.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/target_tags.py
rename to python/tvm_tirx/backend/trn/target_tags.py
diff --git a/tirx/python/tvm_tirx/backend/trn/thread_scope.py b/python/tvm_tirx/backend/trn/thread_scope.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/thread_scope.py
rename to python/tvm_tirx/backend/trn/thread_scope.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/__init__.py b/python/tvm_tirx/backend/trn/tile/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/__init__.py
rename to python/tvm_tirx/backend/trn/tile/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/binary/__init__.py b/python/tvm_tirx/backend/trn/tile/binary/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/binary/__init__.py
rename to python/tvm_tirx/backend/trn/tile/binary/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/binary/default.py b/python/tvm_tirx/backend/trn/tile/binary/default.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/binary/default.py
rename to python/tvm_tirx/backend/trn/tile/binary/default.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/binary/utils.py b/python/tvm_tirx/backend/trn/tile/binary/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/binary/utils.py
rename to python/tvm_tirx/backend/trn/tile/binary/utils.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/common.py b/python/tvm_tirx/backend/trn/tile/common.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/common.py
rename to python/tvm_tirx/backend/trn/tile/common.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/compose_op/__init__.py b/python/tvm_tirx/backend/trn/tile/compose_op/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/compose_op/__init__.py
rename to python/tvm_tirx/backend/trn/tile/compose_op/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/compose_op/binary_chain.py b/python/tvm_tirx/backend/trn/tile/compose_op/binary_chain.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/compose_op/binary_chain.py
rename to python/tvm_tirx/backend/trn/tile/compose_op/binary_chain.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/compose_op/binary_reduce.py b/python/tvm_tirx/backend/trn/tile/compose_op/binary_reduce.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/compose_op/binary_reduce.py
rename to python/tvm_tirx/backend/trn/tile/compose_op/binary_reduce.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/compose_op/unary_reduce.py b/python/tvm_tirx/backend/trn/tile/compose_op/unary_reduce.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/compose_op/unary_reduce.py
rename to python/tvm_tirx/backend/trn/tile/compose_op/unary_reduce.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/compose_op/utils.py b/python/tvm_tirx/backend/trn/tile/compose_op/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/compose_op/utils.py
rename to python/tvm_tirx/backend/trn/tile/compose_op/utils.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/copy/__init__.py b/python/tvm_tirx/backend/trn/tile/copy/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/copy/__init__.py
rename to python/tvm_tirx/backend/trn/tile/copy/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/copy/default.py b/python/tvm_tirx/backend/trn/tile/copy/default.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/copy/default.py
rename to python/tvm_tirx/backend/trn/tile/copy/default.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/dim_utils.py b/python/tvm_tirx/backend/trn/tile/dim_utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/dim_utils.py
rename to python/tvm_tirx/backend/trn/tile/dim_utils.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/gemm/__init__.py b/python/tvm_tirx/backend/trn/tile/gemm/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/gemm/__init__.py
rename to python/tvm_tirx/backend/trn/tile/gemm/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/gemm/default.py b/python/tvm_tirx/backend/trn/tile/gemm/default.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/gemm/default.py
rename to python/tvm_tirx/backend/trn/tile/gemm/default.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/instruction_generator.py b/python/tvm_tirx/backend/trn/tile/instruction_generator.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/instruction_generator.py
rename to python/tvm_tirx/backend/trn/tile/instruction_generator.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/instructions.py b/python/tvm_tirx/backend/trn/tile/instructions.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/instructions.py
rename to python/tvm_tirx/backend/trn/tile/instructions.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/private_alloc.py b/python/tvm_tirx/backend/trn/tile/private_alloc.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/private_alloc.py
rename to python/tvm_tirx/backend/trn/tile/private_alloc.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/reduction/__init__.py b/python/tvm_tirx/backend/trn/tile/reduction/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/reduction/__init__.py
rename to python/tvm_tirx/backend/trn/tile/reduction/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/reduction/utils.py b/python/tvm_tirx/backend/trn/tile/reduction/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/reduction/utils.py
rename to python/tvm_tirx/backend/trn/tile/reduction/utils.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/select/__init__.py b/python/tvm_tirx/backend/trn/tile/select/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/select/__init__.py
rename to python/tvm_tirx/backend/trn/tile/select/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/select/default.py b/python/tvm_tirx/backend/trn/tile/select/default.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/select/default.py
rename to python/tvm_tirx/backend/trn/tile/select/default.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/unary/__init__.py b/python/tvm_tirx/backend/trn/tile/unary/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/unary/__init__.py
rename to python/tvm_tirx/backend/trn/tile/unary/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/unary/default.py b/python/tvm_tirx/backend/trn/tile/unary/default.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/unary/default.py
rename to python/tvm_tirx/backend/trn/tile/unary/default.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/unary/utils.py b/python/tvm_tirx/backend/trn/tile/unary/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/unary/utils.py
rename to python/tvm_tirx/backend/trn/tile/unary/utils.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/unary/with_bias_scale.py b/python/tvm_tirx/backend/trn/tile/unary/with_bias_scale.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/unary/with_bias_scale.py
rename to python/tvm_tirx/backend/trn/tile/unary/with_bias_scale.py
diff --git a/tirx/python/tvm_tirx/backend/trn/tile/workspace_utils.py b/python/tvm_tirx/backend/trn/tile/workspace_utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/tile/workspace_utils.py
rename to python/tvm_tirx/backend/trn/tile/workspace_utils.py
diff --git a/tirx/python/tvm_tirx/backend/trn/transform/__init__.py b/python/tvm_tirx/backend/trn/transform/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/transform/__init__.py
rename to python/tvm_tirx/backend/trn/transform/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/trn/transform/naive_allocator.py b/python/tvm_tirx/backend/trn/transform/naive_allocator.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/transform/naive_allocator.py
rename to python/tvm_tirx/backend/trn/transform/naive_allocator.py
diff --git a/tirx/python/tvm_tirx/backend/trn/transform/private_tensor_alloc.py b/python/tvm_tirx/backend/trn/transform/private_tensor_alloc.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/trn/transform/private_tensor_alloc.py
rename to python/tvm_tirx/backend/trn/transform/private_tensor_alloc.py
diff --git a/tirx/python/tvm_tirx/backend/vulkan/__init__.py b/python/tvm_tirx/backend/vulkan/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/vulkan/__init__.py
rename to python/tvm_tirx/backend/vulkan/__init__.py
diff --git a/tirx/python/tvm_tirx/backend/webgpu/__init__.py b/python/tvm_tirx/backend/webgpu/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/backend/webgpu/__init__.py
rename to python/tvm_tirx/backend/webgpu/__init__.py
diff --git a/tirx/python/tvm_tirx/base.py b/python/tvm_tirx/base.py
similarity index 100%
rename from tirx/python/tvm_tirx/base.py
rename to python/tvm_tirx/base.py
diff --git a/tirx/python/tvm_tirx/codegen/__init__.py b/python/tvm_tirx/codegen/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/codegen/__init__.py
rename to python/tvm_tirx/codegen/__init__.py
diff --git a/tirx/python/tvm_tirx/codegen/executable.py b/python/tvm_tirx/codegen/executable.py
similarity index 100%
rename from tirx/python/tvm_tirx/codegen/executable.py
rename to python/tvm_tirx/codegen/executable.py
diff --git a/tirx/python/tvm_tirx/codegen/llvm.py b/python/tvm_tirx/codegen/llvm.py
similarity index 100%
rename from tirx/python/tvm_tirx/codegen/llvm.py
rename to python/tvm_tirx/codegen/llvm.py
diff --git a/tirx/python/tvm_tirx/config.py b/python/tvm_tirx/config.py
similarity index 100%
rename from tirx/python/tvm_tirx/config.py
rename to python/tvm_tirx/config.py
diff --git a/tirx/python/tvm_tirx/ir/__init__.py b/python/tvm_tirx/ir/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/__init__.py
rename to python/tvm_tirx/ir/__init__.py
diff --git a/tirx/python/tvm_tirx/ir/_constant.py b/python/tvm_tirx/ir/_constant.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/_constant.py
rename to python/tvm_tirx/ir/_constant.py
diff --git a/tirx/python/tvm_tirx/ir/_ffi_api.py b/python/tvm_tirx/ir/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/_ffi_api.py
rename to python/tvm_tirx/ir/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/ir/_overload_prim_expr.py b/python/tvm_tirx/ir/_overload_prim_expr.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/_overload_prim_expr.py
rename to python/tvm_tirx/ir/_overload_prim_expr.py
diff --git a/tirx/python/tvm_tirx/ir/_tensor_expr_overload.py b/python/tvm_tirx/ir/_tensor_expr_overload.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/_tensor_expr_overload.py
rename to python/tvm_tirx/ir/_tensor_expr_overload.py
diff --git a/tirx/python/tvm_tirx/ir/attrs.py b/python/tvm_tirx/ir/attrs.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/attrs.py
rename to python/tvm_tirx/ir/attrs.py
diff --git a/tirx/python/tvm_tirx/ir/base.py b/python/tvm_tirx/ir/base.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/base.py
rename to python/tvm_tirx/ir/base.py
diff --git a/tirx/python/tvm_tirx/ir/expr.py b/python/tvm_tirx/ir/expr.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/expr.py
rename to python/tvm_tirx/ir/expr.py
diff --git a/tirx/python/tvm_tirx/ir/function.py b/python/tvm_tirx/ir/function.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/function.py
rename to python/tvm_tirx/ir/function.py
diff --git a/tirx/python/tvm_tirx/ir/global_info.py b/python/tvm_tirx/ir/global_info.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/global_info.py
rename to python/tvm_tirx/ir/global_info.py
diff --git a/tirx/python/tvm_tirx/ir/json_compact.py b/python/tvm_tirx/ir/json_compact.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/json_compact.py
rename to python/tvm_tirx/ir/json_compact.py
diff --git a/tirx/python/tvm_tirx/ir/location.py b/python/tvm_tirx/ir/location.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/location.py
rename to python/tvm_tirx/ir/location.py
diff --git a/tirx/python/tvm_tirx/ir/module.py b/python/tvm_tirx/ir/module.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/module.py
rename to python/tvm_tirx/ir/module.py
diff --git a/tirx/python/tvm_tirx/ir/op.py b/python/tvm_tirx/ir/op.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/op.py
rename to python/tvm_tirx/ir/op.py
diff --git a/tirx/python/tvm_tirx/ir/prim/__init__.py b/python/tvm_tirx/ir/prim/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/prim/__init__.py
rename to python/tvm_tirx/ir/prim/__init__.py
diff --git a/tirx/python/tvm_tirx/ir/prim/_ffi_api.py b/python/tvm_tirx/ir/prim/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/prim/_ffi_api.py
rename to python/tvm_tirx/ir/prim/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/ir/prim/expr.py b/python/tvm_tirx/ir/prim/expr.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/prim/expr.py
rename to python/tvm_tirx/ir/prim/expr.py
diff --git a/tirx/python/tvm_tirx/ir/prim/op.py b/python/tvm_tirx/ir/prim/op.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/prim/op.py
rename to python/tvm_tirx/ir/prim/op.py
diff --git a/tirx/python/tvm_tirx/ir/prim/vector_expr.py b/python/tvm_tirx/ir/prim/vector_expr.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/prim/vector_expr.py
rename to python/tvm_tirx/ir/prim/vector_expr.py
diff --git a/tirx/python/tvm_tirx/ir/stmt.py b/python/tvm_tirx/ir/stmt.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/stmt.py
rename to python/tvm_tirx/ir/stmt.py
diff --git a/tirx/python/tvm_tirx/ir/transform/__init__.py b/python/tvm_tirx/ir/transform/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/transform/__init__.py
rename to python/tvm_tirx/ir/transform/__init__.py
diff --git a/tirx/python/tvm_tirx/ir/transform/_ffi_instrument_api.py b/python/tvm_tirx/ir/transform/_ffi_instrument_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/transform/_ffi_instrument_api.py
rename to python/tvm_tirx/ir/transform/_ffi_instrument_api.py
diff --git a/tirx/python/tvm_tirx/ir/transform/_ffi_transform_api.py b/python/tvm_tirx/ir/transform/_ffi_transform_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/transform/_ffi_transform_api.py
rename to python/tvm_tirx/ir/transform/_ffi_transform_api.py
diff --git a/tirx/python/tvm_tirx/ir/transform/core.py b/python/tvm_tirx/ir/transform/core.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/transform/core.py
rename to python/tvm_tirx/ir/transform/core.py
diff --git a/tirx/python/tvm_tirx/ir/transform/instrument.py b/python/tvm_tirx/ir/transform/instrument.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/transform/instrument.py
rename to python/tvm_tirx/ir/transform/instrument.py
diff --git a/tirx/python/tvm_tirx/ir/type.py b/python/tvm_tirx/ir/type.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/type.py
rename to python/tvm_tirx/ir/type.py
diff --git a/tirx/python/tvm_tirx/ir/unique_name_supply.py b/python/tvm_tirx/ir/unique_name_supply.py
similarity index 100%
rename from tirx/python/tvm_tirx/ir/unique_name_supply.py
rename to python/tvm_tirx/ir/unique_name_supply.py
diff --git a/tirx/python/tvm_tirx/libinfo.py b/python/tvm_tirx/libinfo.py
similarity index 100%
rename from tirx/python/tvm_tirx/libinfo.py
rename to python/tvm_tirx/libinfo.py
diff --git a/tirx/python/tvm_tirx/runtime/__init__.py b/python/tvm_tirx/runtime/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/runtime/__init__.py
rename to python/tvm_tirx/runtime/__init__.py
diff --git a/tirx/python/tvm_tirx/runtime/_ffi_api.py b/python/tvm_tirx/runtime/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/runtime/_ffi_api.py
rename to python/tvm_tirx/runtime/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/runtime/_tensor.py b/python/tvm_tirx/runtime/_tensor.py
similarity index 100%
rename from tirx/python/tvm_tirx/runtime/_tensor.py
rename to python/tvm_tirx/runtime/_tensor.py
diff --git a/tirx/python/tvm_tirx/runtime/device.py b/python/tvm_tirx/runtime/device.py
similarity index 100%
rename from tirx/python/tvm_tirx/runtime/device.py
rename to python/tvm_tirx/runtime/device.py
diff --git a/tirx/python/tvm_tirx/runtime/memory_scope.py b/python/tvm_tirx/runtime/memory_scope.py
similarity index 100%
rename from tirx/python/tvm_tirx/runtime/memory_scope.py
rename to python/tvm_tirx/runtime/memory_scope.py
diff --git a/tirx/python/tvm_tirx/script/__init__.py b/python/tvm_tirx/script/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/__init__.py
rename to python/tvm_tirx/script/__init__.py
diff --git a/tirx/python/tvm_tirx/script/_ffi_api.py b/python/tvm_tirx/script/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/_ffi_api.py
rename to python/tvm_tirx/script/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/script/ir_builder/__init__.py b/python/tvm_tirx/script/ir_builder/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/ir_builder/__init__.py
rename to python/tvm_tirx/script/ir_builder/__init__.py
diff --git a/tirx/python/tvm_tirx/script/ir_builder/_ffi_api.py b/python/tvm_tirx/script/ir_builder/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/ir_builder/_ffi_api.py
rename to python/tvm_tirx/script/ir_builder/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/script/ir_builder/base.py b/python/tvm_tirx/script/ir_builder/base.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/ir_builder/base.py
rename to python/tvm_tirx/script/ir_builder/base.py
diff --git a/tirx/python/tvm_tirx/script/ir_builder/frame.py b/python/tvm_tirx/script/ir_builder/frame.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/ir_builder/frame.py
rename to python/tvm_tirx/script/ir_builder/frame.py
diff --git a/tirx/python/tvm_tirx/script/ir_builder/ir.py b/python/tvm_tirx/script/ir_builder/ir.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/ir_builder/ir.py
rename to python/tvm_tirx/script/ir_builder/ir.py
diff --git a/tirx/python/tvm_tirx/script/ir_builder/parser_protocol.py b/python/tvm_tirx/script/ir_builder/parser_protocol.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/ir_builder/parser_protocol.py
rename to python/tvm_tirx/script/ir_builder/parser_protocol.py
diff --git a/tirx/python/tvm_tirx/script/ir_builder/stmt.py b/python/tvm_tirx/script/ir_builder/stmt.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/ir_builder/stmt.py
rename to python/tvm_tirx/script/ir_builder/stmt.py
diff --git a/tirx/python/tvm_tirx/script/ir_builder/tracing.py b/python/tvm_tirx/script/ir_builder/tracing.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/ir_builder/tracing.py
rename to python/tvm_tirx/script/ir_builder/tracing.py
diff --git a/tirx/python/tvm_tirx/script/parser/__init__.py b/python/tvm_tirx/script/parser/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/parser/__init__.py
rename to python/tvm_tirx/script/parser/__init__.py
diff --git a/tirx/python/tvm_tirx/script/parser/entry.py b/python/tvm_tirx/script/parser/entry.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/parser/entry.py
rename to python/tvm_tirx/script/parser/entry.py
diff --git a/tirx/python/tvm_tirx/script/parser/inspect_source.py b/python/tvm_tirx/script/parser/inspect_source.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/parser/inspect_source.py
rename to python/tvm_tirx/script/parser/inspect_source.py
diff --git a/tirx/python/tvm_tirx/script/parser/ir.py b/python/tvm_tirx/script/parser/ir.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/parser/ir.py
rename to python/tvm_tirx/script/parser/ir.py
diff --git a/tirx/python/tvm_tirx/script/parser/jit_support.py b/python/tvm_tirx/script/parser/jit_support.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/parser/jit_support.py
rename to python/tvm_tirx/script/parser/jit_support.py
diff --git a/tirx/python/tvm_tirx/script/parser/prescan.py b/python/tvm_tirx/script/parser/prescan.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/parser/prescan.py
rename to python/tvm_tirx/script/parser/prescan.py
diff --git a/tirx/python/tvm_tirx/script/parser/protocol_registry.py b/python/tvm_tirx/script/parser/protocol_registry.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/parser/protocol_registry.py
rename to python/tvm_tirx/script/parser/protocol_registry.py
diff --git a/tirx/python/tvm_tirx/script/parser/transpile.py b/python/tvm_tirx/script/parser/transpile.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/parser/transpile.py
rename to python/tvm_tirx/script/parser/transpile.py
diff --git a/tirx/python/tvm_tirx/script/printer/__init__.py b/python/tvm_tirx/script/printer/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/printer/__init__.py
rename to python/tvm_tirx/script/printer/__init__.py
diff --git a/tirx/python/tvm_tirx/script/printer/_ffi_api.py b/python/tvm_tirx/script/printer/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/printer/_ffi_api.py
rename to python/tvm_tirx/script/printer/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/script/printer/doc.py b/python/tvm_tirx/script/printer/doc.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/printer/doc.py
rename to python/tvm_tirx/script/printer/doc.py
diff --git a/tirx/python/tvm_tirx/script/printer/doc_printer.py b/python/tvm_tirx/script/printer/doc_printer.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/printer/doc_printer.py
rename to python/tvm_tirx/script/printer/doc_printer.py
diff --git a/tirx/python/tvm_tirx/script/printer/highlight.py b/python/tvm_tirx/script/printer/highlight.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/printer/highlight.py
rename to python/tvm_tirx/script/printer/highlight.py
diff --git a/tirx/python/tvm_tirx/script/printer/scriptable.py b/python/tvm_tirx/script/printer/scriptable.py
similarity index 100%
rename from tirx/python/tvm_tirx/script/printer/scriptable.py
rename to python/tvm_tirx/script/printer/scriptable.py
diff --git a/tirx/python/tvm_tirx/script/tirx.pyi b/python/tvm_tirx/script/tirx.pyi
similarity index 100%
rename from tirx/python/tvm_tirx/script/tirx.pyi
rename to python/tvm_tirx/script/tirx.pyi
diff --git a/tirx/python/tvm_tirx/support/__init__.py b/python/tvm_tirx/support/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/__init__.py
rename to python/tvm_tirx/support/__init__.py
diff --git a/tirx/python/tvm_tirx/support/cc.py b/python/tvm_tirx/support/cc.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/cc.py
rename to python/tvm_tirx/support/cc.py
diff --git a/tirx/python/tvm_tirx/support/clang.py b/python/tvm_tirx/support/clang.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/clang.py
rename to python/tvm_tirx/support/clang.py
diff --git a/tirx/python/tvm_tirx/support/libinfo.py b/python/tvm_tirx/support/libinfo.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/libinfo.py
rename to python/tvm_tirx/support/libinfo.py
diff --git a/tirx/python/tvm_tirx/support/ndk.py b/python/tvm_tirx/support/ndk.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/ndk.py
rename to python/tvm_tirx/support/ndk.py
diff --git a/tirx/python/tvm_tirx/support/nvcc.py b/python/tvm_tirx/support/nvcc.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/nvcc.py
rename to python/tvm_tirx/support/nvcc.py
diff --git a/tirx/python/tvm_tirx/support/popen_pool.py b/python/tvm_tirx/support/popen_pool.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/popen_pool.py
rename to python/tvm_tirx/support/popen_pool.py
diff --git a/tirx/python/tvm_tirx/support/popen_worker.py b/python/tvm_tirx/support/popen_worker.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/popen_worker.py
rename to python/tvm_tirx/support/popen_worker.py
diff --git a/tirx/python/tvm_tirx/support/rocm.py b/python/tvm_tirx/support/rocm.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/rocm.py
rename to python/tvm_tirx/support/rocm.py
diff --git a/tirx/python/tvm_tirx/support/tar.py b/python/tvm_tirx/support/tar.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/tar.py
rename to python/tvm_tirx/support/tar.py
diff --git a/tirx/python/tvm_tirx/support/utils.py b/python/tvm_tirx/support/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/utils.py
rename to python/tvm_tirx/support/utils.py
diff --git a/tirx/python/tvm_tirx/support/xcode.py b/python/tvm_tirx/support/xcode.py
similarity index 100%
rename from tirx/python/tvm_tirx/support/xcode.py
rename to python/tvm_tirx/support/xcode.py
diff --git a/tirx/python/tvm_tirx/sym/__init__.py b/python/tvm_tirx/sym/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/sym/__init__.py
rename to python/tvm_tirx/sym/__init__.py
diff --git a/tirx/python/tvm_tirx/sym/_ffi_api.py b/python/tvm_tirx/sym/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/sym/_ffi_api.py
rename to python/tvm_tirx/sym/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/sym/analyzer.py b/python/tvm_tirx/sym/analyzer.py
similarity index 100%
rename from tirx/python/tvm_tirx/sym/analyzer.py
rename to python/tvm_tirx/sym/analyzer.py
diff --git a/tirx/python/tvm_tirx/sym/bound.py b/python/tvm_tirx/sym/bound.py
similarity index 100%
rename from tirx/python/tvm_tirx/sym/bound.py
rename to python/tvm_tirx/sym/bound.py
diff --git a/tirx/python/tvm_tirx/sym/int_set.py b/python/tvm_tirx/sym/int_set.py
similarity index 100%
rename from tirx/python/tvm_tirx/sym/int_set.py
rename to python/tvm_tirx/sym/int_set.py
diff --git a/tirx/python/tvm_tirx/sym/iter_affine_map.py b/python/tvm_tirx/sym/iter_affine_map.py
similarity index 100%
rename from tirx/python/tvm_tirx/sym/iter_affine_map.py
rename to python/tvm_tirx/sym/iter_affine_map.py
diff --git a/tirx/python/tvm_tirx/sym/pattern.py b/python/tvm_tirx/sym/pattern.py
similarity index 100%
rename from tirx/python/tvm_tirx/sym/pattern.py
rename to python/tvm_tirx/sym/pattern.py
diff --git a/tirx/python/tvm_tirx/sym/utils.py b/python/tvm_tirx/sym/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/sym/utils.py
rename to python/tvm_tirx/sym/utils.py
diff --git a/tirx/python/tvm_tirx/target/__init__.py b/python/tvm_tirx/target/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/__init__.py
rename to python/tvm_tirx/target/__init__.py
diff --git a/tirx/python/tvm_tirx/target/_ffi_api.py b/python/tvm_tirx/target/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/_ffi_api.py
rename to python/tvm_tirx/target/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/target/detect_target.py b/python/tvm_tirx/target/detect_target.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/detect_target.py
rename to python/tvm_tirx/target/detect_target.py
diff --git a/tirx/python/tvm_tirx/target/tag.py b/python/tvm_tirx/target/tag.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/tag.py
rename to python/tvm_tirx/target/tag.py
diff --git a/tirx/python/tvm_tirx/target/tag_registry/__init__.py b/python/tvm_tirx/target/tag_registry/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/tag_registry/__init__.py
rename to python/tvm_tirx/target/tag_registry/__init__.py
diff --git a/tirx/python/tvm_tirx/target/tag_registry/arm_cpu.py b/python/tvm_tirx/target/tag_registry/arm_cpu.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/tag_registry/arm_cpu.py
rename to python/tvm_tirx/target/tag_registry/arm_cpu.py
diff --git a/tirx/python/tvm_tirx/target/tag_registry/aws_cpu.py b/python/tvm_tirx/target/tag_registry/aws_cpu.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/tag_registry/aws_cpu.py
rename to python/tvm_tirx/target/tag_registry/aws_cpu.py
diff --git a/tirx/python/tvm_tirx/target/tag_registry/registry.py b/python/tvm_tirx/target/tag_registry/registry.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/tag_registry/registry.py
rename to python/tvm_tirx/target/tag_registry/registry.py
diff --git a/tirx/python/tvm_tirx/target/tag_registry/riscv_cpu.py b/python/tvm_tirx/target/tag_registry/riscv_cpu.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/tag_registry/riscv_cpu.py
rename to python/tvm_tirx/target/tag_registry/riscv_cpu.py
diff --git a/tirx/python/tvm_tirx/target/target.py b/python/tvm_tirx/target/target.py
similarity index 100%
rename from tirx/python/tvm_tirx/target/target.py
rename to python/tvm_tirx/target/target.py
diff --git a/tirx/python/tvm_tirx/testing/__init__.py b/python/tvm_tirx/testing/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/testing/__init__.py
rename to python/tvm_tirx/testing/__init__.py
diff --git a/tirx/python/tvm_tirx/testing/_ffi_api.py b/python/tvm_tirx/testing/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/testing/_ffi_api.py
rename to python/tvm_tirx/testing/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/testing/_pytest.py b/python/tvm_tirx/testing/_pytest.py
similarity index 100%
rename from tirx/python/tvm_tirx/testing/_pytest.py
rename to python/tvm_tirx/testing/_pytest.py
diff --git a/tirx/python/tvm_tirx/testing/env.py b/python/tvm_tirx/testing/env.py
similarity index 100%
rename from tirx/python/tvm_tirx/testing/env.py
rename to python/tvm_tirx/testing/env.py
diff --git a/tirx/python/tvm_tirx/testing/locking.py b/python/tvm_tirx/testing/locking.py
similarity index 100%
rename from tirx/python/tvm_tirx/testing/locking.py
rename to python/tvm_tirx/testing/locking.py
diff --git a/tirx/python/tvm_tirx/testing/popen_pool.py b/python/tvm_tirx/testing/popen_pool.py
similarity index 100%
rename from tirx/python/tvm_tirx/testing/popen_pool.py
rename to python/tvm_tirx/testing/popen_pool.py
diff --git a/tirx/python/tvm_tirx/testing/utils.py b/python/tvm_tirx/testing/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/testing/utils.py
rename to python/tvm_tirx/testing/utils.py
diff --git a/tirx/python/tvm_tirx/tirx/__init__.py b/python/tvm_tirx/tirx/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/__init__.py
rename to python/tvm_tirx/tirx/__init__.py
diff --git a/tirx/python/tvm_tirx/tirx/_compile.py b/python/tvm_tirx/tirx/_compile.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/_compile.py
rename to python/tvm_tirx/tirx/_compile.py
diff --git a/tirx/python/tvm_tirx/tirx/_ffi_api.py b/python/tvm_tirx/tirx/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/_ffi_api.py
rename to python/tvm_tirx/tirx/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/tirx/_tensor_view.py b/python/tvm_tirx/tirx/_tensor_view.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/_tensor_view.py
rename to python/tvm_tirx/tirx/_tensor_view.py
diff --git a/tirx/python/tvm_tirx/tirx/analysis/__init__.py b/python/tvm_tirx/tirx/analysis/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/analysis/__init__.py
rename to python/tvm_tirx/tirx/analysis/__init__.py
diff --git a/tirx/python/tvm_tirx/tirx/analysis/_ffi_api.py b/python/tvm_tirx/tirx/analysis/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/analysis/_ffi_api.py
rename to python/tvm_tirx/tirx/analysis/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/tirx/analysis/analysis.py b/python/tvm_tirx/tirx/analysis/analysis.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/analysis/analysis.py
rename to python/tvm_tirx/tirx/analysis/analysis.py
diff --git a/tirx/python/tvm_tirx/tirx/bench.py b/python/tvm_tirx/tirx/bench.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/bench.py
rename to python/tvm_tirx/tirx/bench.py
diff --git a/tirx/python/tvm_tirx/tirx/compilation_pipeline.py b/python/tvm_tirx/tirx/compilation_pipeline.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/compilation_pipeline.py
rename to python/tvm_tirx/tirx/compilation_pipeline.py
diff --git a/tirx/python/tvm_tirx/tirx/expr.py b/python/tvm_tirx/tirx/expr.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/expr.py
rename to python/tvm_tirx/tirx/expr.py
diff --git a/tirx/python/tvm_tirx/tirx/function.py b/python/tvm_tirx/tirx/function.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/function.py
rename to python/tvm_tirx/tirx/function.py
diff --git a/tirx/python/tvm_tirx/tirx/index_map.py b/python/tvm_tirx/tirx/index_map.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/index_map.py
rename to python/tvm_tirx/tirx/index_map.py
diff --git a/tirx/python/tvm_tirx/tirx/layout.py b/python/tvm_tirx/tirx/layout.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/layout.py
rename to python/tvm_tirx/tirx/layout.py
diff --git a/tirx/python/tvm_tirx/tirx/op/__init__.py b/python/tvm_tirx/tirx/op/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/op/__init__.py
rename to python/tvm_tirx/tirx/op/__init__.py
diff --git a/tirx/python/tvm_tirx/tirx/script/__init__.py b/python/tvm_tirx/tirx/script/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/__init__.py
rename to python/tvm_tirx/tirx/script/__init__.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/__init__.py b/python/tvm_tirx/tirx/script/ir_builder/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/__init__.py
rename to python/tvm_tirx/tirx/script/ir_builder/__init__.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/_ffi_api.py b/python/tvm_tirx/tirx/script/ir_builder/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/_ffi_api.py
rename to python/tvm_tirx/tirx/script/ir_builder/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/external_kernel.py b/python/tvm_tirx/tirx/script/ir_builder/external_kernel.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/external_kernel.py
rename to python/tvm_tirx/tirx/script/ir_builder/external_kernel.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/frame.py b/python/tvm_tirx/tirx/script/ir_builder/frame.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/frame.py
rename to python/tvm_tirx/tirx/script/ir_builder/frame.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/ir.py b/python/tvm_tirx/tirx/script/ir_builder/ir.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/ir.py
rename to python/tvm_tirx/tirx/script/ir_builder/ir.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/op.py b/python/tvm_tirx/tirx/script/ir_builder/op.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/op.py
rename to python/tvm_tirx/tirx/script/ir_builder/op.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py b/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
rename to python/tvm_tirx/tirx/script/ir_builder/parser_protocol.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/triton.py b/python/tvm_tirx/tirx/script/ir_builder/triton.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/triton.py
rename to python/tvm_tirx/tirx/script/ir_builder/triton.py
diff --git a/tirx/python/tvm_tirx/tirx/script/ir_builder/utils.py b/python/tvm_tirx/tirx/script/ir_builder/utils.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/ir_builder/utils.py
rename to python/tvm_tirx/tirx/script/ir_builder/utils.py
diff --git a/tirx/python/tvm_tirx/tirx/script/jit.py b/python/tvm_tirx/tirx/script/jit.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/script/jit.py
rename to python/tvm_tirx/tirx/script/jit.py
diff --git a/tirx/python/tvm_tirx/tirx/tensor.py b/python/tvm_tirx/tirx/tensor.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/tensor.py
rename to python/tvm_tirx/tirx/tensor.py
diff --git a/tirx/python/tvm_tirx/tirx/thread_scope.py b/python/tvm_tirx/tirx/thread_scope.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/thread_scope.py
rename to python/tvm_tirx/tirx/thread_scope.py
diff --git a/tirx/python/tvm_tirx/tirx/tile/__init__.py b/python/tvm_tirx/tirx/tile/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/tile/__init__.py
rename to python/tvm_tirx/tirx/tile/__init__.py
diff --git a/tirx/python/tvm_tirx/tirx/tile/common.py b/python/tvm_tirx/tirx/tile/common.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/tile/common.py
rename to python/tvm_tirx/tirx/tile/common.py
diff --git a/tirx/python/tvm_tirx/tirx/tile/dispatch.py b/python/tvm_tirx/tirx/tile/dispatch.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/tile/dispatch.py
rename to python/tvm_tirx/tirx/tile/dispatch.py
diff --git a/tirx/python/tvm_tirx/tirx/tile/instruction.py b/python/tvm_tirx/tirx/tile/instruction.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/tile/instruction.py
rename to python/tvm_tirx/tirx/tile/instruction.py
diff --git a/tirx/python/tvm_tirx/tirx/tile/views.py b/python/tvm_tirx/tirx/tile/views.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/tile/views.py
rename to python/tvm_tirx/tirx/tile/views.py
diff --git a/tirx/python/tvm_tirx/tirx/transform/__init__.py b/python/tvm_tirx/tirx/transform/__init__.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/transform/__init__.py
rename to python/tvm_tirx/tirx/transform/__init__.py
diff --git a/tirx/python/tvm_tirx/tirx/transform/_ffi_api.py b/python/tvm_tirx/tirx/transform/_ffi_api.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/transform/_ffi_api.py
rename to python/tvm_tirx/tirx/transform/_ffi_api.py
diff --git a/tirx/python/tvm_tirx/tirx/transform/common.py b/python/tvm_tirx/tirx/transform/common.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/transform/common.py
rename to python/tvm_tirx/tirx/transform/common.py
diff --git a/tirx/python/tvm_tirx/tirx/transform/function_pass.py b/python/tvm_tirx/tirx/transform/function_pass.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/transform/function_pass.py
rename to python/tvm_tirx/tirx/transform/function_pass.py
diff --git a/tirx/python/tvm_tirx/tirx/transform/transform.py b/python/tvm_tirx/tirx/transform/transform.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/transform/transform.py
rename to python/tvm_tirx/tirx/transform/transform.py
diff --git a/tirx/python/tvm_tirx/tirx/type.py b/python/tvm_tirx/tirx/type.py
similarity index 100%
rename from tirx/python/tvm_tirx/tirx/type.py
rename to python/tvm_tirx/tirx/type.py
diff --git a/tirx/src/backend/cuda/codegen/codegen_cuda.cc b/src/backend/cuda/codegen/codegen_cuda.cc
similarity index 100%
rename from tirx/src/backend/cuda/codegen/codegen_cuda.cc
rename to src/backend/cuda/codegen/codegen_cuda.cc
diff --git a/tirx/src/backend/cuda/codegen/codegen_cuda.h b/src/backend/cuda/codegen/codegen_cuda.h
similarity index 100%
rename from tirx/src/backend/cuda/codegen/codegen_cuda.h
rename to src/backend/cuda/codegen/codegen_cuda.h
diff --git a/tirx/src/backend/cuda/codegen/codegen_cuda_host.cc b/src/backend/cuda/codegen/codegen_cuda_host.cc
similarity index 100%
rename from tirx/src/backend/cuda/codegen/codegen_cuda_host.cc
rename to src/backend/cuda/codegen/codegen_cuda_host.cc
diff --git a/tirx/src/backend/cuda/codegen/cuda_fallback_module.cc b/src/backend/cuda/codegen/cuda_fallback_module.cc
similarity index 100%
rename from tirx/src/backend/cuda/codegen/cuda_fallback_module.cc
rename to src/backend/cuda/codegen/cuda_fallback_module.cc
diff --git a/tirx/src/backend/cuda/codegen/cuda_fallback_module.h b/src/backend/cuda/codegen/cuda_fallback_module.h
similarity index 100%
rename from tirx/src/backend/cuda/codegen/cuda_fallback_module.h
rename to src/backend/cuda/codegen/cuda_fallback_module.h
diff --git a/tirx/src/backend/cuda/codegen/intrin_rule_cuda.cc b/src/backend/cuda/codegen/intrin_rule_cuda.cc
similarity index 100%
rename from tirx/src/backend/cuda/codegen/intrin_rule_cuda.cc
rename to src/backend/cuda/codegen/intrin_rule_cuda.cc
diff --git a/tirx/src/backend/cuda/codegen/literal/cuda_half_t.h b/src/backend/cuda/codegen/literal/cuda_half_t.h
similarity index 100%
rename from tirx/src/backend/cuda/codegen/literal/cuda_half_t.h
rename to src/backend/cuda/codegen/literal/cuda_half_t.h
diff --git a/tirx/src/backend/cuda/codegen/literal/cuda_int8_t.h b/src/backend/cuda/codegen/literal/cuda_int8_t.h
similarity index 100%
rename from tirx/src/backend/cuda/codegen/literal/cuda_int8_t.h
rename to src/backend/cuda/codegen/literal/cuda_int8_t.h
diff --git a/tirx/src/backend/cuda/codegen/llvm/codegen_nvptx.cc b/src/backend/cuda/codegen/llvm/codegen_nvptx.cc
similarity index 100%
rename from tirx/src/backend/cuda/codegen/llvm/codegen_nvptx.cc
rename to src/backend/cuda/codegen/llvm/codegen_nvptx.cc
diff --git a/tirx/src/backend/cuda/codegen/llvm/intrin_rule_nvptx.cc b/src/backend/cuda/codegen/llvm/intrin_rule_nvptx.cc
similarity index 100%
rename from tirx/src/backend/cuda/codegen/llvm/intrin_rule_nvptx.cc
rename to src/backend/cuda/codegen/llvm/intrin_rule_nvptx.cc
diff --git a/tirx/src/backend/cuda/codegen/ptx.cc b/src/backend/cuda/codegen/ptx.cc
similarity index 100%
rename from tirx/src/backend/cuda/codegen/ptx.cc
rename to src/backend/cuda/codegen/ptx.cc
diff --git a/tirx/src/backend/cuda/codegen/target_kind.cc b/src/backend/cuda/codegen/target_kind.cc
similarity index 100%
rename from tirx/src/backend/cuda/codegen/target_kind.cc
rename to src/backend/cuda/codegen/target_kind.cc
diff --git a/tirx/src/backend/cuda/launch/launch_attributes.h b/src/backend/cuda/launch/launch_attributes.h
similarity index 100%
rename from tirx/src/backend/cuda/launch/launch_attributes.h
rename to src/backend/cuda/launch/launch_attributes.h
diff --git a/tirx/src/backend/cuda/launch/launch_config.h b/src/backend/cuda/launch/launch_config.h
similarity index 100%
rename from tirx/src/backend/cuda/launch/launch_config.h
rename to src/backend/cuda/launch/launch_config.h
diff --git a/tirx/src/backend/cuda/launch/launch_fields.h b/src/backend/cuda/launch/launch_fields.h
similarity index 100%
rename from tirx/src/backend/cuda/launch/launch_fields.h
rename to src/backend/cuda/launch/launch_fields.h
diff --git a/tirx/src/backend/cuda/launch/launch_plan.h b/src/backend/cuda/launch/launch_plan.h
similarity index 100%
rename from tirx/src/backend/cuda/launch/launch_plan.h
rename to src/backend/cuda/launch/launch_plan.h
diff --git a/tirx/src/backend/cuda/launch/launch_source.h b/src/backend/cuda/launch/launch_source.h
similarity index 100%
rename from tirx/src/backend/cuda/launch/launch_source.h
rename to src/backend/cuda/launch/launch_source.h
diff --git a/tirx/src/backend/cuda/layout/axis.cc b/src/backend/cuda/layout/axis.cc
similarity index 100%
rename from tirx/src/backend/cuda/layout/axis.cc
rename to src/backend/cuda/layout/axis.cc
diff --git a/tirx/src/backend/cuda/op/iket.cc b/src/backend/cuda/op/iket.cc
similarity index 100%
rename from tirx/src/backend/cuda/op/iket.cc
rename to src/backend/cuda/op/iket.cc
diff --git a/tirx/src/backend/cuda/op/legacy.cc b/src/backend/cuda/op/legacy.cc
similarity index 100%
rename from tirx/src/backend/cuda/op/legacy.cc
rename to src/backend/cuda/op/legacy.cc
diff --git a/tirx/src/backend/cuda/op/target_builtin.cc b/src/backend/cuda/op/target_builtin.cc
similarity index 100%
rename from tirx/src/backend/cuda/op/target_builtin.cc
rename to src/backend/cuda/op/target_builtin.cc
diff --git a/tirx/src/backend/cuda/op/tcgen05.cc b/src/backend/cuda/op/tcgen05.cc
similarity index 100%
rename from tirx/src/backend/cuda/op/tcgen05.cc
rename to src/backend/cuda/op/tcgen05.cc
diff --git a/tirx/src/backend/cuda/op/tensormap.cc b/src/backend/cuda/op/tensormap.cc
similarity index 100%
rename from tirx/src/backend/cuda/op/tensormap.cc
rename to src/backend/cuda/op/tensormap.cc
diff --git a/tirx/src/backend/cuda/runtime/cuda_device_api.cc b/src/backend/cuda/runtime/cuda_device_api.cc
similarity index 100%
rename from tirx/src/backend/cuda/runtime/cuda_device_api.cc
rename to src/backend/cuda/runtime/cuda_device_api.cc
diff --git a/tirx/src/backend/cuda/runtime/cuda_module.cc b/src/backend/cuda/runtime/cuda_module.cc
similarity index 100%
rename from tirx/src/backend/cuda/runtime/cuda_module.cc
rename to src/backend/cuda/runtime/cuda_module.cc
diff --git a/tirx/src/backend/cuda/tile/exec_analysis.cc b/src/backend/cuda/tile/exec_analysis.cc
similarity index 100%
rename from tirx/src/backend/cuda/tile/exec_analysis.cc
rename to src/backend/cuda/tile/exec_analysis.cc
diff --git a/tirx/src/backend/cuda/tile/exec_analysis.h b/src/backend/cuda/tile/exec_analysis.h
similarity index 100%
rename from tirx/src/backend/cuda/tile/exec_analysis.h
rename to src/backend/cuda/tile/exec_analysis.h
diff --git a/tirx/src/backend/cuda/tile/exec_context.cc b/src/backend/cuda/tile/exec_context.cc
similarity index 100%
rename from tirx/src/backend/cuda/tile/exec_context.cc
rename to src/backend/cuda/tile/exec_context.cc
diff --git a/tirx/src/backend/cuda/tile/exec_context.h b/src/backend/cuda/tile/exec_context.h
similarity index 100%
rename from tirx/src/backend/cuda/tile/exec_context.h
rename to src/backend/cuda/tile/exec_context.h
diff --git a/tirx/src/backend/cuda/tile/filter_canonical.cc b/src/backend/cuda/tile/filter_canonical.cc
similarity index 100%
rename from tirx/src/backend/cuda/tile/filter_canonical.cc
rename to src/backend/cuda/tile/filter_canonical.cc
diff --git a/tirx/src/backend/cuda/tile/filter_canonical.h b/src/backend/cuda/tile/filter_canonical.h
similarity index 100%
rename from tirx/src/backend/cuda/tile/filter_canonical.h
rename to src/backend/cuda/tile/filter_canonical.h
diff --git a/tirx/src/backend/cuda/tile/thread_scope.cc b/src/backend/cuda/tile/thread_scope.cc
similarity index 100%
rename from tirx/src/backend/cuda/tile/thread_scope.cc
rename to src/backend/cuda/tile/thread_scope.cc
diff --git a/tirx/src/backend/cuda/tile/thread_scope.h b/src/backend/cuda/tile/thread_scope.h
similarity index 100%
rename from tirx/src/backend/cuda/tile/thread_scope.h
rename to src/backend/cuda/tile/thread_scope.h
diff --git a/tirx/src/backend/cuda/transforms/bind_backend_config.cc b/src/backend/cuda/transforms/bind_backend_config.cc
similarity index 100%
rename from tirx/src/backend/cuda/transforms/bind_backend_config.cc
rename to src/backend/cuda/transforms/bind_backend_config.cc
diff --git a/tirx/src/backend/cuda/transforms/lower_iket.cc b/src/backend/cuda/transforms/lower_iket.cc
similarity index 100%
rename from tirx/src/backend/cuda/transforms/lower_iket.cc
rename to src/backend/cuda/transforms/lower_iket.cc
diff --git a/tirx/src/backend/hexagon/codegen/hexagon_fallback_module.cc b/src/backend/hexagon/codegen/hexagon_fallback_module.cc
similarity index 100%
rename from tirx/src/backend/hexagon/codegen/hexagon_fallback_module.cc
rename to src/backend/hexagon/codegen/hexagon_fallback_module.cc
diff --git a/tirx/src/backend/hexagon/codegen/hexagon_fallback_module.h b/src/backend/hexagon/codegen/hexagon_fallback_module.h
similarity index 100%
rename from tirx/src/backend/hexagon/codegen/hexagon_fallback_module.h
rename to src/backend/hexagon/codegen/hexagon_fallback_module.h
diff --git a/tirx/src/backend/hexagon/codegen/llvm/codegen_hexagon.cc b/src/backend/hexagon/codegen/llvm/codegen_hexagon.cc
similarity index 100%
rename from tirx/src/backend/hexagon/codegen/llvm/codegen_hexagon.cc
rename to src/backend/hexagon/codegen/llvm/codegen_hexagon.cc
diff --git a/tirx/src/backend/hexagon/codegen/llvm/intrin_rule_hexagon.cc b/src/backend/hexagon/codegen/llvm/intrin_rule_hexagon.cc
similarity index 100%
rename from tirx/src/backend/hexagon/codegen/llvm/intrin_rule_hexagon.cc
rename to src/backend/hexagon/codegen/llvm/intrin_rule_hexagon.cc
diff --git a/tirx/src/backend/hexagon/codegen/memory_scope.h b/src/backend/hexagon/codegen/memory_scope.h
similarity index 100%
rename from tirx/src/backend/hexagon/codegen/memory_scope.h
rename to src/backend/hexagon/codegen/memory_scope.h
diff --git a/tirx/src/backend/hexagon/codegen/target_kind.cc b/src/backend/hexagon/codegen/target_kind.cc
similarity index 100%
rename from tirx/src/backend/hexagon/codegen/target_kind.cc
rename to src/backend/hexagon/codegen/target_kind.cc
diff --git a/tirx/src/backend/metal/codegen/codegen_metal.cc b/src/backend/metal/codegen/codegen_metal.cc
similarity index 100%
rename from tirx/src/backend/metal/codegen/codegen_metal.cc
rename to src/backend/metal/codegen/codegen_metal.cc
diff --git a/tirx/src/backend/metal/codegen/codegen_metal.h b/src/backend/metal/codegen/codegen_metal.h
similarity index 100%
rename from tirx/src/backend/metal/codegen/codegen_metal.h
rename to src/backend/metal/codegen/codegen_metal.h
diff --git a/tirx/src/backend/metal/codegen/intrin_rule_metal.cc b/src/backend/metal/codegen/intrin_rule_metal.cc
similarity index 100%
rename from tirx/src/backend/metal/codegen/intrin_rule_metal.cc
rename to src/backend/metal/codegen/intrin_rule_metal.cc
diff --git a/tirx/src/backend/metal/codegen/metal_fallback_module.cc b/src/backend/metal/codegen/metal_fallback_module.cc
similarity index 100%
rename from tirx/src/backend/metal/codegen/metal_fallback_module.cc
rename to src/backend/metal/codegen/metal_fallback_module.cc
diff --git a/tirx/src/backend/metal/codegen/metal_fallback_module.h b/src/backend/metal/codegen/metal_fallback_module.h
similarity index 100%
rename from tirx/src/backend/metal/codegen/metal_fallback_module.h
rename to src/backend/metal/codegen/metal_fallback_module.h
diff --git a/tirx/src/backend/metal/codegen/target_kind.cc b/src/backend/metal/codegen/target_kind.cc
similarity index 100%
rename from tirx/src/backend/metal/codegen/target_kind.cc
rename to src/backend/metal/codegen/target_kind.cc
diff --git a/tirx/src/backend/metal/op/cooperative_tensor.cc b/src/backend/metal/op/cooperative_tensor.cc
similarity index 100%
rename from tirx/src/backend/metal/op/cooperative_tensor.cc
rename to src/backend/metal/op/cooperative_tensor.cc
diff --git a/tirx/src/backend/metal/op/target_builtin.cc b/src/backend/metal/op/target_builtin.cc
similarity index 100%
rename from tirx/src/backend/metal/op/target_builtin.cc
rename to src/backend/metal/op/target_builtin.cc
diff --git a/tirx/src/backend/metal/runtime/metal_common.h b/src/backend/metal/runtime/metal_common.h
similarity index 100%
rename from tirx/src/backend/metal/runtime/metal_common.h
rename to src/backend/metal/runtime/metal_common.h
diff --git a/tirx/src/backend/metal/runtime/metal_device_api.mm b/src/backend/metal/runtime/metal_device_api.mm
similarity index 100%
rename from tirx/src/backend/metal/runtime/metal_device_api.mm
rename to src/backend/metal/runtime/metal_device_api.mm
diff --git a/tirx/src/backend/metal/runtime/metal_module.mm b/src/backend/metal/runtime/metal_module.mm
similarity index 100%
rename from tirx/src/backend/metal/runtime/metal_module.mm
rename to src/backend/metal/runtime/metal_module.mm
diff --git a/tirx/src/backend/opencl/codegen/codegen_opencl.cc b/src/backend/opencl/codegen/codegen_opencl.cc
similarity index 100%
rename from tirx/src/backend/opencl/codegen/codegen_opencl.cc
rename to src/backend/opencl/codegen/codegen_opencl.cc
diff --git a/tirx/src/backend/opencl/codegen/codegen_opencl.h b/src/backend/opencl/codegen/codegen_opencl.h
similarity index 100%
rename from tirx/src/backend/opencl/codegen/codegen_opencl.h
rename to src/backend/opencl/codegen/codegen_opencl.h
diff --git a/tirx/src/backend/opencl/codegen/intrin_rule_opencl.cc b/src/backend/opencl/codegen/intrin_rule_opencl.cc
similarity index 100%
rename from tirx/src/backend/opencl/codegen/intrin_rule_opencl.cc
rename to src/backend/opencl/codegen/intrin_rule_opencl.cc
diff --git a/tirx/src/backend/opencl/codegen/opencl_fallback_module.cc b/src/backend/opencl/codegen/opencl_fallback_module.cc
similarity index 100%
rename from tirx/src/backend/opencl/codegen/opencl_fallback_module.cc
rename to src/backend/opencl/codegen/opencl_fallback_module.cc
diff --git a/tirx/src/backend/opencl/codegen/opencl_fallback_module.h b/src/backend/opencl/codegen/opencl_fallback_module.h
similarity index 100%
rename from tirx/src/backend/opencl/codegen/opencl_fallback_module.h
rename to src/backend/opencl/codegen/opencl_fallback_module.h
diff --git a/tirx/src/backend/opencl/codegen/target_kind.cc b/src/backend/opencl/codegen/target_kind.cc
similarity index 100%
rename from tirx/src/backend/opencl/codegen/target_kind.cc
rename to src/backend/opencl/codegen/target_kind.cc
diff --git a/tirx/src/backend/opencl/memory_scope.h b/src/backend/opencl/memory_scope.h
similarity index 100%
rename from tirx/src/backend/opencl/memory_scope.h
rename to src/backend/opencl/memory_scope.h
diff --git a/tirx/src/backend/opencl/op/memory.cc b/src/backend/opencl/op/memory.cc
similarity index 100%
rename from tirx/src/backend/opencl/op/memory.cc
rename to src/backend/opencl/op/memory.cc
diff --git a/tirx/src/backend/opencl/runtime/opencl_common.h b/src/backend/opencl/runtime/opencl_common.h
similarity index 100%
rename from tirx/src/backend/opencl/runtime/opencl_common.h
rename to src/backend/opencl/runtime/opencl_common.h
diff --git a/tirx/src/backend/opencl/runtime/opencl_device_api.cc b/src/backend/opencl/runtime/opencl_device_api.cc
similarity index 100%
rename from tirx/src/backend/opencl/runtime/opencl_device_api.cc
rename to src/backend/opencl/runtime/opencl_device_api.cc
diff --git a/tirx/src/backend/opencl/runtime/opencl_module.cc b/src/backend/opencl/runtime/opencl_module.cc
similarity index 100%
rename from tirx/src/backend/opencl/runtime/opencl_module.cc
rename to src/backend/opencl/runtime/opencl_module.cc
diff --git a/tirx/src/backend/opencl/runtime/opencl_wrapper/README.md b/src/backend/opencl/runtime/opencl_wrapper/README.md
similarity index 100%
rename from tirx/src/backend/opencl/runtime/opencl_wrapper/README.md
rename to src/backend/opencl/runtime/opencl_wrapper/README.md
diff --git a/tirx/src/backend/opencl/runtime/opencl_wrapper/opencl_wrapper.cc b/src/backend/opencl/runtime/opencl_wrapper/opencl_wrapper.cc
similarity index 100%
rename from tirx/src/backend/opencl/runtime/opencl_wrapper/opencl_wrapper.cc
rename to src/backend/opencl/runtime/opencl_wrapper/opencl_wrapper.cc
diff --git a/tirx/src/backend/opencl/runtime/source_utils.h b/src/backend/opencl/runtime/source_utils.h
similarity index 100%
rename from tirx/src/backend/opencl/runtime/source_utils.h
rename to src/backend/opencl/runtime/source_utils.h
diff --git a/tirx/src/backend/opencl/runtime/texture.h b/src/backend/opencl/runtime/texture.h
similarity index 100%
rename from tirx/src/backend/opencl/runtime/texture.h
rename to src/backend/opencl/runtime/texture.h
diff --git a/tirx/src/backend/rocm/codegen/llvm/codegen_amdgpu.cc b/src/backend/rocm/codegen/llvm/codegen_amdgpu.cc
similarity index 100%
rename from tirx/src/backend/rocm/codegen/llvm/codegen_amdgpu.cc
rename to src/backend/rocm/codegen/llvm/codegen_amdgpu.cc
diff --git a/tirx/src/backend/rocm/codegen/llvm/intrin_rule_rocm.cc b/src/backend/rocm/codegen/llvm/intrin_rule_rocm.cc
similarity index 100%
rename from tirx/src/backend/rocm/codegen/llvm/intrin_rule_rocm.cc
rename to src/backend/rocm/codegen/llvm/intrin_rule_rocm.cc
diff --git a/tirx/src/backend/rocm/codegen/rocm_fallback_module.cc b/src/backend/rocm/codegen/rocm_fallback_module.cc
similarity index 100%
rename from tirx/src/backend/rocm/codegen/rocm_fallback_module.cc
rename to src/backend/rocm/codegen/rocm_fallback_module.cc
diff --git a/tirx/src/backend/rocm/codegen/rocm_fallback_module.h b/src/backend/rocm/codegen/rocm_fallback_module.h
similarity index 100%
rename from tirx/src/backend/rocm/codegen/rocm_fallback_module.h
rename to src/backend/rocm/codegen/rocm_fallback_module.h
diff --git a/tirx/src/backend/rocm/codegen/target_kind.cc b/src/backend/rocm/codegen/target_kind.cc
similarity index 100%
rename from tirx/src/backend/rocm/codegen/target_kind.cc
rename to src/backend/rocm/codegen/target_kind.cc
diff --git a/tirx/src/backend/rocm/runtime/rocm_common.h b/src/backend/rocm/runtime/rocm_common.h
similarity index 100%
rename from tirx/src/backend/rocm/runtime/rocm_common.h
rename to src/backend/rocm/runtime/rocm_common.h
diff --git a/tirx/src/backend/rocm/runtime/rocm_device_api.cc b/src/backend/rocm/runtime/rocm_device_api.cc
similarity index 100%
rename from tirx/src/backend/rocm/runtime/rocm_device_api.cc
rename to src/backend/rocm/runtime/rocm_device_api.cc
diff --git a/tirx/src/backend/rocm/runtime/rocm_module.cc b/src/backend/rocm/runtime/rocm_module.cc
similarity index 100%
rename from tirx/src/backend/rocm/runtime/rocm_module.cc
rename to src/backend/rocm/runtime/rocm_module.cc
diff --git a/tirx/src/backend/trn/codegen/codegen_trn.cc b/src/backend/trn/codegen/codegen_trn.cc
similarity index 100%
rename from tirx/src/backend/trn/codegen/codegen_trn.cc
rename to src/backend/trn/codegen/codegen_trn.cc
diff --git a/tirx/src/backend/trn/codegen/codegen_trn.h b/src/backend/trn/codegen/codegen_trn.h
similarity index 100%
rename from tirx/src/backend/trn/codegen/codegen_trn.h
rename to src/backend/trn/codegen/codegen_trn.h
diff --git a/tirx/src/backend/trn/codegen/target_kind.cc b/src/backend/trn/codegen/target_kind.cc
similarity index 100%
rename from tirx/src/backend/trn/codegen/target_kind.cc
rename to src/backend/trn/codegen/target_kind.cc
diff --git a/tirx/src/backend/trn/layout/axis.cc b/src/backend/trn/layout/axis.cc
similarity index 100%
rename from tirx/src/backend/trn/layout/axis.cc
rename to src/backend/trn/layout/axis.cc
diff --git a/tirx/src/backend/trn/op/target_builtin.cc b/src/backend/trn/op/target_builtin.cc
similarity index 100%
rename from tirx/src/backend/trn/op/target_builtin.cc
rename to src/backend/trn/op/target_builtin.cc
diff --git a/tirx/src/backend/trn/transform/lower_trainium_layout.cc b/src/backend/trn/transform/lower_trainium_layout.cc
similarity index 100%
rename from tirx/src/backend/trn/transform/lower_trainium_layout.cc
rename to src/backend/trn/transform/lower_trainium_layout.cc
diff --git a/tirx/src/backend/vulkan/codegen/build_vulkan.cc b/src/backend/vulkan/codegen/build_vulkan.cc
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/build_vulkan.cc
rename to src/backend/vulkan/codegen/build_vulkan.cc
diff --git a/tirx/src/backend/vulkan/codegen/codegen_spirv.cc b/src/backend/vulkan/codegen/codegen_spirv.cc
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/codegen_spirv.cc
rename to src/backend/vulkan/codegen/codegen_spirv.cc
diff --git a/tirx/src/backend/vulkan/codegen/codegen_spirv.h b/src/backend/vulkan/codegen/codegen_spirv.h
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/codegen_spirv.h
rename to src/backend/vulkan/codegen/codegen_spirv.h
diff --git a/tirx/src/backend/vulkan/codegen/intrin_rule_spirv.cc b/src/backend/vulkan/codegen/intrin_rule_spirv.cc
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/intrin_rule_spirv.cc
rename to src/backend/vulkan/codegen/intrin_rule_spirv.cc
diff --git a/tirx/src/backend/vulkan/codegen/ir_builder.cc b/src/backend/vulkan/codegen/ir_builder.cc
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/ir_builder.cc
rename to src/backend/vulkan/codegen/ir_builder.cc
diff --git a/tirx/src/backend/vulkan/codegen/ir_builder.h b/src/backend/vulkan/codegen/ir_builder.h
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/ir_builder.h
rename to src/backend/vulkan/codegen/ir_builder.h
diff --git a/tirx/src/backend/vulkan/codegen/spirv_support.cc b/src/backend/vulkan/codegen/spirv_support.cc
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/spirv_support.cc
rename to src/backend/vulkan/codegen/spirv_support.cc
diff --git a/tirx/src/backend/vulkan/codegen/spirv_support.h b/src/backend/vulkan/codegen/spirv_support.h
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/spirv_support.h
rename to src/backend/vulkan/codegen/spirv_support.h
diff --git a/tirx/src/backend/vulkan/codegen/spirv_utils.cc b/src/backend/vulkan/codegen/spirv_utils.cc
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/spirv_utils.cc
rename to src/backend/vulkan/codegen/spirv_utils.cc
diff --git a/tirx/src/backend/vulkan/codegen/spirv_utils.h b/src/backend/vulkan/codegen/spirv_utils.h
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/spirv_utils.h
rename to src/backend/vulkan/codegen/spirv_utils.h
diff --git a/tirx/src/backend/vulkan/codegen/target_kind.cc b/src/backend/vulkan/codegen/target_kind.cc
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/target_kind.cc
rename to src/backend/vulkan/codegen/target_kind.cc
diff --git a/tirx/src/backend/vulkan/codegen/vulkan_fallback_module.cc b/src/backend/vulkan/codegen/vulkan_fallback_module.cc
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/vulkan_fallback_module.cc
rename to src/backend/vulkan/codegen/vulkan_fallback_module.cc
diff --git a/tirx/src/backend/vulkan/codegen/vulkan_fallback_module.h b/src/backend/vulkan/codegen/vulkan_fallback_module.h
similarity index 100%
rename from tirx/src/backend/vulkan/codegen/vulkan_fallback_module.h
rename to src/backend/vulkan/codegen/vulkan_fallback_module.h
diff --git a/tirx/src/backend/vulkan/runtime/README.md b/src/backend/vulkan/runtime/README.md
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/README.md
rename to src/backend/vulkan/runtime/README.md
diff --git a/tirx/src/backend/vulkan/runtime/spirv_shader.h b/src/backend/vulkan/runtime/spirv_shader.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/spirv_shader.h
rename to src/backend/vulkan/runtime/spirv_shader.h
diff --git a/tirx/src/backend/vulkan/runtime/thread_map.h b/src/backend/vulkan/runtime/thread_map.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/thread_map.h
rename to src/backend/vulkan/runtime/thread_map.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_amdrgp.cc b/src/backend/vulkan/runtime/vulkan_amdrgp.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_amdrgp.cc
rename to src/backend/vulkan/runtime/vulkan_amdrgp.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_amdrgp.h b/src/backend/vulkan/runtime/vulkan_amdrgp.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_amdrgp.h
rename to src/backend/vulkan/runtime/vulkan_amdrgp.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_buffer.cc b/src/backend/vulkan/runtime/vulkan_buffer.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_buffer.cc
rename to src/backend/vulkan/runtime/vulkan_buffer.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_buffer.h b/src/backend/vulkan/runtime/vulkan_buffer.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_buffer.h
rename to src/backend/vulkan/runtime/vulkan_buffer.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_common.cc b/src/backend/vulkan/runtime/vulkan_common.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_common.cc
rename to src/backend/vulkan/runtime/vulkan_common.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_common.h b/src/backend/vulkan/runtime/vulkan_common.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_common.h
rename to src/backend/vulkan/runtime/vulkan_common.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_device.cc b/src/backend/vulkan/runtime/vulkan_device.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_device.cc
rename to src/backend/vulkan/runtime/vulkan_device.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_device.h b/src/backend/vulkan/runtime/vulkan_device.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_device.h
rename to src/backend/vulkan/runtime/vulkan_device.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_device_api.cc b/src/backend/vulkan/runtime/vulkan_device_api.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_device_api.cc
rename to src/backend/vulkan/runtime/vulkan_device_api.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_device_api.h b/src/backend/vulkan/runtime/vulkan_device_api.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_device_api.h
rename to src/backend/vulkan/runtime/vulkan_device_api.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_instance.cc b/src/backend/vulkan/runtime/vulkan_instance.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_instance.cc
rename to src/backend/vulkan/runtime/vulkan_instance.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_instance.h b/src/backend/vulkan/runtime/vulkan_instance.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_instance.h
rename to src/backend/vulkan/runtime/vulkan_instance.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_module.cc b/src/backend/vulkan/runtime/vulkan_module.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_module.cc
rename to src/backend/vulkan/runtime/vulkan_module.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_stream.cc b/src/backend/vulkan/runtime/vulkan_stream.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_stream.cc
rename to src/backend/vulkan/runtime/vulkan_stream.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_stream.h b/src/backend/vulkan/runtime/vulkan_stream.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_stream.h
rename to src/backend/vulkan/runtime/vulkan_stream.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_timer.cc b/src/backend/vulkan/runtime/vulkan_timer.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_timer.cc
rename to src/backend/vulkan/runtime/vulkan_timer.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_timer.h b/src/backend/vulkan/runtime/vulkan_timer.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_timer.h
rename to src/backend/vulkan/runtime/vulkan_timer.h
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_wrapped_func.cc b/src/backend/vulkan/runtime/vulkan_wrapped_func.cc
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_wrapped_func.cc
rename to src/backend/vulkan/runtime/vulkan_wrapped_func.cc
diff --git a/tirx/src/backend/vulkan/runtime/vulkan_wrapped_func.h b/src/backend/vulkan/runtime/vulkan_wrapped_func.h
similarity index 100%
rename from tirx/src/backend/vulkan/runtime/vulkan_wrapped_func.h
rename to src/backend/vulkan/runtime/vulkan_wrapped_func.h
diff --git a/tirx/src/backend/webgpu/codegen/codegen_webgpu.cc b/src/backend/webgpu/codegen/codegen_webgpu.cc
similarity index 100%
rename from tirx/src/backend/webgpu/codegen/codegen_webgpu.cc
rename to src/backend/webgpu/codegen/codegen_webgpu.cc
diff --git a/tirx/src/backend/webgpu/codegen/codegen_webgpu.h b/src/backend/webgpu/codegen/codegen_webgpu.h
similarity index 100%
rename from tirx/src/backend/webgpu/codegen/codegen_webgpu.h
rename to src/backend/webgpu/codegen/codegen_webgpu.h
diff --git a/tirx/src/backend/webgpu/codegen/intrin_rule_webgpu.cc b/src/backend/webgpu/codegen/intrin_rule_webgpu.cc
similarity index 100%
rename from tirx/src/backend/webgpu/codegen/intrin_rule_webgpu.cc
rename to src/backend/webgpu/codegen/intrin_rule_webgpu.cc
diff --git a/tirx/src/backend/webgpu/codegen/target_kind.cc b/src/backend/webgpu/codegen/target_kind.cc
similarity index 100%
rename from tirx/src/backend/webgpu/codegen/target_kind.cc
rename to src/backend/webgpu/codegen/target_kind.cc
diff --git a/tirx/src/backend/webgpu/codegen/webgpu_fallback_module.cc b/src/backend/webgpu/codegen/webgpu_fallback_module.cc
similarity index 100%
rename from tirx/src/backend/webgpu/codegen/webgpu_fallback_module.cc
rename to src/backend/webgpu/codegen/webgpu_fallback_module.cc
diff --git a/tirx/src/backend/webgpu/codegen/webgpu_fallback_module.h b/src/backend/webgpu/codegen/webgpu_fallback_module.h
similarity index 100%
rename from tirx/src/backend/webgpu/codegen/webgpu_fallback_module.h
rename to src/backend/webgpu/codegen/webgpu_fallback_module.h
diff --git a/tirx/src/codegen/build_common.h b/src/codegen/build_common.h
similarity index 100%
rename from tirx/src/codegen/build_common.h
rename to src/codegen/build_common.h
diff --git a/tirx/src/codegen/c/codegen_c.cc b/src/codegen/c/codegen_c.cc
similarity index 100%
rename from tirx/src/codegen/c/codegen_c.cc
rename to src/codegen/c/codegen_c.cc
diff --git a/tirx/src/codegen/c/codegen_c.h b/src/codegen/c/codegen_c.h
similarity index 100%
rename from tirx/src/codegen/c/codegen_c.h
rename to src/codegen/c/codegen_c.h
diff --git a/tirx/src/codegen/c/codegen_c_host.cc b/src/codegen/c/codegen_c_host.cc
similarity index 100%
rename from tirx/src/codegen/c/codegen_c_host.cc
rename to src/codegen/c/codegen_c_host.cc
diff --git a/tirx/src/codegen/c/codegen_c_host.h b/src/codegen/c/codegen_c_host.h
similarity index 100%
rename from tirx/src/codegen/c/codegen_c_host.h
rename to src/codegen/c/codegen_c_host.h
diff --git a/tirx/src/codegen/c/codegen_params.cc b/src/codegen/c/codegen_params.cc
similarity index 100%
rename from tirx/src/codegen/c/codegen_params.cc
rename to src/codegen/c/codegen_params.cc
diff --git a/tirx/src/codegen/c/codegen_params.h b/src/codegen/c/codegen_params.h
similarity index 100%
rename from tirx/src/codegen/c/codegen_params.h
rename to src/codegen/c/codegen_params.h
diff --git a/tirx/src/codegen/c/codegen_source_base.cc b/src/codegen/c/codegen_source_base.cc
similarity index 100%
rename from tirx/src/codegen/c/codegen_source_base.cc
rename to src/codegen/c/codegen_source_base.cc
diff --git a/tirx/src/codegen/c/codegen_source_base.h b/src/codegen/c/codegen_source_base.h
similarity index 100%
rename from tirx/src/codegen/c/codegen_source_base.h
rename to src/codegen/c/codegen_source_base.h
diff --git a/tirx/src/codegen/c/source_module.cc b/src/codegen/c/source_module.cc
similarity index 100%
rename from tirx/src/codegen/c/source_module.cc
rename to src/codegen/c/source_module.cc
diff --git a/tirx/src/codegen/c/target_kind.cc b/src/codegen/c/target_kind.cc
similarity index 100%
rename from tirx/src/codegen/c/target_kind.cc
rename to src/codegen/c/target_kind.cc
diff --git a/tirx/src/codegen/canonicalizer/arm_mprofile.cc b/src/codegen/canonicalizer/arm_mprofile.cc
similarity index 100%
rename from tirx/src/codegen/canonicalizer/arm_mprofile.cc
rename to src/codegen/canonicalizer/arm_mprofile.cc
diff --git a/tirx/src/codegen/canonicalizer/arm_mprofile.h b/src/codegen/canonicalizer/arm_mprofile.h
similarity index 100%
rename from tirx/src/codegen/canonicalizer/arm_mprofile.h
rename to src/codegen/canonicalizer/arm_mprofile.h
diff --git a/tirx/src/codegen/codegen.cc b/src/codegen/codegen.cc
similarity index 100%
rename from tirx/src/codegen/codegen.cc
rename to src/codegen/codegen.cc
diff --git a/tirx/src/codegen/intrin_rule.cc b/src/codegen/intrin_rule.cc
similarity index 100%
rename from tirx/src/codegen/intrin_rule.cc
rename to src/codegen/intrin_rule.cc
diff --git a/tirx/src/codegen/llvm/canonicalizer/arm_aprofile.cc b/src/codegen/llvm/canonicalizer/arm_aprofile.cc
similarity index 100%
rename from tirx/src/codegen/llvm/canonicalizer/arm_aprofile.cc
rename to src/codegen/llvm/canonicalizer/arm_aprofile.cc
diff --git a/tirx/src/codegen/llvm/canonicalizer/arm_aprofile.h b/src/codegen/llvm/canonicalizer/arm_aprofile.h
similarity index 100%
rename from tirx/src/codegen/llvm/canonicalizer/arm_aprofile.h
rename to src/codegen/llvm/canonicalizer/arm_aprofile.h
diff --git a/tirx/src/codegen/llvm/canonicalizer/canonicalize.cc b/src/codegen/llvm/canonicalizer/canonicalize.cc
similarity index 100%
rename from tirx/src/codegen/llvm/canonicalizer/canonicalize.cc
rename to src/codegen/llvm/canonicalizer/canonicalize.cc
diff --git a/tirx/src/codegen/llvm/canonicalizer/canonicalize.h b/src/codegen/llvm/canonicalizer/canonicalize.h
similarity index 100%
rename from tirx/src/codegen/llvm/canonicalizer/canonicalize.h
rename to src/codegen/llvm/canonicalizer/canonicalize.h
diff --git a/tirx/src/codegen/llvm/codegen_aarch64.cc b/src/codegen/llvm/codegen_aarch64.cc
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_aarch64.cc
rename to src/codegen/llvm/codegen_aarch64.cc
diff --git a/tirx/src/codegen/llvm/codegen_arm.cc b/src/codegen/llvm/codegen_arm.cc
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_arm.cc
rename to src/codegen/llvm/codegen_arm.cc
diff --git a/tirx/src/codegen/llvm/codegen_blob.cc b/src/codegen/llvm/codegen_blob.cc
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_blob.cc
rename to src/codegen/llvm/codegen_blob.cc
diff --git a/tirx/src/codegen/llvm/codegen_blob.h b/src/codegen/llvm/codegen_blob.h
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_blob.h
rename to src/codegen/llvm/codegen_blob.h
diff --git a/tirx/src/codegen/llvm/codegen_cpu.cc b/src/codegen/llvm/codegen_cpu.cc
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_cpu.cc
rename to src/codegen/llvm/codegen_cpu.cc
diff --git a/tirx/src/codegen/llvm/codegen_cpu.h b/src/codegen/llvm/codegen_cpu.h
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_cpu.h
rename to src/codegen/llvm/codegen_cpu.h
diff --git a/tirx/src/codegen/llvm/codegen_llvm.cc b/src/codegen/llvm/codegen_llvm.cc
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_llvm.cc
rename to src/codegen/llvm/codegen_llvm.cc
diff --git a/tirx/src/codegen/llvm/codegen_llvm.h b/src/codegen/llvm/codegen_llvm.h
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_llvm.h
rename to src/codegen/llvm/codegen_llvm.h
diff --git a/tirx/src/codegen/llvm/codegen_params.cc b/src/codegen/llvm/codegen_params.cc
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_params.cc
rename to src/codegen/llvm/codegen_params.cc
diff --git a/tirx/src/codegen/llvm/codegen_params.h b/src/codegen/llvm/codegen_params.h
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_params.h
rename to src/codegen/llvm/codegen_params.h
diff --git a/tirx/src/codegen/llvm/codegen_x86_64.cc b/src/codegen/llvm/codegen_x86_64.cc
similarity index 100%
rename from tirx/src/codegen/llvm/codegen_x86_64.cc
rename to src/codegen/llvm/codegen_x86_64.cc
diff --git a/tirx/src/codegen/llvm/intrin_rule_llvm.cc b/src/codegen/llvm/intrin_rule_llvm.cc
similarity index 100%
rename from tirx/src/codegen/llvm/intrin_rule_llvm.cc
rename to src/codegen/llvm/intrin_rule_llvm.cc
diff --git a/tirx/src/codegen/llvm/intrin_rule_llvm.h b/src/codegen/llvm/intrin_rule_llvm.h
similarity index 100%
rename from tirx/src/codegen/llvm/intrin_rule_llvm.h
rename to src/codegen/llvm/intrin_rule_llvm.h
diff --git a/tirx/src/codegen/llvm/llvm_instance.cc b/src/codegen/llvm/llvm_instance.cc
similarity index 100%
rename from tirx/src/codegen/llvm/llvm_instance.cc
rename to src/codegen/llvm/llvm_instance.cc
diff --git a/tirx/src/codegen/llvm/llvm_instance.h b/src/codegen/llvm/llvm_instance.h
similarity index 100%
rename from tirx/src/codegen/llvm/llvm_instance.h
rename to src/codegen/llvm/llvm_instance.h
diff --git a/tirx/src/codegen/llvm/llvm_module.cc b/src/codegen/llvm/llvm_module.cc
similarity index 100%
rename from tirx/src/codegen/llvm/llvm_module.cc
rename to src/codegen/llvm/llvm_module.cc
diff --git a/tirx/src/codegen/llvm/llvm_module.h b/src/codegen/llvm/llvm_module.h
similarity index 100%
rename from tirx/src/codegen/llvm/llvm_module.h
rename to src/codegen/llvm/llvm_module.h
diff --git a/tirx/src/codegen/llvm/target_kind.cc b/src/codegen/llvm/target_kind.cc
similarity index 100%
rename from tirx/src/codegen/llvm/target_kind.cc
rename to src/codegen/llvm/target_kind.cc
diff --git a/tirx/src/codegen/module_export.cc b/src/codegen/module_export.cc
similarity index 100%
rename from tirx/src/codegen/module_export.cc
rename to src/codegen/module_export.cc
diff --git a/tirx/src/ir/attrs.cc b/src/ir/attrs.cc
similarity index 100%
rename from tirx/src/ir/attrs.cc
rename to src/ir/attrs.cc
diff --git a/tirx/src/ir/env_func.cc b/src/ir/env_func.cc
similarity index 100%
rename from tirx/src/ir/env_func.cc
rename to src/ir/env_func.cc
diff --git a/tirx/src/ir/expr.cc b/src/ir/expr.cc
similarity index 100%
rename from tirx/src/ir/expr.cc
rename to src/ir/expr.cc
diff --git a/tirx/src/ir/expr_functor.cc b/src/ir/expr_functor.cc
similarity index 100%
rename from tirx/src/ir/expr_functor.cc
rename to src/ir/expr_functor.cc
diff --git a/tirx/src/ir/function.cc b/src/ir/function.cc
similarity index 100%
rename from tirx/src/ir/function.cc
rename to src/ir/function.cc
diff --git a/tirx/src/ir/global_info.cc b/src/ir/global_info.cc
similarity index 100%
rename from tirx/src/ir/global_info.cc
rename to src/ir/global_info.cc
diff --git a/tirx/src/ir/instrument.cc b/src/ir/instrument.cc
similarity index 100%
rename from tirx/src/ir/instrument.cc
rename to src/ir/instrument.cc
diff --git a/tirx/src/ir/location.cc b/src/ir/location.cc
similarity index 100%
rename from tirx/src/ir/location.cc
rename to src/ir/location.cc
diff --git a/tirx/src/ir/module.cc b/src/ir/module.cc
similarity index 100%
rename from tirx/src/ir/module.cc
rename to src/ir/module.cc
diff --git a/tirx/src/ir/op.cc b/src/ir/op.cc
similarity index 100%
rename from tirx/src/ir/op.cc
rename to src/ir/op.cc
diff --git a/tirx/src/ir/prim/builtin.cc b/src/ir/prim/builtin.cc
similarity index 100%
rename from tirx/src/ir/prim/builtin.cc
rename to src/ir/prim/builtin.cc
diff --git a/tirx/src/ir/prim/const_fold.h b/src/ir/prim/const_fold.h
similarity index 100%
rename from tirx/src/ir/prim/const_fold.h
rename to src/ir/prim/const_fold.h
diff --git a/tirx/src/ir/prim/deep_equal.cc b/src/ir/prim/deep_equal.cc
similarity index 100%
rename from tirx/src/ir/prim/deep_equal.cc
rename to src/ir/prim/deep_equal.cc
diff --git a/tirx/src/ir/prim/expr.cc b/src/ir/prim/expr.cc
similarity index 100%
rename from tirx/src/ir/prim/expr.cc
rename to src/ir/prim/expr.cc
diff --git a/tirx/src/ir/prim/int_operator.h b/src/ir/prim/int_operator.h
similarity index 100%
rename from tirx/src/ir/prim/int_operator.h
rename to src/ir/prim/int_operator.h
diff --git a/tirx/src/ir/prim/math.cc b/src/ir/prim/math.cc
similarity index 100%
rename from tirx/src/ir/prim/math.cc
rename to src/ir/prim/math.cc
diff --git a/tirx/src/ir/prim/op.cc b/src/ir/prim/op.cc
similarity index 100%
rename from tirx/src/ir/prim/op.cc
rename to src/ir/prim/op.cc
diff --git a/tirx/src/ir/prim/op_utils.h b/src/ir/prim/op_utils.h
similarity index 100%
rename from tirx/src/ir/prim/op_utils.h
rename to src/ir/prim/op_utils.h
diff --git a/tirx/src/ir/prim/symbolic_limits.cc b/src/ir/prim/symbolic_limits.cc
similarity index 100%
rename from tirx/src/ir/prim/symbolic_limits.cc
rename to src/ir/prim/symbolic_limits.cc
diff --git a/tirx/src/ir/prim/vector_expr.cc b/src/ir/prim/vector_expr.cc
similarity index 100%
rename from tirx/src/ir/prim/vector_expr.cc
rename to src/ir/prim/vector_expr.cc
diff --git a/tirx/src/ir/seq_stmt_mutate.h b/src/ir/seq_stmt_mutate.h
similarity index 100%
rename from tirx/src/ir/seq_stmt_mutate.h
rename to src/ir/seq_stmt_mutate.h
diff --git a/tirx/src/ir/side_effect.cc b/src/ir/side_effect.cc
similarity index 100%
rename from tirx/src/ir/side_effect.cc
rename to src/ir/side_effect.cc
diff --git a/tirx/src/ir/stmt.cc b/src/ir/stmt.cc
similarity index 100%
rename from tirx/src/ir/stmt.cc
rename to src/ir/stmt.cc
diff --git a/tirx/src/ir/subscript_expr.cc b/src/ir/subscript_expr.cc
similarity index 100%
rename from tirx/src/ir/subscript_expr.cc
rename to src/ir/subscript_expr.cc
diff --git a/tirx/src/ir/transform.cc b/src/ir/transform.cc
similarity index 100%
rename from tirx/src/ir/transform.cc
rename to src/ir/transform.cc
diff --git a/tirx/src/ir/type.cc b/src/ir/type.cc
similarity index 100%
rename from tirx/src/ir/type.cc
rename to src/ir/type.cc
diff --git a/tirx/src/ir/unique_name_supply.cc b/src/ir/unique_name_supply.cc
similarity index 100%
rename from tirx/src/ir/unique_name_supply.cc
rename to src/ir/unique_name_supply.cc
diff --git a/tirx/src/runtime/builtin_fp16.cc b/src/runtime/builtin_fp16.cc
similarity index 100%
rename from tirx/src/runtime/builtin_fp16.cc
rename to src/runtime/builtin_fp16.cc
diff --git a/tirx/src/runtime/cpu_device_api.cc b/src/runtime/cpu_device_api.cc
similarity index 100%
rename from tirx/src/runtime/cpu_device_api.cc
rename to src/runtime/cpu_device_api.cc
diff --git a/tirx/src/runtime/device_api.cc b/src/runtime/device_api.cc
similarity index 100%
rename from tirx/src/runtime/device_api.cc
rename to src/runtime/device_api.cc
diff --git a/tirx/src/runtime/launch_param.h b/src/runtime/launch_param.h
similarity index 100%
rename from tirx/src/runtime/launch_param.h
rename to src/runtime/launch_param.h
diff --git a/tirx/src/runtime/logging.cc b/src/runtime/logging.cc
similarity index 100%
rename from tirx/src/runtime/logging.cc
rename to src/runtime/logging.cc
diff --git a/tirx/src/runtime/memory_scope.cc b/src/runtime/memory_scope.cc
similarity index 100%
rename from tirx/src/runtime/memory_scope.cc
rename to src/runtime/memory_scope.cc
diff --git a/tirx/src/runtime/metadata.cc b/src/runtime/metadata.cc
similarity index 100%
rename from tirx/src/runtime/metadata.cc
rename to src/runtime/metadata.cc
diff --git a/tirx/src/runtime/metadata.h b/src/runtime/metadata.h
similarity index 100%
rename from tirx/src/runtime/metadata.h
rename to src/runtime/metadata.h
diff --git a/tirx/src/runtime/module.cc b/src/runtime/module.cc
similarity index 100%
rename from tirx/src/runtime/module.cc
rename to src/runtime/module.cc
diff --git a/tirx/src/runtime/pack_args.h b/src/runtime/pack_args.h
similarity index 100%
rename from tirx/src/runtime/pack_args.h
rename to src/runtime/pack_args.h
diff --git a/tirx/src/runtime/static_library.cc b/src/runtime/static_library.cc
similarity index 100%
rename from tirx/src/runtime/static_library.cc
rename to src/runtime/static_library.cc
diff --git a/tirx/src/runtime/static_library.h b/src/runtime/static_library.h
similarity index 100%
rename from tirx/src/runtime/static_library.h
rename to src/runtime/static_library.h
diff --git a/tirx/src/runtime/tensor.cc b/src/runtime/tensor.cc
similarity index 100%
rename from tirx/src/runtime/tensor.cc
rename to src/runtime/tensor.cc
diff --git a/tirx/src/runtime/thread_pool.cc b/src/runtime/thread_pool.cc
similarity index 100%
rename from tirx/src/runtime/thread_pool.cc
rename to src/runtime/thread_pool.cc
diff --git a/tirx/src/runtime/threading_backend.cc b/src/runtime/threading_backend.cc
similarity index 100%
rename from tirx/src/runtime/threading_backend.cc
rename to src/runtime/threading_backend.cc
diff --git a/tirx/src/runtime/threading_backend.h b/src/runtime/threading_backend.h
similarity index 100%
rename from tirx/src/runtime/threading_backend.h
rename to src/runtime/threading_backend.h
diff --git a/tirx/src/runtime/workspace_pool.cc b/src/runtime/workspace_pool.cc
similarity index 100%
rename from tirx/src/runtime/workspace_pool.cc
rename to src/runtime/workspace_pool.cc
diff --git a/tirx/src/runtime/workspace_pool.h b/src/runtime/workspace_pool.h
similarity index 100%
rename from tirx/src/runtime/workspace_pool.h
rename to src/runtime/workspace_pool.h
diff --git a/tirx/src/script/ir_builder/base.cc b/src/script/ir_builder/base.cc
similarity index 100%
rename from tirx/src/script/ir_builder/base.cc
rename to src/script/ir_builder/base.cc
diff --git a/tirx/src/script/ir_builder/frame.cc b/src/script/ir_builder/frame.cc
similarity index 100%
rename from tirx/src/script/ir_builder/frame.cc
rename to src/script/ir_builder/frame.cc
diff --git a/tirx/src/script/ir_builder/ir.cc b/src/script/ir_builder/ir.cc
similarity index 100%
rename from tirx/src/script/ir_builder/ir.cc
rename to src/script/ir_builder/ir.cc
diff --git a/tirx/src/script/ir_builder/utils.h b/src/script/ir_builder/utils.h
similarity index 100%
rename from tirx/src/script/ir_builder/utils.h
rename to src/script/ir_builder/utils.h
diff --git a/tirx/src/script/printer/config.cc b/src/script/printer/config.cc
similarity index 100%
rename from tirx/src/script/printer/config.cc
rename to src/script/printer/config.cc
diff --git a/tirx/src/script/printer/doc.cc b/src/script/printer/doc.cc
similarity index 100%
rename from tirx/src/script/printer/doc.cc
rename to src/script/printer/doc.cc
diff --git a/tirx/src/script/printer/doc_printer.cc b/src/script/printer/doc_printer.cc
similarity index 100%
rename from tirx/src/script/printer/doc_printer.cc
rename to src/script/printer/doc_printer.cc
diff --git a/tirx/src/script/printer/doc_printer.h b/src/script/printer/doc_printer.h
similarity index 100%
rename from tirx/src/script/printer/doc_printer.h
rename to src/script/printer/doc_printer.h
diff --git a/tirx/src/script/printer/doc_translator.cc b/src/script/printer/doc_translator.cc
similarity index 100%
rename from tirx/src/script/printer/doc_translator.cc
rename to src/script/printer/doc_translator.cc
diff --git a/tirx/src/script/printer/ir/call.cc b/src/script/printer/ir/call.cc
similarity index 100%
rename from tirx/src/script/printer/ir/call.cc
rename to src/script/printer/ir/call.cc
diff --git a/tirx/src/script/printer/ir/ir.cc b/src/script/printer/ir/ir.cc
similarity index 100%
rename from tirx/src/script/printer/ir/ir.cc
rename to src/script/printer/ir/ir.cc
diff --git a/tirx/src/script/printer/ir/misc.cc b/src/script/printer/ir/misc.cc
similarity index 100%
rename from tirx/src/script/printer/ir/misc.cc
rename to src/script/printer/ir/misc.cc
diff --git a/tirx/src/script/printer/ir/prim_expr.cc b/src/script/printer/ir/prim_expr.cc
similarity index 100%
rename from tirx/src/script/printer/ir/prim_expr.cc
rename to src/script/printer/ir/prim_expr.cc
diff --git a/tirx/src/script/printer/ir/prim_type.cc b/src/script/printer/ir/prim_type.cc
similarity index 100%
rename from tirx/src/script/printer/ir/prim_type.cc
rename to src/script/printer/ir/prim_type.cc
diff --git a/tirx/src/script/printer/ir/stmt.cc b/src/script/printer/ir/stmt.cc
similarity index 100%
rename from tirx/src/script/printer/ir/stmt.cc
rename to src/script/printer/ir/stmt.cc
diff --git a/tirx/src/script/printer/ir/utils.cc b/src/script/printer/ir/utils.cc
similarity index 100%
rename from tirx/src/script/printer/ir/utils.cc
rename to src/script/printer/ir/utils.cc
diff --git a/tirx/src/script/printer/ir/utils.h b/src/script/printer/ir/utils.h
similarity index 100%
rename from tirx/src/script/printer/ir/utils.h
rename to src/script/printer/ir/utils.h
diff --git a/tirx/src/script/printer/printer.cc b/src/script/printer/printer.cc
similarity index 100%
rename from tirx/src/script/printer/printer.cc
rename to src/script/printer/printer.cc
diff --git a/tirx/src/script/printer/script_printer.cc b/src/script/printer/script_printer.cc
similarity index 100%
rename from tirx/src/script/printer/script_printer.cc
rename to src/script/printer/script_printer.cc
diff --git a/tirx/src/script/printer/utils.h b/src/script/printer/utils.h
similarity index 100%
rename from tirx/src/script/printer/utils.h
rename to src/script/printer/utils.h
diff --git a/tirx/src/support/limits.h b/src/support/limits.h
similarity index 100%
rename from tirx/src/support/limits.h
rename to src/support/limits.h
diff --git a/tirx/src/sym/analyzer.cc b/src/sym/analyzer.cc
similarity index 100%
rename from tirx/src/sym/analyzer.cc
rename to src/sym/analyzer.cc
diff --git a/tirx/src/sym/bound_deducer.cc b/src/sym/bound_deducer.cc
similarity index 100%
rename from tirx/src/sym/bound_deducer.cc
rename to src/sym/bound_deducer.cc
diff --git a/tirx/src/sym/canonical_simplify.cc b/src/sym/canonical_simplify.cc
similarity index 100%
rename from tirx/src/sym/canonical_simplify.cc
rename to src/sym/canonical_simplify.cc
diff --git a/tirx/src/sym/const_fold.h b/src/sym/const_fold.h
similarity index 100%
rename from tirx/src/sym/const_fold.h
rename to src/sym/const_fold.h
diff --git a/tirx/src/sym/const_int_bound.cc b/src/sym/const_int_bound.cc
similarity index 100%
rename from tirx/src/sym/const_int_bound.cc
rename to src/sym/const_int_bound.cc
diff --git a/tirx/src/sym/constraint_extract.cc b/src/sym/constraint_extract.cc
similarity index 100%
rename from tirx/src/sym/constraint_extract.cc
rename to src/sym/constraint_extract.cc
diff --git a/tirx/src/sym/constraint_extract.h b/src/sym/constraint_extract.h
similarity index 100%
rename from tirx/src/sym/constraint_extract.h
rename to src/sym/constraint_extract.h
diff --git a/tirx/src/sym/constraint_helpers.h b/src/sym/constraint_helpers.h
similarity index 100%
rename from tirx/src/sym/constraint_helpers.h
rename to src/sym/constraint_helpers.h
diff --git a/tirx/src/sym/detect_linear_equation.cc b/src/sym/detect_linear_equation.cc
similarity index 100%
rename from tirx/src/sym/detect_linear_equation.cc
rename to src/sym/detect_linear_equation.cc
diff --git a/tirx/src/sym/int_operator.h b/src/sym/int_operator.h
similarity index 100%
rename from tirx/src/sym/int_operator.h
rename to src/sym/int_operator.h
diff --git a/tirx/src/sym/int_set.cc b/src/sym/int_set.cc
similarity index 100%
rename from tirx/src/sym/int_set.cc
rename to src/sym/int_set.cc
diff --git a/tirx/src/sym/interval_set.h b/src/sym/interval_set.h
similarity index 100%
rename from tirx/src/sym/interval_set.h
rename to src/sym/interval_set.h
diff --git a/tirx/src/sym/iter_affine_map.cc b/src/sym/iter_affine_map.cc
similarity index 100%
rename from tirx/src/sym/iter_affine_map.cc
rename to src/sym/iter_affine_map.cc
diff --git a/tirx/src/sym/known_comparison_analyzer.cc b/src/sym/known_comparison_analyzer.cc
similarity index 100%
rename from tirx/src/sym/known_comparison_analyzer.cc
rename to src/sym/known_comparison_analyzer.cc
diff --git a/tirx/src/sym/modular_set.cc b/src/sym/modular_set.cc
similarity index 100%
rename from tirx/src/sym/modular_set.cc
rename to src/sym/modular_set.cc
diff --git a/tirx/src/sym/pattern_match.h b/src/sym/pattern_match.h
similarity index 100%
rename from tirx/src/sym/pattern_match.h
rename to src/sym/pattern_match.h
diff --git a/tirx/src/sym/product_normal_form.h b/src/sym/product_normal_form.h
similarity index 100%
rename from tirx/src/sym/product_normal_form.h
rename to src/sym/product_normal_form.h
diff --git a/tirx/src/sym/rewrite_simplify.cc b/src/sym/rewrite_simplify.cc
similarity index 100%
rename from tirx/src/sym/rewrite_simplify.cc
rename to src/sym/rewrite_simplify.cc
diff --git a/tirx/src/sym/rewrite_simplify.h b/src/sym/rewrite_simplify.h
similarity index 100%
rename from tirx/src/sym/rewrite_simplify.h
rename to src/sym/rewrite_simplify.h
diff --git a/tirx/src/sym/simplify_base.cc b/src/sym/simplify_base.cc
similarity index 100%
rename from tirx/src/sym/simplify_base.cc
rename to src/sym/simplify_base.cc
diff --git a/tirx/src/sym/simplify_base.h b/src/sym/simplify_base.h
similarity index 100%
rename from tirx/src/sym/simplify_base.h
rename to src/sym/simplify_base.h
diff --git a/tirx/src/sym/z3_prover.cc b/src/sym/z3_prover.cc
similarity index 100%
rename from tirx/src/sym/z3_prover.cc
rename to src/sym/z3_prover.cc
diff --git a/tirx/src/target/target.cc b/src/target/target.cc
similarity index 100%
rename from tirx/src/target/target.cc
rename to src/target/target.cc
diff --git a/tirx/src/target/target_kind.cc b/src/target/target_kind.cc
similarity index 100%
rename from tirx/src/target/target_kind.cc
rename to src/target/target_kind.cc
diff --git a/tirx/src/target/target_tag_registry.cc b/src/target/target_tag_registry.cc
similarity index 100%
rename from tirx/src/target/target_tag_registry.cc
rename to src/target/target_tag_registry.cc
diff --git a/tirx/src/tirx/analysis/check_well_formed.cc b/src/tirx/analysis/check_well_formed.cc
similarity index 100%
rename from tirx/src/tirx/analysis/check_well_formed.cc
rename to src/tirx/analysis/check_well_formed.cc
diff --git a/tirx/src/tirx/analysis/expr_complexity.cc b/src/tirx/analysis/expr_complexity.cc
similarity index 100%
rename from tirx/src/tirx/analysis/expr_complexity.cc
rename to src/tirx/analysis/expr_complexity.cc
diff --git a/tirx/src/tirx/analysis/stmt_finding.cc b/src/tirx/analysis/stmt_finding.cc
similarity index 100%
rename from tirx/src/tirx/analysis/stmt_finding.cc
rename to src/tirx/analysis/stmt_finding.cc
diff --git a/tirx/src/tirx/analysis/undefined_vars.cc b/src/tirx/analysis/undefined_vars.cc
similarity index 100%
rename from tirx/src/tirx/analysis/undefined_vars.cc
rename to src/tirx/analysis/undefined_vars.cc
diff --git a/tirx/src/tirx/analysis/verify_memory.cc b/src/tirx/analysis/verify_memory.cc
similarity index 100%
rename from tirx/src/tirx/analysis/verify_memory.cc
rename to src/tirx/analysis/verify_memory.cc
diff --git a/tirx/src/tirx/ir/data_type_rewriter.cc b/src/tirx/ir/data_type_rewriter.cc
similarity index 100%
rename from tirx/src/tirx/ir/data_type_rewriter.cc
rename to src/tirx/ir/data_type_rewriter.cc
diff --git a/tirx/src/tirx/ir/data_type_rewriter.h b/src/tirx/ir/data_type_rewriter.h
similarity index 100%
rename from tirx/src/tirx/ir/data_type_rewriter.h
rename to src/tirx/ir/data_type_rewriter.h
diff --git a/tirx/src/tirx/ir/function.cc b/src/tirx/ir/function.cc
similarity index 100%
rename from tirx/src/tirx/ir/function.cc
rename to src/tirx/ir/function.cc
diff --git a/tirx/src/tirx/ir/index_map.cc b/src/tirx/ir/index_map.cc
similarity index 100%
rename from tirx/src/tirx/ir/index_map.cc
rename to src/tirx/ir/index_map.cc
diff --git a/tirx/src/tirx/ir/ir_mutator_with_analyzer.cc b/src/tirx/ir/ir_mutator_with_analyzer.cc
similarity index 100%
rename from tirx/src/tirx/ir/ir_mutator_with_analyzer.cc
rename to src/tirx/ir/ir_mutator_with_analyzer.cc
diff --git a/tirx/src/tirx/ir/ir_visitor_with_analyzer.cc b/src/tirx/ir/ir_visitor_with_analyzer.cc
similarity index 100%
rename from tirx/src/tirx/ir/ir_visitor_with_analyzer.cc
rename to src/tirx/ir/ir_visitor_with_analyzer.cc
diff --git a/tirx/src/tirx/ir/layout/axis_registry.cc b/src/tirx/ir/layout/axis_registry.cc
similarity index 100%
rename from tirx/src/tirx/ir/layout/axis_registry.cc
rename to src/tirx/ir/layout/axis_registry.cc
diff --git a/tirx/src/tirx/ir/layout/axis_registry.h b/src/tirx/ir/layout/axis_registry.h
similarity index 100%
rename from tirx/src/tirx/ir/layout/axis_registry.h
rename to src/tirx/ir/layout/axis_registry.h
diff --git a/tirx/src/tirx/ir/layout/compose_layout.cc b/src/tirx/ir/layout/compose_layout.cc
similarity index 100%
rename from tirx/src/tirx/ir/layout/compose_layout.cc
rename to src/tirx/ir/layout/compose_layout.cc
diff --git a/tirx/src/tirx/ir/layout/layout.cc b/src/tirx/ir/layout/layout.cc
similarity index 100%
rename from tirx/src/tirx/ir/layout/layout.cc
rename to src/tirx/ir/layout/layout.cc
diff --git a/tirx/src/tirx/ir/layout/tile_canonicalize.cc b/src/tirx/ir/layout/tile_canonicalize.cc
similarity index 100%
rename from tirx/src/tirx/ir/layout/tile_canonicalize.cc
rename to src/tirx/ir/layout/tile_canonicalize.cc
diff --git a/tirx/src/tirx/ir/layout/tile_core.cc b/src/tirx/ir/layout/tile_core.cc
similarity index 100%
rename from tirx/src/tirx/ir/layout/tile_core.cc
rename to src/tirx/ir/layout/tile_core.cc
diff --git a/tirx/src/tirx/ir/layout/tile_internal.h b/src/tirx/ir/layout/tile_internal.h
similarity index 100%
rename from tirx/src/tirx/ir/layout/tile_internal.h
rename to src/tirx/ir/layout/tile_internal.h
diff --git a/tirx/src/tirx/ir/layout/tile_tile_ops.cc b/src/tirx/ir/layout/tile_tile_ops.cc
similarity index 100%
rename from tirx/src/tirx/ir/layout/tile_tile_ops.cc
rename to src/tirx/ir/layout/tile_tile_ops.cc
diff --git a/tirx/src/tirx/ir/layout/utils.cc b/src/tirx/ir/layout/utils.cc
similarity index 100%
rename from tirx/src/tirx/ir/layout/utils.cc
rename to src/tirx/ir/layout/utils.cc
diff --git a/tirx/src/tirx/ir/layout/utils.h b/src/tirx/ir/layout/utils.h
similarity index 100%
rename from tirx/src/tirx/ir/layout/utils.h
rename to src/tirx/ir/layout/utils.h
diff --git a/tirx/src/tirx/ir/specialize.cc b/src/tirx/ir/specialize.cc
similarity index 100%
rename from tirx/src/tirx/ir/specialize.cc
rename to src/tirx/ir/specialize.cc
diff --git a/tirx/src/tirx/ir/stmt.cc b/src/tirx/ir/stmt.cc
similarity index 100%
rename from tirx/src/tirx/ir/stmt.cc
rename to src/tirx/ir/stmt.cc
diff --git a/tirx/src/tirx/ir/stmt_functor.cc b/src/tirx/ir/stmt_functor.cc
similarity index 100%
rename from tirx/src/tirx/ir/stmt_functor.cc
rename to src/tirx/ir/stmt_functor.cc
diff --git a/tirx/src/tirx/ir/tensor.cc b/src/tirx/ir/tensor.cc
similarity index 100%
rename from tirx/src/tirx/ir/tensor.cc
rename to src/tirx/ir/tensor.cc
diff --git a/tirx/src/tirx/ir/tensor_load.cc b/src/tirx/ir/tensor_load.cc
similarity index 100%
rename from tirx/src/tirx/ir/tensor_load.cc
rename to src/tirx/ir/tensor_load.cc
diff --git a/tirx/src/tirx/ir/transform.cc b/src/tirx/ir/transform.cc
similarity index 100%
rename from tirx/src/tirx/ir/transform.cc
rename to src/tirx/ir/transform.cc
diff --git a/tirx/src/tirx/ir/type.cc b/src/tirx/ir/type.cc
similarity index 100%
rename from tirx/src/tirx/ir/type.cc
rename to src/tirx/ir/type.cc
diff --git a/tirx/src/tirx/op/abi.cc b/src/tirx/op/abi.cc
similarity index 100%
rename from tirx/src/tirx/op/abi.cc
rename to src/tirx/op/abi.cc
diff --git a/tirx/src/tirx/op/annotation.cc b/src/tirx/op/annotation.cc
similarity index 100%
rename from tirx/src/tirx/op/annotation.cc
rename to src/tirx/op/annotation.cc
diff --git a/tirx/src/tirx/op/cpu.cc b/src/tirx/op/cpu.cc
similarity index 100%
rename from tirx/src/tirx/op/cpu.cc
rename to src/tirx/op/cpu.cc
diff --git a/tirx/src/tirx/op/gpu.cc b/src/tirx/op/gpu.cc
similarity index 100%
rename from tirx/src/tirx/op/gpu.cc
rename to src/tirx/op/gpu.cc
diff --git a/tirx/src/tirx/op/math.cc b/src/tirx/op/math.cc
similarity index 100%
rename from tirx/src/tirx/op/math.cc
rename to src/tirx/op/math.cc
diff --git a/tirx/src/tirx/op/memory.cc b/src/tirx/op/memory.cc
similarity index 100%
rename from tirx/src/tirx/op/memory.cc
rename to src/tirx/op/memory.cc
diff --git a/tirx/src/tirx/op/region.cc b/src/tirx/op/region.cc
similarity index 100%
rename from tirx/src/tirx/op/region.cc
rename to src/tirx/op/region.cc
diff --git a/tirx/src/tirx/op/vector.cc b/src/tirx/op/vector.cc
similarity index 100%
rename from tirx/src/tirx/op/vector.cc
rename to src/tirx/op/vector.cc
diff --git a/tirx/src/tirx/script/ir_builder/frame.cc b/src/tirx/script/ir_builder/frame.cc
similarity index 100%
rename from tirx/src/tirx/script/ir_builder/frame.cc
rename to src/tirx/script/ir_builder/frame.cc
diff --git a/tirx/src/tirx/script/ir_builder/ir.cc b/src/tirx/script/ir_builder/ir.cc
similarity index 100%
rename from tirx/src/tirx/script/ir_builder/ir.cc
rename to src/tirx/script/ir_builder/ir.cc
diff --git a/tirx/src/tirx/script/ir_builder/utils.h b/src/tirx/script/ir_builder/utils.h
similarity index 100%
rename from tirx/src/tirx/script/ir_builder/utils.h
rename to src/tirx/script/ir_builder/utils.h
diff --git a/tirx/src/tirx/script/printer/block.cc b/src/tirx/script/printer/block.cc
similarity index 100%
rename from tirx/src/tirx/script/printer/block.cc
rename to src/tirx/script/printer/block.cc
diff --git a/tirx/src/tirx/script/printer/expr.cc b/src/tirx/script/printer/expr.cc
similarity index 100%
rename from tirx/src/tirx/script/printer/expr.cc
rename to src/tirx/script/printer/expr.cc
diff --git a/tirx/src/tirx/script/printer/for_loop.cc b/src/tirx/script/printer/for_loop.cc
similarity index 100%
rename from tirx/src/tirx/script/printer/for_loop.cc
rename to src/tirx/script/printer/for_loop.cc
diff --git a/tirx/src/tirx/script/printer/function.cc b/src/tirx/script/printer/function.cc
similarity index 100%
rename from tirx/src/tirx/script/printer/function.cc
rename to src/tirx/script/printer/function.cc
diff --git a/tirx/src/tirx/script/printer/ir.cc b/src/tirx/script/printer/ir.cc
similarity index 100%
rename from tirx/src/tirx/script/printer/ir.cc
rename to src/tirx/script/printer/ir.cc
diff --git a/tirx/src/tirx/script/printer/stmt.cc b/src/tirx/script/printer/stmt.cc
similarity index 100%
rename from tirx/src/tirx/script/printer/stmt.cc
rename to src/tirx/script/printer/stmt.cc
diff --git a/tirx/src/tirx/script/printer/tensor.cc b/src/tirx/script/printer/tensor.cc
similarity index 100%
rename from tirx/src/tirx/script/printer/tensor.cc
rename to src/tirx/script/printer/tensor.cc
diff --git a/tirx/src/tirx/tile/context.cc b/src/tirx/tile/context.cc
similarity index 100%
rename from tirx/src/tirx/tile/context.cc
rename to src/tirx/tile/context.cc
diff --git a/tirx/src/tirx/tile/dispatch.cc b/src/tirx/tile/dispatch.cc
similarity index 100%
rename from tirx/src/tirx/tile/dispatch.cc
rename to src/tirx/tile/dispatch.cc
diff --git a/tirx/src/tirx/tile/lower.cc b/src/tirx/tile/lower.cc
similarity index 100%
rename from tirx/src/tirx/tile/lower.cc
rename to src/tirx/tile/lower.cc
diff --git a/tirx/src/tirx/tile/op.cc b/src/tirx/tile/op.cc
similarity index 100%
rename from tirx/src/tirx/tile/op.cc
rename to src/tirx/tile/op.cc
diff --git a/tirx/src/tirx/tile/thread_scope.cc b/src/tirx/tile/thread_scope.cc
similarity index 100%
rename from tirx/src/tirx/tile/thread_scope.cc
rename to src/tirx/tile/thread_scope.cc
diff --git a/tirx/src/tirx/transform/bind_target.cc b/src/tirx/transform/bind_target.cc
similarity index 100%
rename from tirx/src/tirx/transform/bind_target.cc
rename to src/tirx/transform/bind_target.cc
diff --git a/tirx/src/tirx/transform/common_subexpr_elim.cc b/src/tirx/transform/common_subexpr_elim.cc
similarity index 100%
rename from tirx/src/tirx/transform/common_subexpr_elim.cc
rename to src/tirx/transform/common_subexpr_elim.cc
diff --git a/tirx/src/tirx/transform/decorate_device_scope.cc b/src/tirx/transform/decorate_device_scope.cc
similarity index 100%
rename from tirx/src/tirx/transform/decorate_device_scope.cc
rename to src/tirx/transform/decorate_device_scope.cc
diff --git a/tirx/src/tirx/transform/dtype_conversion.cc b/src/tirx/transform/dtype_conversion.cc
similarity index 100%
rename from tirx/src/tirx/transform/dtype_conversion.cc
rename to src/tirx/transform/dtype_conversion.cc
diff --git a/tirx/src/tirx/transform/dtype_conversion.h b/src/tirx/transform/dtype_conversion.h
similarity index 100%
rename from tirx/src/tirx/transform/dtype_conversion.h
rename to src/tirx/transform/dtype_conversion.h
diff --git a/tirx/src/tirx/transform/flatten_tensor.cc b/src/tirx/transform/flatten_tensor.cc
similarity index 100%
rename from tirx/src/tirx/transform/flatten_tensor.cc
rename to src/tirx/transform/flatten_tensor.cc
diff --git a/tirx/src/tirx/transform/flattened_tensor.h b/src/tirx/transform/flattened_tensor.h
similarity index 100%
rename from tirx/src/tirx/transform/flattened_tensor.h
rename to src/tirx/transform/flattened_tensor.h
diff --git a/tirx/src/tirx/transform/force_narrow_index_to_i32.cc b/src/tirx/transform/force_narrow_index_to_i32.cc
similarity index 100%
rename from tirx/src/tirx/transform/force_narrow_index_to_i32.cc
rename to src/tirx/transform/force_narrow_index_to_i32.cc
diff --git a/tirx/src/tirx/transform/function_utils.cc b/src/tirx/transform/function_utils.cc
similarity index 100%
rename from tirx/src/tirx/transform/function_utils.cc
rename to src/tirx/transform/function_utils.cc
diff --git a/tirx/src/tirx/transform/hoist_if.cc b/src/tirx/transform/hoist_if.cc
similarity index 100%
rename from tirx/src/tirx/transform/hoist_if.cc
rename to src/tirx/transform/hoist_if.cc
diff --git a/tirx/src/tirx/transform/ir_utils.cc b/src/tirx/transform/ir_utils.cc
similarity index 100%
rename from tirx/src/tirx/transform/ir_utils.cc
rename to src/tirx/transform/ir_utils.cc
diff --git a/tirx/src/tirx/transform/ir_utils.h b/src/tirx/transform/ir_utils.h
similarity index 100%
rename from tirx/src/tirx/transform/ir_utils.h
rename to src/tirx/transform/ir_utils.h
diff --git a/tirx/src/tirx/transform/lower_intrin.cc b/src/tirx/transform/lower_intrin.cc
similarity index 100%
rename from tirx/src/tirx/transform/lower_intrin.cc
rename to src/tirx/transform/lower_intrin.cc
diff --git a/tirx/src/tirx/transform/lower_thread_allreduce.cc b/src/tirx/transform/lower_thread_allreduce.cc
similarity index 100%
rename from tirx/src/tirx/transform/lower_thread_allreduce.cc
rename to src/tirx/transform/lower_thread_allreduce.cc
diff --git a/tirx/src/tirx/transform/lower_tirx.cc b/src/tirx/transform/lower_tirx.cc
similarity index 100%
rename from tirx/src/tirx/transform/lower_tirx.cc
rename to src/tirx/transform/lower_tirx.cc
diff --git a/tirx/src/tirx/transform/lower_tirx_cleanup.cc b/src/tirx/transform/lower_tirx_cleanup.cc
similarity index 100%
rename from tirx/src/tirx/transform/lower_tirx_cleanup.cc
rename to src/tirx/transform/lower_tirx_cleanup.cc
diff --git a/tirx/src/tirx/transform/lower_tirx_dedup_tensormap.cc b/src/tirx/transform/lower_tirx_dedup_tensormap.cc
similarity index 100%
rename from tirx/src/tirx/transform/lower_tirx_dedup_tensormap.cc
rename to src/tirx/transform/lower_tirx_dedup_tensormap.cc
diff --git a/tirx/src/tirx/transform/lower_tvm_builtin.cc b/src/tirx/transform/lower_tvm_builtin.cc
similarity index 100%
rename from tirx/src/tirx/transform/lower_tvm_builtin.cc
rename to src/tirx/transform/lower_tvm_builtin.cc
diff --git a/tirx/src/tirx/transform/make_packed_api.cc b/src/tirx/transform/make_packed_api.cc
similarity index 100%
rename from tirx/src/tirx/transform/make_packed_api.cc
rename to src/tirx/transform/make_packed_api.cc
diff --git a/tirx/src/tirx/transform/narrow_datatype.cc b/src/tirx/transform/narrow_datatype.cc
similarity index 100%
rename from tirx/src/tirx/transform/narrow_datatype.cc
rename to src/tirx/transform/narrow_datatype.cc
diff --git a/tirx/src/tirx/transform/remove_no_op.cc b/src/tirx/transform/remove_no_op.cc
similarity index 100%
rename from tirx/src/tirx/transform/remove_no_op.cc
rename to src/tirx/transform/remove_no_op.cc
diff --git a/tirx/src/tirx/transform/remove_no_op.h b/src/tirx/transform/remove_no_op.h
similarity index 100%
rename from tirx/src/tirx/transform/remove_no_op.h
rename to src/tirx/transform/remove_no_op.h
diff --git a/tirx/src/tirx/transform/renormalize_split_pattern.cc b/src/tirx/transform/renormalize_split_pattern.cc
similarity index 100%
rename from tirx/src/tirx/transform/renormalize_split_pattern.cc
rename to src/tirx/transform/renormalize_split_pattern.cc
diff --git a/tirx/src/tirx/transform/skip_assert.cc b/src/tirx/transform/skip_assert.cc
similarity index 100%
rename from tirx/src/tirx/transform/skip_assert.cc
rename to src/tirx/transform/skip_assert.cc
diff --git a/tirx/src/tirx/transform/split_host_device.cc b/src/tirx/transform/split_host_device.cc
similarity index 100%
rename from tirx/src/tirx/transform/split_host_device.cc
rename to src/tirx/transform/split_host_device.cc
diff --git a/tirx/src/tirx/transform/stmt_simplify.cc b/src/tirx/transform/stmt_simplify.cc
similarity index 100%
rename from tirx/src/tirx/transform/stmt_simplify.cc
rename to src/tirx/transform/stmt_simplify.cc
diff --git a/tirx/src/tirx/transform/storage_rewrite.cc b/src/tirx/transform/storage_rewrite.cc
similarity index 100%
rename from tirx/src/tirx/transform/storage_rewrite.cc
rename to src/tirx/transform/storage_rewrite.cc
diff --git a/tirx/src/tirx/transform/tvm_ffi_binder.cc b/src/tirx/transform/tvm_ffi_binder.cc
similarity index 100%
rename from tirx/src/tirx/transform/tvm_ffi_binder.cc
rename to src/tirx/transform/tvm_ffi_binder.cc
diff --git a/tirx/src/tirx/transform/tvm_ffi_binder.h b/src/tirx/transform/tvm_ffi_binder.h
similarity index 100%
rename from tirx/src/tirx/transform/tvm_ffi_binder.h
rename to src/tirx/transform/tvm_ffi_binder.h
diff --git a/tirx/src/tirx/transform/unroll_loop.cc b/src/tirx/transform/unroll_loop.cc
similarity index 100%
rename from tirx/src/tirx/transform/unroll_loop.cc
rename to src/tirx/transform/unroll_loop.cc
diff --git a/tirx/src/tirx/transform/unsupported_dtype_legalize.cc b/src/tirx/transform/unsupported_dtype_legalize.cc
similarity index 100%
rename from tirx/src/tirx/transform/unsupported_dtype_legalize.cc
rename to src/tirx/transform/unsupported_dtype_legalize.cc
diff --git a/tirx/src/tirx/transform/vectorize_loop.cc b/src/tirx/transform/vectorize_loop.cc
similarity index 100%
rename from tirx/src/tirx/transform/vectorize_loop.cc
rename to src/tirx/transform/vectorize_loop.cc
diff --git a/tirx/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt
similarity index 100%
rename from tirx/tests/cpp/CMakeLists.txt
rename to tests/cpp/CMakeLists.txt
diff --git a/tirx/tests/cpp/ir/expr_functor_test.cc b/tests/cpp/ir/expr_functor_test.cc
similarity index 100%
rename from tirx/tests/cpp/ir/expr_functor_test.cc
rename to tests/cpp/ir/expr_functor_test.cc
diff --git a/tirx/tests/cpp/ir/op_signature_test.cc b/tests/cpp/ir/op_signature_test.cc
similarity index 100%
rename from tirx/tests/cpp/ir/op_signature_test.cc
rename to tests/cpp/ir/op_signature_test.cc
diff --git a/tirx/tests/cpp/ir/tensor_load_test.cc b/tests/cpp/ir/tensor_load_test.cc
similarity index 100%
rename from tirx/tests/cpp/ir/tensor_load_test.cc
rename to tests/cpp/ir/tensor_load_test.cc
diff --git a/tirx/tests/cpp/runtime/backend_workspace_test.cc b/tests/cpp/runtime/backend_workspace_test.cc
similarity index 100%
rename from tirx/tests/cpp/runtime/backend_workspace_test.cc
rename to tests/cpp/runtime/backend_workspace_test.cc
diff --git a/tirx/tests/cpp/runtime/logging_test.cc b/tests/cpp/runtime/logging_test.cc
similarity index 100%
rename from tirx/tests/cpp/runtime/logging_test.cc
rename to tests/cpp/runtime/logging_test.cc
diff --git a/tirx/tests/cpp/runtime/memory_scope_test.cc b/tests/cpp/runtime/memory_scope_test.cc
similarity index 100%
rename from tirx/tests/cpp/runtime/memory_scope_test.cc
rename to tests/cpp/runtime/memory_scope_test.cc
diff --git a/tirx/tests/cpp/runtime/tensor_io_test.cc b/tests/cpp/runtime/tensor_io_test.cc
similarity index 100%
rename from tirx/tests/cpp/runtime/tensor_io_test.cc
rename to tests/cpp/runtime/tensor_io_test.cc
diff --git a/tirx/tests/cpp/script/string_escape_test.cc b/tests/cpp/script/string_escape_test.cc
similarity index 100%
rename from tirx/tests/cpp/script/string_escape_test.cc
rename to tests/cpp/script/string_escape_test.cc
diff --git a/tirx/tests/cpp/sym/domain_map_test.cc b/tests/cpp/sym/domain_map_test.cc
similarity index 100%
rename from tirx/tests/cpp/sym/domain_map_test.cc
rename to tests/cpp/sym/domain_map_test.cc
diff --git a/tirx/tests/cpp/sym/pattern_match_test.cc b/tests/cpp/sym/pattern_match_test.cc
similarity index 100%
rename from tirx/tests/cpp/sym/pattern_match_test.cc
rename to tests/cpp/sym/pattern_match_test.cc
diff --git a/tirx/tests/cpp/target/config_schema_test.cc b/tests/cpp/target/config_schema_test.cc
similarity index 100%
rename from tirx/tests/cpp/target/config_schema_test.cc
rename to tests/cpp/target/config_schema_test.cc
diff --git a/tirx/tests/cpp/target/target_test.cc b/tests/cpp/target/target_test.cc
similarity index 100%
rename from tirx/tests/cpp/target/target_test.cc
rename to tests/cpp/target/target_test.cc
diff --git a/tirx/tests/cpp/tirx/stmt_functor_test.cc b/tests/cpp/tirx/stmt_functor_test.cc
similarity index 100%
rename from tirx/tests/cpp/tirx/stmt_functor_test.cc
rename to tests/cpp/tirx/stmt_functor_test.cc
diff --git a/tirx/tests/cpp/tirx/tensor_var_test.cc b/tests/cpp/tirx/tensor_var_test.cc
similarity index 100%
rename from tirx/tests/cpp/tirx/tensor_var_test.cc
rename to tests/cpp/tirx/tensor_var_test.cc
diff --git a/tirx/tests/cpp/tirx/thread_scope_test.cc b/tests/cpp/tirx/thread_scope_test.cc
similarity index 100%
rename from tirx/tests/cpp/tirx/thread_scope_test.cc
rename to tests/cpp/tirx/thread_scope_test.cc
diff --git a/tirx/tests/python/backend/__init__.py b/tests/python/backend/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/__init__.py
rename to tests/python/backend/__init__.py
diff --git a/tirx/tests/python/backend/cuda/__init__.py b/tests/python/backend/cuda/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/cuda/__init__.py
rename to tests/python/backend/cuda/__init__.py
diff --git a/tirx/tests/python/backend/cuda/codegen/__init__.py b/tests/python/backend/cuda/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/cuda/codegen/__init__.py
rename to tests/python/backend/cuda/codegen/__init__.py
diff --git a/tirx/tests/python/backend/cuda/codegen/test_basic.py b/tests/python/backend/cuda/codegen/test_basic.py
similarity index 100%
rename from tirx/tests/python/backend/cuda/codegen/test_basic.py
rename to tests/python/backend/cuda/codegen/test_basic.py
diff --git a/tirx/tests/python/backend/cuda/codegen/test_fastmath.py b/tests/python/backend/cuda/codegen/test_fastmath.py
similarity index 100%
rename from tirx/tests/python/backend/cuda/codegen/test_fastmath.py
rename to tests/python/backend/cuda/codegen/test_fastmath.py
diff --git a/tirx/tests/python/backend/cuda/codegen/test_fp4.py b/tests/python/backend/cuda/codegen/test_fp4.py
similarity index 100%
rename from tirx/tests/python/backend/cuda/codegen/test_fp4.py
rename to tests/python/backend/cuda/codegen/test_fp4.py
diff --git a/tirx/tests/python/backend/cuda/codegen/test_fp8.py b/tests/python/backend/cuda/codegen/test_fp8.py
similarity index 100%
rename from tirx/tests/python/backend/cuda/codegen/test_fp8.py
rename to tests/python/backend/cuda/codegen/test_fp8.py
diff --git a/tirx/tests/python/backend/cuda/test_host_bundle.py b/tests/python/backend/cuda/test_host_bundle.py
similarity index 100%
rename from tirx/tests/python/backend/cuda/test_host_bundle.py
rename to tests/python/backend/cuda/test_host_bundle.py
diff --git a/tirx/tests/python/backend/cuda/test_module_export.py b/tests/python/backend/cuda/test_module_export.py
similarity index 100%
rename from tirx/tests/python/backend/cuda/test_module_export.py
rename to tests/python/backend/cuda/test_module_export.py
diff --git a/tirx/tests/python/backend/hexagon/__init__.py b/tests/python/backend/hexagon/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/hexagon/__init__.py
rename to tests/python/backend/hexagon/__init__.py
diff --git a/tirx/tests/python/backend/hexagon/codegen/__init__.py b/tests/python/backend/hexagon/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/hexagon/codegen/__init__.py
rename to tests/python/backend/hexagon/codegen/__init__.py
diff --git a/tirx/tests/python/backend/hexagon/codegen/test_basic.py b/tests/python/backend/hexagon/codegen/test_basic.py
similarity index 100%
rename from tirx/tests/python/backend/hexagon/codegen/test_basic.py
rename to tests/python/backend/hexagon/codegen/test_basic.py
diff --git a/tirx/tests/python/backend/metal/__init__.py b/tests/python/backend/metal/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/metal/__init__.py
rename to tests/python/backend/metal/__init__.py
diff --git a/tirx/tests/python/backend/metal/codegen/__init__.py b/tests/python/backend/metal/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/metal/codegen/__init__.py
rename to tests/python/backend/metal/codegen/__init__.py
diff --git a/tirx/tests/python/backend/metal/codegen/test_basic.py b/tests/python/backend/metal/codegen/test_basic.py
similarity index 100%
rename from tirx/tests/python/backend/metal/codegen/test_basic.py
rename to tests/python/backend/metal/codegen/test_basic.py
diff --git a/tirx/tests/python/backend/metal/test_compile_callback.py b/tests/python/backend/metal/test_compile_callback.py
similarity index 100%
rename from tirx/tests/python/backend/metal/test_compile_callback.py
rename to tests/python/backend/metal/test_compile_callback.py
diff --git a/tirx/tests/python/backend/metal/test_module_export.py b/tests/python/backend/metal/test_module_export.py
similarity index 100%
rename from tirx/tests/python/backend/metal/test_module_export.py
rename to tests/python/backend/metal/test_module_export.py
diff --git a/tirx/tests/python/backend/opencl/__init__.py b/tests/python/backend/opencl/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/opencl/__init__.py
rename to tests/python/backend/opencl/__init__.py
diff --git a/tirx/tests/python/backend/opencl/codegen/__init__.py b/tests/python/backend/opencl/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/opencl/codegen/__init__.py
rename to tests/python/backend/opencl/codegen/__init__.py
diff --git a/tirx/tests/python/backend/opencl/codegen/test_basic.py b/tests/python/backend/opencl/codegen/test_basic.py
similarity index 100%
rename from tirx/tests/python/backend/opencl/codegen/test_basic.py
rename to tests/python/backend/opencl/codegen/test_basic.py
diff --git a/tirx/tests/python/backend/opencl/test_module_export.py b/tests/python/backend/opencl/test_module_export.py
similarity index 100%
rename from tirx/tests/python/backend/opencl/test_module_export.py
rename to tests/python/backend/opencl/test_module_export.py
diff --git a/tirx/tests/python/backend/rocm/__init__.py b/tests/python/backend/rocm/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/rocm/__init__.py
rename to tests/python/backend/rocm/__init__.py
diff --git a/tirx/tests/python/backend/rocm/codegen/__init__.py b/tests/python/backend/rocm/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/rocm/codegen/__init__.py
rename to tests/python/backend/rocm/codegen/__init__.py
diff --git a/tirx/tests/python/backend/rocm/codegen/test_basic.py b/tests/python/backend/rocm/codegen/test_basic.py
similarity index 100%
rename from tirx/tests/python/backend/rocm/codegen/test_basic.py
rename to tests/python/backend/rocm/codegen/test_basic.py
diff --git a/tirx/tests/python/backend/rocm/test_module_export.py b/tests/python/backend/rocm/test_module_export.py
similarity index 100%
rename from tirx/tests/python/backend/rocm/test_module_export.py
rename to tests/python/backend/rocm/test_module_export.py
diff --git a/tirx/tests/python/backend/vulkan/__init__.py b/tests/python/backend/vulkan/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/vulkan/__init__.py
rename to tests/python/backend/vulkan/__init__.py
diff --git a/tirx/tests/python/backend/vulkan/codegen/__init__.py b/tests/python/backend/vulkan/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/vulkan/codegen/__init__.py
rename to tests/python/backend/vulkan/codegen/__init__.py
diff --git a/tirx/tests/python/backend/vulkan/codegen/test_basic.py b/tests/python/backend/vulkan/codegen/test_basic.py
similarity index 100%
rename from tirx/tests/python/backend/vulkan/codegen/test_basic.py
rename to tests/python/backend/vulkan/codegen/test_basic.py
diff --git a/tirx/tests/python/backend/vulkan/test_module_export.py b/tests/python/backend/vulkan/test_module_export.py
similarity index 100%
rename from tirx/tests/python/backend/vulkan/test_module_export.py
rename to tests/python/backend/vulkan/test_module_export.py
diff --git a/tirx/tests/python/backend/webgpu/__init__.py b/tests/python/backend/webgpu/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/webgpu/__init__.py
rename to tests/python/backend/webgpu/__init__.py
diff --git a/tirx/tests/python/backend/webgpu/codegen/__init__.py b/tests/python/backend/webgpu/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/backend/webgpu/codegen/__init__.py
rename to tests/python/backend/webgpu/codegen/__init__.py
diff --git a/tirx/tests/python/backend/webgpu/codegen/test_basic.py b/tests/python/backend/webgpu/codegen/test_basic.py
similarity index 100%
rename from tirx/tests/python/backend/webgpu/codegen/test_basic.py
rename to tests/python/backend/webgpu/codegen/test_basic.py
diff --git a/tirx/tests/python/codegen/__init__.py b/tests/python/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/codegen/__init__.py
rename to tests/python/codegen/__init__.py
diff --git a/tirx/tests/python/codegen/c/__init__.py b/tests/python/codegen/c/__init__.py
similarity index 100%
rename from tirx/tests/python/codegen/c/__init__.py
rename to tests/python/codegen/c/__init__.py
diff --git a/tirx/tests/python/codegen/c/test_basic.py b/tests/python/codegen/c/test_basic.py
similarity index 100%
rename from tirx/tests/python/codegen/c/test_basic.py
rename to tests/python/codegen/c/test_basic.py
diff --git a/tirx/tests/python/codegen/gpu_common/__init__.py b/tests/python/codegen/gpu_common/__init__.py
similarity index 100%
rename from tirx/tests/python/codegen/gpu_common/__init__.py
rename to tests/python/codegen/gpu_common/__init__.py
diff --git a/tirx/tests/python/codegen/gpu_common/test_allreduce.py b/tests/python/codegen/gpu_common/test_allreduce.py
similarity index 100%
rename from tirx/tests/python/codegen/gpu_common/test_allreduce.py
rename to tests/python/codegen/gpu_common/test_allreduce.py
diff --git a/tirx/tests/python/codegen/gpu_common/test_device.py b/tests/python/codegen/gpu_common/test_device.py
similarity index 100%
rename from tirx/tests/python/codegen/gpu_common/test_device.py
rename to tests/python/codegen/gpu_common/test_device.py
diff --git a/tirx/tests/python/codegen/gpu_common/test_intrinsics.py b/tests/python/codegen/gpu_common/test_intrinsics.py
similarity index 100%
rename from tirx/tests/python/codegen/gpu_common/test_intrinsics.py
rename to tests/python/codegen/gpu_common/test_intrinsics.py
diff --git a/tirx/tests/python/codegen/llvm/__init__.py b/tests/python/codegen/llvm/__init__.py
similarity index 100%
rename from tirx/tests/python/codegen/llvm/__init__.py
rename to tests/python/codegen/llvm/__init__.py
diff --git a/tirx/tests/python/codegen/llvm/test_aarch64.py b/tests/python/codegen/llvm/test_aarch64.py
similarity index 100%
rename from tirx/tests/python/codegen/llvm/test_aarch64.py
rename to tests/python/codegen/llvm/test_aarch64.py
diff --git a/tirx/tests/python/codegen/llvm/test_arm.py b/tests/python/codegen/llvm/test_arm.py
similarity index 100%
rename from tirx/tests/python/codegen/llvm/test_arm.py
rename to tests/python/codegen/llvm/test_arm.py
diff --git a/tirx/tests/python/codegen/llvm/test_basic.py b/tests/python/codegen/llvm/test_basic.py
similarity index 100%
rename from tirx/tests/python/codegen/llvm/test_basic.py
rename to tests/python/codegen/llvm/test_basic.py
diff --git a/tirx/tests/python/codegen/llvm/test_riscv.py b/tests/python/codegen/llvm/test_riscv.py
similarity index 100%
rename from tirx/tests/python/codegen/llvm/test_riscv.py
rename to tests/python/codegen/llvm/test_riscv.py
diff --git a/tirx/tests/python/codegen/llvm/test_scalable_vector.py b/tests/python/codegen/llvm/test_scalable_vector.py
similarity index 100%
rename from tirx/tests/python/codegen/llvm/test_scalable_vector.py
rename to tests/python/codegen/llvm/test_scalable_vector.py
diff --git a/tirx/tests/python/codegen/llvm/test_x86.py b/tests/python/codegen/llvm/test_x86.py
similarity index 100%
rename from tirx/tests/python/codegen/llvm/test_x86.py
rename to tests/python/codegen/llvm/test_x86.py
diff --git a/tirx/tests/python/codegen/test_argument_validation.py b/tests/python/codegen/test_argument_validation.py
similarity index 100%
rename from tirx/tests/python/codegen/test_argument_validation.py
rename to tests/python/codegen/test_argument_validation.py
diff --git a/tirx/tests/python/codegen/test_assert.py b/tests/python/codegen/test_assert.py
similarity index 100%
rename from tirx/tests/python/codegen/test_assert.py
rename to tests/python/codegen/test_assert.py
diff --git a/tirx/tests/python/codegen/test_bool.py b/tests/python/codegen/test_bool.py
similarity index 100%
rename from tirx/tests/python/codegen/test_bool.py
rename to tests/python/codegen/test_bool.py
diff --git a/tirx/tests/python/codegen/test_common.py b/tests/python/codegen/test_common.py
similarity index 100%
rename from tirx/tests/python/codegen/test_common.py
rename to tests/python/codegen/test_common.py
diff --git a/tirx/tests/python/codegen/test_executable.py b/tests/python/codegen/test_executable.py
similarity index 100%
rename from tirx/tests/python/codegen/test_executable.py
rename to tests/python/codegen/test_executable.py
diff --git a/tirx/tests/python/codegen/test_extern.py b/tests/python/codegen/test_extern.py
similarity index 100%
rename from tirx/tests/python/codegen/test_extern.py
rename to tests/python/codegen/test_extern.py
diff --git a/tirx/tests/python/codegen/test_static_init.py b/tests/python/codegen/test_static_init.py
similarity index 100%
rename from tirx/tests/python/codegen/test_static_init.py
rename to tests/python/codegen/test_static_init.py
diff --git a/tirx/tests/python/conftest.py b/tests/python/conftest.py
similarity index 100%
rename from tirx/tests/python/conftest.py
rename to tests/python/conftest.py
diff --git a/tirx/tests/python/ir/__init__.py b/tests/python/ir/__init__.py
similarity index 100%
rename from tirx/tests/python/ir/__init__.py
rename to tests/python/ir/__init__.py
diff --git a/tirx/tests/python/ir/test_attrs.py b/tests/python/ir/test_attrs.py
similarity index 100%
rename from tirx/tests/python/ir/test_attrs.py
rename to tests/python/ir/test_attrs.py
diff --git a/tirx/tests/python/ir/test_expr_layout.py b/tests/python/ir/test_expr_layout.py
similarity index 100%
rename from tirx/tests/python/ir/test_expr_layout.py
rename to tests/python/ir/test_expr_layout.py
diff --git a/tirx/tests/python/ir/test_json.py b/tests/python/ir/test_json.py
similarity index 100%
rename from tirx/tests/python/ir/test_json.py
rename to tests/python/ir/test_json.py
diff --git a/tirx/tests/python/ir/test_module.py b/tests/python/ir/test_module.py
similarity index 100%
rename from tirx/tests/python/ir/test_module.py
rename to tests/python/ir/test_module.py
diff --git a/tirx/tests/python/ir/test_nonnullable.py b/tests/python/ir/test_nonnullable.py
similarity index 100%
rename from tirx/tests/python/ir/test_nonnullable.py
rename to tests/python/ir/test_nonnullable.py
diff --git a/tirx/tests/python/ir/test_prim_expr_deep_equal.py b/tests/python/ir/test_prim_expr_deep_equal.py
similarity index 100%
rename from tirx/tests/python/ir/test_prim_expr_deep_equal.py
rename to tests/python/ir/test_prim_expr_deep_equal.py
diff --git a/tirx/tests/python/ir/test_roundtrip_runtime_module.py b/tests/python/ir/test_roundtrip_runtime_module.py
similarity index 100%
rename from tirx/tests/python/ir/test_roundtrip_runtime_module.py
rename to tests/python/ir/test_roundtrip_runtime_module.py
diff --git a/tirx/tests/python/ir/test_type.py b/tests/python/ir/test_type.py
similarity index 100%
rename from tirx/tests/python/ir/test_type.py
rename to tests/python/ir/test_type.py
diff --git a/tirx/tests/python/runtime/__init__.py b/tests/python/runtime/__init__.py
similarity index 100%
rename from tirx/tests/python/runtime/__init__.py
rename to tests/python/runtime/__init__.py
diff --git a/tirx/tests/python/runtime/test_device_api.py b/tests/python/runtime/test_device_api.py
similarity index 100%
rename from tirx/tests/python/runtime/test_device_api.py
rename to tests/python/runtime/test_device_api.py
diff --git a/tirx/tests/python/runtime/test_memory_scope.py b/tests/python/runtime/test_memory_scope.py
similarity index 100%
rename from tirx/tests/python/runtime/test_memory_scope.py
rename to tests/python/runtime/test_memory_scope.py
diff --git a/tirx/tests/python/runtime/test_module.py b/tests/python/runtime/test_module.py
similarity index 100%
rename from tirx/tests/python/runtime/test_module.py
rename to tests/python/runtime/test_module.py
diff --git a/tirx/tests/python/runtime/test_tensor.py b/tests/python/runtime/test_tensor.py
similarity index 100%
rename from tirx/tests/python/runtime/test_tensor.py
rename to tests/python/runtime/test_tensor.py
diff --git a/tirx/tests/python/runtime/test_tirx_config.py b/tests/python/runtime/test_tirx_config.py
similarity index 100%
rename from tirx/tests/python/runtime/test_tirx_config.py
rename to tests/python/runtime/test_tirx_config.py
diff --git a/tirx/tests/python/runtime/test_validate_wheel_library.py b/tests/python/runtime/test_validate_wheel_library.py
similarity index 100%
rename from tirx/tests/python/runtime/test_validate_wheel_library.py
rename to tests/python/runtime/test_validate_wheel_library.py
diff --git a/tirx/tests/python/script/conftest.py b/tests/python/script/conftest.py
similarity index 100%
rename from tirx/tests/python/script/conftest.py
rename to tests/python/script/conftest.py
diff --git a/tirx/tests/python/script/minilang.py b/tests/python/script/minilang.py
similarity index 100%
rename from tirx/tests/python/script/minilang.py
rename to tests/python/script/minilang.py
diff --git a/tirx/tests/python/script/test_basic_usage.py b/tests/python/script/test_basic_usage.py
similarity index 100%
rename from tirx/tests/python/script/test_basic_usage.py
rename to tests/python/script/test_basic_usage.py
diff --git a/tirx/tests/python/script/test_builder_void_emission.py b/tests/python/script/test_builder_void_emission.py
similarity index 100%
rename from tirx/tests/python/script/test_builder_void_emission.py
rename to tests/python/script/test_builder_void_emission.py
diff --git a/tirx/tests/python/script/test_cross_function_call.py b/tests/python/script/test_cross_function_call.py
similarity index 100%
rename from tirx/tests/python/script/test_cross_function_call.py
rename to tests/python/script/test_cross_function_call.py
diff --git a/tirx/tests/python/script/test_dynamic_shape.py b/tests/python/script/test_dynamic_shape.py
similarity index 100%
rename from tirx/tests/python/script/test_dynamic_shape.py
rename to tests/python/script/test_dynamic_shape.py
diff --git a/tirx/tests/python/script/test_error_handling.py b/tests/python/script/test_error_handling.py
similarity index 100%
rename from tirx/tests/python/script/test_error_handling.py
rename to tests/python/script/test_error_handling.py
diff --git a/tirx/tests/python/script/test_ir_builder.py b/tests/python/script/test_ir_builder.py
similarity index 100%
rename from tirx/tests/python/script/test_ir_builder.py
rename to tests/python/script/test_ir_builder.py
diff --git a/tirx/tests/python/script/test_jit_specialization.py b/tests/python/script/test_jit_specialization.py
similarity index 100%
rename from tirx/tests/python/script/test_jit_specialization.py
rename to tests/python/script/test_jit_specialization.py
diff --git a/tirx/tests/python/script/test_meta_programming.py b/tests/python/script/test_meta_programming.py
similarity index 100%
rename from tirx/tests/python/script/test_meta_programming.py
rename to tests/python/script/test_meta_programming.py
diff --git a/tirx/tests/python/script/test_parser_entry.py b/tests/python/script/test_parser_entry.py
similarity index 100%
rename from tirx/tests/python/script/test_parser_entry.py
rename to tests/python/script/test_parser_entry.py
diff --git a/tirx/tests/python/script/test_printer_doc.py b/tests/python/script/test_printer_doc.py
similarity index 100%
rename from tirx/tests/python/script/test_printer_doc.py
rename to tests/python/script/test_printer_doc.py
diff --git a/tirx/tests/python/script/test_source_locations.py b/tests/python/script/test_source_locations.py
similarity index 100%
rename from tirx/tests/python/script/test_source_locations.py
rename to tests/python/script/test_source_locations.py
diff --git a/tirx/tests/python/script/test_special_parser_protocol.py b/tests/python/script/test_special_parser_protocol.py
similarity index 100%
rename from tirx/tests/python/script/test_special_parser_protocol.py
rename to tests/python/script/test_special_parser_protocol.py
diff --git a/tirx/tests/python/support/__init__.py b/tests/python/support/__init__.py
similarity index 100%
rename from tirx/tests/python/support/__init__.py
rename to tests/python/support/__init__.py
diff --git a/tirx/tests/python/support/test_ccache.py b/tests/python/support/test_ccache.py
similarity index 100%
rename from tirx/tests/python/support/test_ccache.py
rename to tests/python/support/test_ccache.py
diff --git a/tirx/tests/python/support/test_config.py b/tests/python/support/test_config.py
similarity index 100%
rename from tirx/tests/python/support/test_config.py
rename to tests/python/support/test_config.py
diff --git a/tirx/tests/python/support/test_nvcc.py b/tests/python/support/test_nvcc.py
similarity index 100%
rename from tirx/tests/python/support/test_nvcc.py
rename to tests/python/support/test_nvcc.py
diff --git a/tirx/tests/python/support/test_popen_pool.py b/tests/python/support/test_popen_pool.py
similarity index 100%
rename from tirx/tests/python/support/test_popen_pool.py
rename to tests/python/support/test_popen_pool.py
diff --git a/tirx/tests/python/support/test_util.py b/tests/python/support/test_util.py
similarity index 100%
rename from tirx/tests/python/support/test_util.py
rename to tests/python/support/test_util.py
diff --git a/tirx/tests/python/sym/__init__.py b/tests/python/sym/__init__.py
similarity index 100%
rename from tirx/tests/python/sym/__init__.py
rename to tests/python/sym/__init__.py
diff --git a/tirx/tests/python/sym/test_analyzer_object.py b/tests/python/sym/test_analyzer_object.py
similarity index 100%
rename from tirx/tests/python/sym/test_analyzer_object.py
rename to tests/python/sym/test_analyzer_object.py
diff --git a/tirx/tests/python/sym/test_const_int_bound.py b/tests/python/sym/test_const_int_bound.py
similarity index 100%
rename from tirx/tests/python/sym/test_const_int_bound.py
rename to tests/python/sym/test_const_int_bound.py
diff --git a/tirx/tests/python/sym/test_deduce_bound.py b/tests/python/sym/test_deduce_bound.py
similarity index 100%
rename from tirx/tests/python/sym/test_deduce_bound.py
rename to tests/python/sym/test_deduce_bound.py
diff --git a/tirx/tests/python/sym/test_detect_clip_bound.py b/tests/python/sym/test_detect_clip_bound.py
similarity index 100%
rename from tirx/tests/python/sym/test_detect_clip_bound.py
rename to tests/python/sym/test_detect_clip_bound.py
diff --git a/tirx/tests/python/sym/test_detect_linear_equation.py b/tests/python/sym/test_detect_linear_equation.py
similarity index 100%
rename from tirx/tests/python/sym/test_detect_linear_equation.py
rename to tests/python/sym/test_detect_linear_equation.py
diff --git a/tirx/tests/python/sym/test_intset.py b/tests/python/sym/test_intset.py
similarity index 100%
rename from tirx/tests/python/sym/test_intset.py
rename to tests/python/sym/test_intset.py
diff --git a/tirx/tests/python/sym/test_iter_affine_map.py b/tests/python/sym/test_iter_affine_map.py
similarity index 100%
rename from tirx/tests/python/sym/test_iter_affine_map.py
rename to tests/python/sym/test_iter_affine_map.py
diff --git a/tirx/tests/python/sym/test_rewrite_simplify.py b/tests/python/sym/test_rewrite_simplify.py
similarity index 100%
rename from tirx/tests/python/sym/test_rewrite_simplify.py
rename to tests/python/sym/test_rewrite_simplify.py
diff --git a/tirx/tests/python/sym/test_simplify.py b/tests/python/sym/test_simplify.py
similarity index 100%
rename from tirx/tests/python/sym/test_simplify.py
rename to tests/python/sym/test_simplify.py
diff --git a/tirx/tests/python/sym/test_z3.py b/tests/python/sym/test_z3.py
similarity index 100%
rename from tirx/tests/python/sym/test_z3.py
rename to tests/python/sym/test_z3.py
diff --git a/tirx/tests/python/target/__init__.py b/tests/python/target/__init__.py
similarity index 100%
rename from tirx/tests/python/target/__init__.py
rename to tests/python/target/__init__.py
diff --git a/tirx/tests/python/target/test_llvm_features_info.py b/tests/python/target/test_llvm_features_info.py
similarity index 100%
rename from tirx/tests/python/target/test_llvm_features_info.py
rename to tests/python/target/test_llvm_features_info.py
diff --git a/tirx/tests/python/target/test_parser_mprofile.py b/tests/python/target/test_parser_mprofile.py
similarity index 100%
rename from tirx/tests/python/target/test_parser_mprofile.py
rename to tests/python/target/test_parser_mprofile.py
diff --git a/tirx/tests/python/target/test_riscv_features.py b/tests/python/target/test_riscv_features.py
similarity index 100%
rename from tirx/tests/python/target/test_riscv_features.py
rename to tests/python/target/test_riscv_features.py
diff --git a/tirx/tests/python/target/test_x86_features.py b/tests/python/target/test_x86_features.py
similarity index 100%
rename from tirx/tests/python/target/test_x86_features.py
rename to tests/python/target/test_x86_features.py
diff --git a/tirx/tests/python/testing/__init__.py b/tests/python/testing/__init__.py
similarity index 100%
rename from tirx/tests/python/testing/__init__.py
rename to tests/python/testing/__init__.py
diff --git a/tirx/tests/python/tirx/__init__.py b/tests/python/tirx/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/__init__.py
rename to tests/python/tirx/__init__.py
diff --git a/tirx/tests/python/tirx/analysis/__init__.py b/tests/python/tirx/analysis/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/analysis/__init__.py
rename to tests/python/tirx/analysis/__init__.py
diff --git a/tirx/tests/python/tirx/analysis/test_check_well_defined.py b/tests/python/tirx/analysis/test_check_well_defined.py
similarity index 100%
rename from tirx/tests/python/tirx/analysis/test_check_well_defined.py
rename to tests/python/tirx/analysis/test_check_well_defined.py
diff --git a/tirx/tests/python/tirx/analysis/test_undefined_vars.py b/tests/python/tirx/analysis/test_undefined_vars.py
similarity index 100%
rename from tirx/tests/python/tirx/analysis/test_undefined_vars.py
rename to tests/python/tirx/analysis/test_undefined_vars.py
diff --git a/tirx/tests/python/tirx/base/__init__.py b/tests/python/tirx/base/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/base/__init__.py
rename to tests/python/tirx/base/__init__.py
diff --git a/tirx/tests/python/tirx/base/test_host_func.py b/tests/python/tirx/base/test_host_func.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_host_func.py
rename to tests/python/tirx/base/test_host_func.py
diff --git a/tirx/tests/python/tirx/base/test_imm_values.py b/tests/python/tirx/base/test_imm_values.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_imm_values.py
rename to tests/python/tirx/base/test_imm_values.py
diff --git a/tirx/tests/python/tirx/base/test_index_map.py b/tests/python/tirx/base/test_index_map.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_index_map.py
rename to tests/python/tirx/base/test_index_map.py
diff --git a/tirx/tests/python/tirx/base/test_intrin.py b/tests/python/tirx/base/test_intrin.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_intrin.py
rename to tests/python/tirx/base/test_intrin.py
diff --git a/tirx/tests/python/tirx/base/test_nodes.py b/tests/python/tirx/base/test_nodes.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_nodes.py
rename to tests/python/tirx/base/test_nodes.py
diff --git a/tirx/tests/python/tirx/base/test_op_types.py b/tests/python/tirx/base/test_op_types.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_op_types.py
rename to tests/python/tirx/base/test_op_types.py
diff --git a/tirx/tests/python/tirx/base/test_ptx_cp_async.py b/tests/python/tirx/base/test_ptx_cp_async.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_ptx_cp_async.py
rename to tests/python/tirx/base/test_ptx_cp_async.py
diff --git a/tirx/tests/python/tirx/base/test_ptx_griddepcontrol.py b/tests/python/tirx/base/test_ptx_griddepcontrol.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_ptx_griddepcontrol.py
rename to tests/python/tirx/base/test_ptx_griddepcontrol.py
diff --git a/tirx/tests/python/tirx/base/test_ptx_mma_sp.py b/tests/python/tirx/base/test_ptx_mma_sp.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_ptx_mma_sp.py
rename to tests/python/tirx/base/test_ptx_mma_sp.py
diff --git a/tirx/tests/python/tirx/base/test_ptx_scalar_f32_math.py b/tests/python/tirx/base/test_ptx_scalar_f32_math.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_ptx_scalar_f32_math.py
rename to tests/python/tirx/base/test_ptx_scalar_f32_math.py
diff --git a/tirx/tests/python/tirx/base/test_scalable_datatype.py b/tests/python/tirx/base/test_scalable_datatype.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_scalable_datatype.py
rename to tests/python/tirx/base/test_scalable_datatype.py
diff --git a/tirx/tests/python/tirx/base/test_specialize.py b/tests/python/tirx/base/test_specialize.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_specialize.py
rename to tests/python/tirx/base/test_specialize.py
diff --git a/tirx/tests/python/tirx/base/test_tensor_type.py b/tests/python/tirx/base/test_tensor_type.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_tensor_type.py
rename to tests/python/tirx/base/test_tensor_type.py
diff --git a/tirx/tests/python/tirx/base/test_texture_scope.py b/tests/python/tirx/base/test_texture_scope.py
similarity index 100%
rename from tirx/tests/python/tirx/base/test_texture_scope.py
rename to tests/python/tirx/base/test_texture_scope.py
diff --git a/tirx/tests/python/tirx/codegen/__init__.py b/tests/python/tirx/codegen/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/__init__.py
rename to tests/python/tirx/codegen/__init__.py
diff --git a/tirx/tests/python/tirx/codegen/conftest.py b/tests/python/tirx/codegen/conftest.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/conftest.py
rename to tests/python/tirx/codegen/conftest.py
diff --git a/tirx/tests/python/tirx/codegen/test_ampere.py b/tests/python/tirx/codegen/test_ampere.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_ampere.py
rename to tests/python/tirx/codegen/test_ampere.py
diff --git a/tirx/tests/python/tirx/codegen/test_blackwell.py b/tests/python/tirx/codegen/test_blackwell.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_blackwell.py
rename to tests/python/tirx/codegen/test_blackwell.py
diff --git a/tirx/tests/python/tirx/codegen/test_cuda.py b/tests/python/tirx/codegen/test_cuda.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_cuda.py
rename to tests/python/tirx/codegen/test_cuda.py
diff --git a/tirx/tests/python/tirx/codegen/test_cuda_cta_reduce.py b/tests/python/tirx/codegen/test_cuda_cta_reduce.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_cuda_cta_reduce.py
rename to tests/python/tirx/codegen/test_cuda_cta_reduce.py
diff --git a/tirx/tests/python/tirx/codegen/test_cuda_wait_until.py b/tests/python/tirx/codegen/test_cuda_wait_until.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_cuda_wait_until.py
rename to tests/python/tirx/codegen/test_cuda_wait_until.py
diff --git a/tirx/tests/python/tirx/codegen/test_cuda_warp_reduce.py b/tests/python/tirx/codegen/test_cuda_warp_reduce.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_cuda_warp_reduce.py
rename to tests/python/tirx/codegen/test_cuda_warp_reduce.py
diff --git a/tirx/tests/python/tirx/codegen/test_dsmem.py b/tests/python/tirx/codegen/test_dsmem.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_dsmem.py
rename to tests/python/tirx/codegen/test_dsmem.py
diff --git a/tirx/tests/python/tirx/codegen/test_hopper.py b/tests/python/tirx/codegen/test_hopper.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_hopper.py
rename to tests/python/tirx/codegen/test_hopper.py
diff --git a/tirx/tests/python/tirx/codegen/test_nki.py b/tests/python/tirx/codegen/test_nki.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_nki.py
rename to tests/python/tirx/codegen/test_nki.py
diff --git a/tirx/tests/python/tirx/codegen/test_ptx_addr.py b/tests/python/tirx/codegen/test_ptx_addr.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_ptx_addr.py
rename to tests/python/tirx/codegen/test_ptx_addr.py
diff --git a/tirx/tests/python/tirx/codegen/test_ptx_cvt.py b/tests/python/tirx/codegen/test_ptx_cvt.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_ptx_cvt.py
rename to tests/python/tirx/codegen/test_ptx_cvt.py
diff --git a/tirx/tests/python/tirx/codegen/test_ptx_dialect.py b/tests/python/tirx/codegen/test_ptx_dialect.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_ptx_dialect.py
rename to tests/python/tirx/codegen/test_ptx_dialect.py
diff --git a/tirx/tests/python/tirx/codegen/test_ptx_ld_st_ops.py b/tests/python/tirx/codegen/test_ptx_ld_st_ops.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_ptx_ld_st_ops.py
rename to tests/python/tirx/codegen/test_ptx_ld_st_ops.py
diff --git a/tirx/tests/python/tirx/codegen/test_tcgen05_descriptor_encoders.py b/tests/python/tirx/codegen/test_tcgen05_descriptor_encoders.py
similarity index 100%
rename from tirx/tests/python/tirx/codegen/test_tcgen05_descriptor_encoders.py
rename to tests/python/tirx/codegen/test_tcgen05_descriptor_encoders.py
diff --git a/tirx/tests/python/tirx/conftest.py b/tests/python/tirx/conftest.py
similarity index 100%
rename from tirx/tests/python/tirx/conftest.py
rename to tests/python/tirx/conftest.py
diff --git a/tirx/tests/python/tirx/iket/__init__.py b/tests/python/tirx/iket/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/iket/__init__.py
rename to tests/python/tirx/iket/__init__.py
diff --git a/tirx/tests/python/tirx/iket/iket_profile_workload.py b/tests/python/tirx/iket/iket_profile_workload.py
similarity index 100%
rename from tirx/tests/python/tirx/iket/iket_profile_workload.py
rename to tests/python/tirx/iket/iket_profile_workload.py
diff --git a/tirx/tests/python/tirx/iket/oracle/__init__.py b/tests/python/tirx/iket/oracle/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/iket/oracle/__init__.py
rename to tests/python/tirx/iket/oracle/__init__.py
diff --git a/tirx/tests/python/tirx/iket/oracle/generate_iket_official_oracle.py b/tests/python/tirx/iket/oracle/generate_iket_official_oracle.py
similarity index 100%
rename from tirx/tests/python/tirx/iket/oracle/generate_iket_official_oracle.py
rename to tests/python/tirx/iket/oracle/generate_iket_official_oracle.py
diff --git a/tirx/tests/python/tirx/iket/oracle/iket_official_cutlass_4_6_0_oracle.json b/tests/python/tirx/iket/oracle/iket_official_cutlass_4_6_0_oracle.json
similarity index 100%
rename from tirx/tests/python/tirx/iket/oracle/iket_official_cutlass_4_6_0_oracle.json
rename to tests/python/tirx/iket/oracle/iket_official_cutlass_4_6_0_oracle.json
diff --git a/tirx/tests/python/tirx/iket/test_orchestration.py b/tests/python/tirx/iket/test_orchestration.py
similarity index 100%
rename from tirx/tests/python/tirx/iket/test_orchestration.py
rename to tests/python/tirx/iket/test_orchestration.py
diff --git a/tirx/tests/python/tirx/iket/test_profiler.py b/tests/python/tirx/iket/test_profiler.py
similarity index 100%
rename from tirx/tests/python/tirx/iket/test_profiler.py
rename to tests/python/tirx/iket/test_profiler.py
diff --git a/tirx/tests/python/tirx/iket/verify_iket_official_patch.py b/tests/python/tirx/iket/verify_iket_official_patch.py
similarity index 100%
rename from tirx/tests/python/tirx/iket/verify_iket_official_patch.py
rename to tests/python/tirx/iket/verify_iket_official_patch.py
diff --git a/tirx/tests/python/tirx/layout_fixtures.py b/tests/python/tirx/layout_fixtures.py
similarity index 100%
rename from tirx/tests/python/tirx/layout_fixtures.py
rename to tests/python/tirx/layout_fixtures.py
diff --git a/tirx/tests/python/tirx/script/__init__.py b/tests/python/tirx/script/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/script/__init__.py
rename to tests/python/tirx/script/__init__.py
diff --git a/tirx/tests/python/tirx/script/test_basic_usage.py b/tests/python/tirx/script/test_basic_usage.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_basic_usage.py
rename to tests/python/tirx/script/test_basic_usage.py
diff --git a/tirx/tests/python/tirx/script/test_dynamic_shape.py b/tests/python/tirx/script/test_dynamic_shape.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_dynamic_shape.py
rename to tests/python/tirx/script/test_dynamic_shape.py
diff --git a/tirx/tests/python/tirx/script/test_error_handling.py b/tests/python/tirx/script/test_error_handling.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_error_handling.py
rename to tests/python/tirx/script/test_error_handling.py
diff --git a/tirx/tests/python/tirx/script/test_gpu.py b/tests/python/tirx/script/test_gpu.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_gpu.py
rename to tests/python/tirx/script/test_gpu.py
diff --git a/tirx/tests/python/tirx/script/test_jit_specialization.py b/tests/python/tirx/script/test_jit_specialization.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_jit_specialization.py
rename to tests/python/tirx/script/test_jit_specialization.py
diff --git a/tirx/tests/python/tirx/script/test_meta_programming.py b/tests/python/tirx/script/test_meta_programming.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_meta_programming.py
rename to tests/python/tirx/script/test_meta_programming.py
diff --git a/tirx/tests/python/tirx/script/test_printer_highlight.py b/tests/python/tirx/script/test_printer_highlight.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_printer_highlight.py
rename to tests/python/tirx/script/test_printer_highlight.py
diff --git a/tirx/tests/python/tirx/script/test_printer_invisible_path_info.py b/tests/python/tirx/script/test_printer_invisible_path_info.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_printer_invisible_path_info.py
rename to tests/python/tirx/script/test_printer_invisible_path_info.py
diff --git a/tirx/tests/python/tirx/script/test_printer_structural_equal.py b/tests/python/tirx/script/test_printer_structural_equal.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_printer_structural_equal.py
rename to tests/python/tirx/script/test_printer_structural_equal.py
diff --git a/tirx/tests/python/tirx/script/test_printer_underlining.py b/tests/python/tirx/script/test_printer_underlining.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_printer_underlining.py
rename to tests/python/tirx/script/test_printer_underlining.py
diff --git a/tirx/tests/python/tirx/script/test_source_locations.py b/tests/python/tirx/script/test_source_locations.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_source_locations.py
rename to tests/python/tirx/script/test_source_locations.py
diff --git a/tirx/tests/python/tirx/script/test_tensors.py b/tests/python/tirx/script/test_tensors.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_tensors.py
rename to tests/python/tirx/script/test_tensors.py
diff --git a/tirx/tests/python/tirx/script/test_tracing.py b/tests/python/tirx/script/test_tracing.py
similarity index 100%
rename from tirx/tests/python/tirx/script/test_tracing.py
rename to tests/python/tirx/script/test_tracing.py
diff --git a/tirx/tests/python/tirx/test_alloc_pool.py b/tests/python/tirx/test_alloc_pool.py
similarity index 100%
rename from tirx/tests/python/tirx/test_alloc_pool.py
rename to tests/python/tirx/test_alloc_pool.py
diff --git a/tirx/tests/python/tirx/test_axis_enum.py b/tests/python/tirx/test_axis_enum.py
similarity index 100%
rename from tirx/tests/python/tirx/test_axis_enum.py
rename to tests/python/tirx/test_axis_enum.py
diff --git a/tirx/tests/python/tirx/test_bench_utils.py b/tests/python/tirx/test_bench_utils.py
similarity index 100%
rename from tirx/tests/python/tirx/test_bench_utils.py
rename to tests/python/tirx/test_bench_utils.py
diff --git a/tirx/tests/python/tirx/test_compilation_pipeline.py b/tests/python/tirx/test_compilation_pipeline.py
similarity index 100%
rename from tirx/tests/python/tirx/test_compilation_pipeline.py
rename to tests/python/tirx/test_compilation_pipeline.py
diff --git a/tirx/tests/python/tirx/test_control_flow.py b/tests/python/tirx/test_control_flow.py
similarity index 100%
rename from tirx/tests/python/tirx/test_control_flow.py
rename to tests/python/tirx/test_control_flow.py
diff --git a/tirx/tests/python/tirx/test_cuda_arch_marker.py b/tests/python/tirx/test_cuda_arch_marker.py
similarity index 100%
rename from tirx/tests/python/tirx/test_cuda_arch_marker.py
rename to tests/python/tirx/test_cuda_arch_marker.py
diff --git a/tirx/tests/python/tirx/test_cuda_backend_config.py b/tests/python/tirx/test_cuda_backend_config.py
similarity index 100%
rename from tirx/tests/python/tirx/test_cuda_backend_config.py
rename to tests/python/tirx/test_cuda_backend_config.py
diff --git a/tirx/tests/python/tirx/test_cuda_launch.py b/tests/python/tirx/test_cuda_launch.py
similarity index 100%
rename from tirx/tests/python/tirx/test_cuda_launch.py
rename to tests/python/tirx/test_cuda_launch.py
diff --git a/tirx/tests/python/tirx/test_exec_context.py b/tests/python/tirx/test_exec_context.py
similarity index 100%
rename from tirx/tests/python/tirx/test_exec_context.py
rename to tests/python/tirx/test_exec_context.py
diff --git a/tirx/tests/python/tirx/test_inline.py b/tests/python/tirx/test_inline.py
similarity index 100%
rename from tirx/tests/python/tirx/test_inline.py
rename to tests/python/tirx/test_inline.py
diff --git a/tirx/tests/python/tirx/test_jit.py b/tests/python/tirx/test_jit.py
similarity index 100%
rename from tirx/tests/python/tirx/test_jit.py
rename to tests/python/tirx/test_jit.py
diff --git a/tirx/tests/python/tirx/test_layout.py b/tests/python/tirx/test_layout.py
similarity index 100%
rename from tirx/tests/python/tirx/test_layout.py
rename to tests/python/tirx/test_layout.py
diff --git a/tirx/tests/python/tirx/test_op.py b/tests/python/tirx/test_op.py
similarity index 100%
rename from tirx/tests/python/tirx/test_op.py
rename to tests/python/tirx/test_op.py
diff --git a/tirx/tests/python/tirx/test_op_namespace_cleanup.py b/tests/python/tirx/test_op_namespace_cleanup.py
similarity index 100%
rename from tirx/tests/python/tirx/test_op_namespace_cleanup.py
rename to tests/python/tirx/test_op_namespace_cleanup.py
diff --git a/tirx/tests/python/tirx/test_roundtrip_namespaces.py b/tests/python/tirx/test_roundtrip_namespaces.py
similarity index 100%
rename from tirx/tests/python/tirx/test_roundtrip_namespaces.py
rename to tests/python/tirx/test_roundtrip_namespaces.py
diff --git a/tirx/tests/python/tirx/test_tensor_data_reinfer_type.py b/tests/python/tirx/test_tensor_data_reinfer_type.py
similarity index 100%
rename from tirx/tests/python/tirx/test_tensor_data_reinfer_type.py
rename to tests/python/tirx/test_tensor_data_reinfer_type.py
diff --git a/tirx/tests/python/tirx/test_thread_scope.py b/tests/python/tirx/test_thread_scope.py
similarity index 100%
rename from tirx/tests/python/tirx/test_thread_scope.py
rename to tests/python/tirx/test_thread_scope.py
diff --git a/tirx/tests/python/tirx/test_tile_namespace.py b/tests/python/tirx/test_tile_namespace.py
similarity index 100%
rename from tirx/tests/python/tirx/test_tile_namespace.py
rename to tests/python/tirx/test_tile_namespace.py
diff --git a/tirx/tests/python/tirx/test_verifier.py b/tests/python/tirx/test_verifier.py
similarity index 100%
rename from tirx/tests/python/tirx/test_verifier.py
rename to tests/python/tirx/test_verifier.py
diff --git a/tirx/tests/python/tirx/tile/__init__.py b/tests/python/tirx/tile/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/__init__.py
rename to tests/python/tirx/tile/__init__.py
diff --git a/tirx/tests/python/tirx/tile/cuda/__init__.py b/tests/python/tirx/tile/cuda/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/__init__.py
rename to tests/python/tirx/tile/cuda/__init__.py
diff --git a/tirx/tests/python/tirx/tile/cuda/conftest.py b/tests/python/tirx/tile/cuda/conftest.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/conftest.py
rename to tests/python/tirx/tile/cuda/conftest.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_add_sub_mul_div.py b/tests/python/tirx/tile/cuda/test_add_sub_mul_div.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_add_sub_mul_div.py
rename to tests/python/tirx/tile/cuda/test_add_sub_mul_div.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_cp_async.py b/tests/python/tirx/tile/cuda/test_cp_async.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_cp_async.py
rename to tests/python/tirx/tile/cuda/test_cp_async.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_cp_async_bulk.py b/tests/python/tirx/tile/cuda/test_cp_async_bulk.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_cp_async_bulk.py
rename to tests/python/tirx/tile/cuda/test_cp_async_bulk.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_cp_async_bulk_tensor.py b/tests/python/tirx/tile/cuda/test_cp_async_bulk_tensor.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_cp_async_bulk_tensor.py
rename to tests/python/tirx/tile/cuda/test_cp_async_bulk_tensor.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_cvt.py b/tests/python/tirx/tile/cuda/test_cvt.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_cvt.py
rename to tests/python/tirx/tile/cuda/test_cvt.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_ewise.py b/tests/python/tirx/tile/cuda/test_ewise.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_ewise.py
rename to tests/python/tirx/tile/cuda/test_ewise.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_explicit_patterns.py b/tests/python/tirx/tile/cuda/test_explicit_patterns.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_explicit_patterns.py
rename to tests/python/tirx/tile/cuda/test_explicit_patterns.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_fma.py b/tests/python/tirx/tile/cuda/test_fma.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_fma.py
rename to tests/python/tirx/tile/cuda/test_fma.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_ld_st_cache_policy.py b/tests/python/tirx/tile/cuda/test_ld_st_cache_policy.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_ld_st_cache_policy.py
rename to tests/python/tirx/tile/cuda/test_ld_st_cache_policy.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_ld_st_gmem_smem.py b/tests/python/tirx/tile/cuda/test_ld_st_gmem_smem.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_ld_st_gmem_smem.py
rename to tests/python/tirx/tile/cuda/test_ld_st_gmem_smem.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_ld_st_registers.py b/tests/python/tirx/tile/cuda/test_ld_st_registers.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_ld_st_registers.py
rename to tests/python/tirx/tile/cuda/test_ld_st_registers.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_ldmatrix_stmatrix.py b/tests/python/tirx/tile/cuda/test_ldmatrix_stmatrix.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_ldmatrix_stmatrix.py
rename to tests/python/tirx/tile/cuda/test_ldmatrix_stmatrix.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_mma_sync.py b/tests/python/tirx/tile/cuda/test_mma_sync.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_mma_sync.py
rename to tests/python/tirx/tile/cuda/test_mma_sync.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_mov.py b/tests/python/tirx/tile/cuda/test_mov.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_mov.py
rename to tests/python/tirx/tile/cuda/test_mov.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_pattern_groups.py b/tests/python/tirx/tile/cuda/test_pattern_groups.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_pattern_groups.py
rename to tests/python/tirx/tile/cuda/test_pattern_groups.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_pattern_math.py b/tests/python/tirx/tile/cuda/test_pattern_math.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_pattern_math.py
rename to tests/python/tirx/tile/cuda/test_pattern_math.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_pattern_mma.py b/tests/python/tirx/tile/cuda/test_pattern_mma.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_pattern_mma.py
rename to tests/python/tirx/tile/cuda/test_pattern_mma.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_pattern_transfers.py b/tests/python/tirx/tile/cuda/test_pattern_transfers.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_pattern_transfers.py
rename to tests/python/tirx/tile/cuda/test_pattern_transfers.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_tcgen05_cp.py b/tests/python/tirx/tile/cuda/test_tcgen05_cp.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_tcgen05_cp.py
rename to tests/python/tirx/tile/cuda/test_tcgen05_cp.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_tcgen05_ld_st.py b/tests/python/tirx/tile/cuda/test_tcgen05_ld_st.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_tcgen05_ld_st.py
rename to tests/python/tirx/tile/cuda/test_tcgen05_ld_st.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_tcgen05_mma.py b/tests/python/tirx/tile/cuda/test_tcgen05_mma.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_tcgen05_mma.py
rename to tests/python/tirx/tile/cuda/test_tcgen05_mma.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_tcgen05_mma_codegen.py b/tests/python/tirx/tile/cuda/test_tcgen05_mma_codegen.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_tcgen05_mma_codegen.py
rename to tests/python/tirx/tile/cuda/test_tcgen05_mma_codegen.py
diff --git a/tirx/tests/python/tirx/tile/cuda/test_tcgen05_mma_ws_split_n.py b/tests/python/tirx/tile/cuda/test_tcgen05_mma_ws_split_n.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/cuda/test_tcgen05_mma_ws_split_n.py
rename to tests/python/tirx/tile/cuda/test_tcgen05_mma_ws_split_n.py
diff --git a/tirx/tests/python/tirx/tile/test_dispatcher.py b/tests/python/tirx/tile/test_dispatcher.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/test_dispatcher.py
rename to tests/python/tirx/tile/test_dispatcher.py
diff --git a/tirx/tests/python/tirx/tile/trn/__init__.py b/tests/python/tirx/tile/trn/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/__init__.py
rename to tests/python/tirx/tile/trn/__init__.py
diff --git a/tirx/tests/python/tirx/tile/trn/test_binary.py b/tests/python/tirx/tile/trn/test_binary.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/test_binary.py
rename to tests/python/tirx/tile/trn/test_binary.py
diff --git a/tirx/tests/python/tirx/tile/trn/test_compose_op.py b/tests/python/tirx/tile/trn/test_compose_op.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/test_compose_op.py
rename to tests/python/tirx/tile/trn/test_compose_op.py
diff --git a/tirx/tests/python/tirx/tile/trn/test_copy.py b/tests/python/tirx/tile/trn/test_copy.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/test_copy.py
rename to tests/python/tirx/tile/trn/test_copy.py
diff --git a/tirx/tests/python/tirx/tile/trn/test_gemm.py b/tests/python/tirx/tile/trn/test_gemm.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/test_gemm.py
rename to tests/python/tirx/tile/trn/test_gemm.py
diff --git a/tirx/tests/python/tirx/tile/trn/test_private_alloc.py b/tests/python/tirx/tile/trn/test_private_alloc.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/test_private_alloc.py
rename to tests/python/tirx/tile/trn/test_private_alloc.py
diff --git a/tirx/tests/python/tirx/tile/trn/test_reduction.py b/tests/python/tirx/tile/trn/test_reduction.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/test_reduction.py
rename to tests/python/tirx/tile/trn/test_reduction.py
diff --git a/tirx/tests/python/tirx/tile/trn/test_select.py b/tests/python/tirx/tile/trn/test_select.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/test_select.py
rename to tests/python/tirx/tile/trn/test_select.py
diff --git a/tirx/tests/python/tirx/tile/trn/test_unary.py b/tests/python/tirx/tile/trn/test_unary.py
similarity index 100%
rename from tirx/tests/python/tirx/tile/trn/test_unary.py
rename to tests/python/tirx/tile/trn/test_unary.py
diff --git a/tirx/tests/python/tirx/transform/__init__.py b/tests/python/tirx/transform/__init__.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/__init__.py
rename to tests/python/tirx/transform/__init__.py
diff --git a/tirx/tests/python/tirx/transform/test_bf16_legalize.py b/tests/python/tirx/transform/test_bf16_legalize.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_bf16_legalize.py
rename to tests/python/tirx/transform/test_bf16_legalize.py
diff --git a/tirx/tests/python/tirx/transform/test_common_subexpr_elim.py b/tests/python/tirx/transform/test_common_subexpr_elim.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_common_subexpr_elim.py
rename to tests/python/tirx/transform/test_common_subexpr_elim.py
diff --git a/tirx/tests/python/tirx/transform/test_convert_ssa.py b/tests/python/tirx/transform/test_convert_ssa.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_convert_ssa.py
rename to tests/python/tirx/transform/test_convert_ssa.py
diff --git a/tirx/tests/python/tirx/transform/test_decorate_device_scope.py b/tests/python/tirx/transform/test_decorate_device_scope.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_decorate_device_scope.py
rename to tests/python/tirx/transform/test_decorate_device_scope.py
diff --git a/tirx/tests/python/tirx/transform/test_flatten_tensor.py b/tests/python/tirx/transform/test_flatten_tensor.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_flatten_tensor.py
rename to tests/python/tirx/transform/test_flatten_tensor.py
diff --git a/tirx/tests/python/tirx/transform/test_force_narrow_index_to_i32.py b/tests/python/tirx/transform/test_force_narrow_index_to_i32.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_force_narrow_index_to_i32.py
rename to tests/python/tirx/transform/test_force_narrow_index_to_i32.py
diff --git a/tirx/tests/python/tirx/transform/test_fp8_legalize.py b/tests/python/tirx/transform/test_fp8_legalize.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_fp8_legalize.py
rename to tests/python/tirx/transform/test_fp8_legalize.py
diff --git a/tirx/tests/python/tirx/transform/test_function_pass.py b/tests/python/tirx/transform/test_function_pass.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_function_pass.py
rename to tests/python/tirx/transform/test_function_pass.py
diff --git a/tirx/tests/python/tirx/transform/test_helpers.py b/tests/python/tirx/transform/test_helpers.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_helpers.py
rename to tests/python/tirx/transform/test_helpers.py
diff --git a/tirx/tests/python/tirx/transform/test_hoist_if.py b/tests/python/tirx/transform/test_hoist_if.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_hoist_if.py
rename to tests/python/tirx/transform/test_hoist_if.py
diff --git a/tirx/tests/python/tirx/transform/test_lower_intrin.py b/tests/python/tirx/transform/test_lower_intrin.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_lower_intrin.py
rename to tests/python/tirx/transform/test_lower_intrin.py
diff --git a/tirx/tests/python/tirx/transform/test_lower_tirx.py b/tests/python/tirx/transform/test_lower_tirx.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_lower_tirx.py
rename to tests/python/tirx/transform/test_lower_tirx.py
diff --git a/tirx/tests/python/tirx/transform/test_lower_tvm_builtin.py b/tests/python/tirx/transform/test_lower_tvm_builtin.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_lower_tvm_builtin.py
rename to tests/python/tirx/transform/test_lower_tvm_builtin.py
diff --git a/tirx/tests/python/tirx/transform/test_make_packed_api.py b/tests/python/tirx/transform/test_make_packed_api.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_make_packed_api.py
rename to tests/python/tirx/transform/test_make_packed_api.py
diff --git a/tirx/tests/python/tirx/transform/test_naive_allocator.py b/tests/python/tirx/transform/test_naive_allocator.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_naive_allocator.py
rename to tests/python/tirx/transform/test_naive_allocator.py
diff --git a/tirx/tests/python/tirx/transform/test_narrow_datatype.py b/tests/python/tirx/transform/test_narrow_datatype.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_narrow_datatype.py
rename to tests/python/tirx/transform/test_narrow_datatype.py
diff --git a/tirx/tests/python/tirx/transform/test_pointer_value_type_rewrite.py b/tests/python/tirx/transform/test_pointer_value_type_rewrite.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_pointer_value_type_rewrite.py
rename to tests/python/tirx/transform/test_pointer_value_type_rewrite.py
diff --git a/tirx/tests/python/tirx/transform/test_remove_no_op.py b/tests/python/tirx/transform/test_remove_no_op.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_remove_no_op.py
rename to tests/python/tirx/transform/test_remove_no_op.py
diff --git a/tirx/tests/python/tirx/transform/test_renormalize_split_pattern.py b/tests/python/tirx/transform/test_renormalize_split_pattern.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_renormalize_split_pattern.py
rename to tests/python/tirx/transform/test_renormalize_split_pattern.py
diff --git a/tirx/tests/python/tirx/transform/test_simplify.py b/tests/python/tirx/transform/test_simplify.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_simplify.py
rename to tests/python/tirx/transform/test_simplify.py
diff --git a/tirx/tests/python/tirx/transform/test_split_host_device.py b/tests/python/tirx/transform/test_split_host_device.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_split_host_device.py
rename to tests/python/tirx/transform/test_split_host_device.py
diff --git a/tirx/tests/python/tirx/transform/test_storage_rewrite.py b/tests/python/tirx/transform/test_storage_rewrite.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_storage_rewrite.py
rename to tests/python/tirx/transform/test_storage_rewrite.py
diff --git a/tirx/tests/python/tirx/transform/test_unroll.py b/tests/python/tirx/transform/test_unroll.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_unroll.py
rename to tests/python/tirx/transform/test_unroll.py
diff --git a/tirx/tests/python/tirx/transform/test_vectorize.py b/tests/python/tirx/transform/test_vectorize.py
similarity index 100%
rename from tirx/tests/python/tirx/transform/test_vectorize.py
rename to tests/python/tirx/transform/test_vectorize.py
diff --git a/tirx/tests/python/tirx/utils.py b/tests/python/tirx/utils.py
similarity index 100%
rename from tirx/tests/python/tirx/utils.py
rename to tests/python/tirx/utils.py
diff --git a/tirx/tests/scripts/task_build_arm.sh b/tests/scripts/task_build_arm.sh
similarity index 100%
rename from tirx/tests/scripts/task_build_arm.sh
rename to tests/scripts/task_build_arm.sh
diff --git a/tirx/tests/scripts/task_build_cpu.sh b/tests/scripts/task_build_cpu.sh
similarity index 100%
rename from tirx/tests/scripts/task_build_cpu.sh
rename to tests/scripts/task_build_cpu.sh
diff --git a/tirx/tests/scripts/task_build_gpu.sh b/tests/scripts/task_build_gpu.sh
similarity index 100%
rename from tirx/tests/scripts/task_build_gpu.sh
rename to tests/scripts/task_build_gpu.sh
(tvm) 10/12: [LINT] Add standalone TIRx lint configuration
Posted by tq...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tirx-standalone-root
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit eef005bf301ac849c9df44f454dcffa31e0347c5
Author: tqchen <ti...@gmail.com>
AuthorDate: Fri Oct 16 02:24:49 2026 +0000
[LINT] Add standalone TIRx lint configuration
Move applicable lint hooks, formatters, and checks to the repository root. Preserve package settings while importing Ruff rules and keep CUDA native and Python generation checks independent of the TVM documentation tree.
---
.clang-format | 8 +
.github/workflows/lint.yml | 41 ++
.markdownlint-cli2.yaml | 19 +
.pre-commit-config.yaml | 95 +++++
.yamllint.yaml | 32 ++
pyproject.toml | 49 +++
python/tvm_tirx/backend/cuda/launch/generate.py | 70 ----
tests/lint/check_asf_header.py | 486 ++++++++++++++++++++++++
tests/lint/check_file_type.py | 137 +++++++
9 files changed, 867 insertions(+), 70 deletions(-)
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000000..b61ed538a8
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,8 @@
+# Run the following command to reformat a file:
+# clang-format -i -style=Google <file>
+# Or use clang-format-diff to only reformat the changed lines:
+# https://clang.llvm.org/docs/ClangFormat.html
+BasedOnStyle: Google
+DerivePointerAlignment: false
+ColumnLimit: 100
+PointerAlignment: Left
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000000..a9bff51f3b
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Lint
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+permissions:
+ contents: read
+
+concurrency:
+ group: Lint-${{ github.event.pull_request.number || github.sha }}
+ cancel-in-progress: true
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+ with:
+ fetch-depth: 0
+ fetch-tags: true
+ - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml
new file mode 100644
index 0000000000..8d56f07c61
--- /dev/null
+++ b/.markdownlint-cli2.yaml
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+config:
+ MD013: false
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000..3d0139548a
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,95 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+default_install_hook_types:
+ - pre-commit
+repos:
+ # ---------- Local hooks ----------
+ - repo: local
+ hooks:
+ - id: cuda-launch-generated
+ name: check CUDA launch generated files
+ entry: python python/tvm_tirx/backend/cuda/launch/generate.py --check
+ language: python
+ additional_dependencies: [ruff==0.12.3, clang-format==20.1.8]
+ pass_filenames: false
+ files: ^(python/tvm_tirx/backend/cuda/launch/|src/backend/cuda/launch/)
+ - id: check-asf-header
+ name: check ASF Header
+ entry: python tests/lint/check_asf_header.py --check
+ language: python
+ language_version: python3
+ pass_filenames: false
+ verbose: false
+ - id: check-file-type
+ name: check file types
+ entry: python tests/lint/check_file_type.py
+ language: python
+ language_version: python3
+ pass_filenames: false
+ verbose: false
+ # ---------- General file checks ----------
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v5.0.0
+ hooks:
+ - id: check-added-large-files
+ - id: check-case-conflict
+ - id: check-merge-conflict
+ - id: check-symlinks
+ - id: end-of-file-fixer
+ exclude: ^3rdparty/
+ - id: mixed-line-ending
+ exclude: ^3rdparty/
+ - id: requirements-txt-fixer
+ - id: trailing-whitespace
+ exclude: ^3rdparty/
+ - id: check-yaml
+ - id: check-toml
+
+ # ---------- YAML lint ----------
+ - repo: https://github.com/adrienverge/yamllint
+ rev: v1.35.1
+ hooks:
+ - id: yamllint
+ args:
+ - --config-file
+ - .yamllint.yaml
+ exclude: ^\.github/
+
+ # ---------- TOML format ----------
+ - repo: https://github.com/ComPWA/taplo-pre-commit
+ rev: v0.9.3
+ hooks:
+ - id: taplo-format
+
+ # ---------- Python: ruff ----------
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.12.3
+ hooks:
+ - id: ruff-check
+ types_or: [python, pyi, jupyter]
+ args: [--fix]
+ - id: ruff-format
+ types_or: [python, pyi, jupyter]
+
+ # ---------- C/C++: clang-format ----------
+ - repo: https://github.com/pre-commit/mirrors-clang-format
+ rev: "v20.1.8"
+ hooks:
+ - id: clang-format
+ types_or: [c, c++, cuda, objective-c++]
+ exclude: ^3rdparty/
diff --git a/.yamllint.yaml b/.yamllint.yaml
new file mode 100644
index 0000000000..417d517367
--- /dev/null
+++ b/.yamllint.yaml
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+extends: default
+
+rules:
+ document-start: disable
+ line-length:
+ max: 120
+ level: warning
+ truthy:
+ allowed-values:
+ - "on"
+ - "off"
+ - "yes"
+ - "no"
+ - "true"
+ - "false"
diff --git a/pyproject.toml b/pyproject.toml
index 333c1e8696..bc4d235641 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -166,3 +166,52 @@ rm -rf "$DELOCATE_TMP_DIR" "$TMP_DIR"
[tool.cibuildwheel.windows]
before-build = 'python -m pip install "delvewheel>=1.12.0"'
repair-wheel-command = 'delvewheel repair --analyze-existing --ignore-existing --exclude "*tvm_ffi*.dll" --exclude tvm_runtime_cuda.dll --exclude nvcuda.dll --exclude cudart64_13.dll --exclude nvrtc64_130_0.dll -w {dest_dir} {wheel}'
+
+[tool.ruff]
+include = [
+ "python/**/*.py",
+ "tests/**/*.py",
+ "docs/**/*.py",
+ "ci/**/*.py",
+ "conftest.py",
+]
+line-length = 100
+indent-width = 4
+target-version = "py310"
+exclude = ["3rdparty", "build", "dist", ".venv", ".ruff_cache", "node_modules"]
+
+[tool.ruff.lint]
+select = [
+ "E", # pycodestyle errors, https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
+ "F", # pyflakes, https://docs.astral.sh/ruff/rules/#pyflakes-f
+ "I", # isort, https://docs.astral.sh/ruff/rules/#isort-i
+ "UP", # pyupgrade, https://docs.astral.sh/ruff/rules/#pyupgrade-up
+ "RUF", # ruff, https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
+]
+ignore = [
+ # pyupgrade (style preference or low-value)
+ "UP028", # yield-in-for-loop — sometimes clearer to keep
+ "UP030", # format-literals — minor
+ "UP031", # printf-string-formatting — style preference
+ # ruff (preview rules, not yet stable)
+ "RUF043", # pytest-raises-ambiguous-pattern
+ "RUF059", # unused-unpacked-variable
+]
+fixable = ["ALL"]
+unfixable = []
+
+[tool.ruff.lint.per-file-ignores]
+"__init__.py" = ["E402", "F401", "F403", "F405"]
+# TIRx parser and lowering tests intentionally retain unused IR bindings.
+"tests/python/tirx/**/*.py" = ["F841"]
+
+[tool.ruff.lint.isort]
+known-first-party = ["tvm_tirx"]
+
+[tool.ruff.format]
+quote-style = "double"
+indent-style = "space"
+skip-magic-trailing-comma = false
+line-ending = "auto"
+docstring-code-format = false
+docstring-code-line-length = "dynamic"
diff --git a/python/tvm_tirx/backend/cuda/launch/generate.py b/python/tvm_tirx/backend/cuda/launch/generate.py
index 5e546a650b..e0caea02cf 100644
--- a/python/tvm_tirx/backend/cuda/launch/generate.py
+++ b/python/tvm_tirx/backend/cuda/launch/generate.py
@@ -218,75 +218,6 @@ def native_attributes():
return "\n".join(out)
-def documentation():
- out = [
- ".. Licensed to the Apache Software Foundation (ASF) under one",
- " or more contributor license agreements. See the NOTICE file",
- " distributed with this work for additional information",
- " regarding copyright ownership. The ASF licenses this file",
- ' to you under the Apache License, Version 2.0 (the "License");',
- " you may not use this file except in compliance with the License.",
- " You may obtain a copy of the License at",
- "",
- " http://www.apache.org/licenses/LICENSE-2.0",
- "",
- " Unless required by applicable law or agreed to in writing,",
- ' software distributed under the License is distributed on an "AS IS" BASIS,',
- " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
- " See the License for the specific language governing permissions and",
- " limitations under the License.",
- "",
- ".. Generated by launch/generate.py; edit table.py instead.",
- "",
- "CUDA kernel configuration reference",
- "===================================",
- "",
- "Both CUDA module launches and exported ``cuda_host`` wrappers use this registry.",
- "``LaunchConfig`` describes each launch; ``KernelAttributes`` describes compile-time",
- "CUDA kernel attributes.",
- "Optional launch attributes default to unspecified, preserving CUDA's inherited defaults.",
- "",
- ]
- for name, fields in [
- ("LaunchConfig", table.LAUNCH_FIELDS),
- ("KernelAttributes", table.KERNEL_ATTR_FIELDS),
- *table.COMPOSITES.items(),
- ]:
- out += [
- name,
- "-" * len(name),
- "",
- ".. list-table::",
- " :header-rows: 1",
- "",
- " * - Field",
- " - Type",
- " - Default",
- " - Description",
- ]
- for field in fields:
- doc = field.doc
- if field.enums:
- doc += " Values: " + ", ".join(f"``{key}``" for key, _ in field.enums) + "."
- if field.driver_id:
- doc += (
- f" Encoder requires CUDA {field.version // 1000}.{field.version % 1000 // 10}+."
- )
- out += [
- f" * - ``{field.name}``",
- f" - {field.kind}",
- f" - ``{field.default}``",
- f" - {doc}",
- ]
- out += [""]
- out += [
- "Stream-only synchronization policy and graph-only device-updatable nodes are",
- "outside this kernel-launch API. CUDA checks device-specific support and resource limits.",
- "",
- ]
- return "\n".join(out)
-
-
def format_output(path, content):
"""Use the same pinned formatters as pre-commit, without importing TVM."""
if path.suffix == ".py":
@@ -318,7 +249,6 @@ def main():
DIRECTORY / "_generated.py": python_api(),
ROOT / "src/backend/cuda/launch/launch_fields.h": native_fields(),
ROOT / "src/backend/cuda/launch/launch_attributes.h": native_attributes(),
- ROOT.parent / "docs/tirx/api/cuda_launch.rst": documentation(),
}
for path in list(outputs):
outputs[path] = format_output(path, outputs[path])
diff --git a/tests/lint/check_asf_header.py b/tests/lint/check_asf_header.py
new file mode 100644
index 0000000000..86301e2502
--- /dev/null
+++ b/tests/lint/check_asf_header.py
@@ -0,0 +1,486 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ruff: noqa: E741
+"""Helper tool to check and fix ASF headers in source files tracked by git.
+
+Ported from tvm-ffi. Replaces the previous RAT-based check_asf_header.sh
+(which required Java) with a self-contained Python implementation.
+"""
+
+from __future__ import annotations
+
+import argparse
+import fnmatch
+import subprocess
+import sys
+from pathlib import Path
+
+header_cstyle = """
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+""".strip()
+
+header_mdstyle = """
+<!--- Licensed to the Apache Software Foundation (ASF) under one -->
+<!--- or more contributor license agreements. See the NOTICE file -->
+<!--- distributed with this work for additional information -->
+<!--- regarding copyright ownership. The ASF licenses this file -->
+<!--- to you under the Apache License, Version 2.0 (the -->
+<!--- "License"); you may not use this file except in compliance -->
+<!--- with the License. You may obtain a copy of the License at -->
+
+<!--- http://www.apache.org/licenses/LICENSE-2.0 -->
+
+<!--- Unless required by applicable law or agreed to in writing, -->
+<!--- software distributed under the License is distributed on an -->
+<!--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -->
+<!--- KIND, either express or implied. See the License for the -->
+<!--- specific language governing permissions and limitations -->
+<!--- under the License. -->
+""".strip()
+
+header_pystyle = """
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+""".strip()
+
+header_rststyle = """
+.. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+.. http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+""".strip()
+
+header_groovystyle = """
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+""".strip()
+
+header_cmdstyle = """
+:: Licensed to the Apache Software Foundation (ASF) under one
+:: or more contributor license agreements. See the NOTICE file
+:: distributed with this work for additional information
+:: regarding copyright ownership. The ASF licenses this file
+:: to you under the Apache License, Version 2.0 (the
+:: "License"); you may not use this file except in compliance
+:: with the License. You may obtain a copy of the License at
+::
+:: http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing,
+:: software distributed under the License is distributed on an
+:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+:: KIND, either express or implied. See the License for the
+:: specific language governing permissions and limitations
+:: under the License.
+""".strip()
+
+FMT_MAP = {
+ "sh": header_pystyle,
+ "cc": header_cstyle,
+ "c": header_cstyle,
+ "cu": header_cstyle,
+ "cuh": header_cstyle,
+ "mm": header_cstyle,
+ "m": header_cstyle,
+ "go": header_cstyle,
+ "java": header_cstyle,
+ "h": header_cstyle,
+ "pyi": header_pystyle,
+ "py": header_pystyle,
+ "pyx": header_pystyle,
+ "toml": header_pystyle,
+ "yml": header_pystyle,
+ "yaml": header_pystyle,
+ "rs": header_cstyle,
+ "md": header_mdstyle,
+ "cmake": header_pystyle,
+ "mk": header_pystyle,
+ "rst": header_rststyle,
+ "gradle": header_groovystyle,
+ "groovy": header_groovystyle,
+ "tcl": header_pystyle,
+ "xml": header_mdstyle,
+ "storyboard": header_mdstyle,
+ "pbxproj": header_cstyle,
+ "plist": header_mdstyle,
+ "xcworkspacedata": header_mdstyle,
+ "html": header_mdstyle,
+ "bat": header_cmdstyle,
+}
+
+# Files and patterns to skip during header checking.
+# Files and patterns to skip (3rdparty, generated files, etc.).
+SKIP_LIST: list[str] = [
+ "3rdparty/*",
+ ".github/*",
+ "*.json",
+ "*.txt",
+ "*.svg",
+ "*.lst",
+ "*.lds",
+ "*.in",
+ "*.diff",
+ "*.edl",
+ "*.md5",
+ "*.csv",
+ "*.log",
+ "*.interp",
+ "*.tokens",
+ "*.ipynb",
+ "*.conf",
+ "*.ini",
+ "*.lock",
+ "*.properties",
+ "*.j2",
+]
+
+
+def should_skip_file(filepath: str) -> bool:
+ """Check if file should be skipped based on SKIP_LIST."""
+ for pattern in SKIP_LIST:
+ if fnmatch.fnmatch(filepath, pattern):
+ return True
+ return False
+
+
+def get_git_files() -> list[str] | None:
+ """Get list of files tracked by git (excluding files staged for deletion)."""
+ try:
+ result = subprocess.run(
+ ["git", "ls-files"], check=False, capture_output=True, text=True, cwd=Path.cwd()
+ )
+ if result.returncode != 0:
+ print("Error: Could not get git files. Make sure you're in a git repository.")
+ print("Git command failed:", result.stderr.strip())
+ return None
+ all_files = {line.strip() for line in result.stdout.split("\n") if line.strip()}
+ # Exclude files staged for deletion so the header check does not
+ # report errors for files that are intentionally being removed.
+ deleted_result = subprocess.run(
+ ["git", "ls-files", "--deleted"],
+ check=False,
+ capture_output=True,
+ text=True,
+ cwd=Path.cwd(),
+ )
+ if deleted_result.returncode == 0:
+ deleted = {line.strip() for line in deleted_result.stdout.split("\n") if line.strip()}
+ all_files -= deleted
+ elif deleted_result.stderr:
+ print(f"Warning: 'git ls-files --deleted' failed: {deleted_result.stderr.strip()}")
+ return sorted(all_files)
+ except FileNotFoundError:
+ print("Error: Git not found. This tool requires git to be installed.")
+ return None
+
+
+def copyright_line(line: str) -> bool:
+ # Following two items are intentionally break apart
+ # so that the copyright detector won"t detect the file itself.
+ if line.find("Copyright " + "(c)") != -1:
+ return True
+ # break pattern into two lines to avoid false-negative check
+ spattern1 = "Copyright"
+ if line.find(spattern1) != -1 and line.find("by") != -1:
+ return True
+ return False
+
+
+def check_header(fname: str, header: str) -> bool:
+ """Check header status of file without modifying it."""
+ if not Path(fname).exists():
+ print(f"ERROR: Cannot find {fname}")
+ return False
+
+ lines = Path(fname).open().readlines()
+
+ has_asf_header = False
+ has_copyright = False
+
+ for i, l in enumerate(lines):
+ if l.find("Licensed to the Apache Software Foundation") != -1:
+ has_asf_header = True
+ elif copyright_line(l):
+ has_copyright = True
+
+ if has_asf_header and not has_copyright:
+ return True # File is good
+
+ if not has_asf_header:
+ print(f"ERROR: Missing ASF header in {fname}")
+ print("Run `python tests/lint/check_asf_header.py --fix` to add the header")
+ return False
+
+ if has_copyright:
+ print(f"ERROR: Has copyright line that should be removed in {fname}")
+ return False
+
+ return True
+
+
+def collect_files() -> list[str] | None:
+ """Collect all files that need header checking from git."""
+ files = []
+
+ # Get files from git (required)
+ git_files = get_git_files()
+
+ if git_files is None:
+ # Git is required, so exit if we can't get files
+ return None
+
+ # Filter git files based on supported types and skip list
+ for git_file in git_files:
+ # Check if file should be skipped
+ if should_skip_file(git_file):
+ continue
+
+ # Check if this file type is supported
+ suffix = git_file.split(".")[-1] if "." in git_file else ""
+ basename = Path(git_file).name
+
+ if (
+ suffix in FMT_MAP
+ or basename == "gradle.properties"
+ or (suffix == "" and basename in ["CMakeLists", "Makefile"])
+ ):
+ files.append(git_file)
+
+ return files
+
+
+def add_header(fname: str, header: str) -> None:
+ """Add header to file."""
+ if not Path(fname).exists():
+ print(f"Cannot find {fname} ...")
+ return
+
+ lines = Path(fname).open().readlines()
+
+ has_asf_header = False
+ has_copyright = False
+
+ for i, l in enumerate(lines):
+ if l.find("Licensed to the Apache Software Foundation") != -1:
+ has_asf_header = True
+ elif copyright_line(l):
+ has_copyright = True
+ lines[i] = ""
+
+ if has_asf_header and not has_copyright:
+ return
+
+ with Path(fname).open("w") as outfile:
+ skipline = False
+ if not lines:
+ skipline = False # File is empty
+ elif lines[0][:2] == "#!":
+ skipline = True
+ elif lines[0][:2] == "<?":
+ skipline = True
+ elif lines[0].startswith("<html>"):
+ skipline = True
+ elif lines[0].startswith("// !$"):
+ skipline = True
+
+ if skipline:
+ outfile.write(lines[0])
+ if not has_asf_header:
+ outfile.write(header + "\n\n")
+ outfile.write("".join(lines[1:]))
+ else:
+ if not has_asf_header:
+ outfile.write(header + "\n\n")
+ outfile.write("".join(lines))
+ if not has_asf_header:
+ print(f"Add header to {fname}")
+ if has_copyright:
+ print(f"Removed copyright line from {fname}")
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(
+ description="Check and fix ASF headers in source files tracked by git",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog="""
+This tool processes all files tracked by git (using 'git ls-files') and automatically
+skips files matching patterns in SKIP_LIST (build artifacts, third-party files, etc.).
+
+One of --check, --fix, or --dry-run must be specified.
+
+Examples:
+ # Show all files that would be processed (dry run)
+ python check_asf_header.py --dry-run
+
+ # Check all git-tracked files (report errors)
+ python check_asf_header.py --check
+
+ # Fix all git-tracked files (add/update headers)
+ python check_asf_header.py --fix
+ """,
+ )
+
+ parser.add_argument(
+ "--check",
+ action="store_true",
+ help="Check mode: report errors without modifying files",
+ )
+
+ parser.add_argument(
+ "--fix",
+ action="store_true",
+ help="Fix mode: fix files with missing or incorrect headers (default)",
+ )
+
+ parser.add_argument(
+ "--dry-run",
+ action="store_true",
+ help="Dry run: show files that would be processed without doing anything",
+ )
+
+ args = parser.parse_args()
+
+ # Validate arguments
+ if args.check and args.fix:
+ print("Error: Cannot specify both --check and --fix")
+ return 1
+
+ if not args.check and not args.fix and not args.dry_run:
+ print("Error: Must specify one of --check, --fix, or --dry-run")
+ return 1
+
+ # Always use git-based approach
+ files = collect_files()
+
+ if files is None:
+ return 1 # Error already printed by get_git_files()
+
+ if not files:
+ print("No files found to process")
+ return 0
+
+ # Handle dry-run mode
+ if args.dry_run:
+ print(f"Would process {len(files)} files:")
+ for fname in sorted(files):
+ print(f" {fname}")
+ return 0
+
+ # Determine mode
+ check_only = args.check
+
+ error_count = 0
+ processed_count = 0
+
+ for fname in files:
+ processed_count += 1
+ suffix = fname.split(".")[-1] if "." in fname else ""
+ basename = Path(fname).name
+
+ # Determine header type
+ if suffix in FMT_MAP:
+ header = FMT_MAP[suffix]
+ elif basename == "gradle.properties":
+ header = FMT_MAP["h"]
+ elif suffix == "" and basename in ["CMakeLists", "Makefile"]:
+ header = FMT_MAP["cmake"] if basename == "CMakeLists" else FMT_MAP["mk"]
+ else:
+ if check_only:
+ print(f"ERROR: Cannot handle file type for {fname}")
+ error_count += 1
+ else:
+ print(f"Cannot handle {fname} ...")
+ continue
+
+ if check_only:
+ # Check mode
+ if not check_header(fname, header):
+ error_count += 1
+ else:
+ # Fix mode
+ add_header(fname, header)
+
+ if check_only:
+ if error_count > 0:
+ print(f"\nFound {error_count} errors in {processed_count} files")
+ return 1
+ else:
+ print(f"\nAll {processed_count} files are compliant")
+ return 0
+
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/tests/lint/check_file_type.py b/tests/lint/check_file_type.py
new file mode 100644
index 0000000000..d4fe94b207
--- /dev/null
+++ b/tests/lint/check_file_type.py
@@ -0,0 +1,137 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Helper tool to check file types that are allowed to checkin."""
+
+import subprocess
+import sys
+from pathlib import Path
+
+# List of file types we allow
+ALLOW_EXTENSION = {
+ # source code
+ "cc",
+ "c",
+ "h",
+ "S",
+ "cu",
+ "cuh",
+ "m",
+ "mm",
+ "groovy",
+ "sh",
+ "bat",
+ "py",
+ "pyi",
+ # configurations
+ "cfg",
+ "mk",
+ "in",
+ "cmake",
+ "xml",
+ "toml",
+ "yml",
+ "yaml",
+ "json",
+ "cfg",
+ "ini",
+ # docs
+ "txt",
+ "md",
+ "rst",
+ "css",
+ "html",
+ "ipynb",
+ # Jinja2 templates
+ "j2",
+ # images
+ "png",
+ # misc
+ "properties",
+ "template",
+}
+
+# List of file names allowed
+ALLOW_FILE_NAME = {
+ ".gitignore",
+ ".gitattributes",
+ ".gitmodules",
+ ".clang-format",
+ "README",
+ "Makefile",
+ "Doxyfile",
+}
+
+# List of specific files allowed in relpath to <proj_root>
+ALLOW_SPECIFIC_FILE = {"LICENSE", "NOTICE", "KEYS"}
+
+
+def filename_allowed(name: str) -> bool:
+ """Check if name is allowed by the current policy.
+
+ Parameters
+ ----------
+ name : str
+ Input name
+
+ Returns
+ -------
+ allowed : bool
+ Whether the filename is allowed.
+ """
+ arr = name.rsplit(".", 1)
+ if arr[-1] in ALLOW_EXTENSION:
+ return True
+
+ basename = Path(name).name
+ if basename in ALLOW_FILE_NAME:
+ return True
+
+ if name.startswith("3rdparty/"):
+ return True
+
+ if name in ALLOW_SPECIFIC_FILE:
+ return True
+
+ return False
+
+
+def main() -> None:
+ cmd = ["git", "ls-files"]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ (out, _) = proc.communicate()
+ res = out.decode("utf-8")
+ assert proc.returncode == 0, f"{' '.join(cmd)} errored: {res}"
+ error_list = [f for f in res.split() if not filename_allowed(f)]
+
+ if error_list:
+ report = "------File type check report----\n"
+ report += "\n".join(error_list)
+ report += f"\nFound {len(error_list)} files that are not allowed\n"
+ report += "We do not check in binary files into the repo.\n"
+ report += (
+ "If necessary, please discuss with committers and "
+ "modify tests/lint/check_file_type.py to enable the file you need.\n"
+ )
+ sys.stderr.write(report)
+ sys.stderr.flush()
+ sys.exit(-1)
+
+ print("check_file_type.py: all checks passed..")
+
+
+if __name__ == "__main__":
+ main()