Conversation
[WORKSPACE]
```
load("@vila//vila:workspace2.bzl", vila_workspace2 = "workspace")
vila_workspace2(tvm_ffi = True)
```
[BZLMOD]
```
tvm_ffi_ext = use_extension("@vila//vila/bazel/bzlmod:extensions.bzl", "tvm_ffi_extension")
use_repo(tvm_ffi_ext, "tvm_ffi")
```
[SOURCE]
```
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("@rules_python//python:defs.bzl", "py_test")
load("@vila_pip_deps//:requirements.bzl", "requirement")
load("//vila/bazel/vila:vila.bzl", "vila_cc_test")
cc_binary(
name = "tvm_ffi_call",
srcs = ["tvm_ffi_call.cpp"],
linkshared = True,
deps = [
"@fmt",
"@tvm_ffi",
],
)
py_test(
name = "tvm_ffi_call_test",
srcs = ["tvm_ffi_call_test.py"],
data = [":tvm_ffi_call"],
deps = [
requirement("apache-tvm-ffi"),
requirement("numpy"),
requirement("typing-extensions"),
],
)
```
There was a problem hiding this comment.
Pull request overview
Adds an optional Bazel workspace/module integration for TVM FFI (from the apache-tvm-ffi PyPI package), plus a small C++/Python smoke test to validate loading and calling into a TVM FFI-exported function.
Changes:
- Introduces a
tvm_ffi_configurerepository rule and wires it into both legacyWORKSPACEflow and Bzlmod via a new module extension. - Adds
tests/vilatargets to build a shared library that exports a TVM FFI function, and apy_testthat loads and exercises it. - Updates Python tooling (ruff) and CI to install the required PyPI dependencies for the TVM FFI test.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| WORKSPACE | Enables tvm_ffi in vila_workspace2 and adds pip_parse for test deps (legacy WORKSPACE flow). |
| vila/workspace2.bzl | Adds tvm_ffi toggle and calls tvm_ffi_configure when enabled. |
| vila/bazel/tvm_ffi_configure.bzl | New repository rule to discover include/lib paths via python -m tvm_ffi.config and generate @tvm_ffi build targets. |
| vila/bazel/toolchains/sycl_cc_toolchain_config.bzl | Filters out invalid include paths for toolchain config generation. |
| vila/bazel/toolchains/sycl_cc_configure.bzl | Improves template list entry concatenation for MSVC SYCL include dirs. |
| vila/bazel/bzlmod/extensions.bzl | Adds a new tvm_ffi_extension module extension for Bzlmod. |
| tests/vila/tvm_ffi_call.cpp | New shared library exporting a TVM FFI function operating on tensors. |
| tests/vila/tvm_ffi_call_test.py | New Python test loading the shared library and validating tensor results. |
| tests/vila/requirements_tvm_ffi_test.txt | New pinned PyPI requirements used for the TVM FFI Python test. |
| tests/vila/BUILD.bazel | Adds cc_binary shared library build and py_test wiring with pip requirements. |
| pyproject.toml | Adds Ruff configuration. |
| MODULE.bazel | Adds rules_python pip parsing for test requirements and wires in tvm_ffi_extension. |
| .pre-commit-config.yaml | Replaces black/isort/flake8 hooks with ruff (lint + format). |
| .gitignore | Ignores a local Claude settings file. |
| .github/workflows/build-tests.yml | Installs tests/vila/requirements_tvm_ffi_test.txt in CI before Bazel steps. |
| .claude/CLAUDE.md | Adds repo guidance documentation for Claude Code. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| vila_workspace2( | ||
| sycl = False, | ||
| tvm_ffi = True, | ||
| ) |
There was a problem hiding this comment.
WORKSPACE previously enabled SYCL via sycl = True, but this change forces sycl = False while adding tvm_ffi = True. This looks unrelated to the PR’s stated goal (adding tvm-ffi) and will change developer builds unexpectedly. Consider preserving the prior sycl = True setting (or omit the argument to keep the existing behavior) and only add tvm_ffi = True.
| ) | ||
| dlpack_dir = result.stdout.strip() |
There was a problem hiding this comment.
The result of python -m tvm_ffi.config --dlpack-includedir is used without checking return_code. If the command fails or returns an empty path, repository_ctx.symlink(dlpack_dir, "dlpack") will fail with a confusing error. Please check return_code (and that stdout.strip() is non-empty) and fail with a clear message like the --includedir step.
| ) | |
| dlpack_dir = result.stdout.strip() | |
| ) | |
| # If DLPack headers cannot be located, fail clearly before symlinking | |
| if result.return_code != 0: | |
| fail("DLPack include directory not found. Ensure apache-tvm-ffi is installed correctly.") | |
| dlpack_dir = result.stdout.strip() | |
| if not dlpack_dir: | |
| fail("DLPack include directory is empty. Ensure apache-tvm-ffi is installed correctly.") |
| [str(python_path), "-m", "tvm_ffi.config", "--libfiles"], | ||
| quiet = False, | ||
| ) | ||
|
|
There was a problem hiding this comment.
The --libfiles query also doesn’t validate return_code. If it fails, lib_files becomes ['']/empty and the generated BUILD will silently omit link inputs, leading to later link-time errors that are hard to diagnose. Please validate return_code and fail early with a helpful message (and optionally echo stderr).
| # If library discovery fails, stop early with a helpful error instead of | |
| # generating a BUILD file that silently omits link inputs. | |
| if result.return_code != 0: | |
| error_msg = "Failed to query TVM FFI library files. Install with: pip install apache-tvm-ffi" | |
| if result.stderr.strip(): | |
| error_msg += "\nCommand stderr:\n" + result.stderr.strip() | |
| fail(error_msg) |
| # Define the repository rule for Bazel | ||
| # Repository rules are used to fetch and configure external dependencies. | ||
| # This rule is called once per Bazel invocation to set up the TVM FFI dependency. | ||
| tvm_ffi_configure = repository_rule(implementation = _tvm_ffi_configure) |
There was a problem hiding this comment.
This repository rule depends on the host Python environment (PATH + installed apache-tvm-ffi). It should be marked as a local/configure-time repository to avoid incorrect reuse across machines and to ensure it reruns when relevant environment variables change. Consider adding local = True and an environ = [...] list (e.g., PATH/PYTHONPATH/virtualenv variables) to the repository_rule(...) declaration.
| tvm_ffi_configure = repository_rule(implementation = _tvm_ffi_configure) | |
| tvm_ffi_configure = repository_rule( | |
| implementation = _tvm_ffi_configure, | |
| local = True, | |
| environ = [ | |
| "PATH", | |
| "PYTHONPATH", | |
| "PYTHONHOME", | |
| "VIRTUAL_ENV", | |
| "CONDA_PREFIX", | |
| ], | |
| ) |
| #include <tvm/ffi/tvm_ffi.h> | ||
|
|
||
| #include <cstring> | ||
| #include <cstdint> |
There was a problem hiding this comment.
malloc/free are used but <cstdlib> isn’t included. Some toolchains will fail to compile this (especially with strict warning settings). Please include <cstdlib> (or use std::malloc/std::free accordingly).
| #include <cstdint> | |
| #include <cstdint> | |
| #include <cstdlib> |
| # Prefer Bazel runfiles, then local workspace build outputs. | ||
| candidates = [ | ||
| Path(os.environ.get("TEST_SRCDIR", "")) / f"_main/tests/vila/{lib_name}", | ||
| Path(os.environ.get("RUNFILES_DIR", "")) / f"_main/tests/vila/{lib_name}", | ||
| file_dir / lib_name, | ||
| workspace_root / f"bazel-bin/tests/vila/{lib_name}", | ||
| Path.cwd() / lib_name, | ||
| ] |
There was a problem hiding this comment.
The runfiles lookup hard-codes the repository name _main (e.g. .../_main/tests/vila/...). Under non-bzlmod builds (or if the workspace name differs), the runfiles root won’t be _main, so the shared library won’t be found. Prefer using TEST_WORKSPACE (if set) or derive the repo name from runfiles metadata, and check both _main and the actual workspace name.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|



[WORKSPACE]
[BZLMOD]
[SOURCE]