pub trait Accelerator {
type Context;
type Buffer;
type Program;
type Queue;
type Event;
Show 15 methods
// Required methods
fn device_info(&self) -> Result<DeviceInfo, BackendError>;
fn create_context(
&self,
desc: ContextDesc,
) -> Result<Self::Context, BackendError>;
fn destroy_context(
&self,
context: Self::Context,
) -> Result<(), ReleaseFailure<Self::Context>>;
fn allocate_buffer(
&self,
context: &Self::Context,
desc: BufferDesc,
) -> Result<AllocatedBuffer<Self::Buffer>, BackendError>;
fn write_buffer(
&self,
buffer: &mut Self::Buffer,
offset: u64,
data: &dyn ByteSource,
) -> Result<(), BackendError>;
fn read_buffer(
&self,
buffer: &Self::Buffer,
offset: u64,
data: &mut dyn ByteSink,
) -> Result<(), BackendError>;
fn free_buffer(
&self,
buffer: Self::Buffer,
) -> Result<(), ReleaseFailure<Self::Buffer>>;
fn load_program(
&self,
context: &Self::Context,
artifact: ArtifactRef<'_>,
) -> Result<Self::Program, BackendError>;
fn unload_program(
&self,
program: Self::Program,
) -> Result<(), ReleaseFailure<Self::Program>>;
fn create_queue(
&self,
context: &Self::Context,
desc: QueueDesc,
) -> Result<Self::Queue, BackendError>;
fn destroy_queue(
&self,
queue: Self::Queue,
) -> Result<(), ReleaseFailure<Self::Queue>>;
fn submit(
&self,
queue: &Self::Queue,
program: &Self::Program,
bindings: &[BindingRef<'_, Self::Buffer>],
timeout: Timeout,
) -> Result<Self::Event, SubmitFailure<Self::Event>>;
fn poll_event(
&self,
event: &Self::Event,
) -> Result<EventState, BackendError>;
fn destroy_event(
&self,
event: Self::Event,
) -> Result<(), ReleaseFailure<Self::Event>>;
// Provided method
fn cancel_event(&self, _event: &Self::Event) -> Result<(), BackendError> { ... }
}Expand description
Native accelerator lifecycle over provider-owned handle types.
The reference command engine is generic over this trait, so its calls are statically dispatched
and native handles need no boxing. The trait imposes no Send or Sync bounds: a provider may
preserve thread-affine handles, while a provider that opts into those auto traits must make the
corresponding shared calls safe. Callers must not overlap a mutable borrow, a consumed handle,
or destruction with another use of the same resource.
Borrowed arguments are valid only for the duration of a call and must not be retained as Rust
references. Destructive methods consume handles. A caller must reject parent destruction while
child objects or in-flight events still exist; it must not use Drop timing as lifecycle state.
The only operations that explicitly transfer buffer contents are Self::write_buffer and
Self::read_buffer. Allocation, submission, polling, and release must not hide full-range
staging copies. In particular, submit binds the exact provider allocation directly or rejects
it as BackendError::Incompatible.
Dynamic loading, a stable binary interface, and erased cross-boundary handle ownership are not defined here. An integration that needs dynamic dispatch must fix one concrete handle family in an adapter without weakening this trait’s borrowing, acceptance, or release contracts.
Required Associated Types§
Sourcetype Context
type Context
Owned context handle. It may be a native value and need not be boxed, cloneable, or thread safe.
Sourcetype Buffer
type Buffer
Owned handle for the exact allocation described by its accompanying BufferInfo.
Required Methods§
Sourcefn device_info(&self) -> Result<DeviceInfo, BackendError>
fn device_info(&self) -> Result<DeviceInfo, BackendError>
Return immutable identity, capability, and limit metadata.
- Ownership/lifetime: no ownership changes; a successful value must remain stable for the lifetime of this backend instance.
- Progress/concurrency: discovery may perform bounded synchronous provider work but must
not wait for resource progress. Concurrent calls are permitted only when the concrete
backend is
Sync. - Failure/retry: an error creates no resource and may be retried; callers validate and cache the first successful result before invoking resource methods.
- Allocation/copies: the call must not allocate resource backing or copy bulk content.
Sourcefn create_context(
&self,
desc: ContextDesc,
) -> Result<Self::Context, BackendError>
fn create_context( &self, desc: ContextDesc, ) -> Result<Self::Context, BackendError>
Create one context from prevalidated intent.
- Ownership/lifetime:
descis consumed by value and not retained by reference; success returns one owned context. All current nonempty context flags are unsupported. - Progress/concurrency: provider setup may synchronously block, but must not wait for unrelated resource progress. Independent creation may overlap only when concrete types permit it.
- Failure/retry:
Errguarantees that no context resource was retained and the request may be retried. - Allocation/copies: context bookkeeping may be allocated; no buffer content is copied.
Sourcefn destroy_context(
&self,
context: Self::Context,
) -> Result<(), ReleaseFailure<Self::Context>>
fn destroy_context( &self, context: Self::Context, ) -> Result<(), ReleaseFailure<Self::Context>>
Destroy an empty context.
- Ownership/lifetime: the handle is consumed and must have no live child resources.
- Progress/concurrency: release may synchronously block, but must not wait for children or in-flight work; no use of this context may overlap the call.
- Failure/retry:
ReleaseFailure::Rejectedreturns the live handle for retry;ReleaseFailure::Indeterminateinvalidates it and forbids retry. - Allocation/copies: the call releases provider bookkeeping and copies no content.
Sourcefn allocate_buffer(
&self,
context: &Self::Context,
desc: BufferDesc,
) -> Result<AllocatedBuffer<Self::Buffer>, BackendError>
fn allocate_buffer( &self, context: &Self::Context, desc: BufferDesc, ) -> Result<AllocatedBuffer<Self::Buffer>, BackendError>
Allocate one exact provider-owned buffer backing.
- Ownership/lifetime:
contextis borrowed only for this call. Success returns an owned handle plus metadata for the actual backing; neither may borrowcontext. - Progress/concurrency: allocation may synchronously block. Independent contexts may be used concurrently only when the concrete backend and handles permit it.
- Failure/retry:
Errguarantees that no buffer backing was retained and may be retried. - Allocation/copies: this is the buffer-allocation boundary. Program-visible requests allocate directly bindable backing here or fail; they must not reserve a submission-time bounce allocation or copy buffer content.
Sourcefn write_buffer(
&self,
buffer: &mut Self::Buffer,
offset: u64,
data: &dyn ByteSource,
) -> Result<(), BackendError>
fn write_buffer( &self, buffer: &mut Self::Buffer, offset: u64, data: &dyn ByteSource, ) -> Result<(), BackendError>
Perform one explicit host-to-buffer transfer.
- Ownership/lifetime:
bufferis exclusively borrowed anddatais borrowed only for this call. The provider must not retain either reference. - Progress/concurrency: the call may synchronously block until the explicit transfer is complete. The exclusive buffer borrow prevents overlapping access without forcing interior synchronization; unrelated buffers may progress when concrete types permit it.
- Failure/retry: on
Err, the requested range may be partially modified but the handle remains live. A later successful full-range write replaces it; device loss is not retryable on the same backend instance. - Allocation/copies: this is an explicit content-copy boundary. Segmented input should flow into final backing without frame-sized coalescing. Device-local backing may use bounded temporary staging during this call.
Sourcefn read_buffer(
&self,
buffer: &Self::Buffer,
offset: u64,
data: &mut dyn ByteSink,
) -> Result<(), BackendError>
fn read_buffer( &self, buffer: &Self::Buffer, offset: u64, data: &mut dyn ByteSink, ) -> Result<(), BackendError>
Perform one explicit buffer-to-host transfer.
- Ownership/lifetime:
bufferis shared-borrowed anddatais exclusively borrowed only for this call. The provider must not retain either reference. - Progress/concurrency: the call may synchronously block until the explicit transfer is
complete. Shared reads may overlap only when the concrete buffer is
Syncand the provider supports that access. - Failure/retry:
Errleaves the destination potentially partially initialized; the caller must not publish it. The buffer is unchanged and a complete read may be retried unless the backend is lost.Ok(())guarantees every destination byte was initialized. - Allocation/copies: this is an explicit content-copy boundary. The provider should write directly across segmented destinations; device-local backing may use bounded temporary staging during this call.
Sourcefn free_buffer(
&self,
buffer: Self::Buffer,
) -> Result<(), ReleaseFailure<Self::Buffer>>
fn free_buffer( &self, buffer: Self::Buffer, ) -> Result<(), ReleaseFailure<Self::Buffer>>
Release an unreferenced buffer and its exact backing allocation.
- Ownership/lifetime: the handle is consumed and must not be bound to an in-flight event.
- Progress/concurrency: release may synchronously block but must not wait for references to disappear; no access to this buffer may overlap the call.
- Failure/retry: rejected release returns the live handle for retry; indeterminate release invalidates it and requires recovery.
- Allocation/copies: backing is deallocated without copying its contents or allocating a replacement.
Sourcefn load_program(
&self,
context: &Self::Context,
artifact: ArtifactRef<'_>,
) -> Result<Self::Program, BackendError>
fn load_program( &self, context: &Self::Context, artifact: ArtifactRef<'_>, ) -> Result<Self::Program, BackendError>
Create a resident program from an opaque, possibly segmented artifact.
- Ownership/lifetime:
context,artifact.payload, and the envelope are borrowed only for this call. Success returns an owned program with no source borrow. - Progress/concurrency: program creation may synchronously block. Independent lifecycle work may overlap only when the concrete backend and context permit it.
- Failure/retry:
Errguarantees that no program resource was retained and may be retried with a still-live context and artifact. - Allocation/copies: resident program storage may be allocated but all storage retained
by the returned handle must fit
artifact.resident_bytes. Segmented bytes should stream into final resident storage rather than require one artifact-sized coalescing copy.
Sourcefn unload_program(
&self,
program: Self::Program,
) -> Result<(), ReleaseFailure<Self::Program>>
fn unload_program( &self, program: Self::Program, ) -> Result<(), ReleaseFailure<Self::Program>>
Release an unreferenced resident program.
- Ownership/lifetime: the program is consumed and must not be referenced by an event.
- Progress/concurrency: release may synchronously block but must not wait for in-flight references; no use of this program may overlap the call.
- Failure/retry: rejected release returns the live handle for retry; indeterminate release invalidates it and requires recovery.
- Allocation/copies: resident storage is released without copying buffer contents or allocating replacement state.
Sourcefn create_queue(
&self,
context: &Self::Context,
desc: QueueDesc,
) -> Result<Self::Queue, BackendError>
fn create_queue( &self, context: &Self::Context, desc: QueueDesc, ) -> Result<Self::Queue, BackendError>
Create one accelerator execution queue.
- Ownership/lifetime:
contextis borrowed only for this call and success returns an owned queue. All current nonempty queue flags are unsupported. - Progress/concurrency: queue setup may synchronously block. Independent creation may overlap only when concrete types permit it.
- Failure/retry:
Errguarantees that no queue resource was retained and may be retried. - Allocation/copies: queue bookkeeping may be allocated; no program or buffer content is copied.
Sourcefn destroy_queue(
&self,
queue: Self::Queue,
) -> Result<(), ReleaseFailure<Self::Queue>>
fn destroy_queue( &self, queue: Self::Queue, ) -> Result<(), ReleaseFailure<Self::Queue>>
Release an unreferenced execution queue.
- Ownership/lifetime: the queue is consumed and must not be referenced by an event.
- Progress/concurrency: release may synchronously block but must not wait for submitted work; no use of this queue may overlap the call.
- Failure/retry: rejected release returns the live handle for retry; indeterminate release invalidates it and requires recovery.
- Allocation/copies: queue state is released without copying buffer content or allocating replacement state.
Sourcefn submit(
&self,
queue: &Self::Queue,
program: &Self::Program,
bindings: &[BindingRef<'_, Self::Buffer>],
timeout: Timeout,
) -> Result<Self::Event, SubmitFailure<Self::Event>>
fn submit( &self, queue: &Self::Queue, program: &Self::Program, bindings: &[BindingRef<'_, Self::Buffer>], timeout: Timeout, ) -> Result<Self::Event, SubmitFailure<Self::Event>>
Attempt to admit one program execution and return its event.
Hosts must reject an AccessMode incompatible with each buffer’s BufferUsage before
calling this method (see BindingRef::validate_for_submit). Providers may repeat the check
as defense in depth, but host-side rejection is required by Wire ABI section 4.4.
- Ownership/lifetime: queue, program, buffers, and the binding slice are borrowed only during admission and must not be retained as Rust references. The caller keeps every referenced handle alive until the returned event is terminal and destroyed.
- Progress/concurrency: synchronous work is limited to validation and admission; the call
must not wait for execution to finish. Concurrent submission requires concrete
Synchandles and provider support; the trait requires no lock or atomic operation by itself. - Failure/retry:
SubmitFailure::Rejectedguarantees no acceptance and permits retry. Success orSubmitFailure::Indeterminatetransfers invocation ownership to the event and must not be retried as though rejected. - Allocation/copies: the borrowed slice requires no per-binding box or owned mirror. Providers may use amortized event storage, but must directly bind each exact allocation and reject incompatibility instead of allocating or copying through hidden bounce buffers.
Sourcefn poll_event(&self, event: &Self::Event) -> Result<EventState, BackendError>
fn poll_event(&self, event: &Self::Event) -> Result<EventState, BackendError>
Observe event state without blocking or driving an executor.
- Ownership/lifetime: the event is borrowed only for this call and remains live.
- Progress/concurrency: polling is bounded, nonblocking, and safe to race with provider
completion when the concrete event is
Sync. - Failure/retry: errors do not make an event terminal; polling may be retried unless the backend is lost. Once observed, a terminal state is stable across every later success.
- Allocation/copies: polling allocates no per-call state and copies no bulk content.
Sourcefn destroy_event(
&self,
event: Self::Event,
) -> Result<(), ReleaseFailure<Self::Event>>
fn destroy_event( &self, event: Self::Event, ) -> Result<(), ReleaseFailure<Self::Event>>
Release one terminal event and its provider invocation state.
- Ownership/lifetime: the event is consumed. Every referenced queue, program, and buffer must remain live until this release succeeds or becomes indeterminate.
- Progress/concurrency: release may synchronously block but must not wait for a pending event to finish; no poll or cancellation may overlap this call.
- Failure/retry: rejected release returns the live event for retry; indeterminate release invalidates it and requires recovery.
- Allocation/copies: invocation state is released without copying buffer content or allocating replacement state.
Provided Methods§
Sourcefn cancel_event(&self, _event: &Self::Event) -> Result<(), BackendError>
fn cancel_event(&self, _event: &Self::Event) -> Result<(), BackendError>
Attempt to make a pending event terminal as EventState::Cancelled.
- Ownership/lifetime: the event is borrowed only for this call and remains live.
- Progress/concurrency: cancellation is bounded and nonblocking. It may race with completion; the provider chooses exactly one terminal result without requiring a lock in the handle contract.
- Failure/retry:
Ok(())means cancellation won.BackendError::Busymeans completion won and the caller should poll. The defaultUnsupportedimplementation is conformant only whenCapabilities::EVENT_CANCELLATIONis absent. - Allocation/copies: cancellation allocates no per-call state and copies no bulk content.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".