use naga::valid::{Capabilities, ValidationFlags};
use crate::fft::{fft_bitreverse_wgsl, fft_stage_wgsl};
use crate::shader::{
attention_wgsl, batched_gemm_wgsl, binary_wgsl, conv2d_wgsl, elementwise_wgsl, gemm_wgsl,
gemm_wgsl_f16, reduction_final_wgsl, reduction_nd_wgsl, reduction_wgsl,
};
use crate::shader_ext::{
ScanKind, f64_emul_add_wgsl, layernorm_wgsl, scan_wgsl, softmax_wgsl, transpose_wgsl,
};
fn assert_wgsl_valid(label: &str, src: &str, caps: Capabilities) {
let module = naga::front::wgsl::parse_str(src)
.unwrap_or_else(|e| panic!("WGSL parse failed for `{label}`: {e}"));
let mut validator = naga::valid::Validator::new(ValidationFlags::all(), caps);
validator
.validate(&module)
.unwrap_or_else(|e| panic!("WGSL validation failed for `{label}`: {e}"));
}
#[test]
fn naga_validates_gemm_wgsl() {
assert_wgsl_valid("gemm_wgsl(8)", &gemm_wgsl(8), Capabilities::empty());
}
#[test]
fn naga_validates_gemm_wgsl_tile16() {
assert_wgsl_valid("gemm_wgsl(16)", &gemm_wgsl(16), Capabilities::empty());
}
#[test]
fn naga_validates_gemm_wgsl_f16() {
assert_wgsl_valid(
"gemm_wgsl_f16(8)",
&gemm_wgsl_f16(8),
Capabilities::SHADER_FLOAT16,
);
}
#[test]
fn naga_validates_batched_gemm_wgsl() {
assert_wgsl_valid(
"batched_gemm_wgsl(8)",
&batched_gemm_wgsl(8),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_elementwise_wgsl_relu() {
assert_wgsl_valid(
"elementwise_wgsl(relu)",
&elementwise_wgsl("relu"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_elementwise_wgsl_sigmoid() {
assert_wgsl_valid(
"elementwise_wgsl(sigmoid)",
&elementwise_wgsl("sigmoid"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_elementwise_wgsl_tanh() {
assert_wgsl_valid(
"elementwise_wgsl(tanh)",
&elementwise_wgsl("tanh"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_elementwise_wgsl_neg() {
assert_wgsl_valid(
"elementwise_wgsl(neg)",
&elementwise_wgsl("neg"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_binary_wgsl_add() {
assert_wgsl_valid(
"binary_wgsl(add)",
&binary_wgsl("add"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_binary_wgsl_pow() {
assert_wgsl_valid(
"binary_wgsl(pow)",
&binary_wgsl("pow"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_reduction_wgsl_sum() {
assert_wgsl_valid(
"reduction_wgsl(sum)",
&reduction_wgsl("sum"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_reduction_wgsl_max() {
assert_wgsl_valid(
"reduction_wgsl(max)",
&reduction_wgsl("max"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_reduction_wgsl_min() {
assert_wgsl_valid(
"reduction_wgsl(min)",
&reduction_wgsl("min"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_reduction_nd_wgsl_sum() {
assert_wgsl_valid(
"reduction_nd_wgsl(sum)",
&reduction_nd_wgsl("sum"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_reduction_nd_wgsl_mean() {
assert_wgsl_valid(
"reduction_nd_wgsl(mean)",
&reduction_nd_wgsl("mean"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_reduction_final_wgsl() {
assert_wgsl_valid(
"reduction_final_wgsl(sum)",
&reduction_final_wgsl("sum"),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_conv2d_wgsl() {
let src = conv2d_wgsl(1, 1, 4, 4, 1, 3, 3, 2, 2, 1, 1, 0, 0);
assert_wgsl_valid(
"conv2d_wgsl(1,1,4,4,1,3,3,2,2,1,1,0,0)",
&src,
Capabilities::empty(),
);
}
#[test]
fn naga_validates_conv2d_wgsl_with_padding() {
let src = conv2d_wgsl(1, 3, 8, 8, 4, 3, 3, 8, 8, 1, 1, 1, 1);
assert_wgsl_valid(
"conv2d_wgsl(1,3,8,8,4,3,3,8,8,1,1,1,1)",
&src,
Capabilities::empty(),
);
}
#[test]
fn naga_validates_attention_wgsl_non_causal() {
let src = attention_wgsl(2, 4, 4, 8, 0.5_f32, false);
assert_wgsl_valid(
"attention_wgsl(2,4,4,8,0.5,causal=false)",
&src,
Capabilities::empty(),
);
}
#[test]
fn naga_validates_attention_wgsl_causal() {
let src = attention_wgsl(2, 4, 4, 8, 0.5_f32, true);
assert_wgsl_valid(
"attention_wgsl(2,4,4,8,0.5,causal=true)",
&src,
Capabilities::empty(),
);
}
#[test]
fn naga_validates_transpose_wgsl() {
assert_wgsl_valid(
"transpose_wgsl(8)",
&transpose_wgsl(8),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_transpose_wgsl_tile16() {
assert_wgsl_valid(
"transpose_wgsl(16)",
&transpose_wgsl(16),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_softmax_wgsl() {
assert_wgsl_valid("softmax_wgsl()", &softmax_wgsl(), Capabilities::empty());
}
#[test]
fn naga_validates_scan_wgsl_inclusive() {
assert_wgsl_valid(
"scan_wgsl(256, Inclusive)",
&scan_wgsl(256, ScanKind::Inclusive),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_scan_wgsl_exclusive() {
assert_wgsl_valid(
"scan_wgsl(256, Exclusive)",
&scan_wgsl(256, ScanKind::Exclusive),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_scan_wgsl_block64() {
assert_wgsl_valid(
"scan_wgsl(64, Inclusive)",
&scan_wgsl(64, ScanKind::Inclusive),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_layernorm_wgsl() {
assert_wgsl_valid(
"layernorm_wgsl(1e-5)",
&layernorm_wgsl(1e-5),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_layernorm_wgsl_small_eps() {
assert_wgsl_valid(
"layernorm_wgsl(1e-8)",
&layernorm_wgsl(1e-8),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_f64_emul_add_wgsl() {
assert_wgsl_valid(
"f64_emul_add_wgsl()",
&f64_emul_add_wgsl(),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_fft_bitreverse_wgsl() {
assert_wgsl_valid(
"fft_bitreverse_wgsl()",
&fft_bitreverse_wgsl(),
Capabilities::empty(),
);
}
#[test]
fn naga_validates_fft_stage_wgsl() {
assert_wgsl_valid("fft_stage_wgsl()", &fft_stage_wgsl(), Capabilities::empty());
}