Skip to content

Commit 636c5c3

Browse files
Di Xu (AR)facebook-github-bot
authored andcommitted
Implement upsample_nearest2d.vec op to pass codegen operator tests: scale factor supports only
Summary: Implement upsample_nearest2d.vec op to pass codegen operator tests - Scale factor supports only - Renamed the glsl file to upsample_nearest2d since the caffe2 version has multiple upsample op versions - Output sizes support and others will be following up in T190297757 - May follow up on the dynamic shape support next bypass-github-export-checks bypass-github-pytorch-ci-checks bypass-github-executorch-ci-checks Reviewed By: copyrightly Differential Revision: D57698138 fbshipit-source-id: 8a4d1f5bd4565c52a0b919302ac202aede2a6b74
1 parent c3d1680 commit 636c5c3

File tree

4 files changed

+54
-22
lines changed

4 files changed

+54
-22
lines changed

backends/vulkan/runtime/graph/ops/glsl/upsample.glsl renamed to backends/vulkan/runtime/graph/ops/glsl/upsample_nearest2d.glsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ layout(std430) buffer;
2020
${layout_declare_tensor(0, "w", "t_out", DTYPE, STORAGE)}
2121
${layout_declare_tensor(1, "r", "t_in", DTYPE, STORAGE)}
2222
${layout_declare_ubo(2, "ivec3", "out_limits")}
23+
${layout_declare_ubo(3, "ivec2", "input_size")}
24+
${layout_declare_ubo(4, "vec2", "rev_scales")}
2325

2426
layout(local_size_x_id = 0, local_size_y_id = 1, local_size_z_id = 2) in;
2527

@@ -30,6 +32,8 @@ void main() {
3032
return;
3133
}
3234

33-
VEC4_T in_texel = texelFetch(t_in, pos, 0);
35+
const ivec2 ipos = clamp(ivec2(pos.xy * rev_scales), ivec2(0), input_size);
36+
37+
VEC4_T in_texel = texelFetch(t_in, ivec3(ipos, pos.z), 0);
3438
imageStore(t_out, pos, in_texel);
3539
}

backends/vulkan/runtime/graph/ops/glsl/upsample.yaml renamed to backends/vulkan/runtime/graph/ops/glsl/upsample_nearest2d.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# This source code is licensed under the BSD-style license found in the
55
# LICENSE file in the root directory of this source tree.
66

7-
upsample:
7+
upsample_nearest2d:
88
parameter_names_with_default_values:
99
NDIM: 3
1010
DTYPE: float
@@ -15,4 +15,4 @@ upsample:
1515
- VALUE: half
1616
- VALUE: float
1717
shader_variants:
18-
- NAME: upsample
18+
- NAME: upsample_nearest2d

backends/vulkan/runtime/graph/ops/impl/Upsample.cpp

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,56 @@
1010

1111
#include <executorch/backends/vulkan/runtime/graph/ops/impl/Staging.h>
1212

13-
#include <executorch/backends/vulkan/runtime/graph/ops/impl/utils/ScalarUtils.h>
1413
#include <executorch/backends/vulkan/runtime/graph/ops/impl/utils/TensorUtils.h>
1514

1615
#include <executorch/backends/vulkan/runtime/graph/ops/utils/ShaderNameUtils.h>
1716

1817
namespace vkcompute {
1918

20-
void resize_upsample_node(
21-
ComputeGraph* graph,
22-
const std::vector<ArgGroup>& args,
23-
const std::vector<ValueRef>& extra_args) {
24-
(void)graph;
25-
(void)args;
26-
(void)extra_args;
27-
}
19+
// Executorch-Vulkan framework to add node
20+
// Args:
21+
// in: will be converted from NCHW input tensor to 3D ARGB representation in
22+
// openGL (via Executorch) output_sizes: optional 2D array of targetting
23+
// output size of H and W dimensions. >= input sizes;
2824

29-
void add_upsample_node(
25+
// will be computed if only given the scale_factors.
26+
// scale_factors: optional 2D array of scale factors for H and W dimensions.
27+
// Will be computed if only given the output_sizes.
28+
void add_upsample_nearest2d_node(
3029
ComputeGraph& graph,
3130
const ValueRef in,
31+
const ValueRef output_sizes,
32+
const ValueRef scale_factors,
3233
const ValueRef out) {
33-
ValueRef arg = prepack_if_tensor_ref(graph, in);
34+
// TODO(T190297757) add supports for output_sizes
35+
if (graph.val_is_none(output_sizes) && graph.val_is_none(scale_factors)) {
36+
VK_THROW(
37+
"Invalid input, must provide either output_sizes or scale_factors");
38+
}
39+
if (!graph.val_is_none(output_sizes) && !graph.val_is_none(scale_factors)) {
40+
VK_THROW(
41+
"Invalid input, must provide ONLY one of output_sizes or scale_factors");
42+
}
43+
auto scales = graph.get_double_list(scale_factors);
44+
45+
ValueRef arg_in = prepack_if_tensor_ref(graph, in);
46+
47+
vTensorPtr t_in = graph.get_tensor(in);
48+
api::utils::uvec3 input_sizes = t_in->image_extents();
49+
50+
api::utils::ivec2 input_size = {
51+
api::utils::safe_downcast<int32_t>(input_sizes.data[0]),
52+
api::utils::safe_downcast<int32_t>(input_sizes.data[1])};
53+
// Reverse scale factors that pre-computed before GLSL.
54+
api::utils::vec2 rev_scales = {
55+
api::utils::safe_downcast<float>(1.0 / scales->at(1)),
56+
api::utils::safe_downcast<float>(1.0 / scales->at(0))};
3457

3558
vTensorPtr t_out = graph.get_tensor(out);
3659
api::utils::uvec3 global_size = t_out->image_extents();
3760
api::utils::uvec3 local_size = adaptive_work_group_size(global_size);
3861

39-
std::string kernel_name("upsample");
62+
std::string kernel_name("upsample_nearest2d");
4063
kernel_name.reserve(kShaderNameReserve);
4164

4265
add_dtype_suffix(kernel_name, *t_out);
@@ -47,17 +70,18 @@ void add_upsample_node(
4770
global_size,
4871
local_size,
4972
// Inputs and Outputs
50-
{{out, api::MemoryAccessType::WRITE}, {arg, api::MemoryAccessType::READ}},
73+
{{out, api::MemoryAccessType::WRITE},
74+
{arg_in, api::MemoryAccessType::READ}},
5175
// Shader params buffers
52-
{t_out->texture_limits_ubo()},
76+
{t_out->texture_limits_ubo(),
77+
graph.create_params_buffer(input_size),
78+
graph.create_params_buffer(rev_scales)},
5379
// Specialization Constants
54-
{},
55-
// Resizing Logic
56-
resize_upsample_node));
80+
{}));
5781
}
5882

5983
void upsample(ComputeGraph& graph, const std::vector<ValueRef>& args) {
60-
return add_upsample_node(graph, args[0], args[3]);
84+
return add_upsample_nearest2d_node(graph, args[0], args[1], args[2], args[3]);
6185
}
6286

6387
REGISTER_OPERATORS {

backends/vulkan/test/op_tests/cases.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,12 @@ def get_native_layer_norm_inputs():
244244
def get_upsample_inputs():
245245
test_suite = VkTestSuite(
246246
[
247-
# TODO(dixu): implement the basic upsample logic to have a meaningful test
247+
# (input tensor shape, output 2D image size (H, W), output scaling factors)
248248
((2, 2, 2, 2), None, [1, 1]),
249+
((1, 1, 2, 2), None, [2, 2]),
250+
((1, 1, 2, 2), None, [2, 4]),
251+
((1, 1, 2, 2), None, [4, 2]),
252+
# TODO(T190297757) add supports for output_sizes
249253
]
250254
)
251255
return test_suite

0 commit comments

Comments
 (0)