xtc_accel(3)
---xtc_accel(3)
park a fiber on a GPU/NPU completion; enumerate accelerators
| XTC_ACCEL(3) | Library Functions Manual | XTC_ACCEL(3) |
NAME
xtc_accel_probe,
xtc_accel_wait_fence,
xtc_accel_run_blocking —
park a fiber on a GPU/NPU completion; enumerate
accelerators
SYNOPSIS
#include <xtc.h>
#include <xtc_accel.h>
int
xtc_accel_probe(xtc_accel_dev_t
*out, int max,
int *out_n);
int
xtc_accel_wait_fence(int
fence_fd, int64_t
timeout_ns);
int
xtc_accel_run_blocking(int
(*fn)(void *), void
*arg, int
*out_result);
DESCRIPTION
An accelerator -- a GPU or an NPU (neural / vision processing unit, also called a VPU) -- is, at the layer a concurrency runtime cares about, an asynchronous I/O device: the caller submits an opaque command buffer or compiled graph, the coprocessor runs it, and it signals completion through a fence. On Linux both device kinds are DRM devices (/dev/dri/renderD* for a render GPU, /dev/accel/accel* for an NPU) whose completions are the same kernel object -- a dma-fence exported as a pollable sync_file file descriptor, the identical readiness event the loop already multiplexes for sockets and pipes. A GPU fence fd and an NPU fence fd are indistinguishable to poll(2), so they are handled by one API here.
The xtc_accel facility does
exactly one thing: it parks the calling fiber on such a completion and wakes
it when the device is done. It is
not a tensor library,
a device-memory allocator, or a vendor-SDK portability layer.
libxtc links no GPU/NPU runtime
(Level(Zero), CUDA, Vulkan, OpenVINO, ...): the consumer
links whichever runtime drives the device, submits the work, and hands
xtc_accel_probe the resulting fence fd. The
abstraction stops at the fence; submission and the compute itself live above
it.
xtc_accel_probe()
enumerates the accelerator devices present on the host into
out[0 ..max], writing the total
number found to *out_n (which may exceed
max if the buffer was too small; only the first
max are written). Each
xtc_accel_dev_t reports a kind
(XTC_ACCEL_KIND_GPU or
XTC_ACCEL_KIND_NPU), a short
name, the device node path, and
the backing kernel driver name if cheaply known (for
example ‘xe’ or
‘intel_vpu’). These are for device
selection and observability by the consumer and its runtime;
libxtc opens none of them. The device kind is a tag
only -- it never changes how a fence is waited on. Probing opens and submits
nothing.
xtc_accel_wait_fence()
parks the calling fiber until the completion fence
fence_fd signals or timeout_ns
elapses (negative waits forever). The fence fd is a pollable
sync_file the consumer's runtime produced when it
submitted work (from a Level(Zero) event or fence, an
exported DRM sync object, a VK_KHR_external_fence_fd
Vulkan fence, a CUDA event bridged to an eventfd(2), and
so on). While waiting the fiber holds no OS thread -- the wait rides the
loop's normal readiness path via xtc_proc_wait_fd(3).
libxtc does not own, duplicate, or close
fence_fd; the caller retains ownership. It must be
called from within a fiber.
xtc_accel_run_blocking()
runs the synchronous accelerator call
fn(arg) on the
xtc_blocking(3) thread pool, parking the calling fiber
until it returns and storing fn's return value in
*out_result (may be NULL). It
is the fallback for runtimes that expose only a blocking submit-and-wait
with no pollable fence. It holds one pool thread for the duration of
fn, so it suits coarse-grained inference rather than
thousands of tiny operations per second; prefer
xtc_accel_wait_fence() when a fence fd is
available.
RETURN VALUES
xtc_accel_probe() returns
XTC_OK on success, including when zero devices are
found (absence is not an error), or XTC_E_INVAL on a
bad argument.
xtc_accel_wait_fence() returns
XTC_OK when the fence signals,
XTC_E_AGAIN on timeout (the fence never fired),
XTC_E_INVAL on a bad file descriptor, or
XTC_E_NOSYS when the library was built without
accelerator support.
xtc_accel_run_blocking() returns
XTC_OK (fn
ran; see *out_result),
XTC_E_INVAL for a NULL
fn, or an xtc_blocking(3) error if
the work could not be dispatched. It works regardless of whether accelerator
support was built in.
AVAILABILITY
Accelerator support is selected at configure time with
--with-accel=auto|yes|no
(default auto: enabled where the Linux DRM/accel
subsystem is present). When it is not built in,
xtc_accel_probe()
reports zero devices and xtc_accel_wait_fence()
returns XTC_E_NOSYS, following the same
“always linkable, NOSYS when unsupported” convention as the
TLS and cryptography modules;
xtc_accel_run_blocking() is unaffected.
SEE ALSO
HISTORY
The xtc_accel facility appeared in
libxtc 1.30.
| July 23, 2026 | Debian |