From 145c6468f92d16e4025c2a88f1447ce7a6a935a2 Mon Sep 17 00:00:00 2001 From: Chen Lai Date: Tue, 22 Jul 2025 14:24:12 -0700 Subject: [PATCH] Install libcpp from release package other than apt-get Pull Request resolved: https://github.com/pytorch/executorch/pull/11832 A few changes 1. Use the release package from https://releases.llvm.org/ to install libcpp, so we can install from different linux in addition to Ubuntu 2. Seperate out the qnn version and the url to a seperate file, for better versin management in the future ghstack-source-id: 295685450 Differential Revision: [D77048745](https://our.internmc.facebook.com/intern/diff/D77048745/) --- .ci/scripts/setup-qnn-deps.sh | 44 +----- backends/qualcomm/scripts/install_qnn_sdk.sh | 153 +++++++++++++++++++ backends/qualcomm/scripts/qnn_config.sh | 10 ++ 3 files changed, 165 insertions(+), 42 deletions(-) create mode 100644 backends/qualcomm/scripts/install_qnn_sdk.sh create mode 100644 backends/qualcomm/scripts/qnn_config.sh diff --git a/.ci/scripts/setup-qnn-deps.sh b/.ci/scripts/setup-qnn-deps.sh index 45588e291e9..d962f7b908a 100644 --- a/.ci/scripts/setup-qnn-deps.sh +++ b/.ci/scripts/setup-qnn-deps.sh @@ -7,47 +7,7 @@ set -ex -verify_pkg_installed() { - echo $(dpkg-query -W --showformat='${Status}\n' $1|grep "install ok installed") -} +source "$(dirname "${BASH_SOURCE[0]}")/../../backends/qualcomm/scripts/install_qnn_sdk.sh" -install_qnn() { - echo "Start installing qnn." - QNN_INSTALLATION_DIR=/tmp/qnn - mkdir -p "${QNN_INSTALLATION_DIR}" - - curl -Lo /tmp/v2.28.0.24.10.29.zip "https://softwarecenter.qualcomm.com/api/download/software/qualcomm_neural_processing_sdk/v2.28.0.241029.zip" - echo "Finishing downloading qnn sdk." - unzip -qo /tmp/v2.28.0.24.10.29.zip -d /tmp - echo "Finishing unzip qnn sdk." - - - # Print the content for manual verification - ls -lah "/tmp/qairt" - mv "/tmp/qairt"/* "${QNN_INSTALLATION_DIR}" - echo "Finishing installing qnn '${QNN_INSTALLATION_DIR}' ." - - ls -lah "${QNN_INSTALLATION_DIR}" -} - -setup_libc++() { - clang_version=$1 - sudo apt-get update - pkgs_to_check=("libc++-${clang_version}-dev") - j=0 - while [ $j -lt ${#pkgs_to_check[*]} ]; do - install_status=$(verify_pkg_installed ${pkgs_to_check[$j]}) - if [ "$install_status" == "" ]; then - sudo apt-get install -y ${pkgs_to_check[$j]} - if [[ $? -ne 0 ]]; then - echo "ERROR: Failed to install required packages for libc++" - exit 1 - fi - fi - j=$(( $j +1)); - done -} - -# This needs to match with the clang version from the Docker image -setup_libc++ 12 +setup_libcpp 12 install_qnn diff --git a/backends/qualcomm/scripts/install_qnn_sdk.sh b/backends/qualcomm/scripts/install_qnn_sdk.sh new file mode 100644 index 00000000000..913ce34b711 --- /dev/null +++ b/backends/qualcomm/scripts/install_qnn_sdk.sh @@ -0,0 +1,153 @@ +set -ex + +# Get the absolute path of this script +SCRIPT_DIR="$( cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 ; pwd -P )" + +# Source QNN configuration from the same directory +source "${SCRIPT_DIR}/qnn_config.sh" + +# Function to install Android NDK (only if not already set) +setup_android_ndk() { + # Check if ANDROID_NDK_ROOT is already set and valid + if [ -n "${ANDROID_NDK_ROOT}" ] && [ -d "${ANDROID_NDK_ROOT}" ]; then + echo "Android NDK already set to ${ANDROID_NDK_ROOT} - skipping installation" + return + fi + + NDK_VERSION="r26c" + NDK_INSTALL_DIR="/tmp/android-ndk" + + if [ -d "${NDK_INSTALL_DIR}/ndk" ]; then + echo "Android NDK already installed at ${NDK_INSTALL_DIR}/ndk" + export ANDROID_NDK_ROOT="${NDK_INSTALL_DIR}/ndk" + return + fi + + echo "Installing Android NDK ${NDK_VERSION}" + mkdir -p "${NDK_INSTALL_DIR}" + NDK_ZIP="android-ndk-${NDK_VERSION}-linux.zip" + + curl -Lo "/tmp/${NDK_ZIP}" "https://dl.google.com/android/repository/${NDK_ZIP}" + unzip -q "/tmp/${NDK_ZIP}" -d "${NDK_INSTALL_DIR}" + mv "${NDK_INSTALL_DIR}/android-ndk-${NDK_VERSION}" "${NDK_INSTALL_DIR}/ndk" + + export ANDROID_NDK_ROOT="${NDK_INSTALL_DIR}/ndk" + echo "Android NDK installed to ${ANDROID_NDK_ROOT}" +} + +verify_pkg_installed() { + dpkg-query -W --showformat='${Status}\n' "$1" | grep -q "install ok installed" +} + +install_qnn() { + # Check if QNN_SDK_ROOT is already set and valid + if [ -n "${QNN_SDK_ROOT}" ] && [ -d "${QNN_SDK_ROOT}" ]; then + echo "QNN SDK already set to ${QNN_SDK_ROOT} - skipping installation" + return + fi + + echo "Start installing qnn v${QNN_VERSION}" + QNN_INSTALLATION_DIR="/tmp/qnn" + + # Clean up any previous installation + if [ -d "${QNN_INSTALLATION_DIR}" ]; then + echo "Removing previous QNN installation at ${QNN_INSTALLATION_DIR}" + rm -rf "${QNN_INSTALLATION_DIR}" + fi + + mkdir -p "${QNN_INSTALLATION_DIR}" + + QNN_ZIP_FILE="v${QNN_VERSION}.zip" + curl -Lo "/tmp/${QNN_ZIP_FILE}" "${QNN_ZIP_URL}" + echo "Finishing downloading qnn sdk." + unzip -qo "/tmp/${QNN_ZIP_FILE}" -d /tmp + echo "Finishing unzip qnn sdk." + + # Print the content for manual verification + echo "Contents of /tmp/qairt:" + ls -lah "/tmp/qairt" + + # Move the specific version directory + if [ -d "/tmp/qairt/${QNN_VERSION}" ]; then + mv "/tmp/qairt/${QNN_VERSION}" "${QNN_INSTALLATION_DIR}" + else + mv "/tmp/qairt"/* "${QNN_INSTALLATION_DIR}" + fi + + echo "Finishing installing qnn '${QNN_INSTALLATION_DIR}' ." + echo "Final QNN installation contents:" + ls -lah "${QNN_INSTALLATION_DIR}" + + # Set QNN_SDK_ROOT environment variable + export QNN_SDK_ROOT="${QNN_INSTALLATION_DIR}" + echo "Set QNN_SDK_ROOT=${QNN_SDK_ROOT}" +} + +setup_libcpp() { + clang_version=$1 + LLVM_VERSION="14.0.0" + INSTALL_DIR="/tmp/libcxx-${LLVM_VERSION}" + + # Check if we already have a local installation + if [ -d "${INSTALL_DIR}/include" ] && [ -d "${INSTALL_DIR}/lib" ]; then + echo "Local libc++ already installed at ${INSTALL_DIR} - skipping" + # Set environment variables + export CPLUS_INCLUDE_PATH="${INSTALL_DIR}/include:$CPLUS_INCLUDE_PATH" + export LD_LIBRARY_PATH="${INSTALL_DIR}/lib:$LD_LIBRARY_PATH" + export LIBRARY_PATH="${INSTALL_DIR}/lib:$LIBRARY_PATH" + return + fi + + echo "Installing libc++ manually to ${INSTALL_DIR}" + + # Create temporary directory + TEMP_DIR=$(mktemp -d) + # Ensure cleanup on exit or return + trap 'rm -rf "$TEMP_DIR"' RETURN + + pushd "${TEMP_DIR}" >/dev/null + + BASE_NAME="clang+llvm-${LLVM_VERSION}-x86_64-linux-gnu-ubuntu-18.04" + LLVM_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/${BASE_NAME}.tar.xz" + + echo "Downloading LLVM from ${LLVM_URL}" + curl -fLO "${LLVM_URL}" || { + echo "Error: Failed to download LLVM" + exit 1 + } + + echo "Extracting ${BASE_NAME}.tar.xz" + tar -xf "${BASE_NAME}.tar.xz" || { + echo "Error: Failed to extract LLVM archive" + exit 1 + } + + # Create installation directory + mkdir -p "${INSTALL_DIR}/include" + mkdir -p "${INSTALL_DIR}/lib" + + # Copy libc++ headers and libraries + cp -r "${BASE_NAME}/include/c++/v1/"* "${INSTALL_DIR}/include/" + cp -r "${BASE_NAME}/lib/"*.so* "${INSTALL_DIR}/lib/" + + popd >/dev/null + + # Create necessary symlinks locally + pushd "${INSTALL_DIR}/lib" >/dev/null + ln -sf libc++.so.1.0 libc++.so.1 + ln -sf libc++.so.1 libc++.so + ln -sf libc++abi.so.1.0 libc++abi.so.1 + ln -sf libc++abi.so.1 libc++abi.so + popd >/dev/null + + # Set environment variables + export CPLUS_INCLUDE_PATH="${INSTALL_DIR}/include:$CPLUS_INCLUDE_PATH" + export LD_LIBRARY_PATH="${INSTALL_DIR}/lib:$LD_LIBRARY_PATH" + export LIBRARY_PATH="${INSTALL_DIR}/lib:$LIBRARY_PATH" + + echo "libc++ installed to ${INSTALL_DIR}" +} + +setup_libcpp 12 +setup_android_ndk +install_qnn diff --git a/backends/qualcomm/scripts/qnn_config.sh b/backends/qualcomm/scripts/qnn_config.sh new file mode 100644 index 00000000000..fe2d82e939e --- /dev/null +++ b/backends/qualcomm/scripts/qnn_config.sh @@ -0,0 +1,10 @@ +#!/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. + +# QNN SDK Configuration +QNN_VERSION="2.28.0.241029" +QNN_ZIP_URL="https://softwarecenter.qualcomm.com/api/download/software/qualcomm_neural_processing_sdk/v${QNN_VERSION}.zip"