Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions API_DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ model rather than pretending to be reference-counted like OpenCL.

## Delivery slices

1. Typed errors, platform/device discovery, and string information helpers.
1. Typed errors, platform/device discovery and string information helpers.
2. Context and command-queue ownership. (Implemented.)
3. Typed buffers and bounds-checked blocking transfer helpers. (Implemented.)
4. Program compilation with build logs and scalar, slice, and buffer kernel argument helpers. (Implemented.)
5. Owned events, wait lists, profiling, markers, barriers, and asynchronous 1D/2D/3D buffer/kernel operations. (Implemented.)
4. Program compilation with build logs and scalar, slice and buffer kernel argument helpers. (Implemented.)
5. Owned events, wait lists, profiling, markers, barriers and asynchronous 1D/2D/3D buffer/kernel operations. (Implemented.)
6. Optional extension capability objects and device UUID helpers. (Implemented.)
7. Platform-specific external-memory and external-semaphore loaders, opaque-FD imports, ownership handoffs, and owned imported semaphores. (Implemented.)
8. Typed two-dimensional images, owned samplers, and typed shared virtual memory with explicit host/device synchronization. (Implemented.)
7. Platform-specific external-memory and external-semaphore loaders, opaque-FD imports, ownership handoffs and owned imported semaphores. (Implemented.)
8. Typed two-dimensional images, owned samplers and typed shared virtual memory with explicit host/device synchronization. (Implemented.)

## Ecosystem boundary

This package provides Khronos-registry bindings and thin, explicit resource-management
helpers. Higher-level numerical operations, tensor APIs, and cross-backend compute dispatch
helpers. Higher-level numerical operations, tensor APIs and cross-backend compute dispatch
belong in the V Scientific Library's established [`vsl.vcl`](https://github.com/vlang/vsl/tree/main/vcl)
and [`vsl.compute`](https://github.com/vlang/vsl/tree/main/compute) layers. New work in those
areas should integrate with and be coordinated through VSL rather than creating a competing
Expand Down
10 changes: 5 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
provide explicit `clone_ref()` operations backed by the corresponding native
retain calls. SVM allocations remain uniquely owned because OpenCL provides
no retain operation for them.
- Return owned pointers from constructors, asynchronous operations, and
- Return owned pointers from constructors, asynchronous operations and
`clone_ref()` so owners cross module boundaries without hidden copies on
released V and strict V3.
- Pin Vulkan and GLFW example dependencies to immutable revisions in CI rather
Expand All @@ -22,9 +22,9 @@

## 0.4.0

- Add owned typed 2D images with format-size validation, bounds-checked blocking and asynchronous transfers, supported-format discovery, and typed kernel arguments.
- Add owned typed 2D images with format-size validation, bounds-checked blocking and asynchronous transfers, supported-format discovery and typed kernel arguments.
- Add owned samplers and typed sampler kernel arguments.
- Add owned typed shared virtual memory with capability discovery, checked allocation and transfers, coarse-grained map/unmap operations, and typed kernel arguments.
- Add owned typed shared virtual memory with capability discovery, checked allocation and transfers, coarse-grained map/unmap operations and typed kernel arguments.
- Add an image and SVM example that executes both memory models through real OpenCL kernels.
- Map particle-example cursor coordinates to Vulkan's downward-positive viewport and use logical window dimensions on HiDPI displays.
- Reuse acquire semaphores only after their submission fence signals and keep one presentation semaphore per swapchain image in the Vulkan particle renderer.
Expand Down Expand Up @@ -65,10 +65,10 @@
## 0.2.0

- Add typed errors and platform/device discovery helpers.
- Add owned contexts, queues, typed buffers, programs, kernels, and events.
- Add owned contexts, queues, typed buffers, programs, kernels and events.
- Add checked blocking and asynchronous buffer transfers.
- Add source builds with compiler logs and typed kernel arguments.
- Add event wait lists, markers, barriers, profiling, and 1D/2D/3D dispatch.
- Add event wait lists, markers, barriers, profiling and 1D/2D/3D dispatch.
- Add external-memory and external-semaphore interoperability extensions.
- Add `cl_khr_device_uuid` device identity constants.
- Add portable and Vulkan/OpenCL interoperability examples.
Expand Down
2 changes: 1 addition & 1 deletion GENERATOR_COMMIT
Original file line number Diff line number Diff line change
@@ -1 +1 @@
01837eca8df5ffeb2b9d47a2d747a05e8890a11e
106ea226689ae3ee60699841284ff345754e938a
4 changes: 2 additions & 2 deletions OWNERSHIP.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Ownership model

The convenience API uses explicit `close()` methods. Close events, kernels,
programs, memory objects, and queues before their parent context.
programs, memory objects and queues before their parent context.

`OwnedContext`, `OwnedCommandQueue`, `Buffer`, `Image2D`, `OwnedSampler`,
`SvmAllocation`, `OwnedProgram`, `OwnedKernel`, `OwnedEvent`, and
`SvmAllocation`, `OwnedProgram`, `OwnedKernel`, `OwnedEvent` and
`OwnedExternalSemaphore` are `@[nocopy]`. Constructors return owned pointers so
resources cross module boundaries without copying. Pass those pointers directly
to convenience functions; do not add another `&`.
Expand Down
46 changes: 23 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![Test OpenCL module and advanced example](https://github.com/antono2/opencl/actions/workflows/test.yml/badge.svg)](https://github.com/antono2/opencl/actions/workflows/test.yml)

OpenCL bindings for the [V programming language](https://vlang.io/), with the
complete OpenCL 1.0 through 3.0 core API, selected Khronos extensions, and
complete OpenCL 1.0 through 3.0 core API, selected Khronos extensions and
optional helpers for device discovery and explicit resource ownership.

[Available on VPM](https://vpm.vlang.io/packages/antono2.opencl) ·
Expand Down Expand Up @@ -33,10 +33,10 @@ v run "$HOME/.vmodules/antono2/opencl/setup.vsh"
```

From a source checkout, use `v run setup.vsh`. The script supports Ubuntu and
Debian, Fedora, Arch, openSUSE, macOS, and Windows. It reuses an existing V module.
Debian, Fedora, Arch, openSUSE, macOS and Windows. It reuses an existing V module.
For diagnostics without installing packages, add `--check` to either invocation.

On Linux, setup installs OpenCL headers, the ICD loader, and PoCL for CPU-based
On Linux, setup installs OpenCL headers, the ICD loader and PoCL for CPU-based
development. On Windows, it installs headers and the Khronos loader through
vcpkg; the GPU vendor driver supplies the OpenCL implementation. macOS uses
its built-in OpenCL framework. Device and optional-feature availability is
Expand Down Expand Up @@ -67,7 +67,7 @@ fn main() {
## Convenience API

The generated functions expose the complete raw API. Optional helpers add typed
errors, device discovery, and explicit resource ownership. The snippets below
errors, device discovery and explicit resource ownership. The snippets below
show individual operations; see the [examples](#examples) for complete programs.

### Platform and device discovery
Expand All @@ -81,7 +81,7 @@ for platform in cl.platforms()! {
}
```

### Contexts, queues, and buffers
### Contexts, queues and buffers

Contexts and queues use explicit, idempotent cleanup:

Expand All @@ -96,9 +96,9 @@ defer { buffer.close() or {} }
buffer.write(queue, 0, []f32{len: 1024, init: f32(index)})!
```

The element type used by `Buffer[T]`, typed transfers, and kernel arguments
The element type used by `Buffer[T]`, typed transfers and kernel arguments
must be a plain C-layout value without V-managed references such as strings,
maps, or slices. Element-count multiplication is checked for overflow before
maps or slices. Element-count multiplication is checked for overflow before
an OpenCL allocation or transfer call.

### Programs and kernels
Expand Down Expand Up @@ -135,7 +135,7 @@ uploaded.close()!

### Ownership and cleanup

Owned contexts, queues, buffers, images, samplers, programs, kernels, events,
Owned contexts, queues, buffers, images, samplers, programs, kernels, events
and external semaphores are `@[nocopy]`, preventing accidental double release.
Constructors return owned pointers; pass them directly without adding another
`&`. When two independently closable owners are required,
Expand All @@ -149,7 +149,7 @@ implementation-selected work-group size.
### Images and shared virtual memory

Typed 2D images validate that `T` represents one complete pixel, provide checked
full-image and region transfers, and bind directly to kernels alongside owned
full-image and region transfers and bind directly to kernels alongside owned
samplers:

```v
Expand Down Expand Up @@ -235,7 +235,7 @@ See [`OWNERSHIP.md`](OWNERSHIP.md) for the current ownership and cleanup rules.

[`examples/vector_add`](examples/vector_add) is a compact introduction to the
owned convenience API. It runs asynchronous buffer uploads, a kernel, profiled
readback, and explicit cleanup.
readback and explicit cleanup.

[`examples/image_svm`](examples/image_svm) copies a typed RGBA image through an
image kernel and owned sampler, then executes a second kernel directly over a
Expand All @@ -245,7 +245,7 @@ typed SVM allocation when the selected device advertises buffer SVM support.
example that combines OpenCL compute with Vulkan presentation. On UUID-matched devices it imports
one exported Vulkan allocation into OpenCL and synchronizes access with reusable opaque-FD
semaphores. It also includes a portable host-staged fallback, swapchain recreation, velocity
trails, interactive controls, and display-independent interoperability smoke tests.
trails, interactive controls and display-independent interoperability smoke tests.

The example is a separate nested V module, so its `vulkan` and `glfw` dependencies are not
dependencies of applications that only import `opencl`.
Expand All @@ -255,43 +255,43 @@ dependencies of applications that only import `opencl`.
The module exposes the complete OpenCL 1.0 through 3.0 core API and selected
portable Khronos extensions with V-style snake-case wrappers,
including platform and device discovery, contexts, queues, memory and images,
programs, kernels, events, profiling, synchronization, and object lifecycle.
The bindings generator reads command prototypes, types, pointer depth, and all
programs, kernels, events, profiling, synchronization and object lifecycle.
The bindings generator reads command prototypes, types, pointer depth and all
OpenCL 1.0 through 3.0 core constants from Khronos' XML registry. Constants are
exposed using their corresponding OpenCL typedefs.
Core command callbacks use named V function types, allowing callback signatures
to be checked at compile time while optional callbacks still accept `unsafe { nil }`.
The initial extension set covers `cl_khr_il_program`,
`cl_khr_create_command_queue`, `cl_khr_subgroups`, and
`cl_khr_create_command_queue`, `cl_khr_subgroups` and
`cl_khr_suggested_local_work_size`.
Zero-copy synchronization support covers `cl_khr_semaphore`,
`cl_khr_external_semaphore`, and `cl_khr_external_memory`, including opaque-FD,
DMA-BUF, and sync-file handle variants.
`cl_khr_device_uuid` provides UUID, LUID, and node-mask device queries for
`cl_khr_external_semaphore` and `cl_khr_external_memory`, including opaque-FD,
DMA-BUF and sync-file handle variants.
`cl_khr_device_uuid` provides UUID, LUID and node-mask device queries for
matching an OpenCL device with another compute or graphics API.
Optional extension commands are resolved through the ICD at runtime instead of
being required linker symbols, so applications that do not use them can still
build against older OpenCL loaders.

CI exercises complete typed buffer, image/sampler, and SVM kernel paths, OpenCL
CI exercises complete typed buffer, image/sampler and SVM kernel paths, OpenCL
1.1 user events, an OpenCL 1.2 marker-with-wait-list dependency, and OpenCL 2.0
property-list queue creation and SVM allocation on PoCL.
OpenCL 2.1 coverage additionally checks synchronized device and host timer
queries; IL programs, kernel cloning, subgroup queries, and SVM migration are
queries; IL programs, kernel cloning, subgroup queries and SVM migration are
present in the generated API.
OpenCL 2.2 adds program specialization constants and program-release callbacks.
OpenCL 3.0 adds numeric version helpers, `NameVersion`, context destructor
callbacks, and property-based buffer and image creation.
callbacks and property-based buffer and image creation.

## Supported toolchains

CI pins the release compiler and a V3 compiler revision. The exact compiler,
runner, and dependency versions are recorded in
runner and dependency versions are recorded in
[the test workflow](.github/workflows/test.yml).

| Platform | Compiler lane | Validation |
| --- | --- | --- |
| Linux | Pinned release V, GCC | Kernels, images, SVM, and Vulkan-particle validation smoke tests |
| Linux | Pinned release V, GCC | Kernels, images, SVM and Vulkan-particle validation smoke tests |
| Linux | Pinned release V, TinyCC | Vulkan-particle compile and headless smoke test |
| Linux | Pinned V3, TinyCC | Required frontend checks and module/vector-add runtime smoke tests |
| macOS | Pinned release V, Clang | OpenCL framework ABI compilation |
Expand All @@ -306,7 +306,7 @@ releases on an unrelated upstream change.

## Maintenance and release provenance

The canonical sources, helpers, examples, and this README are maintained in
The canonical sources, helpers, examples and this README are maintained in
[`antono2/v_opencl_bindings`](https://github.com/antono2/v_opencl_bindings).
Submit changes there; its publication workflow updates this module.

Expand Down
2 changes: 1 addition & 1 deletion convenience_test.v
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Checks typed errors, resource reference counts, ownership, and convenience operations.
// Checks typed errors, resource reference counts, ownership and convenience operations.
module main

import antono2.opencl as cl
Expand Down
4 changes: 2 additions & 2 deletions event.v
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub fn (event &OwnedEvent) wait() ! {
check(wait_for_events(1, &event.handle), 'wait for OpenCL event')!
}

// execution_status returns CL_QUEUED, CL_SUBMITTED, CL_RUNNING, CL_COMPLETE,
// execution_status returns CL_QUEUED, CL_SUBMITTED, CL_RUNNING, CL_COMPLETE
// or a negative command execution error code.
pub fn (event &OwnedEvent) execution_status() !i32 {
if isnil(event.handle) {
Expand All @@ -77,7 +77,7 @@ pub fn (event &OwnedEvent) profiling_timestamp(parameter ProfilingInfo) !u64 {
return timestamp
}

// profile waits for completion and returns the portable queued, submit, start,
// profile waits for completion and returns the portable queued, submit, start
// and end timestamps. It returns profiling_info_not_available for queues which
// were not created with queue_profiling_enable.
pub fn (event &OwnedEvent) profile() !EventProfile {
Expand Down
14 changes: 7 additions & 7 deletions examples/vulkan_particles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ buffer with Vulkan. Its preferred path exports a Vulkan allocation and imports i
systems without compatible external-memory and external-semaphore support use per-frame staging.

The implementation is split into independently testable layers: deterministic OpenCL simulation,
display-independent smoke tests, Vulkan/OpenCL device matching, interoperability negotiation, and
display-independent smoke tests, Vulkan/OpenCL device matching, interoperability negotiation and
an interactive Vulkan renderer. On a qualifying device the live renderer uses the exported Vulkan
vertex allocation directly as its OpenCL simulation buffer. Other systems retain the same renderer
and use a host-staged upload each frame. That fallback enables only the swapchain extension and
Expand All @@ -34,7 +34,7 @@ From the repository root:

For PowerShell, run `Push-Location examples/vulkan_particles`, `v install`,
then `Pop-Location`. This keeps the README aligned with the manifest when
OpenCL, Vulkan, or GLFW dependency versions change.
OpenCL, Vulkan or GLFW dependency versions change.

On Debian or Ubuntu, install the OpenCL loader/development headers and GLFW
development files before building. The Vulkan module bundles its own headers
Expand Down Expand Up @@ -67,19 +67,19 @@ The pinned Vulkan release provides the deep-bound Volk loader used by TinyCC.
## Tested hardware

- NVIDIA GeForce GTX 1060 6GB on Linux: UUID-matched opaque-FD external memory,
Vulkan-to-OpenCL-to-Vulkan semaphore synchronization, and 300 frames with
Vulkan-to-OpenCL-to-Vulkan semaphore synchronization and 300 frames with
32,768 particles passed using GCC.

Running without a renderer option intentionally performs only the display-independent smoke test
and prints a reminder that no window will be opened. Run with `--window` for the interactive
renderer or `--help` for the complete command-line interface. The original `PARTICLE_COUNT`,
`PARTICLES_WINDOW`, `PARTICLES_FRAMES`, `PARTICLES_FORCE_STAGED`, and
`PARTICLES_WINDOW`, `PARTICLES_FRAMES`, `PARTICLES_FORCE_STAGED` and
`PARTICLES_REQUIRE_ZERO_COPY` environment variables remain supported for scripts and compatibility.

Startup reports the selected OpenCL and Vulkan devices and either `zero-copy` or a precise reason
for selecting `staged fallback`. Device UUIDs must match before external memory is considered.
`--window` additionally verifies GLFW surface creation, graphics/presentation queue
selection, swapchain negotiation, image enumeration, image-view creation, and the live particle
selection, swapchain negotiation, image enumeration, image-view creation and the live particle
loop. The final console line includes `(zero-copy)` or `(staged)`, confirming the path actually used
by the renderer. `--frames` limits the loop for automated smoke tests; zero means run until
the window is closed. Swapchain resources are rebuilt when a resize makes them suboptimal or
Expand All @@ -89,6 +89,6 @@ external-memory and external-semaphore path on supported hardware.

Each particle also gets a velocity-colored motion streak rendered from the shared particle data.
Move the mouse to steer the third attractor, press Space to pause/resume, R to reset, T to toggle
the streaks, and Escape to exit. The title reports particle count, average FPS, transfer backend,
trail state, and pause state. The live zero-copy loop uses reusable opaque-FD binary semaphores
the streaks and Escape to exit. The title reports particle count, average FPS, transfer backend,
trail state and pause state. The live zero-copy loop uses reusable opaque-FD binary semaphores
for the Vulkan-to-OpenCL and OpenCL-to-Vulkan ownership handoffs, without per-frame host waits.
2 changes: 1 addition & 1 deletion examples/vulkan_particles/compute.v
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Owns OpenCL particle kernels and their compute buffers.
// Supports reset, simulation updates, and readback for staged presentation.
// Supports reset, simulation updates and readback for staged presentation.
module main

import antono2.opencl as cl
Expand Down
2 changes: 1 addition & 1 deletion examples/vulkan_particles/main.v
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Particle-demo entry point selecting headless, staged, or zero-copy execution from options.
// Particle-demo entry point selecting headless, staged or zero-copy execution from options.
module main

import os
Expand Down
2 changes: 1 addition & 1 deletion examples/vulkan_particles/options_test.v
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Checks option precedence, invalid combinations, and cursor-to-particle coordinate mapping.
// Checks option precedence, invalid combinations and cursor-to-particle coordinate mapping.
module main

fn test_command_line_options_override_defaults() {
Expand Down
2 changes: 1 addition & 1 deletion examples/vulkan_particles/swapchain.v
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Creates presentation images, views, and framebuffers for the particle window.
// Creates presentation images, views and framebuffers for the particle window.
// Queries surface support and destroys the associated swapchain resources.
module main

Expand Down
2 changes: 1 addition & 1 deletion image.v
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typed image and sampler ownership with checked dimensions, formats, and transfers.
// Typed image and sampler ownership with checked dimensions, formats and transfers.
module opencl

// Image2D owns a typed two-dimensional OpenCL image. T represents one complete
Expand Down
2 changes: 1 addition & 1 deletion opencl.v
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Code generated from the Khronos OpenCL XML API Registry. DO NOT EDIT.
// Raw OpenCL constants, types, and entry points; resource lifetimes follow the C API.
// Raw OpenCL constants, types and entry points; resource lifetimes follow the C API.
// Regenerate in antono2/v_opencl_bindings with python3 src/main.py.
module opencl

Expand Down
Loading
Loading