ringkernel-wgpu 0.4.2

WebGPU backend for RingKernel - cross-platform GPU support
Documentation
//! WebGPU Backend for RingKernel
//!
//! This crate provides cross-platform GPU support via WebGPU (wgpu).
//! Works on Vulkan, Metal, DX12, and browser environments.
//!
//! # Features
//!
//! - Cross-platform GPU access (Windows, macOS, Linux, Web)
//! - Event-driven execution model (WebGPU limitation)
//! - WGSL shader language support
//!
//! # Limitations
//!
//! - No true persistent kernels (WebGPU doesn't support cooperative groups)
//! - No 64-bit atomics in WGSL
//! - Event-driven execution only
//!
//! # Example
//!
//! ```ignore
//! use ringkernel_wgpu::WgpuRuntime;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     let runtime = WgpuRuntime::new().await?;
//!     let kernel = runtime.launch("compute", Default::default()).await?;
//!     kernel.activate().await?;
//!     Ok(())
//! }
//! ```

#![warn(missing_docs)]

#[cfg(feature = "wgpu")]
mod adapter;
#[cfg(feature = "wgpu")]
mod kernel;
#[cfg(feature = "wgpu")]
mod memory;
#[cfg(feature = "wgpu")]
mod runtime;
#[cfg(feature = "wgpu")]
mod shader;

#[cfg(feature = "wgpu")]
pub use adapter::WgpuAdapter;
#[cfg(feature = "wgpu")]
pub use kernel::WgpuKernel;
#[cfg(feature = "wgpu")]
pub use memory::WgpuBuffer;
#[cfg(feature = "wgpu")]
pub use runtime::WgpuRuntime;

// Stub implementation when wgpu feature is disabled
#[cfg(not(feature = "wgpu"))]
mod stub {
    ringkernel_core::unavailable_backend!(
        WgpuRuntime,
        ringkernel_core::runtime::Backend::Wgpu,
        "wgpu"
    );
}

#[cfg(not(feature = "wgpu"))]
pub use stub::WgpuRuntime;

/// Check if WebGPU is available at runtime.
pub fn is_wgpu_available() -> bool {
    #[cfg(feature = "wgpu")]
    {
        // Try to create an instance
        let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());
        !instance
            .enumerate_adapters(wgpu::Backends::all())
            .is_empty()
    }
    #[cfg(not(feature = "wgpu"))]
    {
        false
    }
}

/// WGSL shader template for ring kernel.
pub const RING_KERNEL_WGSL_TEMPLATE: &str = r#"
// RingKernel WGSL Template
// Generated by ringkernel-wgpu

// Control block binding
struct ControlBlock {
    is_active: u32,
    should_terminate: u32,
    has_terminated: u32,
    _pad1: u32,
    messages_processed_lo: u32,
    messages_processed_hi: u32,
    messages_in_flight_lo: u32,
    messages_in_flight_hi: u32,
    input_head_lo: u32,
    input_head_hi: u32,
    input_tail_lo: u32,
    input_tail_hi: u32,
    output_head_lo: u32,
    output_head_hi: u32,
    output_tail_lo: u32,
    output_tail_hi: u32,
    input_capacity: u32,
    output_capacity: u32,
    input_mask: u32,
    output_mask: u32,
    // HLC state (split for WGSL u32 limitation)
    hlc_physical_lo: u32,
    hlc_physical_hi: u32,
    hlc_logical_lo: u32,
    hlc_logical_hi: u32,
    last_error: u32,
    error_count: u32,
}

@group(0) @binding(0) var<storage, read_write> control: ControlBlock;
@group(0) @binding(1) var<storage, read_write> input_queue: array<u32>;
@group(0) @binding(2) var<storage, read_write> output_queue: array<u32>;

// Thread identification
var<private> thread_id: u32;
var<private> workgroup_id: u32;

@compute @workgroup_size(256)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>,
        @builtin(workgroup_id) wg_id: vec3<u32>,
        @builtin(local_invocation_id) local_id: vec3<u32>) {
    thread_id = local_id.x;
    workgroup_id = wg_id.x;

    // Check if kernel should process
    if (control.is_active == 0u) {
        return;
    }

    // User kernel code will be inserted here
    // USER_KERNEL_CODE

    // Update message counter (simplified without 64-bit atomics)
    if (thread_id == 0u) {
        control.messages_processed_lo = control.messages_processed_lo + 1u;
        if (control.messages_processed_lo == 0u) {
            control.messages_processed_hi = control.messages_processed_hi + 1u;
        }
    }
}
"#;