diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index bc278de848..9fdb1ad398 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -22,15 +22,14 @@ concurrency:
cancel-in-progress: true
jobs:
- build-demo-android:
- name: build-demo-android
+ build-llm-demo:
+ name: build-llm-demo
uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
strategy:
matrix:
- tiktoken: [OFF, ON]
+ tokenizer: [bpe, tiktoken]
with:
- # NB: The example model dl3 requires lots of memory (T161064121)
- runner: linux.12xlarge
+ runner: linux.2xlarge
docker-image: executorch-ubuntu-22.04-clang12-android
submodules: 'true'
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
@@ -42,28 +41,8 @@ jobs:
# The generic Linux job chooses to use base env, not the one setup by the image
CONDA_ENV=$(conda env list --json | jq -r ".envs | .[-1]")
conda activate "${CONDA_ENV}"
-
- # Setup MacOS dependencies as there is no Docker support on MacOS atm
PYTHON_EXECUTABLE=python bash .ci/scripts/setup-linux.sh buck2
- # Build Android library
- export EXECUTORCH_USE_TIKTOKEN=${{ matrix.tiktoken }}
- bash build/build_android_library.sh
- # Build Android demo app
- bash build/test_android_ci.sh
+ export ARTIFACTS_DIR_NAME=artifacts-to-be-uploaded
- mkdir -p artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN
- mkdir -p artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/arm64-v8a/
- mkdir -p artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/x86_64/
- # Copy the jar to S3
- cp extension/android/build/libs/executorch.jar artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/
- # Copy the app and its test suite to S3
- cp examples/demo-apps/android/LlamaDemo/app/build/outputs/apk/debug/*.apk artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/
- cp examples/demo-apps/android/LlamaDemo/app/build/outputs/apk/androidTest/debug/*.apk artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/
- # Also copy the libraries
- cp cmake-out-android-arm64-v8a/lib/*.a artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/arm64-v8a/
- cp cmake-out-android-arm64-v8a/extension/android/*.so artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/arm64-v8a/
- cp cmake-out-android-x86_64/lib/*.a artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/x86_64/
- cp cmake-out-android-x86_64/extension/android/*.so artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/x86_64/
- # Copyp AAR to S3
- cp executorch.aar artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/
- cp executorch-llama.aar artifacts-to-be-uploaded/tiktoken_$EXECUTORCH_USE_TIKTOKEN/
+ # Build LLM Demo for Android
+ bash build/build_android_llm_demo.sh ${{ matrix.tokenizer }} ${ARTIFACTS_DIR_NAME}
diff --git a/build/build_android_library.sh b/build/build_android_llm_demo.sh
similarity index 52%
rename from build/build_android_library.sh
rename to build/build_android_llm_demo.sh
index 8f0a90b307..5bba039a31 100644
--- a/build/build_android_library.sh
+++ b/build/build_android_llm_demo.sh
@@ -11,14 +11,21 @@ build_jar() {
pushd extension/android
./gradlew build
popd
- cp extension/android/build/libs/executorch.jar "${BUILD_AAR_DIR}/libs"
+ mkdir -p "${BUILD_AAR_DIR}/libs"
+ cp extension/android/build/libs/executorch.jar "${BUILD_AAR_DIR}/libs/"
}
build_android_native_library() {
ANDROID_ABI="$1"
+ TOKENIZER="$2"
ANDROID_NDK="${ANDROID_NDK:-/opt/ndk}"
- CMAKE_OUT="cmake-out-android-$1"
- EXECUTORCH_USE_TIKTOKEN="${EXECUTORCH_USE_TIKTOKEN:-OFF}"
+ CMAKE_OUT="cmake-out-android-${ANDROID_ABI}"
+ if [[ $TOKENIZER == "tiktoken" ]]; then
+ EXECUTORCH_USE_TIKTOKEN=ON
+ else
+ EXECUTORCH_USE_TIKTOKEN=OFF
+ fi
+
cmake . -DCMAKE_INSTALL_PREFIX="${CMAKE_OUT}" \
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI="${ANDROID_ABI}" \
@@ -65,32 +72,66 @@ build_android_native_library() {
cmake --build "${CMAKE_OUT}"/extension/android -j "${CMAKE_JOBS}" --config Release
- cp "${CMAKE_OUT}"/extension/android/*.so "${BUILD_AAR_DIR}/jni/$1/"
+ # Copy artifacts to ABI specific directory
+ mkdir -p "${BUILD_AAR_DIR}/jni/${ANDROID_ABI}"
+ cp "${CMAKE_OUT}"/extension/android/*.so "${BUILD_AAR_DIR}/jni/${ANDROID_ABI}/"
}
build_aar() {
echo \ \
- \ \
- \ > "${BUILD_AAR_DIR}/AndroidManifest.xml"
+ package=\"org.pytorch.executorch\"\> \
+ \ \
+ \ > "${BUILD_AAR_DIR}/AndroidManifest.xml"
pushd "${BUILD_AAR_DIR}"
# Rename libexecutorch_jni.so to libexecutorch.so for soname consistency
# between Java and JNI
- mv jni/arm64-v8a/libexecutorch_jni.so jni/arm64-v8a/libexecutorch.so
- mv jni/x86_64/libexecutorch_jni.so jni/x86_64/libexecutorch.so
- zip -r executorch.aar libs jni/arm64-v8a/libexecutorch.so jni/x86_64/libexecutorch.so AndroidManifest.xml
+ find jni -type f -name "libexecutorch_jni.so" -exec bash -c 'mv "$1" "${1/_jni/}"' bash {} \;
+ # Zip all necessary files into the AAR file
+ zip -r executorch.aar libs jni/*/libexecutorch.so AndroidManifest.xml
+ zip -r executorch-llama.aar libs jni/*/libexecutorch_llama_jni.so AndroidManifest.xml
+ popd
+}
- rm jni/arm64-v8a/libexecutorch.so jni/x86_64/libexecutorch.so
- zip -r executorch-llama.aar libs jni/arm64-v8a/libexecutorch_llama_jni.so jni/x86_64/libexecutorch_llama_jni.so AndroidManifest.xml
+build_android_llm_demo_app() {
+ mkdir -p examples/demo-apps/android/LlamaDemo/app/libs
+ cp ${BUILD_AAR_DIR}/executorch-llama.aar examples/demo-apps/android/LlamaDemo/app/libs
+ pushd examples/demo-apps/android/LlamaDemo
+ ANDROID_HOME="${ANDROID_SDK:-/opt/android/sdk}" ./gradlew build assembleAndroidTest
popd
- cp "${BUILD_AAR_DIR}/executorch-llama.aar" .
- cp "${BUILD_AAR_DIR}/executorch.aar" .
+}
+
+collect_artifacts_to_be_uploaded() {
+ TOKENIZER="$1"
+ ARTIFACTS_DIR_NAME="$2"
+ DEMO_APP_DIR="${ARTIFACTS_DIR_NAME}/llm_demo_${TOKENIZER}"
+ # The app directory is named using its build flavor as a suffix.
+ mkdir -p "${DEMO_APP_DIR}"
+ # Collect the app and its test suite
+ cp examples/demo-apps/android/LlamaDemo/app/build/outputs/apk/debug/*.apk "${DEMO_APP_DIR}"
+ cp examples/demo-apps/android/LlamaDemo/app/build/outputs/apk/androidTest/debug/*.apk "${DEMO_APP_DIR}"
+ # Collect all ABI specific libraries
+ for ANDROID_ABI in "${ANDROID_ABIS[@]}"; do
+ mkdir -p "${DEMO_APP_DIR}/${ANDROID_ABI}"
+ cp cmake-out-android-${ANDROID_ABI}/lib/*.a "${DEMO_APP_DIR}/${ANDROID_ABI}/"
+ cp cmake-out-android-${ANDROID_ABI}/extension/android/*.so "${DEMO_APP_DIR}/${ANDROID_ABI}/"
+ done
+ # Collect JAR and AAR
+ cp extension/android/build/libs/executorch.jar "${DEMO_APP_DIR}"
+ find "${BUILD_AAR_DIR}/" -name 'executorch*.aar' -exec cp {} "${DEMO_APP_DIR}" \;
}
BUILD_AAR_DIR="$(mktemp -d)"
export BUILD_AAR_DIR
-mkdir -p "${BUILD_AAR_DIR}/jni/arm64-v8a" "${BUILD_AAR_DIR}/jni/x86_64" "${BUILD_AAR_DIR}/libs"
+ANDROID_ABIS=("arm64-v8a" "x86_64")
+export ANDROID_ABIS
+
+TOKENIZER="${1:-bpe}"
+ARTIFACTS_DIR_NAME="$2"
+
build_jar
-build_android_native_library arm64-v8a
-build_android_native_library x86_64
+for ANDROID_ABI in "${ANDROID_ABIS[@]}"; do
+ build_android_native_library ${ANDROID_ABI} ${TOKENIZER}
+done
build_aar
+build_android_llm_demo_app
+collect_artifacts_to_be_uploaded ${TOKENIZER} ${ARTIFACTS_DIR_NAME}
diff --git a/build/test_android_ci.sh b/build/test_android_ci.sh
index 9ad24e769b..f6ab72cb3f 100755
--- a/build/test_android_ci.sh
+++ b/build/test_android_ci.sh
@@ -26,15 +26,5 @@ build_android_demo_app() {
popd
}
-build_android_llama_demo_app() {
- mkdir -p examples/demo-apps/android/LlamaDemo/app/libs
- cp executorch-llama.aar examples/demo-apps/android/LlamaDemo/app/libs
- pushd examples/demo-apps/android/LlamaDemo
- ANDROID_HOME=/opt/android/sdk ./gradlew build
- ANDROID_HOME=/opt/android/sdk ./gradlew assembleAndroidTest
- popd
-}
-
export_model
build_android_demo_app
-build_android_llama_demo_app