From a1a81470e36efdf5deacafaf2a014ebe5d5d6e83 Mon Sep 17 00:00:00 2001 From: gwang-msft <62914304+gwang-msft@users.noreply.github.com> Date: Wed, 9 Sep 2020 02:06:20 -0700 Subject: [PATCH] Add minimal build binary size verification (arm64) to Android CI (#5087) * Add minimal build binary size verification (arm64) to Android CI * Add comments in the CI ymal --- cmake/CMakeLists.txt | 6 +-- tools/ci_build/build.py | 49 ++++++++++++------- ...ndroid-x86_64-crosscompile-ci-pipeline.yml | 9 ++++ 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 489394acea..1c9738c654 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -222,10 +222,10 @@ if(onnxruntime_MINIMAL_BUILD) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections") if (CMAKE_HOST_SYSTEM MATCHES "Darwin") - add_link_options(-Wl,-dead_strip) + add_link_options(-Wl, -dead_strip) else() add_link_options(-Wl,--gc-sections) - endif() + endif() endif() endif() @@ -344,7 +344,7 @@ if (MSVC) SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Gw /GL") SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Gw /GL") endif() - + # The WinML build tool chain builds ARM/ARM64, and the internal tool chain does not have folders for spectre mitigation libs. # WinML performs spectre mitigation differently. if (NOT DEFINED onnxruntime_DISABLE_QSPECTRE_CHECK) diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index cbc9974c7f..60a54a91e5 100755 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -1173,25 +1173,36 @@ def run_onnxruntime_tests(args, source_dir, ctest_path, build_dir, configs): run_training_python_frontend_tests(cwd=cwd) continue - android_x86_64 = args.android_abi == 'x86_64' - if android_x86_64: - run_subprocess(os.path.join( - source_dir, 'tools', 'ci_build', 'github', 'android', - 'start_android_emulator.sh')) - adb_push('testdata', '/data/local/tmp/', cwd=cwd) - adb_push( - os.path.join(source_dir, 'cmake', 'external', 'onnx', 'onnx', 'backend', 'test'), - '/data/local/tmp/', cwd=cwd) - adb_push('onnxruntime_test_all', '/data/local/tmp/', cwd=cwd) - adb_push('onnx_test_runner', '/data/local/tmp/', cwd=cwd) - adb_shell( - 'cd /data/local/tmp && /data/local/tmp/onnxruntime_test_all') - if args.use_nnapi: + if args.android: + if args.android_abi == 'x86_64': + run_subprocess(os.path.join( + source_dir, 'tools', 'ci_build', 'github', 'android', + 'start_android_emulator.sh')) + adb_push('testdata', '/data/local/tmp/', cwd=cwd) + adb_push( + os.path.join(source_dir, 'cmake', 'external', 'onnx', 'onnx', 'backend', 'test'), + '/data/local/tmp/', cwd=cwd) + adb_push('onnxruntime_test_all', '/data/local/tmp/', cwd=cwd) + adb_push('onnx_test_runner', '/data/local/tmp/', cwd=cwd) adb_shell( - 'cd /data/local/tmp && /data/local/tmp/onnx_test_runner -e nnapi /data/local/tmp/test') # noqa - else: - adb_shell( - 'cd /data/local/tmp && /data/local/tmp/onnx_test_runner /data/local/tmp/test') # noqa + 'cd /data/local/tmp && /data/local/tmp/onnxruntime_test_all') + if args.use_nnapi: + adb_shell( + 'cd /data/local/tmp && /data/local/tmp/onnx_test_runner -e nnapi /data/local/tmp/test') # noqa + else: + adb_shell( + 'cd /data/local/tmp && /data/local/tmp/onnx_test_runner /data/local/tmp/test') # noqa + elif args.android_abi == 'arm64-v8a': + # For Android arm64 abi we are only verify the size of the binary generated by minimal build config + # Will fail the build if the shared_lib size is larger than the threshold + if args.minimal_build and config == 'MinSizeRel' and args.build_shared_lib: + # set current size limit to 1100KB + bin_size_threshold = 1100000 + bin_actual_size = os.path.getsize(os.path.join(cwd, 'libonnxruntime.so')) + log.info('Android arm64 minsizerel libonnxruntime.so size [' + str(bin_actual_size) + 'B]') + if bin_actual_size > bin_size_threshold: + raise BuildError('Android arm64 minsizerel libonnxruntime.so size [' + str(bin_actual_size) + + 'B] is bigger than threshold [' + str(bin_size_threshold) + 'B]') continue dll_path_list = [] if args.use_nuphar: @@ -1613,7 +1624,7 @@ def main(): args.update = True args.build = True if cross_compiling: - args.test = args.android_abi == 'x86_64' + args.test = args.android_abi == 'x86_64' or args.android_abi == 'arm64-v8a' else: args.test = True diff --git a/tools/ci_build/github/azure-pipelines/android-x86_64-crosscompile-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/android-x86_64-crosscompile-ci-pipeline.yml index 7295d954e4..0cfc84a63a 100644 --- a/tools/ci_build/github/azure-pipelines/android-x86_64-crosscompile-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/android-x86_64-crosscompile-ci-pipeline.yml @@ -2,8 +2,17 @@ jobs: - job: Android_CI pool: vmImage: 'macOS-10.15' + timeoutInMinutes: 120 steps: - script: brew install coreutils ninja displayName: Install coreutils and ninja - script: tools/ci_build/build.py --android --build_dir build --android_sdk_path $ANDROID_HOME --android_ndk_path $ANDROID_HOME/ndk-bundle --android_abi=x86_64 --android_api=29 --skip_submodule_sync --parallel --use_nnapi --cmake_generator=Ninja displayName: Build and Test on Android Emulator + - script: pip3 install -U onnx + # Since we want to build ORT with absolutely minimal size, we will need to exclude all the ops in build by running + # exclude_unused_ops.py, which will require onnx to be installed. + displayName: Install onnx for minimal build + - script: rm -rf build && mkdir -p $TMPDIR/include_ops && touch $TMPDIR/include_ops/include_no_ops.txt + displayName: Clear the previous build and setup for arm64 minimal build + - script: tools/ci_build/build.py --android --build_dir build --android_sdk_path $ANDROID_HOME --android_ndk_path $ANDROID_HOME/ndk-bundle --android_abi=arm64-v8a --android_api=29 --skip_submodule_sync --parallel --cmake_generator=Ninja --config MinSizeRel --minimal_build --disable_rtti --disable_ml_ops --disable_exceptions --build_shared_lib --include_ops_by_config $TMPDIR/include_ops/include_no_ops.txt + displayName: Build arm64 absolutely minimal build and verify the library size