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.1.tar.gz (830.9 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.1-cp311-abi3-win_amd64.whl (5.1 MB view details)

Uploaded CPython 3.11+Windows x86-64

edgefirst_hal-0.24.1-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.1-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.1-cp311-abi3-macosx_11_0_arm64.whl (4.2 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

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

Uploaded CPython 3.8+Windows x86-64

edgefirst_hal-0.24.1-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.1-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.1-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.1.tar.gz.

File metadata

  • Download URL: edgefirst_hal-0.24.1.tar.gz
  • Upload date:
  • Size: 830.9 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.1.tar.gz
Algorithm Hash digest
SHA256 1d7edc007a1184d7610fa3f9d6e2ee39a9791217f8624b761d7ea784842edf33
MD5 fc01e77c9a6a4645a9891f2373e157e0
BLAKE2b-256 03d37c30d490bea0cfff1ddf75af1e4851d343095a7050b1ae31b877b17c2b65

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1.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.1-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.1-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c6b30a30afbd031327d262dda8f9063f27bea9c54124ec08c6dff9103af011fa
MD5 32167870271b87394acd86aea8aa43bf
BLAKE2b-256 66d12d640f3ba44705a9c0b3ed23226cc7dffb2bbcf1499d1032311bb4cc7dab

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1-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.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 523cbb7d05f89e8906ccf81d3db20d18b0cfbabdbfca62a603dd329c9697f443
MD5 ae564fba43c406adab3e85f0d5f9946f
BLAKE2b-256 b9fa5e8791660ba0883ea7f2d9be4cf04f3b21da32c0418465195b9fe0781d83

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1-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.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 ce21626629587528584fe7633938250a33862f78567932d576b99d2b37298781
MD5 8b5175d317fa4179be8a956324adcc66
BLAKE2b-256 62ba052a91efb2501eaa82585ad58796e5dd01ea35ca8383036bce9fee08d50c

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1-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.1-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.1-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c4a80bdc918441a0f32d2ed6cf0bfef3adc0108b138ce7fa34e902fbbbc303c7
MD5 41fd610a4bdb3c017a3cfbb3f75f3afb
BLAKE2b-256 f32dc8d2e65c097c5c99e455038360ff1674edc53a0ce1de62d0b857eb4e612d

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1-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.1-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.1-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 e07fcc54e20155cfc384ab3c7166f044f79a057e7205abdb3e248f9ca1b1490b
MD5 04c66b7398785869892411e40752b478
BLAKE2b-256 3b5fd9e1c938a201418b58e97899fb0d2b3bcb5c46d62b067b47b7cd0b8d553c

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1-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.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5e9e0711c42591b8459f21b4df8a01b9390b29e6ff8a98237e9bc7ac0206aa9a
MD5 520394140c189323cb625d0cfb8e13f7
BLAKE2b-256 dbab3e1a2d2dd74a49d983392276530d0fdec74bf3ee79d1a0f67d6d220b0a60

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1-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.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d4ec049629c6bb453133554ea3df8c778f14007f95a4b7a56770b2bf629e6328
MD5 1337eaaeb61fca7b0d5e431fb58204a0
BLAKE2b-256 5857c3399962ce1a240628b7151337552400b83bcf9e905c44ad8f0449e36a09

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1-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.1-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for edgefirst_hal-0.24.1-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2cbcecea345bdfb3fe99695a0645de4a284ff639f5d54aa152831a86e61701a5
MD5 d373d1ff5df63d67fe36ae3adb605949
BLAKE2b-256 0d663f9d11d627c054d98638ca32dc63f06a4d7532c22fdf52c498b0fd1fc462

See more details on using hashes here.

Provenance

The following attestation bundles were made for edgefirst_hal-0.24.1-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