Skip to main content

TVM-FFI OrcJIT

A Python package that enables dynamic loading of compiled object files (.o) using LLVM ORC JIT v2, providing a flexible JIT execution environment for TVM-FFI exported functions.

Features

  • JIT Execution: Load and execute compiled object files at runtime using LLVM's ORC JIT v2
  • High-Level Loading: default_session().load_module(...) mirrors tvm_ffi.load_module, returning a plain tvm_ffi.Module
  • Unified Input: Load from a file path, in-memory object bytes, or a list mixing both
  • Shared Session: A process-wide session so multiple callers share one JIT environment (process symbols, arena, linking)
  • Symbol Isolation: Separate load_module calls define independent symbol namespaces, so they can define the same symbol without conflicts
  • Init/Fini Support: Handles static constructors/destructors across ELF (.init_array/.ctors), Mach-O (__mod_init_func), and COFF (.CRT$XC*/.CRT$XT*)
  • Cross-Platform: Linux (x86_64, aarch64), macOS (arm64), Windows (AMD64)
  • Multi-Compiler: Tested with LLVM Clang, GCC, Apple Clang, MSVC, and clang-cl
  • TVM-FFI Integration: Seamlessly works with TVM-FFI's stable C ABI
  • Python API: Simple Pythonic interface for JIT compilation and execution

Supported Platforms and Compilers

Object files compiled with any of the following compiler/platform combinations can be loaded and executed by the ORC JIT:

Platform Compilers C C++
Linux (x86_64, aarch64) LLVM Clang, GCC yes yes
macOS (arm64) LLVM Clang, Apple Clang yes yes
Windows (AMD64) LLVM Clang, MSVC, clang-cl yes no

Windows is C-only across all compilers. C++ objects compiled with TVM_FFI_DLL_EXPORT_TYPED_FUNC use try/catch (via TVM_FFI_SAFE_CALL_BEGIN/END), which requires Itanium exception ABI symbols (__cxa_begin_catch, __gxx_personality_v0, etc.) that the MSVC-built host process cannot provide. Pure C objects using the TVMFFISafeCallType ABI work on all platforms.

Installation

Install from PyPI

pip install apache-tvm-ffi apache-tvm_ffi_orcjit

Build from Source

Prerequisites

  • Python 3.10+, CMake 3.20+, C++17 compiler
  • LLVM 22+ development libraries (llvmdev, llvm-config)
  • Static zlib and zstd libraries (in the same prefix as LLVM)

Install LLVM via conda-forge

The easiest way to get all dependencies is via conda-forge:

conda create -p /opt/llvm -c conda-forge \
  llvmdev=22.1.0 clangdev=22.1.0 compiler-rt=22.1.0 zlib zstd-static -y
export LLVM_PREFIX=/opt/llvm

On Windows:

conda create -p C:\opt\llvm -c conda-forge llvmdev=22.1.0 zlib zstd-static -y
set LLVM_PREFIX=C:\opt\llvm

Build and install

git clone --recursive https://github.com/apache/tvm-ffi.git
cd tvm-ffi

# Install tvm-ffi first
pip install -e .

# Build and install the orcjit addon
cd addons/tvm_ffi_orcjit
pip install -e .

The LLVM_PREFIX environment variable tells CMake where to find LLVM. If LLVM is installed in a conda env or a standard system path, CMake can auto-discover it and LLVM_PREFIX is not needed.

Usage

Basic Example

The high-level API mirrors tvm_ffi.load_module: a process-wide shared session plus a load_module that accepts a path, in-memory object bytes, or a list of either, and returns a plain tvm_ffi.Module.

import tvm_ffi_orcjit as oj

# Shared process-wide session (created once, cached).
session = oj.default_session()

# Load a single object file by path.
mod = session.load_module("example.o")

# Call an exported function.
result = mod.add(1, 2)
print(f"Result: {result}")  # Output: Result: 3

Loading Multiple Objects and In-Memory Bytes

Objects passed together are linked into one module (the same way a multi-object shared library links). Each element may be a path or an object-file image in memory.

from pathlib import Path

session = oj.default_session()

mod = session.load_module(
    [
        "math_ops.o",                    # path
        Path("kernel.o").read_bytes(),   # in-memory object bytes
    ]
)
result = mod.call_math(10, 20)

Isolated Sessions

default_session() is shared across the process. For an isolated symbol namespace or a tuned memory arena, construct an ExecutionSession directly:

from tvm_ffi_orcjit import ExecutionSession

session = ExecutionSession()          # independent LLVM ExecutionSession
mod = session.load_module("impl.o")

Writing Functions for OrcJIT

C++ (Linux/macOS)

#include <tvm/ffi/function.h>

TVM_FFI_DLL_EXPORT_TYPED_FUNC(add, [](int a, int b) {
    return a + b;
});

Compile: clang++ -std=c++17 -fPIC -O2 -c -o example.o example.cc

Pure C (all platforms including Windows)

#include <tvm/ffi/c_api.h>

TVM_FFI_DLL_EXPORT int __tvm_ffi_add(
    void* self, const TVMFFIAny* args, int32_t num_args, TVMFFIAny* result) {
  result->type_index = kTVMFFIInt;
  result->v_int64 = args[0].v_int64 + args[1].v_int64;
  return 0;
}

Compile: clang -O2 -c -o example.o example.c

How It Works

  • LLJIT: Built on LLVM's ORC JIT v2 with ObjectLinkingLayer (JITLink) for all platforms.
  • InitFiniPlugin: Custom ObjectLinkingLayer::Plugin that collects function pointers from init/fini sections (ELF .init_array/.ctors/.fini_array/.dtors, Mach-O __mod_init_func/__mod_term_func, COFF .CRT$XC*/.CRT$XT*) and runs them in priority order at symbol lookup / library teardown.
  • DLL Import Stubs (Windows): Custom DefinitionGenerator that resolves host process symbols from all loaded DLLs and creates __imp_* pointer stubs in JIT memory, keeping all fixups within PCRel32 range.
  • SEH Stripping (Windows): ObjectTransformLayer strips .pdata/.xdata relocations from COFF objects before JITLink graph building, working around a JITLink limitation with COMDAT section symbols.

Please refers to ORCJIT_PRIMER.md to learn more about object file, linking, llvm orcjit v2, and how the addon works.

Project Structure

tvm_ffi_orcjit/
├── CMakeLists.txt              # Build configuration
├── pyproject.toml              # Python package metadata
├── src/ffi/
│   ├── orcjit_session.cc       # ExecutionSession (LLJIT setup, plugins)
│   ├── orcjit_session.h
│   ├── orcjit_dylib.cc         # JIT dylib module (object loading, symbol lookup)
│   ├── orcjit_dylib.h
│   └── orcjit_utils.h          # LLVM error handling utilities
├── python/tvm_ffi_orcjit/
│   ├── __init__.py             # Module exports and library loading
│   └── session.py              # Python ExecutionSession + default_session
├── tests/                      # See tests/README.md
└── examples/quick-start/       # Complete example with CMake

CI

Runs on Linux (x86_64, aarch64), macOS (arm64), Windows (AMD64) via cibuildwheel. Each platform builds test objects with multiple compilers and runs the full test suite. See the orcjit job in .github/workflows/ci_test.yml.

Troubleshooting

"Cannot find global function" error

The shared library wasn't loaded. Reinstall: pip install --force-reinstall apache-tvm_ffi_orcjit

"Duplicate definition of symbol" error

Use separate libraries for different implementations of the same symbol.

"Symbol not found" error

Ensure functions are exported with TVM-FFI macros (TVM_FFI_DLL_EXPORT_TYPED_FUNC for C++, or __tvm_ffi_ prefix for C).

Relocation errors on Windows

MSVC/clang-cl objects must be compiled with /GS- to disable buffer security checks (__security_cookie) which are CRT symbols the JIT cannot resolve.

LLVM version mismatch

The package requires LLVM 22+. Set LLVM_PREFIX to the LLVM install prefix:

export LLVM_PREFIX=/path/to/llvm

License

Apache License 2.0

Release files for apache-tvm-ffi-orcjit 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for apache-tvm-ffi-orcjit 0.1.1
File
apache_tvm_ffi_orcjit-0.1.1-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
apache_tvm_ffi_orcjit-0.1.1-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
apache_tvm_ffi_orcjit-0.1.1-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64, Linux glibc 2.27+ ARM64 Details
apache_tvm_ffi_orcjit-0.1.1-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details

Total release size: 68.5 MB

Release files / apache_tvm_ffi_orcjit-0.1.1-py3-none-win_amd64.whl

Download URL apache_tvm_ffi_orcjit-0.1.1-py3-none-win_amd64.whl
Size 12.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
dcc2acf0bd18ffb787807e0cdfb902af949d43338c7376f4918fc7d2013c8a81
BLAKE2b-256 checksum
How to use checksums
2e80f09257f8abf8f48224b8657f701847590e30aebbf82285ca4d1decdddc8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release files / apache_tvm_ffi_orcjit-0.1.1-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL apache_tvm_ffi_orcjit-0.1.1-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 21.5 MB
Tags Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
3415f16c211c223a9939a9f2cdcb80dfa604555de9ee86dc4dfd48de6d7f7c38
BLAKE2b-256 checksum
How to use checksums
70309ede72dc7be023e19fac9280ea994fccef05f339b4738b43982cb244279a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release files / apache_tvm_ffi_orcjit-0.1.1-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL apache_tvm_ffi_orcjit-0.1.1-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 19.9 MB
Tags Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
470193cb4651afc8b0c24e651225f610fafe9d85fae950f31d95679e50b36f3d
BLAKE2b-256 checksum
How to use checksums
0ced251f0e69de8ce3355fc1da924feced90bb425e487bbc7a90bbe80ffe61f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release files / apache_tvm_ffi_orcjit-0.1.1-py3-none-macosx_11_0_arm64.whl

Download URL apache_tvm_ffi_orcjit-0.1.1-py3-none-macosx_11_0_arm64.whl
Size 14.9 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
380c9e47f637a4e18aa1fc6803fbec05d4b7901eab7bcd0a471edc880a533e29
BLAKE2b-256 checksum
How to use checksums
fba5d96abb2f0143b081d03e8585c16d0ad635ed57a4515c190345885c6884c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.2

4 release files

This release

0.1.1 This release

4 release files

0.1.0

4 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page