C API bindingslink
Overviewlink
The IREE compiler and IREE runtime both have their own C/C++ APIs. This page introduces the available APIs and describes how to use them from your applications.
Note
There are multiple ways to distribute and depend on C/C++ projects, each with varying levels of portability, flexibility, and toolchain compatibility. IREE aims to support common configurations and platforms.
Compiler APIlink
The IREE compiler is structured as a monolithic shared object with a dynamic plugin system allowing for extensions. The shared object exports symbols for versioned API functions.
graph TD
accTitle: IREE compiler linkage model diagram
accDescr {
The libIREECompiler.so or IREECompiler.dll shared object contains pipelines,
target backends, and general passes as private implementation details.
Compiler plugins interface with the compiler shared object to extend it with
custom targets, dialects, etc.
Applications interface with the compiler shared object through the compiler
C API's exported symbols.
}
subgraph compiler[libIREECompiler.so / IREECompiler.dll]
pipelines("Pipelines
• Flow
• Stream
• etc.")
targets("Target backends
• llvm-cpu
• vulkan-spirv
• etc.")
passes("General passes
• Const eval
• DCE
• etc.")
end
plugins("Compiler plugins
• Custom targets
• Custom dialects
• etc.")
application(Your application)
compiler <-- "Plugin API<br>(static or dynamic linking)" --> plugins
compiler -. "Compiler C API<br>(exported symbols)" .-> application
API definitions can be found in the following locations:
Source location | Overview |
---|---|
iree/compiler/embedding_api.h |
Top-level IREE compiler embedding API |
iree/compiler/PluginAPI/ directory |
IREE compiler plugin API |
mlir/include/mlir-c/ directory |
MLIR C API headers |
Conceptslink
The compiler API is centered around running pipelines to translate inputs to artifacts. These are modeled via sessions, invocations, sources, and outputs.
stateDiagram-v2
accTitle: IREE compiler session and invocation state diagram
accDescr {
Input files are opened (or buffers are wrapped) as sources in a session.
Sources are parsed into invocations, which run pipelines.
Output files are written (or buffers are mapped) for compilation artifacts.
Sessions can contain multiple sources and run multiple invocations.
}
direction LR
InputFile --> Source1 : open file
InputBuffer --> Source2 : wrap buffer
state Session {
Source1 --> Invocation1
Source2 --> Invocation2
Invocation1 --> Invocation1 : run pipeline
Invocation2 --> Invocation2 : run pipeline
}
Invocation1 --> Output1File : write file
Invocation1 --> Output1Buffer : map memory
Invocation2 --> Output2Buffer : map memory
Sessionslink
A session (iree_compiler_session_t
) is a scope where one or more invocations
can run.
- Internally, sessions consist of an
MLIRContext
and a private set of options. - Sessions may activate available plugins based on their options.
Invocationslink
An invocation (iree_compiler_invocation_t
) is a discrete run of the
compiler.
- Invocations run pipelines, consisting of passes, to translate from sources to outputs.
Sourceslink
A source (iree_compiler_source_t
) represents an input program, including
operations and data.
- Sources may refer to files or buffers in memory.
Outputslink
An output (iree_compiler_output_t
) represents a compilation artifact.
- Outputs can be standalone files or more advanced streams.
Pluginslink
A plugin extends the compiler with some combination of target backends,
options, passes, or pipelines. For documentation on compiler plugins, see
compiler/PluginAPI/README.md
.
Usagelink
This snippet shows the general layout of the API. For working examples, see the samples below.
To build a custom tool using the compiler API:
CMakeLists.txt | |
---|---|
1 2 3 |
|
iree_compiler_demo.c | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Sampleslink
Project | Source | Description |
---|---|---|
iree-org/iree-template-compiler-cmake | hello_compiler.c |
Compiler application template |
iree-org/iree | integrations/pjrt/.../iree_compiler.cc |
JIT for TensorFlow + JAX to IREE |
iree-org/iree | compiler/plugins |
In-tree supported compiler plugins |
iree-org/iree | samples/compiler_plugins/ |
In-tree sample compiler plugins |
nod-ai/iree-amd-aie | plugins/.../iree-amd-aie |
Early-phase plugins for interfacing with AMD AIE accelerators |
Runtime APIlink
The IREE runtime is structured as a modular set of library components. Each component is designed to be linked into applications directly and compiled with LTO style optimizations.
The low level library components can be used directly or through a higher level API.
Caution
Prefer using the low level API directly when writing custom bindings or integrating into larger projects. The high level API is mainly useful as a reference and when building samples.
Each runtime component has its own low level API. The low level APIs are typically verbose as they expose the full flexibility of each underlying system.
graph TD
accTitle: IREE runtime low level API diagram
accDescr {
The IREE runtime includes 'base', 'HAL', and 'VM' components, each with
their own types and API methods.
Applications can interface directly with the IREE runtime via the low
level component APIs.
}
subgraph iree_runtime[IREE Runtime]
subgraph base
base_types("Types
• allocator
• status
• etc.")
end
subgraph hal[HAL]
hal_types("Types
• buffer
• device
• etc.")
hal_drivers("Drivers
• local-*
• vulkan
• etc.")
end
subgraph vm[VM]
vm_types("Types
• context
• invocation
• etc.")
end
end
application(Your application)
base_types & hal_types & hal_drivers & vm_types --> application
The high level 'runtime' API sits on top of the low level components. It is relatively terse but does not expose the full flexibility of the underlying systems.
graph TD
accTitle: IREE runtime high level API diagram
accDescr {
The IREE runtime includes 'base', 'HAL', and 'VM' components, each with
their own types and API methods.
A high level "runtime API" sits on top of these component APIs.
Applications can interface indirectly with the IREE runtime via this
high level runtime API.
}
subgraph iree_runtime[IREE Runtime]
subgraph base
base_types("Types
• allocator
• status
• etc.")
end
subgraph hal[HAL]
hal_types("Types
• buffer
• device
• etc.")
hal_drivers("Drivers
• local-*
• vulkan
• etc.")
end
subgraph vm[VM]
vm_types("Types
• context
• invocation
• etc.")
end
runtime_api("Runtime API
• instance
• session
• call")
base_types & hal_types & hal_drivers & vm_types --> runtime_api
end
application(Your application)
runtime_api --> application
Runtime API header files are organized by component:
Component header file | Overview |
---|---|
iree/base/api.h |
Base API: type definitions, cross-platform primitives, utilities |
iree/vm/api.h |
VM APIs: loading modules, I/O, calling functions |
iree/hal/api.h |
HAL APIs: device management, synchronization, accessing hardware features |
iree/runtime/api.h |
High level runtime API |
Low level conceptslink
Baselink
The 'base' component includes general runtime utilities such as:
- Memory allocators
- Status and error handling
- String manipulation
- File input and output
- Event pools and loops
- Synchronization and threading primitives
- Tracing and other debugging
As IREE is designed to support a variety of deployment targets, many of these utilities are written to be cross-platform or be optional.
VMlink
IREE uses its own Virtual Machine (VM) at runtime to interpret program instructions on the host system.
Tip - EmitC alternate lowering path
VM instructions may be further lowered to C source code for static or resource constrained deployment.
See the --output-format=vm-c
compiler option and the samples in
samples/emitc_modules/
for more information.
The VM supports generic operations like loads, stores, arithmetic, function calls, and control flow. The VM builds streams of more complex program logic and dense math into HAL command buffers that are dispatched to hardware backends.
- VM instances can serve multiple isolated execution contexts.
- VM contexts are effectively sandboxes for loading modules and running programs.
-
VM modules provide all functionality to execution contexts, including access to hardware accelerators through the HAL. Compiled user programs are also modules.
stateDiagram-v2 accTitle: Sample VM Modules accDescr { Bytecode modules contain program state, program functions, and debug information. HAL modules contain devices, executables, HAL functions, and HAL types. Custom modules may contain external functions and custom types. } state "Bytecode module" as bytecode { bytecode_contents: Module state<br>Program funcs<br>Debug info } state "HAL module" as HAL { hal_contents: Devices<br>Executables<br>HAL funcs<br>HAL types } state "Parameters module" as Params { parameters_contents: Providers } state "Custom module" as custom { custom_contents: External funcs<br>Custom types }
For more detailed information about the design of the VM, see this design doc.
HALlink
IREE uses a Hardware Abstraction Layer (HAL) to model and interact with hardware devices like CPUs, GPUs and other accelerators.
- HAL drivers are used to enumerate and create HAL devices.
- HAL devices interface with hardware, such as by allocating device memory, preparing executables, recording and dispatching command buffers, and synchronizing with the host.
- HAL buffers represent data storage and buffer views represent views into that storage with associated shapes and types (similar to "tensors").
High level conceptslink
The high level API uses instances, sessions, and calls to run programs with a small API surface.
stateDiagram-v2
accTitle: IREE runtime high level API state diagram
accDescr {
Instances track sessions and state: options, drivers, devices.
Sessions track calls and state: a device and bytecode/VM modules.
Calls track input and output lists.
}
state iree_runtime_instance_t {
instance_state: state<br>- options<br>- drivers<br>- devices
state iree_runtime_session_t {
session_state: state<br>- device<br>- VM / bytecode modules
state iree_runtime_call_t {
inputs
outputs
}
}
}
Instancelink
An instance (iree_runtime_instance_t
) isolates runtime usage and manages
device resources.
- Instances may service multiple sessions to avoid extra device interaction and reuse caches/pools.
- Separate instances are isolated/sandboxed from one another.
Sessionlink
A session (iree_runtime_session_t
) contains a set of loaded modules and
their state.
- Sessions that share an instance may share resources directly.
- Sessions that do not share an instance can transfer resources using import and export APIs.
Calllink
A call (iree_runtime_call_t
) is a stateful VM function call builder.
- Calls can be reused to avoid having to construct input lists for each invocation.
Usagelink
Sampleslink
Project | Source | Description |
---|---|---|
iree-org/iree-template-runtime-cmake | hello_world.c |
Runtime application template |
iree-org/iree | runtime/demo/ |
In-tree demos of the high level runtime API |
iree-org/iree | samples/ |
In-tree sample applications |
iree-org/iree-experimental | runtime-library/ |
Shared runtime library builder Builds libireert.so to aid development |
iml130/iree-template-cpp | simple_embedding.c |
Demo integration into a project |
High level "hello world"link
Below are two samples showing how to use the high level runtime API - one "terse" sample and one "explained" sample with more detailed comments:
Source file: runtime/src/iree/runtime/demo/hello_world_terse.c
runtime/src/iree/runtime/demo/hello_world_terse.c | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
|
Source file: runtime/src/iree/runtime/demo/hello_world_explained.c
runtime/src/iree/runtime/demo/hello_world_explained.c | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
|
Compiler + Runtime = JITlink
The compiler and runtime APIs may be used together to build a "just in time" (JIT) execution engine. JIT compilation allows for last-minute specialization with no prior knowledge of target devices and avoids issues with version drift, but it can also constrain deployment options and usage scenarios.