从源码构建需自行准备 LLVM,且只支持最新稳定版、上一个稳定版或 trunk(README 示例为 22、23、24,不支持 21);vcpkg 默认只安装当前平台所需的最小后端,需要全部后端时要装 halide[target-all];Windows 上用 pip 包的 C++ 接口需把虚拟环境根目录加入 CMAKE_PREFIX_PATH。
pip install halideREADME 未说明显存或 GPU 型号要求;支持 CUDA、OpenCL、Metal、DirectX 12、Vulkan 等 GPU 计算 API,以及 X86、ARM、Hexagon、PowerPC、RISC-V、WebAssembly 等 CPU 架构。使用 Halide 需 C++17 或更高版本。
嵌入 C++ 的图像与数组处理 DSL,把高性能调度与算法逻辑分离,一次编写即可编译到多种 CPU 和 GPU
用 C++ 写的图像处理与数据并行计算 DSL,把算法和调度分开描述,自动生成适配 CPU、GPU 等硬件的高性能代码。
核心能力
- 用 C++ API 构建 Halide pipeline,可 AOT 编译成目标文件或 JIT 就地运行
- 算法与调度分离,同一份代码可针对不同硬件重新调度
- 覆盖 X86、ARM、Hexagon、PowerPC、RISC-V、WebAssembly 等 CPU 架构
- 支持 CUDA、OpenCL、Metal、DirectX 12、Vulkan 等 GPU 计算后端
- 提供 Python 绑定,可不写 C++ 直接用 Python 编写 Halide pipeline
容易踩的坑
- v22.1.0Halide 22.1.0最新正式版2026-10-31 · 2026-10-31 14:27 UTC
Halide 22.1.0
A minor release of Halide 22. It adds FreeBSD as a target OS, fixes undefined behavior and memory-safety bugs, and makes the build easier to package for distributions (see #4660).
New features
- FreeBSD target OS (#9642).
Target::FreeBSD(freebsdin target strings, e.g.x86-64-freebsd) uses the FreeBSD LLVM triple and the POSIX runtime. It is detected as the host OS when Halide is built on FreeBSD and is exposed in the Python bindings and inadd_halide_library. x86, ARM/AArch64 and RISC-V are supported. Native builds were tested on FreeBSD 15.1 amd64; AArch64 is untested.FreeBSDis appended toTarget::OS, so existing enum values are unchanged.
Bug fixes
Python
Buffer.copy_fromrejects mismatched buffers (#9635).hl.Bufferandhlr.Buffernow raiseValueErrorwhen the source has a different element size or number of dimensions. Before, release builds (including the wheels) read past the end of the source.- Dimension indices are bounds-checked (#9645).
crop,slice,embed,translate,transpose,dimand their non-mutating variants onhl.Bufferandhlr.Buffernow raiseIndexErrorfor an out-of-range dimension, andValueErrorfor vector arguments with too many entries (or, fortranspose(order), the wrong number). Before, release builds read or wrote past the buffer's shape array.
Compiler and autoschedulers
- Fixed two left shifts of negative values (undefined behavior before C++20) in
ConstantIntervaland the simplifier (#9640). - Anderson2021: fixed an out-of-bounds read in
Strides::dumpand a latent null dereference inunrolled_loops(#9640). - Anderson2021: worked around a clang 22 ThinLTO miscompile (IPSCCP) that made the Anderson2021 generators segfault in LTO builds (#9640).
Build and packaging
These changes let distribution packages drop their local patches (#9641):
- LLD is only required for the in-process WebAssembly JIT. It is now requested only when
Halide_WASM_BACKENDis set. Builds withHalide_WASM_BACKEND=OFFno longer need LLD and may link LLVM statically. - Shared-only FlatBuffers installs (such as Arch's) are supported, and the installed CMake package now finds them for consumers.
- Installed static libraries are built without LTO.
Halide_GenGenandHalide_PyStubsno longer pick up distro-fltoflags, which left compiler-specific bitcode in the shipped archives. - The empty Sphinx-only
doc/subdirectories are no longer installed. test_export_single_symbolno longer depends on$SHELL, which is unset in containers.- The Homebrew build instructions now say
Halide_LLVM_ROOTinstead ofHalide_ROOT.
Compatibility
There are no API or ABI changes. LLVM 21, 22 and 23 are supported, as in 22.0.0. Python code that relied on out-of-bounds
Bufferarguments now gets an exception.Thanks to @soma0212 for the Python
Bufferfixes.Full changelog: https://github.com/halide/Halide/compare/v22.0.0.post3...v22.1.0
🤖 Generated with Claude Code
- FreeBSD target OS (#9642).
- v22.0.0.post3Halide 22.0.0.post32026-10-29 · 2026-10-29 10:15 UTC
查看更新说明
Packaging-only release. No changes to Halide itself.
- Adds Linux AArch64 (
manylinux_2_28_aarch64) wheels forhalide,halide-bin, andhalide-runtimeon PyPI (#9634). - Adds a Linux AArch64 wheel for
halidoscope22.0.0.
- Adds Linux AArch64 (
- v22.0.0.post22026-10-29 · 2026-10-29 09:12 UTC
查看更新说明
Packaging-only post-release of Halide 22.0.0. Halide itself is unchanged.
- Halidoscope is now published to PyPI:
pip install halidoscope. import halideworks from monolithic CMake installs.halide/bin/__init__.pyis now installed with the Python bindings (new in v22.0.0.post1). This fixes Homebrew/homebrew-core#321694.- nanobind >= 2.11 is accepted, including 3.x, instead of exactly 2.11. These wheels are built with the latest nanobind.
- Python bindings build with Makefile generators again.
- Fixed the wheel CI for development versions.
See #9631 for details.
- Halidoscope is now published to PyPI:
- v22.0.02026-10-27 · 2026-10-27 20:55 UTC
查看更新说明
Halide 22.0.0
Highlights
- New scheduling directives:
eager_inline(),change_type(),hoist_invariants(),split_storage,stream_loads/stream_stores,aligned_split, a GPU max-register cap, andPipeline::sever(). - New profiler with counters, recompute statistics and automatic performance warnings.
- Halidoscope, a new interactive trace and profiling visualizer.
- Struct types are now supported in the language.
MultiRamp, a better representation of affine vectors (nested ramps), with simplifier and codegen work built on it.- ARM: SVE2 and SME2 streaming-SVE support, plus new Neon patterns.
- Docs and tutorials moved to Sphinx, and all C++ tutorials were ported to Python.
- Contributor tooling: pre-commit checks, a fuzz-test framework, and Claude skills for scheduling and simplifier rules.
Breaking changes and deprecations
Build and platform
- Dropped Python 3.9 (#8830). Python 3.12 is now required, and the bindings target the stable ABI via nanobind (#9618).
- Dropped LLVM 20 (#8998). LLVM 21, 22 and 23 are supported.
- Removed the
Halide_BUNDLE_STATICfeature (#8801). - Removed
FetchContentfrom the compiler, hannk and onnx (#8962, #9001, #9005). Dependencies now come from vcpkg or the system. - The autoschedulers now have their own CMake package (#9292).
- Fixed the
Halide/HalideHelpersCMake package dependency inversion (#9234). - Python packages are split, and there is a standalone AOT runtime (#9272).
- CUDA: per-capability libdevice bitcode is replaced by a unified
libdevice.10.bc(#9226).
C++ API and ABI
- ABI:
halide_type_tno longer has alanesfield. It is now{code, bits, reserved}, andhalide_buffer_tkeeps its size and layout.Halide::Typeis a separate language-level type that must be explicitly converted withas_abi(#9205). Forloops now store an inclusivemin/maxinstead ofmin/extent(#8858).- Removed the confusing
lanesparameter fromHandle. Use.with_lanes()for vectors of handles (#9198). - The
IRMutator/IRVisitorentry point is nowoperator(). Custom lowering passes that call custom mutators or visitors may need updating (#9023). Func::in()andFunc::clone_in()are now transitive (#9117) and eager (#9277).- Removed the
CompilerLogger(#9269). - Removed the ability to iterate over a
Scope(#9594). - Renamed
CodeGen_PosixtoCodeGen_CPU(#9097). - Deprecated
Target::OS::OSXin favor ofMacOS(#9451). The"osx"target string is still accepted, with a warning. - Deprecated
TailStrategy::Predicatein favor ofGuardWithIf(#9446).
Python
- The axis convention between
hl.Bufferand the Python buffer protocol is now consistent across the bindings,PyCallableand the Python extension (#8953, #8931).
Tests
- Removed
test/error/. Its tests are now correctness tests (#9463). - Moved the internal self-tests out of libHalide into
test/correctness(#9276).
New features
Scheduling
eager_inline()(#9256):g.eager_inline({f1, ..., fN})immediately and destructively inlines the bodies of the listed Funcs intog, in order, so direct calls between them are inlined too.change_type()(#9257): replaces a Func's computation type with another (e.g. float → int32) by computing in the new type and casting back. It uses value-bounds analysis to prove no values change, adds runtime asserts when a reduction might be long enough to overflow, and rewrites products into widening intrinsics where possible. Unsafe float product accumulation can also be fused into an fma (#9578).hoist_invariants()(#9190): likerfactor, but pulls factors that are invariant over a reduction out of the accumulation when the operators obey a distributive (semiring) law. Multi-term reductions are split into one intermediate per term, returned as aFuncVec(#9419). This lets quantized kernels be writ
- New scheduling directives:
- v21.0.02025-09-16 · 2025-09-16 19:26 UTC
查看更新说明
Release highlights
We have deliberately skipped version 20.0.0 to align with the LLVM version we are now using. Note that LLVM 21.1.1 or higher is required as LLVM 21.1.0 has a major bug in the NVPTX backend.
Major changes
- The
rfactorscheduling directive was rewritten and enhanced. It is now compatible with autoschedulers. - The Mullapudi2016 autoscheduler now supports experimental GPU scheduling.
- The Python bindings have been substantially improved, with many missing bindings filled in.
HL_DEBUG_CODEGENgained a new filtering mode. Debug levels can now be set on a per-file/per-function basis.- Support was added for AMD Zen5 and the iOS Simulator.
- The
strict_floatfeature has been reimplemented and should be much more reliable. - Lots of bugfixes, performance improvements, and build system improvements. We spent a lot of time fixing issues with our testing infrastructure and are looking forward to implementing a more stable contribution experience going forward.
Deprecations
- LLVM 19 and below are no longer supported, in keeping with our support policy.
Halide_BUNDLE_STATICwill be removed in the next release. If you are using it, please migrate to the shared library instead.- Support for Python 3.8 has been dropped.
Changelog
Scheduling
- The
rfactorscheduling directive was rewritten and enhanced.- Rewrite the rfactor scheduling directive by @alexreinking in https://github.com/halide/Halide/pull/8490
- Dequalify names when constructing RVars in rfactor by @alexreinking in https://github.com/halide/Halide/pull/8560
- Add promise_clamped in rfactor by @alexreinking in https://github.com/halide/Halide/pull/8608
- Add rfactor patterns for NaN-propagating min/max by @alexreinking in https://github.com/halide/Halide/pull/8587
- The Mullapudi2016 autoscheduler now supports experimental GPU scheduling.
- GPU autoscheduling with Mullapudi2016: the reference implementation by @antonysigma in https://github.com/halide/Halide/pull/7787
- Mullapudi2016-GPU: Reorder to avoid for-loops to be sandwiched between
gpu_blocks. by @antonysigma in https://github.com/halide/Halide/pull/8647 - Enable experimental Mullapudi2016 GPU scheduler for test-bench by @antonysigma in https://github.com/halide/Halide/pull/8650
- Highlight Metal GPU code in stmt_html by @antonysigma in https://github.com/halide/Halide/pull/8659
- Always ensure gpu_threads count >= warp size of 32 by @antonysigma in https://github.com/halide/Halide/pull/8656
- Fix incorrect natural vector size on Zen4 by @abadams in https://github.com/halide/Halide/pull/8570
- Make it an error to use a device extern stage without target support by @abadams in https://github.com/halide/Halide/pull/8794
- Add support for adding tuple outputs in the configure() method by @abadams in https://github.com/halide/Halide/pull/8649
Python
- Fix argument order in rpow by @alexreinking in https://github.com/halide/Halide/pull/8677
- Drop support for Python 3.8 by @alexreinking in https://github.com/halide/Halide/pull/8678
- Fix segfault in RDom's operator<< by @alexreinking in https://github.com/halide/Halide/pull/8679
- Use ruff to format and lint Python code by @alexreinking in https://github.com/halide/Halide/pull/8684
- Get raw Runtime::Buffer from Buffer in Python rather than use PyBuffer by @alexreinking in https://github.com/halide/Halide/pull/8682
- Bind in-place update operators (e.g. +=) in Python by @alexreinking in https://github.com/halide/Halide/pull/8683
- Clean up Python dependencies; document uv usage by @alexreinking in https://github.com/halide/Halide/pull/8694
- Fix several printing segfaults. by @alexreinking in https://github.com/halide/Halide/pull/8700
- Add Python bindings for serialization by @alexreinking in https://github.com/halide/Halide/pull/8718
- Add all remaining IROperator ops to Python bindings by @alexreinking in https://github.com/halide/Halide/
- The
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Halide
Halide is a programming language designed to make it easier to write high-performance image and array processing code on modern machines. Halide currently targets:
- CPU architectures: X86, ARM, Hexagon, PowerPC, RISC-V, WebAssembly
- Operating systems: Linux, Windows, macOS, Android, iOS, FreeBSD, Qualcomm QuRT
- GPU Compute APIs: CUDA, OpenCL, Apple Metal, Microsoft Direct X 12, Vulkan
Rather than being a standalone programming language, Halide is embedded in C++. This means you write C++ code that builds an in-memory representation of a Halide pipeline using Halide's C++ API. You can then compile this representation to an object file, or JIT-compile it and run it in the same process. Halide also provides a Python binding that provides full support for writing Halide embedded in Python without C++.
Halide requires C++17 (or later) to use.
For more detail about what Halide is, see https://halide-lang.org.
For API documentation see https://halide-lang.org/docs.
For some example code, read through the tutorials online at
https://halide-lang.org/tutorials. The corresponding code is in the tutorials/
directory. Larger examples are in the apps/ directory.
If you've acquired a full source distribution and want to build Halide, see the notes below.
Getting Halide
Pip
We provide binary wheels on PyPI. Halide provides bindings for C++ and Python. Even if you only intend to use Halide from C++, pip may be the easiest way to get a binary build of Halide.
Full releases may be installed with pip or added to a uv project like so:
$ pip install halide
$ uv add halide
The published Python artifacts are split into three distributions that share the
halide import package. The halide distribution provides the compiler Python
API and depends on matching versions of halide-bin (the compiler, headers,
tools, and CMake package) and halide-runtime (the standalone halide.runtime
API). Most users should install only halide; the package manager installs its
two dependencies automatically. Deployments that only call precompiled AOT
pipelines can instead install halide-runtime, avoiding the compiler and LLVM
entirely.
Every commit to main is published to our package index as a
development version. If you use uv, you can pin
the nightly Halide in a project like so:
$ uv add halide --prerelease=allow --index https://pypi.halide-lang.org/simple
Or install directly with pip:
$ pip install halide --pre --extra-index-url https://pypi.halide-lang.org/simple
Currently, we provide wheels for: Windows x86-64, macOS x86-64, macOS arm64, and Linux x86-64. The Linux wheels are built for manylinux_2_28, which makes them broadly compatible (Debian 10, Ubuntu 18.10, Fedora 29).
For C++ usage of the pip package: On Linux and macOS, CMake's find_package
command should find Halide as long as you're in the same virtual environment you
installed it in. On Windows, you will need to add the virtual environment root
directory to CMAKE_PREFIX_PATH. This can be done by running
set CMAKE_PREFIX_PATH=%VIRTUAL_ENV% in cmd.
Other build systems can find the Halide root path by running
python -c "import halide; print(halide.install_dir())".
Alternative for no-Python Environments
If you cannot use Python tooling (e.g. pip or uv) to download the Halide
wheels, you can download them directly from either our
nightly index or the public
PyPI index. Python wheel files are just
standard zip files with a .whl extension.
Homebrew
Alternatively, if you use macOS, you can install Halide via Homebrew like so:
$ brew install halide
Vcpkg
If you use vcpkg to manage dependencies, you can install Halide via:
$ vcpkg install halide:x64-windows # or x64-linux/x64-osx
One caveat: vcpkg installs only the minimum Halide backends required to compile
code for the active platform. If you want to include all the backends, you
should install halide[target-all]:x64-windows instead.
Other package managers
We are interested in bringing Halide to other popular package managers and Linux distribution repositories! We track the status of various distributions of Halide in this GitHub issue. If you have experience publishing packages we would be happy to work with you!
Building Halide
Platform Support
There are two sets of platform requirements relevant to Halide: those required to run the compiler library in either JIT or AOT mode, and those required to run the binary outputs of the AOT compiler.
These are the tested host toolchain and platform combinations for building and running the Halide compiler library.
| Compiler | Version | OS | Architectures |
|---|---|---|---|
| GCC | 9.5 | Ubuntu Linux 20.04 LTS | x86, x64 |
| GCC | 11.4 | Ubuntu Linux 22.04 LTS | ARM32, ARM64 |
| MSVC | 2022 (19.37) | Windows 11 (22631) | x86, x64 |
| AppleClang | 15.0.0 | macOS 14.4.1 | x64 |
| AppleClang | 14.0.0 | macOS 14.6 | ARM64 |
Some users have successfully built Halide for Linux using Clang 9.0.0+, for Windows using ClangCL 11.0.0+, and for Windows ARM64 by cross-compiling with MSVC. We do not actively test these scenarios, however, so your mileage may vary.
Beyond these, we are willing to support (by accepting PRs for) platform and toolchain combinations that still receive active, first-party, public support from their original vendors. For instance, at time of writing, this excludes Windows 7 and includes Ubuntu 18.04 LTS.
Compiled AOT pipelines are expected to have much broader platform support. The binaries use the C ABI, and we expect any compliant C compiler to be able to use the generated headers correctly. The C++ bindings currently require C++17. If you discover a compatibility problem with a generated pipeline, please open an issue.
Acquiring LLVM
At any point in time, building Halide requires either the latest stable version of LLVM, the previous stable version of LLVM, or trunk. At the time of writing, this means versions 22, 23, and 24 (trunk) are supported, but 21 is not.
We publish the LLVM builds we use in CI as Python packages on our package index. This is the easiest way to get a suitable LLVM on any platform. From the Halide source tree, install with uv:
$ uv sync --frozen --group ci-llvm-22 --no-install-workspace
$ export Halide_LLVM_ROOT=$(halide-llvm --prefix)
Replace 22 with the desired LLVM major version (22, 23, or main). The
repository root is a uv workspace containing the three Python distributions.
--no-install-workspace installs only the development tools and LLVM package
needed for a normal CMake build; --frozen uses the committed lockfile without
evaluating or building the workspace packages. To build and install all three
workspace packages into the uv environment instead, run
uv sync --all-packages; this includes a full compiler build. Binary wheels are
available for Linux (x86-64, x86-32, AArch64, ARMv7), macOS (x86-64, ARM64), and
Windows (x86-64, x86-32).
On macOS, Homebrew is also a good option:
brew install llvm. On Debian flavors of Linux, the
LLVM APT repo works well; use the provided installation
script.
[!WARNING] Building LLVM from source requires significant time, disk space, and RAM. Prefer the pre-built binaries above unless you need a custom configuration.
First check it out from GitHub:
$ git clone --depth 1 --branch llvmorg-22.1.8 https://github.com/llvm/llvm-project.git
(These instructions use LLVM 22.1.8. For current trunk, use main instead.)
Then build it like so:
$ cmake -G Ninja -S llvm-project/llvm -B build \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;lld;clang-tools-extra" \
-DLLVM_ENABLE_RUNTIMES=compiler-rt \
-DLLVM_TARGETS_TO_BUILD="WebAssembly;X86;AArch64;ARM;Hexagon;NVPTX;PowerPC;RISCV" \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DLLVM_ENABLE_EH=ON \
-DLLVM_ENABLE_RTTI=ON \
-DLLVM_ENABLE_HTTPLIB=OFF \
-DLLVM_ENABLE_LIBEDIT=OFF \
-DLLVM_ENABLE_LIBXML2=OFF \
-DLLVM_ENABLE_TERMINFO=OFF \
-DLLVM_ENABLE_ZLIB=OFF \
-DLLVM_ENABLE_ZSTD=OFF \
-DLLVM_BUILD_32_BITS=OFF
$ cmake --build build
$ cmake --install build --prefix llvm-install
This will produce a working LLVM installation in $PWD/llvm-install. We refer
to this path as LLVM_ROOT later. Do not confuse this installation tree with
the build tree!
LLVM takes a long time to build, so the above command uses Ninja to maximize
parallelism. If you choose to omit -G Ninja, Makefiles will be generated
instead. In this case, enable parallelism with cmake --build build -j NNN
where NNN is the number of parallel jobs, i.e. the number of CPUs you have.
Note that you must add clang and lld to LLVM_ENABLE_PROJECTS and
WebAssembly and X86 must be included in LLVM_TARGETS_TO_BUILD.
LLVM_ENABLE_RUNTIMES=compiler-rt is only required to build the fuzz tests, and
clang-tools-extra is only necessary if you plan to contribute code to Halide
(so that you can run clang-tidy on your pull requests). You can disable
exception handling (EH) and RTTI if you don't want the Python bindings. We
recommend enabling the full set to simplify builds during development.
Building Halide with CMake
This is discussed in greater detail in BuildingHalideWithCMake.md. CMake version 3.28+ is required to build Halide.
MacOS and Linux
After acquiring LLVM, change directory to the Halide repository and run:
$ cmake --preset release -DHalide_LLVM_ROOT=$LLVM_ROOT
$ cmake --build build/release
Setting -DHalide_LLVM_ROOT is not required if you have a suitable system-wide
version installed. However, if you have multiple LLVMs installed, it can pick
between them. Do not use a relative path for Halide_LLVM_ROOT. It can cause
problems on some systems.
If you use Homebrew on macOS, you can use the provided CMake preset:
$ cmake --preset=macOS
$ cmake --build build/macOS
This automatically finds LLVM from Homebrew's install path.
Windows
We suggest building with Visual Studio 2022. Your mileage may vary with earlier versions. Be sure to install the "C++ CMake tools for Windows" in the Visual Studio installer. For older versions of Visual Studio, do not install the CMake tools, but instead acquire CMake and Ninja from their respective project websites.
These instructions start from the D: drive. We assume this git repo is cloned
to D:\Halide. We also assume that your shell environment is set up correctly.
For a 64-bit build, run:
D:\> "C:\Program Files (x86)\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
For a 32-bit build, run:
D:\> "C:\Program Files (x86)\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64_x86
Managing dependencies with vcpkg
The best way to get compatible dependencies on Windows is to use vcpkg. Install it like so:
D:\> git clone https://github.com/Microsoft/vcpkg.git
D:\> cd vcpkg
D:\vcpkg> .\bootstrap-vcpkg.bat -disableMetrics
...
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake"
Halide includes a vcpkg-configuration.json that automatically configures
overlay ports
and overlay triplets. These overlays redirect LLVM and Python to system
installations, so vcpkg only builds the smaller dependencies (flatbuffers, wabt,
nanobind, etc.). You must have LLVM and Python installed separately (see
Acquiring LLVM above).
If CMake does not find your LLVM installation automatically, pass its absolute
path as -DHalide_LLVM_ROOT, for example:
D:\Halide> cmake --preset=release-vcpkg -DHalide_LLVM_ROOT=D:/llvm-install
Building Halide
Create a separate build tree and call CMake with vcpkg's toolchain. This will
build in either 32-bit or 64-bit depending on the environment script (vcvars)
that was run earlier.
D:\Halide> cmake -G Ninja -S . -B build ^
--toolchain D:/vcpkg/scripts/buildsystems/vcpkg.cmake ^
-DCMAKE_BUILD_TYPE=Release ^
-DVCPKG_MANIFEST_FEATURES=developer
Or use a CMake preset (e.g. for a Visual Studio build):
D:\Halide> cmake --preset=win64 &:: or win32 for 32-bit
D:\Halide> cmake --build build\win64 --config Release
For a Ninja-based build with vcpkg (needs VCPKG_ROOT set in the environment):
D:\Halide> cmake --preset=release-vcpkg
D:\Halide> cmake --build build\release-vcpkg
To run all the tests:
D:\Halide> ctest --test-dir build\release-vcpkg --output-on-failure
Subsets of the tests can be selected with -L and include correctness,
generator, and the other directory names under tests/.
To build the apps, you must first install Halide to a local prefix and record
that prefix in CMAKE_PREFIX_PATH (or set as -DCMAKE_PREFIX_PATH on the CMake
command line):
D:\Halide> cmake --build build\release-vcpkg --target install
By default, this will install to D:\Halide\install\release-vcpkg. You can
choose a different install prefix by manually calling cmake --install with
--prefix <path>.
Then move to the apps folder:
D:\Halide> cd apps
D:\Halide\apps> cmake --preset=release-vcpkg
D:\Halide\apps> cmake --build --preset=release-vcpkg
These commands configure all apps and resolve the dependencies in
apps/vcpkg.json; vcpkg may build both Debug and Release versions of those
dependencies. To build a single app without configuring the full apps project,
configure from that app's directory instead. To build just one app in an
already-configured apps project, pass its directory name as the build target,
for example cmake --build --preset=release-vcpkg --target blur. This builds
all targets needed by that app; the app-named target may be an executable or a
custom target aggregating several targets.
For example, to build blur standalone with dependencies already installed in
the selected vcpkg triplet:
D:\Halide\apps\blur> cmake -G Ninja -S . -B build ^
--toolchain D:/vcpkg/scripts/buildsystems/vcpkg.cmake ^
-DVCPKG_MANIFEST_MODE=OFF ^
-DCMAKE_BUILD_TYPE=Release ^
-DHalide_ROOT=D:/Halide/install/release-vcpkg
D:\Halide\apps\blur> cmake --build build
VCPKG_MANIFEST_MODE=OFF makes vcpkg use dependencies already installed for the
selected triplet instead of installing all dependencies from apps/vcpkg.json.
Install any dependencies required by the chosen app first.
[!WARNING] Building LLVM from source requires significant time, disk space, and RAM. Prefer the pre-built
halide-llvmbinaries (see Acquiring LLVM) unless you need a custom configuration.
First, download LLVM's sources (these instructions use the 22.1.8 release).
D:\> git clone --depth 1 --branch llvmorg-22.1.8 https://github.com/llvm/llvm-project.git
As above, run vcvarsall.bat to pick between x86 and x64. Then configure LLVM
with the following command (for 32-bit, set -DLLVM_BUILD_32_BITS=ON instead):
D:\> cmake -G Ninja -S llvm-project\llvm -B build ^
-DCMAKE_BUILD_TYPE=Release ^
-DLLVM_ENABLE_PROJECTS=clang;lld;clang-tools-extra ^
-DLLVM_ENABLE_RUNTIMES=compiler-rt ^
-DLLVM_TARGETS_TO_BUILD=WebAssembly;X86;AArch64;ARM;Hexagon;NVPTX;PowerPC;RISCV ^
-DLLVM_ENABLE_ASSERTIONS=ON ^
-DLLVM_ENABLE_EH=ON ^
-DLLVM_ENABLE_RTTI=ON ^
-DLLVM_ENABLE_HTTPLIB=OFF ^
-DLLVM_ENABLE_LIBEDIT=OFF ^
-DLLVM_ENABLE_LIBXML2=OFF ^
-DLLVM_ENABLE_TERMINFO=OFF ^
-DLLVM_ENABLE_ZLIB=OFF ^
-DLLVM_ENABLE_ZSTD=OFF ^
-DLLVM_BUILD_32_BITS=OFF
MSBuild: If you want to build LLVM with MSBuild instead of Ninja, use
-G "Visual Studio 17 2022" -Thost=x64 -A x64 or
-G "Visual Studio 17 2022" -Thost=x64 -A Win32 in place of -G Ninja.
Finally, run the build and install to a local directory:
D:\> cmake --build build --config Release
D:\> cmake --install build --prefix llvm-install
You can substitute Debug for Release in the above cmake commands if you
want a debug build.
To use this with Halide, but still allow vcpkg to manage other dependencies,
point CMake to your LLVM with -DHalide_LLVM_ROOT=D:/llvm-install. The overlay
ports in vcpkg-configuration.json automatically prevent vcpkg from trying to
build its own LLVM.
Building Halide with make
[!WARNING] We do not provide support for the Makefile. Feel free to use it, but if anything goes wrong, switch to the CMake build. Note also that the Makefile cannot build the Python bindings or produce install packages.
TL;DR: Have LLVM 22 (or greater) installed and run make in the root
directory of the repository (where this README is).
By default, make will use the llvm-config tool found in the PATH. If you
want to use a different LLVM, such as a custom-built one following the
instructions above, set the following environment variable:
$ export LLVM_CONFIG="$LLVM_ROOT/bin/llvm-config"
Now you should be able to just run make in the root directory of the Halide
source tree. make run_tests will run the JIT test suite, and make test_apps
will make sure all the apps compile and run (but won't check their output).
When building the tests, you can set the AOT compilation target with the
HL_TARGET environment variable.
Building Halide out-of-tree with make
If you wish to build Halide in a separate directory, you can do that like so:
$ cd ..
$ mkdir halide_build
$ cd halide_build
$ make -f ../Halide/Makefile
Some useful environment variables
HL_JIT_TARGET=... will set Halide's JIT compilation target.
HL_DEBUG_CODEGEN=1 will print out pseudocode for what Halide is compiling.
Higher numbers will print more detail. The output can be filtered by source
location using the grammar verbosity[,filename[:line_low[-line_high]]][@func],
with rules separated by ; and OR-ed together (filenames and function names are
matched as suffixes). For example, HL_DEBUG_CODEGEN=3,Simplify.cpp:100-180
prints verbosity-3 output only from lines 100–180 of Simplify.cpp. A handful
of call sites are also given a stable tag (their second debug() argument, e.g.
debug(1, "counterexample")), independent of file/line, selectable via a
tag:name rule (e.g. HL_DEBUG_CODEGEN=tag:counterexample, or
HL_DEBUG_CODEGEN=tag:counterexample,non-monotonic to select either); a tag
rule fires whenever one of its names matches, regardless of verbosity. See
doc/Testing.md for more, including the LLDB/GDB debugger
helpers. HL_DEBUG_CODEGEN output goes to stderr by default; set
HL_DEBUG_CODEGEN_LOG_FILE=<path> to append it to a file instead (the file is
never truncated). The values /dev/stdout and /dev/stderr are recognized
explicitly and remapped to std::cout/std::cerr on all platforms, including
Windows, which has no /dev filesystem to fall back on.
HL_NUM_THREADS=... specifies the number of threads to create for the thread
pool. When the async scheduling directive is used, more threads than this number
may be required and thus allocated. A maximum of 256 threads is allowed. (By
default, the number of cores on the host is used.)
HL_TRACE_FILE=... specifies a binary target file to dump tracing data into
(ignored unless at least one trace_ feature is enabled in the target). The
output can be parsed programmatically by starting from the code in
utils/HalideTraceViz.cpp.
HL_CACHE_DIR=... enables the opt-in generator compile cache, restoring a
generator's previously emitted artifacts instead of recompiling when its inputs
are unchanged. See Generator cache.
Further references
We have more documentation in doc/, the following links might be helpful:
| Document | Description |
|---|---|
| CMake build | How to configure and build Halide using CMake. |
| CMake package | How to use the Halide CMake package to build your code. |
| Generator cache | How to speed up rebuilds with the opt-in generator compile cache. |
| Hexagon | How to use the Hexagon backend. |
| Python | Documentation for the Python bindings. |
| RunGen | How to use the RunGen interface to run and benchmark arbitrary pipelines. |
| Vulkan | How to use the Halide Vulkan backend (BETA) |
| WebAssembly | How to use the WebAssembly backend and how to use V8 in place of wabt. |
| WebGPU | How to run WebGPU pipelines (BETA) |
The following links are of greater interest to developers wishing to contribute code to Halide:
| Document | Description |
|---|---|
| CMake developer | Guidelines for authoring new CMake code. |
| FuzzTesting | Information about fuzz testing the Halide compiler (rather than pipelines). Intended for internal developers. |
| Testing | Information about our test organization and debugging tips. Intended for internal developers. |