Cuda

Explicit CUDA device-buffer API (Driver API wrapper). Separate from ``Gpu`` — never imported by ``@gpu``. ``ReadyBuffer`` and ``Pending`` are linear: every upload, kernel, sync, download, or discard must happen exactly once. Surface ``Float`` is CUDA float64 throughout. Narrative guide: ``docs/cuda.md``. HTML reference: ``aeon --doc libraries/Cuda.ae``. ── Opaque descriptors ───────────────────────────────────────────────── CUDA device handle. Selected by index or ``default_device``.
Imports
open Array;
Table of Contents

Types

Device

(type)
CUDA device handle. Selected by index or ``default_device``.
type Device

Launch1D

(type)
One-dimensional launch configuration: logical item count and block size.
type Launch1D

Launch2D

(type)
Two-dimensional launch configuration: width/height and block dims.
type Launch2D

Stream

(type)
CUDA stream for ordered kernel enqueue on one device.
type Stream

ReadyBuffer

(type) linear
Device allocation ready for kernels, download, or ``free``.
linear type ReadyBuffer a

Pending

(type) linear
In-flight kernel output; promote with ``synchronize`` or abandon with ``discard``.
linear type Pending a

I32Download

(type) linear
Linear download token: host snapshot plus the live device buffer it was read from.
linear type I32Download

Float64Download

(type) linear
linear type Float64Download

I32DownloadPair

(type)
Unrestricted pair after ``unpack_*`` (values + buffer projections).
type I32DownloadPair

Float64DownloadPair

(type)
type Float64DownloadPair

Status

(type) linear
Linear completion token; must be ``check_ok`` or ``discard_status``.
linear type Status

StatusBuffer

(type) linear
Linear pair from ``synchronize_with_status`` (status + optional ready buffer).
linear type StatusBuffer a

StatusPair

(type)
Unrestricted pair after unpacking a ``StatusBuffer``.
type StatusPair a

Functions

mem_kind_device

def mem_kind_device : Int

mem_kind_host_pinned

def mem_kind_host_pinned : Int

mem_kind_managed

def mem_kind_managed : Int

mem_kind_host

def mem_kind_host : Int

access_read_only

def access_read_only : Int

access_read_write

def access_read_write : Int

num_devices

Number of visible CUDA devices.
def num_devices (_ : Unit) : {n : Int | n > 0}

device

Select a device by zero-based index.
def device (id : Int | id ≥ 0 && id < num_devices unit) : { d : Device | device_id d = id && (max_threads_per_block d ≥ 1024 && (warp_size d = 32 && max_shared_mem_per_block d ≥ 0)) }

default_device

Default CUDA device (device 0 when present).
def default_device (_ : Unit) : { d : Device | device_id d ≥ 0 && (max_threads_per_block d ≥ 1024 && (warp_size d = 32 && max_shared_mem_per_block d ≥ 0)) }

default_stream

Default stream on ``device``.
def default_stream (device : Device) : {stream : Stream | stream_device stream = device_id device}

launch_1d

Describe a non-empty 1-D launch on ``device`` with zero shared memory.
def launch_1d (device : Device) (items : Int | items > 0) (threads : Int | threads > 0 && (threads ≤ items && (threads ≤ max_threads_per_block device && threads ≤ 1024))) : { launch : Launch1D | launch_device launch = device_id device && ( launch_items launch = items && ( launch_threads launch = threads && (launch_grid_size launch * launch_threads launch ≥ launch_items launch && launch_shared_bytes launch = 0) ) ) }

launch_1d_shared

Like ``launch_1d`` but records a shared-memory budget for the block.
def launch_1d_shared (device : Device) (items : Int | items > 0) (threads : Int | threads > 0 && (threads ≤ items && (threads ≤ max_threads_per_block device && threads ≤ 1024))) (shared : Int | shared ≥ 0 && shared ≤ max_shared_mem_per_block device) : { launch : Launch1D | launch_device launch = device_id device && ( launch_items launch = items && ( launch_threads launch = threads && (launch_grid_size launch * launch_threads launch ≥ launch_items launch && launch_shared_bytes launch = shared) ) ) }

launch_1d_warped

Like ``launch_1d`` but requires warp-aligned block size (or a single-warp launch).
def launch_1d_warped (device : Device) (items : Int | items > 0) ( threads : Int | threads > 0 && ( threads ≤ items && ( threads ≤ max_threads_per_block device && (threads ≤ 1024 && (threads ≤ warp_size device || threads % warp_size device = 0)) ) ) ) : { launch : Launch1D | launch_device launch = device_id device && ( launch_items launch = items && ( launch_threads launch = threads && (launch_grid_size launch * launch_threads launch ≥ launch_items launch && launch_shared_bytes launch = 0) ) ) }

launch_2d

Describe a non-empty 2-D launch whose grid covers ``width`` × ``height``.
def launch_2d (device : Device) (width : Int | width > 0) (height : Int | height > 0) (tx : Int | tx > 0 && tx ≤ 1024) (ty : Int | ty > 0 && (ty ≤ 1024 && (tx * ty ≤ max_threads_per_block device && tx * ty ≤ 1024))) : { launch : Launch2D | launch2d_device launch = device_id device && ( launch2d_width launch = width && ( launch2d_height launch = height && ( launch2d_threads_x launch = tx && ( launch2d_threads_y launch = ty && ( launch2d_grid_x launch * launch2d_threads_x launch ≥ launch2d_width launch && (launch2d_grid_y launch * launch2d_threads_y launch ≥ launch2d_height launch && launch2d_shared_bytes launch = 0) ) ) ) ) ) }

launch_2d_shared

Like ``launch_2d`` with a shared-memory budget.
def launch_2d_shared (device : Device) (width : Int | width > 0) (height : Int | height > 0) (tx : Int | tx > 0 && tx ≤ 1024) (ty : Int | ty > 0 && (ty ≤ 1024 && (tx * ty ≤ max_threads_per_block device && tx * ty ≤ 1024))) (shared : Int | shared ≥ 0 && shared ≤ max_shared_mem_per_block device) : { launch : Launch2D | launch2d_device launch = device_id device && ( launch2d_width launch = width && ( launch2d_height launch = height && ( launch2d_threads_x launch = tx && ( launch2d_threads_y launch = ty && ( launch2d_grid_x launch * launch2d_threads_x launch ≥ launch2d_width launch && (launch2d_grid_y launch * launch2d_threads_y launch ≥ launch2d_height launch && launch2d_shared_bytes launch = shared) ) ) ) ) ) }

upload_i32

Upload a non-empty ``Int`` array; consumes the host buffer.
def upload_i32 (device : Device) (1 values : Array Int | Array.size values > 0) : { buffer : ReadyBuffer Int | buffer_device buffer = device_id device && ( buffer_size buffer = Array.size values && ( buffer_elem_size buffer = 4 && ( buffer_bytes buffer = buffer_size buffer * buffer_elem_size buffer && ( buffer_bytes buffer ≤ max_allocation device && ( buffer_mem_kind buffer = mem_kind_device && ( buffer_access buffer = access_read_write && (buffer_extent_x buffer = buffer_size buffer && buffer_extent_y buffer = 1) ) ) ) ) ) ) }

upload_float64

Upload a non-empty ``Float`` array as float64; consumes the host buffer.
def upload_float64 (device : Device) (1 values : Array Float | Array.size values > 0) : { buffer : ReadyBuffer Float | buffer_device buffer = device_id device && ( buffer_size buffer = Array.size values && ( buffer_elem_size buffer = 8 && ( buffer_bytes buffer = buffer_size buffer * buffer_elem_size buffer && ( buffer_bytes buffer ≤ max_allocation device && ( buffer_mem_kind buffer = mem_kind_device && ( buffer_access buffer = access_read_write && (buffer_extent_x buffer = buffer_size buffer && buffer_extent_y buffer = 1) ) ) ) ) ) ) }

as_read_only

Transfer a ready buffer into a read-only view of the same allocation.
def as_read_only (1 buffer : ReadyBuffer a) : { r : ReadyBuffer a | buffer_device r = buffer_device buffer && ( buffer_size r = buffer_size buffer && ( buffer_elem_size r = buffer_elem_size buffer && ( buffer_bytes r = buffer_bytes buffer && ( buffer_mem_kind r = buffer_mem_kind buffer && ( buffer_access r = access_read_only && (buffer_extent_x r = buffer_extent_x buffer && buffer_extent_y r = buffer_extent_y buffer) ) ) ) ) ) }

add_i32

Elementwise ``Int`` vector add on ``launch``'s device via ``stream``. left, right: equal-sized device buffers on the launch device (RO or RW).
def add_i32 (launch : Launch1D) (stream : Stream | stream_device stream = launch_device launch) ( 1 left : ReadyBuffer Int | buffer_size left > 0 && ( buffer_elem_size left = 4 && ( buffer_device left = launch_device launch && ( buffer_size left = launch_items launch && ( buffer_mem_kind left = mem_kind_device && ( (buffer_access left = access_read_only || buffer_access left = access_read_write) && launch_grid_size launch * launch_threads launch ≥ buffer_size left ) ) ) ) ) ) ( 1 right : ReadyBuffer Int | buffer_size right = buffer_size left && ( buffer_elem_size right = buffer_elem_size left && ( buffer_device right = buffer_device left && ( buffer_mem_kind right = mem_kind_device && (buffer_access right = access_read_only || buffer_access right = access_read_write) ) ) ) ) : { pending : Pending Int | pending_device pending = launch_device launch && (pending_size pending = launch_items launch && pending_stream pending = stream_id stream) }

add_float64

Elementwise ``Float`` (float64) vector add; same size/device/kind rules as ``add_i32``.
def add_float64 (launch : Launch1D) (stream : Stream | stream_device stream = launch_device launch) ( 1 left : ReadyBuffer Float | buffer_size left > 0 && ( buffer_elem_size left = 8 && ( buffer_device left = launch_device launch && ( buffer_size left = launch_items launch && ( buffer_mem_kind left = mem_kind_device && ( (buffer_access left = access_read_only || buffer_access left = access_read_write) && launch_grid_size launch * launch_threads launch ≥ buffer_size left ) ) ) ) ) ) ( 1 right : ReadyBuffer Float | buffer_size right = buffer_size left && ( buffer_elem_size right = buffer_elem_size left && ( buffer_device right = buffer_device left && ( buffer_mem_kind right = mem_kind_device && (buffer_access right = access_read_only || buffer_access right = access_read_write) ) ) ) ) : { pending : Pending Float | pending_device pending = launch_device launch && (pending_size pending = launch_items launch && pending_stream pending = stream_id stream) }

synchronize

Block until ``pending`` completes; recover a RW device ``ReadyBuffer``.
def synchronize (1 pending : Pending a) : { buffer : ReadyBuffer a | buffer_device buffer = pending_device pending && ( buffer_size buffer = pending_size pending && ( buffer_bytes buffer = buffer_size buffer * buffer_elem_size buffer && ( buffer_mem_kind buffer = mem_kind_device && ( buffer_access buffer = access_read_write && (buffer_extent_x buffer = buffer_size buffer && buffer_extent_y buffer = 1) ) ) ) ) }

synchronize_with_status

Like ``synchronize`` but returns a linear status token paired with the buffer.
def synchronize_with_status (1 pending : Pending a) : { sb : StatusBuffer a | status_buffer_ok sb && (status_buffer_device sb = pending_device pending && status_buffer_size sb = pending_size pending) }

unpack_status_buffer

Unpack a successful ``StatusBuffer`` into an unrestricted status/buffer pair.
def unpack_status_buffer (1 sb : StatusBuffer a | status_buffer_ok sb) : { pair : StatusPair a | status_pair_ok pair && (status_pair_device pair = status_buffer_device sb && status_pair_size pair = status_buffer_size sb) }

status_pair_status

Status half of an unpacked pair (still linear — check or discard).
def status_pair_status (p : StatusPair a | status_pair_ok p) : {s : Status | status_is_ok s}

status_pair_buffer

Ready buffer half of an unpacked ok pair.
def status_pair_buffer (p : StatusPair a | status_pair_ok p) : { b : ReadyBuffer a | buffer_device b = status_pair_device p && ( buffer_size b = status_pair_size p && ( buffer_mem_kind b = mem_kind_device && (buffer_access b = access_read_write && (buffer_extent_x b = buffer_size b && buffer_extent_y b = 1)) ) ) }

check_ok

Consume an ok status (runtime no-op when refinements already prove success).
def check_ok (1 s : Status | status_is_ok s) : Unit

discard_status

Explicitly discard a status without checking.
def discard_status (1 s : Status) : Unit

download_i32

Copy device ``Int`` data to a fresh host array; consumes ``buffer``.
def download_i32 (1 buffer : ReadyBuffer Int) : { result : I32Download | i32_download_device result = buffer_device buffer && i32_download_size result = buffer_size buffer }

download_float64

Copy device float64 data to a fresh host array; consumes ``buffer``.
def download_float64 (1 buffer : ReadyBuffer Float) : { result : Float64Download | float64_download_device result = buffer_device buffer && float64_download_size result = buffer_size buffer }

unpack_i32_download

Split ``I32Download`` into an unrestricted pair (values tuple + buffer).
def unpack_i32_download (1 p : I32Download) : { pair : I32DownloadPair | i32_download_pair_device pair = i32_download_device p && i32_download_pair_size pair = i32_download_size p }

unpack_float64_download

Split ``Float64Download`` into an unrestricted pair.
def unpack_float64_download (1 p : Float64Download) : { pair : Float64DownloadPair | float64_download_pair_device pair = float64_download_device p && float64_download_pair_size pair = float64_download_size p }

download_values_i32

Host snapshot from an ``I32DownloadPair`` (linear ``Array Int``).
def download_values_i32 (p : I32DownloadPair) : {xs : Array Int | Array.size xs = i32_download_pair_size p}

download_buffer_i32

Live GPU buffer from an ``I32DownloadPair``; ``free`` when done.
def download_buffer_i32 (p : I32DownloadPair) : { b : ReadyBuffer Int | buffer_device b = i32_download_pair_device p && ( buffer_size b = i32_download_pair_size p && ( buffer_elem_size b = 4 && ( buffer_bytes b = buffer_size b * buffer_elem_size b && ( buffer_mem_kind b = mem_kind_device && (buffer_access b = access_read_write && (buffer_extent_x b = buffer_size b && buffer_extent_y b = 1)) ) ) ) ) }

download_values_float64

Host snapshot from a ``Float64DownloadPair``.
def download_values_float64 (p : Float64DownloadPair) : {xs : Array Float | Array.size xs = float64_download_pair_size p}

download_buffer_float64

Live GPU buffer from a ``Float64DownloadPair``.
def download_buffer_float64 (p : Float64DownloadPair) : { b : ReadyBuffer Float | buffer_device b = float64_download_pair_device p && ( buffer_size b = float64_download_pair_size p && ( buffer_elem_size b = 8 && ( buffer_bytes b = buffer_size b * buffer_elem_size b && ( buffer_mem_kind b = mem_kind_device && (buffer_access b = access_read_write && (buffer_extent_x b = buffer_size b && buffer_extent_y b = 1)) ) ) ) ) }

free

Release a completed device allocation.
def free (1 buffer : ReadyBuffer a) : Unit

discard

Abandon in-flight work without reading results.
def discard (1 pending : Pending a) : Unit

Uninterpreted

Functions declared as def f ... = uninterpreted: only their signature is known to the verifier; they have no body.

device_id

uninterpreted
def device_id : (d : Device) → Int

num_devices

uninterpreted
def num_devices : (_ : Unit) → Int

max_threads_per_block

uninterpreted
def max_threads_per_block : (d : Device) → Int

max_allocation

uninterpreted
def max_allocation : (d : Device) → Int

warp_size

uninterpreted
def warp_size : (d : Device) → Int

max_shared_mem_per_block

uninterpreted
def max_shared_mem_per_block : (d : Device) → Int

launch_device

uninterpreted
def launch_device : (launch : Launch1D) → Int

launch_items

uninterpreted
def launch_items : (launch : Launch1D) → Int

launch_threads

uninterpreted
def launch_threads : (launch : Launch1D) → Int

launch_grid_size

uninterpreted
def launch_grid_size : (launch : Launch1D) → Int

launch_shared_bytes

uninterpreted
def launch_shared_bytes : (launch : Launch1D) → Int

launch2d_device

uninterpreted
def launch2d_device : (launch : Launch2D) → Int

launch2d_width

uninterpreted
def launch2d_width : (launch : Launch2D) → Int

launch2d_height

uninterpreted
def launch2d_height : (launch : Launch2D) → Int

launch2d_threads_x

uninterpreted
def launch2d_threads_x : (launch : Launch2D) → Int

launch2d_threads_y

uninterpreted
def launch2d_threads_y : (launch : Launch2D) → Int

launch2d_grid_x

uninterpreted
def launch2d_grid_x : (launch : Launch2D) → Int

launch2d_grid_y

uninterpreted
def launch2d_grid_y : (launch : Launch2D) → Int

launch2d_shared_bytes

uninterpreted
def launch2d_shared_bytes : (launch : Launch2D) → Int

stream_device

uninterpreted
def stream_device : (stream : Stream) → Int

stream_id

uninterpreted
def stream_id : (stream : Stream) → Int

pending_stream

uninterpreted
def pending_stream : (pending : Pending a) → Int

buffer_device

uninterpreted
def buffer_device : (buffer : ReadyBuffer a) → Int

buffer_size

uninterpreted
def buffer_size : (buffer : ReadyBuffer a) → Int

buffer_elem_size

uninterpreted
def buffer_elem_size : (buffer : ReadyBuffer a) → Int

buffer_bytes

uninterpreted
def buffer_bytes : (buffer : ReadyBuffer a) → Int

buffer_mem_kind

uninterpreted
def buffer_mem_kind : (buffer : ReadyBuffer a) → Int

buffer_access

uninterpreted
def buffer_access : (buffer : ReadyBuffer a) → Int

buffer_extent_x

uninterpreted
def buffer_extent_x : (buffer : ReadyBuffer a) → Int

buffer_extent_y

uninterpreted
def buffer_extent_y : (buffer : ReadyBuffer a) → Int

pending_device

uninterpreted
def pending_device : (pending : Pending a) → Int

pending_size

uninterpreted
def pending_size : (pending : Pending a) → Int

i32_download_device

uninterpreted
def i32_download_device : (p : I32Download) → Int

i32_download_size

uninterpreted
def i32_download_size : (p : I32Download) → Int

i32_download_pair_device

uninterpreted
def i32_download_pair_device : (p : I32DownloadPair) → Int

i32_download_pair_size

uninterpreted
def i32_download_pair_size : (p : I32DownloadPair) → Int

float64_download_device

uninterpreted
def float64_download_device : (p : Float64Download) → Int

float64_download_size

uninterpreted
def float64_download_size : (p : Float64Download) → Int

float64_download_pair_device

uninterpreted
def float64_download_pair_device : (p : Float64DownloadPair) → Int

float64_download_pair_size

uninterpreted
def float64_download_pair_size : (p : Float64DownloadPair) → Int

status_is_ok

uninterpreted
def status_is_ok : (s : Status) → Bool

status_code

uninterpreted
def status_code : (s : Status) → Int

status_buffer_ok

uninterpreted
def status_buffer_ok : (sb : StatusBuffer a) → Bool

status_buffer_device

uninterpreted
def status_buffer_device : (sb : StatusBuffer a) → Int

status_buffer_size

uninterpreted
def status_buffer_size : (sb : StatusBuffer a) → Int

status_pair_ok

uninterpreted
def status_pair_ok : (p : StatusPair a) → Bool

status_pair_device

uninterpreted
def status_pair_device : (p : StatusPair a) → Int

status_pair_size

uninterpreted
def status_pair_size : (p : StatusPair a) → Int