|
1 |
| -# Android |
| 1 | +# Android Demo App |
2 | 2 |
|
3 |
| -## Demo applications and tutorials |
| 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). |
4 | 4 |
|
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/). |
| 5 | +Please join our [Discord](https://discord.com/channels/1334270993966825602/1349854760299270284) for any questions. |
0 commit comments