diff --git a/wgpu/examples/hello-compute/main.rs b/wgpu/examples/hello-compute/main.rs index 500f728d5f..6e70c0236c 100644 --- a/wgpu/examples/hello-compute/main.rs +++ b/wgpu/examples/hello-compute/main.rs @@ -1,6 +1,9 @@ use std::{borrow::Cow, convert::TryInto, str::FromStr}; use wgpu::util::DeviceExt; +// Indicates a u32 overflow in an intermediate Collatz value +const OVERFLOW: u32 = 0xffffffff; + async fn run() { let numbers = if std::env::args().len() <= 1 { let default = vec![1, 2, 3, 4]; @@ -13,10 +16,19 @@ async fn run() { .collect() }; - let times = execute_gpu(numbers).await; - println!("Times: {:?}", times); + let steps = execute_gpu(numbers).await; + + let disp_steps: Vec = steps + .iter() + .map(|&n| match n { + OVERFLOW => "OVERFLOW".to_string(), + _ => n.to_string(), + }) + .collect(); + + println!("Steps: [{}]", disp_steps.join(", ")); #[cfg(target_arch = "wasm32")] - log::info!("Times: {:?}", times); + log::info!("Steps: [{}]", disp_steps.join(", ")); } async fn execute_gpu(numbers: Vec) -> Vec { @@ -194,6 +206,15 @@ mod tests { pollster::block_on(assert_execute_gpu(input, vec![5, 15, 6, 19])); } + #[test] + fn test_compute_overflow() { + let input = vec![77031, 837799, 8400511, 63728127]; + pollster::block_on(assert_execute_gpu( + input, + vec![350, 524, OVERFLOW, OVERFLOW], + )); + } + #[test] fn test_multithreaded_compute() { use std::{sync::mpsc, thread, time::Duration}; diff --git a/wgpu/examples/hello-compute/shader.wgsl b/wgpu/examples/hello-compute/shader.wgsl index c6ddb72039..2ac9b864b3 100644 --- a/wgpu/examples/hello-compute/shader.wgsl +++ b/wgpu/examples/hello-compute/shader.wgsl @@ -23,6 +23,11 @@ fn collatz_iterations(n_base: u32) -> u32{ n = n / 2u; } else { + // Overflow? (i.e. 3*n + 1 > 0xffffffffu?) + if (n >= 1431655765u) { // 0x55555555u + return 4294967295u; // 0xffffffffu + } + n = 3u * n + 1u; } i = i + 1u;