Skip to content

[DNL] small change to trigger CI testing #13300

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

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .ci/scripts/setup-vulkan-linux-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ install_swiftshader() {

export VK_ICD_FILENAMES="${_swiftshader_dir}/swiftshader/build/Linux/vk_swiftshader_icd.json"
export LD_LIBRARY_PATH="${_swiftshader_dir}/swiftshader/build/Linux/"
export ETVK_USING_SWIFTSHADER=1
}

install_vulkan_sdk() {
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/pull.yml
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,45 @@ jobs:
PYTHON_EXECUTABLE=python bash examples/nxp/run_aot_example.sh


test-vulkan-models-linux:
name: test-vulkan-models-linux
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
permissions:
id-token: write
contents: read
with:
runner: linux.2xlarge
docker-image: ci-image:executorch-ubuntu-22.04-clang12
submodules: 'recursive'
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
timeout: 90
script: |
set -eux

# The generic Linux job chooses to use base env, not the one setup by the image
CONDA_ENV=$(conda env list --json | jq -r ".envs | .[-1]")
conda activate "${CONDA_ENV}"

# Setup swiftshader and Vulkan SDK which are required to build the Vulkan delegate
source .ci/scripts/setup-vulkan-linux-deps.sh

# Setup python
PYTHON_EXECUTABLE=python \
CMAKE_ARGS="-DEXECUTORCH_BUILD_VULKAN=ON" \
.ci/scripts/setup-linux.sh --build-tool "cmake"

PYTHON_EXECUTABLE=python bash backends/vulkan/test/scripts/test_model.sh --build

# Test models serially
PYTHON_EXECUTABLE=python bash backends/vulkan/test/scripts/test_model.sh mv2
PYTHON_EXECUTABLE=python bash backends/vulkan/test/scripts/test_model.sh mv3
PYTHON_EXECUTABLE=python bash backends/vulkan/test/scripts/test_model.sh edsr
PYTHON_EXECUTABLE=python bash backends/vulkan/test/scripts/test_model.sh resnet18
PYTHON_EXECUTABLE=python bash backends/vulkan/test/scripts/test_model.sh resnet50
PYTHON_EXECUTABLE=python bash backends/vulkan/test/scripts/test_model.sh dl3



nxp-build-test:
name: nxp-build-test
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,10 @@ if(EXECUTORCH_BUILD_PYBIND)
list(APPEND _dep_libs xnnpack_backend XNNPACK xnnpack-microkernels-prod)
endif()

if(EXECUTORCH_BUILD_VULKAN)
list(APPEND _dep_libs vulkan_backend)
endif()

# compile options for pybind
set(_pybind_compile_options -Wno-deprecated-declarations -fPIC -frtti
-fexceptions
Expand Down
2 changes: 1 addition & 1 deletion backends/vulkan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ set_target_properties(vulkan_schema PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(
vulkan_schema
INTERFACE
${SCHEMA_INCLUDE_DIR}
$<BUILD_INTERFACE:${SCHEMA_INCLUDE_DIR}>
$<BUILD_INTERFACE:${EXECUTORCH_ROOT}/third-party/flatbuffers/include>
)

Expand Down
11 changes: 10 additions & 1 deletion backends/vulkan/cmake/ShaderLibrary.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ function(gen_vulkan_shader_lib_cpp shaders_path)
set(VULKAN_SHADERGEN_ENV "")
set(VULKAN_SHADERGEN_OUT_PATH ${CMAKE_BINARY_DIR}/vulkan_compute_shaders)

set(GEN_SPV_ARGS "--optimize")
if(DEFINED ENV{ETVK_USING_SWIFTSHADER})
if("$ENV{ETVK_USING_SWIFTSHADER}" STREQUAL "1"
OR "$ENV{ETVK_USING_SWIFTSHADER}" STREQUAL "True"
)
list(APPEND GEN_SPV_ARGS "--replace-u16vecn")
endif()
endif()

add_custom_command(
COMMENT "Generating Vulkan Compute Shaders"
OUTPUT ${VULKAN_SHADERGEN_OUT_PATH}/spv.cpp
Expand All @@ -58,7 +67,7 @@ function(gen_vulkan_shader_lib_cpp shaders_path)
${shaders_path} --output-path ${VULKAN_SHADERGEN_OUT_PATH}
--glslc-path=${GLSLC_PATH}
--tmp-dir-path=${VULKAN_SHADERGEN_OUT_PATH}/shader_cache/ --env
${VULKAN_GEN_ARG_ENV} --optimize
${VULKAN_GEN_ARG_ENV} ${GEN_SPV_ARGS}
DEPENDS ${shaders_path}/*
${EXECUTORCH_ROOT}/backends/vulkan/runtime/gen_vulkan_spv.py
)
Expand Down
38 changes: 36 additions & 2 deletions backends/vulkan/partitioner/vulkan_partitioner.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# pyre-strict

import logging
from typing import Any, Callable, Dict, final, List, Mapping, Optional, Tuple
from typing import Any, Callable, Dict, final, List, Mapping, Optional, Set, Tuple

import executorch.backends.vulkan.utils as utils

Expand All @@ -17,6 +17,7 @@
get_op_features,
has_impl,
OpFeatures,
OpKey,
vulkan_supported_ops,
)

Expand Down Expand Up @@ -55,11 +56,17 @@ def __init__(
texture_limits: utils.ImageExtents,
buffer_limit: int,
require_dynamic_shape: bool = False,
operator_blocklist: Optional[Set[OpKey]] = None,
operator_allowlist: Optional[Set[OpKey]] = None,
) -> None:
super().__init__()
self.texture_limits: utils.ImageExtents = texture_limits
self.buffer_limit = buffer_limit
self.require_dynamic_shapes = require_dynamic_shape
self.operator_blocklist: Set[OpKey] = (
operator_blocklist if operator_blocklist is not None else set()
)
self.operator_allowlist = operator_allowlist

def op_node_is_compatible( # noqa: C901: Function is too complex
self, node: torch.fx.Node, features: Optional[OpFeatures] = None
Expand All @@ -77,6 +84,17 @@ def op_node_is_compatible( # noqa: C901: Function is too complex
assert isinstance(first_arg, torch._ops.OpOverload)
target = first_arg.name()

# Operator allow list is only used for torch ops
if (
utils.is_torch_op_node(node)
and (self.operator_allowlist is not None)
and (target not in self.operator_allowlist)
):
return False, "op is not in allowlist"

if target in self.operator_blocklist:
return False, "op is in blocklist"

# Extract the features for the node's operator, if no override was provided
if features is None:
if not has_impl(target):
Expand All @@ -93,7 +111,7 @@ def op_node_is_compatible( # noqa: C901: Function is too complex
if op_repsets.any_is_empty():
return (
False,
"No valid representations for a tensor in the operation",
f"no valid representations for op {utils.node_io_str(node)}",
)

return True, "Op is compatible"
Expand Down Expand Up @@ -277,6 +295,8 @@ class VulkanPartitioner(Partitioner):
def __init__(
self,
compile_options: Optional[Dict[str, Any]] = None,
operator_blocklist: Optional[List[OpKey]] = None,
operator_allowlist: Optional[List[OpKey]] = None,
) -> None:
self.options: Dict[str, Any] = {}
if compile_options is not None:
Expand All @@ -285,6 +305,18 @@ def __init__(
compile_spec = parse_compile_options(self.options)
self.delegation_spec = DelegationSpec(VulkanBackend.__name__, compile_spec)

self.operator_blocklist: Set[OpKey] = set()
if operator_blocklist is not None:
for entry in operator_blocklist or []:
self.operator_blocklist.add(entry)

self.operator_allowlist: Optional[Set[OpKey]] = None
if operator_allowlist is not None:
self.operator_allowlist = set()
for entry in operator_allowlist:
assert self.operator_allowlist is not None
self.operator_allowlist.add(entry)

def ops_to_not_decompose(
self, ep: ExportedProgram
) -> Tuple[List[torch._ops.OpOverload], Optional[Callable[[torch.fx.Node], bool]]]:
Expand All @@ -308,6 +340,8 @@ def partition(self, exported_program: ExportedProgram) -> PartitionResult:
texture_limits,
buffer_limit,
require_dynamic_shape=self.options.get("require_dynamic_shapes", False),
operator_blocklist=self.operator_blocklist,
operator_allowlist=self.operator_allowlist,
),
allows_single_node_partition=True,
)
Expand Down
2 changes: 1 addition & 1 deletion backends/vulkan/runtime/VulkanBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ class VulkanBackend final : public ::executorch::runtime::BackendInterface {

compute_graph->execute();

for (size_t i = 0; i < compute_graph->outputs().size(); i++) {
for (size_t i = 0; i < compute_graph->outputs().size(); ++i) {
const size_t o = i + num_inputs;
const ValueRef oref = compute_graph->outputs()[i].value;
if (compute_graph->val_is_tensor(oref)) {
Expand Down
1 change: 0 additions & 1 deletion backends/vulkan/runtime/gen_vulkan_spv.py
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,6 @@ def compile_spirv(shader_paths_pair) -> Tuple[str, str]:
for spv_out_path, glsl_out_path in pool.map(
compile_spirv, self.output_file_map.items()
):
print(spv_to_glsl_map)
spv_to_glsl_map[spv_out_path] = glsl_out_path

return spv_to_glsl_map
Expand Down
180 changes: 180 additions & 0 deletions backends/vulkan/test/scripts/test_model.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#!/bin/bash
# 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.

set -exu

# Initialize variables
RUN_BUILD=false
RUN_CORRECTNESS_TEST=false
RUN_CLEAN=false
RUN_RECOMPILE=false
MODEL_NAME=""
OUTPUT_DIRECTORY="."

# Parse arguments
SKIP_NEXT=false
for i in $(seq 1 $#); do
if [[ "$SKIP_NEXT" == true ]]; then
SKIP_NEXT=false
continue
fi

arg="${!i}"
case $arg in
--build|-b)
RUN_BUILD=true
;;
--clean|-c)
RUN_CLEAN=true
;;
--recompile|-rc)
RUN_RECOMPILE=true
;;
--output_directory|-o)
next_i=$((i + 1))
if [[ $next_i -le $# ]]; then
OUTPUT_DIRECTORY="${!next_i}"
SKIP_NEXT=true
else
echo "Error: --output_directory|-o requires a value"
exit 1
fi
;;
--*|-*)
echo "Unknown argument: $arg"
exit 1
;;
*)
if [[ -z "$MODEL_NAME" ]]; then
MODEL_NAME="$arg"
else
echo "Multiple model names provided: $MODEL_NAME and $arg"
exit 1
fi
;;
esac
done

# Determine execution mode based on parsed arguments
if [[ "$RUN_BUILD" == true ]] && [[ -z "$MODEL_NAME" ]]; then
# Build-only mode
RUN_CORRECTNESS_TEST=false
elif [[ "$RUN_BUILD" == true ]] && [[ -n "$MODEL_NAME" ]]; then
# Build and test mode
RUN_CORRECTNESS_TEST=true
elif [[ "$RUN_BUILD" == false ]] && [[ -n "$MODEL_NAME" ]]; then
# Test-only mode
RUN_CORRECTNESS_TEST=true
else
echo "Invalid argument combination. Usage:"
echo " $0 --build|-b [--clean|-c] [--recompile|-rc] [-o|--output_directory DIR] # Build-only mode"
echo " $0 model_name [--build|-b] [--clean|-c] [--recompile|-rc] [-o|--output_directory DIR] # Test mode or build+test mode"
exit 1
fi

if [[ -z "${PYTHON_EXECUTABLE:-}" ]]; then
PYTHON_EXECUTABLE=python3
fi
which "${PYTHON_EXECUTABLE}"

CMAKE_OUTPUT_DIR=cmake-out

# Only set EXPORTED_MODEL if running correctness test
if [[ "${RUN_CORRECTNESS_TEST}" == true ]]; then
EXPORTED_MODEL=${MODEL_NAME}_vulkan
fi


clean_build_directory() {
echo "Cleaning build directory: ${CMAKE_OUTPUT_DIR}"
rm -rf ${CMAKE_OUTPUT_DIR}
}

recompile() {
cmake --build cmake-out -j64 --target install
}

build_core_libraries_and_devtools() {
echo "Building core libraries and devtools with comprehensive Vulkan support..."

# Build core libraries with all required components
cmake . \
-DCMAKE_INSTALL_PREFIX=cmake-out \
-DEXECUTORCH_BUILD_KERNELS_CUSTOM=ON \
-DEXECUTORCH_BUILD_KERNELS_CUSTOM_AOT=ON \
-DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON \
-DEXECUTORCH_BUILD_KERNELS_QUANTIZED=ON \
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
-DEXECUTORCH_BUILD_EXTENSION_FLAT_TENSOR=ON \
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
-DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON \
-DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \
-DEXECUTORCH_BUILD_EXECUTOR_RUNNER=ON \
-DEXECUTORCH_BUILD_DEVTOOLS=ON \
-DEXECUTORCH_BUILD_VULKAN=ON \
-DEXECUTORCH_BUILD_XNNPACK=ON \
-Bcmake-out && \
cmake --build cmake-out -j64 --target install

# Build devtools example runner
cmake examples/devtools \
-DCMAKE_INSTALL_PREFIX=cmake-out \
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
-DEXECUTORCH_BUILD_VULKAN=ON \
-Bcmake-out/examples/devtools && \
cmake --build cmake-out/examples/devtools -j16 --config Release
}

run_example_runner() {
./${CMAKE_OUTPUT_DIR}/examples/devtools/example_runner -bundled_program_path "${OUTPUT_DIRECTORY}/${EXPORTED_MODEL}.bpte" -output_verification
}

test_bundled_model_with_vulkan() {
# Export model as bundled program with Vulkan backend
"${PYTHON_EXECUTABLE}" -m examples.vulkan.export --model_name="${MODEL_NAME}" --output_dir="${OUTPUT_DIRECTORY}" --bundled

# Update exported model name for bundled program
EXPORTED_MODEL="${MODEL_NAME}_vulkan"

# Verify the exported bundled model exists
if [[ ! -f "${OUTPUT_DIRECTORY}/${EXPORTED_MODEL}.bpte" ]]; then
echo "Error: Failed to export bundled model ${MODEL_NAME} with Vulkan backend"
exit 1
fi

# Note: Running bundled programs may require different executor runner
echo "Bundled program created successfully. Use appropriate bundled program runner to test."

run_example_runner
}


# Main execution
if [[ "${RUN_BUILD}" == true ]]; then
if [[ "${RUN_CLEAN}" == true ]]; then
clean_build_directory
fi
build_core_libraries_and_devtools
fi

if [[ "${RUN_RECOMPILE}" == true ]]; then
recompile
fi

if [[ "${RUN_CORRECTNESS_TEST}" == true ]]; then
echo "Testing ${MODEL_NAME} with Vulkan backend..."
# Always use bundled program testing
test_bundled_model_with_vulkan

# Check if test completed successfully
if [[ $? -eq 0 ]]; then
echo "Vulkan model test completed successfully!"
else
echo "Vulkan model test failed!"
exit 1
fi
fi
Loading
Loading