diff --git a/.ci/docker/common/install_android.sh b/.ci/docker/common/install_android.sh index 0758a005a9..ab779ade8f 100755 --- a/.ci/docker/common/install_android.sh +++ b/.ci/docker/common/install_android.sh @@ -11,22 +11,33 @@ set -ex [ -n "${ANDROID_NDK_VERSION}" ] install_prerequiresites() { - apt-get update + OS=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"') + case "$OS" in + amzn) + # https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html + yum install -y java-17-amazon-corretto \ + ca-certificates \ + ant + ;; + *) + apt-get update - # NB: Need OpenJDK 17 at the minimum - apt-get install -y --no-install-recommends \ - openjdk-17-jdk \ - ca-certificates-java \ - ant + # NB: Need OpenJDK 17 at the minimum + apt-get install -y --no-install-recommends \ + openjdk-17-jdk \ + ca-certificates-java \ + ant - # Cleanup package manager - apt-get autoclean && apt-get clean - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + # Cleanup package manager + apt-get autoclean && apt-get clean + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + ;; + esac } install_ndk() { NDK_INSTALLATION_DIR=/opt/ndk - mkdir -p "${NDK_INSTALLATION_DIR}" + rm -rf "${NDK_INSTALLATION_DIR}" && mkdir -p "${NDK_INSTALLATION_DIR}" pushd /tmp # The NDK installation is cached on ossci-android S3 bucket @@ -54,7 +65,7 @@ install_cmdtools() { install_sdk() { SDK_INSTALLATION_DIR=/opt/android/sdk - mkdir -p "${SDK_INSTALLATION_DIR}" + rm -rf "${SDK_INSTALLATION_DIR}" && mkdir -p "${SDK_INSTALLATION_DIR}" # These are the tools needed to build Android apps yes | /opt/cmdline-tools/bin/sdkmanager --sdk_root="${SDK_INSTALLATION_DIR}" --install "platforms;android-34" diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 1533bec3fd..7b3d8ab9a8 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -45,6 +45,7 @@ jobs: # Build LLM Demo for Android bash build/build_android_llm_demo.sh ${{ matrix.tokenizer }} ${ARTIFACTS_DIR_NAME} + # Upload artifacts to S3. The artifacts are needed not only by the device farm but also TorchChat upload-artifacts: needs: build-llm-demo @@ -77,6 +78,73 @@ jobs: if-no-files-found: ignore path: ${{ runner.temp }}/artifacts/ + # Running Android emulator directly on the runner and not using Docker + run-emulator: + needs: build-llm-demo + runs-on: amz2023.linux.4xlarge + env: + ANDROID_NDK_VERSION: r26c + API_LEVEL: 34 + steps: + - name: Setup SSH (Click me for login details) + uses: pytorch/test-infra/.github/actions/setup-ssh@main + with: + github-secret: ${{ secrets.GITHUB_TOKEN }} + instructions: | + This is used to run Android emulators, ANDROID_HOME is installed at /opt/android/sdk + + - uses: actions/checkout@v3 + with: + submodules: false + + - name: Setup conda + uses: pytorch/test-infra/.github/actions/setup-miniconda@main + with: + python-version: '3.10' + + - name: Install Android dependencies + shell: bash + run: | + set -eux + + # Reuse the script that install Android on ET Docker image + sudo -E bash .ci/docker/common/install_android.sh + + - name: Gradle cache + uses: gradle/actions/setup-gradle@v3 + + - name: AVD cache + uses: actions/cache@v4 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-${{ env.API_LEVEL }} + + # NB: It takes about 10m to cold boot the emulator here + - name: Run Android emulator + env: + ANDROID_HOME: /opt/android/sdk + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ env.API_LEVEL }} + # NB: x86_64 emulator is slow because the lack of KVM support on AWS, it + # seems that we can use metal instance for that but it hasn't been tried + # out yet. Also arm64-v8a arch requires an ARM runner + arch: x86_64 + script: ./build/run_android_emulator.sh + # NB: This is to boot the emulator faster following the instructions on + # https://github.com/ReactiveCircus/android-emulator-runner. The max number + # of cores we can set is 6, any higher number will be reduced to 6. + cores: 6 + ram-size: 12288M + force-avd-creation: false + disable-animations: true + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + # This is to make sure that the job doesn't fail flakily + emulator-boot-timeout: 900 + # Let's see how expensive this job is, we might want to tone it down by running it periodically test-llama-app: needs: upload-artifacts diff --git a/build/run_android_emulator.sh b/build/run_android_emulator.sh new file mode 100755 index 0000000000..aa63e2a86a --- /dev/null +++ b/build/run_android_emulator.sh @@ -0,0 +1,22 @@ +#!/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. + +set -ex + +# This script is originally adopted from https://github.com/pytorch/pytorch/blob/main/android/run_tests.sh +ADB_PATH=$ANDROID_HOME/platform-tools/adb + +echo "Waiting for emulator boot to complete" +# shellcheck disable=SC2016 +$ADB_PATH wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 5; done;' + +# The device will be created by ReactiveCircus/android-emulator-runner GHA +echo "List all running emulators" +$ADB_PATH devices + +# TODO: Run tests on emulator here, atm the script only boots up the emulator +# and exits without doing anything yet