53 Commits

Author SHA1 Message Date
Tianqi Chen bbfdab79d9 [CI] Repair Python test cleanup regressions (#19955)
## Summary

- Keep the Python test launcher close to plain `pytest -n auto`, move
nightly tests under `tests/nightly/python`, remove obsolete launchers
and collection bookkeeping, and partition CPU/GPU jobs with explicit
`gpu` marker expressions.
- Repair exact-pointer regressions at their owning boundaries: packed
raw-string ABI values, CUDA/Metal matrix intrinsic pointers, internal TE
extern offsets, MetaSchedule scalar annotations, localized
auto-tensorization scope matching, and typed DLTensor fixture fields.
- Preserve typed workspace calls in TIR and cast pointer-returning
external calls in CodeGenC, covered by a plain-TIRx 1024-byte global
workspace that is compiled as C++.
- Finish phasing out value-bearing Relax `R.Prim` annotations by
requiring an explicit dtype, removing obsolete value-based contracts,
and expressing the DISCO rank-dependent slices as explicit scalar
`call_tir` inputs.
- Gate the distributed callback on the optional DISCO runtime, NCCL, and
at least two GPUs so capability-limited jobs skip instead of failing.
- Remove the non-demonstrating pointer probe, use direct TVMScript
comparison for packed strings, and remove the four designated legacy
testing modules.

The seven repaired CPU categories cover packed raw strings (7 failures),
CUDA/Metal matrix access-pointer types (7), internal TE extern offsets
(1), a typed DLTensor fixture (1), MetaSchedule scalar annotations (1),
CodeGenC workspace return casts (12), and localized auto-tensorization
storage-scope matching (19).

## Validation

- Base: `ded6ad8dd212869c881efb5590f8a33fc972728e`
- Head: `a7277e86dbcfe0638c8c252d36760859c4ab4297`
- All 35 locally available original failing node IDs pass across the
focused runs.
- The full focused TE, TIR builtin-lowering, and CodeGenC files pass: 61
tests.
- The complete touched Relax/TVMScript set plus
PlanAndUpdateBufferAllocationLocation passes with 784 passed, 20
skipped, and 1 expected failure.
- The DISCO callback collects and skips when its runtime or two-GPU
environment is unavailable.
- Six direct mapping tests, twelve tensor-core sketches, and the dp4a
sketch pass unchanged.
- The compiler rebuild, branch-wide pre-commit hooks, and full-range
whitespace checks pass.
- The 13 broad CBLAS/TFLite nodes remain dependency-gated; their owning
TE and generated-C regressions compile.

No merge is included in this change.
2026-07-06 16:29:52 +08:00
Tianqi Chen 3452fd4ffa [TEST] Serialize local GPU execution under pytest-xdist (#19942)
Add tvm.testing.run_with_gpu_lock backed by the existing
tvm_ffi.utils.FileLock. Migrate live local GPU tests to acquire the
machine-local lock around device execution, synchronization, host
transfer, and checks while leaving target construction and compilation
outside the critical section.

Replace the custom xdist scheduler with standard xdist_group placement
for the order-dependent test family. RPC tests retain dynamic port
allocation and per-test process isolation rather than gaining a broad
category lock.
2026-07-04 17:49:45 -04:00
Tianqi Chen f3f5a3e42a [REFACTOR][RELAX] Rename Relax base type to AnyType (#19889)
This PR introduces Relax AnyType as the primary top/base type spelling,
replacing the previous ObjectType naming for the type that represents
any Relax value.

Changes:
- Add AnyType/AnyTypeNode with relax.AnyType registration and keep
ObjectType/R.Object compatibility aliases.
- Update Relax type analysis, type visitors, opaque function defaults,
and script printer/parser handling to use AnyType/R.Any.
- Migrate affected Python/C++ call sites, docs, and focused tests to the
new spelling.

Validation:
- cmake --build build --parallel 16
- Focused Relax/TVMScript pytest: 704 passed, 1 xfailed
- pre_commit run --files <changed files>
2026-06-25 13:29:10 -04:00
Tianqi Chen 1bb5cf6102 [REFACTOR][IR] Unify StructInfo and Type (#19853)
## Summary

- unify Relax's former StructInfo surface into the Type vocabulary and
Expr.ty storage path
- remove leftover DependentTypeNode and legacy OpNode::op_type storage
- keep base Type nullable while concrete Relax/DTensor type refs are
non-nullable
- clean stale StructInfo/TensorStructInfo/sinfo vocabulary in
Python/docs and distributed-op macros
- address Gemini follow-ups for parser annotations, BlockBuilder
docstring, and Adreno TensorType cast audit
2026-06-21 10:12:12 -04:00
Shushi Hong e4da848e57 [Tests] Modernize test gating (#19777)
This pr modernizes test gating. It replaces the heavy
`tvm.testing.Feature` machinery with a thin `tvm.testing.env` module of
`has_*()` capability probes, used via standard pytest.mark + skipif. And
markers move to `pyproject.toml`
2026-06-15 18:50:57 -04:00
Shushi Hong b57d0b3d07 [Runtime][Disco] Fix session attribute storage, NVSHMEM build, and test gating (#19736)
The tvm_ffi Object metaclass now gives every subclass `__slots__ = ()`,
so the Disco Python wrappers can no longer store instance attributes and
every session construction fails with AttributeError. Declare the
attributes each
wrapper actually stores as named slots, fix the NVSHMEM `dist_gemm.cu`
so TVM builds with `USE_NVSHMEM = ON`, and gate the disco tests on the
disco runtime being present so they skip cleanly on builds (e.g. the pip
wheel) that report `USE_NCCL` / `USE_NVSHMEM = ON` without shipping it.

### Session attribute storage
- `DPackedFunc` / `DModule`: `__slots__ = ("session",)`.
- `Session`: `__slots__ = ("_cache", "_import_python_module")`
2026-06-12 08:32:23 -04:00
Shushi Hong 3d95decde0 [Tests][Disco] Skip CCL tests when runtime support is absent (#19724)
The disco CCL tests called
tvm.get_global_func("runtime.disco.compiled_ccl") at module import time,
which raises ValueError on TVM builds without Disco CCL support (e.g.
published wheels), failing pytest collection. Resolve the function with
allow_missing=True and skip the module when it is absent.
2026-06-10 18:26:27 -04:00
Bohan Hou 859498dc01 [TIRx] Bringup TIRx Infrastructure (#19581)
## Summary

This PR adds the initial TIRx support needed for low-level programming
of Blackwell-class GPU architectures. As part of the ongoing TIRx
refactor, it introduces TVMScript support for directly scripting
advanced hardware features without relying on scheduling as the primary
programming interface.

The change keeps existing `s_tir` script support intact while making
direct scripting a first-class path for TIRx programs.

## Main Changes

- Add TIRx operator dispatch and layout infrastructure.
- Add TVMScript support for new low-level TIRx operations.
- Add analysis, transform, and lowering support for TIRx IR nodes.
- Add CUDA/Blackwell-oriented codegen and intrinsic coverage.
- Add Python and C++ integration points for TIRx scripting and runtime
support.

## Validation

- `pre-commit run --all-files`
- `ninja -C build -j32`
- `CUDA_VISIBLE_DEVICES=2 pytest tests/python/tirx/ -n 16`
  - `1723 passed, 47 skipped, 32 warnings`
- `CUDA_VISIBLE_DEVICES=2 python -m pytest -v
tests/python/all-platform-minimal-test`
  - `37 passed, 105 skipped`
- `TVM_TEST_TARGETS=llvm python -m pytest -v tests/python/tirx-analysis
tests/python/tirx-base tests/python/tirx-transform -n 16`
  - `664 passed, 25 skipped, 9 xfailed, 1 xpassed`

## Local CI Notes

Some full CI-equivalent jobs were not locally reproducible because this
machine is missing parts of the Apache TVM CI environment, including
`llvm-config-15/17`, Vulkan, ROCm, Maven, Sphinx, Doxygen, Emscripten,
and ARM/QEMU cross-toolchain components. Metal-specific tests were
skipped locally because no Metal runtime is available.
2026-05-18 16:44:43 -07:00
Tianqi Chen 9edd5bd958 [REFACTOR] Remove tvm.runtime.packed_func and container shims; route via tvm_ffi (#19442)
## Summary

- Delete the three Python shim modules that re-exported tvm-ffi types
under `tvm.runtime` / `tvm.ir`:
`python/tvm/runtime/packed_func.py`, `python/tvm/runtime/container.py`,
`python/tvm/ir/container.py`.
- Drop the matching re-exports from `tvm.runtime`, `tvm.ir`, and `tvm`
package init files, so
`tvm.runtime.PackedFunc`, `tvm.runtime.ShapeTuple`,
`tvm.runtime.String`, `tvm.ir.Array`,
  `tvm.ir.Map`, and `tvm.container.Array` no longer exist.
- Migrate every productive caller, test, and tutorial to the canonical
names: `tvm_ffi.Function`,
`tvm_ffi.Shape`, `tvm_ffi.core.String`, `tvm_ffi.Array`, and
`tvm_ffi.Map`.

## Test plan

- [x] `pytest tests/python/all-platform-minimal-test` (75 passed, 77
skipped)
- [x] `pytest tests/python/runtime/test_runtime_container.py
tests/python/all-platform-minimal-test/test_runtime_packed_func.py` (20
passed)
- [x] `pytest tests/python/ir/test_node_reflection.py
tests/python/ir/test_container_structural_equal.py` (32 passed)
- [x] `pytest tests/python/relax/test_vm_build.py
tests/python/relax/test_vm_execbuilder.py
tests/python/relax/test_vm_codegen_only.py` (125 passed, 2 xfailed)
- [x] `pytest tests/python/relax/test_runtime_builtin.py
tests/python/relax/test_op_misc.py` (19 passed)
- [x] `pytest tests/python/target/test_target_target.py` (37 passed, 3
skipped)
- [x] `pre-commit run` clean on touched files
2026-04-25 11:02:08 -04:00
Tianqi Chen 141c22fd8a [Refactor] Bring up tirx namespace (#18913)
This PR brings up the tirx namespace. We have been spliting out the
original tir namespace to include high-level component s_tir and this PR
updates the remaining low-level part as tirx namespace
2026-03-19 21:27:54 -07:00
Tianqi Chen 9a8320acbd [LINT][PYTHON] Modernize annotations with ruff UP rules (#18830)
This PR enables ruff pyupgrade (UP) rules with py310 target, auto-fixing
~5600 annotation modernizations (PEP 585 generics, PEP 604 unions,
deprecated typing imports).

Also removes from __future__ import annotations from ir/module.py and
rmsnorm.py, bumps requires-python to >=3.10, and removes absolute_import
aliases from topi/contrib files.
2026-02-27 21:29:47 -05:00
Tianqi Chen 33dcea1686 [REFACTOR][LINT] Modernize ruff config (#18810)
This PR removes the extra lint violations from the codebase so lint
aligns with the latest style
2026-02-23 07:29:21 -05:00
Tianqi Chen aa2e609136 [LINT] Modernize lint to use pre-commit hooks (#18807)
This PR migrates existing lint to use pre-commit hooks
2026-02-22 11:03:21 -05:00
Tianqi Chen adda179705 [REFACTOR][S-TIR] Lift dlight into s_tir namespace (#18734)
This PR migrates dlight into s_tir namespace, so s_tir related
components are closely grouped together.
2026-02-08 20:20:11 -05:00
Tianqi Chen 877b448b02 [REFACTOR][TIR] Rename tir.Block to SBlock (#18689)
This PR renames tir.Block to SBlock. This clearly indicate the
scheduable property of the block and is a prereq for followup stir
passes refactor.

Main changes:

- Data structure change from Block to SBlock
- Syntax change from T.block to T.sblock
2026-01-28 08:02:10 -05:00
Kathryn (Jinqi) Chen 2004a8bcbf [NVRTC] Add NVSHMEM support to NVRTC compilation path (#18681) 2026-01-24 14:52:51 -05:00
Kathryn (Jinqi) Chen fa905d2b69 [Compile] accelerate compilation speed using NVRTC (#18519)
This PR supports NVRTC as an alternative to NVCC for faster, device-side
JIT compilation of CUDA kernels, in favor of the PR
[https://github.com/apache/tvm-ffi/pull/283](https://github.com/apache/tvm-ffi/pull/283).

It enhances the CUDA compilation backend by:
- Adding Python NVRTC support using cuda-python bindings
- Removing legacy C++ NVRTC fallback in favor of a Python-first approach
- Keeping nvcc as the default compiler with fatbin output (no behavior
change for existing users)

Users can choose the compilation backend using an environment variable
`TVM_CUDA_COMPILE_MODE`, choosing from "nvcc" and "nvrtc". For example,

`TVM_CUDA_COMPILE_MODE=nvrtc python3 your_program.py`

Here is a short benchmark of the compilation speed of kernels in
`test_target_codegen_cuda.py`.

### NVCC vs NVRTC Compilation Time Comparison (Python-side Call)

| Test Case | Code Size | NVCC Time (ms) | NVRTC Time (ms) | Speedup |
| :--- | :--- | :--- | :--- | :--- |
| `test_crossthread_reduction1` | 1945 B | 241.27 | 51.23 | **4.7x** |
| `test_cuda_bf16_vectorize_add` | 3760 B | 342.72 | 44.50 | **7.7x** |
| `test_cuda_const_float_to_half` | 12394 B | 272.85 | 31.99 | **8.5x**
|
| `test_cuda_device_func_call` | 975 B | 215.58 | 21.47 | **10.0x** |
| `test_cuda_float_const_hex_format` | 685 B | 217.39 | 20.52 |
**10.6x** |
| `test_cuda_floordiv_with_vectorization` | 1050 B | 213.88 | 23.32 |
**9.2x** |
| `test_cuda_inf_nan` | 673 B | 214.33 | 24.94 | **8.6x** |
| `test_cuda_tensormap` | 755 B | 213.91 | 20.74 | **10.3x** |
| `test_cuda_thread_sync_inside_condition` | 1007 B | 213.43 | 28.29 |
**7.5x** |
| `test_cuda_vectorize_add` | 908 B | 226.81 | 40.39 | **5.6x** |
| `test_cuda_vectorize_load` | 734 B | 217.25 | 24.02 | **9.0x** |
| `test_device_host_call_same_func` | 924 B | 216.03 | 21.21 | **10.2x**
|
| `test_vectorized_intrin1` | 847 B | 226.15 | 26.34 | **8.6x** |

### NVSHMEM Support

Currently, NVSHMEM is **not** supported via NVRTC.
- Fallback Behavior: When NVSHMEM is required, the compilation pipeline
will automatically fall back to NVCC, even if `TVM_CUDA_COMPILE_MODE` is
set to nvrtc.
- Future Roadmap: Support for NVRTC with NVSHMEM is planned for
follow-up PRs.
2026-01-08 11:08:06 -05:00
Guan-Ming (Wesley) Chiu acda952b31 [Relax][PyTorch] Unify tests using shared tvm.testing.assert_allclose (#18522)
## Why

We have the shared assert_allclose func in tests and to use it in every
tests could help persist consistency
2025-11-29 00:51:52 -05:00
Tianqi Chen 543e64dbb1 [FFI][REFACTOR] Cleanup tvm_ffi python API and types (#18277)
This PR cleans up the python API to make things more consistent
with existing python array api and torch.

Device update
- device_id => index, to be consistent with torch
- device_type => dlpack_device_type() returns int
- added type property same as torch.device

API updates:

- Move the convenient method like cpu() out into tvm runtime to keep device minimal
- tvm_ffi._init_api => tvm_ffi.init_ffi_api
- tvm_ffi.register_func => tvm_ffi.register_global_func
2025-09-07 10:38:50 -04:00
Tianqi Chen 3c36ce2ec6 [FFI][REFACTOR][ABI] Rename NDArray to Tensor (#18275)
This PR Updates the NDArray => Tensor.

Both tensor and ndarray are commonly used terms.

Because the term Tensor is getting more common in the context of ML,
we do the rename to stay more aligned with torch.Tensor and DLTensor.
2025-09-06 14:33:59 -07:00
Tianqi Chen a7a0168be5 [FFI][REFACTOR] Establish tvm_ffi python module (#18226)
* [FFI][REFACTOR] Establish tvm_ffi as a standalone python module

This PR establishes tvm_ffi as a standalone python module.
The ffi is structured as a minimal pip module that can be
directly install by path or url.

examples/get_started provided a minimal example.
This is a major change as we are decoupling tvm_ffi as a
separate package, users need to install tvm_ffi separately.

Thanks to its minimal dependency, tvm_ffi can be easily installed
even just from the source by pip install ./ffi

This change would enable future improvement for library plugins
to have lightweight dependencies by just working on top of
the tvm_ffi, while the main compiler toolchain and runtime
can be layered on top.

* [FFI] Improve traceback setups

This PR improves traceback related setups
2025-08-24 15:46:20 -07:00
Tianqi Chen 3c189f015c [FFI][REFACTOR] Hide StringObj/BytesObj into details (#18184)
This PR hides StringObj/BytesObj into details and bring
implementations to directly focus on the String/Bytes.

This change will prepare us for future changes such as SmallStr support.
Also moves more ObjectRef into Any in RPC.
2025-08-01 21:42:55 -04:00
Kathryn (Jinqi) Chen a40f73f04d [NVSHMEM] Extend CUDA backend to compile and link TIR modules with NVSHMEM (#18093) 2025-06-26 19:09:26 -04:00
Ruihang Lai 61e7c8fb63 [Refactor] Rename relax_vm to vm (#18049)
This PR renames the filenames/namespaces of `relax_vm`
to `vm`.

Previously, both VMs of relay and relax exist, and to avoid the
name conflicts, we added the prefix `relax_` to relax VM.
With the Relay runtime being phased out, we can now rename
`relax_vm` to `vm` for conciseness.
2025-06-06 18:54:28 -04:00
Tianqi Chen 4289efa0d5 [REFACTOR][PYTHON] Phase out tvm._ffi and Limited API support (#18020)
This PR phases out tvm._ffi redirections in favor of new FFI
new functions are now called via tvm.ffi.

We also enabled limited API support for python 3.12+
so the compiled binary can be forward compatible to future
python versions.
2025-05-28 16:52:36 -04:00
Siyuan Feng be8e43814a [Refactor] Migrate build API to tvm.compile (#17718)
* tvm.build -> tvm.compile

* relax.build -> tvm.compile

* update
2025-03-09 07:23:52 -04:00
Hongyi Jin 567eeed38b [Runtime][Dist] Implementation of KV cache transfer (#17557)
This PR introduces kv transfer kernel and KV cache integration used
in prefill-decode disaggregation.

Co-authored-by: Ruihang Lai <ruihangl@cs.cmu.edu>
Co-authored-by: Charlie Ruan <53290280+CharlieFRuan@users.noreply.github.com>
Co-authored-by: Yingcheng Wang <135535812+yingchen21@users.noreply.github.com>
2024-12-15 22:56:01 +08:00
Yaxing Cai 4f94890112 [NVSHMEM] Enable nvshmem memory allocation (#17415)
This PR add the support of nvshmem memory allocation, and integrates it into disco.
2024-09-30 11:47:36 -04:00
Yaxing Cai 40b6c14bba [Disco] Add NVSHMEM support (#17317)
This PR adds the supports of NVSHMEM.
2024-09-01 17:00:15 -04:00
Wuwei Lin 1b6c00d756 [Disco] Implement SocketSession (#17182)
* [Disco] Implement SocketSession

Implements SocketSession that connects multiple local worker
processes/threads over multiple distributed nodes via TCP socket.

* doc

* lint

* resolve conflcit

* lint

* add local worker id

* lint

* lint

* disable for hexagon

* remove from header
2024-07-25 21:11:33 -07:00
Ruihang Lai ae1be53d6d [Disco] Cross-group and p2p send/receive primitives (#17191)
This PR introduces the disco CCL primitives for cross-group
and p2p communication.

Specifically, we introduce the send/receive primitives for one group
to send a buffer to its next group, where every worker in the first
group sends the buffer to the corresponding worker in the second
group. The p2p communication refer to the send/receive operations
to/from a target global worker.
2024-07-24 08:03:21 -04:00
Yaxing Cai bbc97c77fb [Disco] Group-wise operation (#17180)
This PR introduces the group attribute into Disco, so that group wise
allreduce and allgather is enabled.
2024-07-23 08:52:57 -04:00
Eric Lunderberg 7c2c0d9337 [Disco][QoL] Implement broadcast/scatter methods for Session (#17035)
* [Disco][QoL] Implement broadcast/scatter methods for Session

Prior to this commit, use of the `disco.Session` API to broadcast or
scatter an array required several steps from the caller.

1. Allocate memory on worker0
2. Transfer data from the controller to worker0
3. Allocate memory on each worker
4. Broadcast/scatter data from worker0 to all workers

While exposing these steps is necessary for performance, especially
when used repeatedly, it can be tedious/error-prone to use for
initialization that is only performed once.

This commit adds utility methods `Session.broadcast` and
`Session.scatter`, which are implemented in terms of the existing
lower-level methods `Session.broadcast_from_worker0` and
`Session.scatter_from_worker0`.  These methods perform the transfer
from the controller to worker0, and from worker0 to all other
workers.

* lint fix
2024-05-30 07:28:50 -04:00
Eric Lunderberg 54c68d6af4 [Disco] Implement num_workers property for disco.Session (#16978)
Prior to this commit, while the `num_workers` argument was provided to
the `disco.Session` object, it could not be determined from an
existing `disco.Session` object.  As a result, functions that
interacted with a multi-GPU setup frequently required separate
`num_workers` and `disco_session` argument, which could erroneously be
out-of-sync (e.g. passing the incorrect `num_workers`, or omitting the
`disco_session` argument when `num_workers>1`).

To remove this class of errors, this commit adds a
`disco.Session.num_workers` property.  The separate `num_workers`
argument is no longer necessary, as it can be determined from the
`disco.Session` instance.
2024-05-14 09:39:00 -05:00
Eric Lunderberg c6a8a80009 [Disco] Allow allocation that only exists on worker0 (#16993)
The `disco.Session.scatter_from_worker0` function expects a `DRef`
which an `NDArray` on worker 0, and `NullOpt` on all other workers.
Prior to this commit, there was no method in the `disco.Session` that
could be used to make such a `DRef`.  As a result, every use of
`scatter_from_worker0` generated an error, stating that non-zero
workers should have `NullOpt` as their `send` argument.

This commit adds a `worker0_only: bool` argument to
`disco.Session.empty`.  This can be used to generate an allocation
that only exists on worker zero, suitable for use in
`scatter_from_worker0`.
2024-05-14 09:38:43 -05:00
Ruihang Lai 2f889774ec [3rdparty] AUTO mode for custom all-reduce strategy (#16797)
This PR adds the automatic mode selection for customized all-reduce
kernels, referring TensorRT-LLM.

Meanwhile, this PR fixes a bug that may cause customized all-reduce
kernel to hang forever. Prior to this PR, each worker resets its
barrier values to 0 *after using all-gather to exchange their
barrier handles*. Afterwards, the customized all-reduce kernels
update the barriers of all workers. So it is possible that, worker 0
updates worker 1's barrier *before* worker 1 resets its barrier to 0.
This lead to the all-reduce kernel hanging forever.

This PR changes the behavior to resetting barriers before all-gather,
and forcing a device synchronization after reset.
2024-03-26 22:30:09 -07:00
Ruihang Lai e257fb8a41 [Runtime] CUDA IPC Memory support and custom allreduce kernels (#16750)
This PR introduces the CUDA IPC memory support in TVM runtime.
IPC memory allows multiple distribtued workers accessing the GPU
memory of each other directly. This functionality is helpful for
implementing customzied communication primitives across distributed
workers.

In this PR, we bring the customized all-reduce implementation
from TensorRT-LLM into 3rdparty. This all-reduce implementation
makes use of the CUDA IPC memory. We expose the all-reduce function
in global function under namespace `tvm::runtime::disco::cuda_ipc`.

One unit test for the customized all-reduce kernel over two workers
is added.

---

Co-authored-by: Hongyi Jin <hongyij@andrew.cmu.edu>
2024-03-20 19:29:27 -04:00
Eric Lunderberg 3ec0ca5b0b [Disco] Expose functions to query the per-worker device/rank (#16639)
In addition to the PackedFunc `"runtime.disco.worker_id"`, which
returns the worker ID wrapped in a `ShapeTuple`, this commit adds
`"runtime.disco.worker_rank"`, which returns the worker ID without
wrapping, and `"runtime.disco.device"`, which returns the device for
each worker.

The unit test added in this commit simulates loading of model weights
through a parameter transformation function.
2024-02-26 19:06:15 +09:00
Eric Lunderberg e359e7a210 [Disco] Add loader for presharded params. (#15957)
* [Disco] Add loader for presharded params.

Prior to this commit, sharding of model weights was always performed
when initializing the model.  This could cause slow initialization,
especially for larger numbers of GPUs, as all model weights are
initially transferred to GPU-0, before being scattered to all workers.

This commit updates the `tvm::runtime::ShardLoaderObj` to also allow
loading of pre-sharded model weights.  With pre-sharded model weights,
the tensors are sharded while the model is being built, and each
worker independently loads the specific model weights that it
requires.

* Update based on review comments.

* Removed commented-out print statements

---------

Co-authored-by: Chris Sullivan <csullivan@octoml.ai>
2023-11-09 08:05:45 -06:00
Lesheng Jin 88a08ae47a [Disco] Loading-time sharding support (#15826)
In our previous implementation, parameter sharding relies on pre-quantization weight processing,
meaning each set of quantized weights corresponds strictly to a hardcoded constant `num_shards`,
and re-quantization is strictly required upon each change of #GPUs, e.g. from 4-GPU to 8-GPU
setting. This PR makes it possible to move parameter sharding to post-quantization loading-time.
During loading, we iterate over all parameters and apply the sharding operation based on the
provided sharding information.

To make this happen, this PR makes an enhancement to the existing `shard_info.json` to include the
sharding function being used at loading time. Each parameter is attached to a list of loading-time
preprocessing methods that are serially applied to it to transform this parameter to the desired
shape, as shown in the example below:

```python
shard_info = {
  "x_0": [ # name of the parameter
    [ # a list of preprocessing functions to be applied
      "tests.disco.shard_dim_1",  # name of the sharding function
      [(num_shards, 64, 64), "float16"],  # output shape/dtype of `tests.disco.shard_dim_1`
      num_shards,  # extra inputs to `tests.disco.shard_dim_1`
    ],
  ],
  "x_1": [...],
}
```

To parameter `x_0`, it means we will call method `tests.disco.shard_dim_1` which has the signature:

```python
def shard_dim_1(
  input: NDArray,
  num_shards, # extra inputs
  output: NDArray, # and its shape is (num_shards, 64, 64), and dtype is "float16"
) -> None: ...
```

This approach simplifies parameter sharding for users and ensures correctness.
2023-10-03 00:06:21 -07:00
Farshid Salemi Parizi 230f8b2491 [Disco] Add AllGather (#15764)
* [Disco] Add AllGather

* update to allgather to be compatiple with #15766

* lint fix

* add num workers to all gather

* change num_gpus to prim value instead of int

* fix typo

* remove all_gather attrs and minor improvment

* Update allgather doc

Co-authored-by: Lesheng Jin <34279105+LeshengJin@users.noreply.github.com>

---------

Co-authored-by: Lesheng Jin <34279105+LeshengJin@users.noreply.github.com>
2023-09-27 10:02:16 -05:00
Lesheng Jin 2fdedf1ea8 [Disco] Integrate RCCL (#15776)
This PR integrates RCCL for amd multi-GPU parallelism.
2023-09-20 15:26:02 -07:00
Hongyi Jin afb2e421f0 [Unity][Disco] separate computation and communication into 2 stream (#15742)
put computation on default stream and put communication on a new stream.
2023-09-14 21:37:11 -07:00
Junru Shao 40b9a926b9 [Disco] Pipe-based Multi-processing Session (#15727)
This PR introduces `ProcessSession`, a new session implementation based
on multi-processing.

`ProcessSession` shares exactly the same communication protocol with
`ThreadedSession`, but all workers except for worker 0 are launched in a
separate process than thread. Workers communicate with the controller
via pipe provided by the OS, rather than SPSC message queue between
threads.

In our implementation, Python's `subproces.popen` is used to create
subprocesses, and the Python executable, or more specifically,
`sys.executable` calls into `tvm.exec.disco_worker` as the entrypoint.
Besides the launching logic that is only executed once in the very
beginning, the rest of the implementation resides in a C++-only
environment, including reads/writes to pipe file descriptors,
serialization and deserialization of messages, worker interpretation of
each message, etc.

Detailed engineering elements included in this PR:
- Refactors the MinRPC-based communication protocol out to be shared by
  `ProcessSession` and `ThreadedSession` as `protocol.h`;
- Refactors a controller-side worker thread into `DiscoWorkerThread`,
  which is shared by both session implementation to launch worker-0;
- Added two instructions `kDebugGetFromRemote` and `kDebugSetRegister`,
  which are used to communicate with workers other than worker-0 in
  debug mode;
- Introduces multi-processing infra including: `tvm.exec.disco_worker`
  serving as the entrypoint that launches workers, and
  `tvm/runtime/disco/process_pool.py` that exposes APIs to launch worker
  processes. `tvm.exec.disco_worker` calls into a global function
  `runtime.disco.WorkerProcess` that executes the worker main loop in
  pure C++;
- Introduces `src/support/process_id.h` that provides cross-platform pid
  and tid printing utilities;
- Refactors Disco's NCCL integration that get rids of initialized-once
  global NCCL context, and switches to broadcasting `ncclUniqueId` from
  controller to all workers, and then create NCCL communicators in each
  worker thread/process accordingly. This is a thread/process-agnostic
  way of using NCCL.
2023-09-14 07:43:44 -04:00
Hongyi Jin fb883b77d8 [Unity][disco] Change collective communication to destination-passing style (#15735)
This eliminates extra malloc in collective communication op
2023-09-13 09:04:24 -07:00
Hongyi Jin 4956e4f260 [Disco] Add LoadAll method to Disco Shard Loader (#15673)
This PR adds a `LoadAll` method to the Disco shard loader to load
parameters all at once.

Co-authored-by: Junru Shao <junrushao@apache.org>
2023-09-08 00:05:42 -07:00
Lesheng Jin 98ba395b6f [Disco][Op] gather_to_worker0 (#15690)
This pr introduce `gather_to_worker0`, which gathers an array from all other workers to worker-0.
2023-09-07 15:45:14 -07:00
Junru Shao f1246d0078 [Disco] Introduce ShardLoader (#15655)
This PR introduces `ShardLoader`, an object that allows convenient
sharding of each parameter, assuming there is a single shard dimension
and the sharding strategy is even. The sharding can be performed
efficiently on device (e.g. CUDA) and scattered to each worker with
NCCL support.

The shard loading process could be further compiled to Relax IRModule
to be executed by each worker with the function signature below:

```python
@R.function
def main(loader: R.Object) -> R.Tuple(
  R.Tensor((64, 64), "float32"),
  R.Tensor((16, 128), "float32"),
):
  R.func_attr({"global_symbol": "main"})
  with R.dataflow():
    lv0 = R.call_pure_packed(
      "runtime.disco.ShardLoaderLoad",
      loader,
      R.shape([0]),
      sinfo_args=R.Tensor((64, 64), "float32"),
    )
    lv1 = R.call_pure_packed(
      "runtime.disco.ShardLoaderLoad",
      loader,
      R.shape([1]),
      sinfo_args=R.Tensor((16, 128), "float32"),
    )
    lv2 = R.tuple(lv0, lv1)
    R.output(lv2)
  return lv2
```
2023-09-02 23:10:43 -07:00
Junru Shao c2eaa1d370 [Disco] Add Scatter-From-Worker0 (#15653)
* [Runtime] ShapeTuple.Product and ShapeTuple Printing (#15652)

This PR adds two convenient methods for `ShapeTuple`.

```C++
// Returns the number of elements in the shape,
// i.e. the product of all dimensions
ShapeTupleObj::index_type ShapeTupleObj::Product();

// Printing method for shape
std::ostream& operator<<(std::ostream& os, const ShapeTuple& shape);
```

* [Disco] Add `Scatter-From-Worker0`

This PR introduces an API:

```C++
void ScatterFromWorker0(Optional<NDArray> send, NDArray recv);
```

This mimics the MPI-style scattering primitive that divides NDArray
`send` into chunks, and send them to each worker's NDArray `recv`.
2023-09-02 07:10:39 -04:00
Lesheng Jin 71b81127a2 [Disco][Op] broadcast_from_worker0 (#15633)
This pr introduces op broadcast_from_zero, which broadcasts input tensor from worker-0 to all other workers.
2023-08-28 14:26:51 -07:00