PyTorch的Android编译

背景

Gemfield得承认,“PyTorch的Android编译”应该是“caffe2的Android编译”,只不过caffe2现在被合并到PyTorch仓库里了,所以这么写。所以本文中,如果说的是Android上的PyTorch,那么就等价于Android上的caffe2.

好了,如果要将PyTorch在GPU Server上训练的模型部署到Android手机上,应该怎么做呢?是的,要将PyTorch的模型转换为ONNX,然后再将ONNX转换为caffe2的pb模型文件。不过,这只是模型转换过去了,要完整的将一个App(哪怕是简化的demo)在Android手机上运行起来,必须要有一些工程上的封装诸如输入输出、网络的加载初始化、调用forward并取得前向的结果等。要做到这些功能,我们就得额外做以下的工作:

1,使用Android Studio(AS),这是安卓开发的IDE;

2,在AS上配置安装Android SDK,包含SDK Platforms、SDK Tools(Build-tools、CMake、NDK、SDK Platform-tools、SDK tools);其中NDK是为了Android上java语言调用C++ API而服务的;

3,额外的工程源代码,有基本的图像的输入输出处理,有模型的加载、前向等。在Android上,模型的加载、前向等功能的实现需要调用PyTorch(caffe2)library。这就带来了一个问题:编译Android程序时,项目代码必然要include PyTorch(caffe2)的头文件并且要链接PyTorch的library。

4,实际上,从项目编译的完整性上讲,除了要使用PyTorch库之外,C++的代码要include以下的头文件:

  • 自己写的
  • NDK的(可以理解为安卓系统头文件)
  • PyTorch的

而要链接以下库文件:

  • 自己编译的
  • NDK的
  • PyTorch的

Gemfield本文将要介绍如何编译PyTorch的Android库,并整理出需要include的PyTorch头文件

PyTorch安卓编译的入口

在PyTorch源代码目录下,要编译PyTorch的Android库,使用命令:

bash scripts/build_android.sh

这个脚本主要做了以下工作:

1,调用scripts/build_host_protoc.sh脚本编译出host上的protoc compiler,这是因为我们需要将protobuf 源文件编译/转换成c++源文件。这一步完成后,将生成build_host_protoc/bin/protoc可执行程序;

2,设置ANDROID_NDK路径;

3,CMake检测完成后得到的配置如下:

-- ******** Summary ********
-- General:
--   CMake version         : 3.13.3
--   CMake command         : /usr/local/lib/python2.7/dist-packages/cmake/data/bin/cmake
--   System                : Android
--   C++ compiler          : /home/gemfield/android-ndk-r16b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++
--   C++ compiler id       : Clang
--   C++ compiler version  : 3.8
--   BLAS                  : Eigen
--   CXX flags             : -isystem /home/gemfield/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=21 -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security -frtti -fexceptions  -Wno-deprecated -fvisibility-inlines-hidden -O2 -fPIC -Wno-narrowing -Wall -Wextra -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -Wno-invalid-partial-specialization -Wno-typedef-redefinition -Wno-unknown-warning-option -Wno-unused-private-field -Wno-inconsistent-missing-override -Wno-aligned-allocation-unavailable -Wno-c++14-extensions -Wno-constexpr-not-const -Wno-missing-braces -Qunused-arguments -Wno-unused-but-set-variable -Wno-maybe-uninitialized
--   Build type            : Release
--   Compile definitions   : ONNX_NAMESPACE=onnx_c2
--   CMAKE_PREFIX_PATH     :
--   CMAKE_INSTALL_PREFIX  : /home/gemfield/pytorch/install
--
--   TORCH_VERSION         : 1.0.0
--   CAFFE2_VERSION        : 1.0.0
--   BUILD_ATEN_MOBILE     : ON
--   BUILD_BINARY          : ON
--   BUILD_CUSTOM_PROTOBUF : ON
--     Protobuf compiler   :
--     Protobuf includes   :
--     Protobuf libraries  :
--   BUILD_CAFFE2_OPS      : ON
--   USE_EIGEN_FOR_BLAS    : ON
--   USE_NNPACK            : ON
--   USE_NUMPY             : ON
--   USE_QNNPACK           : ON
--   USE_DISTRIBUTED       : ON
--   Public Dependencies  : Threads::Threads
--   Private Dependencies : qnnpack;nnpack;cpuinfo;fp16;log;onnxifi_loader;dl
......

可以看到即将要编译BUILD_ATEN_MOBILE、BUILD_CAFFE2_OPS、USE_NNPACK、USE_QNNPACK等,这些都具有鲜明的移动平台特色。然后使用PyTorch源码中的Cmake文件进行编译。

要弄懂PyTorch Android library的编译原理,我们最好要弄懂PyTorch在服务端的编译与安卓版library的编译有什么区别。

PyTorch安卓编译的原理

假设PyTorch根目录在/home/gemfield/pytorch下,要编译PyTorch的安卓库,主要有以下步骤:

1,编译proto文件

要编译多个proto文件,以caffe2/proto/torch.proto为例,使用下面的命令:

build_host_protoc/bin/protoc -I/home/gemfield/pytorch --cpp_out=dllexport_decl=CAFFE2_API:/home/gemfield/pytorch/build_android /home/gemfield/pytorch/caffe2/proto/torch.proto

输入是caffe2/proto/torch.proto文件, 输出是在build_androidsss/caffe2/proto目录下产生源文件http://torch.pb.cc 、torch.pb.h。

2,编译生成Android上的静态库和动态库

下面就开始交叉编译C++源文件了,整个PyTorch项目总共会编译出以下15个.a库、2个.so库:

lib/libprotobuf.a
lib/libprotobuf-lite.a
lib/libclog.a
lib/libcpuinfo.a
lib/libqnnpack.a
lib/libcpuinfo_internals.a
lib/libpthreadpool.a
lib/libnnpack_reference_layers.a
lib/libnnpack.a
lib/libonnx_proto.a
lib/libonnxifi_loader.a
lib/libonnx.a
lib/libonnxifi_dummy.so
lib/libc10.a
lib/libcaffe2_protos.a
lib/libcaffe2.a
lib/libcaffe2_detectron_ops.so

每个库的编译一般都会经历3步:

  • 从C++源文件编译出.o文件;
  • 合并多个.o文件成为一个.a文件;
  • 使用arm-linux-androideabi-ranlib生成index来加速访问.a库;

限于篇幅,下面介绍.a和.so库的生成过程时默认会省略掉第1步和第3步。

编译生成Android上的libprotobuf.a

源文件是用以下参数进行编译的(以源文件third_party/protobuf/src/google/protobuf/http://wrappers.pb.cc为例):

/home/gemfield/android-ndk-r16b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ \
--target=armv7-none-linux-androideabi \
--gcc-toolchain=/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 \
--sysroot=/home/gemfield/android-ndk-r16b/sysroot  \
-DGOOGLE_PROTOBUF_CMAKE_BUILD -DHAVE_PTHREAD \
-I/home/gemfield/pytorch/build_android/third_party/protobuf/cmake \
-I/home/gemfield/pytorch/third_party/protobuf/src \
-isystem /home/gemfield/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/include \
-isystem /home/gemfield/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include \
-isystem /home/gemfield/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/include/backward \
-isystem /home/gemfield/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi \
-D__ANDROID_API__=21 -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong \
-no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb \
-mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security -frtti -fexceptions  \
-Wno-deprecated -fvisibility-inlines-hidden -Os -DNDEBUG  -fPIC \
-std=c++11 \
-o CMakeFiles/libprotobuf.dir/__/src/google/protobuf/wrappers.pb.cc.o \
-c /home/gemfield/pytorch/third_party/protobuf/src/google/protobuf/wrappers.pb.cc

多个.o文件合并成.a文件:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../../lib/libprotobuf.a
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/arena.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/arenastring.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/extension_set.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/generated_message_table_driven_lite.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/generated_message_util.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/implicit_weak_message.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/io/coded_stream.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/io/zero_copy_stream.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/io/zero_copy_stream_impl_lite.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/message_lite.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/repeated_field.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/bytestream.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/common.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/int128.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/io_win32.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/status.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/statusor.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/stringpiece.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/stringprintf.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/structurally_valid.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/strutil.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/time.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/wire_format_lite.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/any.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/any.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/api.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/compiler/importer.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/compiler/parser.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/descriptor.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/descriptor.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/descriptor_database.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/duration.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/dynamic_message.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/empty.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/extension_set_heavy.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/field_mask.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/generated_message_reflection.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/generated_message_table_driven.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/io/gzip_stream.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/io/printer.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/io/strtod.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/io/tokenizer.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/io/zero_copy_stream_impl.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/map_field.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/message.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/reflection_ops.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/service.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/source_context.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/struct.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/mathlimits.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/stubs/substitute.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/text_format.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/timestamp.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/type.pb.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/unknown_field_set.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/delimited_message_util.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/field_comparator.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/field_mask_util.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/datapiece.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/default_value_objectwriter.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/error_listener.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/field_mask_utility.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/json_escaping.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/json_objectwriter.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/json_stream_parser.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/object_writer.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/proto_writer.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/protostream_objectsource.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/protostream_objectwriter.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/type_info.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/type_info_test_helper.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/internal/utility.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/json_util.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/message_differencer.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/time_util.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/util/type_resolver_util.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/wire_format.cc.o
CMakeFiles/libprotobuf.dir/__/src/google/protobuf/wrappers.pb.cc.o

生成index来加快.a库中符号的访问:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ranlib \
../../../lib/libprotobuf.a

编译生成Android上的libprotobuf-lite.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libprotobuf-lite.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../../lib/libprotobuf-lite.a
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/arena.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/arenastring.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/extension_set.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/generated_message_table_driven_lite.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/generated_message_util.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/implicit_weak_message.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/io/coded_stream.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/io/zero_copy_stream.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/io/zero_copy_stream_impl_lite.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/message_lite.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/repeated_field.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/bytestream.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/common.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/int128.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/io_win32.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/status.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/statusor.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/stringpiece.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/stringprintf.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/structurally_valid.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/strutil.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/stubs/time.cc.o
CMakeFiles/libprotobuf-lite.dir/__/src/google/protobuf/wire_format_lite.cc.o

编译生成Android上的libclog.a

源文件编译成.o文件:

/home/gemfield/android-ndk-r16b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang \
--target=armv7-none-linux-androideabi \
--gcc-toolchain=/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 \
--sysroot=/home/gemfield/android-ndk-r16b/sysroot \
-DCLOG_LOG_TO_STDIO=0 -I/home/gemfield/pytorch/third_party/QNNPACK/deps/clog/include \
-I/home/gemfield/pytorch/third_party/protobuf/src  \
-isystem /home/gemfield/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi \
-D__ANDROID_API__=21 -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong \
-no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as \
-mthumb -mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security  -Os -DNDEBUG  -fPIC \
-std=c99 -o CMakeFiles/clog.dir/src/clog.c.o \  
-c /home/gemfield/pytorch/third_party/QNNPACK/deps/clog/src/clog.c

合并为.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libclog.a  CMakeFiles/clog.dir/src/clog.c.o

编译生成Android上的libcpuinfo.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libcpuinfo.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libcpuinfo.a 
CMakeFiles/cpuinfo.dir/src/init.c.o
CMakeFiles/cpuinfo.dir/src/api.c.o
CMakeFiles/cpuinfo.dir/src/arm/uarch.c.o
CMakeFiles/cpuinfo.dir/src/arm/cache.c.o
CMakeFiles/cpuinfo.dir/src/arm/linux/init.c.o
CMakeFiles/cpuinfo.dir/src/arm/linux/cpuinfo.c.o
CMakeFiles/cpuinfo.dir/src/arm/linux/clusters.c.o
CMakeFiles/cpuinfo.dir/src/arm/linux/chipset.c.o
CMakeFiles/cpuinfo.dir/src/arm/linux/midr.c.o
CMakeFiles/cpuinfo.dir/src/arm/linux/hwcap.c.o
CMakeFiles/cpuinfo.dir/src/arm/linux/aarch32-isa.c.o
CMakeFiles/cpuinfo.dir/src/arm/android/properties.c.o
CMakeFiles/cpuinfo.dir/src/linux/smallfile.c.o
CMakeFiles/cpuinfo.dir/src/linux/multiline.c.o
CMakeFiles/cpuinfo.dir/src/linux/current.c.o
CMakeFiles/cpuinfo.dir/src/linux/cpulist.c.o
CMakeFiles/cpuinfo.dir/src/linux/processors.c.o

编译生成Android上的libqnnpack.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libqnnpack.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libqnnpack.a 
CMakeFiles/qnnpack.dir/src/init.c.o
CMakeFiles/qnnpack.dir/src/add.c.o
CMakeFiles/qnnpack.dir/src/average-pooling.c.o
CMakeFiles/qnnpack.dir/src/channel-shuffle.c.o
CMakeFiles/qnnpack.dir/src/clamp.c.o
CMakeFiles/qnnpack.dir/src/convolution.c.o
CMakeFiles/qnnpack.dir/src/deconvolution.c.o
CMakeFiles/qnnpack.dir/src/fully-connected.c.o
CMakeFiles/qnnpack.dir/src/global-average-pooling.c.o
CMakeFiles/qnnpack.dir/src/leaky-relu.c.o
CMakeFiles/qnnpack.dir/src/max-pooling.c.o
CMakeFiles/qnnpack.dir/src/sigmoid.c.o
CMakeFiles/qnnpack.dir/src/softargmax.c.o
CMakeFiles/qnnpack.dir/src/operator-delete.c.o
CMakeFiles/qnnpack.dir/src/indirection.c.o
CMakeFiles/qnnpack.dir/src/operator-run.c.o
CMakeFiles/qnnpack.dir/src/u8lut32norm/scalar.c.o
CMakeFiles/qnnpack.dir/src/x8lut/scalar.c.o
CMakeFiles/qnnpack.dir/src/sgemm/6x8-psimd.c.o
CMakeFiles/qnnpack.dir/src/q8avgpool/mp8x9p8q-neon.c.o
CMakeFiles/qnnpack.dir/src/q8avgpool/up8x9-neon.c.o
CMakeFiles/qnnpack.dir/src/q8avgpool/up8xm-neon.c.o
CMakeFiles/qnnpack.dir/src/q8conv/4x8-neon.c.o
CMakeFiles/qnnpack.dir/src/q8conv/8x8-neon.c.o
CMakeFiles/qnnpack.dir/src/q8dwconv/mp8x25-neon.c.o
CMakeFiles/qnnpack.dir/src/q8dwconv/up8x9-neon.c.o
CMakeFiles/qnnpack.dir/src/q8gavgpool/mp8x7p7q-neon.c.o
CMakeFiles/qnnpack.dir/src/q8gavgpool/up8x7-neon.c.o
CMakeFiles/qnnpack.dir/src/q8gavgpool/up8xm-neon.c.o
CMakeFiles/qnnpack.dir/src/q8gemm/4x-sumrows-neon.c.o
CMakeFiles/qnnpack.dir/src/q8gemm/4x8-neon.c.o
CMakeFiles/qnnpack.dir/src/q8gemm/4x8c2-xzp-neon.c.o
CMakeFiles/qnnpack.dir/src/q8gemm/6x4-neon.c.o
CMakeFiles/qnnpack.dir/src/q8gemm/8x8-neon.c.o
CMakeFiles/qnnpack.dir/src/q8vadd/neon.c.o
CMakeFiles/qnnpack.dir/src/sgemm/5x8-neon.c.o
CMakeFiles/qnnpack.dir/src/sgemm/6x8-neon.c.o
CMakeFiles/qnnpack.dir/src/u8clamp/neon.c.o
CMakeFiles/qnnpack.dir/src/u8maxpool/16x9p8q-neon.c.o
CMakeFiles/qnnpack.dir/src/u8maxpool/sub16-neon.c.o
CMakeFiles/qnnpack.dir/src/u8rmax/neon.c.o
CMakeFiles/qnnpack.dir/src/x8zip/x2-neon.c.o
CMakeFiles/qnnpack.dir/src/x8zip/x3-neon.c.o
CMakeFiles/qnnpack.dir/src/x8zip/x4-neon.c.o
CMakeFiles/qnnpack.dir/src/x8zip/xm-neon.c.o
CMakeFiles/qnnpack.dir/src/hgemm/8x8-aarch32-neonfp16arith.S.o
CMakeFiles/qnnpack.dir/src/q8conv/4x8-aarch32-neon.S.o
CMakeFiles/qnnpack.dir/src/q8dwconv/up8x9-aarch32-neon.S.o
CMakeFiles/qnnpack.dir/src/q8gemm/4x8-aarch32-neon.S.o
CMakeFiles/qnnpack.dir/src/q8gemm/4x8c2-xzp-aarch32-neon.S.o

编译生成Android上的libcpuinfo_internals.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libcpuinfo_internals.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libcpuinfo_internals.a 
CMakeFiles/cpuinfo_internals.dir/src/init.c.o
CMakeFiles/cpuinfo_internals.dir/src/api.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/uarch.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/cache.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/linux/init.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/linux/cpuinfo.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/linux/clusters.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/linux/chipset.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/linux/midr.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/linux/hwcap.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/linux/aarch32-isa.c.o
CMakeFiles/cpuinfo_internals.dir/src/arm/android/properties.c.o
CMakeFiles/cpuinfo_internals.dir/src/linux/smallfile.c.o
CMakeFiles/cpuinfo_internals.dir/src/linux/multiline.c.o
CMakeFiles/cpuinfo_internals.dir/src/linux/current.c.o
CMakeFiles/cpuinfo_internals.dir/src/linux/cpulist.c.o
CMakeFiles/cpuinfo_internals.dir/src/linux/processors.c.o

编译生成Android上的libpthreadpool.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libpthreadpool.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libpthreadpool.a 
CMakeFiles/pthreadpool.dir/src/threadpool-pthreads.c.o

编译生成Android上的libnnpack_reference_layers.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libnnpack_reference_layers.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar \
qc../../lib/libnnpack_reference_layers.a 
CMakeFiles/nnpack_reference_layers.dir/src/ref/convolution-output.c.o
CMakeFiles/nnpack_reference_layers.dir/src/ref/convolution-input-gradient.c.o
CMakeFiles/nnpack_reference_layers.dir/src/ref/convolution-kernel.c.o
CMakeFiles/nnpack_reference_layers.dir/src/ref/fully-connected-output.c.o
CMakeFiles/nnpack_reference_layers.dir/src/ref/max-pooling-output.c.o
CMakeFiles/nnpack_reference_layers.dir/src/ref/softmax-output.c.o
CMakeFiles/nnpack_reference_layers.dir/src/ref/relu-output.c.o
CMakeFiles/nnpack_reference_layers.dir/src/ref/relu-input-gradient.c.o

编译生成Android上的libnnpack.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libnnpack.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libnnpack.a 
CMakeFiles/nnpack.dir/src/init.c.o
CMakeFiles/nnpack.dir/src/convolution-inference.c.o
CMakeFiles/nnpack.dir/src/fully-connected-inference.c.o
CMakeFiles/nnpack.dir/src/pooling-output.c.o
CMakeFiles/nnpack.dir/src/relu-output.c.o
CMakeFiles/nnpack.dir/src/softmax-output.c.o
CMakeFiles/nnpack.dir/src/fully-connected-output.c.o
CMakeFiles/nnpack.dir/src/relu-input-gradient.c.o
CMakeFiles/nnpack.dir/src/convolution-input-gradient.c.o
CMakeFiles/nnpack.dir/src/convolution-kernel-gradient.c.o
CMakeFiles/nnpack.dir/src/convolution-output.c.o
CMakeFiles/nnpack.dir/src/psimd/2d-fourier-8x8.c.o
CMakeFiles/nnpack.dir/src/psimd/2d-fourier-16x16.c.o
CMakeFiles/nnpack.dir/src/neon/2d-winograd-8x8-3x3.c.o
CMakeFiles/nnpack.dir/src/neon/2d-winograd-8x8-3x3-fp16.c.o
CMakeFiles/nnpack.dir/src/neon/blas/h4gemm.c.o
CMakeFiles/nnpack.dir/src/neon/blas/s4gemm.c.o
CMakeFiles/nnpack.dir/src/neon/blas/c4gemm-conjb.c.o
CMakeFiles/nnpack.dir/src/neon/blas/s4c2gemm-conjb.c.o
CMakeFiles/nnpack.dir/src/neon/blas/conv1x1.c.o
CMakeFiles/nnpack.dir/src/neon/blas/sgemm.c.o
CMakeFiles/nnpack.dir/src/neon/blas/h4gemm-aarch32.S.o
CMakeFiles/nnpack.dir/src/neon/blas/s4gemm-aarch32.S.o
CMakeFiles/nnpack.dir/src/neon/blas/sgemm-aarch32.S.o
CMakeFiles/nnpack.dir/src/neon/relu.c.o
CMakeFiles/nnpack.dir/src/psimd/softmax.c.o
CMakeFiles/nnpack.dir/src/neon/blas/sdotxf.c.o
CMakeFiles/nnpack.dir/src/psimd/blas/shdotxf.c.o
CMakeFiles/nnpack.dir/src/neon/blas/c4gemm.c.o
CMakeFiles/nnpack.dir/src/neon/blas/s4c2gemm.c.o
CMakeFiles/nnpack.dir/src/neon/blas/c4gemm-conjb-transc.c.o
CMakeFiles/nnpack.dir/src/neon/blas/s4c2gemm-conjb-transc.c.o

编译生成Android上的libonnx_proto.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libonnx_proto.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libonnx_proto.a 
CMakeFiles/onnx_proto.dir/onnx/onnx_onnx_c2.pb.cc.o
CMakeFiles/onnx_proto.dir/onnx/onnx-operators_onnx_c2.pb.cc.o

编译生成Android上的libonnxifi_loader.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libonnxifi_loader.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libonnxifi_loader.a 
CMakeFiles/onnxifi_loader.dir/onnx/onnxifi_loader.c.o

编译生成Android上的libonnx.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libonnx.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../../lib/libonnx.a 
CMakeFiles/onnx.dir/__/__/caffe2/onnx/torch_ops/defs.cc.o
CMakeFiles/onnx.dir/__/__/caffe2/onnx/torch_ops/schema.cc.o
CMakeFiles/onnx.dir/onnx/checker.cc.o
CMakeFiles/onnx.dir/onnx/common/assertions.cc.o
CMakeFiles/onnx.dir/onnx/common/interned_strings.cc.o
CMakeFiles/onnx.dir/onnx/common/ir_pb_converter.cc.o
CMakeFiles/onnx.dir/onnx/common/model_helpers.cc.o
CMakeFiles/onnx.dir/onnx/common/status.cc.o
CMakeFiles/onnx.dir/onnx/defs/controlflow/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/controlflow/old.cc.o
CMakeFiles/onnx.dir/onnx/defs/data_type_utils.cc.o
CMakeFiles/onnx.dir/onnx/defs/experiments/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/experiments/experiments_functions.cc.o
CMakeFiles/onnx.dir/onnx/defs/function.cc.o
CMakeFiles/onnx.dir/onnx/defs/generator/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/generator/old.cc.o
CMakeFiles/onnx.dir/onnx/defs/logical/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/logical/old.cc.o
CMakeFiles/onnx.dir/onnx/defs/math/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/math/old.cc.o
CMakeFiles/onnx.dir/onnx/defs/nn/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/nn/old.cc.o
CMakeFiles/onnx.dir/onnx/defs/reduction/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/rnn/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/rnn/old.cc.o
CMakeFiles/onnx.dir/onnx/defs/schema.cc.o
CMakeFiles/onnx.dir/onnx/defs/tensor/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/tensor/old.cc.o
CMakeFiles/onnx.dir/onnx/defs/traditionalml/defs.cc.o
CMakeFiles/onnx.dir/onnx/defs/traditionalml/old.cc.o
CMakeFiles/onnx.dir/onnx/onnxifi_utils.cc.o
CMakeFiles/onnx.dir/onnx/optimizer/optimize.cc.o
CMakeFiles/onnx.dir/onnx/optimizer/pass.cc.o
CMakeFiles/onnx.dir/onnx/optimizer/pass_manager.cc.o
CMakeFiles/onnx.dir/onnx/optimizer/pass_registry.cc.o
CMakeFiles/onnx.dir/onnx/shape_inference/implementation.cc.o
CMakeFiles/onnx.dir/onnx/version_converter/convert.cc.o
CMakeFiles/onnx.dir/onnx/version_converter/helper.cc.o

编译生成Android上的libonnxifi_dummy.so

源文件编译成.o文件使用的参数就不介绍了,同上;然后onnxifi_dummy.c.o链接-ldl -latomic -lm 生成libonnxifi_dummy.so库:

/home/gemfield/android-ndk-r16b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=armv7-none-linux-androideabi --gcc-toolchain=/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 \
--sysroot=/home/gemfield/android-ndk-r16b/sysroot -fPIC \
-isystem /home/gemfield/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi \
-D__ANDROID_API__=21 -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong \
-no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -mfpu=neon \
-Wa,--noexecstack -Wformat -Werror=format-security -Os -DNDEBUG  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a \
--sysroot /home/gemfield/android-ndk-r16b/platforms/android-21/arch-arm -Wl,--build-id \
-Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--fix-cortex-a8 -Wl,--no-undefined \
-Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now  -rdynamic -shared \
-Wl,-soname,libonnxifi_dummy.so -o ../../lib/libonnxifi_dummy.so \
CMakeFiles/onnxifi_dummy.dir/onnx/onnxifi_dummy.c.o -ldl -latomic -lm

编译生成Android上的libc10.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libc10.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../lib/libc10.a 
CMakeFiles/c10.dir/core/Allocator.cpp.o
CMakeFiles/c10.dir/core/CopyBytes.cpp.o
CMakeFiles/c10.dir/core/DefaultDtype.cpp.o
CMakeFiles/c10.dir/core/Device.cpp.o
CMakeFiles/c10.dir/core/DeviceType.cpp.o
CMakeFiles/c10.dir/core/Scalar.cpp.o
CMakeFiles/c10.dir/core/Storage.cpp.o
CMakeFiles/c10.dir/core/StorageImpl.cpp.o
CMakeFiles/c10.dir/core/Stream.cpp.o
CMakeFiles/c10.dir/core/TensorImpl.cpp.o
CMakeFiles/c10.dir/core/TensorOptions.cpp.o
CMakeFiles/c10.dir/core/TensorTypeId.cpp.o
CMakeFiles/c10.dir/core/TensorTypeIdRegistration.cpp.o
CMakeFiles/c10.dir/core/UndefinedTensorImpl.cpp.o
CMakeFiles/c10.dir/core/impl/DeviceGuardImplInterface.cpp.o
CMakeFiles/c10.dir/util/Array.cpp.o
CMakeFiles/c10.dir/util/Backtrace.cpp.o
CMakeFiles/c10.dir/util/C++17.cpp.o
CMakeFiles/c10.dir/util/Exception.cpp.o
CMakeFiles/c10.dir/util/Half.cpp.o
CMakeFiles/c10.dir/util/LeftRight.cpp.o
CMakeFiles/c10.dir/util/Logging.cpp.o
CMakeFiles/c10.dir/util/Metaprogramming.cpp.o
CMakeFiles/c10.dir/util/Optional.cpp.o
CMakeFiles/c10.dir/util/SmallVector.cpp.o
CMakeFiles/c10.dir/util/StringUtil.cpp.o
CMakeFiles/c10.dir/util/Type.cpp.o
CMakeFiles/c10.dir/util/TypeList.cpp.o
CMakeFiles/c10.dir/util/TypeTraits.cpp.o
CMakeFiles/c10.dir/util/UniqueVoidPtr.cpp.o
CMakeFiles/c10.dir/util/flags_use_gflags.cpp.o
CMakeFiles/c10.dir/util/flags_use_no_gflags.cpp.o
CMakeFiles/c10.dir/util/intrusive_ptr.cpp.o
CMakeFiles/c10.dir/util/numa.cpp.o
CMakeFiles/c10.dir/util/typeid.cpp.o

c10模块已经在Gemfield的专栏文章Gemfield:PyTorch ATen代码的动态生成介绍过了,这个模块实现了Tensor的核心,面向移动端。

编译生成Android上的libcaffe2_protos.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libcaffe2_protos.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../lib/libcaffe2_protos.a 
proto/CMakeFiles/Caffe2_PROTO.dir/caffe2.pb.cc.o
proto/CMakeFiles/Caffe2_PROTO.dir/caffe2_legacy.pb.cc.o
proto/CMakeFiles/Caffe2_PROTO.dir/hsm.pb.cc.o
proto/CMakeFiles/Caffe2_PROTO.dir/metanet.pb.cc.o
proto/CMakeFiles/Caffe2_PROTO.dir/predictor_consts.pb.cc.o
proto/CMakeFiles/Caffe2_PROTO.dir/prof_dag.pb.cc.o
proto/CMakeFiles/Caffe2_PROTO.dir/torch.pb.cc.o

编译生成Android上的libcaffe2.a

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并成libcaffe2.a库:

/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar qc \
../lib/libcaffe2.a 
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/ATenGeneral.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/Formatting.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/LegacyDeviceTypeInit.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/LegacyTypeDispatch.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/Range.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/Tensor.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/VariableHooksInterface.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/blob.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/context_base.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/dispatch/Dispatcher.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/interned_strings.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/ivalue.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/register_symbols.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/thread_pool.cpp.o
CMakeFiles/caffe2.dir/__/aten/src/ATen/core/type.cpp.o
CMakeFiles/caffe2.dir/core/allocator.cc.o
CMakeFiles/caffe2.dir/core/blob_serialization.cc.o
CMakeFiles/caffe2.dir/core/blob_stats.cc.o
CMakeFiles/caffe2.dir/core/common.cc.o
CMakeFiles/caffe2.dir/core/context.cc.o
CMakeFiles/caffe2.dir/core/context_base.cc.o
CMakeFiles/caffe2.dir/core/db.cc.o
CMakeFiles/caffe2.dir/core/event.cc.o
CMakeFiles/caffe2.dir/core/graph.cc.o
CMakeFiles/caffe2.dir/core/init.cc.o
CMakeFiles/caffe2.dir/core/init_denormals.cc.o
CMakeFiles/caffe2.dir/core/init_intrinsics_check.cc.o
CMakeFiles/caffe2.dir/core/init_omp.cc.o
CMakeFiles/caffe2.dir/core/int8_serialization.cc.o
CMakeFiles/caffe2.dir/core/memonger.cc.o
CMakeFiles/caffe2.dir/core/module.cc.o
CMakeFiles/caffe2.dir/core/net.cc.o
CMakeFiles/caffe2.dir/core/net_async_base.cc.o
CMakeFiles/caffe2.dir/core/net_async_scheduling.cc.o
CMakeFiles/caffe2.dir/core/net_async_task.cc.o
CMakeFiles/caffe2.dir/core/net_async_task_future.cc.o
CMakeFiles/caffe2.dir/core/net_async_task_graph.cc.o
CMakeFiles/caffe2.dir/core/net_async_tracing.cc.o
CMakeFiles/caffe2.dir/core/net_dag_utils.cc.o
CMakeFiles/caffe2.dir/core/net_parallel.cc.o
CMakeFiles/caffe2.dir/core/net_simple.cc.o
CMakeFiles/caffe2.dir/core/net_simple_refcount.cc.o
CMakeFiles/caffe2.dir/core/numa.cc.o
CMakeFiles/caffe2.dir/core/operator.cc.o
CMakeFiles/caffe2.dir/core/operator_c10wrapper.cc.o
CMakeFiles/caffe2.dir/core/operator_schema.cc.o
CMakeFiles/caffe2.dir/core/plan_executor.cc.o
CMakeFiles/caffe2.dir/core/prof_dag_counters.cc.o
CMakeFiles/caffe2.dir/core/qtensor.cc.o
CMakeFiles/caffe2.dir/core/qtensor_serialization.cc.o
CMakeFiles/caffe2.dir/core/stats.cc.o
CMakeFiles/caffe2.dir/core/tensor.cc.o
CMakeFiles/caffe2.dir/core/tensor_int8.cc.o
CMakeFiles/caffe2.dir/core/test_utils.cc.o
CMakeFiles/caffe2.dir/core/transform.cc.o
CMakeFiles/caffe2.dir/core/types.cc.o
CMakeFiles/caffe2.dir/core/workspace.cc.o
CMakeFiles/caffe2.dir/utils/bench_utils.cc.o
CMakeFiles/caffe2.dir/utils/cpuid.cc.o
CMakeFiles/caffe2.dir/utils/math/broadcast.cc.o
CMakeFiles/caffe2.dir/utils/math/elementwise.cc.o
CMakeFiles/caffe2.dir/utils/math/reduce.cc.o
CMakeFiles/caffe2.dir/utils/math/utils.cc.o
CMakeFiles/caffe2.dir/utils/math_cpu.cc.o
CMakeFiles/caffe2.dir/utils/murmur_hash3.cc.o
CMakeFiles/caffe2.dir/utils/proto_convert.cc.o
CMakeFiles/caffe2.dir/utils/proto_utils.cc.o
CMakeFiles/caffe2.dir/utils/proto_wrap.cc.o
CMakeFiles/caffe2.dir/utils/signal_handler.cc.o
CMakeFiles/caffe2.dir/utils/smart_tensor_printer.cc.o
CMakeFiles/caffe2.dir/utils/string_utils.cc.o
CMakeFiles/caffe2.dir/utils/thread_name.cc.o
CMakeFiles/caffe2.dir/utils/threadpool/ThreadPool.cc.o
CMakeFiles/caffe2.dir/utils/threadpool/pthreadpool.cc.o
CMakeFiles/caffe2.dir/utils/threadpool/pthreadpool_impl.cc.o
CMakeFiles/caffe2.dir/predictor/predictor.cc.o
CMakeFiles/caffe2.dir/predictor/predictor_utils.cc.o
CMakeFiles/caffe2.dir/predictor/predictor_config.cc.o
CMakeFiles/caffe2.dir/core/nomnigraph/Representations/NeuralNet.cc.o
CMakeFiles/caffe2.dir/core/nomnigraph/tests/test_util.cc.o
CMakeFiles/caffe2.dir/__/third_party/miniz-2.0.8/miniz.c.o
CMakeFiles/caffe2.dir/serialize/inline_container.cc.o
CMakeFiles/caffe2.dir/serialize/istream_adapter.cc.o
CMakeFiles/caffe2.dir/serialize/file_adapter.cc.o
CMakeFiles/caffe2.dir/serialize/read_adapter_interface.cc.o
CMakeFiles/caffe2.dir/db/create_db_op.cc.o
CMakeFiles/caffe2.dir/db/protodb.cc.o
CMakeFiles/caffe2.dir/distributed/file_store_handler.cc.o
CMakeFiles/caffe2.dir/distributed/file_store_handler_op.cc.o
CMakeFiles/caffe2.dir/distributed/store_handler.cc.o
CMakeFiles/caffe2.dir/distributed/store_ops.cc.o
CMakeFiles/caffe2.dir/onnx/backend.cc.o
CMakeFiles/caffe2.dir/onnx/backend_rep.cc.o
CMakeFiles/caffe2.dir/onnx/device.cc.o
CMakeFiles/caffe2.dir/onnx/helper.cc.o
CMakeFiles/caffe2.dir/onnx/onnx_exporter.cc.o
CMakeFiles/caffe2.dir/onnx/onnxifi_graph_info.cc.o
CMakeFiles/caffe2.dir/onnx/onnxifi_init.cc.o
CMakeFiles/caffe2.dir/operators/abs_op.cc.o
CMakeFiles/caffe2.dir/operators/accumulate_op.cc.o
CMakeFiles/caffe2.dir/operators/accuracy_op.cc.o
CMakeFiles/caffe2.dir/operators/acos_op.cc.o
CMakeFiles/caffe2.dir/operators/adjust_batch_op.cc.o
CMakeFiles/caffe2.dir/operators/affine_channel_op.cc.o
CMakeFiles/caffe2.dir/operators/apmeter_op.cc.o
......
CMakeFiles/caffe2.dir/operators/experimental/c10/schemas/add.cc.o
CMakeFiles/caffe2.dir/operators/experimental/c10/schemas/flatten.cc.o
CMakeFiles/caffe2.dir/operators/rnn/recurrent_network_blob_fetcher_op.cc.o
CMakeFiles/caffe2.dir/operators/rnn/recurrent_network_executor.cc.o
CMakeFiles/caffe2.dir/operators/rnn/recurrent_network_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/init_qnnpack.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_add_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_average_pool_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_channel_shuffle_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_concat_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_conv_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_conv_transpose_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_dequantize_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_fc_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_flatten_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_given_tensor_fill_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_leaky_relu_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_max_pool_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_quantize_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_relu_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_reshape_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_resize_nearest_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_roi_align_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_slice_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_sigmoid_op.cc.o
CMakeFiles/caffe2.dir/operators/quantized/int8_softmax_op.cc.o
CMakeFiles/caffe2.dir/opt/annotations.cc.o
CMakeFiles/caffe2.dir/opt/backend_cutting.cc.o
CMakeFiles/caffe2.dir/opt/bound_shape_inferencer.cc.o
CMakeFiles/caffe2.dir/opt/converter.cc.o
CMakeFiles/caffe2.dir/opt/dead_code_elim.cc.o
CMakeFiles/caffe2.dir/opt/device.cc.o
CMakeFiles/caffe2.dir/opt/distributed.cc.o
CMakeFiles/caffe2.dir/opt/distributed_converter.cc.o
CMakeFiles/caffe2.dir/opt/fusion.cc.o
CMakeFiles/caffe2.dir/opt/mobile.cc.o
CMakeFiles/caffe2.dir/opt/onnxifi_transformer.cc.o
CMakeFiles/caffe2.dir/opt/optimize_ideep.cc.o
CMakeFiles/caffe2.dir/opt/optimizer.cc.o
CMakeFiles/caffe2.dir/opt/passes.cc.o
CMakeFiles/caffe2.dir/opt/sink.cc.o
CMakeFiles/caffe2.dir/perfkernels/adagrad.cc.o
CMakeFiles/caffe2.dir/perfkernels/embedding_lookup.cc.o
CMakeFiles/caffe2.dir/perfkernels/fused_8bit_rowwise_embedding_lookup.cc.o
CMakeFiles/caffe2.dir/perfkernels/math_cpu_base.cc.o
CMakeFiles/caffe2.dir/perfkernels/typed_axpy.cc.o
CMakeFiles/caffe2.dir/queue/blobs_queue.cc.o
CMakeFiles/caffe2.dir/queue/blobs_queue_db.cc.o
CMakeFiles/caffe2.dir/queue/queue_ops.cc.o
CMakeFiles/caffe2.dir/queue/rebatching_queue.cc.o
CMakeFiles/caffe2.dir/queue/rebatching_queue_ops.cc.o
CMakeFiles/caffe2.dir/sgd/adadelta_op.cc.o
CMakeFiles/caffe2.dir/sgd/adagrad_op.cc.o
CMakeFiles/caffe2.dir/sgd/adam_op.cc.o
CMakeFiles/caffe2.dir/sgd/clip_tensor_op.cc.o
CMakeFiles/caffe2.dir/sgd/ftrl_op.cc.o
CMakeFiles/caffe2.dir/sgd/gftrl_op.cc.o
CMakeFiles/caffe2.dir/sgd/iter_op.cc.o
CMakeFiles/caffe2.dir/sgd/lars_op.cc.o
CMakeFiles/caffe2.dir/sgd/learning_rate_adaption_op.cc.o
CMakeFiles/caffe2.dir/sgd/learning_rate_op.cc.o
CMakeFiles/caffe2.dir/sgd/momentum_sgd_op.cc.o
CMakeFiles/caffe2.dir/sgd/rmsprop_op.cc.o
CMakeFiles/caffe2.dir/sgd/wngrad_op.cc.o
CMakeFiles/caffe2.dir/sgd/yellowfin_op.cc.o
CMakeFiles/caffe2.dir/share/contrib/nnpack/conv_op.cc.o
CMakeFiles/caffe2.dir/share/contrib/depthwise/depthwise3x3_conv_op.cc.o
CMakeFiles/caffe2.dir/transforms/common_subexpression_elimination.cc.o
CMakeFiles/caffe2.dir/transforms/conv_to_nnpack_transform.cc.o
CMakeFiles/caffe2.dir/transforms/pattern_net_transform.cc.o
CMakeFiles/caffe2.dir/transforms/single_op_transform.cc.o

即使从链接的.o文件的数量来看,你也知道libcaffe2.a是最主要的那个库。在安卓编译上,这个库包含了312个operators、ATen实现的tensor、caffe2框架的初始化、网络的初始化及前向等逻辑。

编译生成Android上的libcaffe2_detectron_ops.so

源文件编译成.o文件使用的参数就不介绍了,同上;然后多个.o合并并且链接前述的一些.a库,然后生成libcaffe2_detectron_ops.so库:

/home/gemfield/android-ndk-r16b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ \
--target=armv7-none-linux-androideabi --gcc-toolchain=/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 --sysroot=/home/gemfield/android-ndk-r16b/sysroot -fPIC -isystem /home/gemfield/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=21 -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security -frtti -fexceptions  -Wno-deprecated -fvisibility-inlines-hidden -O2 -fPIC -Wno-narrowing -Wall -Wextra -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -Wno-invalid-partial-specialization -Wno-typedef-redefinition -Wno-unknown-warning-option -Wno-unused-private-field -Wno-inconsistent-missing-override -Wno-aligned-allocation-unavailable -Wno-c++14-extensions -Wno-constexpr-not-const -Wno-missing-braces -Qunused-arguments -Wno-unused-but-set-variable -Wno-maybe-uninitialized -Os -DNDEBUG  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot /home/gemfield/android-ndk-r16b/platforms/android-21/arch-arm -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now  -rdynamic -shared \
-Wl,-soname,libcaffe2_detectron_ops.so \
-o ../../lib/libcaffe2_detectron_ops.so \
CMakeFiles/caffe2_detectron_ops.dir/batch_permutation_op.cc.o \
CMakeFiles/caffe2_detectron_ops.dir/group_spatial_softmax_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/ps_roi_pool_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/roi_pool_f_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/sample_as_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/select_smooth_l1_loss_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/sigmoid_cross_entropy_loss_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/sigmoid_focal_loss_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/smooth_l1_loss_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/softmax_focal_loss_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/spatial_narrow_as_op.cc.o
CMakeFiles/caffe2_detectron_ops.dir/upsample_nearest_op.cc.o
../../lib/libcaffe2.a
-Wl,--whole-archive,/home/gemfield/pytorch/build_android/lib/libcaffe2_protos.a
-Wl,--no-whole-archive
../../lib/libc10.a
../../lib/libqnnpack.a
../../lib/libnnpack.a
../../lib/libcpuinfo.a
../../lib/libclog.a
-llog
../../lib/libonnxifi_loader.a
-ldl
../../lib/libprotobuf.a
-Wl,--whole-archive,/home/gemfield/pytorch/build_android/lib/libonnx_proto.a
-Wl,--no-whole-archive
-latomic
-lm "/home/gemfield/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a"

3,编译生成Android上的可执行程序

下面就开始交叉编译C++源文件来生成可执行程序了,整个PyTorch项目总共会编译出11个可执行程序,这些程序都是一些小的工具、demo等:

bin/tutorial_blob
bin/predictor_verifier
bin/convert_db
bin/print_registered_core_operators
bin/run_plan
bin/make_mnist_db
bin/speed_benchmark
bin/make_cifar_db
bin/split_db
bin/convert_caffe_image_db
bin/db_throughput

以其中的speed_benchmark为例

首先,源文件http://speed_benchmark.cc编译成speed_benchmark.cc.o:

home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
--sysroot=/home/gemfield/android-ndk-r16b/sysroot
-DCPUINFO_SUPPORTED_PLATFORM=1
-DNNP_CONVOLUTION_ONLY=0
-DNNP_INFERENCE_ONLY=0
-DONNX_NAMESPACE=onnx_c2
-I/home/gemfield/pytorch/aten/src
-I/home/gemfield/pytorch/build_android
-I/home/gemfield/pytorch
-I/home/gemfield/pytorch/third_party/protobuf/src
-I/home/gemfield/pytorch/third_party/onnx
-I/home/gemfield/pytorch/build_android/third_party/onnx
-I/home/gemfield/pytorch/c10/..
-I/home/gemfield/pytorch/third_party/QNNPACK/include
-I/home/gemfield/pytorch/third_party/pthreadpool/include
-I/home/gemfield/pytorch/third_party/NNPACK/include
-I/home/gemfield/pytorch/third_party/cpuinfo/include
-I/home/gemfield/pytorch/third_party/FP16/include
-isystem /home/gemfield/pytorch/third_party/gemmlowp
-isystem /home/gemfield/pytorch/third_party/neon2sse
-isystem /home/gemfield/pytorch/cmake/../third_party/eigen
-isystem /home/gemfield/pytorch/cmake/../third_party/pybind11/include
-isystem /opt/rocm/hip/include
-isystem /include
-isystem /home/gemfield/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/include
-isystem /home/gemfield/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include
-isystem /home/gemfield/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/include/backward
-isystem /home/gemfield/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi
-D__ANDROID_API__=21
-DANDROID
-O2
-fPIC
......
-std=c++11
-std=gnu++11
-o CMakeFiles/speed_benchmark.dir/speed_benchmark.cc.o
-c /home/gemfield/pytorch/binaries/speed_benchmark.cc

其次,speed_benchmark.cc.o链接之前编译的.a库,以及NDK里的系统库,最终编译为可执行程序speed_benchmark:

/home/gemfield/android-ndk-r16b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++
--target=armv7-none-linux-androideabi
--gcc-toolchain=/home/gemfield/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
--sysroot=/home/gemfield/android-ndk-r16b/sysroot
-isystem /home/gemfield/android-ndk-r16b/sysroot/usr/include/arm-linux-androideabi
-D__ANDROID_API__=21
-DANDROID
-ffunction-sections
-funwind-tables
-fstack-protector-strong
-no-canonical-prefixes
-march=armv7-a
-mfloat-abi=softfp
-mfpu=vfpv3-d16
-fno-integrated-as
-mthumb
-mfpu=neon
-Wa,--noexecstack
-Wformat
-Werror=format-security
-frtti
-fexceptions
-Wno-deprecated
-fvisibility-inlines-hidden
-O2
-fPIC
......
-Os
-DNDEBUG
-Wl,--exclude-libs,libgcc.a
-Wl,--exclude-libs,libatomic.a
--sysroot /home/gemfield/android-ndk-r16b/platforms/android-21/arch-arm
-pie
-fPIE
-rdynamic
-s CMakeFiles/speed_benchmark.dir/speed_benchmark.cc.o
-o ../bin/speed_benchmark
-Wl,--whole-archive,/home/gemfield/pytorch/build_android/lib/libcaffe2.a
-Wl,--no-whole-archive
-Wl,--whole-archive,/home/gemfield/pytorch/build_android/lib/libcaffe2_protos.a
-Wl,--no-whole-archive
../lib/libc10.a
../lib/libqnnpack.a
../lib/libnnpack.a
../lib/libcpuinfo.a
../lib/libclog.a
-llog
../lib/libonnxifi_loader.a
-ldl
../lib/libprotobuf.a
-Wl,--whole-archive,/home/gemfield/pytorch/build_android/lib/libonnx_proto.a
-Wl,--no-whole-archive
-latomic
-lm
"/home/gemfield/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a"

4,收集头文件和库文件

编译完成后,在merge gemfield的PR之前,你需要手工在build_android目录下执行make install命令,所需头文件和库会被拷贝到$PYTORCH_ROOT/install 目录下;如果merge了gemfield的PR,则按照脚本提示即可。

然后你可以拷贝头文件和库文件到android studio项目的目录下使用。比如,对于类似AICamera的项目,你可以将头文件拷贝到AICamera/app/src/main/cpp目录下,库文件拷贝到AICamera/app/src/main/jni/armeabi-v7a即可。

5,错误处理

1,有时候,你在Android Studio上编译项目会遇到下面的错误:

Build command failed.
Error while executing process C:\Users\lenovo\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build C:\Users\lenovo\Desktop\pytorch-android-master\app\.externalNativeBuild\cmake\debug\armeabi-v7a --target native-lib}
[1/1] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\armeabi-v7a\libnative-lib.so
FAILED: cmd.exe /C "cd . && C:\Users\lenovo\AppData\Local\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=armv7-none-linux-androideabi --gcc-toolchain=C:/Users/lenovo/AppData/Local/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/lenovo/AppData/Local/Android/Sdk/ndk-bundle/sysroot -fPIC -isystem C:/Users/lenovo/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=22 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -frtti -fexceptions -std=c++11 -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot C:/Users/lenovo/AppData/Local/Android/Sdk/ndk-bundle/platforms/android-22/arch-arm -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--fix-cortex-a8 -Wl,--exclude-libs,libunwind.a -LC:/Users/lenovo/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\armeabi-v7a\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o  -Wl,--whole-archive ../../../../src/main/jniLibs/armeabi-v7a/libcaffe2.a -Wl,--no-whole-archive ../../../../src/main/jniLibs/armeabi-v7a/libnnpack.a ../../../../src/main/jniLibs/armeabi-v7a/libqnnpack.a ../../../../src/main/jniLibs/armeabi-v7a/libcaffe2_protos.a ../../../../src/main/jniLibs/armeabi-v7a/libonnx_proto.a ../../../../src/main/jniLibs/armeabi-v7a/libonnx.a ../../../../src/main/jniLibs/armeabi-v7a/libonnxifi_loader.a ../../../../src/main/jniLibs/armeabi-v7a/libc10.a ../../../../src/main/jniLibs/armeabi-v7a/libprotobuf.a libcpufeatures.a ../../../../src/main/jniLibs/armeabi-v7a/libpthreadpool.a ../../../../src/main/jniLibs/armeabi-v7a/libcpuinfo.a ../../../../src/main/jniLibs/armeabi-v7a/libclog.a -llog -landroid -ldl -latomic -lm "C:/Users/lenovo/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++.so" && cd ."
../../../../src/main/jniLibs/armeabi-v7a/libcaffe2.a(Formatting.cpp.o):/home/gemfield/pytorch/aten/src/ATen/core/Formatting.cpp:function c10::operator<<(std::ostream&, c10::Backend): error: undefined reference to 'std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int)'
../../../../src/main/jniLibs/armeabi-v7a/libcaffe2.a(Formatting.cpp.o):/home/gemfield/pytorch/aten/src/ATen/core/Formatting.cpp:function at::operator<<(std::ostream&, at::Type const&): error: undefined reference to 'std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int)'
../../../../src/main/jniLibs/armeabi-v7a/libcaffe2.a(Formatting.cpp.o):/home/gemfield/pytorch/aten/src/ATen/core/Formatting.cpp:function at::operator<<(std::ostream&, at::Type const&): error: undefined reference to 'std::basic_ios<char, std::char_traits<char> >::clear(std::_Ios_Iostate)'

这是因为AS项目中配置的NDK libc++链接库和在PyTorch编译时使用的NDK libc++链接库不同导致的,这个时候只需要在AS的配置文件(比如CMakeList.txt)里指定正确的即可:

externalNativeBuild {     cmake {         cppFlags "-frtti -fexceptions -std=c++11"         //arguments "-DANDROID_STL=c++_shared"         arguments "-DANDROID_STL=gnustl_static"     } }

2, 有時候使用NDK r16编译的libcaffe2.a为100M左右,但是使用NDK r18编译的libcaffe2.a却有2GB之多,这是因为r18默认启用了-g debug选项,你可以在编译的时候使用-DCMAKE_CXX_FLAGS_RELEASE=-g0 来disable掉debug:

bash scripts/build_android.sh -DANDROID_ABI=arm64-v8a -DANDROID_TOOLCHAIN=clang -DBUILD_BINARY=ON -DCMAKE_CXX_FLAGS=-O3 -DCMAKE_CXX_FLAGS_RELEASE=-g0

这样编译出来的libcaffe2.a就只有150M左右。

总结

可见,在PyTorch的Android编译上,PyTorch主要编译了protobuf、ATen、C10、Caffe2、QNNPACK,这和服务端的编译还是截然不同的。

    原文作者:Gemfield
    原文地址: https://zhuanlan.zhihu.com/p/57144943
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞