std::gpu
std::gpu is the public host-side API for pure-Silk GPU discovery, device
memory, streams, kernel launch, and synchronization. GPU-v1 mixed Linux x86_64
executables use the provider recorded in their bundle: AMDHSA through HIP or
NVIDIA PTX through the CUDA Driver API. Importing the module adds no link-time
HIP or CUDA dependency.
Exported API#
is_supported() -> boolreturns whether the bundled provider runtime can be opened and reports at least one device. It does not pre-load every embedded target artifact; target/device compatibility is verified when a named kernel is loaded for launch.device_count() -> intreturns the number of provider devices, or0when the provider is unavailable.current_device() -> intreturns the selected zero-based device index, or-1when no device is selected.select_device(index: int) -> intselects one enumerated device for new allocations, default-stream launches, and device-wide synchronization.last_error() -> stringreturns the runtime's borrowed diagnostic text for the most recent failed operation on the current process. A later GPU operation may overwrite the borrowed text.launch(kernel_name: string, grid_size: u64, workgroup_size: u64, ...args: u64) -> intpacks zero to 32 explicitu64kernel arguments, loads the named embedded kernel, validates the argument byte count recorded in the executable bundle, and enqueues a one-dimensional dispatch.grid_sizeis the total number of work items;grid_size / workgroup_sizeprovider blocks are used. Both values must be nonzero,grid_sizemust be divisible byworkgroup_size, andworkgroup_sizemust not exceed 1024.grid_sizemust not exceed4294967295, and the resulting block count must not exceed2147483647. The divisibility contract prevents unrequested trailing work items from escaping the requested buffer bounds; the work-item and block limits give every advertised provider the same exact one-dimensional geometry range.synchronize() -> intwaits for all previously submitted work on the selected device.DispatchResult { launch_status: int, synchronize_status: int }records the two independent statuses from one automatically completed dispatch.is_ok() -> boolis true only when both statuses are zero.launch_failed() -> boolis true whenlaunch_statusis nonzero.synchronize_failed() -> boolis true whensynchronize_statusis nonzero.launch_and_synchronize(kernel_name: string, grid_size: u64, workgroup_size: u64, ...args: u64) -> DispatchResultcallslaunch, then callssynchronizeexactly once even if launch failed, and returns both statuses. It is the public replaceable-stdlib operation behind checkedgpuforms.Buffer { address: u64, byte_len: u64, device_index: int }owns a provider device allocation and records its creation device.Buffer.alloc(byte_len) -> Bufferreturns an invalid zero-address buffer on failure.is_valid() -> boolreports whether the allocation succeeded.upload(host_address, byte_count) -> intcopies host memory to the start of the device allocation.download(host_address, byte_count) -> intcopies from the allocation to host memory.close() -> intreleases the allocation and invalidates the handle.drop()atomically releases a still-live allocation on its creation device during scope cleanup without changing the caller's selected device.Stream { handle: u64, device_index: int }owns one provider stream on the device selected when it was created.Stream.create() -> Streamreturns an invalid stream on failure.is_valid() -> boolreports whether the stream owns a runtime handle.synchronize() -> intwaits only for work in that stream.close() -> intreleases the stream and invalidates it.drop()atomically releases a still-live stream on its creation device during scope cleanup without changing the caller's selected device.launch_on(stream, kernel_name, grid_size, workgroup_size, ...args) -> intenqueues through an owning stream without changing the packed kernel ABI.
All status-returning operations use 0 for success and a nonzero failure
status. Call last_error() for diagnostic text; programs must not parse that
text for control flow.
The language-level
gpu (grid=..., workspace=...) { kernel(args...); } form resolves and checks
kernel at compile time, then dispatches through this module's
launch_and_synchronize implementation. Statement position discards its
DispatchResult; value position returns that result so launch and completion
failure can independently affect control flow without repeating a kernel-name
string. Separate manual launch and synchronize calls remain supported for
overlap and phase-local last_error() access. The checked form does not replace
buffer ownership, discovery, or last_error.
Buffer.upload_on(stream, host_address, byte_count) and
Buffer.download_on(stream, host_address, byte_count) enqueue asynchronous
copies on a stream owned by the same device. The caller synchronizes that
stream before reusing host storage or observing downloaded bytes. Every
explicit-stream operation requires a live nonzero Stream; an invalid stream
returns a nonzero status and never falls back to the default stream.
host_address is an explicit raw address. A caller may obtain it with the
normal Silk raw conversion for an array, slice, or struct whose lifetime covers
the copy. A device buffer's address may be passed as a u64 kernel argument.
The standard library packs arguments in declaration order, so applications do
not construct provider launch-argument memory or depend on a HIP/CUDA ABI.
Launch lifecycle#
- Build the executable with
--gpu-target. - Optionally call
is_supported()to handle machines without the bundled provider runtime or any reported device. A target mismatch remains an observable launch failure rather than an availability skip. - Allocate/copy any device buffers.
- Use a checked
gpuvalue or calllaunch_and_synchronizewhen automatic completion and both statuses are wanted. For explicit overlap, calllaunchwith the lexical kernel name and one trailingu64value per parameter. - After a manual launch, call
synchronizebefore observing results or releasing resources used by the dispatch.
The runtime caches loaded modules/functions for the process lifetime. Buffer ownership remains explicit and independent of that cache.
DispatchResult values are ordinary per-call values and remain stable when
other tasks use the GPU API. The initial bundled runtime state and
last_error() storage are process-global.
The shipped runtime serializes each public GPU operation with a process-wide
mutex, so launch blocks and manual calls may execute from multiple task-worker
threads without racing runtime initialization, allocation tracking, kernel
caching, or provider calls. Because launch and synchronization are distinct
operations, another task may submit work between them; synchronization waits
for all prior work on the selected device. The borrowed last_error() text may
still be overwritten after an operation returns, so programs must read it
before another task performs a GPU operation. Because automatic synchronization
is the later phase, last_error() after a checked block is not a durable copy
of an earlier launch diagnostic. Use launch_status for control flow; use the
separate manual calls when diagnostic text must be read between phases.
The shipped runtime accepts up to 64 reported provider devices and tracks up to
256 simultaneous live Buffer allocations, 128 streams, and 128 cached kernel
functions. Exceeding a bound returns a nonzero failure status and records a
diagnostic in last_error().
Errors and portability#
The shipped runtime rejects non-Linux hosts, a missing or incomplete selected HIP/CUDA provider library, no reported provider device, an executable without a valid Silk GPU bundle, an unknown kernel name, a target artifact that the selected device cannot load, invalid grid/work-group sizes, copies larger than the owning buffer, cross-device resource use, a launch argument byte count that does not match the kernel declaration, and errors returned by provider operations.
An alternative std:: package may implement this API using another runtime
without changing application imports. The compiler-owned bundle format and
attr(device=gpu) semantics remain the same.
See gpu execution for placement rules and gpu device for the semantic device-operation surface.
Source repository · Edit this page · View Markdown