OTP Application for EMLX.
Allocates the application-default EMLX.CommandQueue (one per device:
:cpu and :gpu) at boot and stashes the NIF resource references in
:persistent_term. These are the workers used by EMLX.eval/1 and
EMLX.to_blob/1 for any process that has not bound its own queue via
EMLX.CommandQueue.with_queue/2.
See clean-room-import/01-worker-thread-dispatch.md for the rationale
behind :persistent_term instead of a GenServer + Registry.
Idempotency
start/2 is safe to call more than once (e.g. from an umbrella where
:emlx is referenced by several apps). The first call to allocate a
worker for a given device wins; subsequent calls observe the existing
:persistent_term entry and skip. This matters because every
:persistent_term.put/2 triggers a global GC scan across every
process heap on the node — we do exactly two puts (CPU + GPU) over
the BEAM's lifetime.
GPU absence
On platforms where MLX cannot allocate a GPU stream (e.g. Linux without
Metal), EMLX.NIF.command_queue_new(:gpu) returns {:error, _} and
this module silently skips the GPU worker. Subsequent
EMLX.eval/1 calls on a GPU tensor will raise at use time with the
underlying :persistent_term ArgumentError.
Summary
Functions
Returns the application-default EMLX.CommandQueue NIF resource for
the given device.
Functions
@spec default_worker(:cpu | :gpu) :: reference()
Returns the application-default EMLX.CommandQueue NIF resource for
the given device.
Raises ArgumentError if no worker has been allocated for the device
(e.g. asking for :gpu on a system without Metal).
Never call :persistent_term.put/2 on the underlying key
({EMLX, :default_worker, device}) — overwriting a :persistent_term
value triggers a node-wide GC.