use ringkernel::prelude::*;
use ringkernel_derive::RingMessage;
use rkyv::{Archive, Deserialize, Serialize};
#[derive(Debug, Clone, RingMessage, Archive, Serialize, Deserialize)]
#[archive(check_bytes)]
#[message(type_id = 0x2001)]
pub struct DerivedVectorAddRequest {
#[message(id)]
pub id: MessageId,
#[message(correlation)]
pub correlation_id: CorrelationId,
pub a: Vec<f32>,
pub b: Vec<f32>,
}
#[derive(Debug, Clone, RingMessage, Archive, Serialize, Deserialize)]
#[archive(check_bytes)]
#[message(type_id = 0x2002)]
pub struct DerivedVectorAddResponse {
#[message(id)]
pub id: MessageId,
#[message(correlation)]
pub correlation_id: CorrelationId,
pub result: Vec<f32>,
pub processing_time_us: u64,
}
#[derive(Debug, Clone, Archive, Serialize, Deserialize)]
pub struct ManualVectorAddRequest {
pub id: u64,
pub correlation_id: u64,
pub a: Vec<f32>,
pub b: Vec<f32>,
}
impl RingMessage for ManualVectorAddRequest {
fn message_type() -> u64 {
0x1001 }
fn message_id(&self) -> MessageId {
MessageId::new(self.id)
}
fn correlation_id(&self) -> CorrelationId {
CorrelationId::new(self.correlation_id)
}
fn priority(&self) -> Priority {
Priority::Normal
}
fn serialize(&self) -> Vec<u8> {
rkyv::to_bytes::<_, 256>(self)
.map(|v| v.to_vec())
.unwrap_or_default()
}
fn deserialize(bytes: &[u8]) -> Result<Self> {
let archived = unsafe { rkyv::archived_root::<Self>(bytes) };
archived
.deserialize(&mut rkyv::Infallible)
.map_err(|_| RingKernelError::DeserializationError("Failed to deserialize".into()))
}
}
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt::init();
println!("=== RingKernel Vector Add Example ===\n");
let runtime = RingKernel::new().await?;
println!("Runtime backend: {:?}\n", runtime.backend());
let kernel = runtime
.launch("vector_add", LaunchOptions::default())
.await?;
println!("Launched kernel: {}\n", kernel.id());
let a = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let b = vec![10.0, 20.0, 30.0, 40.0, 50.0];
println!("Input vectors:");
println!(" a = {:?}", a);
println!(" b = {:?}\n", b);
println!("--- Using #[derive(RingMessage)] ---\n");
let derived_request = DerivedVectorAddRequest {
id: MessageId::generate(),
correlation_id: CorrelationId::generate(),
a: a.clone(),
b: b.clone(),
};
println!(
"Message type ID: 0x{:04X}",
DerivedVectorAddRequest::message_type()
);
println!("Message ID: {}", derived_request.message_id());
println!("Correlation ID: {:?}", derived_request.correlation_id());
let bytes = RingMessage::serialize(&derived_request);
println!("Serialized size: {} bytes", bytes.len());
let restored = <DerivedVectorAddRequest as RingMessage>::deserialize(&bytes)?;
println!("Restored a = {:?}", restored.a);
println!("Restored b = {:?}\n", restored.b);
println!("--- Using Manual Implementation ---\n");
let manual_request = ManualVectorAddRequest {
id: MessageId::generate().inner(),
correlation_id: CorrelationId::generate().0,
a: a.clone(),
b: b.clone(),
};
println!(
"Message type ID: 0x{:04X}",
ManualVectorAddRequest::message_type()
);
let bytes = RingMessage::serialize(&manual_request);
println!("Serialized size: {} bytes", bytes.len());
let restored = <ManualVectorAddRequest as RingMessage>::deserialize(&bytes)?;
println!("Restored a = {:?}", restored.a);
println!("Restored b = {:?}\n", restored.b);
println!("--- Simulated GPU Processing ---\n");
let result: Vec<f32> = a.iter().zip(&b).map(|(x, y)| x + y).collect();
let response = DerivedVectorAddResponse {
id: MessageId::generate(),
correlation_id: derived_request.correlation_id,
result,
processing_time_us: 42,
};
println!("Result: {:?}", response.result);
println!("Processing time: {}us", response.processing_time_us);
kernel.terminate().await?;
runtime.shutdown().await?;
println!("\n=== Vector Add Example Complete! ===");
println!("\nRecommendation: Use #[derive(RingMessage)] for cleaner code.");
println!("The manual implementation shows what the macro generates.");
Ok(())
}