blob: 2cc37d56bdab26579be0b71b8faa0d1ff11f0c8d [file] [view]
# Using IREE with Custom MLIR-Adjacent Dependencies via Bzlmod
This document explains how projects that depend on IREE can provide their own
LLVM, StableHLO, torch-mlir, and compiler plugin registry instead of using
IREE's bundled defaults.
## Terminology
### Bzlmod
Bazel's module system (introduced in Bazel 6.0, default in Bazel 7.0+). It replaces
the legacy WORKSPACE file with `MODULE.bazel` for managing external dependencies.
### Root Module
The top-level project being built. In bzlmod, only the root module's `MODULE.bazel`
is fully evaluated - dependency modules have limited control over the build graph.
### Module Extension
A mechanism for creating repositories dynamically in bzlmod. Extensions are defined
in `.bzl` files and invoked via `use_extension()` in MODULE.bazel.
### `use_extension()`
Runs a module extension's implementation function, which typically creates repositories.
Returns an extension proxy that can be passed to `use_repo()`.
### `use_repo()`
Imports repositories created by a module extension into the current module's visibility
scope. Without `use_repo()`, repos created by an extension exist but aren't accessible
to your BUILD files.
```python
# Extension creates repos internally
ext = use_extension("@some_module//:extensions.bzl", "some_extension")
# use_repo makes specific repos visible as @repo_a, @repo_b, etc.
use_repo(ext, "repo_a", "repo_b")
```
### `use_repo_rule()`
Imports a repository rule from another module so it can be called directly in
MODULE.bazel to create a repository.
### Raw source repositories
Repositories such as `llvm-raw` and `torch-mlir-raw` contain unconfigured
upstream source trees. They are inputs to repository rules that overlay Bazel
BUILD files and produce configured repositories such as `llvm-project` and
`torch-mlir`.
### `llvm-project`
The configured LLVM repository created by `llvm_configure`. It overlays Bazel BUILD
files onto the `llvm-raw` source and extracts CMake configuration variables.
### `llvm-project-overlay`
The bzlmod module name for LLVM's Bazel integration (located at
`llvm-project/utils/bazel/`). It provides the `llvm_repos_extension` and
`llvm_configure` rule.
## How It Works
IREE's module extension (`iree_extension`) creates MLIR-adjacent source
repositories **only when IREE is the root module**:
```python
# In build_tools/bazel/extensions.bzl
def _iree_extension_impl(module_ctx):
if any([m.is_root and m.name == "iree_core" for m in module_ctx.modules]):
new_local_repository(
name = "llvm-raw",
build_file_content = "# empty",
path = "third_party/llvm-project",
)
local_repository(
name = "stablehlo",
path = "third_party/stablehlo",
)
new_local_repository(
name = "torch-mlir-raw",
build_file_content = "# empty - BUILD files overlaid by torch_mlir_configure",
path = "third_party/torch-mlir",
)
# ... other repos
```
When your project depends on IREE, IREE is **not** the root module - your project is.
Therefore, IREE's extension will not create these MLIR-adjacent repositories,
and you must provide the ones needed by the compiler plugins you enable.
## MODULE.bazel Ordering
The order of statements in MODULE.bazel matters:
1. `module()` - must be first
2. `bazel_dep()` - declare module dependencies
3. `local_path_override()` - must come after the `bazel_dep()` it overrides
4. `use_extension()` - must come after the `bazel_dep()` that provides the extension
5. `use_repo()` - must come after its corresponding `use_extension()`
6. `use_repo_rule()` + invocation - can reference repos created by earlier extensions
## Example: Using Your Own LLVM, StableHLO, and torch-mlir
```python
# my_project/MODULE.bazel
module(
name = "my_project",
version = "1.0.0",
)
# Standard bazel dependencies (must match or be compatible with IREE's versions)
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_cc", version = "0.2.11")
# ... other deps as needed
# Depend on IREE
bazel_dep(name = "iree_core", version = "0.0.1")
# Override IREE to use your local checkout (optional, for development)
local_path_override(
module_name = "iree_core",
path = "third_party/iree",
)
# Depend on LLVM overlay module
bazel_dep(name = "llvm-project-overlay", version = "main")
local_path_override(
module_name = "llvm-project-overlay",
path = "my/custom/llvm-project/utils/bazel",
)
# Create your own raw repositories pointing to the upstream projects you want.
new_local_repository = use_repo_rule(
"@bazel_tools//tools/build_defs/repo:local.bzl",
"new_local_repository",
)
new_local_repository(
name = "llvm-raw",
path = "my/custom/llvm-project",
build_file_content = "# empty",
)
new_local_repository(
name = "torch-mlir-raw",
path = "my/custom/torch-mlir",
build_file_content = "# empty",
)
local_repository = use_repo_rule(
"@bazel_tools//tools/build_defs/repo:local.bzl",
"local_repository",
)
local_repository(
name = "stablehlo",
path = "my/custom/stablehlo",
)
# Use LLVM's extension for third-party deps (gmp, mpfr, etc.)
llvm_repos_ext = use_extension(
"@llvm-project-overlay//:extensions.bzl",
"llvm_repos_extension",
)
use_repo(
llvm_repos_ext,
"gmp",
"mpc",
"mpfr",
"nanobind",
"pfm",
"pybind11",
"vulkan_sdk",
)
# Use IREE's extension (won't create llvm-raw since you're the root module)
iree_ext = use_extension(
"@iree_core//build_tools/bazel:extensions.bzl",
"iree_extension",
)
use_repo(
iree_ext,
"com_github_dvidelabs_flatcc",
"com_google_benchmark",
"com_google_googletest",
"stablehlo",
# ... other IREE repos you need
)
# Configure LLVM (creates llvm-project from your llvm-raw)
llvm_configure = use_repo_rule(
"@llvm-raw//utils/bazel:configure.bzl",
"llvm_configure",
)
llvm_configure(name = "llvm-project")
# Configure torch-mlir from your raw source repository if you enable the Torch
# input plugin.
torch_mlir_configure = use_repo_rule(
"@torch-mlir-raw//utils/bazel:configure.bzl",
"torch_mlir_configure",
)
torch_mlir_configure(
name = "torch-mlir",
src_workspace = "@torch-mlir-raw//:CMakeLists.txt",
)
```
## Custom Compiler Plugin Registry
IREE's `//compiler/plugins` package loads the plugin registry from the root
workspace:
```python
load("@//build_tools/bazel:default_compiler_plugins.bzl", ...)
```
When IREE is the root module, this resolves to IREE's default registry. A
downstream root workspace can provide a file at the same path to register
additional compiler plugins, replace registration targets, or change the
default enabled plugin IDs. In-tree IREE plugin labels should be qualified with
`@iree_core//...` from such a downstream file.
## Using LLVM from an HTTP Archive
If you want to fetch LLVM from a release tarball instead of a local path:
```python
# my_project/MODULE.bazel
http_archive = use_repo_rule(
"@bazel_tools//tools/build_defs/repo:http.bzl",
"http_archive",
)
LLVM_COMMIT = "abc123..." # Your desired commit
LLVM_SHA256 = "..." # SHA256 of the tarball
http_archive(
name = "llvm-raw",
build_file_content = "# empty",
sha256 = LLVM_SHA256,
strip_prefix = "llvm-project-" + LLVM_COMMIT,
urls = ["https://github.com/llvm/llvm-project/archive/{}.tar.gz".format(LLVM_COMMIT)],
)
```
## Version Compatibility
When providing your own LLVM, ensure compatibility with IREE:
1. **LLVM Version**: IREE targets a specific LLVM commit. Check IREE's
`third_party/llvm-project` submodule for the expected version.
2. **Bazel Dependencies**: Your LLVM's `utils/bazel/MODULE.bazel` declares
dependency versions. These should be compatible with IREE's dependencies.
3. **API Compatibility**: LLVM APIs change between versions. Your LLVM must
be API-compatible with what IREE expects.
## Troubleshooting
### "repository 'llvm-raw' is not defined"
You haven't created the `llvm-raw` repository. As the root module, you must
define it yourself if you configure LLVM (see examples above).
### "repository 'stablehlo' is not defined"
You enabled the StableHLO input plugin without providing a `stablehlo`
repository from your root module.
### "repository 'torch-mlir' is not defined"
You enabled the Torch input plugin without configuring a `torch-mlir` repository
from your root module.
### Build errors in LLVM code
Your LLVM version may be incompatible with IREE. Check that your LLVM commit
is close to IREE's expected version.
### Duplicate repository errors
Multiple modules may be trying to create the same repository. Ensure only
one source defines each repository name.