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

Uploaded CPython 3.11+Windows x86-64

edgefirst_hal-0.23.2-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.23.2-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.23.2-cp311-abi3-macosx_11_0_arm64.whl (4.1 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

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

Uploaded CPython 3.8+Windows x86-64

edgefirst_hal-0.23.2-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.23.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.4 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

edgefirst_hal-0.23.2-cp38-abi3-macosx_11_0_arm64.whl (4.1 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: edgefirst_hal-0.23.2.tar.gz
  • Upload date:
  • Size: 783.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.23.2.tar.gz
Algorithm Hash digest
SHA256 abb45d761cd90e5c1a765b3599ea25c652c57771100d581a111d338ee511b234
MD5 6188723fd8e463b63528443176ecc435
BLAKE2b-256 d988569fe12e418ffab387ced9e7d1d6e01b91b4750a0bfe515c8c2ef65297ff

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for edgefirst_hal-0.23.2-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 d597a56cbb4057fa2e8c329293b3cb1a94bb2318ae9c11db626467cefa499da4
MD5 89ff74d6089940134d603bb862e9986c
BLAKE2b-256 1bb68b1a365f7a8f73ae1e6596bbc45576a450891be33b904fd73c4ecd7e0142

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for edgefirst_hal-0.23.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ae4285346be63180331942a6efe02e2a3224b1f78b149d71c86d65c3f37a12f0
MD5 9f46eed02e1e2415259eb07c0505b15e
BLAKE2b-256 6852100a55d974415f7eac8b6fe43922ad29ec9ea34535fe11361651d8f6323d

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for edgefirst_hal-0.23.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2c6bb25bb002e0f37da5a622ca55db259310a5700ed541939b1337d8d70ce9aa
MD5 6a0a1fdaf39b769e0fa1701979be5b60
BLAKE2b-256 55f87663590049d65c5279f38483e7c46d25fc5340061fbec90f65741cde262a

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for edgefirst_hal-0.23.2-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6594667ca40c7a6297fe308d56b3adacac4586def7e0b1cc511428146703ad47
MD5 e4e0fc7319c6e4846dc351ed944d8928
BLAKE2b-256 dcf2de44d596442b709ff9c7026e10f2823f1252febca00b237fca6aa6b03f17

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for edgefirst_hal-0.23.2-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 6866129d2311eb7dcf0caf525048b057ee300d68cdefc46b71a3916bda23cc2f
MD5 61689da5bbfd46d380a3afbb5e80d761
BLAKE2b-256 a053fc923d4e254d088ed60523e991732f8b81e718d173e366b24d9bbe17cc1c

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for edgefirst_hal-0.23.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 64c7d5042ebbceee9f25361448240d20a37c8670018d268bbdd0592e1b762c35
MD5 086c0798d8be488a82f6a854d7e1e6eb
BLAKE2b-256 db3630582dee2f735581a73bef62323fcef88c60be51b5746e9d1518807ec9bd

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for edgefirst_hal-0.23.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c885ccf74e70f38536b5b22d3cf5e9c4e500bde481a9893e3abb1f5b6c96d3b9
MD5 fa9b6be4982c49ef9b96fa3b209b8c1a
BLAKE2b-256 f06b2ef175ef2818eb28480c7150124a0a77f84addd99e30180df82ac9903c60

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for edgefirst_hal-0.23.2-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4dba8601db2cbed868198e6a9b4ce51cfc836326e1185b866998f67db4b6b201
MD5 16356bde69f8455ae8cecf44521e4278
BLAKE2b-256 55938f25e71d945ba8b128fea035588e33f1e76fa93387f510e3d6456c46b9bc

See more details on using hashes here.

Provenance

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