Skip to content

Commit 56c6edd

Browse files
committed
Update
[ghstack-poisoned]
1 parent e22789d commit 56c6edd

3 files changed

Lines changed: 124 additions & 0 deletions

File tree

backends/vulkan/test/op_tests/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ if(TARGET vulkan_backend AND LIB_TORCH)
120120
adamw_step_test ${CMAKE_CURRENT_SOURCE_DIR}/adamw_step_test.cpp
121121
test_utils
122122
)
123+
vulkan_op_test(
124+
linear_q4gsw_dw_test ${CMAKE_CURRENT_SOURCE_DIR}/linear_q4gsw_dw_test.cpp
125+
test_utils
126+
)
123127

124128
# Only build generated op tests if a path to tags.yaml and
125129
# native_functions.yaml is provided. These files are required for codegen.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#include <gtest/gtest.h>
10+
11+
#include <ATen/ATen.h>
12+
13+
#include <executorch/backends/vulkan/runtime/api/api.h>
14+
#include <executorch/backends/vulkan/runtime/graph/ComputeGraph.h>
15+
#include <executorch/backends/vulkan/runtime/graph/ops/OperatorRegistry.h>
16+
17+
#include "test_utils.h"
18+
19+
//
20+
// Reference Implementation
21+
//
22+
23+
// Golden: dW[N, K] = d_out^T @ x, contracting over the flattened leading dims.
24+
// Mirrors the CPU-eager linear_q4gsw_dw_impl in custom_ops_lib.py.
25+
at::Tensor linear_q4gsw_dw_reference_impl(
26+
const at::Tensor& d_out,
27+
const at::Tensor& x) {
28+
const int64_t N = d_out.size(-1);
29+
const int64_t K = x.size(-1);
30+
return d_out.reshape({-1, N})
31+
.t()
32+
.matmul(x.reshape({-1, K}))
33+
.contiguous();
34+
}
35+
36+
//
37+
// Test function
38+
//
39+
40+
void test_vulkan_linear_q4gsw_dw_impl(
41+
const std::vector<int64_t>& d_out_sizes,
42+
const std::vector<int64_t>& x_sizes,
43+
const vkcompute::utils::StorageType storage =
44+
vkcompute::utils::kBuffer) {
45+
at::Tensor d_out =
46+
at::rand(d_out_sizes, at::device(at::kCPU).dtype(at::kFloat));
47+
at::Tensor x = at::rand(x_sizes, at::device(at::kCPU).dtype(at::kFloat));
48+
49+
at::Tensor dW_ref = linear_q4gsw_dw_reference_impl(d_out, x);
50+
51+
// Build Vulkan graph
52+
using namespace vkcompute;
53+
54+
GraphConfig config;
55+
ComputeGraph graph(config);
56+
57+
IOValueRef r_d_out = graph.add_input_tensor(
58+
d_out.sizes().vec(), from_at_scalartype(d_out.scalar_type()), storage);
59+
IOValueRef r_x = graph.add_input_tensor(
60+
x.sizes().vec(), from_at_scalartype(x.scalar_type()), storage);
61+
62+
const ValueRef r_dW = graph.add_tensor(
63+
dW_ref.sizes().vec(), from_at_scalartype(dW_ref.scalar_type()), storage);
64+
65+
VK_GET_OP_FN("et_vk.linear_q4gsw_dw.default")
66+
(graph, {r_d_out.value, r_x.value, r_dW});
67+
68+
ValueRef staging_out = graph.set_output_tensor(r_dW);
69+
70+
graph.prepare();
71+
graph.prepack();
72+
graph.propagate_resize();
73+
74+
graph.maybe_cast_and_copy_into_staging(
75+
r_d_out.staging,
76+
d_out.const_data_ptr(),
77+
d_out.numel(),
78+
from_at_scalartype(d_out.scalar_type()));
79+
graph.maybe_cast_and_copy_into_staging(
80+
r_x.staging,
81+
x.const_data_ptr(),
82+
x.numel(),
83+
from_at_scalartype(x.scalar_type()));
84+
85+
graph.execute();
86+
87+
at::Tensor vk_dW = at::empty_like(dW_ref);
88+
graph.maybe_cast_and_copy_from_staging(
89+
staging_out,
90+
vk_dW.mutable_data_ptr(),
91+
vk_dW.numel(),
92+
from_at_scalartype(vk_dW.scalar_type()));
93+
94+
ASSERT_TRUE(at::allclose(vk_dW, dW_ref, 1e-3, 1e-3));
95+
}
96+
97+
// Tile-aligned 2D shapes (M, N, K all multiples of 4).
98+
TEST(VulkanLinearQ4gswDwTest, test_tile_aligned) {
99+
test_vulkan_linear_q4gsw_dw_impl(
100+
/*d_out_sizes=*/{8, 16}, /*x_sizes=*/{8, 32});
101+
}
102+
103+
// Non-tile-multiple shapes (M, N, K each not a multiple of 4) to exercise the
104+
// partial-tile min()-clamp paths in the shader.
105+
TEST(VulkanLinearQ4gswDwTest, test_non_tile_multiple) {
106+
test_vulkan_linear_q4gsw_dw_impl(
107+
/*d_out_sizes=*/{5, 6}, /*x_sizes=*/{5, 10});
108+
}
109+
110+
// Leading dims > 2D: M is the flattened product of all leading dims.
111+
TEST(VulkanLinearQ4gswDwTest, test_leading_dims_flatten) {
112+
test_vulkan_linear_q4gsw_dw_impl(
113+
/*d_out_sizes=*/{2, 3, 16}, /*x_sizes=*/{2, 3, 32});
114+
}

backends/vulkan/test/op_tests/targets.bzl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ def define_common_targets(is_fbcode = False):
186186
":test_utils",
187187
]
188188
)
189+
define_test_targets(
190+
"linear_q4gsw_dw_test",
191+
extra_deps = [
192+
":test_utils",
193+
]
194+
)
189195
define_test_targets(
190196
"rms_norm_test",
191197
extra_deps = [

0 commit comments

Comments
 (0)