Skip to content
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

build android qnn package #22295

Closed
wants to merge 4 commits into from
Closed
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
29 changes: 25 additions & 4 deletions java/build-android.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 ' +
Expand 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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -160,7 +166,22 @@ publishing {
id = 'onnxruntime'
name = 'ONNX Runtime'
email = '[email protected]'
}
}
}

if (addQnnDependency) {
println "Modifying the POM XML to include QNN dependency"
def qnnVersion = System.properties['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')
}
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions tools/ci_build/github/android/build_aar_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -99,6 +100,12 @@ 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")
qnn_sdk_version = os.getenv("QNN_SDK_VERSION")
if not qnn_sdk_version:
raise OSError("QNN_SDK_VERSION environment variable is not set.")
abi_build_command += ["--qnn_home=" + qnn_home]
if ops_config_path is not None:
abi_build_command += ["--include_ops_by_config=" + ops_config_path]

Expand Down Expand Up @@ -156,8 +163,13 @@ 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"),
]

# Add qnn specific parameters
if qnn_android_build:
gradle_command.append(f"-DqnnVersion={qnn_sdk_version}")

# clean, build, and publish to a local directory
subprocess.run([*gradle_command, "clean"], env=temp_env, shell=False, check=True, cwd=JAVA_ROOT)
subprocess.run([*gradle_command, "build"], env=temp_env, shell=False, check=True, cwd=JAVA_ROOT)
Expand Down
17 changes: 17 additions & 0 deletions tools/ci_build/github/android/default_qnn_aar_build_settings.json
Original file line number Diff line number Diff line change
@@ -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"
]
}
Original file line number Diff line number Diff line change
@@ -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}}'
21 changes: 21 additions & 0 deletions tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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_aar_build_settings.json'
artifactName: 'onnxruntime-android-qnn-aar'
job_name_suffix: 'QNN'
publish_executables: '0'
#TODO: Add test job for QNN Android AAR

- stage: iOS_Full_xcframework
dependsOn: []
jobs:
Expand Down Expand Up @@ -268,6 +280,7 @@ stages:
- Windows_Packaging_CPU_x64_${{ parameters.BuildVariant }}
- Windows_Packaging_CPU_arm64_${{ parameters.BuildVariant }}
- Android_Java_API_AAR_Packaging_Full
#- Android_Java_API_AAR_Packaging_QNN
- iOS_Full_xcframework
condition: succeeded()
jobs:
Expand Down Expand Up @@ -350,6 +363,14 @@ stages:
SpecificArtifact: ${{ parameters.specificArtifact }}
BuildId: ${{ parameters.BuildId }}

#- template: flex-downloadPipelineArtifact.yml
# parameters:
# StepName: 'Download Android-QNN-aar Pipeline Artifact'
# ArtifactName: 'onnxruntime-android-qnn-aar'
# TargetPath: '$(Build.BinariesDirectory)/nuget-artifact'
# SpecificArtifact: ${{ parameters.specificArtifact }}
# BuildId: ${{ parameters.BuildId }}

- template: flex-downloadPipelineArtifact.yml
parameters:
StepName: 'Download drop-extra Pipeline Artifact'
Expand Down
Loading