For Loop
Demonstrates for-loop support with range expressions: exclusive (0..n), inclusive (0..=n), and literal bounds. Variable bounds require #[wgsl_allow(non_literal_loop_bounds)].
Rust Source
#![allow(unused)]
fn main() {
#[wgsl]
pub mod for_loop_example {
//! Demonstrates for-loop support with range expressions.
//! - Exclusive ranges: `for i in 0..10 { ... }`
//! - Inclusive ranges: `for i in 0..=9 { ... }`
//! - Variable bounds: `for i in start..end { ... }` (requires
//! `#[wgsl_allow]`)
use wgsl_rs::std::*;
// Sum values from 0 to n-1 using exclusive range.
// Uses #[wgsl_allow] on for-loop because `n` is a variable bound.
pub fn sum_exclusive(n: i32) -> i32 {
let mut total = 0;
#[wgsl_allow(non_literal_loop_bounds)]
for i in 0..n {
total += i;
}
total
}
// Sum values from 0 to n (inclusive) using inclusive range.
// Uses #[wgsl_allow] on for-loop because `n` is a variable bound.
pub fn sum_inclusive(n: i32) -> i32 {
let mut total = 0;
#[wgsl_allow(non_literal_loop_bounds)]
for i in 0..=n {
total += i;
}
total
}
// Compute dot product of two arrays using for-loop.
// No #[wgsl_allow] needed because bounds are literals.
pub fn dot_product(a: [f32; 4], b: [f32; 4]) -> f32 {
let mut result = 0.0;
for i in 0..4 {
result += a[i as usize] * b[i as usize];
}
result
}
// Nested for-loops: initialize a 2D-like structure.
// No #[wgsl_allow] needed because bounds are literals.
pub fn nested_loops() -> i32 {
let mut sum = 0;
for i in 0..3 {
for j in 0..4 {
sum += i * 4 + j;
}
}
sum
}
#[fragment]
pub fn for_loop_fragment() -> Vec4f {
// Test sum_exclusive: sum of 0..10 = 0+1+2+...+9 = 45
let exclusive_sum = sum_exclusive(10);
// Test sum_inclusive: sum of 0..=9 = 0+1+2+...+9 = 45
let inclusive_sum = sum_inclusive(9);
// Test dot_product
let a: [f32; 4] = [1.0, 2.0, 3.0, 4.0];
let b: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
let dot = dot_product(a, b); // 1+2+3+4 = 10
// Test nested loops: sum of (i*4+j) for i in 0..3, j in 0..4
// = (0,1,2,3) + (4,5,6,7) + (8,9,10,11) = 6 + 22 + 38 = 66
let nested = nested_loops();
vec4f(
f32(exclusive_sum) / 100.0,
f32(inclusive_sum) / 100.0,
dot / 10.0,
f32(nested) / 100.0,
)
}
}
}
Generated WGSL
fn sum_exclusive(n: i32) -> i32 {
var total = 0;
for (var i = 0; i < n; i++) {
total += i;
}
return total;
}
fn sum_inclusive(n: i32) -> i32 {
var total = 0;
for (var i = 0; i <= n; i++) {
total += i;
}
return total;
}
fn dot_product(a: array<f32, 4>, b: array<f32, 4>) -> f32 {
var result = 0.0;
for (var i = 0; i < 4; i++) {
result += a[u32(i)] * b[u32(i)];
}
return result;
}
fn nested_loops() -> i32 {
var sum = 0;
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 4; j++) {
sum += i * 4 + j;
}
}
return sum;
}
@fragment fn for_loop_fragment() -> @location(0) vec4f {
let exclusive_sum = sum_exclusive(10);
let inclusive_sum = sum_inclusive(9);
let a: array<f32, 4> = array(1.0, 2.0, 3.0, 4.0);
let b: array<f32, 4> = array(1.0, 1.0, 1.0, 1.0);
let dot = dot_product(a, b);
let nested = nested_loops();
return vec4f(f32(exclusive_sum) / 100.0, f32(inclusive_sum) / 100.0, dot / 10.0, f32(nested) / 100.0);
}
Notes
- Rust
for i in 0..nbecomes a WGSL C-stylefor (var i = 0; i < n; i++). - Inclusive ranges (
0..=n) translate toi <= n. #[wgsl_allow(non_literal_loop_bounds)]is required when loop bounds are not literal constants, because WGSL’sforrequires constant bounds — the transpiler emits them anyway and naga lowers the loop to aloopwith abreakcondition.