#![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;
#[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;
pub fn is_wgpu_available() -> bool {
#[cfg(feature = "wgpu")]
{
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());
!instance
.enumerate_adapters(wgpu::Backends::all())
.is_empty()
}
#[cfg(not(feature = "wgpu"))]
{
false
}
}
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;
}
}
}
"#;