Goal
Ship the user-facing GPU path on the final launch substrate: compile @Gpu, marshal args, launch, join, writeback
Depends on: Issues 1–3 (context, memory/GpuPack, launch/join smoke).
Locked (do not reopen)
Vulkan compute + SPIR-V; no public DeviceBuffer
Launch -> join only; no mid-run Python sync
Binding convention: binding 0 = scalar SSBO, 1..N = lists
CB + fence stay per in-flight job (overlapping launches). Command pool is process-lifetime on Context
ShaderCache already owns pipelines/layouts
Todos
A: Launch substrate (new)
B: @Gpu emit
@Gpu decorator and registry (same idea as @Thread)
Validator: int, float, bool, list[float|int]; reject mid-run sync, dicts, locks, events, barriers, TBuffers, nested jobs
Emit compute SPIR-V: scalar std430 at binding 0, one binding per list
In-process GLSL->SPIR-V (shaderc) when CTHREADS_GPU is on
Disk cache by source, signature, compiler version
One parallelism model (e.g. gl_GlobalInvocationID over n) and stick to it
C: Public entry
Out of scope (later)
Empty-list dummy SSBOs, hash-keyed ShaderCache, disk VkPipelineCache (only if needed)
POD list[Threadable] + math (next issue)
Packaging / CI ship pass
Batch multi-dispatch, Mac, CPU->GPU launch
Acceptance
Overlapping launches work with shared pool + per-job CB/fence
User can @Gpu a simple list kernel and run it via gpu(...).join() with correct in-place list writeback
No public device-buffer API; clear errors when GPU not built / no device / bad types
Goal
Ship the user-facing GPU path on the final launch substrate: compile
@Gpu, marshal args, launch, join, writebackDepends on: Issues 1–3 (context, memory/GpuPack, launch/join smoke).
Locked (do not reopen)
DeviceBufferjoinonly; no mid-run Python syncTodos
A: Launch substrate (new)
Contextjoin(overlapping jobs stay correct)vkQueueSubmitwhen multiple host threads can launchB:
@Gpuemit@Gpudecorator and registry (same idea as@Thread)int,float,bool,list[float|int]; reject mid-run sync, dicts, locks, events, barriers, TBuffers, nested jobsstd430at binding 0, one binding per listCTHREADS_GPUis ongl_GlobalInvocationIDovern) and stick to itC: Public entry
gpu(fn, *args) -> GpuJob(Python wrapper over existing C++ launch/join)joinwriteback into the same Python lists (scalars if outputs); optionalresult()for scalar returns@Gpukernel only throughgpu()(lists mutated afterjoin)CTHREADS_GPUOut of scope (later)
VkPipelineCache(only if needed)list[Threadable]+ math (next issue)Acceptance
@Gpua simple list kernel and run it viagpu(...).join()with correct in-place list writeback