From e4bd4e88bbe583a39ff340177d19a660000f12a9 Mon Sep 17 00:00:00 2001 From: Sheetal Kadam Date: Wed, 2 Oct 2024 15:57:34 -0700 Subject: [PATCH] build android qnn package --- java/build-android.gradle | 29 ++++- .../github/android/build_aar_package.py | 5 + .../default_qnn_aar_build_settings.json | 17 +++ .../templates/android-qnn-java-api-aar.yml | 119 ++++++++++++++++++ .../azure-pipelines/templates/c-api-cpu.yml | 12 ++ 5 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 tools/ci_build/github/android/default_qnn_aar_build_settings.json create mode 100644 tools/ci_build/github/azure-pipelines/templates/android-qnn-java-api-aar.yml diff --git a/java/build-android.gradle b/java/build-android.gradle index fd22fa27e8db9..d2ab321749efa 100644 --- a/java/build-android.gradle +++ b/java/build-android.gradle @@ -8,6 +8,7 @@ def publishDir = System.properties['publishDir'] def minSdkVer = System.properties['minSdkVer'] def targetSdkVer = System.properties['targetSdkVer'] boolean enableTrainingApis = (System.properties['ENABLE_TRAINING_APIS'] ?: "0") == "1" +boolean addQnnDependency = (System.properties['addQnnDependency'] ?: "0") == "1" // Since Android requires a higher numbers indicating more recent versions // This function assume ORT version number will be in formart of A.B.C such as 1.7.0 @@ -25,7 +26,8 @@ project.buildDir = buildDir project.version = rootProject.file('../VERSION_NUMBER').text.trim() project.group = "com.microsoft.onnxruntime" -def tmpArtifactId = enableTrainingApis ? project.name + "-training" : project.name +def tmpArtifactId = "${project.name}${enableTrainingApis ? '-training' : ''}${addQnnDependency ? '-qnn' : ''}" + def mavenArtifactId = tmpArtifactId + '-android' def defaultDescription = 'ONNX Runtime is a performance-focused inference engine for ONNX (Open Neural Network ' + 'Exchange) models. This package contains the Android (aar) build of ONNX Runtime. It includes support for all ' + @@ -34,6 +36,9 @@ def trainingDescription = 'The onnxruntime-training android package is designed 'wide range of ONNX models on edge devices, such as mobile phones, tablets, and other portable devices with ' + 'a focus on minimizing resource usage and maximizing accuracy.' + 'See https://github.com/microsoft/onnxruntime-training-examples/tree/master/on_device_training for more details.' +def QNNDescription = 'ONNX Runtime is a performance-focused inference engine for ONNX (Open Neural Network ' + + 'Exchange) models. This package contains the Android (aar) build of ONNX Runtime for QNN. It includes support for all ' + + 'types and operators, for ONNX format models. All standard ONNX models can be executed with this package.' buildscript { repositories { @@ -137,8 +142,9 @@ publishing { artifact sourcesJar pom { - name = enableTrainingApis ? 'onnxruntime-training' : 'onnx-runtime' - description = enableTrainingApis ? trainingDescription : defaultDescription + name = addQnnDependency ? 'onnx-runtime-qnn-test' : (enableTrainingApis ? 'onnxruntime-training' : 'onnx-runtime') + description = addQnnDependency ? QNNDescription : (enableTrainingApis ? trainingDescription : defaultDescription) + url = 'https://microsoft.github.io/onnxruntime/' licenses { license { @@ -160,7 +166,22 @@ publishing { id = 'onnxruntime' name = 'ONNX Runtime' email = 'onnxruntime@microsoft.com' - } + } + } + + if (addQnnDependency) { + println "Modifying the POM XML to include QNN dependency" + def qnnVersion = project.hasProperty('qnnVersion') + + qnnVersion = "$qnnVersion.+" + withXml { + + def dependencynode = asNode().appendNode('dependencies').appendNode('dependency') + dependencynode.appendNode('groupId', 'com.qualcomm.qti') + dependencynode.appendNode('artifactId', 'qnn-runtime') + dependencynode.appendNode('version', qnnVersion) + dependencynode.appendNode('scope', 'runtime') + } } } } diff --git a/tools/ci_build/github/android/build_aar_package.py b/tools/ci_build/github/android/build_aar_package.py index 036db703ccf27..fef636125b2bc 100644 --- a/tools/ci_build/github/android/build_aar_package.py +++ b/tools/ci_build/github/android/build_aar_package.py @@ -79,6 +79,7 @@ def _build_aar(args): build_settings = _parse_build_settings(args) build_dir = os.path.abspath(args.build_dir) ops_config_path = os.path.abspath(args.include_ops_by_config) if args.include_ops_by_config else None + qnn_android_build = "--use_qnn" in build_settings["build_params"] # Setup temp environment for building temp_env = os.environ.copy() @@ -99,6 +100,9 @@ def _build_aar(args): abi_build_dir = os.path.join(intermediates_dir, abi) abi_build_command = [*base_build_command, "--android_abi=" + abi, "--build_dir=" + abi_build_dir] + if qnn_android_build: + qnn_home = os.getenv("QNN_HOME") + abi_build_command += ["--qnn_home=" + qnn_home] if ops_config_path is not None: abi_build_command += ["--include_ops_by_config=" + ops_config_path] @@ -156,6 +160,7 @@ def _build_aar(args): if "--enable_training_apis" in build_settings["build_params"] else "-DENABLE_TRAINING_APIS=0" ), + ("-DaddQnnDependency=1" if qnn_android_build else "-DaddQnnDependency=0"), ] # clean, build, and publish to a local directory diff --git a/tools/ci_build/github/android/default_qnn_aar_build_settings.json b/tools/ci_build/github/android/default_qnn_aar_build_settings.json new file mode 100644 index 0000000000000..0f38b56980d6e --- /dev/null +++ b/tools/ci_build/github/android/default_qnn_aar_build_settings.json @@ -0,0 +1,17 @@ +{ + "build_abis": [ + "arm64-v8a" + ], + "android_min_sdk_version": 21, + "android_target_sdk_version": 24, + "build_params": [ + "--enable_lto", + "--android", + "--parallel", + "--cmake_generator=Ninja", + "--build_java", + "--build_shared_lib", + "--use_qnn", + "--skip_tests" + ] +} diff --git a/tools/ci_build/github/azure-pipelines/templates/android-qnn-java-api-aar.yml b/tools/ci_build/github/azure-pipelines/templates/android-qnn-java-api-aar.yml new file mode 100644 index 0000000000000..e64614f615425 --- /dev/null +++ b/tools/ci_build/github/azure-pipelines/templates/android-qnn-java-api-aar.yml @@ -0,0 +1,119 @@ +parameters: +- name: buildConfig + displayName: Configuration to build + type: string + default: 'Release' + +- name: buildSettings + displayName: Path to the build setting file + type: string + default: '' + +- name: includedOpsConfig + displayName: Path to the included ops config file + type: string + default: '' + +- name: artifactName + displayName: Artifact Name + type: string + default: '' + +- name: job_name_suffix + displayName: Job name + type: string + default: '' + +- name: publish_executables + # The executables will only be published if the publish_executables is set to "1" + displayName: Publish executables such as onnxruntime_perf_test, ... + type: string + default: '0' + +- name: pool_name + displayName: Pool name + type: string + default: 'onnxruntime-Ubuntu2204-AMD-CPU' + +- name: packageName + displayName: Package Name + type: string + default: 'onnxruntime-android-qnn' + +- name: QnnSdk + displayName: QNN SDK version + type: string + default: 2.26.0.240828 + +jobs: +- job: Android_QNN_Java_API_AAR_Packaging_${{ parameters.job_name_suffix }} + timeoutInMinutes: 120 + workspace: + clean: all + pool: ${{parameters.pool_name}} + + variables: + artifacts_directory: $(Build.BinariesDirectory)/.artifacts + + steps: + - checkout: self + clean: true + submodules: none + + - task: CmdLine@2 + displayName: Create artifacts directory + inputs: + script: | + # Create a folder for artifacts + mkdir -p $(artifacts_directory) + workingDirectory: $(Build.BinariesDirectory) + + #TODO: use a different docker file since this job doesn't need to rely on manylinux + - template: get-docker-image-steps.yml + parameters: + Dockerfile: tools/ci_build/github/linux/docker/Dockerfile.manylinux2_28_cpu + Context: tools/ci_build/github/linux/docker + DockerBuildArgs: "--build-arg BUILD_UID=$( id -u )" + Repository: onnxruntimecpubuild + + - template: set-version-number-variables-step.yml + + - template: use-android-ndk.yml + + - task: CmdLine@2 + displayName: Build Android AAR Packages + inputs: + script: | + set -e -x + NDK_HOME=$(realpath $ANDROID_NDK_HOME) + mkdir $(Build.BinariesDirectory)/.build_settings + cp ${{parameters.buildSettings}} $(Build.BinariesDirectory)/.build_settings/build_settings.json + [ -f "${{parameters.includedOpsConfig}}" ] && \ + cp ${{parameters.includedOpsConfig}} $(Build.BinariesDirectory)/.build_settings/include_ops_and_types.config + docker run --rm \ + --volume $(Build.SourcesDirectory):/onnxruntime_src \ + --volume $(Build.BinariesDirectory):/build \ + --volume $ANDROID_HOME:/android_home \ + --volume $NDK_HOME:/ndk_home \ + --volume QnnSDKRootDir:/qnn_home \ + --volume $(artifacts_directory):/home/onnxruntimedev/.artifacts \ + --volume $(Build.BinariesDirectory)/.build_settings:/home/onnxruntimedev/.build_settings \ + -e QNN_SDK_VERSION=${{parameters.QnnSdk}} \ + -e NIGHTLY_BUILD \ + -e BUILD_BUILDNUMBER \ + -e BUILD_CONFIG=${{parameters.buildConfig}} \ + -e ORT_VERSION=$(OnnxRuntimeVersion) \ + -e PUBLISH_EXECUTABLES=${{parameters.publish_executables}} \ + -e PACKAGE_NAME=${{parameters.packageName}} \ + onnxruntimecpubuild \ + /bin/bash /onnxruntime_src/tools/ci_build/github/android/build_aar_and_copy_artifacts.sh + workingDirectory: $(Build.SourcesDirectory) + + - template: jar-maven-signing-linux.yml + parameters: + JarFileDirectory: '$(artifacts_directory)' + + #- task: PublishBuildArtifacts@1 + # inputs: + # pathtoPublish: '$(artifacts_directory)' + # artifactName: '${{parameters.artifactName}}' diff --git a/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml b/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml index a483db2f9688e..fa10d73a4b6cd 100644 --- a/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml +++ b/tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml @@ -76,6 +76,18 @@ stages: artifactName: 'onnxruntime-android-full-aar' job_name_suffix: 'Full' +- stage: Android_Java_API_AAR_Packaging_QNN + dependsOn: [] + jobs: + - template: android-qnn-java-api-aar.yml + parameters: + buildConfig: 'Release' + buildSettings: '$(Build.SourcesDirectory)/tools/ci_build/github/android/default_qnn_full_aar_build_settings.json' + artifactName: 'onnxruntime-android-full-aar' + job_name_suffix: 'QNN' + publish_executables: '0' + #TODO: Add test job for QNN Android AAR + - stage: iOS_Full_xcframework dependsOn: [] jobs: