Skip to content

Integrate a placeholder upsample_nearest2d.vec to Vulkan codegen operator tests #3711

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions backends/vulkan/runtime/graph/ops/glsl/upsample.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

#version 450 core

#include "broadcasting_utils.h"
#include "indexing_utils.h"

#define PRECISION ${PRECISION}

#define VEC4_T ${texel_type(DTYPE)}

// TODO(T189829641): migrate to the new buffer infra D57577019

layout(std430) buffer;

layout(set = 0, binding = 0, ${IMAGE_FORMAT[DTYPE]}) uniform PRECISION restrict writeonly ${IMAGE_T[NDIM][DTYPE]} image_out;

layout(set = 0, binding = 1) uniform PRECISION sampler3D image_in;

layout(set = 0, binding = 2) uniform PRECISION restrict OutLimits {
ivec3 out_limits;
};

layout(set = 0, binding = 3) uniform PRECISION restrict Sizes {
ivec4 sizes;
};

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

void main() {
const ivec3 pos = ivec3(gl_GlobalInvocationID);

if (any(greaterThanEqual(pos, out_limits))) {
return;
}

VEC4_T in_texel = texelFetch(image_in, pos, 0);
imageStore(image_out, pos, in_texel);
}
17 changes: 17 additions & 0 deletions backends/vulkan/runtime/graph/ops/glsl/upsample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

upsample:
parameter_names_with_default_values:
NDIM: 3
DTYPE: float
PACKING: C_packed
generate_variant_forall:
DTYPE:
- VALUE: half
- VALUE: float
shader_variants:
- NAME: upsample
67 changes: 67 additions & 0 deletions backends/vulkan/runtime/graph/ops/impl/Upsample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

#include <executorch/backends/vulkan/runtime/graph/ops/OperatorRegistry.h>

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

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

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

namespace vkcompute {

void resize_upsample_node(
ComputeGraph* graph,
const std::vector<ArgGroup>& args,
const std::vector<ValueRef>& extra_args) {
(void)graph;
(void)args;
(void)extra_args;
}

void add_upsample_node(
ComputeGraph& graph,
const ValueRef in,
const ValueRef out) {
ValueRef arg = prepack_if_tensor_ref(graph, in);

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

std::string kernel_name("upsample");
kernel_name.reserve(kShaderNameReserve);

add_dtype_suffix(kernel_name, *t_out);

graph.execute_nodes().emplace_back(new ExecuteNode(
graph,
VK_KERNEL_FROM_STR(kernel_name),
global_size,
local_size,
// Inputs and Outputs
{{out, api::MemoryAccessType::WRITE}, {arg, api::MemoryAccessType::READ}},
// Shader params buffers
{t_out->texture_limits_ubo(), graph.create_params_buffer(0.5)},
// Specialization Constants
{},
// Resizing Logic
resize_upsample_node));
}

void upsample(ComputeGraph& graph, const std::vector<ValueRef>& args) {
return add_upsample_node(graph, args[0], args[3]);
}

REGISTER_OPERATORS {
VK_REGISTER_OP(aten.upsample_nearest2d.vec, upsample);
}

} // namespace vkcompute
11 changes: 11 additions & 0 deletions backends/vulkan/test/op_tests/cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,16 @@ def get_native_layer_norm_inputs():
return test_suite


def get_upsample_inputs():
test_suite = VkTestSuite(
[
# TODO(dixu): implement the basic upsample logic to have a meaningful test
((2, 2, 2, 2), None, [1, 1]),
]
)
return test_suite


def get_full_inputs():
test_suite = VkTestSuite(
[
Expand Down Expand Up @@ -796,4 +806,5 @@ def get_gelu_inputs():
"aten._native_batch_norm_legit_no_training.default": get_native_batch_norm_inputs(),
"aten.gelu.default": get_gelu_inputs(),
"aten.hardshrink.default": get_unary_ops_inputs(),
"aten.upsample_nearest2d.vec": get_upsample_inputs(),
}
12 changes: 12 additions & 0 deletions backends/vulkan/test/op_tests/utils/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
CppTestFileGen,
DOUBLE,
INT,
OPT_AT_DOUBLE_ARRAY_REF,
OPT_AT_INT_ARRAY_REF,
OPT_AT_TENSOR,
OPT_BOOL,
OPT_DEVICE,
Expand Down Expand Up @@ -289,6 +291,16 @@ def create_value_for(self, ref: ValueRefList) -> str: # noqa: C901
ret_str += f"{self.graph}{self.dot}add_scalar<int64_t>"
ret_str += f"({ref.src_cpp_name}.value());\n"
return ret_str
elif (
ref.src_cpp_type == OPT_AT_DOUBLE_ARRAY_REF
or ref.src_cpp_type == OPT_AT_INT_ARRAY_REF
):
ret_str = f"{cpp_type} {ref.name} = "
ret_str += f"!{ref.src_cpp_name}.has_value() ? "
ret_str += f"{self.graph}{self.dot}add_none() : "
ret_str += f"{self.graph}{self.dot}add_scalar_list"
ret_str += f"({ref.src_cpp_name}->vec());\n"
return ret_str
elif ref.src_cpp_type == AT_TENSOR_LIST:
assert ref.is_in, "AT_TENSOR_LIST must be an input"
# This logic is a bit convoluted. We need to create a IOValueRef for
Expand Down
11 changes: 11 additions & 0 deletions backends/vulkan/test/op_tests/utils/codegen_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
BOOL = "bool"
DOUBLE = "double"
INT = "int64_t"
OPT_AT_DOUBLE_ARRAY_REF = "::std::optional<at::ArrayRef<double>>"
OPT_AT_INT_ARRAY_REF = "at::OptionalIntArrayRef"
OPT_AT_TENSOR = "::std::optional<at::Tensor>"
OPT_BOOL = "::std::optional<bool>"
OPT_INT64 = "::std::optional<int64_t>"
Expand Down Expand Up @@ -142,6 +144,10 @@ def create_input_data(self, arg: Argument, data: Any) -> str: # noqa: C901

if cpp_type == AT_INT_ARRAY_REF:
ret_str = f"std::vector<int64_t> {arg.name} = "
elif (
cpp_type == OPT_AT_DOUBLE_ARRAY_REF or cpp_type == OPT_AT_INT_ARRAY_REF
) and str(data) != "None":
ret_str = f"std::vector<double> {arg.name} = "
else:
ret_str = f"{cpp_type} {arg.name} = "

Expand All @@ -156,6 +162,11 @@ def create_input_data(self, arg: Argument, data: Any) -> str: # noqa: C901
ret_str += f"{data};"
elif cpp_type == AT_INT_ARRAY_REF:
ret_str += f"{init_list_str(data)};"
elif cpp_type == OPT_AT_DOUBLE_ARRAY_REF or cpp_type == OPT_AT_INT_ARRAY_REF:
if str(data) == "None":
ret_str += "std::nullopt;"
else:
ret_str += f"{init_list_str(data)};"
elif cpp_type == BOOL:
ret_str += f"{str(data).lower()};"
elif cpp_type == INT:
Expand Down
Loading