10000 Revert "Reapply "Delete TorchScript based Android demo app and point … · pytorch/pytorch@084c4aa · GitHub
[go: up one dir, main page]

Skip to content

Commit 084c4aa

Browse files
Revert "Reapply "Delete TorchScript based Android demo app and point to ExecuTorch (#153633)" (#153656)"
This reverts commit 7ed377f. Reverted #153656 on behalf of https://github.com/larryliu0820 due to Still being used internally so can't remove ([comment](#153656 (comment)))
1 parent e4a636d commit 084c4aa

File tree

119 files changed

+7700
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+7700
-3
lines changed

.ci/pytorch/build.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,30 @@ if [[ "$BUILD_ENVIRONMENT" == *aarch64* ]]; then
9999
export ACL_ROOT_DIR=/ComputeLibrary
100100
fi
101101

102+
if [[ "$BUILD_ENVIRONMENT" == *libtorch* ]]; then
103+
POSSIBLE_JAVA_HOMES=()
104+
POSSIBLE_JAVA_HOMES+=(/usr/local)
105+
POSSIBLE_JAVA_HOMES+=(/usr/lib/jvm/java-8-openjdk-amd64)
106+
POSSIBLE_JAVA_HOMES+=(/Library/Java/JavaVirtualMachines/*.jdk/Contents/Home)
107+
# Add the Windows-specific JNI
108+
POSSIBLE_JAVA_HOMES+=("$PWD/.circleci/windows-jni/")
109+
for JH in "${POSSIBLE_JAVA_HOMES[@]}" ; do
110+
if [[ -e "$JH/include/jni.h" ]] ; then
111+
# Skip if we're not on Windows but haven't found a JAVA_HOME
112+
if [[ "$JH" == "$PWD/.circleci/windows-jni/" && "$OSTYPE" != "msys" ]] ; then
113+
break
114+
fi
115+
echo "Found jni.h under $JH"
116+
export JAVA_HOME="$JH"
117+
export BUILD_JNI=ON
118+
break
119+
fi
120+
done
121+
if [ -z "$JAVA_HOME" ]; then
122+
echo "Did not find jni.h"
123+
fi
124+
fi
125+
102126
# Use special scripts for Android builds
103127
if [[ "${BUILD_ENVIRONMENT}" == *-android* ]]; then
104128
export ANDROID_NDK=/opt/ndk

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ option(
222222
BUILD_MOBILE_TEST
223223
"Build C++ test binaries for mobile (ARM) targets(need gtest and gbenchmark)"
224224
OFF)
225+
option(BUILD_JNI "Build JNI bindings" OFF)
225226
option(BUILD_MOBILE_AUTOGRAD
226227
"Build autograd function in mobile build (in development)" OFF)
227228
cmake_dependent_option(INSTALL_TEST "Install test binaries if BUILD_TEST is on"
@@ -1349,6 +1350,16 @@ if(BUILD_BINARY)
13491350
add_subdirectory(binaries)
13501351
endif()
13511352

1353+
# ---[ JNI
1354+
if(BUILD_JNI)
1355+
if(NOT MSVC)
1356+
string(APPEND CMAKE_CXX_FLAGS " -Wno-unused-variable")
1357+
endif()
1358+
set(BUILD_LIBTORCH_WITH_JNI 1)
1359+
set(FBJNI_SKIP_TESTS 1)
1360+
add_subdirectory(android/pytorch_android)
1361+
endif()
1362+
13521363
include(cmake/Summary.cmake)
13531364
caffe2_print_configuration_summary()
13541365

android/README.md

Lines changed: 238 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,240 @@
1-
# Android Demo App
1+
# Android
22

3-
Please refer to [pytorch-labs/executorch-examples](https://github.com/pytorch-labs/executorch-examples/tree/main/dl3/android/DeepLabV3Demo) for the Android demo app based on [ExecuTorch](https://github.com/pytorch/executorch).
3+
## Demo applications and tutorials
44

5-
Please join our [Discord](https://discord.com/channels/1334270993966825602/1349854760299270284) for any questions.
5+
Demo applications with code walk-through can be find in [this github repo](https://github.com/pytorch/android-demo-app).
6+
7+
## Publishing
8+
9+
##### Release
10+
Release artifacts are published to jcenter:
11+
12+
```groovy
13+
repositories {
14+
jcenter()
15+
}
16+
17+
# lite interpreter build
18+
dependencies {
19+
implementation 'org.pytorch:pytorch_android_lite:1.10.0'
20+
implementation 'org.pytorch:pytorch_android_torchvision_lite:1.10.0'
21+
}
22+
23+
# full jit build
24+
dependencies {
25+
implementation 'org.pytorch:pytorch_android:1.10.0'
26+
implementation 'org.pytorch:pytorch_android_torchvision:1.10.0'
27+
}
28+
```
29+
30+
##### Nightly
31+
32+
Nightly(snapshots) builds are published every night from `master` branch to [nexus sonatype snapshots repository](https://oss.sonatype.org/#nexus-search;quick~pytorch_android)
33+
34+
To use them repository must be specified explicitly:
35+
```groovy
36+
repositories {
37+
maven {
38+
url "https://oss.sonatype.org/content/repositories/snapshots"
39+
}
40+
}
41+
42+
# lite interpreter build
43+
dependencies {
44+
...
45+
implementation 'org.pytorch:pytorch_android_lite:1.12.0-SNAPSHOT'
46+
implementation 'org.pytorch:pytorch_android_torchvision_lite:1.12.0-SNAPSHOT'
47+
...
48+
}
49+
50+
# full jit build
51+
dependencies {
52+
...
53+
implementation 'org.pytorch:pytorch_android:1.12.0-SNAPSHOT'
54+
implementation 'org.pytorch:pytorch_android_torchvision:1.12.0-SNAPSHOT'
55+
...
56+
}
57+
```
58+
The current nightly(snapshots) version is the value of `VERSION_NAME` in `gradle.properties` in current folder, at this moment it is `1.8.0-SNAPSHOT`.
59+
60+
## Building PyTorch Android from Source
61+
62+
In some cases you might want to use a local build of pytorch android, for example you may build custom libtorch binary with another set of operators or to make local changes.
63+
64+
For this you can use `./scripts/build_pytorch_android.sh` script.
65+
```bash
66+
git clone https://github.com/pytorch/pytorch.git
67+
cd pytorch
68+
git submodule update --init --recursive
69+
bash ./scripts/build_pytorch_android.sh
70+
```
71+
72+
The workflow contains several steps:
73+
74+
1\. Build libtorch for android for all 4 android abis (armeabi-v7a, arm64-v8a, x86, x86_64)
75+
76+
2\. Create symbolic links to the results of those builds:
77+
`android/pytorch_android/src/main/jniLibs/${abi}` to the directory with output libraries
78+
`android/pytorch_android/src/main/cpp/libtorch_include/${abi}` to the directory with headers. These directories are used to build `libpytorch.so` library that will be loaded on android device.
79+
80+
3\. And finally run `gradle` in `android/pytorch_android` directory with task `assembleRelease`
81+
82+
Script requires that Android SDK, Android NDK and gradle are installed.
83+
They are specified as environment variables:
84+
85+
`ANDROID_HOME` - path to [Android SDK](https://developer.android.com/studio/command-line/sdkmanager.html)
86+
87+
`ANDROID_NDK` - path to [Android NDK](https://developer.android.com/studio/projects/install-ndk). It's recommended to use NDK 21.x.
88+
89+
`GRADLE_HOME` - path to [gradle](https://gradle.org/releases/)
90+
91+
92+
After successful build you should see the result as aar file:
93+
94+
```bash
95+
$ find pytorch_android/build/ -type f -name *aar
96+
pytorch_android/build/outputs/aar/pytorch_android.aar
97+
pytorch_android_torchvision/build/outputs/aar/pytorch_android.aar
98+
```
99+
100+
It can be used directly in android projects, as a gradle dependency:
101+
```groovy
102+
allprojects {
103+
repositories {
104+
flatDir {
105+
dirs 'libs'
106+
}
107+
}
108+
}
109+
110+
dependencies {
111+
implementation(name:'pytorch_android', ext:'aar')
112+
implementation(name:'pytorch_android_torchvision', ext:'aar')
113+
...
114+
implementation 'com.facebook.soloader:nativeloader:0.10.5'
115+
implementation 'com.facebook.fbjni:fbjni-java-only:0.2.2'
116+
}
117+
```
118+
We also have to add all transitive dependencies of our aars.
119+
As `pytorch_android` [depends](https://github.com/pytorch/pytorch/blob/master/android/pytorch_android/build.gradle#L76-L77) on `'com.facebook.soloader:nativeloader:0.10.5'` and `'com.facebook.fbjni:fbjni-java-only:0.2.2'`, we need to add them.
120+
(In case of using maven dependencies they are added automatically from `pom.xml`).
121+
122+
You can check out [test app example](https://github.com/pytorch/pytorch/blob/master/android/test_app/app/build.gradle) that uses aars directly.
123+
124+
## Linking to prebuilt libtorch library from gradle dependency
125+
126+
In some cases, you may want to use libtorch from your android native build.
127+
You can do it without building libtorch android, using native libraries from PyTorch android gradle dependency.
128+
For that, you will need to add the next lines to your gradle build.
129+
```groovy
130+
android {
131+
...
132+
configurations {
133+
extractForNativeBuild
134+
}
135+
...
136+
compileOptions {
137+
externalNativeBuild {
138+
cmake {
139+
arguments "-DANDROID_STL=c++_shared"
140+
}
141+
}
142+
}
143+
...
144+
externalNativeBuild {
145+
cmake {
146+
path "CMakeLists.txt"
147+
}
148+
}
149+
}
150+
151+
dependencies {
152+
extractForNativeBuild('org.pytorch:pytorch_android:1.10.0')
153+
}
154+
155+
task extractAARForNativeBuild {
156+
doLast {
157+
configurations.extractForNativeBuild.files.each {
158+
def file = it.absoluteFile
159+
copy {
160+
from zipTree(file)
161+
into "$buildDir/$file.name"
162+
include "headers/**"
163+
include "jni/**"
164+
}
165+
}
166+
}
167+
}
168+
169+
tasks.whenTaskAdded { task ->
170+
if (task.name.contains('externalNativeBuild')) {
171+
task.dependsOn(extractAARForNativeBuild)
172+
}
173+
}
174+
```
175+
176+
pytorch_android aar contains headers to link in `headers` folder and native libraries in `jni/$ANDROID_ABI/`.
177+
As PyTorch native libraries use `ANDROID_STL` - we should use `ANDROID_STL=c++_shared` to have only one loaded binary of STL.
178+
179+
The added task will unpack them to gradle build directory.
180+
181+
In your native build you can link to them adding these lines to your CMakeLists.txt:
182+
183+
184+
```cmake
185+
# Relative path of gradle build directory to CMakeLists.txt
186+
set(build_DIR ${CMAKE_SOURCE_DIR}/build)
187+
188+
file(GLOB PYTORCH_INCLUDE_DIRS "${build_DIR}/pytorch_android*.aar/headers")
189+
file(GLOB PYTORCH_LINK_DIRS "${build_DIR}/pytorch_android*.aar/jni/${ANDROID_ABI}")
190+
191+
set(BUILD_SUBDIR ${ANDROID_ABI})
192+
target_include_directories(${PROJECT_NAME} PRIVATE
193+
${PYTORCH_INCLUDE_DIRS}
194+
)
195+
196+
find_library(PYTORCH_LIBRARY pytorch_jni
197+
PATHS ${PYTORCH_LINK_DIRS}
198+
NO_CMAKE_FIND_ROOT_PATH)
199+
200+
find_library(FBJNI_LIBRARY fbjni
201+
PATHS ${PYTORCH_LINK_DIRS}
202+
NO_CMAKE_FIND_ROOT_PATH)
203+
204+
target_link_libraries(${PROJECT_NAME}
205+
${PYTORCH_LIBRARY})
206+
${FBJNI_LIBRARY})
207+
208+
```
209+
If your CMakeLists.txt file is located in the same directory as your build.gradle, `set(build_DIR ${CMAKE_SOURCE_DIR}/build)` should work for you. But if you have another location of it, you may need to change it.
210+
211+
After that, you can use libtorch C++ API from your native code.
212+
```cpp
213+
#include <string>
214+
#include <ATen/NativeFunctions.h>
215+
#include <torch/script.h>
216+
namespace pytorch_testapp_jni {
217+
namespace {
218+
struct JITCallGuard {
219+
c10::InferenceMode guard;
220+
torch::jit::GraphOptimizerEnabledGuard no_optimizer_guard{false};
221+
};
222+
}
223+
224+
void loadAndForwardModel(const std::string& modelPath) {
225+
JITCallGuard guard;
226+
torch::jit::Module module = torch::jit::load(modelPath);
227+
module.eval();
228+
torch::Tensor t = torch::randn({1, 3, 224, 224});
229+
c10::IValue t_out = module.forward({t});
230+
}
231+
}
232+
```
233+
234+
To load torchscript model for mobile we need some special setup which is placed in `struct JITCallGuard` in this example. It may change in future, you can track the latest changes keeping an eye in our [pytorch android jni code]([https://github.com/pytorch/pytorch/blob/master/android/pytorch_android/src/main/cpp/pytorch_jni_jit.cpp#L28)
235+
236+
[Example of linking to libtorch from aar](https://github.com/pytorch/pytorch/tree/master/android/test_app)
237+
238+
## PyTorch Android API Javadoc
239+
240+
You can find more details about the PyTorch Android API in the [Javadoc](https://pytorch.org/javadoc/).

android/build.gradle

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
allprojects {
2+
buildscript {
3+
ext {
4+
minSdkVersion = 21
5+
targetSdkVersion = 28
6+
compileSdkVersion = 28
7+
buildToolsVersion = '28.0.3'
8+
9+
coreVersion = "1.2.0"
10+
extJUnitVersion = "1.1.1"
11+
runnerVersion = "1.2.0"
12+
rulesVersion = "1.2.0"
13+
junitVersion = "4.12"
14+
15+
fbjniJavaOnlyVersion = "0.2.2"
16+
soLoaderNativeLoaderVersion = "0.10.5"
17+
}
18+
19+
repositories {
20+
google()
21+
mavenLocal()
22+
mavenCentral()
23+
jcenter()
24+
}
25+
26+
dependencies {
27+
classpath 'com.android.tools.build:gradle:4.1.2'
28+
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.14.2'
29+
}
30+
}
31+
32+
repositories {
33+
google()
34+
jcenter()
35+
}
36+
}
37+
38+
ext.deps = [
39+
jsr305: 'com.google.code.findbugs:jsr305:3.0.1',
40+
]

android/build_test_app.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/bash
2+
set -eux
3+
4+
PYTORCH_DIR="$(cd $(dirname $0)/..; pwd -P)"
5+
PYTORCH_ANDROID_DIR=$PYTORCH_DIR/android
6+
7+
echo "PYTORCH_DIR:$PYTORCH_DIR"
8+
9+
source "$PYTORCH_ANDROID_DIR/common.sh"
10+
11+
check_android_sdk
12+
check_gradle
13+
parse_abis_list "$@"
14+
build_android
15+
16+
# To set proxy for gradle add following lines to ./gradle/gradle.properties:
17+
# systemProp.http.proxyHost=...
18+
# systemProp.http.proxyPort=8080
19+
# systemProp.https.proxyHost=...
20+
# systemProp.https.proxyPort=8080
21+
22+
if [ "$CUSTOM_ABIS_LIST" = true ]; then
23+
NDK_DEBUG=1 $GRADLE_PATH -PnativeLibsDoNotStrip=true -PABI_FILTERS=$ABIS_LIST -p $PYTORCH_ANDROID_DIR clean test_app:assembleDebug
24+
else
25+
NDK_DEBUG=1 $GRADLE_PATH -PnativeLibsDoNotStrip=true -p $PYTORCH_ANDROID_DIR clean test_app:assembleDebug
26+
fi
27+
28+
find $PYTORCH_ANDROID_DIR -type f -name *apk
29+
30+
find $PYTORCH_ANDROID_DIR -type f -name *apk | xargs echo "To install apk run: $ANDROID_HOME/platform-tools/adb install -r "

0 commit comments

Comments
 (0)
0