diff --git a/backends/arm/README.md b/backends/arm/README.md index f56cd7201fe..47811ee5e7c 100644 --- a/backends/arm/README.md +++ b/backends/arm/README.md @@ -106,6 +106,13 @@ Setup: ./examples/arm/setup.sh --disable-ethos-u-deps --enable-mlsdk-deps ``` +This is the default setup path and installs the MLSDK components from pip. +Developers who need local source builds can use: + +``` +./backends/arm/scripts/setup-mlsdk-from-source.sh +``` + The current flow lowers to TOSA and converts to VGF for use in external projects, so the `executor_runner` is not typically used here. diff --git a/backends/arm/scripts/mlsdk_utils.sh b/backends/arm/scripts/mlsdk_utils.sh index 1f999e0ce42..eab830a9ea3 100755 --- a/backends/arm/scripts/mlsdk_utils.sh +++ b/backends/arm/scripts/mlsdk_utils.sh @@ -6,236 +6,68 @@ set -euo pipefail -# URL and tag of the MLSDK manifest repository. Can be overridden by environment variables. -# eg. export MLSDK_MANIFEST_URL=...; export MLSDK_MANIFEST_TAG=... -mlsdk_manifest_url="${MLSDK_MANIFEST_URL:-https://github.com/arm/ai-ml-sdk-manifest.git}" -mlsdk_manifest_tag="${MLSDK_MANIFEST_TAG:-refs/tags/v2025.12.0}" - script_dir=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) source ${script_dir}/utils.sh -function mlsdk_sync_manifest() { - local manifest_dir="$1" - - mkdir -p "${manifest_dir}" - pushd "${manifest_dir}" || return 1 - local parallel_jobs="$(get_parallel_jobs)" - - if [[ ! -f repo ]]; then - log_step "mlsdk" "Fetching repo tool" - curl https://storage.googleapis.com/git-repo-downloads/repo > repo - chmod u+x repo - fi - - ./repo init \ - --depth=1 \ - --no-repo-verify \ - --manifest-url "${mlsdk_manifest_url}" \ - --manifest-branch "${mlsdk_manifest_tag}" \ - -g model-converter,emulation-layer,vgf-library - - local default_manifest=".repo/manifests/default.xml" - - ./repo sync --force-sync -j"${parallel_jobs}" - - popd -} - -function download_ai_mlsdk_manifest() { - local _manifest_dir="$1" +function apply_emulation_layer_deploy_dir() { + local deploy_dir="$1" - if [[ -z "${_manifest_dir}" ]]; then - log_step "mlsdk" "Error: _manifest_dir parameter missing" + if [[ -z "${deploy_dir}" ]] || [[ ! -d "${deploy_dir}" ]]; then return 1 fi - if [[ -z "${mlsdk_manifest_url}" ]]; then - log_step "mlsdk" "Error: mlsdk_manifest_url parameter missing" - return 1 - fi + prepend_env_in_setup_path LD_LIBRARY_PATH "${deploy_dir}/lib" + prepend_env_in_setup_path DYLD_LIBRARY_PATH "${deploy_dir}/lib" + prepend_env_in_setup_path VK_LAYER_PATH "${deploy_dir}/share/vulkan/explicit_layer.d" + prepend_env_in_setup_path VK_ADD_LAYER_PATH "${deploy_dir}/share/vulkan/explicit_layer.d" + prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Tensor_Emulation + prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Graph_Emulation +} - if [[ ! -d "${_manifest_dir}/sw" ]] || [[ ! -d "${_manifest_dir}/dependencies" ]]; then - log_step "mlsdk" "MLSDK checkout not found at ${_manifest_dir}; performing initial download" - mlsdk_sync_manifest "${_manifest_dir}" +function find_vulkaninfo_binary() { + if command -v vulkaninfo >/dev/null 2>&1; then + command -v vulkaninfo return 0 fi - # If a checkout exists, get the URL and tag of the existing checkout. - local cached_url="" - local cached_tag="" - local repo_config="${_manifest_dir}/.repo/manifests.git/config" - if [[ -f "${repo_config}" ]]; then - cached_url="$(git config --file "${repo_config}" remote.origin.url 2>/dev/null || echo "")" - cached_tag="$(git config --file "${repo_config}" branch.default.merge 2>/dev/null || echo "")" + if [[ -n "${root_dir:-}" && \ + -n "${vulkan_sdk_bin_dir:-}" && \ + -x "${root_dir}/${vulkan_sdk_bin_dir}/vulkaninfo" ]]; then + printf '%s\n' "${root_dir}/${vulkan_sdk_bin_dir}/vulkaninfo" + return 0 fi - # If the tag is main or refs/heads/main, always refresh the checkout. - # This allows users to track the latest main branch without needing to manually - # delete the checkout. - local tag_tracks_main=0 - if [[ "${mlsdk_manifest_tag}" == "main" ]] || [[ "${mlsdk_manifest_tag}" == "refs/heads/main" ]]; then - tag_tracks_main=1 - fi + return 1 +} - # If the URL and tag match, and the tag does not track main, reuse the existing checkout. - # Skip fetching updates. - if [[ "${cached_url}" == "${mlsdk_manifest_url}" ]] && [[ "${cached_tag}" == "${mlsdk_manifest_tag}" ]] && [[ "${tag_tracks_main}" -eq 0 ]]; then - log_step "mlsdk" "Reusing cached MLSDK dependencies at ${_manifest_dir}" +function detect_emulation_layer_float_as_double() { + local vulkaninfo_bin="" + if ! vulkaninfo_bin=$(find_vulkaninfo_binary); then + log_step "mlsdk" \ + "vulkaninfo not found, can't detect shaderFloat64 support." >&2 + printf 'UNKNOWN\n' return 0 fi - # If we reach here, either the URL or tag changed, or the tag tracks main. - # In all cases, refresh the checkout. - if [[ "${tag_tracks_main}" -eq 1 ]]; then - log_step "mlsdk" "Manifest tracks branch ${mlsdk_manifest_tag}; refreshing checkout" + if grep -qE 'shaderFloat64[[:space:]]*= false' < <("${vulkaninfo_bin}" 2>&1); then + printf 'ON\n' else - log_step "mlsdk" "Manifest changed (url=${cached_url:-} -> ${mlsdk_manifest_url}, tag=${cached_tag:-} -> ${mlsdk_manifest_tag}); refreshing checkout" - fi - - # Clean up any local manifest changes to avoid repo sync errors. - # Since we patched in a local manifest for tosa_gitlab.xml, - # remove any existing local manifests to avoid conflicts. - # TODO: we should remove this at some point in the future, but its not hurting anything for now. - if [[ -d "${_manifest_dir}/.repo/local_manifests" ]]; then - rm -rf "${_manifest_dir}/.repo/local_manifests/" - fi - - # Clean up any local changes in the manifests repository. - if [[ -d "${_manifest_dir}/.repo/manifests.git" ]]; then - git -C "${_manifest_dir}/.repo/manifests.git" reset --hard HEAD >/dev/null 2>&1 || true - git -C "${_manifest_dir}/.repo/manifests.git" clean -fd >/dev/null 2>&1 || true - fi - - # Clean up any local changes in the manifests working copy. - if [[ -d "${_manifest_dir}/.repo/manifests" ]]; then - git -C "${_manifest_dir}/.repo/manifests" reset --hard HEAD >/dev/null 2>&1 || true - git -C "${_manifest_dir}/.repo/manifests" clean -fd >/dev/null 2>&1 || true + printf 'OFF\n' fi - - # Going from v2025.10.0 to v2025.12.0 seems particular hard so just keep it simple. - # TODO: Remove once this is history - if [[ "${cached_tag}" == "refs/tags/v2025.10.0" ]] && [[ "${mlsdk_manifest_tag}" == "refs/tags/v2025.12.0" ]]; then - pushd "${_manifest_dir}/.." - log_step "mlsdk" "Deleting ${mlsdk_manifest_dir} and starting fresh" - manifest_base_dir=$(basename "${_manifest_dir}") - rm -fr $manifest_base_dir - popd - fi - - mlsdk_sync_manifest "${_manifest_dir}" } -function setup_mlsdk() { - local work_dir="$1" - local manifest_dir="$2" - local enable_model_converter="$3" - local enable_vgf_lib="$4" - local enable_emulation_layer="$5" - - if [[ -z "$work_dir" ]]; then - log_step "mlsdk" "Error: work_dir parameter is required" - return 1 +function find_emulation_layer_pkg_dir() { + local py="python3" + if ! command -v "${py}" >/dev/null 2>&1; then + py="python" fi - if [[ -z "$manifest_dir" ]]; then - log_step "mlsdk" "Error: manifest_dir parameter is required" + if ! command -v "${py}" >/dev/null 2>&1; then return 1 fi - mkdir -p "$work_dir" - pushd "$work_dir" || exit 1 - - log_step "mlsdk" "Syncing MLSDK manifest into ${manifest_dir}" - download_ai_mlsdk_manifest "${manifest_dir}" - - pushd "$manifest_dir" - local parallel_jobs="$(get_parallel_jobs)" - - # model-converter - if [[ "${enable_model_converter}" -eq 1 ]]; then - log_step "mlsdk" "Building MLSDK model-converter" - python sw/model-converter/scripts/build.py -j"${parallel_jobs}" - log_step "mlsdk" "MLSDK model-converter build complete" - fi - - # libvgf - if [[ "${enable_vgf_lib}" -eq 1 ]]; then - log_step "mlsdk" "Building MLSDK VGF library" - pushd sw/vgf-lib - python scripts/build.py -j"${parallel_jobs}" - cmake --install build --prefix deploy - log_step "mlsdk" "MLSDK VGF library build complete" - popd - fi - - # emu layer - if [[ "${enable_emulation_layer}" -eq 1 ]]; then - log_step "mlsdk" "Building MLSDK Vulkan emulation layer" - pushd sw/emulation-layer - cmake -B build \ - -DGLSLANG_PATH=../../dependencies/glslang \ - -DSPIRV_CROSS_PATH=../../dependencies/SPIRV-Cross \ - -DSPIRV_HEADERS_PATH=../../dependencies/SPIRV-Headers \ - -DSPIRV_TOOLS_PATH=../../dependencies/SPIRV-Tools \ - -DVULKAN_HEADERS_PATH=../../dependencies/Vulkan-Headers - - cmake --build build -j"${parallel_jobs}" - cmake --install build --prefix deploy - log_step "mlsdk" "MLSDK Vulkan emulation layer build complete" - popd - fi - - popd -} - -function setup_path_model_converter() { - cd "${root_dir}" - model_converter_bin_path="$(cd "${mlsdk_manifest_dir}/sw/model-converter/build" && pwd)" - append_env_in_setup_path PATH "${model_converter_bin_path}" -} - -function setup_path_vgf_lib() { - cd "${root_dir}" - model_vgf_path="$(cd "${mlsdk_manifest_dir}/sw/vgf-lib/deploy" && pwd)" - append_env_in_setup_path PATH "${model_vgf_path}/bin" - append_env_in_setup_path LD_LIBRARY_PATH "${model_vgf_path}/lib" - append_env_in_setup_path DYLD_LIBRARY_PATH "${model_vgf_path}/lib" -} - -function setup_path_emulation_layer() { - cd "${root_dir}" - model_emulation_layer_path="$(cd "${mlsdk_manifest_dir}/sw/emulation-layer/" && pwd)" - prepend_env_in_setup_path LD_LIBRARY_PATH "${model_emulation_layer_path}/deploy/lib" - prepend_env_in_setup_path DYLD_LIBRARY_PATH "${model_emulation_layer_path}/deploy/lib" - prepend_env_in_setup_path VK_LAYER_PATH "${model_emulation_layer_path}/deploy/share/vulkan/explicit_layer.d" - prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Tensor_Emulation - prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Graph_Emulation -} - -function setup_path_emulation_layer_from_pip() { - if ! command -v emulation_layer >/dev/null 2>&1; then - echo "[mlsdk_utils] 'emulation_layer' command not found; skipping pip emulation layer path setup" - return - fi - - local output - if ! output=$(emulation_layer 2>/dev/null); then - output="" - fi - - local exports - exports=$(echo "$output" | grep '^export ' || true) - - if [[ -z "${exports}" ]] || echo "$output" | grep -q "Unsupported platform"; then - local py="python3" - if ! command -v "${py}" >/dev/null 2>&1; then - py="python" - fi - - local pkg_dir="" - if command -v "${py}" >/dev/null 2>&1; then - pkg_dir=$("${py}" - <<'PY' + "${py}" - <<'PY' import importlib.util import os import sys @@ -251,71 +83,15 @@ elif spec.origin: else: print("") PY -) - fi +} - if [[ -n "${pkg_dir}" && -d "${pkg_dir}/deploy" ]]; then - local deploy_dir="${pkg_dir}/deploy" - prepend_env_in_setup_path LD_LIBRARY_PATH "${deploy_dir}/lib" - prepend_env_in_setup_path DYLD_LIBRARY_PATH "${deploy_dir}/lib" - prepend_env_in_setup_path VK_LAYER_PATH "${deploy_dir}/share/vulkan/explicit_layer.d" - prepend_env_in_setup_path VK_ADD_LAYER_PATH "${deploy_dir}/share/vulkan/explicit_layer.d" - prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Tensor_Emulation - prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Graph_Emulation +function setup_path_emulation_layer() { + local pkg_dir="" + if pkg_dir=$(find_emulation_layer_pkg_dir); then + if [[ -n "${pkg_dir}" ]] && apply_emulation_layer_deploy_dir "${pkg_dir}/deploy"; then return fi fi - if [[ -z "${exports}" ]]; then - echo "[mlsdk_utils] Failed to query emulation_layer environment; skipping" - return - fi - - local ld_line - ld_line=$(echo "$exports" | grep 'LD_LIBRARY_PATH=' || true) - if [[ -n "${ld_line}" ]]; then - local ld_value=${ld_line#export LD_LIBRARY_PATH=} - ld_value=${ld_value%%:\$LD_LIBRARY_PATH*} - if [[ -n "${ld_value}" ]]; then - prepend_env_in_setup_path LD_LIBRARY_PATH "${ld_value}" - fi - fi - - local dyld_line - dyld_line=$(echo "$exports" | grep 'DYLD_LIBRARY_PATH=' || true) - if [[ -n "${dyld_line}" ]]; then - local dyld_value=${dyld_line#export DYLD_LIBRARY_PATH=} - dyld_value=${dyld_value%%:\$DYLD_LIBRARY_PATH*} - if [[ -n "${dyld_value}" ]]; then - prepend_env_in_setup_path DYLD_LIBRARY_PATH "${dyld_value}" - fi - fi - - local vk_layer_line - vk_layer_line=$(echo "$exports" | grep 'VK_LAYER_PATH=' || true) - if [[ -n "${vk_layer_line}" ]]; then - local vk_layer_value=${vk_layer_line#export VK_LAYER_PATH=} - vk_layer_value=${vk_layer_value%%:\$VK_LAYER_PATH*} - if [[ -n "${vk_layer_value}" ]]; then - prepend_env_in_setup_path VK_LAYER_PATH "${vk_layer_value}" - fi - fi - - local vk_add_line - vk_add_line=$(echo "$exports" | grep 'VK_ADD_LAYER_PATH=' || true) - if [[ -n "${vk_add_line}" ]]; then - local vk_add_value=${vk_add_line#export VK_ADD_LAYER_PATH=} - if [[ -n "${vk_add_value}" ]]; then - prepend_env_in_setup_path VK_ADD_LAYER_PATH "${vk_add_value}" - fi - fi - - local vk_instance_line - vk_instance_line=$(echo "$exports" | grep 'VK_INSTANCE_LAYERS=' || true) - if [[ -n "${vk_instance_line}" ]]; then - local vk_instance_value=${vk_instance_line#export VK_INSTANCE_LAYERS=} - if [[ -n "${vk_instance_value}" ]]; then - prepend_env_in_setup_path VK_INSTANCE_LAYERS "${vk_instance_value}" - fi - fi + echo "[mlsdk_utils] Failed to query emulation_layer environment; skipping" } diff --git a/backends/arm/scripts/setup-mlsdk-from-source.sh b/backends/arm/scripts/setup-mlsdk-from-source.sh new file mode 100755 index 00000000000..0d6b6040bf9 --- /dev/null +++ b/backends/arm/scripts/setup-mlsdk-from-source.sh @@ -0,0 +1,393 @@ +#!/usr/bin/env bash +# Copyright 2026 Arm Limited and/or its affiliates. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + +set -euo pipefail + +script_dir=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) +et_dir=$(realpath "${script_dir}/../../..") +ARCH="$(uname -m)" +OS="$(uname -s)" + +root_dir="${et_dir}/examples/arm/arm-scratch" +setup_path_script="" +mlsdk_manifest_dir="ml-sdk-for-vulkan-manifest" +mlsdk_manifest_url="${MLSDK_MANIFEST_URL:-https://github.com/arm/ai-ml-sdk-manifest.git}" +mlsdk_manifest_tag="${MLSDK_MANIFEST_TAG:-refs/tags/v2026.03.0}" # Keep this in sync with what is mentioned in requirements-arm-vgf.txt + +enable_model_converter=0 +enable_vgf_lib=0 +enable_emulation_layer=0 +enable_vulkan_sdk=0 + +source "${script_dir}/utils.sh" +source "${script_dir}/vulkan_utils.sh" +source "${script_dir}/mlsdk_utils.sh" + +OPTION_LIST=( + "--root-dir Path to scratch directory (default: examples/arm/arm-scratch)" + "--manifest-dir Path to the MLSDK source checkout (default: /ml-sdk-for-vulkan-manifest)" + "--mlsdk-manifest-url Override the MLSDK manifest repository URL" + "--mlsdk-manifest-tag Override the MLSDK manifest tag or branch" + "--enable-model-converter Build model-converter from source" + "--enable-vgf-lib Build the VGF library from source" + "--enable-emulation-layer Build the Vulkan emulation layer from source" + "--enable-vulkan-sdk Download and export the Vulkan SDK" + "--help Display help" +) + +function print_usage() { + echo "Usage: $(basename "$0") [OPTIONS]" + echo + echo "Available options:" + for entry in "${OPTION_LIST[@]}"; do + opt="${entry%% *}" + desc="${entry#* }" + printf " %-40s %s\n" "$opt" "$desc" + done + echo + echo "When no component flags are provided, the script builds model-converter," + echo "vgf-lib, the emulation layer, and the Vulkan SDK." +} + +function check_options() { + while [[ "${#}" -gt 0 ]]; do + case "$1" in + --root-dir) + if [[ $# -lt 2 ]]; then + print_usage + exit 1 + fi + root_dir="$2" + shift 2 + ;; + --manifest-dir) + if [[ $# -lt 2 ]]; then + print_usage + exit 1 + fi + mlsdk_manifest_dir="$2" + shift 2 + ;; + --mlsdk-manifest-url) + if [[ $# -lt 2 ]]; then + print_usage + exit 1 + fi + mlsdk_manifest_url="$2" + shift 2 + ;; + --mlsdk-manifest-tag) + if [[ $# -lt 2 ]]; then + print_usage + exit 1 + fi + mlsdk_manifest_tag="$2" + shift 2 + ;; + --enable-model-converter) + enable_model_converter=1 + shift + ;; + --enable-vgf-lib) + enable_vgf_lib=1 + shift + ;; + --enable-emulation-layer) + enable_emulation_layer=1 + shift + ;; + --enable-vulkan-sdk) + enable_vulkan_sdk=1 + shift + ;; + --enable-mlsdk-deps) + # Backwards-compatible alias for the default "build everything" behavior. + enable_model_converter=1 + enable_vgf_lib=1 + enable_emulation_layer=1 + enable_vulkan_sdk=1 + shift + ;; + --help) + print_usage + exit 0 + ;; + *) + print_usage + exit 1 + ;; + esac + done + + # If no component was selected explicitly, build the full MLSDK source stack. + if [[ "${enable_model_converter}" -eq 0 && \ + "${enable_vgf_lib}" -eq 0 && \ + "${enable_emulation_layer}" -eq 0 && \ + "${enable_vulkan_sdk}" -eq 0 ]]; then + enable_model_converter=1 + enable_vgf_lib=1 + enable_emulation_layer=1 + enable_vulkan_sdk=1 + fi +} + +function setup_root_dir() { + mkdir -p "${root_dir}" + root_dir=$(realpath "${root_dir}") + setup_path_script="${root_dir}/setup_path" + log_step "main" "Prepared root dir at ${root_dir}" +} + +function mlsdk_sync_manifest() { + local manifest_dir="$1" + + mkdir -p "${manifest_dir}" + pushd "${manifest_dir}" >/dev/null || return 1 + local parallel_jobs="$(get_parallel_jobs)" + + if [[ ! -f repo ]]; then + log_step "mlsdk" "Fetching repo tool" + curl https://storage.googleapis.com/git-repo-downloads/repo > repo + chmod u+x repo + fi + + ./repo init \ + --depth=1 \ + --no-repo-verify \ + --manifest-url "${mlsdk_manifest_url}" \ + --manifest-branch "${mlsdk_manifest_tag}" \ + -g model-converter,emulation-layer,vgf-library + + ./repo sync --force-sync -j"${parallel_jobs}" + + popd >/dev/null || return 1 +} + +function download_ai_mlsdk_manifest() { + local manifest_dir="$1" + + if [[ -z "${manifest_dir}" ]]; then + log_step "mlsdk" "Error: manifest_dir parameter is required" + return 1 + fi + + if [[ -z "${mlsdk_manifest_url}" ]]; then + log_step "mlsdk" "Error: mlsdk_manifest_url parameter is required" + return 1 + fi + + if [[ ! -d "${manifest_dir}/sw" ]] || [[ ! -d "${manifest_dir}/dependencies" ]]; then + log_step "mlsdk" "MLSDK checkout not found at ${manifest_dir}; performing initial download" + mlsdk_sync_manifest "${manifest_dir}" + return 0 + fi + + # A manifest checkout already exists. Compare its URL and branch/tag to the + # requested manifest source and refresh it if they do not match. + local cached_url="" + local cached_tag="" + local repo_config="${manifest_dir}/.repo/manifests.git/config" + if [[ -f "${repo_config}" ]]; then + cached_url="$(git config --file "${repo_config}" remote.origin.url 2>/dev/null || echo "")" + cached_tag="$(git config --file "${repo_config}" branch.default.merge 2>/dev/null || echo "")" + fi + + local tag_tracks_main=0 + if [[ "${mlsdk_manifest_tag}" == "main" ]] || [[ "${mlsdk_manifest_tag}" == "refs/heads/main" ]]; then + tag_tracks_main=1 + fi + + if [[ "${cached_url}" == "${mlsdk_manifest_url}" && \ + "${cached_tag}" == "${mlsdk_manifest_tag}" && \ + "${tag_tracks_main}" -eq 0 ]]; then + log_step "mlsdk" "Reusing cached MLSDK dependencies at ${manifest_dir}" + return 0 + fi + + if [[ "${tag_tracks_main}" -eq 1 ]]; then + log_step "mlsdk" "Manifest tracks branch ${mlsdk_manifest_tag}; refreshing checkout" + else + log_step "mlsdk" \ + "Manifest changed (url=${cached_url:-} -> ${mlsdk_manifest_url}, tag=${cached_tag:-} -> ${mlsdk_manifest_tag}); refreshing checkout" + fi + + if [[ -d "${manifest_dir}/.repo/local_manifests" ]]; then + rm -rf "${manifest_dir}/.repo/local_manifests/" + fi + + if [[ -d "${manifest_dir}/.repo/manifests.git" ]]; then + git -C "${manifest_dir}/.repo/manifests.git" reset --hard HEAD >/dev/null 2>&1 || true + git -C "${manifest_dir}/.repo/manifests.git" clean -fd >/dev/null 2>&1 || true + fi + + if [[ -d "${manifest_dir}/.repo/manifests" ]]; then + git -C "${manifest_dir}/.repo/manifests" reset --hard HEAD >/dev/null 2>&1 || true + git -C "${manifest_dir}/.repo/manifests" clean -fd >/dev/null 2>&1 || true + fi + + # Keep this migration workaround from the old setup flow. Going directly + # from v2025.10.0 to v2025.12.0 has required a clean checkout in practice. + if [[ "${cached_tag}" == "refs/tags/v2025.10.0" && \ + "${mlsdk_manifest_tag}" == "refs/tags/v2025.12.0" ]]; then + pushd "${manifest_dir}/.." >/dev/null || return 1 + log_step "mlsdk" "Deleting ${mlsdk_manifest_dir} and starting fresh" + rm -rf "$(basename "${manifest_dir}")" + popd >/dev/null || return 1 + fi + + mlsdk_sync_manifest "${manifest_dir}" +} + +function setup_mlsdk_source() { + local manifest_dir="$1" + + if [[ -z "${manifest_dir}" ]]; then + log_step "mlsdk" "Error: manifest_dir parameter is required" + return 1 + fi + + mkdir -p "${root_dir}" + pushd "${root_dir}" >/dev/null || return 1 + + log_step "mlsdk" "Syncing MLSDK manifest into ${manifest_dir}" + download_ai_mlsdk_manifest "${manifest_dir}" + + pushd "${manifest_dir}" >/dev/null || return 1 + local parallel_jobs + parallel_jobs="$(get_parallel_jobs)" + + if [[ "${enable_model_converter}" -eq 1 ]]; then + log_step "mlsdk" "Building MLSDK model-converter" + python sw/model-converter/scripts/build.py -j"${parallel_jobs}" + log_step "mlsdk" "MLSDK model-converter build complete" + fi + + if [[ "${enable_vgf_lib}" -eq 1 ]]; then + log_step "mlsdk" "Building MLSDK VGF library" + pushd sw/vgf-lib >/dev/null || return 1 + python scripts/build.py -j"${parallel_jobs}" + cmake --install build --prefix deploy + popd >/dev/null || return 1 + log_step "mlsdk" "MLSDK VGF library build complete" + fi + + if [[ "${enable_emulation_layer}" -eq 1 ]]; then + local float_as_double + float_as_double="$(detect_emulation_layer_float_as_double)" + if [[ "${float_as_double}" == "ON" ]]; then + log_step "mlsdk" \ + "Detected missing shaderFloat64 support. Building Vulkan emulation layer with VMEL_USE_FLOAT_AS_DOUBLE=ON." + elif [[ "${float_as_double}" == "UNKNOWN" ]]; then + log_step "mlsdk" \ + "shaderFloat64 support could not be detected. Building Vulkan emulation layer with VMEL_USE_FLOAT_AS_DOUBLE=OFF." + fi + + log_step "mlsdk" "Building MLSDK Vulkan emulation layer" + pushd sw/emulation-layer >/dev/null || return 1 + cmake -B build \ + -DGLSLANG_PATH=../../dependencies/glslang \ + -DSPIRV_CROSS_PATH=../../dependencies/SPIRV-Cross \ + -DSPIRV_HEADERS_PATH=../../dependencies/SPIRV-Headers \ + -DSPIRV_TOOLS_PATH=../../dependencies/SPIRV-Tools \ + -DVULKAN_HEADERS_PATH=../../dependencies/Vulkan-Headers \ + -DVMEL_USE_FLOAT_AS_DOUBLE="${float_as_double/UNKNOWN/OFF}" + cmake --build build -j"${parallel_jobs}" + cmake --install build --prefix deploy + popd >/dev/null || return 1 + log_step "mlsdk" "MLSDK Vulkan emulation layer build complete" + fi + + popd >/dev/null || return 1 + popd >/dev/null || return 1 +} + +function setup_path_model_converter() { + local model_converter_bin_path="${mlsdk_manifest_dir}/sw/model-converter/build" + if [[ ! -d "${model_converter_bin_path}" ]]; then + log_step "path" "model-converter build output not found; skipping PATH update" + return + fi + + model_converter_bin_path="$(cd "${model_converter_bin_path}" && pwd)" + append_env_in_setup_path PATH "${model_converter_bin_path}" +} + +function setup_path_vgf_lib() { + local model_vgf_path="${mlsdk_manifest_dir}/sw/vgf-lib/deploy" + if [[ ! -d "${model_vgf_path}" ]]; then + log_step "path" "VGF deploy directory not found; skipping PATH update" + return + fi + + model_vgf_path="$(cd "${model_vgf_path}" && pwd)" + append_env_in_setup_path PATH "${model_vgf_path}/bin" + append_env_in_setup_path LD_LIBRARY_PATH "${model_vgf_path}/lib" + append_env_in_setup_path DYLD_LIBRARY_PATH "${model_vgf_path}/lib" +} + +function setup_path_source_emulation_layer() { + local deploy_dir="${mlsdk_manifest_dir}/sw/emulation-layer/deploy" + if [[ ! -d "${deploy_dir}" ]]; then + log_step "path" "Emulation layer deploy directory not found; skipping Vulkan layer exports" + return + fi + + deploy_dir="$(cd "${deploy_dir}" && pwd)" + apply_emulation_layer_deploy_dir "${deploy_dir}" +} + +function create_setup_path() { + cd "${root_dir}" + + clear_setup_path + log_step "path" "Generating setup path scripts at ${setup_path_script}" + + if [[ -n "${VIRTUAL_ENV:-}" && -d "${VIRTUAL_ENV}/bin" ]]; then + prepend_env_in_setup_path PATH "${VIRTUAL_ENV}/bin" + elif [[ -d "${et_dir}/env/bin" ]]; then + prepend_env_in_setup_path PATH "${et_dir}/env/bin" + fi + + if [[ "${enable_vulkan_sdk}" -eq 1 ]]; then + setup_path_vulkan + fi + + if [[ "${enable_model_converter}" -eq 1 ]]; then + setup_path_model_converter + fi + + if [[ "${enable_vgf_lib}" -eq 1 ]]; then + setup_path_vgf_lib + fi + + if [[ "${enable_emulation_layer}" -eq 1 ]]; then + setup_path_source_emulation_layer + fi + + log_step "path" "Update PATH by sourcing ${setup_path_script}.{sh|fish}" +} + +check_options "$@" +check_platform_support +check_os_support + +setup_root_dir +if [[ "${mlsdk_manifest_dir}" != /* ]]; then + mlsdk_manifest_dir="${root_dir}/${mlsdk_manifest_dir}" +fi + +log_step "options" \ + "root=${root_dir}, manifest-dir=${mlsdk_manifest_dir}, manifest-url=${mlsdk_manifest_url}, manifest-tag=${mlsdk_manifest_tag}" +log_step "options" \ + "mlsdk: model-converter=${enable_model_converter}, vgf-lib=${enable_vgf_lib}, emu-layer=${enable_emulation_layer}, vulkan-sdk=${enable_vulkan_sdk}" + +if [[ "${enable_vulkan_sdk}" -eq 1 ]]; then + log_step "vulkan" "Configuring Vulkan SDK" + setup_vulkan_sdk +fi + +setup_mlsdk_source "${mlsdk_manifest_dir}" +create_setup_path diff --git a/backends/arm/scripts/vulkan_utils.sh b/backends/arm/scripts/vulkan_utils.sh index 2bbecffa7d0..c8b169c0c3d 100644 --- a/backends/arm/scripts/vulkan_utils.sh +++ b/backends/arm/scripts/vulkan_utils.sh @@ -20,9 +20,6 @@ source "${script_dir}/utils.sh" vulkan_sdk_version="1.4.321.1" vulkan_sdk_base_dir="vulkan_sdk" -# MLSDK dependencies -mlsdk_manifest_dir="ml-sdk-for-vulkan-manifest" - os_name="${OS:-$(uname -s)}" vulkan_sdk_arch="${ARCH}" diff --git a/examples/arm/setup.sh b/examples/arm/setup.sh index 6f7d8384467..323815b59a2 100755 --- a/examples/arm/setup.sh +++ b/examples/arm/setup.sh @@ -26,7 +26,6 @@ enable_model_converter=0 # model-converter tool for VGF output enable_vgf_lib=0 # vgf reader - runtime backend dependency enable_emulation_layer=0 # Vulkan layer driver - emulates Vulkan ML extensions enable_vulkan_sdk=0 # Download and export Vulkan SDK required by emulation layer -enable_mlsdk_pip_install=1 # Figure out if setup.sh was called or sourced and save it into "is_script_sourced" (return 0 2>/dev/null) && is_script_sourced=1 || is_script_sourced=0 @@ -54,9 +53,10 @@ OPTION_LIST=( "--enable-emulation-layer Enable MLSDK Vulkan emulation layer" "--disable-ethos-u-deps Do not setup what is needed for Ethos-U" "--enable-mlsdk-deps Setup what is needed for MLSDK" - "--install-mlsdk-deps-with-pip (default) Use MLSDK PyPi package. This flag will be removed." - "--install-mlsdk-deps-from-src Build from source instead of using MLSDK PyPi packages" - "--mlsdk-manifest-url URL to the MLSDK manifest for vulkan." + "--install-mlsdk-deps-with-pip (default) Use MLSDK PyPI packages" + "--install-mlsdk-deps-from-src Use the dedicated source-build script instead" + "--mlsdk-manifest-url Deprecated: use with the dedicated source-build script" + "--mlsdk-manifest-tag Deprecated: use with the dedicated source-build script" "--help Display help" ) @@ -146,12 +146,34 @@ function check_options() { shift ;; --install-mlsdk-deps-with-pip) - enable_mlsdk_pip_install=1 + log_step "mlsdk" \ + "Option '--install-mlsdk-deps-with-pip' is now the default behavior" shift ;; --install-mlsdk-deps-from-src) - enable_mlsdk_pip_install=0 - shift + log_step "mlsdk" \ + "Deprecated option '--install-mlsdk-deps-from-src' selected" + log_step "mlsdk" \ + "Source builds moved to ./backends/arm/scripts/setup-mlsdk-from-source.sh" + exit 1 + ;; + --mlsdk-manifest-url) + if [[ $# -lt 2 ]]; then + print_usage "$@" + exit 1 + fi + log_step "mlsdk" \ + "Deprecated option '--mlsdk-manifest-url' selected; use it with ./backends/arm/scripts/setup-mlsdk-from-source.sh instead" + shift 2 + ;; + --mlsdk-manifest-tag) + if [[ $# -lt 2 ]]; then + print_usage "$@" + exit 1 + fi + log_step "mlsdk" \ + "Deprecated option '--mlsdk-manifest-tag' selected; use it with ./backends/arm/scripts/setup-mlsdk-from-source.sh instead" + shift 2 ;; --enable-mlsdk-deps) enable_model_converter=1 @@ -190,10 +212,31 @@ function setup_ethos_u_tools() { } function setup_mlsdk_dependencies() { - log_step "mlsdk" "Installing MLSDK dependencies from pip" + log_step "mlsdk" "Installing MLSDK dependencies" pip install -r $et_dir/backends/arm/requirements-arm-vgf.txt } +function validate_mlsdk_pip_compatibility() { + if [[ "${enable_emulation_layer}" -eq 0 ]]; then + return + fi + + local float_as_double="" + float_as_double="$(detect_emulation_layer_float_as_double)" + if [[ "${float_as_double}" == "ON" ]]; then + log_step "mlsdk" \ + "Detected missing shaderFloat64 support. The pip-installed emulation layer does not include the required workaround." + log_step "mlsdk" \ + "Use ./backends/arm/scripts/setup-mlsdk-from-source.sh to build the emulation layer from source." + exit 1 + fi + + if [[ "${float_as_double}" == "UNKNOWN" ]]; then + log_step "mlsdk" \ + "Unable to detect shaderFloat64 support. If the emulation layer crashes, use ./backends/arm/scripts/setup-mlsdk-from-source.sh." + fi +} + function create_setup_path(){ cd "${root_dir}" @@ -206,11 +249,6 @@ function create_setup_path(){ prepend_env_in_setup_path PATH "${et_dir}/env/bin" fi - local use_mlsdk_pip=0 - if use_mlsdk_pip_package; then - use_mlsdk_pip=1 - fi - if [[ "${enable_fvps}" -eq 1 ]]; then setup_path_fvp fi @@ -223,33 +261,13 @@ function create_setup_path(){ setup_path_vulkan fi - if [[ "${enable_model_converter}" -eq 1 && "${use_mlsdk_pip}" -eq 0 ]]; then - setup_path_model_converter - fi - - if [[ "${enable_vgf_lib}" -eq 1 && "${use_mlsdk_pip}" -eq 0 ]]; then - setup_path_vgf_lib - fi - if [[ "${enable_emulation_layer}" -eq 1 ]]; then - if [[ "${use_mlsdk_pip}" -eq 0 ]]; then - setup_path_emulation_layer - else - setup_path_emulation_layer_from_pip - fi + setup_path_emulation_layer fi log_step "path" "Update PATH by sourcing ${setup_path_script}.{sh|fish}" } -function use_mlsdk_pip_package() { - if [[ "${enable_mlsdk_pip_install}" -eq 0 ]]; then - return 1 - fi - - return 0 -} - ######## ### main @@ -277,12 +295,8 @@ if [[ $is_script_sourced -eq 0 ]]; then setup_root_dir cd "${root_dir}" - if [[ "${mlsdk_manifest_dir}" != /* ]]; then - mlsdk_manifest_dir="${root_dir}/${mlsdk_manifest_dir}" - fi - log_step "options" \ - "root=${root_dir}, target-toolchain=${target_toolchain:-}, mlsdk-dir=${mlsdk_manifest_dir}" + "root=${root_dir}, target-toolchain=${target_toolchain:-}" log_step "options" \ "ethos-u: fvps=${enable_fvps}, toolchain=${enable_baremetal_toolchain}, vela=${enable_vela} | " \ "mlsdk: model-converter=${enable_model_converter}, vgf-lib=${enable_vgf_lib}, " \ @@ -310,21 +324,16 @@ if [[ $is_script_sourced -eq 0 ]]; then setup_vulkan_sdk fi + # Keep this after Vulkan SDK setup so vulkaninfo is available for the + # shaderFloat64 compatibility probe. + validate_mlsdk_pip_compatibility + if [[ "${enable_model_converter}" -eq 1 || \ "${enable_vgf_lib}" -eq 1 || \ "${enable_emulation_layer}" -eq 1 ]]; then log_step "mlsdk" "Configuring MLSDK components (model-converter=${enable_model_converter}, " \ "vgf-lib=${enable_vgf_lib}, emu-layer=${enable_emulation_layer})" - if use_mlsdk_pip_package; then - setup_mlsdk_dependencies - else - log_step "mlsdk" "Installing MLSDK dependencies from source" - setup_mlsdk ${root_dir} \ - ${mlsdk_manifest_dir} \ - ${enable_model_converter} \ - ${enable_vgf_lib} \ - ${enable_emulation_layer} - fi + setup_mlsdk_dependencies fi # Create the setup_path.sh used to create the PATH variable for shell