From 818bbc4105aba86cb0a8961b9f66698120babf2f Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Thu, 8 Oct 2026 20:03:53 +0200 Subject: [PATCH 1/4] chore: `ruff check --fix` --- examples/compare_quantization_sizes.py | 7 +++---- examples/kv_cache_device_tensors.py | 18 ++++++++-------- examples/minilm_embeddings.py | 8 +++---- examples/mobilenetv2_from_hub.py | 4 ++-- examples/mobilenetv2_real.py | 1 - examples/save_load_example.py | 4 ++-- examples/test_quantization_roundtrip.py | 28 ++++++++++++------------- examples/text_generation_enhanced.py | 1 - examples/text_generation_gpt.py | 3 +-- examples/train_simple_demo.py | 1 - python/webnn/__init__.pyi | 2 +- python/webnn/hub.py | 1 - tests/test_coreml_basic.py | 2 -- tests/test_integration.py | 1 - tests/test_performance.py | 9 ++++---- 15 files changed, 40 insertions(+), 50 deletions(-) diff --git a/examples/compare_quantization_sizes.py b/examples/compare_quantization_sizes.py index 088dffc..1056452 100644 --- a/examples/compare_quantization_sizes.py +++ b/examples/compare_quantization_sizes.py @@ -7,7 +7,6 @@ """ import tempfile -import os import numpy as np from pathlib import Path @@ -122,9 +121,9 @@ def compare_sizes(size_multiplier=1): print("=" * 80) print("QUANTIZATION FILE SIZE COMPARISON") print("=" * 80) - print(f"\nModel Configuration:") + print("\nModel Configuration:") print(f" Base size: {64 * size_multiplier} x {64 * size_multiplier}") - print(f" Layers: 2 fully-connected layers (matmul + relu + matmul)") + print(" Layers: 2 fully-connected layers (matmul + relu + matmul)") print(f" Total parameters: ~{2 * (64 * size_multiplier) ** 2:,}") print() @@ -226,7 +225,7 @@ def compare_sizes(size_multiplier=1): if size_multiplier > 1: print(f"\n[INFO] Using size multiplier: {size_multiplier}x") - print(f"[INFO] This will create larger models for more realistic comparison\n") + print("[INFO] This will create larger models for more realistic comparison\n") results = compare_sizes(size_multiplier) diff --git a/examples/kv_cache_device_tensors.py b/examples/kv_cache_device_tensors.py index 02df81b..4f771ea 100644 --- a/examples/kv_cache_device_tensors.py +++ b/examples/kv_cache_device_tensors.py @@ -133,7 +133,7 @@ def run_with_device_tensors(ctx, graph, num_steps=50): past_key_device.write(np.zeros(kv_shape, dtype=np.float32)) past_value_device.write(np.zeros(kv_shape, dtype=np.float32)) - print(f" Device tensors created:") + print(" Device tensors created:") print(f" KV cache: {past_key_device}") start = time.time() @@ -177,7 +177,7 @@ def run_with_device_tensors(ctx, graph, num_steps=50): except Exception as e: print(f" Device tensor execution failed: {e}") - print(f" Note: This may be expected if device tensors are not fully supported yet") + print(" Note: This may be expected if device tensors are not fully supported yet") return None @@ -198,17 +198,17 @@ def main(): # Build decoder graph print("Building decoder graph...") graph = build_decoder_graph(ctx) - print(f" Graph built successfully") + print(" Graph built successfully") print() # Configuration num_steps = 50 - print(f"Configuration:") - print(f" Batch size: 1") - print(f" Sequence length: 128") - print(f" Hidden dim: 256") - print(f" Num heads: 4") + print("Configuration:") + print(" Batch size: 1") + print(" Sequence length: 128") + print(" Hidden dim: 256") + print(" Num heads: 4") print(f" Decode steps: {num_steps}") print() print("-" * 70) @@ -240,7 +240,7 @@ def main(): print("Note: Current implementation does host round-trips for both modes.") print("True zero-copy execution will show larger speedups on GPU/NPU.") else: - print(f"Device tensors: Not available") + print("Device tensors: Not available") print() print("This demo shows the API for device tensors.") print("Full zero-copy execution coming soon!") diff --git a/examples/minilm_embeddings.py b/examples/minilm_embeddings.py index 1e54f60..94059bb 100755 --- a/examples/minilm_embeddings.py +++ b/examples/minilm_embeddings.py @@ -337,16 +337,16 @@ def _load_webnn_model(self): print(f"[INFO] Downloading model from Hugging Face Hub: {self.model_id}") hub = webnn.Hub() model_files = hub.download_model(self.model_id) - print(f"[OK] Model downloaded") + print("[OK] Model downloaded") # Load graph from files - print(f"[INFO] Loading graph...") + print("[INFO] Loading graph...") graph = webnn.MLGraph.load( model_files['graph'], manifest_path=model_files['manifest'], weights_path=model_files['weights'] ) - print(f"[OK] Graph loaded successfully") + print("[OK] Graph loaded successfully") print(f" - Operand count: {graph.operand_count}") print(f" - Operation count: {graph.operation_count}") print(f" - Inputs: {graph.get_input_names()}") @@ -677,7 +677,7 @@ def main(): except Exception as e: error_msg = str(e) if "404" in error_msg or "Entry Not Found" in error_msg: - print(f"[WARNING] Model not found on Hugging Face Hub") + print("[WARNING] Model not found on Hugging Face Hub") print( "[INFO] The model may not be uploaded yet to: tarekziade/all-MiniLM-L6-v2-webnn" ) diff --git a/examples/mobilenetv2_from_hub.py b/examples/mobilenetv2_from_hub.py index c62ced0..00b1940 100755 --- a/examples/mobilenetv2_from_hub.py +++ b/examples/mobilenetv2_from_hub.py @@ -35,9 +35,9 @@ def load_imagenet_labels(): # Download from GitHub if not found import urllib.request url = "https://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txt" - print(f" [DOWNLOAD] ImageNet labels from GitHub...") + print(" [DOWNLOAD] ImageNet labels from GitHub...") urllib.request.urlretrieve(url, labels_file) - print(f" [OK] Labels downloaded") + print(" [OK] Labels downloaded") with open(labels_file) as f: return [line.strip() for line in f] diff --git a/examples/mobilenetv2_real.py b/examples/mobilenetv2_real.py index 05aad97..e54201c 100644 --- a/examples/mobilenetv2_real.py +++ b/examples/mobilenetv2_real.py @@ -17,7 +17,6 @@ import time import argparse from pathlib import Path -import urllib.request try: import numpy as np diff --git a/examples/save_load_example.py b/examples/save_load_example.py index b120c1a..d46dc9c 100644 --- a/examples/save_load_example.py +++ b/examples/save_load_example.py @@ -66,7 +66,7 @@ def main(): save_path = "example_graph.webnn" print(f"\n5. Saving graph to '{save_path}'...") graph.save(save_path) - print(f" Graph saved successfully") + print(" Graph saved successfully") # Check file size file_size = os.path.getsize(save_path) @@ -114,7 +114,7 @@ def main(): print(f"... ({len(content) - 500} more characters)") # Cleanup - print(f"\n11. Cleaning up...") + print("\n11. Cleaning up...") os.remove(save_path) print(f" Removed '{save_path}'") diff --git a/examples/test_quantization_roundtrip.py b/examples/test_quantization_roundtrip.py index c32c371..a0231fa 100644 --- a/examples/test_quantization_roundtrip.py +++ b/examples/test_quantization_roundtrip.py @@ -45,45 +45,45 @@ def test_quantization_roundtrip(quant_dtype="int8", quant_level_name="int8"): # Quantize the input quantized = builder.quantize_linear(x, scale, zero_point) - print(f" Created quantize_linear node") - print(f" Input dtype: float32") + print(" Created quantize_linear node") + print(" Input dtype: float32") print(f" Output dtype: {quant_dtype}") # Dequantize for computation output = builder.dequantize_linear(quantized, scale, zero_point) - print(f" Created dequantize_linear node") + print(" Created dequantize_linear node") print(f" Input dtype: {quant_dtype}") - print(f" Output dtype: float32") + print(" Output dtype: float32") # Build graph graph = builder.build({"output": output}) - print(f" Graph built successfully") + print(" Graph built successfully") # Step 2: Save with quantized=True marker with tempfile.TemporaryDirectory() as tmpdir: model_path = Path(tmpdir) / "quantized_model.webnn" print(f"\n[STEP 2] Saving quantized graph to {model_path}...") graph.save(str(model_path), quantized=True) - print(f" Model saved with quantized=True marker") + print(" Model saved with quantized=True marker") # Verify file was created if not model_path.exists(): - print(f" [ERROR] Model file not found!") + print(" [ERROR] Model file not found!") return False # Read the file to verify quantized marker (JSON format uses "quantized": true) - print(f"\n[STEP 3] Verifying saved file contains quantized marker...") + print("\n[STEP 3] Verifying saved file contains quantized marker...") with open(model_path, 'r') as f: content = f.read() if '"quantized": true' in content: - print(f" [OK] JSON quantized field found: \"quantized\": true") + print(" [OK] JSON quantized field found: \"quantized\": true") else: - print(f" [ERROR] Quantized marker NOT found in saved file") + print(" [ERROR] Quantized marker NOT found in saved file") print(f" First 500 chars: {content[:500]}") return False # Step 4: Run inference to verify it works - print(f"\n[STEP 4] Running inference...") + print("\n[STEP 4] Running inference...") test_input = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0], @@ -104,11 +104,11 @@ def test_quantization_roundtrip(quant_dtype="int8", quant_level_name="int8"): # So y should be close to x but with quantization error if not np.allclose(output_tensor, test_input, rtol=0.1): - print(f" [WARNING] Output differs from input more than expected") + print(" [WARNING] Output differs from input more than expected") else: - print(f" [OK] Output matches input (within quantization error)") + print(" [OK] Output matches input (within quantization error)") - print(f"\n[STEP 5] COMPLETE") + print("\n[STEP 5] COMPLETE") print("=" * 80) print() return True diff --git a/examples/text_generation_enhanced.py b/examples/text_generation_enhanced.py index ec96e5c..4192612 100644 --- a/examples/text_generation_enhanced.py +++ b/examples/text_generation_enhanced.py @@ -19,7 +19,6 @@ python text_generation_enhanced.py --weights model.json --use-kv-cache --tokens 100 """ -import sys import argparse import json from pathlib import Path diff --git a/examples/text_generation_gpt.py b/examples/text_generation_gpt.py index 61b9ae6..006e173 100644 --- a/examples/text_generation_gpt.py +++ b/examples/text_generation_gpt.py @@ -14,7 +14,6 @@ using pre-trained or initialized weights. """ -import sys import argparse import json from pathlib import Path @@ -252,7 +251,7 @@ def main(): print("Next-Token Generation with Attention (WebNN)") print("=" * 70) print(f"Backend: {backend_name}") - print(f"Model: vocab=128 (ASCII), d_model=64, max_seq=32") + print("Model: vocab=128 (ASCII), d_model=64, max_seq=32") print() # Create WebNN context diff --git a/examples/train_simple_demo.py b/examples/train_simple_demo.py index a958600..b2a2f30 100644 --- a/examples/train_simple_demo.py +++ b/examples/train_simple_demo.py @@ -18,7 +18,6 @@ import argparse import json import numpy as np -from pathlib import Path # Character-level vocabulary diff --git a/python/webnn/__init__.pyi b/python/webnn/__init__.pyi index b24df3b..ef837f4 100644 --- a/python/webnn/__init__.pyi +++ b/python/webnn/__init__.pyi @@ -1,6 +1,6 @@ """Type stubs for webnn package""" -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional import numpy as np import numpy.typing as npt diff --git a/python/webnn/hub.py b/python/webnn/hub.py index df56e18..834c063 100644 --- a/python/webnn/hub.py +++ b/python/webnn/hub.py @@ -4,7 +4,6 @@ Downloads WebNN model files (graph, weights, manifest) from Hugging Face Hub. """ -import os from pathlib import Path from urllib.request import urlretrieve from urllib.error import HTTPError diff --git a/tests/test_coreml_basic.py b/tests/test_coreml_basic.py index a40c0da..65760d2 100755 --- a/tests/test_coreml_basic.py +++ b/tests/test_coreml_basic.py @@ -20,9 +20,7 @@ import argparse import os import sys -from pathlib import Path -import numpy as np try: import webnn diff --git a/tests/test_integration.py b/tests/test_integration.py index 89b4d82..edb5827 100755 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -17,7 +17,6 @@ import argparse import os import sys -from pathlib import Path import numpy as np diff --git a/tests/test_performance.py b/tests/test_performance.py index 752e847..95af3e9 100644 --- a/tests/test_performance.py +++ b/tests/test_performance.py @@ -21,7 +21,6 @@ from typing import Dict, List, Tuple # Import conftest fixtures -from conftest import ml, context, builder def measure_inference_time(context, graph, inputs: Dict, num_runs: int = 5) -> Tuple[float, List[float]]: @@ -107,7 +106,7 @@ def test_performance_simple_onnx_cpu(ml): warm_avg = sum(warm_times) / len(warm_times) print(f"\n{'='*60}") - print(f"ONNX CPU - Simple Model (10 layers)") + print("ONNX CPU - Simple Model (10 layers)") print(f"{'='*60}") print(f"Cold start: {cold_time:.2f}ms") print(f"Warm avg: {warm_avg:.2f}ms") @@ -135,7 +134,7 @@ def test_performance_simple_coreml(ml): warm_avg = sum(warm_times) / len(warm_times) print(f"\n{'='*60}") - print(f"CoreML - Simple Model (10 layers)") + print("CoreML - Simple Model (10 layers)") print(f"{'='*60}") print(f"Cold start: {cold_time:.2f}ms") print(f"Warm avg: {warm_avg:.2f}ms") @@ -160,7 +159,7 @@ def test_performance_complex_onnx_cpu(ml): warm_avg = sum(warm_times) / len(warm_times) print(f"\n{'='*60}") - print(f"ONNX CPU - Complex Model (200 operations)") + print("ONNX CPU - Complex Model (200 operations)") print(f"{'='*60}") print(f"Cold start: {cold_time:.2f}ms") print(f"Warm avg: {warm_avg:.2f}ms") @@ -190,7 +189,7 @@ def test_performance_complex_coreml(ml): speedup = cold_time / warm_avg print(f"\n{'='*60}") - print(f"CoreML - Complex Model (200 operations)") + print("CoreML - Complex Model (200 operations)") print(f"{'='*60}") print(f"Cold start: {cold_time:.2f}ms") print(f"Run 2: {warm_times[0]:.2f}ms") From 922e4cf138ab1d88ca4d294cb42f74e5b42f142e Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Thu, 8 Oct 2026 20:05:40 +0200 Subject: [PATCH 2/4] chore: `ruff check --fix --unsafe-fixes` --- examples/text_generation_enhanced.py | 4 +- examples/text_generation_gpt.py | 4 +- examples/train_text_model.py | 6 +- tests/test_performance.py | 2 +- tests/test_python_api.py | 238 +++++++++++++-------------- tests/test_wpt_conformance.py | 2 +- tests/wpt_utils.py | 2 +- 7 files changed, 129 insertions(+), 129 deletions(-) diff --git a/examples/text_generation_enhanced.py b/examples/text_generation_enhanced.py index 4192612..5f91523 100644 --- a/examples/text_generation_enhanced.py +++ b/examples/text_generation_enhanced.py @@ -186,8 +186,8 @@ def build_graph_with_kv(self, builder, x_input, cached_k, cached_v): ln_beta = builder.constant(self.ln_beta, list(self.ln_beta.shape), "float32") # Compute Q, K, V for new token - Q = builder.matmul(x_input, W_q) # (1, d_model) - K = builder.matmul(x_input, W_k) # (1, d_model) + builder.matmul(x_input, W_q) # (1, d_model) + builder.matmul(x_input, W_k) # (1, d_model) V = builder.matmul(x_input, W_v) # (1, d_model) # Simplified attention: use mean pooling diff --git a/examples/text_generation_gpt.py b/examples/text_generation_gpt.py index 006e173..2005e9b 100644 --- a/examples/text_generation_gpt.py +++ b/examples/text_generation_gpt.py @@ -132,8 +132,8 @@ def build_graph(self, builder, x_input): # Simplified attention: use last token's representation # Q, K, V = x @ W_q, x @ W_k, x @ W_v - Q = builder.matmul(x_input, W_q) # (seq_len, d_model) - K = builder.matmul(x_input, W_k) # (seq_len, d_model) + builder.matmul(x_input, W_q) # (seq_len, d_model) + builder.matmul(x_input, W_k) # (seq_len, d_model) V = builder.matmul(x_input, W_v) # (seq_len, d_model) # Compute attention scores for last position diff --git a/examples/train_text_model.py b/examples/train_text_model.py index c78c64b..922ca25 100644 --- a/examples/train_text_model.py +++ b/examples/train_text_model.py @@ -72,8 +72,8 @@ def compute_loss(model, X_batch, y_batch): # Forward pass (simplified in NumPy) # Q, K, V - Q = x_embedded @ model.W_q - K = x_embedded @ model.W_k + x_embedded @ model.W_q + x_embedded @ model.W_k V = x_embedded @ model.W_v # Mean pooling approximation @@ -114,7 +114,7 @@ def train_step(model, X_batch, y_batch, lr=0.05): Perform one training step with simple gradient descent. Improved to focus on most important parameters. """ - batch_size = X_batch.shape[0] + X_batch.shape[0] epsilon = 0.0001 # Get original loss diff --git a/tests/test_performance.py b/tests/test_performance.py index 95af3e9..7bd2e4a 100644 --- a/tests/test_performance.py +++ b/tests/test_performance.py @@ -40,7 +40,7 @@ def measure_inference_time(context, graph, inputs: Dict, num_runs: int = 5) -> T for i in range(num_runs): start = time.time() - result = context.compute(graph, inputs) + context.compute(graph, inputs) elapsed = (time.time() - start) * 1000 times.append(elapsed) diff --git a/tests/test_python_api.py b/tests/test_python_api.py index c4089c1..641c816 100644 --- a/tests/test_python_api.py +++ b/tests/test_python_api.py @@ -44,7 +44,7 @@ def test_context_creation(ml): """Test context creation with different options""" # Test CPU-only context (accelerated=False) ctx = ml.create_context(power_preference="default", accelerated=False) - assert ctx.accelerated == False + assert not ctx.accelerated assert ctx.power_preference == "default" # Test accelerated context with high performance @@ -1469,27 +1469,27 @@ def test_tensor_descriptor_flags(context): """Test MLTensor descriptor flags per W3C WebNN spec""" # Test default flags (readable=False, writable=False per spec) tensor_default = context.create_tensor([2, 3], "float32") - assert tensor_default.readable == False - assert tensor_default.writable == False - assert tensor_default.exportable_to_gpu == False + assert not tensor_default.readable + assert not tensor_default.writable + assert not tensor_default.exportable_to_gpu # Test host tensor convenience method tensor_host = context.create_host_tensor([2, 3], "float32") - assert tensor_host.readable == True - assert tensor_host.writable == True - assert tensor_host.exportable_to_gpu == False + assert tensor_host.readable + assert tensor_host.writable + assert not tensor_host.exportable_to_gpu # Test custom flags tensor_readonly = context.create_tensor([2, 3], "float32", readable=True, writable=False) - assert tensor_readonly.readable == True - assert tensor_readonly.writable == False + assert tensor_readonly.readable + assert not tensor_readonly.writable tensor_writeonly = context.create_tensor([2, 3], "float32", readable=False, writable=True) - assert tensor_writeonly.readable == False - assert tensor_writeonly.writable == True + assert not tensor_writeonly.readable + assert tensor_writeonly.writable tensor_gpu_exportable = context.create_tensor([2, 3], "float32", exportable_to_gpu=True) - assert tensor_gpu_exportable.exportable_to_gpu == True + assert tensor_gpu_exportable.exportable_to_gpu def test_tensor_destroy(context): @@ -1721,7 +1721,7 @@ async def test_async_dispatch_with_actual_computation(async_context): @pytest.mark.asyncio async def test_async_context_properties(async_context): """Test that async context preserves underlying context properties""" - assert async_context.accelerated == False # CPU-only from fixture + assert not async_context.accelerated # CPU-only from fixture assert async_context.power_preference == "default" # Test synchronous methods still work @@ -1740,7 +1740,7 @@ def test_reduce_sum_single_axis(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_sum(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_sum_single_axis_keep_dims(context): @@ -1749,7 +1749,7 @@ def test_reduce_sum_single_axis_keep_dims(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_sum(x, axes=[1], keep_dimensions=True) assert output.shape == [2, 1, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_sum_multiple_axes(context): @@ -1758,7 +1758,7 @@ def test_reduce_sum_multiple_axes(context): x = builder.input("x", [2, 3, 4, 5], "float32") output = builder.reduce_sum(x, axes=[1, 2], keep_dimensions=False) assert output.shape == [2, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_sum_all_axes(context): @@ -1767,7 +1767,7 @@ def test_reduce_sum_all_axes(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_sum(x, axes=None, keep_dimensions=False) assert output.shape == [] # Scalar - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_mean_single_axis(context): @@ -1776,7 +1776,7 @@ def test_reduce_mean_single_axis(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_mean(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_mean_keep_dims(context): @@ -1785,7 +1785,7 @@ def test_reduce_mean_keep_dims(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_mean(x, axes=[0, 2], keep_dimensions=True) assert output.shape == [1, 3, 1] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_max(context): @@ -1794,7 +1794,7 @@ def test_reduce_max(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_max(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_min(context): @@ -1803,7 +1803,7 @@ def test_reduce_min(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_min(x, axes=[2], keep_dimensions=False) assert output.shape == [2, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_product(context): @@ -1812,7 +1812,7 @@ def test_reduce_product(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_product(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_l1(context): @@ -1821,7 +1821,7 @@ def test_reduce_l1(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_l1(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_l2(context): @@ -1830,7 +1830,7 @@ def test_reduce_l2(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_l2(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_log_sum(context): @@ -1839,7 +1839,7 @@ def test_reduce_log_sum(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_log_sum(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_log_sum_exp(context): @@ -1848,7 +1848,7 @@ def test_reduce_log_sum_exp(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_log_sum_exp(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_sum_square(context): @@ -1857,7 +1857,7 @@ def test_reduce_sum_square(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.reduce_sum_square(x, axes=[1], keep_dimensions=False) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_invalid_axis(context): @@ -1865,7 +1865,7 @@ def test_reduce_invalid_axis(context): builder = context.create_graph_builder() x = builder.input("x", [2, 3, 4], "float32") with pytest.raises(ValueError, match="out of bounds"): - output = builder.reduce_sum(x, axes=[5], keep_dimensions=False) + builder.reduce_sum(x, axes=[5], keep_dimensions=False) def test_reduce_duplicate_axes(context): @@ -1873,7 +1873,7 @@ def test_reduce_duplicate_axes(context): builder = context.create_graph_builder() x = builder.input("x", [2, 3, 4], "float32") with pytest.raises(ValueError, match="Duplicate axis"): - output = builder.reduce_sum(x, axes=[1, 1], keep_dimensions=False) + builder.reduce_sum(x, axes=[1, 1], keep_dimensions=False) def test_reduce_sum_non_contiguous_axes(context): @@ -1882,7 +1882,7 @@ def test_reduce_sum_non_contiguous_axes(context): x = builder.input("x", [2, 3, 4, 5], "float32") output = builder.reduce_sum(x, axes=[0, 2], keep_dimensions=False) assert output.shape == [3, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_reduce_sum_non_contiguous_axes_keep_dims(context): @@ -1891,7 +1891,7 @@ def test_reduce_sum_non_contiguous_axes_keep_dims(context): x = builder.input("x", [2, 3, 4, 5], "float32") output = builder.reduce_sum(x, axes=[0, 2], keep_dimensions=True) assert output.shape == [1, 3, 1, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Quantization operations @@ -1908,7 +1908,7 @@ def test_dequantize_linear(context): # Output should be float32 with same shape as input assert output.shape == [1, 3, 224, 224] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_quantize_linear(context): @@ -1924,7 +1924,7 @@ def test_quantize_linear(context): # Output should be int8 with same shape as input assert output.shape == [1, 3, 224, 224] assert output.data_type == "int8" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_quantize_linear_uint8(context): @@ -1937,7 +1937,7 @@ def test_quantize_linear_uint8(context): # Output data type matches zero_point assert output.shape == [8, 128] assert output.data_type == "uint8" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_dequantize_linear_uint8(context): @@ -1949,7 +1949,7 @@ def test_dequantize_linear_uint8(context): output = builder.dequantize_linear(x, scale, zero_point) assert output.shape == [8, 128] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_quantization_roundtrip(context): @@ -1965,7 +1965,7 @@ def test_quantization_roundtrip(context): # Final output should be float32 with same shape assert dequantized.shape == [10, 20] assert dequantized.data_type == "float32" - graph = builder.build({"output": dequantized}) + builder.build({"output": dequantized}) def test_quantize_linear_int4_per_tensor(context): @@ -1976,7 +1976,7 @@ def test_quantize_linear_int4_per_tensor(context): zero_point = builder.constant(np.array([[0, 0]], dtype=np.int8)) q = builder.quantize_linear(x, scale, zero_point) assert q.data_type == "int8" - graph = builder.build({"q": q}) + builder.build({"q": q}) def test_quantize_linear_uint4_per_axis(context): @@ -1988,7 +1988,7 @@ def test_quantize_linear_uint4_per_axis(context): zero_point = builder.constant(np.array([[[0, 1]]], dtype=np.uint8)) q = builder.quantize_linear(x, scale, zero_point) assert q.data_type == "uint8" - graph = builder.build({"q": q}) + builder.build({"q": q}) def test_dequantize_linear_int4_blockwise(context): @@ -1999,7 +1999,7 @@ def test_dequantize_linear_int4_blockwise(context): zero_point = builder.constant(np.array([[0, -1]], dtype=np.int8)) y = builder.dequantize_linear(qx, scale, zero_point) assert y.data_type == "float32" - graph = builder.build({"y": y}) + builder.build({"y": y}) @requires_execution_backend @@ -2099,7 +2099,7 @@ def test_transpose_default_permutation(context): x = builder.input("x", [4, 6], "float32") output = builder.transpose(x) assert output.shape == [6, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_transpose_custom_permutation_2d(context): @@ -2108,7 +2108,7 @@ def test_transpose_custom_permutation_2d(context): x = builder.input("x", [4, 6], "float32") output = builder.transpose(x, permutation=[1, 0]) assert output.shape == [6, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_transpose_custom_permutation_3d(context): @@ -2117,7 +2117,7 @@ def test_transpose_custom_permutation_3d(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.transpose(x, permutation=[2, 0, 1]) assert output.shape == [4, 2, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_transpose_4d_nchw_to_nhwc(context): @@ -2126,7 +2126,7 @@ def test_transpose_4d_nchw_to_nhwc(context): x = builder.input("x", [1, 3, 224, 224], "float32") output = builder.transpose(x, permutation=[0, 2, 3, 1]) assert output.shape == [1, 224, 224, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Concat tests @@ -2137,7 +2137,7 @@ def test_concat_2_inputs_axis_0(context): x2 = builder.input("x2", [2, 3], "float32") output = builder.concat([x1, x2], axis=0) assert output.shape == [4, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_concat_2_inputs_axis_1(context): @@ -2147,7 +2147,7 @@ def test_concat_2_inputs_axis_1(context): x2 = builder.input("x2", [2, 3], "float32") output = builder.concat([x1, x2], axis=1) assert output.shape == [2, 6] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_concat_multiple_inputs(context): @@ -2158,7 +2158,7 @@ def test_concat_multiple_inputs(context): x3 = builder.input("x3", [3, 3], "float32") output = builder.concat([x1, x2, x3], axis=0) assert output.shape == [6, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_concat_3d(context): @@ -2168,7 +2168,7 @@ def test_concat_3d(context): x2 = builder.input("x2", [2, 3, 4], "float32") output = builder.concat([x1, x2], axis=2) assert output.shape == [2, 3, 8] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Slice tests @@ -2178,7 +2178,7 @@ def test_slice_1d(context): x = builder.input("x", [24], "float32") output = builder.slice(x, starts=[12], sizes=[12]) assert output.shape == [12] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_slice_2d(context): @@ -2187,7 +2187,7 @@ def test_slice_2d(context): x = builder.input("x", [4, 6], "float32") output = builder.slice(x, starts=[2, 2], sizes=[2, 4]) assert output.shape == [2, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_slice_3d(context): @@ -2196,7 +2196,7 @@ def test_slice_3d(context): x = builder.input("x", [4, 3, 2], "float32") output = builder.slice(x, starts=[1, 1, 1], sizes=[3, 2, 1]) assert output.shape == [3, 2, 1] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_slice_whole_dimension(context): @@ -2205,7 +2205,7 @@ def test_slice_whole_dimension(context): x = builder.input("x", [4, 6], "float32") output = builder.slice(x, starts=[0, 2], sizes=[4, 4]) assert output.shape == [4, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Expand tests @@ -2215,7 +2215,7 @@ def test_expand_1d_to_larger_1d(context): x = builder.input("x", [1], "float32") output = builder.expand(x, new_shape=[24]) assert output.shape == [24] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_expand_1d_to_2d(context): @@ -2224,7 +2224,7 @@ def test_expand_1d_to_2d(context): x = builder.input("x", [1], "float32") output = builder.expand(x, new_shape=[4, 6]) assert output.shape == [4, 6] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_expand_some_dimensions(context): @@ -2233,7 +2233,7 @@ def test_expand_some_dimensions(context): x = builder.input("x", [1, 6], "float32") output = builder.expand(x, new_shape=[4, 6]) assert output.shape == [4, 6] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_expand_scalar_to_tensor(context): @@ -2242,7 +2242,7 @@ def test_expand_scalar_to_tensor(context): x = builder.input("x", [], "float32") output = builder.expand(x, new_shape=[24]) assert output.shape == [24] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Gather tests @@ -2253,7 +2253,7 @@ def test_gather_1d_indices(context): indices = builder.input("indices", [8], "int32") output = builder.gather(input_tensor, indices, axis=0) assert output.shape == [8] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_gather_2d_input_1d_indices_axis0(context): @@ -2263,7 +2263,7 @@ def test_gather_2d_input_1d_indices_axis0(context): indices = builder.input("indices", [8], "int32") output = builder.gather(input_tensor, indices, axis=0) assert output.shape == [8, 2] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_gather_3d_input_2d_indices_axis1(context): @@ -2273,7 +2273,7 @@ def test_gather_3d_input_2d_indices_axis1(context): indices = builder.input("indices", [2, 2], "int32") output = builder.gather(input_tensor, indices, axis=1) assert output.shape == [3, 2, 2, 2] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_gather_default_axis(context): @@ -2283,7 +2283,7 @@ def test_gather_default_axis(context): indices = builder.input("indices", [8], "int32") output = builder.gather(input_tensor, indices) assert output.shape == [8, 2] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Split tests (note: current architecture only supports using first output) @@ -2295,7 +2295,7 @@ def test_split_by_count(context): assert len(outputs) == 3 assert all(o.shape == [8] for o in outputs) # Note: Only first output can be used in graph due to single-output limitation - graph = builder.build({"output": outputs[0]}) + builder.build({"output": outputs[0]}) def test_split_by_sizes(context): @@ -2305,7 +2305,7 @@ def test_split_by_sizes(context): outputs = builder.split(x, splits=[8, 8, 8], axis=0) assert len(outputs) == 3 assert all(o.shape == [8] for o in outputs) - graph = builder.build({"output": outputs[0]}) + builder.build({"output": outputs[0]}) def test_split_unequal_sizes(context): @@ -2315,7 +2315,7 @@ def test_split_unequal_sizes(context): outputs = builder.split(x, splits=[3, 3, 3, 3], axis=0) assert len(outputs) == 4 assert all(o.shape == [3] for o in outputs) - graph = builder.build({"output": outputs[0]}) + builder.build({"output": outputs[0]}) def test_split_2d_along_axis1(context): @@ -2325,7 +2325,7 @@ def test_split_2d_along_axis1(context): outputs = builder.split(x, splits=3, axis=1) assert len(outputs) == 3 assert all(o.shape == [8, 1] for o in outputs) - graph = builder.build({"output": outputs[0]}) + builder.build({"output": outputs[0]}) # Where tests @@ -2337,7 +2337,7 @@ def test_where_same_shapes(context): false_value = builder.input("false_value", [2, 3], "float32") output = builder.where_(condition, true_value, false_value) assert output.shape == [2, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_where_with_broadcasting(context): @@ -2348,7 +2348,7 @@ def test_where_with_broadcasting(context): false_value = builder.input("false_value", [2, 1], "float32") output = builder.where_(condition, true_value, false_value) assert output.shape == [2, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_where_scalar_values(context): @@ -2359,7 +2359,7 @@ def test_where_scalar_values(context): false_value = builder.input("false_value", [2, 3], "float32") output = builder.where_(condition, true_value, false_value) assert output.shape == [2, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Pad tests @@ -2369,7 +2369,7 @@ def test_pad_1d(context): x = builder.input("x", [9], "float32") output = builder.pad(x, padding=[1, 1]) assert output.shape == [11] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_pad_2d(context): @@ -2378,7 +2378,7 @@ def test_pad_2d(context): x = builder.input("x", [3, 3], "float32") output = builder.pad(x, padding=[1, 1, 1, 1]) assert output.shape == [5, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_pad_4d(context): @@ -2387,7 +2387,7 @@ def test_pad_4d(context): x = builder.input("x", [1, 3, 3, 1], "float32") output = builder.pad(x, padding=[0, 2, 2, 0, 0, 2, 2, 0]) assert output.shape == [1, 7, 7, 1] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_pad_with_mode(context): @@ -2396,7 +2396,7 @@ def test_pad_with_mode(context): x = builder.input("x", [3, 3], "float32") output = builder.pad(x, padding=[1, 1, 1, 1], mode="edge") assert output.shape == [5, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_pad_with_value(context): @@ -2405,7 +2405,7 @@ def test_pad_with_value(context): x = builder.input("x", [3, 3], "float32") output = builder.pad(x, padding=[1, 1, 1, 1], mode="constant", value=5.0) assert output.shape == [5, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_pad_asymmetric(context): @@ -2414,7 +2414,7 @@ def test_pad_asymmetric(context): x = builder.input("x", [3, 3], "float32") output = builder.pad(x, padding=[1, 2, 3, 4]) assert output.shape == [7, 9] - graph = builder.build({"output": output}) + builder.build({"output": output}) # ======================================== @@ -2429,7 +2429,7 @@ def test_gelu_basic(context): output = builder.gelu(x) assert output.shape == [2, 3] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_gelu_multidimensional(context): @@ -2438,7 +2438,7 @@ def test_gelu_multidimensional(context): x = builder.input("x", [2, 3, 4, 5], "float32") output = builder.gelu(x) assert output.shape == [2, 3, 4, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_gelu_1d(context): @@ -2447,7 +2447,7 @@ def test_gelu_1d(context): x = builder.input("x", [10], "float32") output = builder.gelu(x) assert output.shape == [10] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Squeeze tests @@ -2457,7 +2457,7 @@ def test_squeeze_all_ones(context): x = builder.input("x", [1, 3, 1, 4, 1], "float32") output = builder.squeeze(x) assert output.shape == [3, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_squeeze_specific_axes(context): @@ -2466,7 +2466,7 @@ def test_squeeze_specific_axes(context): x = builder.input("x", [1, 3, 1, 4], "float32") output = builder.squeeze(x, axes=[0, 2]) assert output.shape == [3, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_squeeze_single_axis(context): @@ -2475,7 +2475,7 @@ def test_squeeze_single_axis(context): x = builder.input("x", [1, 3, 4], "float32") output = builder.squeeze(x, axes=[0]) assert output.shape == [3, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_squeeze_no_ones(context): @@ -2484,7 +2484,7 @@ def test_squeeze_no_ones(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.squeeze(x) assert output.shape == [2, 3, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Unsqueeze tests @@ -2494,7 +2494,7 @@ def test_unsqueeze_single_axis_front(context): x = builder.input("x", [3, 4], "float32") output = builder.unsqueeze(x, axes=[0]) assert output.shape == [1, 3, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_unsqueeze_single_axis_middle(context): @@ -2503,7 +2503,7 @@ def test_unsqueeze_single_axis_middle(context): x = builder.input("x", [3, 4], "float32") output = builder.unsqueeze(x, axes=[1]) assert output.shape == [3, 1, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_unsqueeze_single_axis_end(context): @@ -2512,7 +2512,7 @@ def test_unsqueeze_single_axis_end(context): x = builder.input("x", [3, 4], "float32") output = builder.unsqueeze(x, axes=[2]) assert output.shape == [3, 4, 1] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_unsqueeze_multiple_axes(context): @@ -2521,7 +2521,7 @@ def test_unsqueeze_multiple_axes(context): x = builder.input("x", [3, 4], "float32") output = builder.unsqueeze(x, axes=[0, 2]) assert output.shape == [1, 3, 1, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_unsqueeze_1d_to_4d(context): @@ -2530,7 +2530,7 @@ def test_unsqueeze_1d_to_4d(context): x = builder.input("x", [5], "float32") output = builder.unsqueeze(x, axes=[0, 2, 3]) assert output.shape == [1, 5, 1, 1] - graph = builder.build({"output": output}) + builder.build({"output": output}) # ArgMax tests @@ -2541,7 +2541,7 @@ def test_arg_max_axis_0_no_keep(context): output = builder.arg_max(x, axis=0) assert output.shape == [3, 4] assert output.data_type == "int64" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_arg_max_axis_1_keep_dims(context): @@ -2551,7 +2551,7 @@ def test_arg_max_axis_1_keep_dims(context): output = builder.arg_max(x, axis=1, keep_dimensions=True) assert output.shape == [2, 1, 4] assert output.data_type == "int64" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_arg_max_axis_2_int32(context): @@ -2561,7 +2561,7 @@ def test_arg_max_axis_2_int32(context): output = builder.arg_max(x, axis=2, output_data_type="int32") assert output.shape == [2, 3] assert output.data_type == "int32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_arg_max_1d(context): @@ -2571,7 +2571,7 @@ def test_arg_max_1d(context): output = builder.arg_max(x, axis=0) assert output.shape == [] assert output.data_type == "int64" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_arg_max_1d_keep_dims(context): @@ -2581,7 +2581,7 @@ def test_arg_max_1d_keep_dims(context): output = builder.arg_max(x, axis=0, keep_dimensions=True) assert output.shape == [1] assert output.data_type == "int64" - graph = builder.build({"output": output}) + builder.build({"output": output}) # ArgMin tests @@ -2592,7 +2592,7 @@ def test_arg_min_axis_0_no_keep(context): output = builder.arg_min(x, axis=0) assert output.shape == [3, 4] assert output.data_type == "int64" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_arg_min_axis_1_keep_dims(context): @@ -2602,7 +2602,7 @@ def test_arg_min_axis_1_keep_dims(context): output = builder.arg_min(x, axis=1, keep_dimensions=True) assert output.shape == [2, 1, 4] assert output.data_type == "int64" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_arg_min_axis_2_int32(context): @@ -2612,7 +2612,7 @@ def test_arg_min_axis_2_int32(context): output = builder.arg_min(x, axis=2, output_data_type="int32") assert output.shape == [2, 3] assert output.data_type == "int32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_arg_min_1d(context): @@ -2622,7 +2622,7 @@ def test_arg_min_1d(context): output = builder.arg_min(x, axis=0) assert output.shape == [] assert output.data_type == "int64" - graph = builder.build({"output": output}) + builder.build({"output": output}) # Cast tests @@ -2633,7 +2633,7 @@ def test_cast_float32_to_int32(context): output = builder.cast(x, "int32") assert output.shape == [2, 3] assert output.data_type == "int32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_cast_int32_to_float32(context): @@ -2643,7 +2643,7 @@ def test_cast_int32_to_float32(context): output = builder.cast(x, "float32") assert output.shape == [2, 3] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_cast_float32_to_float16(context): @@ -2653,7 +2653,7 @@ def test_cast_float32_to_float16(context): output = builder.cast(x, "float16") assert output.shape == [2, 3, 4] assert output.data_type == "float16" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_cast_int8_to_uint8(context): @@ -2663,7 +2663,7 @@ def test_cast_int8_to_uint8(context): output = builder.cast(x, "uint8") assert output.shape == [10] assert output.data_type == "uint8" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_cast_to_int64(context): @@ -2673,7 +2673,7 @@ def test_cast_to_int64(context): output = builder.cast(x, "int64") assert output.shape == [5, 5] assert output.data_type == "int64" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_cast_preserves_shape(context): @@ -2683,7 +2683,7 @@ def test_cast_preserves_shape(context): output = builder.cast(x, "int32") assert output.shape == [2, 3, 4, 5] assert output.data_type == "int32" - graph = builder.build({"output": output}) + builder.build({"output": output}) # ScatterElements tests @@ -2696,7 +2696,7 @@ def test_scatter_elements_1d(context): output = builder.scatter_elements(data, indices, updates, axis=0) assert output.shape == [4] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_scatter_elements_2d_axis_0(context): @@ -2708,7 +2708,7 @@ def test_scatter_elements_2d_axis_0(context): output = builder.scatter_elements(data, indices, updates, axis=0) assert output.shape == [3, 4] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_scatter_elements_2d_axis_1(context): @@ -2720,7 +2720,7 @@ def test_scatter_elements_2d_axis_1(context): output = builder.scatter_elements(data, indices, updates, axis=1) assert output.shape == [3, 4] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_scatter_elements_3d(context): @@ -2731,7 +2731,7 @@ def test_scatter_elements_3d(context): updates = builder.input("updates", [2, 2, 4], "float32") output = builder.scatter_elements(data, indices, updates, axis=1) assert output.shape == [2, 3, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) # ScatterND tests @@ -2744,7 +2744,7 @@ def test_scatter_nd_basic(context): output = builder.scatter_nd(data, indices, updates) assert output.shape == [4, 5] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_scatter_nd_3d(context): @@ -2756,7 +2756,7 @@ def test_scatter_nd_3d(context): output = builder.scatter_nd(data, indices, updates) assert output.shape == [2, 3, 4] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_scatter_nd_full_rank(context): @@ -2767,7 +2767,7 @@ def test_scatter_nd_full_rank(context): updates = builder.input("updates", [5], "float32") # [5] + [] output = builder.scatter_nd(data, indices, updates) assert output.shape == [2, 3, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_scatter_nd_4d(context): @@ -2778,7 +2778,7 @@ def test_scatter_nd_4d(context): updates = builder.input("updates", [6, 4, 5], "float32") # [6] + [4, 5] output = builder.scatter_nd(data, indices, updates) assert output.shape == [2, 3, 4, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) # Tile tests @@ -2789,7 +2789,7 @@ def test_tile_1d(context): output = builder.tile(x, [2]) assert output.shape == [8] # 4 * 2 assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_tile_2d(context): @@ -2799,7 +2799,7 @@ def test_tile_2d(context): output = builder.tile(x, [2, 3]) assert output.shape == [4, 9] # 2*2, 3*3 assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_tile_no_repetition(context): @@ -2808,7 +2808,7 @@ def test_tile_no_repetition(context): x = builder.input("x", [2, 3, 4], "float32") output = builder.tile(x, [1, 1, 1]) assert output.shape == [2, 3, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_tile_different_repetitions(context): @@ -2817,7 +2817,7 @@ def test_tile_different_repetitions(context): x = builder.input("x", [2, 3], "float32") output = builder.tile(x, [3, 1]) assert output.shape == [6, 3] # 2*3, 3*1 - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_tile_4d(context): @@ -2826,7 +2826,7 @@ def test_tile_4d(context): x = builder.input("x", [1, 2, 3, 4], "float32") output = builder.tile(x, [2, 1, 2, 1]) assert output.shape == [2, 2, 6, 4] # 1*2, 2*1, 3*2, 4*1 - graph = builder.build({"output": output}) + builder.build({"output": output}) # Triangular tests @@ -2837,7 +2837,7 @@ def test_triangular_2d_upper(context): output = builder.triangular(x, True, 0) assert output.shape == [3, 3] assert output.data_type == "float32" - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_triangular_2d_lower(context): @@ -2846,7 +2846,7 @@ def test_triangular_2d_lower(context): x = builder.input("x", [3, 3], "float32") output = builder.triangular(x, False, 0) assert output.shape == [3, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_triangular_default_params(context): @@ -2855,7 +2855,7 @@ def test_triangular_default_params(context): x = builder.input("x", [4, 4], "float32") output = builder.triangular(x, True, 0) # explicit: upper=True, diagonal=0 assert output.shape == [4, 4] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_triangular_upper_diagonal_1(context): @@ -2864,7 +2864,7 @@ def test_triangular_upper_diagonal_1(context): x = builder.input("x", [3, 3], "float32") output = builder.triangular(x, True, 1) assert output.shape == [3, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_triangular_lower_diagonal_minus_1(context): @@ -2873,7 +2873,7 @@ def test_triangular_lower_diagonal_minus_1(context): x = builder.input("x", [3, 3], "float32") output = builder.triangular(x, False, -1) assert output.shape == [3, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_triangular_3d(context): @@ -2882,7 +2882,7 @@ def test_triangular_3d(context): x = builder.input("x", [2, 3, 3], "float32") output = builder.triangular(x, True, 0) assert output.shape == [2, 3, 3] - graph = builder.build({"output": output}) + builder.build({"output": output}) def test_triangular_non_square(context): @@ -2891,7 +2891,7 @@ def test_triangular_non_square(context): x = builder.input("x", [4, 5], "float32") output = builder.triangular(x, True, 0) assert output.shape == [4, 5] - graph = builder.build({"output": output}) + builder.build({"output": output}) # ============================================================================ diff --git a/tests/test_wpt_conformance.py b/tests/test_wpt_conformance.py index 29ea8aa..68dbe6b 100644 --- a/tests/test_wpt_conformance.py +++ b/tests/test_wpt_conformance.py @@ -226,7 +226,7 @@ def test_wpt_conformance(context, backend_name, wpt_test_case, wpt_file, operati if not graph: pytest.skip("Invalid WPT test case (missing graph)") - test_name = wpt_test_case.get("name", "") + wpt_test_case.get("name", "") skip_reason = should_skip_test(graph) if skip_reason: pytest.skip(skip_reason) diff --git a/tests/wpt_utils.py b/tests/wpt_utils.py index 67fa951..b73f9d5 100644 --- a/tests/wpt_utils.py +++ b/tests/wpt_utils.py @@ -107,7 +107,7 @@ def numpy_array_from_test_data(test_data: Dict[str, Any]) -> np.ndarray: np_dtype = dtype_map.get(dtype_str, np.float32) if isinstance(data, (int, float)): - total_elements = math.prod(shape) if shape else 1 + math.prod(shape) if shape else 1 fill = _parse_wpt_int64_scalar(data) if dtype_str == "int64" else data if dtype_str == "uint64": fill = int(data) From d77faa4a4641550e0139ed1be199c2f129c94972 Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Thu, 8 Oct 2026 20:07:38 +0200 Subject: [PATCH 3/4] ci: run ruff --- .github/workflows/lint.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index bfdd30f..6a6bed5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -47,7 +47,7 @@ jobs: - name: Install linting tools run: | pip install --upgrade pip - pip install black mypy + pip install black mypy ruff - name: Check Python formatting with black run: black --check python/ tests/ examples/ @@ -56,3 +56,7 @@ jobs: - name: Run mypy type checking run: mypy python/ continue-on-error: true + + - name: Run ruff + run: ruff + continue-on-error: true From cbfc6d5854a18ad679c05c8b2fc2a9a0b5952377 Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Thu, 8 Oct 2026 20:13:00 +0200 Subject: [PATCH 4/4] chore: remove unused statements --- tests/test_wpt_conformance.py | 1 - tests/wpt_utils.py | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/test_wpt_conformance.py b/tests/test_wpt_conformance.py index 68dbe6b..bb0fb76 100644 --- a/tests/test_wpt_conformance.py +++ b/tests/test_wpt_conformance.py @@ -226,7 +226,6 @@ def test_wpt_conformance(context, backend_name, wpt_test_case, wpt_file, operati if not graph: pytest.skip("Invalid WPT test case (missing graph)") - wpt_test_case.get("name", "") skip_reason = should_skip_test(graph) if skip_reason: pytest.skip(skip_reason) diff --git a/tests/wpt_utils.py b/tests/wpt_utils.py index b73f9d5..8016f82 100644 --- a/tests/wpt_utils.py +++ b/tests/wpt_utils.py @@ -107,7 +107,6 @@ def numpy_array_from_test_data(test_data: Dict[str, Any]) -> np.ndarray: np_dtype = dtype_map.get(dtype_str, np.float32) if isinstance(data, (int, float)): - math.prod(shape) if shape else 1 fill = _parse_wpt_int64_scalar(data) if dtype_str == "int64" else data if dtype_str == "uint64": fill = int(data)