Xenova HF Staff commited on
Commit
cadd417
·
verified ·
1 Parent(s): 9e7cac1

sync 2e7068faf55e

Browse files
README.md CHANGED
@@ -1,3 +1,81 @@
1
  ---
 
2
  license: apache-2.0
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ library_name: kernels
3
  license: apache-2.0
4
+ tags:
5
+ - kernel
6
+ - webgpu
7
+ - wgsl
8
  ---
9
+ # ai.onnx.Range
10
+
11
+ `ai.onnx` · standard ONNX operator · ONNX opset ≥ 27
12
+
13
+ ## Description
14
+
15
+ Generates a 1-D tensor of numbers starting at `start`, incrementing by `delta`, up to but not including `limit`. The output length is `max(ceil((limit - start) / delta), 0)`, and element `i` equals `start + i * delta`. Float16 inputs use float32 intermediate arithmetic when `stash_type` is `1`, then cast each result back to float16.
16
+
17
+ See the [ONNX `Range` spec](https://onnx.ai/onnx/operators/onnx__Range.html) for the reference semantics.
18
+
19
+ ## Inputs
20
+
21
+ | Name | Bind key | Logical dtype | Rank | Shape | Description | Presence |
22
+ | --- | --- | --- | --- | --- | --- | --- |
23
+ | `start` | `start` | `T` | `0` | — | Scalar first value in the output sequence. | required |
24
+ | `limit` | `limit` | `T` | `0` | — | Scalar exclusive upper bound of the sequence. | required |
25
+ | `delta` | `delta` | `T` | `0` | — | Scalar step size between consecutive output values. | required |
26
+
27
+ ## Outputs
28
+
29
+ | Name | Bind key | Logical dtype | Rank | Shape | Description | Presence |
30
+ | --- | --- | --- | --- | --- | --- | --- |
31
+ | `output` | `output` | `T` | `1` | — | 1-D tensor containing the generated range of values, with the same dtype as the inputs. | required |
32
+
33
+ ## Attributes
34
+
35
+ Default values (overridable per request):
36
+
37
+ | Attribute | Default | Description |
38
+ | --- | --- | --- |
39
+ | `stash_type` | `1` | TensorProto element type used for float16 intermediate arithmetic; this implementation supports the standard float32 value (`1`). It has no effect for float32 and int32 inputs. |
40
+
41
+ ## Type constraints
42
+
43
+ | Variable | Allowed dtypes |
44
+ | --- | --- |
45
+ | `T` | `float32`, `float16`, `int32` |
46
+
47
+ ## Files
48
+
49
+ - [`metadata.json`](build/webgpu/metadata.json) — kernel metadata (id, digests, provenance)
50
+ - [`manifest.json`](build/webgpu/manifest.json) — the op contract (source of truth)
51
+ - [`test.json`](build/webgpu/test.json) — correctness cases
52
+ - [`bench.json`](build/webgpu/bench.json) — benchmark + tuning cases
53
+ - [`range.wgsl.jinja`](build/webgpu/range.wgsl.jinja)
54
+
55
+ ## Use with `@huggingface/kernels`
56
+
57
+ The loader automatically allocates outputs whose metadata it can derive from the manifest contract and this call.
58
+
59
+ The explicit `outputs` entries provide shape and logical dtype metadata for the results listed below:
60
+
61
+ - `output`
62
+
63
+ Each entry either requests an optional result or supplies metadata that cannot be inferred from the inputs.
64
+
65
+ The `version: 1` option selects the published kernel contract; it is independent of any operator opset, contrib `since_version`, or model version.
66
+
67
+ Replace each `*Data` placeholder with a typed array containing the corresponding input data.
68
+
69
+ ```js
70
+ import { getKernel } from "@huggingface/kernels";
71
+
72
+ const kernel = await getKernel("webgpu-kernels/ai.onnx.Range", { version: 1 });
73
+ // Explicit destinations request optional results or supply metadata that cannot be inferred.
74
+ const { output } = await kernel({
75
+ start: { data: startData, shape: [] },
76
+ limit: { data: limitData, shape: [] },
77
+ delta: { data: deltaData, shape: [] },
78
+ }, {
79
+ outputs: { output: { shape: [1], dtype: "float32" } },
80
+ });
81
+ ```
build/webgpu/bench.json ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "op": "ai.onnx.Range",
3
+ "cases": [
4
+ {
5
+ "name": "positions_4096",
6
+ "inputs": {
7
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
8
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [4096] } },
9
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
10
+ },
11
+ "outputs": { "output": { "dtype": "int32", "shape": [4096] } }
12
+ },
13
+ {
14
+ "name": "large_fill_i32_16777216",
15
+ "preset": "smoke",
16
+ "vars": { "dtype": "int32" },
17
+ "inputs": {
18
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
19
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [16777216] } },
20
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
21
+ },
22
+ "outputs": { "output": { "dtype": "int32", "shape": [16777216], "dist": "empty" } },
23
+ "bench": {
24
+ "primary": true,
25
+ "metrics": [{ "type": "bandwidth", "value": "numel(shapes.output) * dtypeBytes(args.dtype)" }]
26
+ }
27
+ },
28
+ {
29
+ "name": "large_fill_f32_16777216",
30
+ "preset": "smoke",
31
+ "vars": { "dtype": "float32" },
32
+ "inputs": {
33
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [0.0] } },
34
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [16777216.0] } },
35
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1.0] } }
36
+ },
37
+ "outputs": { "output": { "dtype": "float32", "shape": [16777216], "dist": "empty" } },
38
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "numel(shapes.output) * dtypeBytes(args.dtype)" }] }
39
+ },
40
+ {
41
+ "name": "dispatch_cliff_2dfold_i32_16777216",
42
+ "preset": "smoke",
43
+ "vars": { "dtype": "int32" },
44
+ "inputs": {
45
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
46
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [16777216] } },
47
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
48
+ },
49
+ "outputs": { "output": { "dtype": "int32", "shape": [16777216], "dist": "empty" } },
50
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "numel(shapes.output) * dtypeBytes(args.dtype)" }] }
51
+ },
52
+ {
53
+ "name": "dispatch_single_dim_i32_16776960",
54
+ "preset": "smoke",
55
+ "vars": { "dtype": "int32" },
56
+ "inputs": {
57
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
58
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [16776960] } },
59
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
60
+ },
61
+ "outputs": { "output": { "dtype": "int32", "shape": [16776960], "dist": "empty" } },
62
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "numel(shapes.output) * dtypeBytes(args.dtype)" }] }
63
+ },
64
+ {
65
+ "name": "tiny_overhead_bound_i32_4096",
66
+ "preset": "smoke",
67
+ "vars": { "dtype": "int32" },
68
+ "inputs": {
69
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
70
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [4096] } },
71
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
72
+ },
73
+ "outputs": { "output": { "dtype": "int32", "shape": [4096], "dist": "empty" } },
74
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "numel(shapes.output) * dtypeBytes(args.dtype)" }] }
75
+ }
76
+ ]
77
+ }
build/webgpu/manifest.json ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "domain": "ai.onnx",
3
+ "name": "Range",
4
+ "sinceVersion": 27,
5
+ "description": "Generates a 1-D tensor of numbers starting at `start`, incrementing by `delta`, up to but not including `limit`. The output length is `max(ceil((limit - start) / delta), 0)`, and element `i` equals `start + i * delta`. Float16 inputs use float32 intermediate arithmetic when `stash_type` is `1`, then cast each result back to float16.",
6
+ "inputs": [
7
+ { "role": "start", "dtype": "T", "description": "Scalar first value in the output sequence.", "rank": 0 },
8
+ { "role": "limit", "dtype": "T", "description": "Scalar exclusive upper bound of the sequence.", "rank": 0 },
9
+ { "role": "delta", "dtype": "T", "description": "Scalar step size between consecutive output values.", "rank": 0 }
10
+ ],
11
+ "outputs": [
12
+ {
13
+ "role": "output",
14
+ "dtype": "T",
15
+ "description": "1-D tensor containing the generated range of values, with the same dtype as the inputs.",
16
+ "rank": 1
17
+ }
18
+ ],
19
+ "attributes": { "stash_type": 1 },
20
+ "attributeDescriptions": {
21
+ "stash_type": "TensorProto element type used for float16 intermediate arithmetic; this implementation supports the standard float32 value (`1`). It has no effect for float32 and int32 inputs."
22
+ },
23
+ "typeConstraints": { "T": ["float32", "float16", "int32"] },
24
+ "args": {
25
+ "start": { "kind": "tensor", "semantic": "start", "role": "start" },
26
+ "limit": { "kind": "tensor", "semantic": "limit", "role": "limit" },
27
+ "delta": { "kind": "tensor", "semantic": "delta", "role": "delta" },
28
+ "output": { "kind": "tensor", "semantic": "output", "role": "output" }
29
+ },
30
+ "tunables": { "WORKGROUP_SIZE": 256 },
31
+ "variants": [
32
+ {
33
+ "id": "scalar_inputs",
34
+ "when": ["ranks.start == 0", "ranks.limit == 0", "ranks.delta == 0", "ranks.output == 1", "(dtypes.T == \"f32\" or dtypes.T == \"f16\" or dtypes.T == \"i32\")", "f16Ok(dtypes.T)", "logicalDtypes.T != \"float16\" or attrs.stash_type == onnxDtypeCode(\"float32\")"],
35
+ "constants": {
36
+ "scalar": "dtypes.T",
37
+ "isI32": "dtypes.T == \"i32\"",
38
+ "isF16": "dtypes.T == \"f16\"",
39
+ "usesF16": "dtypes.T == \"f16\"",
40
+ "vec4": "numel(shapes.output) > 0 and numel(shapes.output) % 4 == 0",
41
+ "outElement": "(\"vec4<\" ~ dtypes.T ~ \">\") if (numel(shapes.output) > 0 and numel(shapes.output) % 4 == 0) else dtypes.T"
42
+ },
43
+ "passes": [
44
+ {
45
+ "id": "main",
46
+ "name": "Range",
47
+ "shader": "range.wgsl.jinja",
48
+ "bindings": [
49
+ {
50
+ "name": "start",
51
+ "arg": "start",
52
+ "semantic": "start",
53
+ "buffer": { "type": "read-only-storage" },
54
+ "elementType": "$scalar",
55
+ "length": 1
56
+ },
57
+ {
58
+ "name": "delta",
59
+ "arg": "delta",
60
+ "semantic": "delta",
61
+ "buffer": { "type": "read-only-storage" },
62
+ "elementType": "$scalar",
63
+ "length": 1
64
+ },
65
+ {
66
+ "name": "output",
67
+ "arg": "output",
68
+ "semantic": "output",
69
+ "buffer": { "type": "storage" },
70
+ "elementType": "$outElement"
71
+ },
72
+ {
73
+ "name": "params",
74
+ "semantic": "kernel.params",
75
+ "buffer": { "type": "uniform" },
76
+ "struct": {
77
+ "name": "Params",
78
+ "fields": [
79
+ { "name": "count", "type": "u32", "value": "numel(shapes.output)" },
80
+ { "name": "countV4", "type": "u32", "value": "ceilDiv(numel(shapes.output), 4)" }
81
+ ]
82
+ }
83
+ }
84
+ ],
85
+ "dispatch": { "threads": "ceilDiv(numel(shapes.output), 4)", "workgroupSize": "tunables.WORKGROUP_SIZE" }
86
+ }
87
+ ]
88
+ }
89
+ ]
90
+ }
build/webgpu/metadata.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "ai.onnx.Range",
3
+ "id": "_ai_onnx_range_webgpu_ee87b02",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "backend": { "type": "webgpu" },
7
+ "digest": {
8
+ "algorithm": "sha256",
9
+ "files": {
10
+ "bench.json": "xMGgyqKg5gqzD5cxTqsYuMjzoLMNnUwayCGjdcxlZQ4=",
11
+ "manifest.json": "KVdMY/jv0Fvuemw67Mwx/pCr0u50yj4Mv8mW96vthrg=",
12
+ "range.wgsl.jinja": "y8duBaW6JJX+aryiqb6ngPZwW1p9wylUeTbQhzHk7yY=",
13
+ "test.json": "Tke9pc1jbyjPaMJF3Wxcu129odh9ujdY/1j4rs4SP6M="
14
+ }
15
+ },
16
+ "provenance": { "kernel": { "sha": "2e7068faf55e7f43df740015f6d1ee49391a41c5", "dirty": false } },
17
+ "webgpu": { "manifestSpec": "1.0", "specialized": true, "opPath": "ops/ai.onnx.Range" }
18
+ }
build/webgpu/range.wgsl.jinja ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% if usesF16 %}
2
+ enable f16;
3
+ {% endif %}
4
+ {{ env.wgsl.resourceDeclarations }}
5
+
6
+ // Each output is evaluated independently as start + i*delta rather than by
7
+ // accumulating deltas, preserving the same result across vector widths.
8
+ {% macro value(i) %}
9
+ {% if isI32 %}start[0] + i32({{ i }}) * delta[0]{% elif isF16 %}f16(f32(start[0]) + f32({{ i }}) * f32(delta[0])){% else %}start[0] + f32({{ i }}) * delta[0]{% endif %}
10
+ {% endmacro %}
11
+ @compute @workgroup_size({{ tunables.WORKGROUP_SIZE }})
12
+ fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) nwg: vec3<u32>) {
13
+ // Generate four adjacent values per invocation while retaining scalar
14
+ // storage for arbitrary output lengths.
15
+ let q = gid.x + gid.y * nwg.x * {{ tunables.WORKGROUP_SIZE }}u;
16
+ let base = q * 4u;
17
+ {% if vec4 %}
18
+ // A whole number of quads lets each invocation write one vec4 without a tail.
19
+ if (q >= params.countV4) {
20
+ return;
21
+ }
22
+ output[q] = vec4<{{ scalar }}>(
23
+ {{ value('base') }},
24
+ {{ value('(base + 1u)') }},
25
+ {{ value('(base + 2u)') }},
26
+ {{ value('(base + 3u)') }});
27
+ {% else %}
28
+ if (base >= params.count) {
29
+ return;
30
+ }
31
+ let end = min(base + 4u, params.count);
32
+ for (var i = base; i < end; i = i + 1u) {
33
+ output[i] = {{ value('i') }};
34
+ }
35
+ {% endif %}
36
+ }
build/webgpu/test.json ADDED
@@ -0,0 +1,391 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "op": "ai.onnx.Range",
3
+ "cases": [
4
+ {
5
+ "name": "dispatch_cliff_i32_16777216",
6
+ "inputs": {
7
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
8
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [16777216] } },
9
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
10
+ },
11
+ "outputs": { "output": { "dtype": "int32", "shape": [16777216], "tolerance": 0 } }
12
+ },
13
+ {
14
+ "name": "f32_positive",
15
+ "provenance": {
16
+ "notes": "Range-27 defines stash_type only for float16/bfloat16 accumulation, so the non-default FLOAT16 code has no effect on this float32 route."
17
+ },
18
+ "attrs": { "stash_type": 10 },
19
+ "inputs": {
20
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1.5] } },
21
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [6.0] } },
22
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1.5] } }
23
+ },
24
+ "outputs": { "output": { "dtype": "float32", "shape": [3] } }
25
+ },
26
+ {
27
+ "name": "i32_scalar_inputs_positive_delta",
28
+ "provenance": {
29
+ "notes": "Covers a positive integer step whose interval length is exactly divisible by the step."
30
+ },
31
+ "inputs": {
32
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [4] } },
33
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [10] } },
34
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [2] } }
35
+ },
36
+ "outputs": { "output": { "dtype": "int32", "shape": [3] } }
37
+ },
38
+ {
39
+ "name": "f32_true_scalar_inputs",
40
+ "inputs": {
41
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-1.5] } },
42
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [2.0] } },
43
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1.0] } }
44
+ },
45
+ "outputs": { "output": { "dtype": "float32", "shape": [4], "tolerance": 0.000001 } }
46
+ },
47
+ {
48
+ "name": "f32_negative_delta",
49
+ "provenance": {
50
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
51
+ "test": "RangeTest.Float_NegativeDelta_0"
52
+ },
53
+ "inputs": {
54
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [2.0] } },
55
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-8.1] } },
56
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-2.0] } }
57
+ },
58
+ "outputs": { "output": { "dtype": "float32", "shape": [6], "tolerance": 0.000001 } }
59
+ },
60
+ {
61
+ "name": "f32_negative_delta_empty",
62
+ "inputs": {
63
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [2.0] } },
64
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [9.0] } },
65
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-2.0] } }
66
+ },
67
+ "outputs": { "output": { "dtype": "float32", "shape": [0], "tolerance": 0 } }
68
+ },
69
+ {
70
+ "name": "f32_same_start_limit_empty",
71
+ "provenance": {
72
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
73
+ "test": "RangeTest.Float_SameStartAndLimit"
74
+ },
75
+ "inputs": {
76
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [2.0] } },
77
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [2.0] } },
78
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1.0] } }
79
+ },
80
+ "outputs": { "output": { "dtype": "float32", "shape": [0], "tolerance": 0 } }
81
+ },
82
+ {
83
+ "name": "f32_almost_same_high_delta_one_value",
84
+ "provenance": {
85
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
86
+ "test": "RangeTest.AlmostSameStartAndLimitHighDelta"
87
+ },
88
+ "inputs": {
89
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [2.0] } },
90
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [2.01] } },
91
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1000000.0] } }
92
+ },
93
+ "outputs": { "output": { "dtype": "float32", "shape": [1], "tolerance": 0 } }
94
+ },
95
+ {
96
+ "name": "f32_subnormal_positive_delta_length_rounding_gpu_gap",
97
+ "skipGpu": {
98
+ "category": "permanent",
99
+ "reason": "Portable WGSL floating-point semantics do not guarantee preservation of the subnormal values required by this fixture. Backend evidence: Metal FTZ: subnormal f32 start/limit/delta (1e-40) flush to zero on GPU, so the generated range collapses to zeros instead of the subnormal sequence (tolerance 2e-45)."
100
+ },
101
+ "provenance": {
102
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
103
+ "test": "RangeTest.Float_Delta_NonDefault",
104
+ "notes": "Valid float32 denormal-step edge: ORT computes length from rounded f32 inputs, producing five values for [0, 4e-40) at delta 1e-40."
105
+ },
106
+ "inputs": {
107
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [0.0] } },
108
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [4e-40] } },
109
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1e-40] } }
110
+ },
111
+ "outputs": {
112
+ "output": {
113
+ "dtype": "float32",
114
+ "shape": [5],
115
+ "tolerance": 2e-45,
116
+ "data": {
117
+ "kind": "values",
118
+ "values": [0.0, 9.99994610111476e-41, 1.999989220222952e-40, 2.999983830334428e-40, 3.999978440445904e-40]
119
+ }
120
+ }
121
+ }
122
+ },
123
+ {
124
+ "name": "f32_subnormal_negative_delta_length_rounding_gpu_gap",
125
+ "skipGpu": {
126
+ "category": "permanent",
127
+ "reason": "Portable WGSL floating-point semantics do not guarantee preservation of the subnormal values required by this fixture. Backend evidence: Metal FTZ: subnormal f32 start/limit/delta (1e-40) flush to zero on GPU, so the generated range collapses to zeros instead of the subnormal sequence (tolerance 2e-45)."
128
+ },
129
+ "provenance": {
130
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
131
+ "test": "RangeTest.Float_NegativeDelta_0",
132
+ "notes": "Negative denormal-step companion; the output shape and values follow ORT's rounded float32 Range semantics."
133
+ },
134
+ "inputs": {
135
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [0.0] } },
136
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-4e-40] } },
137
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-1e-40] } }
138
+ },
139
+ "outputs": {
140
+ "output": {
141
+ "dtype": "float32",
142
+ "shape": [5],
143
+ "tolerance": 2e-45,
144
+ "data": {
145
+ "kind": "values",
146
+ "values": [0.0, -9.99994610111476e-41, -1.999989220222952e-40, -2.999983830334428e-40, -3.999978440445904e-40]
147
+ }
148
+ }
149
+ }
150
+ },
151
+ {
152
+ "name": "f32_subnormal_positive_delta_shifted_start_gpu_gap",
153
+ "skipGpu": {
154
+ "category": "permanent",
155
+ "reason": "Portable WGSL floating-point semantics do not guarantee preservation of the subnormal values required by this fixture. Backend evidence: Metal FTZ: subnormal f32 start/limit/delta (1e-40) flush to zero on GPU, so the generated range collapses to zeros instead of the subnormal sequence (tolerance 2e-45)."
156
+ },
157
+ "provenance": {
158
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
159
+ "test": "RangeTest.Float_Delta_NonDefault",
160
+ "notes": "Shifted-start companion to the denormal-step Range edge: every output value is a valid positive subnormal, including the first element."
161
+ },
162
+ "inputs": {
163
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1e-40] } },
164
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [5e-40] } },
165
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1e-40] } }
166
+ },
167
+ "outputs": { "output": { "dtype": "float32", "shape": [5], "tolerance": 2e-45 } }
168
+ },
169
+ {
170
+ "name": "f32_subnormal_negative_delta_shifted_start_gpu_gap",
171
+ "skipGpu": {
172
+ "category": "permanent",
173
+ "reason": "Portable WGSL floating-point semantics do not guarantee preservation of the subnormal values required by this fixture. Backend evidence: Metal FTZ: subnormal f32 start/limit/delta (1e-40) flush to zero on GPU, so the generated range collapses to zeros instead of the subnormal sequence (tolerance 2e-45)."
174
+ },
175
+ "provenance": {
176
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
177
+ "test": "RangeTest.Float_NegativeDelta_0",
178
+ "notes": "Negative shifted-start companion: the generated sequence should preserve finite negative subnormal values instead of flushing the range to zeros."
179
+ },
180
+ "inputs": {
181
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-1e-40] } },
182
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-5e-40] } },
183
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [-1e-40] } }
184
+ },
185
+ "outputs": { "output": { "dtype": "float32", "shape": [5], "tolerance": 2e-45 } }
186
+ },
187
+ {
188
+ "name": "ort_f32_delta_default_style",
189
+ "provenance": {
190
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
191
+ "test": "RangeTest.Float_DeltaDefault"
192
+ },
193
+ "inputs": {
194
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [0.0] } },
195
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [5.0] } },
196
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1.0] } }
197
+ },
198
+ "outputs": { "output": { "dtype": "float32", "shape": [5], "tolerance": 0 } }
199
+ },
200
+ {
201
+ "name": "ort_i32_delta_default_style",
202
+ "provenance": {
203
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
204
+ "test": "RangeTest.Int32_DeltaDefault"
205
+ },
206
+ "inputs": {
207
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
208
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [5] } },
209
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
210
+ },
211
+ "outputs": { "output": { "dtype": "int32", "shape": [5], "tolerance": 0 } }
212
+ },
213
+ {
214
+ "name": "ort_i32_delta_nondefault_even",
215
+ "provenance": {
216
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
217
+ "test": "RangeTest.Int32_Delta_NonDefault"
218
+ },
219
+ "inputs": {
220
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
221
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [10] } },
222
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [2] } }
223
+ },
224
+ "outputs": { "output": { "dtype": "int32", "shape": [5], "tolerance": 0 } }
225
+ },
226
+ {
227
+ "name": "ort_i32_delta_nondefault_odd_limit",
228
+ "provenance": {
229
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
230
+ "test": "RangeTest.Int64_Delta_NonDefault_0",
231
+ "notes": "Native int32 projection of ORT's int64 odd-limit nondefault-delta case."
232
+ },
233
+ "inputs": {
234
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [0] } },
235
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [9] } },
236
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [2] } }
237
+ },
238
+ "outputs": { "output": { "dtype": "int32", "shape": [5], "tolerance": 0 } }
239
+ },
240
+ {
241
+ "name": "ort_i32_delta_nondefault_one_value",
242
+ "provenance": {
243
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
244
+ "test": "RangeTest.Int64_Delta_NonDefault_1",
245
+ "notes": "Native int32 projection of ORT's int64 one-value nondefault-delta case."
246
+ },
247
+ "inputs": {
248
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } },
249
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [2] } },
250
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [2] } }
251
+ },
252
+ "outputs": { "output": { "dtype": "int32", "shape": [1], "tolerance": 0 } }
253
+ },
254
+ {
255
+ "name": "ort_i32_negative_delta",
256
+ "provenance": {
257
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
258
+ "test": "RangeTest.Int32_NegativeDelta_0"
259
+ },
260
+ "inputs": {
261
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [2] } },
262
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [-9] } },
263
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [-2] } }
264
+ },
265
+ "outputs": { "output": { "dtype": "int32", "shape": [6], "tolerance": 0 } }
266
+ },
267
+ {
268
+ "name": "ort_i32_negative_delta_empty",
269
+ "provenance": {
270
+ "source": "onnxruntime/test/providers/cpu/generator/range_test.cc",
271
+ "test": "RangeTest.Int32_NegativeDelta_1"
272
+ },
273
+ "inputs": {
274
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [2] } },
275
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [9] } },
276
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [-2] } }
277
+ },
278
+ "outputs": { "output": { "dtype": "int32", "shape": [0], "tolerance": 0 } }
279
+ },
280
+ {
281
+ "name": "i32_exact_above_float24_no_f32_cast",
282
+ "inputs": {
283
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [16777217] } },
284
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [16777221] } },
285
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
286
+ },
287
+ "outputs": { "output": { "dtype": "int32", "shape": [4], "tolerance": 0 } }
288
+ },
289
+ {
290
+ "name": "onnx_backend_range_float_type_positive_delta",
291
+ "provenance": { "source": "cmake/external/onnx/onnx/backend/test/data/node/test_range_float_type_positive_delta" },
292
+ "inputs": {
293
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1.0] } },
294
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [5.0] } },
295
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [2.0] } }
296
+ },
297
+ "outputs": { "output": { "dtype": "float32", "shape": [2], "tolerance": 0 } }
298
+ },
299
+ {
300
+ "name": "onnx_backend_range_int32_type_negative_delta",
301
+ "provenance": { "source": "cmake/external/onnx/onnx/backend/test/data/node/test_range_int32_type_negative_delta" },
302
+ "inputs": {
303
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [10] } },
304
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [6] } },
305
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [-3] } }
306
+ },
307
+ "outputs": { "output": { "dtype": "int32", "shape": [2], "tolerance": 0 } }
308
+ },
309
+ {
310
+ "name": "f32_2dfold_dispatch_16777216",
311
+ "inputs": {
312
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [0.0] } },
313
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [16777216.0] } },
314
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [1.0] } }
315
+ },
316
+ "outputs": { "output": { "dtype": "float32", "shape": [16777216], "tolerance": 0 } }
317
+ },
318
+ {
319
+ "name": "f32_fractional_delta_nonmult4_len1027",
320
+ "inputs": {
321
+ "start": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [0.0] } },
322
+ "limit": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [256.75] } },
323
+ "delta": { "dtype": "float32", "shape": [], "data": { "kind": "values", "values": [0.25] } }
324
+ },
325
+ "outputs": { "output": { "dtype": "float32", "shape": [1027], "tolerance": 0 } }
326
+ },
327
+ {
328
+ "name": "i32_negative_start_positive_delta_len8",
329
+ "inputs": {
330
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [-3] } },
331
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [5] } },
332
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [1] } }
333
+ },
334
+ "outputs": { "output": { "dtype": "int32", "shape": [8], "tolerance": 0 } }
335
+ },
336
+ {
337
+ "name": "i32_negative_start_negative_delta_descending",
338
+ "provenance": {
339
+ "notes": "Negative start with negative delta produces a descending negative sequence [-5,-8,-11,-14,-17]; exercises start + i32(i)*delta with a negative base and negative step, a sign combination not covered by existing negative-delta cases (which start positive)."
340
+ },
341
+ "inputs": {
342
+ "start": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [-5] } },
343
+ "limit": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [-20] } },
344
+ "delta": { "dtype": "int32", "shape": [], "data": { "kind": "values", "values": [-3] } }
345
+ },
346
+ "outputs": { "output": { "dtype": "int32", "shape": [5], "tolerance": 0 } }
347
+ },
348
+ {
349
+ "name": "onnx27_f16_stash_float32_vec4",
350
+ "provenance": {
351
+ "source": "ONNX Operators.md Range-27",
352
+ "notes": "Pins the float16 type and explicit float32 stash semantics added by Range-27 on the vec4 output route."
353
+ },
354
+ "attrs": { "stash_type": 1 },
355
+ "inputs": {
356
+ "start": { "dtype": "float16", "shape": [], "data": { "kind": "values", "values": [2048.0] } },
357
+ "limit": { "dtype": "float16", "shape": [], "data": { "kind": "values", "values": [2052.0] } },
358
+ "delta": { "dtype": "float16", "shape": [], "data": { "kind": "values", "values": [1.0] } }
359
+ },
360
+ "outputs": {
361
+ "output": {
362
+ "dtype": "float16",
363
+ "shape": [4],
364
+ "data": { "kind": "values", "values": [2048.0, 2048.0, 2050.0, 2052.0] },
365
+ "tolerance": 0
366
+ }
367
+ }
368
+ },
369
+ {
370
+ "name": "onnx27_f16_stash_float32_scalar_tail",
371
+ "provenance": {
372
+ "source": "ONNX Operators.md Range-27",
373
+ "notes": "Non-multiple-of-four companion which pins float32 accumulation followed by a float16 cast on the scalar-tail route."
374
+ },
375
+ "attrs": { "stash_type": 1 },
376
+ "inputs": {
377
+ "start": { "dtype": "float16", "shape": [], "data": { "kind": "values", "values": [-1.5] } },
378
+ "limit": { "dtype": "float16", "shape": [], "data": { "kind": "values", "values": [0.0] } },
379
+ "delta": { "dtype": "float16", "shape": [], "data": { "kind": "values", "values": [0.5] } }
380
+ },
381
+ "outputs": {
382
+ "output": {
383
+ "dtype": "float16",
384
+ "shape": [3],
385
+ "data": { "kind": "values", "values": [-1.5, -1.0, -0.5] },
386
+ "tolerance": 0
387
+ }
388
+ }
389
+ }
390
+ ]
391
+ }