Halide: A C++ and Python DSL for Fast Array and Image Pipelines
a language for fast, portable data-parallel computation
At a glance
- What is it?
- Halide embeds a scheduling language in C++ and Python so the same image or array pipeline can be retargeted across x86, ARM, Hexagon, CUDA, Metal, and Vulkan. This covers what it does, how to install it, and where it stops being the right tool.
- Who is it for?
- Adopt Halide if you ship image or array kernels that must run on several CPU and GPU targets and you are willing to restructure them as a pipeline plus a schedule. Skip it if your workload is a single dense matrix multiply, if you cannot ship a C++17 toolchain, or if you need a general-purpose language rather than a library embedded in one.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Halide solves: separating what a kernel computes from how it runs
A typical image filter is written once and then rewritten for each target. The naive version is a loop nest with a temporary buffer; the fast version fuses stages, tiles the loops, vectorizes the inner dimension, and reorders the traversal so the working set stays in cache. Those changes do not alter the result, only the performance, and in most codebases they are tangled into the same source file as the arithmetic.
Halide splits the two. You write the arithmetic as a set of Halide functions, then write a schedule that says how those functions are computed: where they are inlined, how loops are split and reordered, which dimension is vectorized, and which target backend to use. The same pipeline definition can be compiled for x86, ARM, Hexagon, PowerPC, RISC-V, or WebAssembly, and for GPU compute APIs including CUDA, OpenCL, Apple Metal, DirectX 12, and Vulkan.
The audience is narrow and technical: engineers writing image processing, computational photography, or array kernels in C++ or Python who need one codebase to cover several architectures. The README is explicit that Halide is not a standalone language. It is embedded in C++, so you write C++ that builds an in-memory representation of a pipeline through Halide's C++ API, then either compile that representation to an object file or JIT-compile it and run it in the same process. A Python binding offers the same capability without C++.
How a Halide pipeline is built, compiled, and run
The data flow is a two-phase design. In the first phase your program constructs a graph of Halide functions in memory. Nothing executes yet; you are describing the computation and, separately, the schedule. In the second phase you hand that graph to the compiler, which lowers it through LLVM into machine code for the chosen target. That lowering is where the loop transformations from the schedule are applied.
Two execution modes follow from this. JIT mode compiles the pipeline and runs it in the same process, which suits interactive work and lets you change the schedule and re-run without a separate build step. AOT mode compiles the pipeline to an object file plus a header, which you link into a larger application. The README notes that compiled AOT pipelines are expected to have much broader platform support than the compiler itself: the binaries use the C ABI, and any compliant C compiler should be able to use the generated headers correctly. The C++ bindings around them require C++17.
LLVM sits underneath the compiler, and the version constraint is tight. At the time of writing the README states that building Halide requires either the latest stable LLVM, the previous stable version, or trunk, which it spells out as versions 23, 22, and 21 supported, and 20 not supported. That is a real operational constraint: an LLVM upgrade in your environment can put you outside the supported window.
Installing Halide from pip and running a first pipeline
The README calls pip possibly the easiest way to get a binary build even if you only intend to use Halide from C++. Full releases install like this:
$ pip install halide
$ uv add halideThe published Python artifacts are split into three distributions sharing the `halide` import package. The `halide` distribution provides the compiler Python API and depends on matching versions of `halide-bin` (compiler, headers, tools, and CMake package) and `halide-runtime` (the standalone `halide.runtime` API). Most users should install only `halide`, and the package manager pulls in the other two. A deployment that only calls precompiled AOT pipelines can install `halide-runtime` instead and avoid the compiler and LLVM entirely.
Wheels are currently provided for Windows x86-64, macOS x86-64, macOS arm64, and Linux x86-64. The Linux wheels are built for manylinux_2_28, which the README describes as broadly compatible with Debian 10, Ubuntu 18.10, and Fedora 29.
If you want to use the pip package from C++, the README says CMake's `find_package` should locate Halide on Linux and macOS when you are in the same virtual environment you installed it in. On Windows you must add the virtual environment root to `CMAKE_PREFIX_PATH`:
set CMAKE_PREFIX_PATH=%VIRTUAL_ENV%Other build systems can locate the Halide root by asking the installed package:
python -c "import halide; print(halide.install_dir())"On macOS there is a second route, `brew install halide`. Binary tarballs for many platforms are published on the GitHub releases page, and vcpkg users can run `vcpkg install halide:x64-windows` (or `x64-linux`/`x64-osx`). The README warns that vcpkg installs only the minimum backends required for the active platform; `halide[target-all]:x64-windows` adds the rest.
To get a working compiler from source you also need LLVM. The project publishes the LLVM builds it uses in CI as Python packages on its own index, and the README gives this sequence from the Halide source tree:
$ uv sync --frozen --group ci-llvm-22 --no-install-workspace
$ export Halide_LLVM_ROOT=$(halide-llvm --prefix)For a first real use, the README points to the tutorials at halide-lang.org/tutorials with corresponding code in the `tutorials/` directory, and to larger examples in `apps/`. That is the intended entry point rather than a documented single-file hello world.
Where Halide is the wrong tool
The build matrix is the first hard boundary. The README lists tested host toolchain combinations for building and running the compiler library: GCC 9.5 on Ubuntu 20.04 for x86 and x64, GCC 11.4 on Ubuntu 22.04 for ARM32 and ARM64, MSVC 2022 (19.37) on Windows 11 for x86 and x64, AppleClang 15.0.0 on macOS 14.4.1 for x64, and AppleClang 14.0.0 on macOS 14.6 for ARM64. Clang 9.0.0+ on Linux, ClangCL 11.0.0+ on Windows, and Windows ARM64 cross-compilation with MSVC are described as scenarios some users have built successfully but that are not actively tested, so results vary.
The compiler itself also has a cost profile that does not suit every project. Halide requires C++17, and building it requires a supported LLVM. If your product is a small numerical routine, pulling in a compiler and LLVM to generate it is a large dependency for the gain. The Makefile still exists for building `libHalide.a` and running the internal test suite, but it errors out on MinGW with the message that Halide no longer supports the MinGW environment and that MSVC through CMake should be used instead, so that path is closed.
There is also a scope limit. Halide targets image and array processing with explicit schedules. It is not a general-purpose replacement for C++ or Python, and it is not a framework that will pick a schedule for you. If you cannot express your computation as a Halide pipeline, the scheduling machinery has nothing to work with.
Halide compared with a tensor compiler like TVM
The closest comparison in this space is TVM, which also separates computation from scheduling and also lowers through LLVM to multiple backends. The difference is in what each one assumes about the workload and the graph.
TVM is built around tensor expressions and a graph-level IR, with an emphasis on importing models from frameworks and compiling them for inference. Halide is built around Halide functions over arrays, with a C++ and Python API where you construct the pipeline directly in your own program. Halide's stated targets are image and array processing first: it lists CPU architectures including Hexagon and RISC-V, operating systems including Android, iOS, and Qualcomm QuRT, and GPU compute APIs including CUDA, OpenCL, Metal, DirectX 12, and Vulkan.
The practical consequence is where the boundary sits. If you have an ONNX model and want it on an accelerator, TVM's graph import is the natural entry. If you have a hand-written image pipeline and want the same arithmetic to run on a phone CPU, a desktop GPU, and a Hexagon DSP, Halide's model of writing the pipeline in C++ and supplying a schedule per target fits better. The `apps` dependency group in the repository's pyproject.toml includes `onnx==1.19.0`, which shows Halide's own examples interoperate with ONNX models rather than replacing that pipeline.
Maintenance, release cadence, and licence status
The repository is not archived, and the last push was on 2026-09-21. Recent releases are v21.0.0 on 2025-09-16, v19.0.0 on 2024-12-17, and v18.0.0 on 2024-07-17. Note the gap: there is no v20.0.0 in the release list, so the major version numbers are not strictly consecutive in the published releases. Every commit to `main` is published to the project's package index as a development version, which the README shows how to consume with uv or pip:
$ uv add halide --prerelease=allow --index https://pypi.halide-lang.org/simple
$ pip install halide --pre --extra-index-url https://pypi.halide-lang.org/simpleThe upgrade cost is dominated by the LLVM coupling. The README states that at any point in time the build supports the latest stable LLVM, the previous stable version, or trunk, and that at the time of writing this meant 23, 22, and 21 were supported while 20 was not. A project pinned to a Halide release therefore inherits a narrow LLVM window and must move when that window moves. The `pyproject.toml` encodes this in named dependency groups: `ci-llvm-main` pins `halide-llvm~=23.0.0.dev0`, `ci-llvm-22` pins `halide-llvm~=22.1.0`, and `ci-llvm-21` pins `halide-llvm~=21.1.0`.
On licensing, the repository ships a LICENSE.txt and the GitHub metadata reports the licence as NOASSERTION, meaning the platform could not map it to a standard identifier. Anyone embedding Halide in a distributed product should read LICENSE.txt directly and have their own counsel assess the terms; the metadata alone does not tell you which terms apply.
Editorial conclusion
Adopt Halide if you ship image or array kernels that must run on several CPU and GPU targets and you are willing to restructure them as a pipeline plus a schedule. Skip it if your workload is a single dense matrix multiply, if you cannot ship a C++17 toolchain, or if you need a general-purpose language rather than a library embedded in one. Before committing, verify that a wheel exists for your platform (Windows x86-64, macOS x86-64, macOS arm64, Linux x86-64 only), check that your LLVM version is one of the three the build supports, and confirm that your deployment target can take either the compiler or a precompiled AOT object.
Frequently asked questions
How do I install Halide?
The README says pip is possibly the easiest route even for C++ users: `pip install halide`, or `uv add halide`. On macOS you can also run `brew install halide`, and vcpkg users can install `halide:x64-windows`. Wheels are currently published for Windows x86-64, macOS x86-64, macOS arm64, and Linux x86-64.
Does Halide work with Python, or is it C++ only?
It provides a Python binding that the README describes as full support for writing Halide embedded in Python without C++. The published artifacts are split into `halide`, `halide-bin`, and `halide-runtime`; most users install only `halide` and the package manager pulls in the other two.
Which LLVM version does Halide require?
The README states that building Halide requires either the latest stable LLVM, the previous stable version, or trunk, and that at the time of writing versions 23, 22, and 21 were supported while 20 was not. The project publishes the LLVM builds it uses in CI as Python packages on its own index.
Can I deploy a Halide pipeline without shipping the compiler?
Yes. The README says deployments that only call precompiled AOT pipelines can install `halide-runtime` instead of `halide`, avoiding the compiler and LLVM entirely. Compiled AOT pipelines use the C ABI, and the README expects any compliant C compiler to be able to use the generated headers correctly.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/halide-halide)