Skip to content

Commit 89255ab

Browse files
committed
Arm backend: Split MLSDK setup flows and handle shaderFloat64 workaround
Keep examples/arm/setup.sh focused on the pip-installed MLSDK flow and move source builds into the dedicated setup-mlsdk-from-source.sh script. Retain the old MLSDK source-build-related setup.sh options as deprecated compatibility shims that guide users to the dedicated source-build flow. When the Vulkan ICD reports shaderFloat64 = false, the pip-installed emulation layer is no longer accepted for that setup because it cannot be configured with the required workaround. In that case, setup.sh now points users to the source-build script, and the source-build script builds the emulation layer with VMEL_USE_FLOAT_AS_DOUBLE=ON. Also simplify pip-based emulation-layer environment setup by deriving paths from the installed package layout instead of scraping shell export output from the emulation_layer helper. Update the Arm README to document the split between the default pip workflow and the advanced source-build workflow. Change-Id: I4bebe171ee3b3728fb126c9d00d73881cb332253 Signed-off-by: Per Held <per.held@arm.com>
1 parent bb07e8b commit 89255ab

5 files changed

Lines changed: 499 additions & 317 deletions

File tree

backends/arm/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ Setup:
106106
./examples/arm/setup.sh --disable-ethos-u-deps --enable-mlsdk-deps
107107
```
108108

109+
This is the default setup path and installs the MLSDK components from pip.
110+
Developers who need local source builds can use:
111+
112+
```
113+
./backends/arm/scripts/setup-mlsdk-from-source.sh
114+
```
115+
109116
The current flow lowers to TOSA and converts to VGF for use in external projects,
110117
so the `executor_runner` is not typically used here.
111118

backends/arm/scripts/mlsdk_utils.sh

Lines changed: 41 additions & 265 deletions
Original file line numberDiff line numberDiff line change
@@ -6,236 +6,68 @@
66

77
set -euo pipefail
88

9-
# URL and tag of the MLSDK manifest repository. Can be overridden by environment variables.
10-
# eg. export MLSDK_MANIFEST_URL=...; export MLSDK_MANIFEST_TAG=...
11-
mlsdk_manifest_url="${MLSDK_MANIFEST_URL:-https://github.com/arm/ai-ml-sdk-manifest.git}"
12-
mlsdk_manifest_tag="${MLSDK_MANIFEST_TAG:-refs/tags/v2025.12.0}"
13-
149
script_dir=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd)
1510

1611
source ${script_dir}/utils.sh
1712

18-
function mlsdk_sync_manifest() {
19-
local manifest_dir="$1"
20-
21-
mkdir -p "${manifest_dir}"
22-
pushd "${manifest_dir}" || return 1
23-
local parallel_jobs="$(get_parallel_jobs)"
24-
25-
if [[ ! -f repo ]]; then
26-
log_step "mlsdk" "Fetching repo tool"
27-
curl https://storage.googleapis.com/git-repo-downloads/repo > repo
28-
chmod u+x repo
29-
fi
30-
31-
./repo init \
32-
--depth=1 \
33-
--no-repo-verify \
34-
--manifest-url "${mlsdk_manifest_url}" \
35-
--manifest-branch "${mlsdk_manifest_tag}" \
36-
-g model-converter,emulation-layer,vgf-library
37-
38-
local default_manifest=".repo/manifests/default.xml"
39-
40-
./repo sync --force-sync -j"${parallel_jobs}"
41-
42-
popd
43-
}
44-
45-
function download_ai_mlsdk_manifest() {
46-
local _manifest_dir="$1"
13+
function apply_emulation_layer_deploy_dir() {
14+
local deploy_dir="$1"
4715

48-
if [[ -z "${_manifest_dir}" ]]; then
49-
log_step "mlsdk" "Error: _manifest_dir parameter missing"
16+
if [[ -z "${deploy_dir}" ]] || [[ ! -d "${deploy_dir}" ]]; then
5017
return 1
5118
fi
5219

53-
if [[ -z "${mlsdk_manifest_url}" ]]; then
54-
log_step "mlsdk" "Error: mlsdk_manifest_url parameter missing"
55-
return 1
56-
fi
20+
prepend_env_in_setup_path LD_LIBRARY_PATH "${deploy_dir}/lib"
21+
prepend_env_in_setup_path DYLD_LIBRARY_PATH "${deploy_dir}/lib"
22+
prepend_env_in_setup_path VK_LAYER_PATH "${deploy_dir}/share/vulkan/explicit_layer.d"
23+
prepend_env_in_setup_path VK_ADD_LAYER_PATH "${deploy_dir}/share/vulkan/explicit_layer.d"
24+
prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Tensor_Emulation
25+
prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Graph_Emulation
26+
}
5727

58-
if [[ ! -d "${_manifest_dir}/sw" ]] || [[ ! -d "${_manifest_dir}/dependencies" ]]; then
59-
log_step "mlsdk" "MLSDK checkout not found at ${_manifest_dir}; performing initial download"
60-
mlsdk_sync_manifest "${_manifest_dir}"
28+
function find_vulkaninfo_binary() {
29+
if command -v vulkaninfo >/dev/null 2>&1; then
30+
command -v vulkaninfo
6131
return 0
6232
fi
6333

64-
# If a checkout exists, get the URL and tag of the existing checkout.
65-
local cached_url=""
66-
local cached_tag=""
67-
local repo_config="${_manifest_dir}/.repo/manifests.git/config"
68-
if [[ -f "${repo_config}" ]]; then
69-
cached_url="$(git config --file "${repo_config}" remote.origin.url 2>/dev/null || echo "")"
70-
cached_tag="$(git config --file "${repo_config}" branch.default.merge 2>/dev/null || echo "")"
34+
if [[ -n "${root_dir:-}" && \
35+
-n "${vulkan_sdk_bin_dir:-}" && \
36+
-x "${root_dir}/${vulkan_sdk_bin_dir}/vulkaninfo" ]]; then
37+
printf '%s\n' "${root_dir}/${vulkan_sdk_bin_dir}/vulkaninfo"
38+
return 0
7139
fi
7240

73-
# If the tag is main or refs/heads/main, always refresh the checkout.
74-
# This allows users to track the latest main branch without needing to manually
75-
# delete the checkout.
76-
local tag_tracks_main=0
77-
if [[ "${mlsdk_manifest_tag}" == "main" ]] || [[ "${mlsdk_manifest_tag}" == "refs/heads/main" ]]; then
78-
tag_tracks_main=1
79-
fi
41+
return 1
42+
}
8043

81-
# If the URL and tag match, and the tag does not track main, reuse the existing checkout.
82-
# Skip fetching updates.
83-
if [[ "${cached_url}" == "${mlsdk_manifest_url}" ]] && [[ "${cached_tag}" == "${mlsdk_manifest_tag}" ]] && [[ "${tag_tracks_main}" -eq 0 ]]; then
84-
log_step "mlsdk" "Reusing cached MLSDK dependencies at ${_manifest_dir}"
44+
function detect_emulation_layer_float_as_double() {
45+
local vulkaninfo_bin=""
46+
if ! vulkaninfo_bin=$(find_vulkaninfo_binary); then
47+
log_step "mlsdk" \
48+
"vulkaninfo not found, can't detect shaderFloat64 support." >&2
49+
printf 'UNKNOWN\n'
8550
return 0
8651
fi
8752

88-
# If we reach here, either the URL or tag changed, or the tag tracks main.
89-
# In all cases, refresh the checkout.
90-
if [[ "${tag_tracks_main}" -eq 1 ]]; then
91-
log_step "mlsdk" "Manifest tracks branch ${mlsdk_manifest_tag}; refreshing checkout"
53+
if grep -qE 'shaderFloat64[[:space:]]*= false' < <("${vulkaninfo_bin}" 2>&1); then
54+
printf 'ON\n'
9255
else
93-
log_step "mlsdk" "Manifest changed (url=${cached_url:-<unknown>} -> ${mlsdk_manifest_url}, tag=${cached_tag:-<unknown>} -> ${mlsdk_manifest_tag}); refreshing checkout"
94-
fi
95-
96-
# Clean up any local manifest changes to avoid repo sync errors.
97-
# Since we patched in a local manifest for tosa_gitlab.xml,
98-
# remove any existing local manifests to avoid conflicts.
99-
# TODO: we should remove this at some point in the future, but its not hurting anything for now.
100-
if [[ -d "${_manifest_dir}/.repo/local_manifests" ]]; then
101-
rm -rf "${_manifest_dir}/.repo/local_manifests/"
102-
fi
103-
104-
# Clean up any local changes in the manifests repository.
105-
if [[ -d "${_manifest_dir}/.repo/manifests.git" ]]; then
106-
git -C "${_manifest_dir}/.repo/manifests.git" reset --hard HEAD >/dev/null 2>&1 || true
107-
git -C "${_manifest_dir}/.repo/manifests.git" clean -fd >/dev/null 2>&1 || true
108-
fi
109-
110-
# Clean up any local changes in the manifests working copy.
111-
if [[ -d "${_manifest_dir}/.repo/manifests" ]]; then
112-
git -C "${_manifest_dir}/.repo/manifests" reset --hard HEAD >/dev/null 2>&1 || true
113-
git -C "${_manifest_dir}/.repo/manifests" clean -fd >/dev/null 2>&1 || true
56+
printf 'OFF\n'
11457
fi
115-
116-
# Going from v2025.10.0 to v2025.12.0 seems particular hard so just keep it simple.
117-
# TODO: Remove once this is history
118-
if [[ "${cached_tag}" == "refs/tags/v2025.10.0" ]] && [[ "${mlsdk_manifest_tag}" == "refs/tags/v2025.12.0" ]]; then
119-
pushd "${_manifest_dir}/.."
120-
log_step "mlsdk" "Deleting ${mlsdk_manifest_dir} and starting fresh"
121-
manifest_base_dir=$(basename "${_manifest_dir}")
122-
rm -fr $manifest_base_dir
123-
popd
124-
fi
125-
126-
mlsdk_sync_manifest "${_manifest_dir}"
12758
}
12859

129-
function setup_mlsdk() {
130-
local work_dir="$1"
131-
local manifest_dir="$2"
132-
local enable_model_converter="$3"
133-
local enable_vgf_lib="$4"
134-
local enable_emulation_layer="$5"
135-
136-
if [[ -z "$work_dir" ]]; then
137-
log_step "mlsdk" "Error: work_dir parameter is required"
138-
return 1
60+
function find_emulation_layer_pkg_dir() {
61+
local py="python3"
62+
if ! command -v "${py}" >/dev/null 2>&1; then
63+
py="python"
13964
fi
14065

141-
if [[ -z "$manifest_dir" ]]; then
142-
log_step "mlsdk" "Error: manifest_dir parameter is required"
66+
if ! command -v "${py}" >/dev/null 2>&1; then
14367
return 1
14468
fi
14569

146-
mkdir -p "$work_dir"
147-
pushd "$work_dir" || exit 1
148-
149-
log_step "mlsdk" "Syncing MLSDK manifest into ${manifest_dir}"
150-
download_ai_mlsdk_manifest "${manifest_dir}"
151-
152-
pushd "$manifest_dir"
153-
local parallel_jobs="$(get_parallel_jobs)"
154-
155-
# model-converter
156-
if [[ "${enable_model_converter}" -eq 1 ]]; then
157-
log_step "mlsdk" "Building MLSDK model-converter"
158-
python sw/model-converter/scripts/build.py -j"${parallel_jobs}"
159-
log_step "mlsdk" "MLSDK model-converter build complete"
160-
fi
161-
162-
# libvgf
163-
if [[ "${enable_vgf_lib}" -eq 1 ]]; then
164-
log_step "mlsdk" "Building MLSDK VGF library"
165-
pushd sw/vgf-lib
166-
python scripts/build.py -j"${parallel_jobs}"
167-
cmake --install build --prefix deploy
168-
log_step "mlsdk" "MLSDK VGF library build complete"
169-
popd
170-
fi
171-
172-
# emu layer
173-
if [[ "${enable_emulation_layer}" -eq 1 ]]; then
174-
log_step "mlsdk" "Building MLSDK Vulkan emulation layer"
175-
pushd sw/emulation-layer
176-
cmake -B build \
177-
-DGLSLANG_PATH=../../dependencies/glslang \
178-
-DSPIRV_CROSS_PATH=../../dependencies/SPIRV-Cross \
179-
-DSPIRV_HEADERS_PATH=../../dependencies/SPIRV-Headers \
180-
-DSPIRV_TOOLS_PATH=../../dependencies/SPIRV-Tools \
181-
-DVULKAN_HEADERS_PATH=../../dependencies/Vulkan-Headers
182-
183-
cmake --build build -j"${parallel_jobs}"
184-
cmake --install build --prefix deploy
185-
log_step "mlsdk" "MLSDK Vulkan emulation layer build complete"
186-
popd
187-
fi
188-
189-
popd
190-
}
191-
192-
function setup_path_model_converter() {
193-
cd "${root_dir}"
194-
model_converter_bin_path="$(cd "${mlsdk_manifest_dir}/sw/model-converter/build" && pwd)"
195-
append_env_in_setup_path PATH "${model_converter_bin_path}"
196-
}
197-
198-
function setup_path_vgf_lib() {
199-
cd "${root_dir}"
200-
model_vgf_path="$(cd "${mlsdk_manifest_dir}/sw/vgf-lib/deploy" && pwd)"
201-
append_env_in_setup_path PATH "${model_vgf_path}/bin"
202-
append_env_in_setup_path LD_LIBRARY_PATH "${model_vgf_path}/lib"
203-
append_env_in_setup_path DYLD_LIBRARY_PATH "${model_vgf_path}/lib"
204-
}
205-
206-
function setup_path_emulation_layer() {
207-
cd "${root_dir}"
208-
model_emulation_layer_path="$(cd "${mlsdk_manifest_dir}/sw/emulation-layer/" && pwd)"
209-
prepend_env_in_setup_path LD_LIBRARY_PATH "${model_emulation_layer_path}/deploy/lib"
210-
prepend_env_in_setup_path DYLD_LIBRARY_PATH "${model_emulation_layer_path}/deploy/lib"
211-
prepend_env_in_setup_path VK_LAYER_PATH "${model_emulation_layer_path}/deploy/share/vulkan/explicit_layer.d"
212-
prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Tensor_Emulation
213-
prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Graph_Emulation
214-
}
215-
216-
function setup_path_emulation_layer_from_pip() {
217-
if ! command -v emulation_layer >/dev/null 2>&1; then
218-
echo "[mlsdk_utils] 'emulation_layer' command not found; skipping pip emulation layer path setup"
219-
return
220-
fi
221-
222-
local output
223-
if ! output=$(emulation_layer 2>/dev/null); then
224-
output=""
225-
fi
226-
227-
local exports
228-
exports=$(echo "$output" | grep '^export ' || true)
229-
230-
if [[ -z "${exports}" ]] || echo "$output" | grep -q "Unsupported platform"; then
231-
local py="python3"
232-
if ! command -v "${py}" >/dev/null 2>&1; then
233-
py="python"
234-
fi
235-
236-
local pkg_dir=""
237-
if command -v "${py}" >/dev/null 2>&1; then
238-
pkg_dir=$("${py}" - <<'PY'
70+
"${py}" - <<'PY'
23971
import importlib.util
24072
import os
24173
import sys
@@ -251,71 +83,15 @@ elif spec.origin:
25183
else:
25284
print("")
25385
PY
254-
)
255-
fi
86+
}
25687

257-
if [[ -n "${pkg_dir}" && -d "${pkg_dir}/deploy" ]]; then
258-
local deploy_dir="${pkg_dir}/deploy"
259-
prepend_env_in_setup_path LD_LIBRARY_PATH "${deploy_dir}/lib"
260-
prepend_env_in_setup_path DYLD_LIBRARY_PATH "${deploy_dir}/lib"
261-
prepend_env_in_setup_path VK_LAYER_PATH "${deploy_dir}/share/vulkan/explicit_layer.d"
262-
prepend_env_in_setup_path VK_ADD_LAYER_PATH "${deploy_dir}/share/vulkan/explicit_layer.d"
263-
prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Tensor_Emulation
264-
prepend_env_in_setup_path VK_INSTANCE_LAYERS VK_LAYER_ML_Graph_Emulation
88+
function setup_path_emulation_layer() {
89+
local pkg_dir=""
90+
if pkg_dir=$(find_emulation_layer_pkg_dir); then
91+
if [[ -n "${pkg_dir}" ]] && apply_emulation_layer_deploy_dir "${pkg_dir}/deploy"; then
26592
return
26693
fi
26794
fi
26895

269-
if [[ -z "${exports}" ]]; then
270-
echo "[mlsdk_utils] Failed to query emulation_layer environment; skipping"
271-
return
272-
fi
273-
274-
local ld_line
275-
ld_line=$(echo "$exports" | grep 'LD_LIBRARY_PATH=' || true)
276-
if [[ -n "${ld_line}" ]]; then
277-
local ld_value=${ld_line#export LD_LIBRARY_PATH=}
278-
ld_value=${ld_value%%:\$LD_LIBRARY_PATH*}
279-
if [[ -n "${ld_value}" ]]; then
280-
prepend_env_in_setup_path LD_LIBRARY_PATH "${ld_value}"
281-
fi
282-
fi
283-
284-
local dyld_line
285-
dyld_line=$(echo "$exports" | grep 'DYLD_LIBRARY_PATH=' || true)
286-
if [[ -n "${dyld_line}" ]]; then
287-
local dyld_value=${dyld_line#export DYLD_LIBRARY_PATH=}
288-
dyld_value=${dyld_value%%:\$DYLD_LIBRARY_PATH*}
289-
if [[ -n "${dyld_value}" ]]; then
290-
prepend_env_in_setup_path DYLD_LIBRARY_PATH "${dyld_value}"
291-
fi
292-
fi
293-
294-
local vk_layer_line
295-
vk_layer_line=$(echo "$exports" | grep 'VK_LAYER_PATH=' || true)
296-
if [[ -n "${vk_layer_line}" ]]; then
297-
local vk_layer_value=${vk_layer_line#export VK_LAYER_PATH=}
298-
vk_layer_value=${vk_layer_value%%:\$VK_LAYER_PATH*}
299-
if [[ -n "${vk_layer_value}" ]]; then
300-
prepend_env_in_setup_path VK_LAYER_PATH "${vk_layer_value}"
301-
fi
302-
fi
303-
304-
local vk_add_line
305-
vk_add_line=$(echo "$exports" | grep 'VK_ADD_LAYER_PATH=' || true)
306-
if [[ -n "${vk_add_line}" ]]; then
307-
local vk_add_value=${vk_add_line#export VK_ADD_LAYER_PATH=}
308-
if [[ -n "${vk_add_value}" ]]; then
309-
prepend_env_in_setup_path VK_ADD_LAYER_PATH "${vk_add_value}"
310-
fi
311-
fi
312-
313-
local vk_instance_line
314-
vk_instance_line=$(echo "$exports" | grep 'VK_INSTANCE_LAYERS=' || true)
315-
if [[ -n "${vk_instance_line}" ]]; then
316-
local vk_instance_value=${vk_instance_line#export VK_INSTANCE_LAYERS=}
317-
if [[ -n "${vk_instance_value}" ]]; then
318-
prepend_env_in_setup_path VK_INSTANCE_LAYERS "${vk_instance_value}"
319-
fi
320-
fi
96+
echo "[mlsdk_utils] Failed to query emulation_layer environment; skipping"
32197
}

0 commit comments

Comments
 (0)