English | 简体中文
Nim bindings for the OpenVINO Runtime C API.
OpenVINO Nim API provides two layers. The managed API is idiomatic Nim with private native handles, Nim exceptions and documented ownership rules. The raw layer is a header-faithful binding to the OpenVINO C ABI for callers who need it.
This is a community-maintained project. It is not an official Intel or OpenVINO project, and it is not endorsed by or affiliated with Intel Corporation. OpenVINO is a trademark of Intel Corporation.
Version 0.1.0 was released on 2026-09-25. Download the source archives from
the GitHub Release.
The work is tracked phase by phase in
OPENVINO_NIM_0.1_DEVELOPMENT_PLAN.md.
Synchronous inference works. Core, Model, CompiledModel,
InferRequest, Tensor, properties, profiling and explicit blob
export/import are implemented and covered by tests that run real inference on
CPU, including a thousand-iteration lifetime loop.
Verified on two hosts: Windows 11 x86_64 with Nim 2.2.12, and Ubuntu 26.04
x86_64 with Nim 2.2.4, both against OpenVINO 2026.4.0 on CPU. On each host
the ABI, smoke, lifetime, integration and example suites all pass. No claim is
made for GPU, NPU or macOS. See compatibility for what
was and was not run. Nothing in this README should be read as a claim that a
feature already works unless it says so.
| Capability | 0.1.0 status | Notes |
|---|---|---|
| Managed Nim API | Available | Core, Model, CompiledModel, InferRequest, Tensor, shapes and properties |
| Raw C ABI layer | Available | Import it explicitly with openvino/raw; pinned to OpenVINO 2026.4 headers |
| Synchronous CPU inference | Available | Windows and Linux x86_64 are verified in CI and on clean hosts |
| Runtime discovery and diagnostics | Available | Version, device listing, symbol checks and actionable loader errors |
| Profiling and explicit blob I/O | Available | No implicit cache directory or device policy is added |
| Async inference and callbacks | Roadmap | Needs a Nim-safe callback and thread-lifetime design |
| Dynamic shapes and preprocessing | Roadmap | The corresponding C headers are intentionally not in the 0.1.0 surface |
| GPU/NPU inference | Not claimed | Device discovery is not evidence of a verified inference path |
The roadmap is deliberately explicit about what is not implemented. See the API overview and the roadmap before designing an application around a future feature.
-
Install OpenVINO Runtime
2026.4.xand run its official environment setup script for the current shell. -
Clone this repository and install the local Nim package:
git clone https://github.com/AbyssGG/OpenVINO-Nim-API.git cd OpenVINO-Nim-API nimble install -
Run the verified examples against the included four-value ReLU fixture:
nimble examples
The getting started guide has platform-specific
loader checks and troubleshooting. The complete inference snippet is kept
below and is compiled from the same source as examples/minimal.nim.
The v0.1.0 Release follows the packaging contract in the development plan
and contains exactly four canonical assets with one shared base name:
openvino-nim-{version}-{date}-ov{openvino-version}.zip
openvino-nim-{version}-{date}-ov{openvino-version}.tar.gz
openvino-nim-{version}-{date}-ov{openvino-version}.zip.sha256
openvino-nim-{version}-{date}-ov{openvino-version}.tar.gz.sha256
Both archives contain one top-level directory named after the base name and were checked for reproducibility and forbidden runtime/model files. See RELEASE_NOTES.md for the published asset names and the consumer-side checksum command.
These names are deliberately different. Mixing them up is the most common source of confusion when installing the package.
| Name | Where it is used | Why |
|---|---|---|
OpenVINO Nim API |
Project title, prose, repository description | The human-readable display name |
OpenVINO-Nim-API |
GitHub repository name | The exact public repository name requested by the project owner |
openvino-nim |
Release archive prefix and distribution references | Lowercase because file systems and package indexes disagree about case |
openvino |
Nimble package identifier | Nimble package identifiers may not contain a hyphen |
openvino.nimble |
Manifest file name | Nimble requires the manifest name to match the package identifier |
import openvino |
Nim source code | The stable import root, kept identical to the package identifier |
The GitHub repository is the hyphenated form of the human-readable project
title. Package and archive tooling use their lowercase identifiers:
openvino-nim for release assets and openvino for Nimble and imports. A Git
tag remains a SemVer tag such as v0.1.0; it is not derived from any of these
names.
nimble releaseCheck asserts that this README mentions the repository,
display and distribution names, that the repository is the hyphenated display
name, and that the distribution name stays lowercase, so none can quietly
drift from src/openvino/version.nim.
Release archives use the base name
openvino-nim-{version}-{date}-ov{openvino-version} with dots replaced by
hyphens. For version 0.1.0 released against OpenVINO 2026.4.0, the
archive base name is generated by the release tooling rather than written by
hand, so that the Git tag, release title, archive name and checksums cannot
drift apart.
| Component | Requirement |
|---|---|
| Nim | 2.0.0 or newer; CI pins the exact versions that are verified |
| OpenVINO Runtime | 2026.4.x, verified against 2026.4.0 |
| Tier 1 platforms | Windows x86_64, Linux x86_64 |
| Baseline device | CPU |
The 2026.4 requirement is not arbitrary. This package uses the
non-variadic properties API (ov_property_t, ov_core_compile_model_props,
ov_compiled_model_set_properties and friends) that avoids passing property
pairs through C varargs. The package does not silently fall back to older
runtimes.
GPU and NPU devices are discovered dynamically when the corresponding OpenVINO plugins are installed. They are not build or release prerequisites, and support for them is not claimed beyond what CI verifies.
The package binds to the OpenVINO runtime at run time and never ships it.
Install OpenVINO 2026.4.x separately, then make sure the C API library is
visible to the dynamic loader:
| Platform | Library | Loader notes |
|---|---|---|
| Windows | openvino_c.dll |
Must be on the DLL search path |
| Linux | libopenvino_c.so, or libopenvino_c.so.2640 |
Must be on the loader search path. A pip installation ships only the versioned name; both are tried |
Loading openvino_c alone is not enough to run inference. Core also needs
plugins.xml, the device plugins and the model frontends from the same
official runtime layout. Copying a single library out of an OpenVINO
installation will fail at model load time, not at library load time.
The official setup scripts (setupvars.bat on Windows, setupvars.sh on
Linux) configure the environment for the current shell. This package never
modifies environment variables or the process search path on your behalf.
nimble install openvinoThe Nimble package index entry is not published yet. Until then, install from a local checkout:
nimble installimport openvino
const modelPath = "tests/fixtures/relu_1x4_f32.xml"
proc main() =
let core = newCore()
defer: core.close()
let compiled = core.compileModel(modelPath, "CPU")
defer: compiled.close()
let request = compiled.createInferRequest()
defer: request.close()
let input = tensorFrom(etF32, initShape(1, 4),
[float32(-1.5), 2.0, -0.25, 4.0])
defer: input.close()
request.setInputTensor(0, input)
request.infer()
let output = request.outputTensor(0)
defer: output.close()
echo output.toSeq(float32)
main()Prints @[0.0, 2.0, 0.0, 4.0]: the model is a ReLU, so the two negative
inputs become zero and the two positive ones pass through.
This is not a transcription. The same code is examples/minimal.nim, which
nimble examples compiles and runs, and nimble lint fails if the two drift
apart. Note what is absent: no device is chosen for you, no cache directory
appears, and every object is closed where it was created.
More examples, all using the public API only:
| Example | What it shows |
|---|---|
examples/list_devices.nim |
Runtime version and device discovery, useful first when a deployment misbehaves |
examples/minimal.nim |
The block above |
examples/sync_infer.nim |
The same loop with the model path and device taken from the command line, plus model metadata |
examples/tensor_basics.nim |
Shapes, element types, and the difference between the safe data paths and the unsafe one |
examples/profiling.nim |
Per-node timings, and what the numbers do and do not mean |
Failures surface as distinguishable Nim exceptions rather than status codes:
| Exception | Meaning |
|---|---|
OpenVinoError |
An OpenVINO C call returned a non-OK status |
OpenVinoLibraryError |
The dynamic library or a required symbol is missing |
OpenVinoVersionError |
The detected runtime major/minor is unsupported |
OpenVinoError carries the operation name, the numeric status, the stable
status description and the native detail captured at the moment of failure.
Argument errors such as a negative index, an invalid shape or a call on a
closed object are raised before entering the C layer.
Two rules cover most of what you need to know:
- Every managed type owns exactly one native handle and offers an
idempotent
close(). Callingclose()twice is harmless. Using an object afterclose()raises a Nim error instead of crashing in native code. Destructors are a backstop, not a replacement forclose(). - Tensors allocated by OpenVINO or copied from Nim data are the safe
default. Any entry point that borrows caller memory without owning it is
named with
unsafeand documents exactly what the caller must guarantee about address stability, alignment, capacity and lifetime.
The documentation hub groups the English guides and the generated API reference.
Start with whichever question you have:
| Question | Document |
|---|---|
| How is this put together, and why? | Architecture |
| What has actually been tested? | Compatibility |
| Something does not work | Troubleshooting |
| Who releases what? | Ownership rules |
| Which C entry points are bound? | C API coverage |
| What is the public API shape? | API overview |
| How do I install and verify it? | Getting started |
| What is planned after 0.1.0? | Roadmap |
| I have Resonance code | Migration guide |
| Why was it done this way? | Symbol loading, handle model |
Project documents: notice and provenance, development plan, development log in English and Chinese, style guide, contributing, changelog, prototype audit.
| Path | Purpose |
|---|---|
src/openvino.nim |
Stable managed import root |
src/openvino/ |
Managed handles, conversions and user-facing errors |
src/openvino/raw/ |
Explicit, header-faithful C ABI declarations |
examples/ |
Small runnable programs using only the public API |
tests/ |
Unit, ABI, lifecycle, integration and packaging checks |
docs/ |
Architecture, compatibility, API coverage and decisions |
.github/workflows/ |
Static, runtime, documentation and release checks |
Bug reports should include the OpenVINO runtime version, Nim version, target device and the smallest reproducible example. Start with Troubleshooting, then open a GitHub issue if the problem is reproducible with the supported matrix. Security reports belong in SECURITY.md, not in a public issue.
Pull requests are welcome. Read CONTRIBUTING.md, keep the managed/raw boundary intact, and update tests and documentation with any public API change. The project is community maintained and is not an Intel product.
Apache-2.0. See LICENSE, and NOTICE for how this package relates to the OpenVINO C headers, why no upstream text is copied, and what is and is not bundled.