Skip to content

Commit cb565be

Browse files
Update
[ghstack-poisoned]
2 parents 14ba473 + a1b81cc commit cb565be

13 files changed

Lines changed: 37 additions & 114 deletions

File tree

backends/webgpu/runtime/WebGPUGraph.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ void WebGPUGraph::build(
331331
value_types_[i] = ValueType::ValueList;
332332
const auto* items = val->value_as_ValueList()->items();
333333
if (items) {
334+
value_lists_[i].reserve(items->size());
334335
for (unsigned j = 0; j < items->size(); j++) {
335336
value_lists_[i].push_back(static_cast<int>(items->Get(j)));
336337
}

backends/webgpu/runtime/ops/sigmoid/UnaryOp.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ void sigmoid_impl(WebGPUGraph& graph, const std::vector<int>& args) {
3636
// 4-byte (fp32) alignment guard on both operands; also the dtype guard.
3737
if (in_tensor.nbytes % sizeof(float) != 0 ||
3838
out_tensor.nbytes % sizeof(float) != 0) {
39-
throw std::runtime_error(
40-
"sigmoid: operand not 4-byte aligned (expected fp32)");
39+
throw std::runtime_error("sigmoid: operand not 4-byte aligned");
4140
}
4241

4342
uint32_t num_elements =

backends/webgpu/runtime/ops/slice/Slice.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ void slice_impl(WebGPUGraph& graph, const std::vector<int>& args) {
7171
// Clamp start to [0, in_size] (guards the gather offset; out size is AOT).
7272
start = start < 0 ? 0 : (start > in_size ? in_size : start);
7373
const int64_t step = read_scalar(graph, args.at(4), 1, "step");
74+
if (step < 1) {
75+
throw std::runtime_error("slice: step must be >= 1");
76+
}
7477

7578
TensorMeta out_meta;
7679
TensorMeta in_meta;

backends/webgpu/runtime/ops/view_copy/ViewCopy.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ void add_flat_copy(WebGPUGraph& graph, int in_id, int out_id) {
4040

4141
const auto& in_tensor = graph.get_tensor(in_id);
4242
const auto& out_tensor = graph.get_tensor(out_id);
43+
// Flat byte copy assumes dense row-major operands; the WebGPU buffer
44+
// backend only produces contiguous tensors, so a strided/transposed
45+
// view cannot reach here.
4346

4447
// 4-byte (fp32) alignment guard on both operands; also the dtype guard.
4548
if (in_tensor.nbytes % sizeof(float) != 0 ||
4649
out_tensor.nbytes % sizeof(float) != 0) {
47-
throw std::runtime_error(
48-
"flat_copy: operand not 4-byte aligned (expected fp32)");
50+
throw std::runtime_error("flat_copy: operand not 4-byte aligned");
4951
}
5052

5153
const uint32_t in_numel =

backends/webgpu/test/ops/cat/test_cat.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
"""`aten.cat.default` module + configs for the WebGPU op-test framework.
88
99
`CatModule` + `CONFIGS` are imported by `cases.py` to drive the declarative op-test
10-
suite. `TestCat` is the export-delegation + eager-correctness smoke test.
10+
suite. `CatTest` is the export-delegation smoke test.
1111
"""
1212

1313
import unittest
1414

1515
import torch
1616

17-
from executorch.backends.vulkan import VulkanPartitioner
17+
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
1818
from executorch.exir import to_edge_transform_and_lower
1919

2020
# name -> (list_of_input_shapes, dim)
@@ -67,7 +67,7 @@ def _op_delegated(edge, op_substr: str) -> bool:
6767
return all(op_substr not in str(getattr(n, "target", "")) for n in gm.graph.nodes)
6868

6969

70-
class TestCat(unittest.TestCase):
70+
class CatTest(unittest.TestCase):
7171
def test_export_delegates(self) -> None:
7272
for name, (shapes, dim) in CONFIGS.items():
7373
edge = _lower(dim, _det_inputs(shapes))
@@ -79,12 +79,3 @@ def test_export_delegates(self) -> None:
7979
_op_delegated(edge, "cat"),
8080
f"cat not delegated (fell back to CPU) for {name}",
8181
)
82-
83-
def test_golden_matches_eager(self) -> None:
84-
for _, (shapes, dim) in CONFIGS.items():
85-
xs = _det_inputs(shapes)
86-
torch.testing.assert_close(CatModule(dim)(*xs), torch.cat(xs, dim))
87-
88-
89-
if __name__ == "__main__":
90-
unittest.main()

backends/webgpu/test/ops/mul/test_mul.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77
"""`aten.mul.Tensor` (full broadcast) module + configs for the WebGPU op-test framework.
88
99
`MulModule` + `CONFIGS` are imported by `cases.py` to drive the declarative op-test
10-
suite (export via VulkanPartitioner + fp64 torch golden, run on Dawn). `TestMul` is
11-
the export-delegation + eager-correctness smoke test. Configs span the same-shape
10+
suite (export via VulkanPartitioner + fp64 torch golden, run on Dawn). `MulTest` is
11+
the export-delegation smoke test. Configs span the same-shape
1212
fast path (SwiGLU), last-dim broadcast at LLM width, and a mixed-rank left-pad case.
1313
"""
1414

1515
import unittest
1616

1717
import torch
1818

19-
from executorch.backends.vulkan import VulkanPartitioner
19+
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
2020
from executorch.exir import to_edge_transform_and_lower
2121

2222
# name -> (shape_a, shape_b). Output shape is the broadcast of the two.
@@ -55,20 +55,11 @@ def _delegated(et) -> bool:
5555
)
5656

5757

58-
class TestMul(unittest.TestCase):
58+
class MulTest(unittest.TestCase):
5959
def test_export_delegates(self) -> None:
6060
for name, (sa, sb) in CONFIGS.items():
6161
a, b = _det_inputs(sa, sb)
6262
et = _export(a, b)
6363
self.assertTrue(
6464
_delegated(et), f"Expected a VulkanBackend delegate (mul {name})"
6565
)
66-
67-
def test_golden_matches_eager(self) -> None:
68-
for _, (sa, sb) in CONFIGS.items():
69-
a, b = _det_inputs(sa, sb)
70-
torch.testing.assert_close(MulModule()(a, b), a * b)
71-
72-
73-
if __name__ == "__main__":
74-
unittest.main()

backends/webgpu/test/ops/permute/test_permute.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
"""`aten.permute_copy.default` module + configs for the WebGPU op-test framework.
88
99
`PermuteModule` + `CONFIGS` are imported by `cases.py` to drive the declarative
10-
op-test suite. `TestPermute` is the export-delegation + eager-correctness smoke
10+
op-test suite. `PermuteTest` is the export-delegation smoke
1111
test.
1212
"""
1313

1414
import unittest
1515

1616
import torch
1717

18-
from executorch.backends.vulkan import VulkanPartitioner
18+
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
1919
from executorch.exir import to_edge_transform_and_lower
2020

2121
# name -> (input_shape, perm)
@@ -60,7 +60,7 @@ def _op_delegated(edge, op_substr: str) -> bool:
6060
return all(op_substr not in str(getattr(n, "target", "")) for n in gm.graph.nodes)
6161

6262

63-
class TestPermute(unittest.TestCase):
63+
class PermuteTest(unittest.TestCase):
6464
def test_export_delegates(self) -> None:
6565
for name, (shape, perm) in CONFIGS.items():
6666
edge = _lower(perm, _det_input(shape))
@@ -72,14 +72,3 @@ def test_export_delegates(self) -> None:
7272
_op_delegated(edge, "permute"),
7373
f"permute not delegated (fell back to CPU) for {name}",
7474
)
75-
76-
def test_golden_matches_eager(self) -> None:
77-
for _, (shape, perm) in CONFIGS.items():
78-
x = _det_input(shape)
79-
torch.testing.assert_close(
80-
PermuteModule(perm)(x), torch.permute(x, perm).contiguous()
81-
)
82-
83-
84-
if __name__ == "__main__":
85-
unittest.main()

backends/webgpu/test/ops/select/test_select.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"""`aten.select_copy.int` module + configs for the WebGPU op-test framework.
88
99
`SelectModule` + `CONFIGS` are imported by `cases.py` to drive the declarative
10-
op-test suite. `TestSelect` is the export-delegation + eager-correctness smoke test.
10+
op-test suite. `SelectTest` is the export-delegation smoke test.
1111
Configs cover the leading, middle, and last dim plus a negative index (output rank =
1212
input rank - 1).
1313
"""
@@ -16,7 +16,7 @@
1616

1717
import torch
1818

19-
from executorch.backends.vulkan import VulkanPartitioner
19+
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
2020
from executorch.exir import to_edge_transform_and_lower
2121

2222
# name -> (input_shape, select_fn)
@@ -57,19 +57,10 @@ def _delegated(et) -> bool:
5757
)
5858

5959

60-
class TestSelect(unittest.TestCase):
60+
class SelectTest(unittest.TestCase):
6161
def test_export_delegates(self) -> None:
6262
for name, (shape, fn) in CONFIGS.items():
6363
et = _export(fn, _det_input(shape))
6464
self.assertTrue(
6565
_delegated(et), f"Expected a VulkanBackend delegate (select {name})"
6666
)
67-
68-
def test_golden_matches_eager(self) -> None:
69-
for _, (shape, fn) in CONFIGS.items():
70-
x = _det_input(shape)
71-
torch.testing.assert_close(SelectModule(fn)(x), fn(x))
72-
73-
74-
if __name__ == "__main__":
75-
unittest.main()

backends/webgpu/test/ops/sigmoid/test_sigmoid.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"""`aten.sigmoid.default` module + input for the WebGPU op-test framework.
88
99
`SigmoidModule`, `N`, and `_det_input` are imported by `cases.py` to drive the
10-
declarative op-test suite. `TestSigmoid` is the export-delegation + eager-correctness
10+
declarative op-test suite. `SigmoidTest` is the export-delegation
1111
smoke test. Sigmoid is on the Llama critical path (`F.silu` -> `sigmoid` + `mul`); the
1212
deterministic input spans the saturation tails.
1313
"""
@@ -16,7 +16,7 @@
1616

1717
import torch
1818

19-
from executorch.backends.vulkan import VulkanPartitioner
19+
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
2020
from executorch.exir import to_edge_transform_and_lower
2121

2222
# Input length; the deterministic input spans the saturation tails.
@@ -40,7 +40,7 @@ def _export(m: torch.nn.Module, x: torch.Tensor):
4040
).to_executorch()
4141

4242

43-
class TestSigmoid(unittest.TestCase):
43+
class SigmoidTest(unittest.TestCase):
4444
def test_export_delegates(self) -> None:
4545
et = _export(SigmoidModule().eval(), _det_input())
4646
found = any(
@@ -49,11 +49,3 @@ def test_export_delegates(self) -> None:
4949
for d in plan.delegates
5050
)
5151
self.assertTrue(found, "Expected a VulkanBackend delegate (sigmoid)")
52-
53-
def test_golden_matches_eager(self) -> None:
54-
x = _det_input()
55-
torch.testing.assert_close(SigmoidModule()(x), torch.sigmoid(x))
56-
57-
58-
if __name__ == "__main__":
59-
unittest.main()

backends/webgpu/test/ops/slice/test_slice.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
"""`aten.slice_copy.Tensor` module + configs for the WebGPU op-test framework.
88
99
`SliceModule` + `CONFIGS` are imported by `cases.py` to drive the declarative
10-
op-test suite. `TestSlice` is the export-delegation + eager-correctness smoke
10+
op-test suite. `SliceTest` is the export-delegation smoke
1111
test.
1212
"""
1313

1414
import unittest
1515

1616
import torch
1717

18-
from executorch.backends.vulkan import VulkanPartitioner
18+
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
1919
from executorch.exir import to_edge_transform_and_lower
2020

2121
# name -> (input_shape, slice_fn)
@@ -56,19 +56,10 @@ def _delegated(et) -> bool:
5656
)
5757

5858

59-
class TestSlice(unittest.TestCase):
59+
class SliceTest(unittest.TestCase):
6060
def test_export_delegates(self) -> None:
6161
for name, (shape, fn) in CONFIGS.items():
6262
et = _export(fn, _det_input(shape))
6363
self.assertTrue(
6464
_delegated(et), f"Expected a VulkanBackend delegate (slice {name})"
6565
)
66-
67-
def test_golden_matches_eager(self) -> None:
68-
for _, (shape, fn) in CONFIGS.items():
69-
x = _det_input(shape)
70-
torch.testing.assert_close(SliceModule(fn)(x), fn(x))
71-
72-
73-
if __name__ == "__main__":
74-
unittest.main()

0 commit comments

Comments
 (0)