Skip to main content

Hardware Abstraction Layer for edge AI with zero-copy tensors, image processing, and YOLO decoding

Project description

edgefirst-hal

PyPI Python License

Hardware-accelerated image processing, zero-copy tensors, and YOLO decoding for edge AI inference pipelines. Built in Rust with Python bindings via PyO3.

Installation

pip install edgefirst-hal

Pre-built wheels are available for Linux (x86_64, aarch64), macOS, and Windows. No Rust toolchain required.

Python 3.11+ wheels use the improved stable ABI for zero-copy buffer protocol support. Python 3.8–3.10 wheels use a compatible fallback. Pip selects the best wheel automatically.

Quick Start

import edgefirst_hal as ef

# Load a source image
src = ef.Tensor.load("photo.jpg", ef.PixelFormat.Rgb)

# Create an image processor (auto-selects best backend: GPU > G2D > CPU)
processor = ef.ImageProcessor()

# Allocate a GPU-optimal output buffer — always use create_image() for
# destinations passed to convert(), so the processor can select the best
# memory type (DMA-buf, PBO, or system memory) for zero-copy GPU paths.
dst = processor.create_image(640, 640, ef.PixelFormat.Rgb)

# Convert with letterbox resize (preserves aspect ratio)
processor.convert(src, dst)

# Access pixel data as a numpy array. Use the context manager + .view()
# form — this is the portable pattern that works on both wheel variants.
import numpy as np
with dst.map() as m:
    pixels = np.frombuffer(m.view(), dtype=np.uint8).reshape(dst.shape())

# The shorter `np.frombuffer(dst.map(), ...)` form only works on the
# abi3-py311 wheel, where `TensorMap` exposes Python's buffer protocol
# directly. The abi3-py38 compatibility wheel disables `__getbuffer__`,
# so use `.view()` if your code needs to run on Python 3.8–3.10.

Role in edgefirst-hal

The edgefirst-hal package on PyPI is the Python face of the EdgeFirst HAL Rust workspace:

  • Built from crates/python, which is a PyO3 binding over the edgefirst-hal Rust umbrella crate.
  • Does not consume the C API (edgefirst-hal-capi); the binding goes directly through Rust.
  • Exposes the same Tensor, ImageProcessor, Decoder, and Tracker surfaces as the Rust crate, with numpy-friendly conversions and the buffer protocol for zero-copy interop.
  • Wheels are distributed as two stable-ABI variants per platform — abi3-py311 (preferred, supports buffer protocol features added in 3.11) and abi3-py38 (compatibility fallback for 3.8–3.10). Pip selects the best wheel automatically.

Key Features

  • Zero-copy tensors — DMA-BUF, POSIX shared memory, and PBO-backed buffers with automatic fallback to system memory
  • Hardware-accelerated image processing — OpenGL, NXP G2D, and optimized CPU backends with automatic selection
  • Letterbox resize — aspect-ratio-preserving resize with configurable padding color, rotation, and flip
  • Int8 outputcreate_image(..., dtype="int8") for direct signed int8 tensor output with GPU-accelerated XOR bias
  • YOLO decoding — YOLOv5, YOLOv8, YOLO11, and YOLO26 detection and instance segmentation (including end-to-end models)
  • Object tracking — ByteTrack multi-object tracker with Kalman filtering
  • Fully typed — ships with .pyi stubs for IDE autocompletion and type checking with mypy / pyright

Image Processing

import edgefirst_hal as ef

processor = ef.ImageProcessor()
src = ef.Tensor.load("frame.jpg", ef.PixelFormat.Rgb)

# Letterbox resize to model input size
dst = processor.create_image(640, 640, ef.PixelFormat.Rgb)
processor.convert(src, dst)

# With rotation and horizontal flip
processor.convert(src, dst, rotation=ef.Rotation.Rotate90, flip=ef.Flip.Horizontal)

# Crop source region
processor.convert(src, dst, src_crop=ef.Rect(100, 100, 400, 400))

# Int8 output for quantized models
dst_i8 = processor.create_image(640, 640, ef.PixelFormat.Rgb, dtype="int8")
processor.convert(src, dst_i8)

Zero-Copy External Buffer (Linux)

When integrating with an NPU delegate that owns DMA-BUF buffers, render directly into the delegate's buffer to eliminate a memcpy:

import edgefirst_hal as ef

processor = ef.ImageProcessor()
src = ef.Tensor.load("frame.jpg", ef.PixelFormat.Rgb)

# Render directly into the delegate's DMA-BUF — zero copies
dst = processor.import_image(fd=vx_fd, width=640, height=640, format=ef.PixelFormat.Rgb)
processor.convert(src, dst)

# Reverse: HAL allocates, consumer imports the fd
hal_dst = processor.create_image(640, 640, ef.PixelFormat.Rgb)
fd = hal_dst.dmabuf_clone()  # Raises if not DMA-backed
delegate.register(fd)

You can also attach format metadata to any raw tensor created via from_fd():

t = ef.Tensor.from_fd(some_fd, [480, 640, 3])
t.set_format(ef.PixelFormat.Rgb)
processor.convert(src, t)

Performance tip: When rotating through a pool of DMA-BUFs (e.g. 2-3 from an NPU delegate), create the Tensor wrappers once at init and reuse them across frames. This avoids EGL image cache misses (~100-300us each on Vivante GPUs).

YOLO Decoding

import edgefirst_hal as ef

# Configure decoder from model metadata
decoder = ef.Decoder(
    {"detection": {"shape": [1, 84, 8400], "dtype": "float32"}},
    score_threshold=0.5,
    iou_threshold=0.45,
)

# Decode model outputs → (boxes, scores, class_ids)
boxes, scores, classes = decoder.decode([output_tensor])

Object Tracking

ByteTrack is a multi-object tracker based on ByteTrack with Kalman filtering. It assigns consistent track IDs across frames.

import edgefirst_hal as ef

tracker = ef.ByteTrack(
    high_conf=0.7,         # High-confidence detection threshold
    iou=0.25,              # IoU threshold for association
    update=0.25,           # Update/low-confidence threshold
    lifespan_ns=500_000_000,  # Track lifespan without detection (nanoseconds)
)

# Decode and track in one call (returns boxes, scores, classes, masks, track_infos)
boxes, scores, classes, masks, tracks = decoder.decode_tracked(
    tracker, timestamp_ns, [output_tensor]
)
# masks is empty for detection-only models

# Or query currently active tracks
active = tracker.get_active_tracks()

Segmentation Mask Rendering

draw_decoded_masks()

Draw pre-decoded masks onto a destination image:

processor.draw_decoded_masks(
    dst,
    bbox,           # numpy array [N, 4]
    scores,         # numpy array [N]
    classes,        # numpy array [N]
    seg=[],         # list of segmentation arrays (optional)
    background=None,  # optional background tensor to blit before drawing
    opacity=1.0,    # mask alpha scale (0.0 – 1.0)
)

draw_masks()

Decode model outputs and draw segmentation masks in a single call. Masks never leave Rust, eliminating the Python round-trip overhead of decode() + draw_decoded_masks().

Without a tracker, returns (boxes, scores, classes). With a tracker, returns (boxes, scores, classes, track_infos).

import edgefirst_hal as ef

processor = ef.ImageProcessor()
tracker = ef.ByteTrack()

# Without tracking
boxes, scores, classes = processor.draw_masks(decoder, outputs, dst)

# With overlay parameters
boxes, scores, classes = processor.draw_masks(
    decoder, outputs, dst,
    background=bg_tensor,  # blit bg_tensor into dst before masks
    opacity=0.7,           # semi-transparent masks
)

# With tracking (requires tracker= and timestamp=)
import time
ts = time.monotonic_ns()
boxes, scores, classes, tracks = processor.draw_masks(
    decoder, outputs, dst,
    tracker=tracker,
    timestamp=ts,
)

Platform Support

Platform GPU Acceleration Memory Types
Linux (NXP i.MX8/i.MX95) OpenGL + G2D DMA-buf, SHM, PBO, Mem
Linux (x86_64, other ARM) OpenGL SHM, PBO, Mem
macOS / Windows CPU only Mem

Hardware acceleration is used automatically when available. All platforms fall back to CPU.

Part of the EdgeFirst Ecosystem

edgefirst-hal is the runtime inference library in the EdgeFirst platform for deploying AI at the edge.

  • EdgeFirst Studio — label, train, and deploy models for edge devices
  • Rust crates — use the same library directly from Rust or C
  • GitHub — source code, architecture docs, benchmarks, and contribution guide

Documentation

License

Apache-2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

edgefirst_hal-0.24.0.tar.gz (824.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

edgefirst_hal-0.24.0-cp311-abi3-win_amd64.whl (5.1 MB view details)

Uploaded CPython 3.11+Windows x86-64

edgefirst_hal-0.24.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

edgefirst_hal-0.24.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

edgefirst_hal-0.24.0-cp311-abi3-macosx_11_0_arm64.whl (4.2 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

edgefirst_hal-0.24.0-cp38-abi3-win_amd64.whl (5.1 MB view details)

Uploaded CPython 3.8+Windows x86-64

edgefirst_hal-0.24.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

edgefirst_hal-0.24.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

edgefirst_hal-0.24.0-cp38-abi3-macosx_11_0_arm64.whl (4.2 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

Details for the file edgefirst_hal-0.24.0.tar.gz.

File metadata

  • Download URL: edgefirst_hal-0.24.0.tar.gz
  • Upload date:
  • Size: 824.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for edgefirst_hal-0.24.0.tar.gz
Algorithm Hash digest
SHA256 63bb45bd50e3edbfe5ddcb95f7d2e4acc50a9090b95e596e1fafbe594f963c3d
MD5 2b823762933fdfcf6cc134dc87baab23
BLAKE2b-256 21d44853dde47c0aa36ecc0b4283cc2734553ec90488c56e752f066357d83dc1

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0.tar.gz:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edgefirst_hal-0.24.0-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 212991907eaafa959e5386c00edc5bdeddf792dd45c68102d8c93375bb5756f3
MD5 d01857b47b95bdd90a5a126781914788
BLAKE2b-256 f1523e4d84b7a7c9f8b99c025518ab9ce26ba907c6d4aad7690c226bb3ff5292

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0-cp311-abi3-win_amd64.whl:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edgefirst_hal-0.24.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 713843dad87f884a9d3eca21f78912a70cb0f91717e83d73517e13a42d726524
MD5 e673b0e902e79664fcdaea5a7e947e2d
BLAKE2b-256 2355d5defd7f83f3993a2fd8aa28a8c1d0d210b8e1f93f91f60163a6f4e27cd8

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edgefirst_hal-0.24.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 67d61f7bcadb168d2393ab030f009e446f4f332187e46997cf01c6652002ce42
MD5 2611a773f7f4309199b0ea91a5366ae9
BLAKE2b-256 8b0b4c4564a461be95e73eddb89c4a6017c33d492205ddd29acdfd3b6e3a7d96

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edgefirst_hal-0.24.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2057d4972262fee42b1314d946da6b71fea0ec390cfc598bc8a70d3809b86114
MD5 b0320f5e67d92ed4acd67c017bcddef2
BLAKE2b-256 de5fca568464b280712673c5a1c6f56cd6644f863fd2c0e71221affd14af4e17

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edgefirst_hal-0.24.0-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 7fb0371371539b803c2da502b0a85c3012b53092029d37cab205c5a0325fa9ce
MD5 93631cd85148f0ae3d9892d03443fa8a
BLAKE2b-256 4aad8d3c96770b4b00984633f16b03594946aa248340e73bf6ecf56ea061217e

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0-cp38-abi3-win_amd64.whl:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edgefirst_hal-0.24.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 16512a77bdf6675c93e1e090dc51545bae3e23d6e981dca044f46dee7d29c2d8
MD5 923081f58b9fdb28c39dd3d026dc9201
BLAKE2b-256 12e9fb1256146bc1674a7e733a5b5fedd479215316ef437a28ae252ae8fd5299

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edgefirst_hal-0.24.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 acece4cccabc5fc05d62f24c417bd362c77a64635648a16256036c1abf15f76c
MD5 ec51baf763cf9e0461eacb4ba21528b3
BLAKE2b-256 acea1cb8d75473f6e0c4aebd84edc0eba64e8786e97c7a626e794e7e0a6dbb7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file edgefirst_hal-0.24.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 710f3d3d5cb705fd22f179d5c0a90ce9b3d7ee1f3c5520559ec2a7841ff85435
MD5 f8141977fafebad0dbbde29d025034e3
BLAKE2b-256 eba46fd0e64f7bb5e6f2373e831a5d47783ba67aa454383908c459db96f23ff3

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.0-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on EdgeFirstAI/hal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page