diff --git a/CMakeLists.txt b/CMakeLists.txt index 43aea26f59802c4e58cecaf2313288ba2d1f307b..89473e9f329a0a37dd3ed24f20e13d00513fca1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,8 +40,6 @@ else() list(REMOVE_ITEM PADDLE_MOBILE_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/operators/kernel/mali/*.h) list(REMOVE_ITEM PADDLE_MOBILE_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/operators/kernel/mali/*.cc) list(REMOVE_ITEM PADDLE_MOBILE_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/operators/kernel/mali/*.cpp) - - endif() if(FPGA) @@ -103,6 +101,10 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY build) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY build) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build) +# NET default +set(NET "defult" CACHE STRING "select net type") +set_property(CACHE NET PROPERTY STRINGS "defult" "googlenet" "mobilenet" "yolo" "squeezenet") + include("${CMAKE_CURRENT_LIST_DIR}/tools/op.cmake") # if (IS_IOS) @@ -118,4 +120,3 @@ if(DEBUGING) add_subdirectory(test) endif() - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a25d65e02afb09dabc96e1ec241346cff34f6f2..f07b2eeb93daa827361acc97951483c21092135f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -183,6 +183,10 @@ upstream 接下来等待 review,如果有需要修改的地方,参照上述步骤更新 origin 中的对应分支即可。 + +![](http://otkwwi4x8.bkt.clouddn.com/2018-06-20-15294877166787.jpg) +之后就可以提交代码了 + ## 删除远程分支 在 PR 被 merge 进主仓库后,我们可以在 PR 的页面删除远程仓库的分支。 @@ -219,7 +223,8 @@ upstream - 原因:如果仅仅修改一个文件但提交了十几个commit,每个commit只做了少量的修改,这会给评审人带来很大困扰。评审人需要逐一查看每个commit才能知道做了哪些修改,且不排除commit之间的修改存在相互覆盖的情况。 - 建议:每次提交时,保持尽量少的commit,可以通过`git commit --amend`补充上次的commit。对已经Push到远程仓库的多个commit,可以参考[squash commits after push](http://stackoverflow.com/questions/5667884/how-to-squash-commits-in-git-after-they-have-been-pushed)。 - 请注意每个commit的名称:应能反映当前commit的内容,不能太随意。 -3. 如果解决了某个Issue的问题,请在该Pull Request的**第一个**评论框中加上:`fix #issue_number`,这样当该PUll Request被合并后,会自动关闭对应的Issue。关键词包括:close, closes, closed, fix, fixes, fixed, resolve, resolves, resolved,请选择合适的词汇。详细可参考[Closing issues via commit messages](https://help.github.com/articles/closing-issues-via-commit-messages)。 + +3. 如果解决了某个Issue的问题,请在该Pull Request的**第一个**评论框中加上:`fix #issue_number`,这样当该Pull Request被合并后,会自动关闭对应的Issue。关键词包括:close, closes, closed, fix, fixes, fixed, resolve, resolves, resolved,请选择合适的词汇。详细可参考[Closing issues via commit messages](https://help.github.com/articles/closing-issues-via-commit-messages)。 此外,在回复评审人意见时,请您遵守以下约定: diff --git a/README.md b/README.md index b6ae2beed999d146c64ffc9ee495373d9b77a175..f8957545a64fff7723bd4c1c6bc2db1fd90d728b 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,104 @@ -# Paddle-Mobile - +# Paddle-Mobile [![Build Status](https://travis-ci.org/PaddlePaddle/paddle-mobile.svg?branch=develop&longCache=true&style=flat-square)](https://travis-ci.org/PaddlePaddle/paddle-mobile) -[![License](https://img.shields.io/badge/license-Apache%202-brightgreen.svg)](LICENSE) +[![Documentation Status](https://img.shields.io/badge/中文文档-最新-brightgreen.svg)](https://github.com/PaddlePaddle/paddle-mobile/tree/develop/doc) +[![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](LICENSE) + -This project is used to develop the next version deep learning freamwork for mobile device. -# Development -[Used model in development](https://mms-mis.cdn.bcebos.com/paddle-mobile/models.zip) +欢迎来到 Paddle-Mobile GitHub 项目。 -## cross-compilation to android +Paddle-Moible是PaddlePaddle组织下的项目,是一个致力于嵌入式平台的深度学习的框架。Paddle-Moible设计思想和PaddlePaddle的最新版fluid版本保持了高度一致,同时针对嵌入式做了大量优化。设计之初就对嵌入式的性能、体积、能耗、硬件平台覆盖等方面做了考虑。 -* NDK is required -* ANDROID_NDK environment variable is required +## Features -```bash -sh build.sh android -``` +- **ARM CPU** -## build for x86 -paddle-mobile is to run on arm platform. x86 only used to test not arm assembly code. So do not recommend compiling x86. + arm cpu是paddle-mobile的主要支持方向,cpu的通用性一直是其优势。嵌入式深度学习,需要大量的cpu汇编实现。我们正在紧锣密鼓的编码,为的是能充分硬件的每一点加速能力。 + arm cpu的优化工作还在进行中,现在使用了常规的cpu优化。在arm a73上paddle-mobile现在单核运行一次mobilenet 1.0是160+ms,显然这不是我们的最终目标,我们正在用大量的汇编改写,后续性能仍会有巨大提升空间。 + +- **Mali GPU** -Now only support osx. + Mali GPU是百度和ARM合作开发的,双方团队近期都在致力于将paddle的op能无缝运行在ACL(arm compute library)。目前已经支持squeezenet,googlenet,resnet等几个网络模型,后续会继续加大力度。使全部移动端paddle op能高效运行在mali gpu上。 + 在 +- **苹果设备的GPU Metal实现** + + 基于Metal实现的苹果设备的GPU预测库,也已经在实现中,近期也会有相应可运行版本。 + +- **FPGA** + + FPGA实现正在进行中,是基于Xilinx的ZU5目标开发板。 + +- **灵活性** + + * paddle-mobile cpu版不依赖任何第三库, 可进行快速集成。 + * 使用泛型特化进行平台切换, 可灵活切换 cpu、gpu 和其他协处理器。 + * 可根据特定的常见网络, 进行编译特定的 op, 降低编译时间, 减小包大小。 + * 使用 docker 编译, 提供统一的编译环境。 + * 高可拓展性, 方便拓展其他协处理器, 提供高性能 arm 算子实现, 方便其他协处理器开发者集成开发。 + * 直接兼容 paddle-fluid 模型, 不需要额外的转换操作。 + +- **体积** + + paddle-mobile从设计之初就深入考虑到移动端的包体积的问题,cpu实现中没有外部依赖。在编译过程中,如果该网络不需要的op是完全不会被打入的。同时编译选项优化也为体积压缩提供了帮助。 + 除了二进制体积,我们对代码体积极力避免过大。整个仓库不到5m的代码体积。 + + +## 文档 + +### 设计文档 + +关于paddle-mobile设计文档在下面链接中,如果想了解更多内容。[issue](https://github.com/PaddlePaddle/paddle-mobile/issues)中会有很多早期的设计和讨论过程。 +[设计文档链接](https://github.com/PaddlePaddle/paddle-mobile/blob/develop/doc/design_doc.md) + +### 开发文档 + +开发文档主要是关于编译、运行等问题。做为开发者,它可以和贡献文档共同结合使用。 +[开发文档]()https://github.com/PaddlePaddle/paddle-mobile/blob/develop/doc/development_doc.md + +### 贡献文档 +- [贡献文档链接](https://github.com/PaddlePaddle/paddle-mobile/blob/develop/CONTRIBUTING.md) +- 上面文档中涵盖了主要的贡献代码流程,如果在实践中您还遇到了其他问题,可以发[issue](https://github.com/PaddlePaddle/paddle-mobile/issues)。我们看到后会尽快处理。 + + +## 模型获得 +目前Paddle-Mobile仅支持Paddle fluid训练的模型。如果你手中的模型是不同种类的模型,需要进行模型转换才可以运行。 +### 1. 直接使用Paddle Fluid训练 +该方式最为可靠,推荐方式 +### 2. caffe转为Paddle Fluid模型 +[链接](https://github.com/PaddlePaddle/models/tree/develop/fluid/image_classification/caffe2fluid) +### 3. ONNX +ONNX全称为“Open Neural Network Exchange”,即“开放的神经网络切换”。该项目的目的是让不同的神经网络开发框架做到互通互用。 + +除直接使用PaddlePaddle训练fluid版本的模型外,还可以通过onnx转换得到个别Paddle fluid模型。 + +目前,百度也在做onnx支持工作。相关转换项目在这里:[paddle-onnx](https://github.com/PaddlePaddle/paddle-onnx)。 + +```flow +st=>start: 其他模型 +op1=>operation: onnx模型 +op2=>operation: paddle-onnx +op3=>operation: paddle fluid模型 +e=>end: paddle-mobile运行 +st->op1->op2->op3->e ``` -sh build.sh mac -``` -## Old Version of Mobile-Deep-Learning -The old version of MDL was I moved to here [Mobile-Deep-Learning](https://github.com/allonli/mobile-deep-learning) +### 4. 部分测试模型下载 +[下载链接](https://mms-mis.cdn.bcebos.com/paddle-mobile/models.zip) + +## 问题解决 + +欢迎提出或解决我们的问题,有疑问可以发issue. [Github Issues](https://github.com/PaddlePaddle/paddle-mobile/issues). + +## Copyright and License +Paddle-Mobile 提供相对宽松的Apache-2.0开源协议 [Apache-2.0 license](LICENSE). + +## 旧版 Mobile-Deep-Learning +原MDL(Mobile-Deep-Learning)工程被迁移到了这里 [Mobile-Deep-Learning](https://github.com/allonli/mobile-deep-learning) diff --git a/doc/design_doc.md b/doc/design_doc.md new file mode 100644 index 0000000000000000000000000000000000000000..3407c78443de0f0c7d9ebab848122c2e089e9e41 --- /dev/null +++ b/doc/design_doc.md @@ -0,0 +1,183 @@ +# paddle-mobile 设计文档 + + +#### 以下是 paddle-mobile 代码的执行流程图: + + +![执行流程图](http://otkwwi4x8.bkt.clouddn.com/2018-07-02-15305189473720.png) + + +#### 主要分为: Loader 模块、 Program 模块、 Executor 模块、 op 模块、 kernel 模块、scope variable Tensor 模块 + +#### 下面展开说一下各个模块的作用以及设计思路 + +### 一. Loader +先来看一下模型, 模型分为两种结构: + 一种为参数文件是散开的, 如下图, 红框为模型结构的 protobuf 文件, 其余为参数文件 + + +![模型描述](http://otkwwi4x8.bkt.clouddn.com/2018-07-02-15305190629577.png) + + +另一种为参数文件结合在一起的, 如下图, 红框内为模型结构描述的 protobuf 文件, 另一个文件为结合在一起的参数文件 + +![模型描述combined](http://otkwwi4x8.bkt.clouddn.com/2018-07-02-15305191057130.png) + +loader 模块的作用是将模型结构信息 load 进内存, 将红框内的 protobuf 文件 load 进内存, 并对模型结构进行优化(如将几个细粒度的 op 融合成 粗粒度的 op, 如将 conv、 add、 batchnorm、 relu 融合为 conv\_add\_batchnorm\_relu). +方便进行算法优化. + +__那么为什么融合在一起能够做算法优化 ?__ + +如果未融合的 conv add batchnorm relu 运算是这样的 + +``` +[n] +[conv_res] = conv([n]) + +for &res in conv_res { + res = add_biase(res) +} + +for &res in conv_res { + res = batchnorm(res) +} + +for &res in conv_res { + res = relu(res) +} + +``` +融合后的 conv\_add\_batchnorm\_relu 运算是这样的: + +``` +[n] +[conv_res] = conv([n]) + +for &res in conv_res { + res = relu(batchnorm(add_biase(res))) +} + +``` +由于 conv 可以转换为两个大矩阵相乘, 更进一步可以分为若干个一行一列的小矩阵相乘, 那最终的运算是这样的: + +``` +[n] +for &res in [res] { + res = relu(batchnorm(add_biase(A * B))) +} + +其中 A 和 B 为 1 * k 和 k * 1 矩阵 + +``` + + + +### 二. Program + +program 为 loader 模块的结果, 包含了优化前的模型结构对象, 以及优化后的模型结构对象, 此模块基本对应着 paddle 模型的结构, 关于paddle 模型的一些概念的定义, 详细设计可以参考 [program.md](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/fluid/design/concepts/program.md), 以下是一个简单的概况: + +* programDesc 中包含着若干个(googlenet mobilenet yolo squeezenet resnet 常见的模型只有一个)可以嵌套的 block, blocks中的第一个block中的某个 op 可能会执行 blocks 中后边 block 中的一系列 op 运算(只有多个block才会有此概念) +* block 包含着 ops 和 vars +* ops 为一系列 op 的描述, 描述着每个 op 的类型, 输入输出, 所需参数 +* vars 里包含的为所有 op 运算所需的参数描述 + +### 三. Executor + +executor 主要是用于 op 运算的上层调度操作, 主要有两个操作, executor 实例化 和 暴露给上层的 predict 方法 + +* executor 实例化过程中, 主要进行了这几个操作 + 1. 根据 loader 产出的 program 初始化 operator 对象 + 2. 分配所有需要用到的内存, 包括每个op 的输入输出, 权重参数, 目前模型的权重参数文件的内存格式为 NCHW, op 的输入输出中间矩阵参数也是 NCHW 格式 + 3. 调用每个 op 的 init 方法, init 方法是每个 op 实现者进行参数预处理的地方, 有助于减少 predict 的耗时 + +* predict, 主要用于拿到外部的输入, 顺序调用 op 的 run 方法进行运算, 并返回最终的结果. + + +### 四. op +关于 op 模块代码的详细设计可以参考 [operator部分代码设计](https://github.com/PaddlePaddle/paddle-mobile/issues/300), operator主要包含一个kernel用于运算、一个 param 用于存储属性, operator 主要有三个操作, Init、RunImp、InferShape + +* Init: Init 函数主要用于参数预处理, 如对 batchNorm 参数进行预处理, 可以将 batchNorm 运算转化为 a * x + b 形式的运算, 这个函数也会调用, kernel 的 Init 函数对 kernel 进行初始化 +* RunImp: RunImp 函数会调用自己的kernel 的 compute 方法进行运算 +* InferShape: InferShape 函数会根据输入和参数得出输出的形状, 这个函数会在 executor 实例化时, 内存初始化前调用 + +每个 operator 都需要进行注册才可以被使用, 以 conv 为例, 需在 conv_op.cpp 底部这样写: + +```c++ +// 三个平台都注册了 conv op +namespace ops = paddle_mobile::operators; +#ifdef PADDLE_MOBILE_CPU +USE_OP_CPU(conv2d); +REGISTER_OPERATOR_CPU(conv2d, ops::ConvOp); +#endif + +#ifdef PADDLE_MOBILE_MALI_GPU +USE_OP_MALI_GPU(conv2d); +REGISTER_OPERATOR_MALI_GPU(conv2d, ops::ConvOp); +#endif + +#ifdef PADDLE_MOBILE_FPGA +USE_OP_FPGA(conv2d); +REGISTER_OPERATOR_FPGA(conv2d, ops::ConvOp); +#endif + +``` + +__一个关于包大小的优化__: + +每个 operator 都由一个宏控制编译, 如 conv_op.h(除了 conv_op.h , conv_op.cpp、conv_kernle.h、conv_kernle.cpp 也都需要加此宏控制) + +```c++ + +#ifdef CONV_OP //这个宏控制着 conv_op 是否被编译, 除了 conv_op.h , conv_op.cpp、conv_kernle.h conv_kernle.cpp 也都需要加此宏控制 + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/conv_kernel.h" + +namespace paddle_mobile { +namespace operators { +using std::string; +template +class ConvOp + //impl +}; + +} // namespace operators +} // namespace paddle_mobile + +#endif + +``` +这样做的目的是为了根据不同类型的网络编译特定的op, 在 cmake 中已经配置好不同网络编译的宏, 如果你要进行编译支持 yolo 的模型, 仅需执行: + +```sh +cd toools +sh build.sh android yolo + +``` +这样只会编译 yolo 所包含的四种 op, 极大的减小了包体积和编译时间 + +### 五. kernel +kernel 为 op 的底层运算实现, 主要有两个函数, Init 和 Compute, 分别用来初始化、预处理 和 运算操作, 值得提出的是, kernel 会根据泛型特化到不同的平台, 如图所示: + +![设备特化]![](http://otkwwi4x8.bkt.clouddn.com/2018-07-02-15305191401976.png) + +不同平台的 kernel 实现, 为同一个 kernel 类不同泛型的特化实现, 目前有三个平台, arm、mali、fpga, 图中的 central-arm-func\ 目录为 op kernel 的 arm 实现, 它承担了 arm\ 目录下 kernel 的底层实现, 同时 arm 处理器作为中央处理器, central-arm-func\ 也可以作为其他协处理器的底层实现, 如: fpga 的某一个 op kernel 还没有 fpga 协处理器的实现, 就可以直接调用使用这里的 arm 实现. + +__如果你有兴趣新增一个协处理器实现, 就可以在次添加一个 kernel 目录, 提供协处理器实现, 如果某个 kernel 你没有实现完, 你也可以直接使用 arm 实现__ + +### 六. scope variable Tensor +* scope 用来存储管理所需用到的所有 variable(用来存储不同类型的对象, 主要是矩阵Tensor, 也就是说 scpoe 管理着 op 运算过程中所有参数矩阵, 输入输出矩阵), 可以将 scope 理解为一个 map, 这里在 map 上封了一层 scope 的概念是为了方便内存管理 +* variable 可以用来存储不同类型的对象, paddle-mobile 里主要用它来存储矩阵 Tensor +* tensor 代表着矩阵, 通过泛型可以用来存储不同类型的矩阵, 但需要注意的是, 存入和取出时的类型必须保持一致, 如果类型不一致, 使用 inline const T \*data() const 获取指针会不能通过类型检查, 通过 inline T \*mutable_data() 获取指针会重新分配内存, 以下是关于 Tensor 的一些小概念: + 1. DDim: 用来存储矩阵的维度信息. + 2. Slice(): 这个函数用来获取 N 维 (NCHW中的 N) 上切片 + 3. 当实例化未分配内存时, 调用 inline T *mutable_data() 会分配内存 + + + + + + diff --git a/doc/development_doc.md b/doc/development_doc.md new file mode 100644 index 0000000000000000000000000000000000000000..5673e043bda80e414d7e841928283764bd2b310e --- /dev/null +++ b/doc/development_doc.md @@ -0,0 +1,85 @@ +# iOS开发文档 + +## 编译 + +### 一. 使用 build.sh 编译 + +```sh +sh build.sh ios + +# 如果只想编译某个特定模型的 op, 则需执行以下命令 +sh build.sh ios googlenet + +# 在这个文件夹下, 你可以拿到生成的 .a 库 +cd ../build/release/ios/build + +``` + +### 二. 使用 xcode 编译 + +我们提供了 ios 开发更为熟悉的 xcode 编译环境: +在 ios/ 目录下打开 PaddleMobile.xcworkspace 即可编译 PaddleMobile 或者 运行 Demo + +### 三. 集成 + +#### 如使用 c++ 接口 +将 + +``` +libpaddle-mobile.a +io.h +program.h +types.h +lod_tensor.h +tensor.h +``` +拖入工程, io.h 为接口文件, 可在 [github](https://github.com/PaddlePaddle/paddle-mobile/blob/develop/src/io/io.h)上查看接口注释 + +#### 如使用 oc 接口 +将在xcode 编译生成的 +``` +libPaddleMobile.a +PaddleMobile.h +``` +拖入工程, 接口如下: + +``` +/* + 创建单例对象 +*/ ++ (instancetype)sharedInstance; + +/* + load 模型, 开辟内存 +*/ +- (BOOL)load:(NSString *)modelPath andWeightsPath:(NSString *)weighsPath; + +/* + 进行预测, means 和 scale 为训练模型时的预处理参数, 如训练时没有做这些预处理则直接使用 predict +*/ +- (NSArray *)predict:(CGImageRef)image means:(NSArray *)means scale:(float)scale; + +/* + 进行预测 +*/ +- (NSArray *)predict:(CGImageRef)image; + +/* + 清理内存 +*/ +- (void)clear; + +``` + + + + + + + + + + + + + diff --git a/doc/images/devices.png b/doc/images/devices.png new file mode 100644 index 0000000000000000000000000000000000000000..413d32c249972ee96f678d50a5cd0b36a2a03e29 Binary files /dev/null and b/doc/images/devices.png differ diff --git a/doc/images/flow_chart.png b/doc/images/flow_chart.png new file mode 100644 index 0000000000000000000000000000000000000000..c747230da43e2e688d7460704268631758d34596 Binary files /dev/null and b/doc/images/flow_chart.png differ diff --git a/doc/images/model_desc.png b/doc/images/model_desc.png new file mode 100644 index 0000000000000000000000000000000000000000..3c026b6192c8e1d84b3a82c3db91e022f35358c2 Binary files /dev/null and b/doc/images/model_desc.png differ diff --git a/doc/images/model_desc_combined.png b/doc/images/model_desc_combined.png new file mode 100644 index 0000000000000000000000000000000000000000..38e7388efcfdcad53f4e80ce0ac5d3b993eb986c Binary files /dev/null and b/doc/images/model_desc_combined.png differ diff --git a/ios/PaddleMobile.xcworkspace/contents.xcworkspacedata b/ios/PaddleMobile.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000000000000000000000000000000..7c3243eefa5fdeaa40b8697bd8e0b5ba2daeeb55 --- /dev/null +++ b/ios/PaddleMobile.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/PaddleMobile.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/PaddleMobile.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000000000000000000000000000000..18d981003d68d0546c4804ac2ff47dd97c6e7921 --- /dev/null +++ b/ios/PaddleMobile.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/PaddleMobile.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate b/ios/PaddleMobile.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..ff9a9abc7211d4c390fca9535743ee452515390e Binary files /dev/null and b/ios/PaddleMobile.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ios/PaddleMobile.xcworkspace/xcuserdata/liuruilong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/ios/PaddleMobile.xcworkspace/xcuserdata/liuruilong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000000000000000000000000000000000000..ed9a9b4d42c454d27017c91c04ce8b8a518ac029 --- /dev/null +++ b/ios/PaddleMobile.xcworkspace/xcuserdata/liuruilong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/ios/PaddleMobile/PaddleMobile.xcodeproj/project.pbxproj b/ios/PaddleMobile/PaddleMobile.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..7907ac8955996b25f9173a6114bccad3b1e1bed9 --- /dev/null +++ b/ios/PaddleMobile/PaddleMobile.xcodeproj/project.pbxproj @@ -0,0 +1,965 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + FC086BB420E7839B00D85EF7 /* PaddleMobile.m in Sources */ = {isa = PBXBuildFile; fileRef = FC086BB320E7839B00D85EF7 /* PaddleMobile.m */; }; + FC086BB520E7839B00D85EF7 /* PaddleMobile.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FC086BB220E7839B00D85EF7 /* PaddleMobile.h */; }; + FC086DC620E7841E00D85EF7 /* t_malloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086CFE20E7841E00D85EF7 /* t_malloc.cpp */; }; + FC086DC720E7841E00D85EF7 /* lrn_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0320E7841E00D85EF7 /* lrn_op.cpp */; }; + FC086DC820E7841E00D85EF7 /* sigmoid_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0520E7841E00D85EF7 /* sigmoid_op.cpp */; }; + FC086DC920E7841E00D85EF7 /* box_coder_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0620E7841E00D85EF7 /* box_coder_op.cpp */; }; + FC086DCA20E7841E00D85EF7 /* feed_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0720E7841E00D85EF7 /* feed_op.cpp */; }; + FC086DCB20E7841E00D85EF7 /* fusion_conv_add_bn_relu_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0A20E7841E00D85EF7 /* fusion_conv_add_bn_relu_op.cpp */; }; + FC086DCC20E7841E00D85EF7 /* reshape_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0B20E7841E00D85EF7 /* reshape_op.cpp */; }; + FC086DCD20E7841E00D85EF7 /* concat_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0C20E7841E00D85EF7 /* concat_op.cpp */; }; + FC086DCE20E7841E00D85EF7 /* transpose_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0D20E7841E00D85EF7 /* transpose_op.cpp */; }; + FC086DCF20E7841E00D85EF7 /* prior_box_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0E20E7841E00D85EF7 /* prior_box_op.cpp */; }; + FC086DD020E7841E00D85EF7 /* fusion_conv_add_relu_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D0F20E7841E00D85EF7 /* fusion_conv_add_relu_op.cpp */; }; + FC086DD120E7841E00D85EF7 /* softmax_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D1520E7841E00D85EF7 /* softmax_op.cpp */; }; + FC086DD220E7841E00D85EF7 /* depthwise_conv_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D1720E7841E00D85EF7 /* depthwise_conv_op.cpp */; }; + FC086DD320E7841E00D85EF7 /* elementwise_add_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D1A20E7841E00D85EF7 /* elementwise_add_op.cpp */; }; + FC086DD420E7841E00D85EF7 /* gemm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D1F20E7841E00D85EF7 /* gemm.cpp */; }; + FC086DD520E7841E00D85EF7 /* pool_2x2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D2220E7841E00D85EF7 /* pool_2x2.cpp */; }; + FC086DD620E7841E00D85EF7 /* im2col.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D2320E7841E00D85EF7 /* im2col.cpp */; }; + FC086DD720E7841E00D85EF7 /* vol2col.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D2620E7841E00D85EF7 /* vol2col.cpp */; }; + FC086DD820E7841E00D85EF7 /* math_function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D2720E7841E00D85EF7 /* math_function.cpp */; }; + FC086DD920E7841E00D85EF7 /* pool_3x3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D2820E7841E00D85EF7 /* pool_3x3.cpp */; }; + FC086DDA20E7841E00D85EF7 /* pooling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D2B20E7841E00D85EF7 /* pooling.cpp */; }; + FC086DDB20E7841E00D85EF7 /* depthwise_conv_3x3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D2D20E7841E00D85EF7 /* depthwise_conv_3x3.cpp */; }; + FC086DDC20E7841E00D85EF7 /* softmax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D2F20E7841E00D85EF7 /* softmax.cpp */; }; + FC086DDD20E7841E00D85EF7 /* fetch_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D3420E7841E00D85EF7 /* fetch_op.cpp */; }; + FC086DDE20E7841E00D85EF7 /* fusion_conv_add.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D3520E7841E00D85EF7 /* fusion_conv_add.cpp */; }; + FC086DDF20E7841E00D85EF7 /* op_param.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D3620E7841E00D85EF7 /* op_param.cpp */; }; + FC086DE020E7841E00D85EF7 /* mul_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D3A20E7841E00D85EF7 /* mul_op.cpp */; }; + FC086DE120E7841E00D85EF7 /* relu_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D3B20E7841E00D85EF7 /* relu_op.cpp */; }; + FC086DE220E7841E00D85EF7 /* conv_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D3C20E7841E00D85EF7 /* conv_op.cpp */; }; + FC086DE320E7841E00D85EF7 /* fusion_fc_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D3D20E7841E00D85EF7 /* fusion_fc_op.cpp */; }; + FC086DE420E7841E00D85EF7 /* batchnorm_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D4020E7841E00D85EF7 /* batchnorm_op.cpp */; }; + FC086DE520E7841E00D85EF7 /* pool_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D4220E7841E00D85EF7 /* pool_op.cpp */; }; + FC086DE620E7841E00D85EF7 /* multiclass_nms_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D4420E7841E00D85EF7 /* multiclass_nms_op.cpp */; }; + FC086DE720E7841E00D85EF7 /* acl_tensor.cc in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5220E7841E00D85EF7 /* acl_tensor.cc */; }; + FC086DE820E7841E00D85EF7 /* acl_operator.cc in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5320E7841E00D85EF7 /* acl_operator.cc */; }; + FC086DE920E7841E00D85EF7 /* conv_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5420E7841E00D85EF7 /* conv_kernel.cpp */; }; + FC086DEA20E7841E00D85EF7 /* conv_add_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5620E7841E00D85EF7 /* conv_add_kernel.cpp */; }; + FC086DEB20E7841E00D85EF7 /* relu_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5820E7841E00D85EF7 /* relu_kernel.cpp */; }; + FC086DEC20E7841E00D85EF7 /* mul_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5920E7841E00D85EF7 /* mul_kernel.cpp */; }; + FC086DED20E7841E00D85EF7 /* elementwise_add_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5A20E7841E00D85EF7 /* elementwise_add_kernel.cpp */; }; + FC086DEE20E7841E00D85EF7 /* softmax_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5C20E7841E00D85EF7 /* softmax_kernel.cpp */; }; + FC086DEF20E7841E00D85EF7 /* concat_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5D20E7841E00D85EF7 /* concat_kernel.cpp */; }; + FC086DF020E7841E00D85EF7 /* pool_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5E20E7841E00D85EF7 /* pool_kernel.cpp */; }; + FC086DF120E7841E00D85EF7 /* reshape_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D5F20E7841E00D85EF7 /* reshape_kernel.cpp */; }; + FC086DF220E7841E00D85EF7 /* lrn_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D6020E7841E00D85EF7 /* lrn_kernel.cpp */; }; + FC086DF320E7841E00D85EF7 /* fushion_fc_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D6120E7841E00D85EF7 /* fushion_fc_kernel.cpp */; }; + FC086DF420E7841E00D85EF7 /* batchnorm_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D6220E7841E00D85EF7 /* batchnorm_kernel.cpp */; }; + FC086DF520E7841E00D85EF7 /* conv_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D6F20E7841E00D85EF7 /* conv_kernel.cpp */; }; + FC086DF620E7841E00D85EF7 /* prior_box_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7420E7841E00D85EF7 /* prior_box_kernel.cpp */; }; + FC086DF720E7841E00D85EF7 /* conv_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7520E7841E00D85EF7 /* conv_kernel.cpp */; }; + FC086DF820E7841E00D85EF7 /* conv_add_bn_relu_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7620E7841E00D85EF7 /* conv_add_bn_relu_kernel.cpp */; }; + FC086DF920E7841E00D85EF7 /* box_coder_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7720E7841E00D85EF7 /* box_coder_kernel.cpp */; }; + FC086DFA20E7841E00D85EF7 /* conv_add_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7820E7841E00D85EF7 /* conv_add_kernel.cpp */; }; + FC086DFB20E7841E00D85EF7 /* sigmoid_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7920E7841E00D85EF7 /* sigmoid_kernel.cpp */; }; + FC086DFC20E7841E00D85EF7 /* relu_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7A20E7841E00D85EF7 /* relu_kernel.cpp */; }; + FC086DFD20E7841E00D85EF7 /* mul_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7B20E7841E00D85EF7 /* mul_kernel.cpp */; }; + FC086DFE20E7841E00D85EF7 /* elementwise_add_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7C20E7841E00D85EF7 /* elementwise_add_kernel.cpp */; }; + FC086DFF20E7841E00D85EF7 /* conv_add_relu_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7D20E7841E00D85EF7 /* conv_add_relu_kernel.cpp */; }; + FC086E0020E7841E00D85EF7 /* transpose_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7E20E7841E00D85EF7 /* transpose_kernel.cpp */; }; + FC086E0120E7841E00D85EF7 /* depthwise_conv_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D7F20E7841E00D85EF7 /* depthwise_conv_kernel.cpp */; }; + FC086E0220E7841E00D85EF7 /* softmax_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8020E7841E00D85EF7 /* softmax_kernel.cpp */; }; + FC086E0320E7841E00D85EF7 /* concat_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8120E7841E00D85EF7 /* concat_kernel.cpp */; }; + FC086E0420E7841E00D85EF7 /* fusion_fc_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8220E7841E00D85EF7 /* fusion_fc_kernel.cpp */; }; + FC086E0520E7841E00D85EF7 /* pool_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8320E7841E00D85EF7 /* pool_kernel.cpp */; }; + FC086E0620E7841E00D85EF7 /* reshape_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8420E7841E00D85EF7 /* reshape_kernel.cpp */; }; + FC086E0720E7841E00D85EF7 /* lrn_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8520E7841E00D85EF7 /* lrn_kernel.cpp */; }; + FC086E0820E7841E00D85EF7 /* batchnorm_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8620E7841E00D85EF7 /* batchnorm_kernel.cpp */; }; + FC086E0920E7841E00D85EF7 /* multiclass_nms_kernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8720E7841E00D85EF7 /* multiclass_nms_kernel.cpp */; }; + FC086E0A20E7841E00D85EF7 /* framework.pb-c.c in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8B20E7841E00D85EF7 /* framework.pb-c.c */; }; + FC086E0B20E7841E00D85EF7 /* tensor_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8C20E7841E00D85EF7 /* tensor_util.cpp */; }; + FC086E0C20E7841E00D85EF7 /* operator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D8F20E7841E00D85EF7 /* operator.cpp */; }; + FC086E0D20E7841E00D85EF7 /* ddim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D9020E7841E00D85EF7 /* ddim.cpp */; }; + FC086E0E20E7841E00D85EF7 /* scope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D9320E7841E00D85EF7 /* scope.cpp */; }; + FC086E0F20E7841E00D85EF7 /* attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D9920E7841E00D85EF7 /* attribute.cpp */; }; + FC086E1020E7841E00D85EF7 /* op_desc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D9C20E7841E00D85EF7 /* op_desc.cpp */; }; + FC086E1120E7841E00D85EF7 /* program_desc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086D9D20E7841E00D85EF7 /* program_desc.cpp */; }; + FC086E1220E7841E00D85EF7 /* node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086DA320E7841E00D85EF7 /* node.cpp */; }; + FC086E1320E7841E00D85EF7 /* program_optimize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086DA620E7841E00D85EF7 /* program_optimize.cpp */; }; + FC086E1420E7841E00D85EF7 /* block_desc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086DA720E7841E00D85EF7 /* block_desc.cpp */; }; + FC086E1520E7841E00D85EF7 /* lod_tensor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086DAB20E7841E00D85EF7 /* lod_tensor.cpp */; }; + FC086E1620E7841E00D85EF7 /* io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086DB320E7841E00D85EF7 /* io.cpp */; }; + FC086E1720E7841E00D85EF7 /* types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086DB620E7841E00D85EF7 /* types.cpp */; }; + FC086E1820E7841E00D85EF7 /* openmp-fix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086DBA20E7841E00D85EF7 /* openmp-fix.cpp */; }; + FC086E1920E7841E00D85EF7 /* protobuf-c.c in Sources */ = {isa = PBXBuildFile; fileRef = FC086DC120E7841E00D85EF7 /* protobuf-c.c */; }; + FC086E1A20E7841E00D85EF7 /* paddle_mobile_jni.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FC086DC420E7841E00D85EF7 /* paddle_mobile_jni.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + FC086BAD20E7839B00D85EF7 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + FC086BB520E7839B00D85EF7 /* PaddleMobile.h in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + FC086BAF20E7839B00D85EF7 /* libPaddleMobile.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPaddleMobile.a; sourceTree = BUILT_PRODUCTS_DIR; }; + FC086BB220E7839B00D85EF7 /* PaddleMobile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PaddleMobile.h; sourceTree = ""; }; + FC086BB320E7839B00D85EF7 /* PaddleMobile.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PaddleMobile.m; sourceTree = ""; }; + FC086CFE20E7841E00D85EF7 /* t_malloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = t_malloc.cpp; sourceTree = ""; }; + FC086CFF20E7841E00D85EF7 /* t_malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = t_malloc.h; sourceTree = ""; }; + FC086D0120E7841E00D85EF7 /* feed_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = feed_op.h; sourceTree = ""; }; + FC086D0220E7841E00D85EF7 /* fusion_conv_add_bn_relu_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fusion_conv_add_bn_relu_op.h; sourceTree = ""; }; + FC086D0320E7841E00D85EF7 /* lrn_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lrn_op.cpp; sourceTree = ""; }; + FC086D0420E7841E00D85EF7 /* op_param.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = op_param.h; sourceTree = ""; }; + FC086D0520E7841E00D85EF7 /* sigmoid_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sigmoid_op.cpp; sourceTree = ""; }; + FC086D0620E7841E00D85EF7 /* box_coder_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = box_coder_op.cpp; sourceTree = ""; }; + FC086D0720E7841E00D85EF7 /* feed_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = feed_op.cpp; sourceTree = ""; }; + FC086D0820E7841E00D85EF7 /* mul_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mul_op.h; sourceTree = ""; }; + FC086D0920E7841E00D85EF7 /* prior_box_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prior_box_op.h; sourceTree = ""; }; + FC086D0A20E7841E00D85EF7 /* fusion_conv_add_bn_relu_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fusion_conv_add_bn_relu_op.cpp; sourceTree = ""; }; + FC086D0B20E7841E00D85EF7 /* reshape_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reshape_op.cpp; sourceTree = ""; }; + FC086D0C20E7841E00D85EF7 /* concat_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = concat_op.cpp; sourceTree = ""; }; + FC086D0D20E7841E00D85EF7 /* transpose_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transpose_op.cpp; sourceTree = ""; }; + FC086D0E20E7841E00D85EF7 /* prior_box_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prior_box_op.cpp; sourceTree = ""; }; + FC086D0F20E7841E00D85EF7 /* fusion_conv_add_relu_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fusion_conv_add_relu_op.cpp; sourceTree = ""; }; + FC086D1020E7841E00D85EF7 /* lrn_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lrn_op.h; sourceTree = ""; }; + FC086D1120E7841E00D85EF7 /* multiclass_nms_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multiclass_nms_op.h; sourceTree = ""; }; + FC086D1220E7841E00D85EF7 /* relu_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = relu_op.h; sourceTree = ""; }; + FC086D1320E7841E00D85EF7 /* fusion_conv_add.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fusion_conv_add.h; sourceTree = ""; }; + FC086D1420E7841E00D85EF7 /* conv_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_op.h; sourceTree = ""; }; + FC086D1520E7841E00D85EF7 /* softmax_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = softmax_op.cpp; sourceTree = ""; }; + FC086D1620E7841E00D85EF7 /* pool_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pool_op.h; sourceTree = ""; }; + FC086D1720E7841E00D85EF7 /* depthwise_conv_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = depthwise_conv_op.cpp; sourceTree = ""; }; + FC086D1820E7841E00D85EF7 /* softmax_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = softmax_op.h; sourceTree = ""; }; + FC086D1920E7841E00D85EF7 /* elementwise_add_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = elementwise_add_op.h; sourceTree = ""; }; + FC086D1A20E7841E00D85EF7 /* elementwise_add_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = elementwise_add_op.cpp; sourceTree = ""; }; + FC086D1B20E7841E00D85EF7 /* fetch_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fetch_op.h; sourceTree = ""; }; + FC086D1D20E7841E00D85EF7 /* elementwise_op_function.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = elementwise_op_function.h; sourceTree = ""; }; + FC086D1E20E7841E00D85EF7 /* softmax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = softmax.h; sourceTree = ""; }; + FC086D1F20E7841E00D85EF7 /* gemm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gemm.cpp; sourceTree = ""; }; + FC086D2020E7841E00D85EF7 /* math_function.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_function.h; sourceTree = ""; }; + FC086D2120E7841E00D85EF7 /* conv_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_func.h; sourceTree = ""; }; + FC086D2220E7841E00D85EF7 /* pool_2x2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pool_2x2.cpp; sourceTree = ""; }; + FC086D2320E7841E00D85EF7 /* im2col.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = im2col.cpp; sourceTree = ""; }; + FC086D2420E7841E00D85EF7 /* gemm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gemm.h; sourceTree = ""; }; + FC086D2520E7841E00D85EF7 /* im2col.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = im2col.h; sourceTree = ""; }; + FC086D2620E7841E00D85EF7 /* vol2col.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vol2col.cpp; sourceTree = ""; }; + FC086D2720E7841E00D85EF7 /* math_function.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math_function.cpp; sourceTree = ""; }; + FC086D2820E7841E00D85EF7 /* pool_3x3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pool_3x3.cpp; sourceTree = ""; }; + FC086D2920E7841E00D85EF7 /* pool_2x2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pool_2x2.h; sourceTree = ""; }; + FC086D2A20E7841E00D85EF7 /* depthwise_conv_3x3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = depthwise_conv_3x3.h; sourceTree = ""; }; + FC086D2B20E7841E00D85EF7 /* pooling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pooling.cpp; sourceTree = ""; }; + FC086D2C20E7841E00D85EF7 /* pool_3x3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pool_3x3.h; sourceTree = ""; }; + FC086D2D20E7841E00D85EF7 /* depthwise_conv_3x3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = depthwise_conv_3x3.cpp; sourceTree = ""; }; + FC086D2E20E7841E00D85EF7 /* vol2col.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vol2col.h; sourceTree = ""; }; + FC086D2F20E7841E00D85EF7 /* softmax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = softmax.cpp; sourceTree = ""; }; + FC086D3020E7841E00D85EF7 /* transform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transform.h; sourceTree = ""; }; + FC086D3120E7841E00D85EF7 /* pooling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pooling.h; sourceTree = ""; }; + FC086D3220E7841E00D85EF7 /* math_func_neon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_func_neon.h; sourceTree = ""; }; + FC086D3320E7841E00D85EF7 /* fusion_conv_add_relu_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fusion_conv_add_relu_op.h; sourceTree = ""; }; + FC086D3420E7841E00D85EF7 /* fetch_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fetch_op.cpp; sourceTree = ""; }; + FC086D3520E7841E00D85EF7 /* fusion_conv_add.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fusion_conv_add.cpp; sourceTree = ""; }; + FC086D3620E7841E00D85EF7 /* op_param.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = op_param.cpp; sourceTree = ""; }; + FC086D3720E7841E00D85EF7 /* transpose_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transpose_op.h; sourceTree = ""; }; + FC086D3820E7841E00D85EF7 /* fusion_fc_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fusion_fc_op.h; sourceTree = ""; }; + FC086D3920E7841E00D85EF7 /* batchnorm_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = batchnorm_op.h; sourceTree = ""; }; + FC086D3A20E7841E00D85EF7 /* mul_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mul_op.cpp; sourceTree = ""; }; + FC086D3B20E7841E00D85EF7 /* relu_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = relu_op.cpp; sourceTree = ""; }; + FC086D3C20E7841E00D85EF7 /* conv_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conv_op.cpp; sourceTree = ""; }; + FC086D3D20E7841E00D85EF7 /* fusion_fc_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fusion_fc_op.cpp; sourceTree = ""; }; + FC086D3E20E7841E00D85EF7 /* box_coder_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = box_coder_op.h; sourceTree = ""; }; + FC086D3F20E7841E00D85EF7 /* concat_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = concat_op.h; sourceTree = ""; }; + FC086D4020E7841E00D85EF7 /* batchnorm_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = batchnorm_op.cpp; sourceTree = ""; }; + FC086D4120E7841E00D85EF7 /* reshape_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reshape_op.h; sourceTree = ""; }; + FC086D4220E7841E00D85EF7 /* pool_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pool_op.cpp; sourceTree = ""; }; + FC086D4320E7841E00D85EF7 /* sigmoid_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sigmoid_op.h; sourceTree = ""; }; + FC086D4420E7841E00D85EF7 /* multiclass_nms_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multiclass_nms_op.cpp; sourceTree = ""; }; + FC086D4620E7841E00D85EF7 /* relu_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = relu_kernel.h; sourceTree = ""; }; + FC086D4720E7841E00D85EF7 /* multiclass_nms_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multiclass_nms_kernel.h; sourceTree = ""; }; + FC086D4820E7841E00D85EF7 /* depthwise_conv_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = depthwise_conv_kernel.h; sourceTree = ""; }; + FC086D4920E7841E00D85EF7 /* lrn_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lrn_kernel.h; sourceTree = ""; }; + FC086D4A20E7841E00D85EF7 /* pool_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pool_kernel.h; sourceTree = ""; }; + FC086D4B20E7841E00D85EF7 /* fusion_fc_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fusion_fc_kernel.h; sourceTree = ""; }; + FC086D4C20E7841E00D85EF7 /* box_coder_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = box_coder_kernel.h; sourceTree = ""; }; + FC086D4D20E7841E00D85EF7 /* concat_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = concat_kernel.h; sourceTree = ""; }; + FC086D4E20E7841E00D85EF7 /* mul_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mul_kernel.h; sourceTree = ""; }; + FC086D4F20E7841E00D85EF7 /* softmax_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = softmax_kernel.h; sourceTree = ""; }; + FC086D5020E7841E00D85EF7 /* batchnorm_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = batchnorm_kernel.h; sourceTree = ""; }; + FC086D5220E7841E00D85EF7 /* acl_tensor.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = acl_tensor.cc; sourceTree = ""; }; + FC086D5320E7841E00D85EF7 /* acl_operator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = acl_operator.cc; sourceTree = ""; }; + FC086D5420E7841E00D85EF7 /* conv_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conv_kernel.cpp; sourceTree = ""; }; + FC086D5520E7841E00D85EF7 /* acl_operator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = acl_operator.h; sourceTree = ""; }; + FC086D5620E7841E00D85EF7 /* conv_add_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conv_add_kernel.cpp; sourceTree = ""; }; + FC086D5720E7841E00D85EF7 /* acl_tensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = acl_tensor.h; sourceTree = ""; }; + FC086D5820E7841E00D85EF7 /* relu_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = relu_kernel.cpp; sourceTree = ""; }; + FC086D5920E7841E00D85EF7 /* mul_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mul_kernel.cpp; sourceTree = ""; }; + FC086D5A20E7841E00D85EF7 /* elementwise_add_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = elementwise_add_kernel.cpp; sourceTree = ""; }; + FC086D5C20E7841E00D85EF7 /* softmax_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = softmax_kernel.cpp; sourceTree = ""; }; + FC086D5D20E7841E00D85EF7 /* concat_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = concat_kernel.cpp; sourceTree = ""; }; + FC086D5E20E7841E00D85EF7 /* pool_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pool_kernel.cpp; sourceTree = ""; }; + FC086D5F20E7841E00D85EF7 /* reshape_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reshape_kernel.cpp; sourceTree = ""; }; + FC086D6020E7841E00D85EF7 /* lrn_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lrn_kernel.cpp; sourceTree = ""; }; + FC086D6120E7841E00D85EF7 /* fushion_fc_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fushion_fc_kernel.cpp; sourceTree = ""; }; + FC086D6220E7841E00D85EF7 /* batchnorm_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = batchnorm_kernel.cpp; sourceTree = ""; }; + FC086D6320E7841E00D85EF7 /* elementwise_add_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = elementwise_add_kernel.h; sourceTree = ""; }; + FC086D6520E7841E00D85EF7 /* conv_arm_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_arm_func.h; sourceTree = ""; }; + FC086D6620E7841E00D85EF7 /* conv_add_bn_relu_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_add_bn_relu_func.h; sourceTree = ""; }; + FC086D6720E7841E00D85EF7 /* conv_add_relu_arm_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_add_relu_arm_func.h; sourceTree = ""; }; + FC086D6820E7841E00D85EF7 /* depthwise_conv_arm_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = depthwise_conv_arm_func.h; sourceTree = ""; }; + FC086D6920E7841E00D85EF7 /* batchnorm_arm_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = batchnorm_arm_func.h; sourceTree = ""; }; + FC086D6A20E7841E00D85EF7 /* conv_add_relu_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_add_relu_kernel.h; sourceTree = ""; }; + FC086D6B20E7841E00D85EF7 /* reshape_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reshape_kernel.h; sourceTree = ""; }; + FC086D6C20E7841E00D85EF7 /* transpose_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transpose_kernel.h; sourceTree = ""; }; + FC086D6D20E7841E00D85EF7 /* conv_add_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_add_kernel.h; sourceTree = ""; }; + FC086D6F20E7841E00D85EF7 /* conv_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conv_kernel.cpp; sourceTree = ""; }; + FC086D7020E7841E00D85EF7 /* conv_add_bn_relu_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_add_bn_relu_kernel.h; sourceTree = ""; }; + FC086D7120E7841E00D85EF7 /* prior_box_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prior_box_kernel.h; sourceTree = ""; }; + FC086D7220E7841E00D85EF7 /* conv_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conv_kernel.h; sourceTree = ""; }; + FC086D7420E7841E00D85EF7 /* prior_box_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prior_box_kernel.cpp; sourceTree = ""; }; + FC086D7520E7841E00D85EF7 /* conv_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conv_kernel.cpp; sourceTree = ""; }; + FC086D7620E7841E00D85EF7 /* conv_add_bn_relu_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conv_add_bn_relu_kernel.cpp; sourceTree = ""; }; + FC086D7720E7841E00D85EF7 /* box_coder_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = box_coder_kernel.cpp; sourceTree = ""; }; + FC086D7820E7841E00D85EF7 /* conv_add_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conv_add_kernel.cpp; sourceTree = ""; }; + FC086D7920E7841E00D85EF7 /* sigmoid_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sigmoid_kernel.cpp; sourceTree = ""; }; + FC086D7A20E7841E00D85EF7 /* relu_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = relu_kernel.cpp; sourceTree = ""; }; + FC086D7B20E7841E00D85EF7 /* mul_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mul_kernel.cpp; sourceTree = ""; }; + FC086D7C20E7841E00D85EF7 /* elementwise_add_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = elementwise_add_kernel.cpp; sourceTree = ""; }; + FC086D7D20E7841E00D85EF7 /* conv_add_relu_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conv_add_relu_kernel.cpp; sourceTree = ""; }; + FC086D7E20E7841E00D85EF7 /* transpose_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transpose_kernel.cpp; sourceTree = ""; }; + FC086D7F20E7841E00D85EF7 /* depthwise_conv_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = depthwise_conv_kernel.cpp; sourceTree = ""; }; + FC086D8020E7841E00D85EF7 /* softmax_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = softmax_kernel.cpp; sourceTree = ""; }; + FC086D8120E7841E00D85EF7 /* concat_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = concat_kernel.cpp; sourceTree = ""; }; + FC086D8220E7841E00D85EF7 /* fusion_fc_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fusion_fc_kernel.cpp; sourceTree = ""; }; + FC086D8320E7841E00D85EF7 /* pool_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pool_kernel.cpp; sourceTree = ""; }; + FC086D8420E7841E00D85EF7 /* reshape_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reshape_kernel.cpp; sourceTree = ""; }; + FC086D8520E7841E00D85EF7 /* lrn_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lrn_kernel.cpp; sourceTree = ""; }; + FC086D8620E7841E00D85EF7 /* batchnorm_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = batchnorm_kernel.cpp; sourceTree = ""; }; + FC086D8720E7841E00D85EF7 /* multiclass_nms_kernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multiclass_nms_kernel.cpp; sourceTree = ""; }; + FC086D8820E7841E00D85EF7 /* sigmoid_kernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sigmoid_kernel.h; sourceTree = ""; }; + FC086D8920E7841E00D85EF7 /* depthwise_conv_op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = depthwise_conv_op.h; sourceTree = ""; }; + FC086D8B20E7841E00D85EF7 /* framework.pb-c.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "framework.pb-c.c"; sourceTree = ""; }; + FC086D8C20E7841E00D85EF7 /* tensor_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tensor_util.cpp; sourceTree = ""; }; + FC086D8D20E7841E00D85EF7 /* operator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = operator.h; sourceTree = ""; }; + FC086D8E20E7841E00D85EF7 /* op_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = op_info.h; sourceTree = ""; }; + FC086D8F20E7841E00D85EF7 /* operator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = operator.cpp; sourceTree = ""; }; + FC086D9020E7841E00D85EF7 /* ddim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddim.cpp; sourceTree = ""; }; + FC086D9120E7841E00D85EF7 /* tensor_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tensor_util.h; sourceTree = ""; }; + FC086D9220E7841E00D85EF7 /* variable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = variable.h; sourceTree = ""; }; + FC086D9320E7841E00D85EF7 /* scope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scope.cpp; sourceTree = ""; }; + FC086D9420E7841E00D85EF7 /* data_layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = data_layout.h; sourceTree = ""; }; + FC086D9520E7841E00D85EF7 /* lod_tensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lod_tensor.h; sourceTree = ""; }; + FC086D9620E7841E00D85EF7 /* dim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dim.h; sourceTree = ""; }; + FC086D9720E7841E00D85EF7 /* framework.pb-c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "framework.pb-c.h"; sourceTree = ""; }; + FC086D9820E7841E00D85EF7 /* op_kernel_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = op_kernel_type.h; sourceTree = ""; }; + FC086D9920E7841E00D85EF7 /* attribute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = attribute.cpp; sourceTree = ""; }; + FC086D9A20E7841E00D85EF7 /* op_proto_maker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = op_proto_maker.h; sourceTree = ""; }; + FC086D9C20E7841E00D85EF7 /* op_desc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = op_desc.cpp; sourceTree = ""; }; + FC086D9D20E7841E00D85EF7 /* program_desc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = program_desc.cpp; sourceTree = ""; }; + FC086D9E20E7841E00D85EF7 /* var_desc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = var_desc.h; sourceTree = ""; }; + FC086D9F20E7841E00D85EF7 /* program_desc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = program_desc.h; sourceTree = ""; }; + FC086DA020E7841E00D85EF7 /* op_desc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = op_desc.h; sourceTree = ""; }; + FC086DA220E7841E00D85EF7 /* fusion_op_register.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fusion_op_register.h; sourceTree = ""; }; + FC086DA320E7841E00D85EF7 /* node.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node.cpp; sourceTree = ""; }; + FC086DA420E7841E00D85EF7 /* node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = node.h; sourceTree = ""; }; + FC086DA520E7841E00D85EF7 /* program_optimize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = program_optimize.h; sourceTree = ""; }; + FC086DA620E7841E00D85EF7 /* program_optimize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = program_optimize.cpp; sourceTree = ""; }; + FC086DA720E7841E00D85EF7 /* block_desc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = block_desc.cpp; sourceTree = ""; }; + FC086DA820E7841E00D85EF7 /* program.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = program.h; sourceTree = ""; }; + FC086DA920E7841E00D85EF7 /* tensor_desc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tensor_desc.h; sourceTree = ""; }; + FC086DAA20E7841E00D85EF7 /* block_desc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = block_desc.h; sourceTree = ""; }; + FC086DAB20E7841E00D85EF7 /* lod_tensor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lod_tensor.cpp; sourceTree = ""; }; + FC086DAC20E7841E00D85EF7 /* framework.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = framework.proto; sourceTree = ""; }; + FC086DAD20E7841E00D85EF7 /* ddim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddim.h; sourceTree = ""; }; + FC086DAE20E7841E00D85EF7 /* attribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attribute.h; sourceTree = ""; }; + FC086DAF20E7841E00D85EF7 /* scope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scope.h; sourceTree = ""; }; + FC086DB020E7841E00D85EF7 /* tensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tensor.h; sourceTree = ""; }; + FC086DB120E7841E00D85EF7 /* op_registry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = op_registry.h; sourceTree = ""; }; + FC086DB320E7841E00D85EF7 /* io.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = io.cpp; sourceTree = ""; }; + FC086DB420E7841E00D85EF7 /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = ""; }; + FC086DB620E7841E00D85EF7 /* types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = types.cpp; sourceTree = ""; }; + FC086DB720E7841E00D85EF7 /* threadpool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threadpool.h; sourceTree = ""; }; + FC086DB820E7841E00D85EF7 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; + FC086DB920E7841E00D85EF7 /* protobuf-c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "protobuf-c.h"; sourceTree = ""; }; + FC086DBA20E7841E00D85EF7 /* openmp-fix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "openmp-fix.cpp"; sourceTree = ""; }; + FC086DBB20E7841E00D85EF7 /* dep_core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dep_core.h; sourceTree = ""; }; + FC086DBC20E7841E00D85EF7 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = ""; }; + FC086DBD20E7841E00D85EF7 /* log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = log.h; sourceTree = ""; }; + FC086DBE20E7841E00D85EF7 /* macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macros.h; sourceTree = ""; }; + FC086DBF20E7841E00D85EF7 /* type_define.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = type_define.h; sourceTree = ""; }; + FC086DC020E7841E00D85EF7 /* enforce.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = enforce.h; sourceTree = ""; }; + FC086DC120E7841E00D85EF7 /* protobuf-c.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "protobuf-c.c"; sourceTree = ""; }; + FC086DC220E7841E00D85EF7 /* variant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = variant.h; sourceTree = ""; }; + FC086DC420E7841E00D85EF7 /* paddle_mobile_jni.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paddle_mobile_jni.cpp; sourceTree = ""; }; + FC086DC520E7841E00D85EF7 /* paddle_mobile_jni.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = paddle_mobile_jni.h; sourceTree = ""; }; + FC2428A520E78DF20095932F /* MacroDefine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MacroDefine.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FC086BAC20E7839B00D85EF7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + FC086BA620E7839B00D85EF7 = { + isa = PBXGroup; + children = ( + FC086BB120E7839B00D85EF7 /* PaddleMobile */, + FC086BB020E7839B00D85EF7 /* Products */, + ); + sourceTree = ""; + }; + FC086BB020E7839B00D85EF7 /* Products */ = { + isa = PBXGroup; + children = ( + FC086BAF20E7839B00D85EF7 /* libPaddleMobile.a */, + ); + name = Products; + sourceTree = ""; + }; + FC086BB120E7839B00D85EF7 /* PaddleMobile */ = { + isa = PBXGroup; + children = ( + FC086CFC20E7841E00D85EF7 /* src */, + FC086BB220E7839B00D85EF7 /* PaddleMobile.h */, + FC086BB320E7839B00D85EF7 /* PaddleMobile.m */, + FC2428A520E78DF20095932F /* MacroDefine.h */, + ); + path = PaddleMobile; + sourceTree = ""; + }; + FC086CFC20E7841E00D85EF7 /* src */ = { + isa = PBXGroup; + children = ( + FC086CFD20E7841E00D85EF7 /* memory */, + FC086D0020E7841E00D85EF7 /* operators */, + FC086D8A20E7841E00D85EF7 /* framework */, + FC086DB220E7841E00D85EF7 /* io */, + FC086DB520E7841E00D85EF7 /* common */, + FC086DC320E7841E00D85EF7 /* jni */, + ); + name = src; + path = ../../../src; + sourceTree = ""; + }; + FC086CFD20E7841E00D85EF7 /* memory */ = { + isa = PBXGroup; + children = ( + FC086CFE20E7841E00D85EF7 /* t_malloc.cpp */, + FC086CFF20E7841E00D85EF7 /* t_malloc.h */, + ); + path = memory; + sourceTree = ""; + }; + FC086D0020E7841E00D85EF7 /* operators */ = { + isa = PBXGroup; + children = ( + FC086D0120E7841E00D85EF7 /* feed_op.h */, + FC086D0220E7841E00D85EF7 /* fusion_conv_add_bn_relu_op.h */, + FC086D0320E7841E00D85EF7 /* lrn_op.cpp */, + FC086D0420E7841E00D85EF7 /* op_param.h */, + FC086D0520E7841E00D85EF7 /* sigmoid_op.cpp */, + FC086D0620E7841E00D85EF7 /* box_coder_op.cpp */, + FC086D0720E7841E00D85EF7 /* feed_op.cpp */, + FC086D0820E7841E00D85EF7 /* mul_op.h */, + FC086D0920E7841E00D85EF7 /* prior_box_op.h */, + FC086D0A20E7841E00D85EF7 /* fusion_conv_add_bn_relu_op.cpp */, + FC086D0B20E7841E00D85EF7 /* reshape_op.cpp */, + FC086D0C20E7841E00D85EF7 /* concat_op.cpp */, + FC086D0D20E7841E00D85EF7 /* transpose_op.cpp */, + FC086D0E20E7841E00D85EF7 /* prior_box_op.cpp */, + FC086D0F20E7841E00D85EF7 /* fusion_conv_add_relu_op.cpp */, + FC086D1020E7841E00D85EF7 /* lrn_op.h */, + FC086D1120E7841E00D85EF7 /* multiclass_nms_op.h */, + FC086D1220E7841E00D85EF7 /* relu_op.h */, + FC086D1320E7841E00D85EF7 /* fusion_conv_add.h */, + FC086D1420E7841E00D85EF7 /* conv_op.h */, + FC086D1520E7841E00D85EF7 /* softmax_op.cpp */, + FC086D1620E7841E00D85EF7 /* pool_op.h */, + FC086D1720E7841E00D85EF7 /* depthwise_conv_op.cpp */, + FC086D1820E7841E00D85EF7 /* softmax_op.h */, + FC086D1920E7841E00D85EF7 /* elementwise_add_op.h */, + FC086D1A20E7841E00D85EF7 /* elementwise_add_op.cpp */, + FC086D1B20E7841E00D85EF7 /* fetch_op.h */, + FC086D1C20E7841E00D85EF7 /* math */, + FC086D3320E7841E00D85EF7 /* fusion_conv_add_relu_op.h */, + FC086D3420E7841E00D85EF7 /* fetch_op.cpp */, + FC086D3520E7841E00D85EF7 /* fusion_conv_add.cpp */, + FC086D3620E7841E00D85EF7 /* op_param.cpp */, + FC086D3720E7841E00D85EF7 /* transpose_op.h */, + FC086D3820E7841E00D85EF7 /* fusion_fc_op.h */, + FC086D3920E7841E00D85EF7 /* batchnorm_op.h */, + FC086D3A20E7841E00D85EF7 /* mul_op.cpp */, + FC086D3B20E7841E00D85EF7 /* relu_op.cpp */, + FC086D3C20E7841E00D85EF7 /* conv_op.cpp */, + FC086D3D20E7841E00D85EF7 /* fusion_fc_op.cpp */, + FC086D3E20E7841E00D85EF7 /* box_coder_op.h */, + FC086D3F20E7841E00D85EF7 /* concat_op.h */, + FC086D4020E7841E00D85EF7 /* batchnorm_op.cpp */, + FC086D4120E7841E00D85EF7 /* reshape_op.h */, + FC086D4220E7841E00D85EF7 /* pool_op.cpp */, + FC086D4320E7841E00D85EF7 /* sigmoid_op.h */, + FC086D4420E7841E00D85EF7 /* multiclass_nms_op.cpp */, + FC086D4520E7841E00D85EF7 /* kernel */, + FC086D8920E7841E00D85EF7 /* depthwise_conv_op.h */, + ); + path = operators; + sourceTree = ""; + }; + FC086D1C20E7841E00D85EF7 /* math */ = { + isa = PBXGroup; + children = ( + FC086D1D20E7841E00D85EF7 /* elementwise_op_function.h */, + FC086D1E20E7841E00D85EF7 /* softmax.h */, + FC086D1F20E7841E00D85EF7 /* gemm.cpp */, + FC086D2020E7841E00D85EF7 /* math_function.h */, + FC086D2120E7841E00D85EF7 /* conv_func.h */, + FC086D2220E7841E00D85EF7 /* pool_2x2.cpp */, + FC086D2320E7841E00D85EF7 /* im2col.cpp */, + FC086D2420E7841E00D85EF7 /* gemm.h */, + FC086D2520E7841E00D85EF7 /* im2col.h */, + FC086D2620E7841E00D85EF7 /* vol2col.cpp */, + FC086D2720E7841E00D85EF7 /* math_function.cpp */, + FC086D2820E7841E00D85EF7 /* pool_3x3.cpp */, + FC086D2920E7841E00D85EF7 /* pool_2x2.h */, + FC086D2A20E7841E00D85EF7 /* depthwise_conv_3x3.h */, + FC086D2B20E7841E00D85EF7 /* pooling.cpp */, + FC086D2C20E7841E00D85EF7 /* pool_3x3.h */, + FC086D2D20E7841E00D85EF7 /* depthwise_conv_3x3.cpp */, + FC086D2E20E7841E00D85EF7 /* vol2col.h */, + FC086D2F20E7841E00D85EF7 /* softmax.cpp */, + FC086D3020E7841E00D85EF7 /* transform.h */, + FC086D3120E7841E00D85EF7 /* pooling.h */, + FC086D3220E7841E00D85EF7 /* math_func_neon.h */, + ); + path = math; + sourceTree = ""; + }; + FC086D4520E7841E00D85EF7 /* kernel */ = { + isa = PBXGroup; + children = ( + FC086D4620E7841E00D85EF7 /* relu_kernel.h */, + FC086D4720E7841E00D85EF7 /* multiclass_nms_kernel.h */, + FC086D4820E7841E00D85EF7 /* depthwise_conv_kernel.h */, + FC086D4920E7841E00D85EF7 /* lrn_kernel.h */, + FC086D4A20E7841E00D85EF7 /* pool_kernel.h */, + FC086D4B20E7841E00D85EF7 /* fusion_fc_kernel.h */, + FC086D4C20E7841E00D85EF7 /* box_coder_kernel.h */, + FC086D4D20E7841E00D85EF7 /* concat_kernel.h */, + FC086D4E20E7841E00D85EF7 /* mul_kernel.h */, + FC086D4F20E7841E00D85EF7 /* softmax_kernel.h */, + FC086D5020E7841E00D85EF7 /* batchnorm_kernel.h */, + FC086D5120E7841E00D85EF7 /* mali */, + FC086D6320E7841E00D85EF7 /* elementwise_add_kernel.h */, + FC086D6420E7841E00D85EF7 /* central-arm-func */, + FC086D6A20E7841E00D85EF7 /* conv_add_relu_kernel.h */, + FC086D6B20E7841E00D85EF7 /* reshape_kernel.h */, + FC086D6C20E7841E00D85EF7 /* transpose_kernel.h */, + FC086D6D20E7841E00D85EF7 /* conv_add_kernel.h */, + FC086D6E20E7841E00D85EF7 /* fpga */, + FC086D7020E7841E00D85EF7 /* conv_add_bn_relu_kernel.h */, + FC086D7120E7841E00D85EF7 /* prior_box_kernel.h */, + FC086D7220E7841E00D85EF7 /* conv_kernel.h */, + FC086D7320E7841E00D85EF7 /* arm */, + FC086D8820E7841E00D85EF7 /* sigmoid_kernel.h */, + ); + path = kernel; + sourceTree = ""; + }; + FC086D5120E7841E00D85EF7 /* mali */ = { + isa = PBXGroup; + children = ( + FC086D5220E7841E00D85EF7 /* acl_tensor.cc */, + FC086D5320E7841E00D85EF7 /* acl_operator.cc */, + FC086D5420E7841E00D85EF7 /* conv_kernel.cpp */, + FC086D5520E7841E00D85EF7 /* acl_operator.h */, + FC086D5620E7841E00D85EF7 /* conv_add_kernel.cpp */, + FC086D5720E7841E00D85EF7 /* acl_tensor.h */, + FC086D5820E7841E00D85EF7 /* relu_kernel.cpp */, + FC086D5920E7841E00D85EF7 /* mul_kernel.cpp */, + FC086D5A20E7841E00D85EF7 /* elementwise_add_kernel.cpp */, + FC086D5B20E7841E00D85EF7 /* ACL_Android */, + FC086D5C20E7841E00D85EF7 /* softmax_kernel.cpp */, + FC086D5D20E7841E00D85EF7 /* concat_kernel.cpp */, + FC086D5E20E7841E00D85EF7 /* pool_kernel.cpp */, + FC086D5F20E7841E00D85EF7 /* reshape_kernel.cpp */, + FC086D6020E7841E00D85EF7 /* lrn_kernel.cpp */, + FC086D6120E7841E00D85EF7 /* fushion_fc_kernel.cpp */, + FC086D6220E7841E00D85EF7 /* batchnorm_kernel.cpp */, + ); + path = mali; + sourceTree = ""; + }; + FC086D5B20E7841E00D85EF7 /* ACL_Android */ = { + isa = PBXGroup; + children = ( + ); + path = ACL_Android; + sourceTree = ""; + }; + FC086D6420E7841E00D85EF7 /* central-arm-func */ = { + isa = PBXGroup; + children = ( + FC086D6520E7841E00D85EF7 /* conv_arm_func.h */, + FC086D6620E7841E00D85EF7 /* conv_add_bn_relu_func.h */, + FC086D6720E7841E00D85EF7 /* conv_add_relu_arm_func.h */, + FC086D6820E7841E00D85EF7 /* depthwise_conv_arm_func.h */, + FC086D6920E7841E00D85EF7 /* batchnorm_arm_func.h */, + ); + path = "central-arm-func"; + sourceTree = ""; + }; + FC086D6E20E7841E00D85EF7 /* fpga */ = { + isa = PBXGroup; + children = ( + FC086D6F20E7841E00D85EF7 /* conv_kernel.cpp */, + ); + path = fpga; + sourceTree = ""; + }; + FC086D7320E7841E00D85EF7 /* arm */ = { + isa = PBXGroup; + children = ( + FC086D7420E7841E00D85EF7 /* prior_box_kernel.cpp */, + FC086D7520E7841E00D85EF7 /* conv_kernel.cpp */, + FC086D7620E7841E00D85EF7 /* conv_add_bn_relu_kernel.cpp */, + FC086D7720E7841E00D85EF7 /* box_coder_kernel.cpp */, + FC086D7820E7841E00D85EF7 /* conv_add_kernel.cpp */, + FC086D7920E7841E00D85EF7 /* sigmoid_kernel.cpp */, + FC086D7A20E7841E00D85EF7 /* relu_kernel.cpp */, + FC086D7B20E7841E00D85EF7 /* mul_kernel.cpp */, + FC086D7C20E7841E00D85EF7 /* elementwise_add_kernel.cpp */, + FC086D7D20E7841E00D85EF7 /* conv_add_relu_kernel.cpp */, + FC086D7E20E7841E00D85EF7 /* transpose_kernel.cpp */, + FC086D7F20E7841E00D85EF7 /* depthwise_conv_kernel.cpp */, + FC086D8020E7841E00D85EF7 /* softmax_kernel.cpp */, + FC086D8120E7841E00D85EF7 /* concat_kernel.cpp */, + FC086D8220E7841E00D85EF7 /* fusion_fc_kernel.cpp */, + FC086D8320E7841E00D85EF7 /* pool_kernel.cpp */, + FC086D8420E7841E00D85EF7 /* reshape_kernel.cpp */, + FC086D8520E7841E00D85EF7 /* lrn_kernel.cpp */, + FC086D8620E7841E00D85EF7 /* batchnorm_kernel.cpp */, + FC086D8720E7841E00D85EF7 /* multiclass_nms_kernel.cpp */, + ); + path = arm; + sourceTree = ""; + }; + FC086D8A20E7841E00D85EF7 /* framework */ = { + isa = PBXGroup; + children = ( + FC086D8B20E7841E00D85EF7 /* framework.pb-c.c */, + FC086D8C20E7841E00D85EF7 /* tensor_util.cpp */, + FC086D8D20E7841E00D85EF7 /* operator.h */, + FC086D8E20E7841E00D85EF7 /* op_info.h */, + FC086D8F20E7841E00D85EF7 /* operator.cpp */, + FC086D9020E7841E00D85EF7 /* ddim.cpp */, + FC086D9120E7841E00D85EF7 /* tensor_util.h */, + FC086D9220E7841E00D85EF7 /* variable.h */, + FC086D9320E7841E00D85EF7 /* scope.cpp */, + FC086D9420E7841E00D85EF7 /* data_layout.h */, + FC086D9520E7841E00D85EF7 /* lod_tensor.h */, + FC086D9620E7841E00D85EF7 /* dim.h */, + FC086D9720E7841E00D85EF7 /* framework.pb-c.h */, + FC086D9820E7841E00D85EF7 /* op_kernel_type.h */, + FC086D9920E7841E00D85EF7 /* attribute.cpp */, + FC086D9A20E7841E00D85EF7 /* op_proto_maker.h */, + FC086D9B20E7841E00D85EF7 /* program */, + FC086DAB20E7841E00D85EF7 /* lod_tensor.cpp */, + FC086DAC20E7841E00D85EF7 /* framework.proto */, + FC086DAD20E7841E00D85EF7 /* ddim.h */, + FC086DAE20E7841E00D85EF7 /* attribute.h */, + FC086DAF20E7841E00D85EF7 /* scope.h */, + FC086DB020E7841E00D85EF7 /* tensor.h */, + FC086DB120E7841E00D85EF7 /* op_registry.h */, + ); + path = framework; + sourceTree = ""; + }; + FC086D9B20E7841E00D85EF7 /* program */ = { + isa = PBXGroup; + children = ( + FC086D9C20E7841E00D85EF7 /* op_desc.cpp */, + FC086D9D20E7841E00D85EF7 /* program_desc.cpp */, + FC086D9E20E7841E00D85EF7 /* var_desc.h */, + FC086D9F20E7841E00D85EF7 /* program_desc.h */, + FC086DA020E7841E00D85EF7 /* op_desc.h */, + FC086DA120E7841E00D85EF7 /* program-optimize */, + FC086DA720E7841E00D85EF7 /* block_desc.cpp */, + FC086DA820E7841E00D85EF7 /* program.h */, + FC086DA920E7841E00D85EF7 /* tensor_desc.h */, + FC086DAA20E7841E00D85EF7 /* block_desc.h */, + ); + path = program; + sourceTree = ""; + }; + FC086DA120E7841E00D85EF7 /* program-optimize */ = { + isa = PBXGroup; + children = ( + FC086DA220E7841E00D85EF7 /* fusion_op_register.h */, + FC086DA320E7841E00D85EF7 /* node.cpp */, + FC086DA420E7841E00D85EF7 /* node.h */, + FC086DA520E7841E00D85EF7 /* program_optimize.h */, + FC086DA620E7841E00D85EF7 /* program_optimize.cpp */, + ); + path = "program-optimize"; + sourceTree = ""; + }; + FC086DB220E7841E00D85EF7 /* io */ = { + isa = PBXGroup; + children = ( + FC086DB320E7841E00D85EF7 /* io.cpp */, + FC086DB420E7841E00D85EF7 /* io.h */, + ); + path = io; + sourceTree = ""; + }; + FC086DB520E7841E00D85EF7 /* common */ = { + isa = PBXGroup; + children = ( + FC086DB620E7841E00D85EF7 /* types.cpp */, + FC086DB720E7841E00D85EF7 /* threadpool.h */, + FC086DB820E7841E00D85EF7 /* types.h */, + FC086DB920E7841E00D85EF7 /* protobuf-c.h */, + FC086DBA20E7841E00D85EF7 /* openmp-fix.cpp */, + FC086DBB20E7841E00D85EF7 /* dep_core.h */, + FC086DBC20E7841E00D85EF7 /* common.h */, + FC086DBD20E7841E00D85EF7 /* log.h */, + FC086DBE20E7841E00D85EF7 /* macros.h */, + FC086DBF20E7841E00D85EF7 /* type_define.h */, + FC086DC020E7841E00D85EF7 /* enforce.h */, + FC086DC120E7841E00D85EF7 /* protobuf-c.c */, + FC086DC220E7841E00D85EF7 /* variant.h */, + ); + path = common; + sourceTree = ""; + }; + FC086DC320E7841E00D85EF7 /* jni */ = { + isa = PBXGroup; + children = ( + FC086DC420E7841E00D85EF7 /* paddle_mobile_jni.cpp */, + FC086DC520E7841E00D85EF7 /* paddle_mobile_jni.h */, + ); + path = jni; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + FC086BAE20E7839B00D85EF7 /* PaddleMobile */ = { + isa = PBXNativeTarget; + buildConfigurationList = FC086BB820E7839B00D85EF7 /* Build configuration list for PBXNativeTarget "PaddleMobile" */; + buildPhases = ( + FC086BAB20E7839B00D85EF7 /* Sources */, + FC086BAC20E7839B00D85EF7 /* Frameworks */, + FC086BAD20E7839B00D85EF7 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PaddleMobile; + productName = PaddleMobile; + productReference = FC086BAF20E7839B00D85EF7 /* libPaddleMobile.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FC086BA720E7839B00D85EF7 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = orange; + TargetAttributes = { + FC086BAE20E7839B00D85EF7 = { + CreatedOnToolsVersion = 9.3.1; + }; + }; + }; + buildConfigurationList = FC086BAA20E7839B00D85EF7 /* Build configuration list for PBXProject "PaddleMobile" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = FC086BA620E7839B00D85EF7; + productRefGroup = FC086BB020E7839B00D85EF7 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FC086BAE20E7839B00D85EF7 /* PaddleMobile */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + FC086BAB20E7839B00D85EF7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FC086DCE20E7841E00D85EF7 /* transpose_op.cpp in Sources */, + FC086DD820E7841E00D85EF7 /* math_function.cpp in Sources */, + FC086DE120E7841E00D85EF7 /* relu_op.cpp in Sources */, + FC086E0920E7841E00D85EF7 /* multiclass_nms_kernel.cpp in Sources */, + FC086E0220E7841E00D85EF7 /* softmax_kernel.cpp in Sources */, + FC086DCD20E7841E00D85EF7 /* concat_op.cpp in Sources */, + FC086DCA20E7841E00D85EF7 /* feed_op.cpp in Sources */, + FC086DD920E7841E00D85EF7 /* pool_3x3.cpp in Sources */, + FC086DF020E7841E00D85EF7 /* pool_kernel.cpp in Sources */, + FC086E1A20E7841E00D85EF7 /* paddle_mobile_jni.cpp in Sources */, + FC086DF620E7841E00D85EF7 /* prior_box_kernel.cpp in Sources */, + FC086DC620E7841E00D85EF7 /* t_malloc.cpp in Sources */, + FC086DD320E7841E00D85EF7 /* elementwise_add_op.cpp in Sources */, + FC086E0E20E7841E00D85EF7 /* scope.cpp in Sources */, + FC086DDE20E7841E00D85EF7 /* fusion_conv_add.cpp in Sources */, + FC086DFF20E7841E00D85EF7 /* conv_add_relu_kernel.cpp in Sources */, + FC086DD720E7841E00D85EF7 /* vol2col.cpp in Sources */, + FC086E0B20E7841E00D85EF7 /* tensor_util.cpp in Sources */, + FC086E1320E7841E00D85EF7 /* program_optimize.cpp in Sources */, + FC086DF820E7841E00D85EF7 /* conv_add_bn_relu_kernel.cpp in Sources */, + FC086DC820E7841E00D85EF7 /* sigmoid_op.cpp in Sources */, + FC086E0D20E7841E00D85EF7 /* ddim.cpp in Sources */, + FC086E0120E7841E00D85EF7 /* depthwise_conv_kernel.cpp in Sources */, + FC086DDB20E7841E00D85EF7 /* depthwise_conv_3x3.cpp in Sources */, + FC086BB420E7839B00D85EF7 /* PaddleMobile.m in Sources */, + FC086E1420E7841E00D85EF7 /* block_desc.cpp in Sources */, + FC086DC920E7841E00D85EF7 /* box_coder_op.cpp in Sources */, + FC086DDF20E7841E00D85EF7 /* op_param.cpp in Sources */, + FC086DD520E7841E00D85EF7 /* pool_2x2.cpp in Sources */, + FC086DFD20E7841E00D85EF7 /* mul_kernel.cpp in Sources */, + FC086E0C20E7841E00D85EF7 /* operator.cpp in Sources */, + FC086DE020E7841E00D85EF7 /* mul_op.cpp in Sources */, + FC086E1520E7841E00D85EF7 /* lod_tensor.cpp in Sources */, + FC086DE720E7841E00D85EF7 /* acl_tensor.cc in Sources */, + FC086DDD20E7841E00D85EF7 /* fetch_op.cpp in Sources */, + FC086DE220E7841E00D85EF7 /* conv_op.cpp in Sources */, + FC086DDA20E7841E00D85EF7 /* pooling.cpp in Sources */, + FC086DEF20E7841E00D85EF7 /* concat_kernel.cpp in Sources */, + FC086DE520E7841E00D85EF7 /* pool_op.cpp in Sources */, + FC086DE820E7841E00D85EF7 /* acl_operator.cc in Sources */, + FC086DF220E7841E00D85EF7 /* lrn_kernel.cpp in Sources */, + FC086E0F20E7841E00D85EF7 /* attribute.cpp in Sources */, + FC086E0520E7841E00D85EF7 /* pool_kernel.cpp in Sources */, + FC086DDC20E7841E00D85EF7 /* softmax.cpp in Sources */, + FC086E0420E7841E00D85EF7 /* fusion_fc_kernel.cpp in Sources */, + FC086E1220E7841E00D85EF7 /* node.cpp in Sources */, + FC086E0820E7841E00D85EF7 /* batchnorm_kernel.cpp in Sources */, + FC086DCC20E7841E00D85EF7 /* reshape_op.cpp in Sources */, + FC086DE920E7841E00D85EF7 /* conv_kernel.cpp in Sources */, + FC086E1920E7841E00D85EF7 /* protobuf-c.c in Sources */, + FC086DF920E7841E00D85EF7 /* box_coder_kernel.cpp in Sources */, + FC086DF120E7841E00D85EF7 /* reshape_kernel.cpp in Sources */, + FC086DF720E7841E00D85EF7 /* conv_kernel.cpp in Sources */, + FC086DCF20E7841E00D85EF7 /* prior_box_op.cpp in Sources */, + FC086E1720E7841E00D85EF7 /* types.cpp in Sources */, + FC086DF320E7841E00D85EF7 /* fushion_fc_kernel.cpp in Sources */, + FC086DEB20E7841E00D85EF7 /* relu_kernel.cpp in Sources */, + FC086E0620E7841E00D85EF7 /* reshape_kernel.cpp in Sources */, + FC086E0720E7841E00D85EF7 /* lrn_kernel.cpp in Sources */, + FC086DE620E7841E00D85EF7 /* multiclass_nms_op.cpp in Sources */, + FC086E1120E7841E00D85EF7 /* program_desc.cpp in Sources */, + FC086E0320E7841E00D85EF7 /* concat_kernel.cpp in Sources */, + FC086DEC20E7841E00D85EF7 /* mul_kernel.cpp in Sources */, + FC086DFB20E7841E00D85EF7 /* sigmoid_kernel.cpp in Sources */, + FC086E1820E7841E00D85EF7 /* openmp-fix.cpp in Sources */, + FC086DF420E7841E00D85EF7 /* batchnorm_kernel.cpp in Sources */, + FC086DEA20E7841E00D85EF7 /* conv_add_kernel.cpp in Sources */, + FC086E1620E7841E00D85EF7 /* io.cpp in Sources */, + FC086DD620E7841E00D85EF7 /* im2col.cpp in Sources */, + FC086DC720E7841E00D85EF7 /* lrn_op.cpp in Sources */, + FC086DD220E7841E00D85EF7 /* depthwise_conv_op.cpp in Sources */, + FC086DFA20E7841E00D85EF7 /* conv_add_kernel.cpp in Sources */, + FC086E0A20E7841E00D85EF7 /* framework.pb-c.c in Sources */, + FC086DD020E7841E00D85EF7 /* fusion_conv_add_relu_op.cpp in Sources */, + FC086DCB20E7841E00D85EF7 /* fusion_conv_add_bn_relu_op.cpp in Sources */, + FC086DFC20E7841E00D85EF7 /* relu_kernel.cpp in Sources */, + FC086DE320E7841E00D85EF7 /* fusion_fc_op.cpp in Sources */, + FC086E0020E7841E00D85EF7 /* transpose_kernel.cpp in Sources */, + FC086DEE20E7841E00D85EF7 /* softmax_kernel.cpp in Sources */, + FC086DE420E7841E00D85EF7 /* batchnorm_op.cpp in Sources */, + FC086DED20E7841E00D85EF7 /* elementwise_add_kernel.cpp in Sources */, + FC086DF520E7841E00D85EF7 /* conv_kernel.cpp in Sources */, + FC086DD120E7841E00D85EF7 /* softmax_op.cpp in Sources */, + FC086E1020E7841E00D85EF7 /* op_desc.cpp in Sources */, + FC086DD420E7841E00D85EF7 /* gemm.cpp in Sources */, + FC086DFE20E7841E00D85EF7 /* elementwise_add_kernel.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + FC086BB620E7839B00D85EF7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + FC086BB720E7839B00D85EF7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FC086BB920E7839B00D85EF7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Z5M2UUN5YV; + HEADER_SEARCH_PATHS = ../../src; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + FC086BBA20E7839B00D85EF7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Z5M2UUN5YV; + HEADER_SEARCH_PATHS = ../../src; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FC086BAA20E7839B00D85EF7 /* Build configuration list for PBXProject "PaddleMobile" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC086BB620E7839B00D85EF7 /* Debug */, + FC086BB720E7839B00D85EF7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FC086BB820E7839B00D85EF7 /* Build configuration list for PBXNativeTarget "PaddleMobile" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC086BB920E7839B00D85EF7 /* Debug */, + FC086BBA20E7839B00D85EF7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FC086BA720E7839B00D85EF7 /* Project object */; +} diff --git a/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000000000000000000000000000000..18f14d0d53b03b7326c6b613e445438ab35e4bed --- /dev/null +++ b/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000000000000000000000000000000..18d981003d68d0546c4804ac2ff47dd97c6e7921 --- /dev/null +++ b/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate b/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..d1170b2289cb3302e40f5101b720bc835d08e7e1 Binary files /dev/null and b/ios/PaddleMobile/PaddleMobile.xcodeproj/project.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ios/PaddleMobile/PaddleMobile.xcodeproj/xcuserdata/liuruilong.xcuserdatad/xcschemes/xcschememanagement.plist b/ios/PaddleMobile/PaddleMobile.xcodeproj/xcuserdata/liuruilong.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000000000000000000000000000000000000..a877b7cd221cba607fdb31df85bfa008b95d988c --- /dev/null +++ b/ios/PaddleMobile/PaddleMobile.xcodeproj/xcuserdata/liuruilong.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + PaddleMobile.xcscheme + + orderHint + 1 + + + + diff --git a/ios/PaddleMobile/PaddleMobile/MacroDefine.h b/ios/PaddleMobile/PaddleMobile/MacroDefine.h new file mode 100644 index 0000000000000000000000000000000000000000..a09c420e87ec698345b6d1ffa4fd64c2c6ef9b47 --- /dev/null +++ b/ios/PaddleMobile/PaddleMobile/MacroDefine.h @@ -0,0 +1,13 @@ +// +// MacroDefine.h +// PaddleMobile +// +// Created by liuRuiLong on 2018/6/30. +// Copyright © 2018年 orange. All rights reserved. +// + +#ifndef MacroDefine_h +#define MacroDefine_h + + +#endif /* MacroDefine_h */ diff --git a/ios/PaddleMobile/PaddleMobile/PaddleMobile.h b/ios/PaddleMobile/PaddleMobile/PaddleMobile.h new file mode 100644 index 0000000000000000000000000000000000000000..3878c54c8a19a99e535bd8ad90eb1e19e28757c3 --- /dev/null +++ b/ios/PaddleMobile/PaddleMobile/PaddleMobile.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ + +#import +#import + +@interface PaddleMobile : NSObject + ++ (instancetype)sharedInstance; +- (BOOL)load:(NSString *)modelPath andWeightsPath:(NSString *)weighsPath; +- (NSArray *)predict:(CGImageRef)image means:(NSArray *)means scale:(float)scale; +- (NSArray *)predict:(CGImageRef)image; +- (void)clear; + +@end diff --git a/ios/PaddleMobile/PaddleMobile/PaddleMobile.m b/ios/PaddleMobile/PaddleMobile/PaddleMobile.m new file mode 100644 index 0000000000000000000000000000000000000000..a350330b1d0fbf7072d35c41cab75da0b477c31d --- /dev/null +++ b/ios/PaddleMobile/PaddleMobile/PaddleMobile.m @@ -0,0 +1,43 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ + +#import "PaddleMobile.h" + +@implementation PaddleMobile + ++ (instancetype)sharedInstance{ + //TODO: imp + exit(0); +} + +- (BOOL)load:(NSString *)modelPath andWeightsPath:(NSString *)weighsPath{ + //TODO: imp + exit(0); +} + +- (NSArray *)predict:(CGImageRef)image means:(NSArray *)means scale:(float)scale{ + //TODO: imp + exit(0); +} + +- (NSArray *)predict:(CGImageRef)image{ + //TODO: imp + exit(0); +} + +- (void)clear{ + //TODO: imp + exit(0); +} +@end diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.pbxproj b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..e7e77ada15e84a6957a082c203c0121e118c5a3b --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.pbxproj @@ -0,0 +1,340 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + FC086BC920E783AF00D85EF7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FC086BC820E783AF00D85EF7 /* AppDelegate.m */; }; + FC086BCC20E783AF00D85EF7 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC086BCB20E783AF00D85EF7 /* ViewController.m */; }; + FC086BCF20E783AF00D85EF7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC086BCD20E783AF00D85EF7 /* Main.storyboard */; }; + FC086BD120E783B100D85EF7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC086BD020E783B100D85EF7 /* Assets.xcassets */; }; + FC086BD420E783B100D85EF7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC086BD220E783B100D85EF7 /* LaunchScreen.storyboard */; }; + FC086BD720E783B100D85EF7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FC086BD620E783B100D85EF7 /* main.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + FC086BC420E783AF00D85EF7 /* PaddleMobileDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PaddleMobileDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FC086BC720E783AF00D85EF7 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + FC086BC820E783AF00D85EF7 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + FC086BCA20E783AF00D85EF7 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + FC086BCB20E783AF00D85EF7 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + FC086BCE20E783AF00D85EF7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + FC086BD020E783B100D85EF7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + FC086BD320E783B100D85EF7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + FC086BD520E783B100D85EF7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FC086BD620E783B100D85EF7 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FC086BC120E783AF00D85EF7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + FC086BBB20E783AF00D85EF7 = { + isa = PBXGroup; + children = ( + FC086BC620E783AF00D85EF7 /* PaddleMobileDemo */, + FC086BC520E783AF00D85EF7 /* Products */, + ); + sourceTree = ""; + }; + FC086BC520E783AF00D85EF7 /* Products */ = { + isa = PBXGroup; + children = ( + FC086BC420E783AF00D85EF7 /* PaddleMobileDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + FC086BC620E783AF00D85EF7 /* PaddleMobileDemo */ = { + isa = PBXGroup; + children = ( + FC086BC720E783AF00D85EF7 /* AppDelegate.h */, + FC086BC820E783AF00D85EF7 /* AppDelegate.m */, + FC086BCA20E783AF00D85EF7 /* ViewController.h */, + FC086BCB20E783AF00D85EF7 /* ViewController.m */, + FC086BCD20E783AF00D85EF7 /* Main.storyboard */, + FC086BD020E783B100D85EF7 /* Assets.xcassets */, + FC086BD220E783B100D85EF7 /* LaunchScreen.storyboard */, + FC086BD520E783B100D85EF7 /* Info.plist */, + FC086BD620E783B100D85EF7 /* main.m */, + ); + path = PaddleMobileDemo; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + FC086BC320E783AF00D85EF7 /* PaddleMobileDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = FC086BDA20E783B100D85EF7 /* Build configuration list for PBXNativeTarget "PaddleMobileDemo" */; + buildPhases = ( + FC086BC020E783AF00D85EF7 /* Sources */, + FC086BC120E783AF00D85EF7 /* Frameworks */, + FC086BC220E783AF00D85EF7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PaddleMobileDemo; + productName = PaddleMobileDemo; + productReference = FC086BC420E783AF00D85EF7 /* PaddleMobileDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FC086BBC20E783AF00D85EF7 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = orange; + TargetAttributes = { + FC086BC320E783AF00D85EF7 = { + CreatedOnToolsVersion = 9.3.1; + }; + }; + }; + buildConfigurationList = FC086BBF20E783AF00D85EF7 /* Build configuration list for PBXProject "PaddleMobileDemo" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = FC086BBB20E783AF00D85EF7; + productRefGroup = FC086BC520E783AF00D85EF7 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FC086BC320E783AF00D85EF7 /* PaddleMobileDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + FC086BC220E783AF00D85EF7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FC086BD420E783B100D85EF7 /* LaunchScreen.storyboard in Resources */, + FC086BD120E783B100D85EF7 /* Assets.xcassets in Resources */, + FC086BCF20E783AF00D85EF7 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + FC086BC020E783AF00D85EF7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FC086BCC20E783AF00D85EF7 /* ViewController.m in Sources */, + FC086BD720E783B100D85EF7 /* main.m in Sources */, + FC086BC920E783AF00D85EF7 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + FC086BCD20E783AF00D85EF7 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FC086BCE20E783AF00D85EF7 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + FC086BD220E783B100D85EF7 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FC086BD320E783B100D85EF7 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + FC086BD820E783B100D85EF7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + FC086BD920E783B100D85EF7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FC086BDB20E783B100D85EF7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Z5M2UUN5YV; + INFOPLIST_FILE = PaddleMobileDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = orange.PaddleMobileDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + FC086BDC20E783B100D85EF7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Z5M2UUN5YV; + INFOPLIST_FILE = PaddleMobileDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = orange.PaddleMobileDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FC086BBF20E783AF00D85EF7 /* Build configuration list for PBXProject "PaddleMobileDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC086BD820E783B100D85EF7 /* Debug */, + FC086BD920E783B100D85EF7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FC086BDA20E783B100D85EF7 /* Build configuration list for PBXNativeTarget "PaddleMobileDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC086BDB20E783B100D85EF7 /* Debug */, + FC086BDC20E783B100D85EF7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FC086BBC20E783AF00D85EF7 /* Project object */; +} diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000000000000000000000000000000..e4db9529ba656814e6a2bd889426662d914277eb --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000000000000000000000000000000..18d981003d68d0546c4804ac2ff47dd97c6e7921 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..69b699dbf553971a96471ef864e4e848c9b17e12 Binary files /dev/null and b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/project.xcworkspace/xcuserdata/liuruilong.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/xcuserdata/liuruilong.xcuserdatad/xcschemes/xcschememanagement.plist b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/xcuserdata/liuruilong.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000000000000000000000000000000000000..7caa9222e77f1e53c0ee45c298aacb330e870688 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo.xcodeproj/xcuserdata/liuruilong.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + PaddleMobileDemo.xcscheme + + orderHint + 0 + + + + diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/AppDelegate.h b/ios/PaddleMobileDemo/PaddleMobileDemo/AppDelegate.h new file mode 100644 index 0000000000000000000000000000000000000000..eb789ffbb2d394d9c45651b48a931d3759a7687b --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/AppDelegate.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/AppDelegate.m b/ios/PaddleMobileDemo/PaddleMobileDemo/AppDelegate.m new file mode 100644 index 0000000000000000000000000000000000000000..12cc19636b43f7fc3634736c4b551b4aba29ce73 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/AppDelegate.m @@ -0,0 +1,57 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + + +@end diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/PaddleMobileDemo/PaddleMobileDemo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..d8db8d65fd79fd541b2b7eba75c7378af3448f9c --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/Assets.xcassets/Contents.json b/ios/PaddleMobileDemo/PaddleMobileDemo/Assets.xcassets/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..da4a164c918651cdd1e11dca5cc62c333f097601 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/Base.lproj/LaunchScreen.storyboard b/ios/PaddleMobileDemo/PaddleMobileDemo/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000000000000000000000000000000000..f83f6fd5810b9c852cf98563d82d5ed1e84ff893 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/Base.lproj/Main.storyboard b/ios/PaddleMobileDemo/PaddleMobileDemo/Base.lproj/Main.storyboard new file mode 100644 index 0000000000000000000000000000000000000000..d7c78a1255c016bde922c849eef8555881c207b6 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/Info.plist b/ios/PaddleMobileDemo/PaddleMobileDemo/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..16be3b681122de83e380d47b840b7d0486f71f86 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/ViewController.h b/ios/PaddleMobileDemo/PaddleMobileDemo/ViewController.h new file mode 100644 index 0000000000000000000000000000000000000000..092a369366b4f28e88eaac6032b60f18a332ba84 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/ViewController.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/ViewController.m b/ios/PaddleMobileDemo/PaddleMobileDemo/ViewController.m new file mode 100644 index 0000000000000000000000000000000000000000..369e90039d37f62545a20ae30b5ce47d1c27dc95 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/ViewController.m @@ -0,0 +1,33 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; +} + + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; +} + + +@end diff --git a/ios/PaddleMobileDemo/PaddleMobileDemo/main.m b/ios/PaddleMobileDemo/PaddleMobileDemo/main.m new file mode 100644 index 0000000000000000000000000000000000000000..8429e87bd1fba3a2e7070db56b458f2656b9bfa6 --- /dev/null +++ b/ios/PaddleMobileDemo/PaddleMobileDemo/main.m @@ -0,0 +1,22 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/src/common/log.h b/src/common/log.h index faab6b31a31d7ce7148f96630900aff82931c771..d964d9c1b39a7e72e3d757ef2be0737fd1d25f94 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -174,7 +174,10 @@ struct ToLog; struct Print { friend struct ToLog; template - Print &operator<<(T const &value) {} + Print &operator<<(T const &value) { + Print p = Print(); + return p; + } private: }; diff --git a/src/common/types.cpp b/src/common/types.cpp index 1611a919ffe716e31ff83b8673035a048ebe96d2..cea42171f0205e0d40b2703d5c90f0b9fc253e68 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -40,6 +40,8 @@ const std::string G_OP_TYPE_SPLIT = "split"; const std::string G_OP_TYPE_FEED = "feed"; const std::string G_OP_TYPE_FETCH = "fetch"; const std::string G_OP_TYPE_DEPTHWISE_CONV = "depthwise_conv2d"; +const std::string G_OP_TYPE_IM2SEQUENCE = "im2sequence"; +const std::string G_OP_TYPE_DROPOUT = "dropout"; std::unordered_map< std::string, std::pair, std::vector>> @@ -66,6 +68,8 @@ std::unordered_map< {G_OP_TYPE_FC, {{"X", "Y", "Z"}, {"Out"}}}, {G_OP_TYPE_RESHAPE, {{"X"}, {"Out"}}}, {G_OP_TYPE_DEPTHWISE_CONV, {{"Input"}, {"Output"}}}, - {G_OP_TYPE_FUSION_CONV_ADD_RELU, {{"Input"}, {"Out"}}}}; + {G_OP_TYPE_FUSION_CONV_ADD_RELU, {{"Input"}, {"Out"}}}, + {G_OP_TYPE_IM2SEQUENCE, {{"X"}, {"Out"}}}, + {G_OP_TYPE_DROPOUT, {{"X"}, {"Out"}}}}; } // namespace paddle_mobile diff --git a/src/common/types.h b/src/common/types.h index 9134ebe3561153e32db157c4c4b835a1bc464149..ec428b9911f64d7ccc8c6f5dc4be7f970e855d3c 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -96,6 +96,8 @@ extern const std::string G_OP_TYPE_SPLIT; extern const std::string G_OP_TYPE_FEED; extern const std::string G_OP_TYPE_FETCH; extern const std::string G_OP_TYPE_DEPTHWISE_CONV; +extern const std::string G_OP_TYPE_IM2SEQUENCE; +extern const std::string G_OP_TYPE_DROPOUT; extern std::unordered_map< std::string, std::pair, std::vector>> diff --git a/src/common/variant.h b/src/common/variant.h index 7fbf0ec0772f102165770dc9c8e053f469965f10..b87a5e67a76f4c616f2c450ef4527bcf6c16286b 100644 --- a/src/common/variant.h +++ b/src/common/variant.h @@ -83,6 +83,7 @@ struct Variant { return *const_cast(reinterpret_cast(&data)); } else { PADDLE_MOBILE_THROW_EXCEPTION(" bad cast in variant "); + exit(0); } } diff --git a/src/framework/attribute.h b/src/framework/attribute.h index 478fc1b3f5ae95d9720b057d3ab0d2e8912e7093..f0519a35b3ed2a02e35f1ef0d6a718efb7b76095 100644 --- a/src/framework/attribute.h +++ b/src/framework/attribute.h @@ -129,6 +129,7 @@ class Attribute { return vistor(attr.variant_.Get()); } else { PADDLE_MOBILE_THROW_EXCEPTION("type not support"); + exit(0); } } diff --git a/src/framework/data_layout.h b/src/framework/data_layout.h index 3b31445707a887a2715afd0b9e7192ad76724351..f1249008f088dce48ed040e47900121c2eb41af1 100644 --- a/src/framework/data_layout.h +++ b/src/framework/data_layout.h @@ -40,6 +40,7 @@ inline DataLayout StringToDataLayout(const std::string &str) { return DataLayout::kAnyLayout; } else { PADDLE_MOBILE_THROW_EXCEPTION("Unknown storage order string: %s", s.c_str()) + exit(0); } } @@ -52,6 +53,8 @@ inline std::string DataLayoutToString(const DataLayout &data_layout) { case DataLayout::kAnyLayout: return "ANY_LAYOUT"; default: + PADDLE_MOBILE_THROW_EXCEPTION("Unknown storage order string ") + exit(0); break; } } diff --git a/src/framework/ddim.h b/src/framework/ddim.h index ff94c24adac5bea1fd4c7a80857b212056c06d36..833bc2783f855fd9d6df50d21345539fbe2ca6c4 100644 --- a/src/framework/ddim.h +++ b/src/framework/ddim.h @@ -58,7 +58,8 @@ struct DDim { } else if (d.var.TypeId() == typeid(Dim<9>).hash_code()) { return vistor(d.var.Get>()); } else { - DLOG << " dim not support"; + PADDLE_MOBILE_ENFORCE(false, " dim not support"); + exit(0); } } diff --git a/src/framework/dim.h b/src/framework/dim.h index 38e62df99519c3e869dc0fd2ae71beed28370122..dd7610de65d4a4c93402cf49b0fdbdc7995610c0 100644 --- a/src/framework/dim.h +++ b/src/framework/dim.h @@ -129,6 +129,7 @@ int64_t &indexer(Dim &dim, int idx) { template <> int64_t &indexer<0>(Dim<0> &dim, int idx) { PADDLE_MOBILE_THROW_EXCEPTION("Invalid index") + exit(0); } template @@ -145,6 +146,7 @@ int64_t indexer(const Dim &dim, int idx) { template <> int64_t indexer<0>(const Dim<0> &dim, int idx) { PADDLE_MOBILE_THROW_EXCEPTION("Invalid index") + exit(0); } } // namespace diff --git a/src/io/io.cpp b/src/io/executor.cpp similarity index 72% rename from src/io/io.cpp rename to src/io/executor.cpp index 007ed8df2a8192c5b310d54dc9eb3ad852aeeee0..c8bd2e5e8c49a7d6594f93052ece7ef110c56527 100644 --- a/src/io/io.cpp +++ b/src/io/executor.cpp @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "io/io.h" +#include "io/executor.h" #include #include #include "common/enforce.h" @@ -39,7 +39,7 @@ char *Get_binary_data(std::string filename) { PADDLE_MOBILE_ENFORCE(file != nullptr, "can't open file: %s ", filename.c_str()); fseek(file, 0, SEEK_END); - long size = ftell(file); + int64_t size = ftell(file); PADDLE_MOBILE_ENFORCE(size > 0, "size is too small"); rewind(file); char *data = new char[size]; @@ -50,116 +50,6 @@ char *Get_binary_data(std::string filename) { return data; } -static size_t ReadBuffer(const char *file_name, uint8_t **out) { - printf("%s \n", file_name); - FILE *fp; - fp = fopen(file_name, "rb"); - PADDLE_MOBILE_ENFORCE(fp != NULL, " %s open failed !", file_name); - - fseek(fp, 0, SEEK_END); - size_t size = ftell(fp); - rewind(fp); - - DLOG << "model size: " << size; - - *out = reinterpret_cast(malloc(size)); - - size_t cur_len = 0; - size_t nread; - while ((nread = fread(*out + cur_len, 1, size - cur_len, fp)) != 0) { - cur_len += nread; - } - fclose(fp); - return cur_len; -} - -template -const framework::Program Loader::Load( - const std::string &dirname, bool optimize, bool can_add_split) { - auto program = - this->LoadProgram(dirname + "/__model__", optimize, can_add_split); - program.model_path = dirname; - return program; -} - -template -const framework::Program Loader::Load( - const std::string &model_path, const std::string ¶_path, - bool optimize) { - auto program = this->LoadProgram(model_path, optimize); - program.para_path = para_path; - program.combined = true; - return program; -} - -template -const framework::Program Loader::LoadProgram( - const std::string &model_path, bool optimize, bool can_add_split) { - std::string model_filename = model_path; - PaddleMobile__Framework__Proto__ProgramDesc *c_program; - uint8_t *buf = NULL; - size_t read_size = ReadBuffer(model_filename.c_str(), &buf); - - PADDLE_MOBILE_ENFORCE(buf != NULL, "read from __model__ is null"); - - c_program = paddle_mobile__framework__proto__program_desc__unpack( - NULL, read_size, buf); - // - PADDLE_MOBILE_ENFORCE(c_program != NULL, "program is null"); - // - DLOG << "n_ops: " << (*c_program->blocks)->n_ops; - // - auto originProgramDesc = std::make_shared(c_program); - - framework::Program program; - program.originProgram = originProgramDesc; - - auto scope = std::make_shared(); - program.scope = scope; - - for (const auto &block : originProgramDesc->Blocks()) { - for (auto var_desc : block->Vars()) { - auto var = scope->Var(var_desc->Name()); - - if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) { - if (var_desc->Persistable() && - var_desc->Type() != framework::VARTYPE_TYPE_FEED_MINIBATCH && - var_desc->Type() != framework::VARTYPE_TYPE_FETCH_LIST) { - auto dim = var_desc->Tensor_desc().Dims(); - auto tensor = var->GetMutable(); - tensor->Resize(framework::make_ddim(dim)); - } else { - auto dim = var_desc->Tensor_desc().Dims(); - PADDLE_MOBILE_ENFORCE(dim.size() > 0, "dim size is 0"); - dim[0] = 1; - auto tensor = var->GetMutable(); - tensor->Resize(framework::make_ddim(dim)); - } - } else { - // TODO(codeWorm): some. - } - } - } - - if (optimize) { - framework::ProgramOptimize program_optimize; - program.optimizeProgram = - program_optimize.FusionOptimize(originProgramDesc, can_add_split); - } - if (optimize) { - program.optimizeProgram->Description("optimize: "); - } else { - originProgramDesc->Description("program: "); - } - - paddle_mobile__framework__proto__program_desc__free_unpacked(c_program, NULL); - return program; -} - -template class Loader; -template class Loader; -template class Loader; - #pragma mark - executor template Executor::Executor(const framework::Program p, int batch_size, @@ -209,30 +99,30 @@ Executor::Executor(const framework::Program p, int batch_size, template void Executor::LoadMemory(const framework::VarDesc var_desc, - framework::LoDTensor *tensor, char *&data) { + framework::LoDTensor *tensor, char **data) { // 1. version - uint32_t version = *(uint32_t *)data; - data += sizeof(uint32_t); + uint32_t version = *reinterpret_cast(*data); + + (*data) += sizeof(uint32_t); // 2 Lod information uint64_t *lod_level_ptr = new uint64_t(); - memcpy(lod_level_ptr, data, sizeof(uint64_t)); + memcpy(lod_level_ptr, (*data), sizeof(uint64_t)); uint64_t lod_level = *lod_level_ptr; delete lod_level_ptr; - data += sizeof(uint64_t); + (*data) += sizeof(uint64_t); auto &lod = *tensor->mutable_lod(); lod.resize(lod_level); for (uint64_t i = 0; i < lod_level; ++i) { - uint64_t size = *(uint64_t *)data; - data += sizeof(uint64_t); + uint64_t size = *reinterpret_cast(*data); + (*data) += sizeof(uint64_t); DLOG << "lod size: " << i << size; std::vector tmp(size / sizeof(size_t)); for (int k = 0; k < tmp.size(); ++k) { - tmp[k] = *(size_t *)data; - DLOG << "tmp[k]: " << k << *(size_t *)data; - data += sizeof(size_t); + tmp[k] = *reinterpret_cast(*data); + (*data) += sizeof(size_t); } for (auto j : tmp) { @@ -242,18 +132,18 @@ void Executor::LoadMemory(const framework::VarDesc var_desc, } // 3. tensor version - uint32_t tensor_version = *(uint32_t *)data; - data += sizeof(uint32_t); + uint32_t tensor_version = *reinterpret_cast(*data); + (*data) += sizeof(uint32_t); // 4. tensor desc - int32_t size = *(int32_t *)data; - data += sizeof(int32_t); + int32_t size = *reinterpret_cast(*data); + (*data) += sizeof(int32_t); std::unique_ptr buf(new char[size]); for (int m = 0; m < size; ++m) { - buf.get()[m] = data[m]; + buf.get()[m] = (*data)[m]; } - data += (sizeof(char) * size); + (*data) += (sizeof(char) * size); const framework::TensorDesc &desc = var_desc.Tensor_desc(); int memory_size = 1; @@ -290,9 +180,9 @@ void Executor::LoadMemory(const framework::VarDesc var_desc, } for (int n = 0; n < memory_size * type_size; ++n) { - static_cast(memory)[n] = data[n]; + static_cast(memory)[n] = (*data)[n]; } - data += (sizeof(char) * memory_size * type_size); + (*data) += (sizeof(char) * memory_size * type_size); } template @@ -309,7 +199,7 @@ void Executor::InitMemory() { char *origin_data = Get_binary_data(program_.model_path + "/" + var_desc->Name()); char *data = origin_data; - LoadMemory(*var_desc, tensor, data); + LoadMemory(*var_desc, tensor, &data); delete origin_data; } else { if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) { @@ -335,7 +225,7 @@ void Executor::InitCombineMemory() { if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") { continue; } - LoadMemory(*var_desc, tensor, data); + LoadMemory(*var_desc, tensor, &data); } else { if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) { auto tensor = var->template GetMutable(); @@ -442,7 +332,8 @@ std::shared_ptr Executor::Predict( *(program_.scope)); #ifdef PADDLE_MOBILE_PROFILE #ifdef PADDLE_EXECUTOR_MULTITHREAD - // TODO expose profile info as an interface, user can get them to analysis + // TODO(haipeng): expose profile info as an interface, user can get them to + // analysis // the performance of their deepnet. FILE *df = fopen("net.dot", "w"); fprintf(df, "digraph {\n"); @@ -480,8 +371,9 @@ std::shared_ptr Executor::Predict( std::sort(_tv.begin(), _tv.end(), compf); _tv.push_back(std::make_pair("total", _ptotal)); for (auto const &p : _tv) { - printf("%-16s\t%-10.0f\t%-2.4f\n", p.first.c_str(), (float)p.second, - (float)p.second / _ptotal * 100.0); + printf("%-16s\t%-10.0f\t%-2.4f\n", p.first.c_str(), + static_cast(p.second), + static_cast(p.second) / _ptotal * 100.0); } printf("====================[---------]======================\n"); #endif diff --git a/src/io/io.h b/src/io/executor.h similarity index 71% rename from src/io/io.h rename to src/io/executor.h index acae829339bdc049c5899b9c7f6a7a2c91693ae8..f8f2a8ad5657fdb3cf6cb249e32537bd5e866913 100644 --- a/src/io/io.h +++ b/src/io/executor.h @@ -18,6 +18,7 @@ limitations under the License. */ #include #include #include + #include "common/types.h" #include "framework/lod_tensor.h" #include "framework/operator.h" @@ -32,31 +33,6 @@ limitations under the License. */ namespace paddle_mobile { -template -class Loader { - public: - /* - * @b load separate format fluid model - * @b 加载分开形式的 fluid 模型 - * */ - const framework::Program Load(const std::string &dirname, - bool optimize = false, - bool can_add_split = false); - - /* - * @b load combine format fluid mode - * @b 加载结合在一起格式的模型 - * */ - const framework::Program Load(const std::string &model_path, - const std::string ¶_path, - bool optimize = false); - - private: - const framework::Program LoadProgram(const std::string &model_path, - bool optimize = false, - bool can_add_split = false); -}; - template class Executor { public: @@ -86,7 +62,7 @@ class Executor { Executor() = default; void InitMemory(); void LoadMemory(const framework::VarDesc var_desc, - framework::LoDTensor *tensor, char *&data); + framework::LoDTensor *tensor, char **data); void InitCombineMemory(); framework::Program program_; int batch_size_ = 1; diff --git a/src/io/loader.cpp b/src/io/loader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f3b19abbe17c3d5e8b5cc082a115c05058aa0219 --- /dev/null +++ b/src/io/loader.cpp @@ -0,0 +1,133 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#include "io/loader.h" + +#include "framework/lod_tensor.h" +#include "framework/program/program-optimize/program_optimize.h" + +namespace paddle_mobile { +using framework::Variable; + +static size_t ReadBuffer(const char *file_name, uint8_t **out) { + printf("%s \n", file_name); + FILE *fp; + fp = fopen(file_name, "rb"); + PADDLE_MOBILE_ENFORCE(fp != NULL, " %s open failed !", file_name); + + fseek(fp, 0, SEEK_END); + size_t size = ftell(fp); + rewind(fp); + + DLOG << "model size: " << size; + + *out = reinterpret_cast(malloc(size)); + + size_t cur_len = 0; + size_t nread; + while ((nread = fread(*out + cur_len, 1, size - cur_len, fp)) != 0) { + cur_len += nread; + } + fclose(fp); + return cur_len; +} + +template +const framework::Program Loader::Load( + const std::string &dirname, bool optimize, bool can_add_split) { + auto program = + this->LoadProgram(dirname + "/__model__", optimize, can_add_split); + program.model_path = dirname; + return program; +} + +template +const framework::Program Loader::Load( + const std::string &model_path, const std::string ¶_path, + bool optimize) { + auto program = this->LoadProgram(model_path, optimize); + program.para_path = para_path; + program.combined = true; + return program; +} + +template +const framework::Program Loader::LoadProgram( + const std::string &model_path, bool optimize, bool can_add_split) { + std::string model_filename = model_path; + PaddleMobile__Framework__Proto__ProgramDesc *c_program; + uint8_t *buf = NULL; + size_t read_size = ReadBuffer(model_filename.c_str(), &buf); + + PADDLE_MOBILE_ENFORCE(buf != NULL, "read from __model__ is null"); + + c_program = paddle_mobile__framework__proto__program_desc__unpack( + NULL, read_size, buf); + // + PADDLE_MOBILE_ENFORCE(c_program != NULL, "program is null"); + // + DLOG << "n_ops: " << (*c_program->blocks)->n_ops; + // + auto originProgramDesc = std::make_shared(c_program); + + framework::Program program; + program.originProgram = originProgramDesc; + + auto scope = std::make_shared(); + program.scope = scope; + + for (const auto &block : originProgramDesc->Blocks()) { + for (auto var_desc : block->Vars()) { + auto var = scope->Var(var_desc->Name()); + + if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) { + if (var_desc->Persistable() && + var_desc->Type() != framework::VARTYPE_TYPE_FEED_MINIBATCH && + var_desc->Type() != framework::VARTYPE_TYPE_FETCH_LIST) { + auto dim = var_desc->Tensor_desc().Dims(); + auto tensor = var->GetMutable(); + tensor->Resize(framework::make_ddim(dim)); + } else { + auto dim = var_desc->Tensor_desc().Dims(); + PADDLE_MOBILE_ENFORCE(dim.size() > 0, "dim size is 0"); + dim[0] = 1; + auto tensor = var->GetMutable(); + tensor->Resize(framework::make_ddim(dim)); + } + } else { + // TODO(codeWorm): some. + } + } + } + + if (optimize) { + framework::ProgramOptimize program_optimize; + program.optimizeProgram = + program_optimize.FusionOptimize(originProgramDesc, can_add_split); + } + if (optimize) { + program.optimizeProgram->Description("optimize: "); + } else { + originProgramDesc->Description("program: "); + } + + paddle_mobile__framework__proto__program_desc__free_unpacked(c_program, NULL); + return program; +} + +template class Loader; +template class Loader; +template class Loader; + +} // namespace paddle_mobile diff --git a/src/io/loader.h b/src/io/loader.h new file mode 100644 index 0000000000000000000000000000000000000000..5e3c53dc9db858f506a13d2105339038340344a6 --- /dev/null +++ b/src/io/loader.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#pragma once + +#include + +#include "common/types.h" +#include "framework/program/program.h" + +namespace paddle_mobile { + +template +class Loader { + public: + /* + * @b load separate format fluid model + * @b 加载分开形式的 fluid 模型 + * */ + const framework::Program Load(const std::string &dirname, + bool optimize = false, + bool can_add_split = false); + + /* + * @b load combine format fluid mode + * @b 加载结合在一起格式的模型 + * */ + const framework::Program Load(const std::string &model_path, + const std::string ¶_path, + bool optimize = false); + + private: + const framework::Program LoadProgram(const std::string &model_path, + bool optimize = false, + bool can_add_split = false); +}; + +} // namespace paddle_mobile diff --git a/src/io/paddle_mobile.cpp b/src/io/paddle_mobile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1fa65032896c8ff3caf866c04cf711ce2416a8b --- /dev/null +++ b/src/io/paddle_mobile.cpp @@ -0,0 +1,85 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +// +// Created by liuRuiLong on 2018/7/2. +// + +#include "io/paddle_mobile.h" + +namespace paddle_mobile { + +template +bool PaddleMobile::Load(const std::string &dirname, bool optimize, + int batch_size) { + if (loader_.get() == nullptr) { + loader_ = std::make_shared>(); + } else { + LOG(kLOG_INFO) << "loader inited"; + } + + if (executor_.get() == nullptr) { + executor_ = std::make_shared>( + loader_->Load(dirname, optimize), batch_size, optimize); + } else { + LOG(kLOG_INFO) << "executor inited"; + } + + return true; +} + +template +bool PaddleMobile::Load(const std::string &model_path, + const std::string ¶_path, bool optimize, + int batch_size) { + if (loader_.get() == nullptr) { + loader_ = std::make_shared>(); + } else { + LOG(kLOG_INFO) << "loader inited"; + } + + if (executor_.get() == nullptr) { + executor_ = std::make_shared>( + loader_->Load(model_path, para_path, optimize), batch_size, optimize); + } else { + LOG(kLOG_INFO) << "executor inited"; + } + + return true; +} + +template +std::shared_ptr PaddleMobile::Predict( + const framework::Tensor &t) { + return executor_->Predict(t); +} + +template +std::vector::Ptype> +PaddleMobile::Predict(const std::vector &input, + const std::vector &dims) { + return executor_->Predict(input, dims); +} + +template +void PaddleMobile::Clear() { + executor_ = nullptr; + loader_ = nullptr; +} + +template class PaddleMobile; +template class PaddleMobile; +template class PaddleMobile; + +} // namespace paddle_mobile diff --git a/src/io/paddle_mobile.h b/src/io/paddle_mobile.h new file mode 100644 index 0000000000000000000000000000000000000000..901f0e00050dfdcc427f98d2296e3bb9b657414d --- /dev/null +++ b/src/io/paddle_mobile.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#pragma once + +#include +#include +#include + +#include "common/types.h" +#include "framework/tensor.h" +#include "io/executor.h" +#include "io/loader.h" + +namespace paddle_mobile { + +template +class PaddleMobile { + typedef typename PrecisionTrait

::ptype Ptype; + + public: + PaddleMobile() {} + /* + * @b load separate format fluid model + * @b 加载分开形式的 fluid 模型 + * */ + bool Load(const std::string &dirname, bool optimize = false, + int batch_size = 1); + + /* + * @b load combine format fluid mode + * @b 加载结合在一起格式的模型 + * */ + bool Load(const std::string &model_path, const std::string ¶_path, + bool optimize = false, int batch_size = 1); + + /* + * @b to predict + * */ + std::shared_ptr Predict(const framework::Tensor &t); + + /* + * @b to predict with vector and dim + * + * @b 使用 输入 和 输入的维度信息 进行预测 + * */ + std::vector Predict(const std::vector &input, + const std::vector &dims); + + void Clear(); + + private: + std::shared_ptr> loader_; + std::shared_ptr> executor_; +}; + +} // namespace paddle_mobile diff --git a/src/jni/paddle_mobile_jni.cpp b/src/jni/paddle_mobile_jni.cpp index f663b78fd490f2c9f0af525c7dabd2cc513c3a53..323d1e37c1c4420f8b0d91cafefa83a98ef9328b 100644 --- a/src/jni/paddle_mobile_jni.cpp +++ b/src/jni/paddle_mobile_jni.cpp @@ -15,6 +15,10 @@ limitations under the License. */ #ifdef ANDROID #include "paddle_mobile_jni.h" +#include "common/log.h" +#include "framework/tensor.h" +#include "io/paddle_mobile.h" + #ifdef __cplusplus extern "C" { #endif @@ -28,17 +32,16 @@ using std::string; extern const char *ANDROID_LOG_TAG = "paddle_mobile LOG built on " __DATE__ " " __TIME__; -static Executor *shared_executor_instance = nullptr; +static PaddleMobile *shared_paddle_mobile_instance = nullptr; // toDo mutex lock // static std::mutex shared_mutex; -Executor *getExecutorInstance(const Program p, int batch_size, - bool use_optimize) { - if (nullptr == shared_executor_instance) { - shared_executor_instance = new Executor(p, batch_size, use_optimize); +PaddleMobile *getPaddleMobileInstance() { + if (nullptr == shared_paddle_mobile_instance) { + shared_paddle_mobile_instance = new PaddleMobile(); } - return shared_executor_instance; + return shared_paddle_mobile_instance; } string jstring2cppstring(JNIEnv *env, jstring jstr) { @@ -51,11 +54,9 @@ string jstring2cppstring(JNIEnv *env, jstring jstr) { JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_load(JNIEnv *env, jclass thiz, jstring modelPath) { - paddle_mobile::Loader loader; bool optimize = true; - auto program = loader.Load(jstring2cppstring(env, modelPath), optimize); - shared_executor_instance = getExecutorInstance(program, 1, optimize); - return shared_executor_instance != nullptr ? JNI_TRUE : JNI_FALSE; + return getPaddleMobileInstance()->Load(jstring2cppstring(env, modelPath), + optimize); } JNIEXPORT jfloatArray JNICALL Java_com_baidu_paddle_PML_predictImage( @@ -73,7 +74,7 @@ JNIEXPORT jfloatArray JNICALL Java_com_baidu_paddle_PML_predictImage( for (int i = 0; i < framework::product(ddim); i++) { input_ptr[i] = dataPointer[i]; } - auto output = shared_executor_instance->Predict(input); + auto output = shared_paddle_mobile_instance->Predict(input); count = output->numel(); result = env->NewFloatArray(count); env->SetFloatArrayRegion(result, 0, count, output->data()); @@ -81,7 +82,9 @@ JNIEXPORT jfloatArray JNICALL Java_com_baidu_paddle_PML_predictImage( } JNIEXPORT void JNICALL Java_com_baidu_paddle_PML_clear(JNIEnv *env, - jclass thiz) {} + jclass thiz) { + getPaddleMobileInstance()->Clear(); +} } // namespace jni } // namespace paddle_mobile diff --git a/src/jni/paddle_mobile_jni.h b/src/jni/paddle_mobile_jni.h index a262d4070c37013977e869fa816d52d78fbfa485..3497144999b028c927aad9a0ffa079044c3bcdf0 100644 --- a/src/jni/paddle_mobile_jni.h +++ b/src/jni/paddle_mobile_jni.h @@ -15,9 +15,6 @@ limitations under the License. */ #pragma once #ifdef ANDROID #include -#include "common/log.h" -#include "framework/tensor.h" -#include "io/io.h" #ifdef __cplusplus extern "C" { diff --git a/src/operators/dropout_op.cpp b/src/operators/dropout_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..709d83a1f57b7faa0ecce1f1f8590c86c1eba1a8 --- /dev/null +++ b/src/operators/dropout_op.cpp @@ -0,0 +1,39 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef DROPOUT_OP +#include "operators/dropout_op.h" +namespace paddle_mobile { +namespace operators { + +template +void DropoutOp::InferShape() const { + auto input_dims = this->param_.InputX()->dims(); + this->param_.Out()->Resize(input_dims); +} +template class DropoutOp; +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; +#ifdef PADDLE_MOBILE_CPU +USE_OP_CPU(dropout); +REGISTER_OPERATOR_CPU(dropout, ops::DropoutOp); +#endif +#ifdef PADDLE_MOBILE_MALI_GPU +#endif +#ifdef PADDLE_MOBILE_FPGA +#endif + +#endif diff --git a/src/operators/dropout_op.h b/src/operators/dropout_op.h new file mode 100644 index 0000000000000000000000000000000000000000..bc2986b791e9069e8782d778a0f16cb639ac4396 --- /dev/null +++ b/src/operators/dropout_op.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef DROPOUT_OP + +#pragma once + +#include + +#include "framework/operator.h" +#include "operators/kernel/dropout_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +using paddle_mobile::framework::Tensor; + +template +class DropoutOp + : public framework::OperatorWithKernel< + DeviceType, DropoutParam, operators::DropoutKernel> { + public: + DropoutOp(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, const framework::AttributeMap attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel>( + type, inputs, outputs, attrs, scope) {} + + // using framework::OperatorWithKernel>; + void InferShape() const override; + + protected: +}; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/im2sequence_op.cpp b/src/operators/im2sequence_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2cb2d6398f85f461bd6214e2631dd0a8f951fb2d --- /dev/null +++ b/src/operators/im2sequence_op.cpp @@ -0,0 +1,65 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef IM2SEQUENCE_OP + +#include "operators/im2sequence_op.h" + +namespace paddle_mobile { +namespace operators { + +int Im2SequenceOutputSize(int input_size, int kernel, int padding_1, + int padding_2, int stride) { + int output_size = + 1 + (padding_1 + padding_2 + input_size - kernel + stride - 1) / stride; + return output_size; +} + +template +void Im2SequenceOp::InferShape() const { + auto in_x_dims = this->param_.Input()->dims(); + + const std::vector &kernels = this->param_.Kernels(); + + const std::vector &strides = this->param_.Strides(); + + std::vector paddings = this->param_.Paddings(); + + std::vector output_shape({in_x_dims[0], in_x_dims[1]}); + for (size_t i = 0; i < strides.size(); ++i) { + output_shape.push_back(Im2SequenceOutputSize(in_x_dims[i + 2], kernels[i], + paddings[i], paddings[i + 2], + strides[i])); + } + + framework::DDim ddim = framework::make_ddim(output_shape); + this->param_.Output()->Resize(ddim); +} + +template class Im2SequenceOp; + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; +#ifdef PADDLE_MOBILE_CPU +USE_OP_CPU(im2sequence); +REGISTER_OPERATOR_CPU(im2sequence, ops::Im2SequenceOp); +#endif +#ifdef PADDLE_MOBILE_MALI_GPU +#endif +#ifdef PADDLE_MOBILE_FPGA +#endif + +#endif diff --git a/src/operators/im2sequence_op.h b/src/operators/im2sequence_op.h new file mode 100644 index 0000000000000000000000000000000000000000..4c4dee617277bcee874d1fcd840c7ddd8fd68cbd --- /dev/null +++ b/src/operators/im2sequence_op.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef IM2SEQUENCE_OP + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/im2sequence_kernel.h" + +namespace paddle_mobile { +namespace operators { + +using namespace framework; + +template +class Im2SequenceOp : public framework::OperatorWithKernel< + DeviceType, Im2SequenceParam, + operators::Im2SequenceKernel> { + public: + Im2SequenceOp(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel< + DeviceType, Im2SequenceParam, + operators::Im2SequenceKernel>(type, inputs, outputs, + attrs, scope) {} + + // using framework::OperatorWithKernel< + // DeviceType, Im2SequenceParam, + // operators::Im2SequenceKernel>::OperatorWithKernel; + void InferShape() const override; + + private: +}; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/arm/box_coder_kernel.cpp b/src/operators/kernel/arm/box_coder_kernel.cpp index fb113b16f53bcd1b9fca7a1dbbf94a846e9a0f81..d2a479391fbbb416eea7d19ae64125cac4637ef1 100644 --- a/src/operators/kernel/arm/box_coder_kernel.cpp +++ b/src/operators/kernel/arm/box_coder_kernel.cpp @@ -15,130 +15,21 @@ limitations under the License. */ #ifdef BOXCODER_OP #include "operators/kernel/box_coder_kernel.h" -#include +#include "operators/kernel/central-arm-func/box_coder_arm_func.h" namespace paddle_mobile { namespace operators { -template -void EncodeCenterSize(const framework::Tensor& target_box, - const framework::Tensor& prior_box, - const framework::Tensor& prior_box_var, T* output) { - int64_t row = target_box.dims()[0]; - int64_t col = prior_box.dims()[0]; - int64_t len = prior_box.dims()[1]; - auto* target_box_data = target_box.data(); - auto* prior_box_data = prior_box.data(); - auto* prior_box_var_data = prior_box_var.data(); - - for (int64_t i = 0; i < row; ++i) { - for (int64_t j = 0; j < col; ++j) { - T prior_box_width = prior_box_data[j * len + 2] - prior_box_data[j * len]; - T prior_box_height = - prior_box_data[j * len + 3] - prior_box_data[j * len + 1]; - T prior_box_center_x = - (prior_box_data[j * len + 2] + prior_box_data[j * len]) / 2; - T prior_box_center_y = - (prior_box_data[j * len + 3] + prior_box_data[j * len + 1]) / 2; - - T target_box_center_x = - (target_box_data[i * len + 2] + target_box_data[i * len]) / 2; - T target_box_center_y = - (target_box_data[i * len + 3] + target_box_data[i * len + 1]) / 2; - T target_box_width = - target_box_data[i * len + 2] - target_box_data[i * len]; - T target_box_height = - target_box_data[i * len + 3] - target_box_data[i * len + 1]; - - size_t offset = i * col * len + j * len; - output[offset] = (target_box_center_x - prior_box_center_x) / - prior_box_width / prior_box_var_data[j * len]; - output[offset + 1] = (target_box_center_y - prior_box_center_y) / - prior_box_height / prior_box_var_data[j * len + 1]; - output[offset + 2] = - std::log(std::fabs(target_box_width / prior_box_width)) / - prior_box_var_data[j * len + 2]; - output[offset + 3] = - std::log(std::fabs(target_box_height / prior_box_height)) / - prior_box_var_data[j * len + 3]; - } - } -} - -template -void DecodeCenterSize(const framework::Tensor& target_box, - const framework::Tensor& prior_box, - const framework::Tensor& prior_box_var, T* output) { - int64_t row = target_box.dims()[0]; - int64_t col = prior_box.dims()[0]; - int64_t len = prior_box.dims()[1]; - - auto* target_box_data = target_box.data(); - auto* prior_box_data = prior_box.data(); - auto* prior_box_var_data = prior_box_var.data(); - - for (int64_t i = 0; i < row; ++i) { - for (int64_t j = 0; j < col; ++j) { - size_t offset = i * col * len + j * len; - T prior_box_width = prior_box_data[j * len + 2] - prior_box_data[j * len]; - T prior_box_height = - prior_box_data[j * len + 3] - prior_box_data[j * len + 1]; - T prior_box_center_x = - (prior_box_data[j * len + 2] + prior_box_data[j * len]) / 2; - T prior_box_center_y = - (prior_box_data[j * len + 3] + prior_box_data[j * len + 1]) / 2; - - T target_box_center_x = prior_box_var_data[j * len] * - target_box_data[offset] * prior_box_width + - prior_box_center_x; - T target_box_center_y = prior_box_var_data[j * len + 1] * - target_box_data[offset + 1] * - prior_box_height + - prior_box_center_y; - T target_box_width = std::exp(prior_box_var_data[j * len + 2] * - target_box_data[offset + 2]) * - prior_box_width; - T target_box_height = std::exp(prior_box_var_data[j * len + 3] * - target_box_data[offset + 3]) * - prior_box_height; - - output[offset] = target_box_center_x - target_box_width / 2; - output[offset + 1] = target_box_center_y - target_box_height / 2; - output[offset + 2] = target_box_center_x + target_box_width / 2; - output[offset + 3] = target_box_center_y + target_box_height / 2; - } - } -} - template <> -bool BoxCoderKernel::Init(BoxCoderParam* param) { +bool BoxCoderKernel::Init(BoxCoderParam *param) { return true; } template <> -void BoxCoderKernel::Compute(const BoxCoderParam& param) const { - const auto* input_priorbox = param.InputPriorBox(); - const auto* input_priorboxvar = param.InputPriorBoxVar(); - const auto* input_targetbox = param.InputTargetBox(); - - const auto& code_type = param.CodeType(); - - auto row = input_targetbox->dims()[0]; - auto col = input_priorbox->dims()[0]; - auto len = input_priorbox->dims()[1]; - - Tensor* output_box = param.OutputBox(); - auto* output_box_dataptr = output_box->mutable_data({row, col, len}); - - if (code_type == "encode_center_size") { - EncodeCenterSize(*input_targetbox, *input_priorbox, - *input_priorboxvar, output_box_dataptr); - } - if (code_type == "decode_center_size") { - DecodeCenterSize(*input_targetbox, *input_priorbox, - *input_priorboxvar, output_box_dataptr); - } +void BoxCoderKernel::Compute(const BoxCoderParam ¶m) const { + BoxCoderCompute(param); } + } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/kernel/arm/concat_kernel.cpp b/src/operators/kernel/arm/concat_kernel.cpp index 5daf3e104a04025165ce7281f3a16d8e3f9cb522..b6810bf76946bfb8151f3001b76fcbaa5e99e5fc 100644 --- a/src/operators/kernel/arm/concat_kernel.cpp +++ b/src/operators/kernel/arm/concat_kernel.cpp @@ -15,42 +15,10 @@ limitations under the License. */ #ifdef CONCAT_OP #include "operators/kernel/concat_kernel.h" +#include "operators/kernel/central-arm-func/concat_arm_func.h" namespace paddle_mobile { namespace operators { -template -class ConcatFunctor { - public: - void operator()(const std::vector &input, const int axis, - framework::Tensor *output) { - size_t num = input.size(); - int rows = 1; - auto dim_0 = input[0].dims(); - for (int i = 0; i < axis; ++i) { - rows *= dim_0[i]; - } - int out_rows = rows, out_cols = 0; - - std::vector input_cols(input.size()); - for (int i = 0; i < num; ++i) { - int t_cols = input[i].numel() / rows; - out_cols += t_cols; - input_cols[i] = t_cols; - } - - // computation - for (int k = 0; k < out_rows; ++k) { - T *dst_ptr = output->data() + k * out_cols; - int col_idx = 0; - for (int j = 0; j < num; ++j) { - int col_len = input_cols[j]; - const T *src_prt = input[j].data() + k * col_len; - memory::Copy(dst_ptr + col_idx, src_prt, sizeof(T) * col_len); - col_idx += col_len; - } - } - } -}; template <> bool ConcatKernel::Init(ConcatParam *param) { @@ -59,33 +27,7 @@ bool ConcatKernel::Init(ConcatParam *param) { template <> void ConcatKernel::Compute(const ConcatParam ¶m) const { - auto inputs = param.Inputs(); - auto *out = param.Out(); - int64_t axis = param.Axis(); - out->mutable_data(); - - /// Sometimes direct copies will be faster, this maybe need deeply analysis. - if (axis == 0 && inputs.size() < 10) { - size_t output_offset = 0; - for (auto *in : inputs) { - auto in_stride = framework::stride_numel(in->dims()); - auto out_stride = framework::stride_numel(out->dims()); - auto dst = out->data() + output_offset; - auto src = in->data(); - PADDLE_MOBILE_ENFORCE( - in_stride.size() == out_stride.size(), - "src and dst tensor should have the same dims size."); - memory::Copy(dst, src, sizeof(float) * in_stride[0]); - output_offset += in_stride[0]; - } - } else { - std::vector inputs_concat(inputs.size()); - for (int j = 0; j < inputs.size(); ++j) { - inputs_concat[j] = *inputs[j]; - } - ConcatFunctor concat_functor; - concat_functor(inputs_concat, static_cast(axis), out); - } + ConcatCompute(param); } } // namespace operators diff --git a/src/operators/kernel/arm/conv_add_bn_relu_kernel.cpp b/src/operators/kernel/arm/conv_add_bn_relu_kernel.cpp index e95bd8e76c5034f3897eff81e0ba67119d04a95b..1fd1c66d4dc92a9918243b23e400ef5309422050 100644 --- a/src/operators/kernel/arm/conv_add_bn_relu_kernel.cpp +++ b/src/operators/kernel/arm/conv_add_bn_relu_kernel.cpp @@ -22,11 +22,11 @@ namespace operators { template <> bool ConvAddBNReluKernel::Init(FusionConvAddBNReluParam *param) { - const Tensor *mean = (*param).InputMean(); - const Tensor *variance = (*param).InputVariance(); - const Tensor *scale = (*param).InputScale(); - const Tensor *bias = (*param).InputBias(); - const float epsilon = (*param).Epsilon(); + const Tensor *mean = param->InputMean(); + const Tensor *variance = param->InputVariance(); + const Tensor *scale = param->InputScale(); + const Tensor *bias = param->InputBias(); + const float epsilon = param->Epsilon(); auto mean_ptr = mean->data(); auto variance_ptr = variance->data(); @@ -47,8 +47,8 @@ bool ConvAddBNReluKernel::Init(FusionConvAddBNReluParam *param) { new_scale_ptr[i] = inv_std_ptr[i] * scale_ptr[i]; new_bias_ptr[i] = bias_ptr[i] - mean_ptr[i] * inv_std_ptr[i] * scale_ptr[i]; } - (*param).SetNewScale(new_scale); - (*param).SetNewBias(new_bias); + param->SetNewScale(new_scale); + param->SetNewBias(new_bias); return true; } diff --git a/src/operators/kernel/arm/dropout_kernel.cpp b/src/operators/kernel/arm/dropout_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af16048a1b4eba2ff36f842b6cf968031989576e --- /dev/null +++ b/src/operators/kernel/arm/dropout_kernel.cpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef DROPOUT_OP + +#pragma once + +#include "operators/kernel/dropout_kernel.h" +#include + +namespace paddle_mobile { +namespace operators { + +template <> +bool DropoutKernel::Init(DropoutParam *para) { + return true; +} + +template +struct DropoutFunctor { + inline T operator()(T in) const { return in; } +}; + +template <> +void DropoutKernel::Compute(const DropoutParam ¶m) const { + const auto *input_x = param.InputX(); + auto *input_x_ptr = input_x->data(); + auto *out = param.Out(); + auto *out_ptr = out->mutable_data(); + + DropoutFunctor func_; + math::Transform trans; + trans(input_x_ptr, input_x_ptr + input_x->numel(), out_ptr, func_); +} +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/arm/elementwise_add_kernel.cpp b/src/operators/kernel/arm/elementwise_add_kernel.cpp index bd9bb26d299bd340074965e41e5658df86bab347..fdab1c60a310480d8e59f3f84802001ea592433a 100644 --- a/src/operators/kernel/arm/elementwise_add_kernel.cpp +++ b/src/operators/kernel/arm/elementwise_add_kernel.cpp @@ -14,18 +14,12 @@ limitations under the License. */ #ifdef ELEMENTWISEADD_OP -#pragma once - #include "operators/kernel/elementwise_add_kernel.h" +#include "operators/kernel/central-arm-func/elementwise_add_arm_func.h" namespace paddle_mobile { namespace operators { -template -struct AddFunctor { - inline T operator()(T a, T b) const { return a + b; } -}; - template <> bool ElementwiseAddKernel::Init(ElementwiseAddParam *param) { return true; @@ -34,17 +28,9 @@ bool ElementwiseAddKernel::Init(ElementwiseAddParam *param) { template <> void ElementwiseAddKernel::Compute( const ElementwiseAddParam ¶m) const { - const Tensor *input_x = param.InputX(); - const Tensor *input_y = param.InputY(); - Tensor *Out = param.Out(); - Out->mutable_data(); - int axis = param.Axis(); - ElementwiseComputeEx, float>(input_x, input_y, axis, - AddFunctor(), Out); + ElementwiseAddCompute(param); } -template class ElementwiseAddKernel; - } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/kernel/arm/fusion_fc_kernel.cpp b/src/operators/kernel/arm/fusion_fc_kernel.cpp index e10f11c0b19edf710ffc45f199f096bea0a34b7d..c72960e67f19c601e6f27a3bedf7123c80875e0c 100644 --- a/src/operators/kernel/arm/fusion_fc_kernel.cpp +++ b/src/operators/kernel/arm/fusion_fc_kernel.cpp @@ -14,9 +14,8 @@ limitations under the License. */ #ifdef FUSION_FC_OP -#pragma once - #include "operators/kernel/fusion_fc_kernel.h" +#include "operators/kernel/central-arm-func/fusion_fc_arm_func.h" namespace paddle_mobile { namespace operators { @@ -28,46 +27,7 @@ bool FusionFcKernel::Init(FusionFcParam *param) { template <> void FusionFcKernel::Compute(const FusionFcParam ¶m) const { - const Tensor *input_x = param.InputX(); - const Tensor *input_y = param.InputY(); - const Tensor *input_z = param.InputZ(); - auto *input_z_data = input_z->data(); - int axis = param.Axis(); - Tensor *out = param.Out(); - auto *out_data = out->mutable_data(); - const Tensor x_matrix = - input_x->dims().size() > 2 - ? framework::ReshapeToMatrix(*input_x, param.XNumColDims()) - : *input_x; - const Tensor y_matrix = - input_y->dims().size() > 2 - ? framework::ReshapeToMatrix(*input_y, param.YNumColDims()) - : *input_y; - auto out_dim = out->dims(); - if (out_dim.size() != 2) { - out->Resize({x_matrix.dims()[0], y_matrix.dims()[1]}); - } - PADDLE_MOBILE_ENFORCE(out_dim.size() == 2, " out_dim.size must be 2."); - PADDLE_MOBILE_ENFORCE(input_z->dims().size() == 1, "inpu_z size must be 1"); - PADDLE_MOBILE_ENFORCE(out_dim[1] == input_z->dims()[0], - " out_dim.size must be 2."); - axis = (axis == -1 ? out_dim.size() - input_z->dims().size() : axis); - PADDLE_MOBILE_ENFORCE(axis == 1, " to fit broadcast, axis = 1. ") - - int64_t classes = input_z->numel(); - for (int i = 0; i < out_dim[0]; i++) { - memory::Copy(out_data + i * classes, input_z_data, sizeof(float) * classes); - } - - for (int i = 0; i < out->numel(); i++) { - DLOG << out_data[i]; - } - math::matmul(x_matrix, false, y_matrix, false, static_cast(1), - out, static_cast(1)); - PADDLE_MOBILE_ENFORCE(out_dim.size() == 2, " out_dim.size must be 2."); - // if (out_dim.size() != 2) { - // out->Resize(out_dim); - // } + FusionFcCompute(param); } } // namespace operators diff --git a/src/operators/kernel/arm/im2sequence_kernel.cpp b/src/operators/kernel/arm/im2sequence_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..709fa30a23d4efba3531d9bc567c99f53875bc12 --- /dev/null +++ b/src/operators/kernel/arm/im2sequence_kernel.cpp @@ -0,0 +1,78 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef IM2SEQUENCE_OP + +#include "operators/kernel/im2sequence_kernel.h" + +namespace paddle_mobile { +namespace operators { + +template <> +bool Im2SequenceKernel::Init(Im2SequenceParam *para) { + return true; +} + +inline int Im2SeqOutputSize(int input_size, int filter_size, int padding_0, + int padding_1, int stride) { + const int output_size = + (input_size + padding_0 + padding_1 - filter_size) / stride + 1; + return output_size; +} + +template <> +void Im2SequenceKernel::Compute( + const Im2SequenceParam ¶m) const { + const Tensor *in_x = param.Input(); + Tensor *out = param.Output(); + out->mutable_data(); + + std::vector kernels = param.Kernels(); + std::vector strides = param.Strides(); + std::vector paddings = param.Paddings(); + + auto in_x_dim = in_x->dims(); + const int batch_size = static_cast(in_x_dim[0]); + const int img_channels = static_cast(in_x_dim[1]); + const int img_height = static_cast(in_x_dim[2]); + const int img_width = static_cast(in_x_dim[3]); + + int output_height = Im2SeqOutputSize(img_height, kernels[0], paddings[0], + paddings[2], strides[0]); + int output_width = Im2SeqOutputSize(img_width, kernels[1], paddings[1], + paddings[3], strides[1]); + const std::vector dilations({1, 1}); + + // TODO: verify + auto out_dims = out->dims(); + out->Resize({batch_size, out->numel() / batch_size}); + + for (int i = 0; i < batch_size; i++) { + const Tensor src = + in_x->Slice(i, i + 1).Resize({img_channels, img_height, img_width}); + Tensor dst = out->Slice(i, i + 1).Resize( + {output_height, output_width, img_channels, kernels[0], kernels[1]}); + + math::Im2ColFunctor f; + f(src, dilations, strides, paddings, &dst); + } + out->Resize(out_dims); +} + +template class Im2SequenceKernel; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/arm/lrn_kernel.cpp b/src/operators/kernel/arm/lrn_kernel.cpp index 356aa388276d9d0359b1a6b3a45c86bcb822fd9e..0c20c5167adee5165067cc5ab4935df255751755 100644 --- a/src/operators/kernel/arm/lrn_kernel.cpp +++ b/src/operators/kernel/arm/lrn_kernel.cpp @@ -14,9 +14,8 @@ limitations under the License. */ #ifdef LRN_OP -#pragma once - #include "operators/kernel/lrn_kernel.h" +#include "operators/kernel/central-arm-func/lrn_arm_func.h" namespace paddle_mobile { namespace operators { @@ -28,26 +27,9 @@ bool LrnKernel::Init(LrnParam *param) { template <> void LrnKernel::Compute(const LrnParam ¶m) const { - const Tensor *input_x = param.InputX(); - auto x_dims = input_x->dims(); - Tensor *out = param.Out(); - out->mutable_data(); - /// data_format = NCHW - const int N = x_dims[0]; - const int C = x_dims[1]; - const int H = x_dims[2]; - const int W = x_dims[3]; - - const int n = param.N(); - const float alpha = param.Alpha(); - const float beta = param.Beta(); - const float k = param.K(); - LRNFunctor lrnFunctor; - lrnFunctor(*input_x, out, N, C, H, W, n, k, alpha, beta); + LrnCompute(param); } -template class LrnKernel; - } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/kernel/arm/mul_kernel.cpp b/src/operators/kernel/arm/mul_kernel.cpp index 99b6576d364671be78efa9a8f2ebf85a6e133f33..ac5010ce5492ae1d99e59bfa761e22bb3aa5d1c9 100644 --- a/src/operators/kernel/arm/mul_kernel.cpp +++ b/src/operators/kernel/arm/mul_kernel.cpp @@ -14,9 +14,8 @@ limitations under the License. */ #ifdef MUL_OP -#pragma once - #include "operators/kernel/mul_kernel.h" +#include "operators/kernel/central-arm-func/mul_arm_func.h" namespace paddle_mobile { namespace operators { @@ -28,31 +27,9 @@ bool MulKernel::Init(MulParam *param) { template <> void MulKernel::Compute(const MulParam ¶m) const { - const Tensor *input_x = param.InputX(); - const Tensor *input_y = param.InputY(); - Tensor *out = param.Out(); - out->mutable_data(); - const Tensor x_matrix = - input_x->dims().size() > 2 - ? framework::ReshapeToMatrix(*input_x, param.XNumColDims()) - : *input_x; - const Tensor y_matrix = - input_y->dims().size() > 2 - ? framework::ReshapeToMatrix(*input_y, param.YNumColDims()) - : *input_y; - auto out_dim = out->dims(); - if (out_dim.size() != 2) { - out->Resize({x_matrix.dims()[0], y_matrix.dims()[1]}); - } - math::matmul(x_matrix, false, y_matrix, false, static_cast(1), - out, static_cast(0)); - if (out_dim.size() != 2) { - out->Resize(out_dim); - } + MulCompute(param); } -template class MulKernel; - } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/kernel/arm/multiclass_nms_kernel.cpp b/src/operators/kernel/arm/multiclass_nms_kernel.cpp index ecdc60f77b0cad3af2e8b026ab3666394dc43fee..9ed8f1731afe2bab723c66ea1e2e8c5042f6ce28 100644 --- a/src/operators/kernel/arm/multiclass_nms_kernel.cpp +++ b/src/operators/kernel/arm/multiclass_nms_kernel.cpp @@ -15,265 +15,20 @@ limitations under the License. */ #ifdef MULTICLASSNMS_OP #include "operators/kernel/multiclass_nms_kernel.h" -#include +#include "operators/kernel/central-arm-func/multiclass_nms_arm_func.h" + namespace paddle_mobile { namespace operators { -constexpr int kOutputDim = 6; -constexpr int kBBoxSize = 4; - -template -bool SortScorePairDescend(const std::pair& pair1, - const std::pair& pair2) { - return pair1.first > pair2.first; -} - -template -static inline void GetMaxScoreIndex( - const std::vector& scores, const T threshold, int top_k, - std::vector>* sorted_indices) { - for (size_t i = 0; i < scores.size(); ++i) { - if (scores[i] > threshold) { - sorted_indices->push_back(std::make_pair(scores[i], i)); - } - } - // Sort the score pair according to the scores in descending order - std::stable_sort(sorted_indices->begin(), sorted_indices->end(), - SortScorePairDescend); - // Keep top_k scores if needed. - if (top_k > -1 && top_k < static_cast(sorted_indices->size())) { - sorted_indices->resize(top_k); - } -} - -template -static inline T BBoxArea(const T* box, const bool normalized) { - if (box[2] < box[0] || box[3] < box[1]) { - // If coordinate values are is invalid - // (e.g. xmax < xmin or ymax < ymin), return 0. - return static_cast(0.); - } else { - const T w = box[2] - box[0]; - const T h = box[3] - box[1]; - if (normalized) { - return w * h; - } else { - // If coordinate values are not within range [0, 1]. - return (w + 1) * (h + 1); - } - } -} - -template -static inline T JaccardOverlap(const T* box1, const T* box2, - const bool normalized) { - if (box2[0] > box1[2] || box2[2] < box1[0] || box2[1] > box1[3] || - box2[3] < box1[1]) { - return static_cast(0.); - } else { - const T inter_xmin = std::max(box1[0], box2[0]); - const T inter_ymin = std::max(box1[1], box2[1]); - const T inter_xmax = std::min(box1[2], box2[2]); - const T inter_ymax = std::min(box1[3], box2[3]); - const T inter_w = inter_xmax - inter_xmin; - const T inter_h = inter_ymax - inter_ymin; - const T inter_area = inter_w * inter_h; - const T bbox1_area = BBoxArea(box1, normalized); - const T bbox2_area = BBoxArea(box2, normalized); - return inter_area / (bbox1_area + bbox2_area - inter_area); - } -} - -template -static inline void NMSFast(const Tensor& bbox, const Tensor& scores, - const T score_threshold, const T nms_threshold, - const T eta, const int64_t top_k, - std::vector* selected_indices) { - // The total boxes for each instance. - int64_t num_boxes = bbox.dims()[0]; - // 4: [xmin ymin xmax ymax] - int64_t box_size = bbox.dims()[1]; - - std::vector scores_data(num_boxes); - std::copy_n(scores.data(), num_boxes, scores_data.begin()); - std::vector> sorted_indices; - GetMaxScoreIndex(scores_data, score_threshold, top_k, &sorted_indices); - - selected_indices->clear(); - T adaptive_threshold = nms_threshold; - const T* bbox_data = bbox.data(); - - while (sorted_indices.size() != 0) { - const int idx = sorted_indices.front().second; - bool keep = true; - for (size_t k = 0; k < selected_indices->size(); ++k) { - if (keep) { - const int kept_idx = (*selected_indices)[k]; - T overlap = JaccardOverlap(bbox_data + idx * box_size, - bbox_data + kept_idx * box_size, true); - keep = overlap <= adaptive_threshold; - } else { - break; - } - } - if (keep) { - selected_indices->push_back(idx); - } - sorted_indices.erase(sorted_indices.begin()); - if (keep && eta < 1 && adaptive_threshold > 0.5) { - adaptive_threshold *= eta; - } - } -} - -template -void MultiClassNMS(const Tensor& scores, const Tensor& bboxes, - std::map>* indices, int* num_nmsed_out, - const int& background_label, const int& nms_top_k, - const int& keep_top_k, const T& nms_threshold, - const T& nms_eta, const T& score_threshold) { - int64_t class_num = scores.dims()[0]; - int64_t predict_dim = scores.dims()[1]; - int num_det = 0; - for (int64_t c = 0; c < class_num; ++c) { - if (c == background_label) continue; - Tensor score = scores.Slice(c, c + 1); - /// [c] is key - NMSFast(bboxes, score, score_threshold, nms_threshold, nms_eta, - nms_top_k, &((*indices)[c])); - num_det += (*indices)[c].size(); - } - - *num_nmsed_out = num_det; - const T* scores_data = scores.data(); - if (keep_top_k > -1 && num_det > keep_top_k) { - std::vector>> score_index_pairs; - for (const auto& it : *indices) { - int label = it.first; - const T* sdata = scores_data + label * predict_dim; - const std::vector& label_indices = it.second; - for (size_t j = 0; j < label_indices.size(); ++j) { - int idx = label_indices[j]; - // PADDLE_ENFORCE_LT(idx, predict_dim); - score_index_pairs.push_back( - std::make_pair(sdata[idx], std::make_pair(label, idx))); - } - } - // Keep top k results per image. - std::stable_sort(score_index_pairs.begin(), score_index_pairs.end(), - SortScorePairDescend>); - score_index_pairs.resize(keep_top_k); - - // Store the new indices. - std::map> new_indices; - for (size_t j = 0; j < score_index_pairs.size(); ++j) { - int label = score_index_pairs[j].second.first; - int idx = score_index_pairs[j].second.second; - new_indices[label].push_back(idx); - } - new_indices.swap(*indices); - *num_nmsed_out = keep_top_k; - } -} - -template -void MultiClassOutput(const Tensor& scores, const Tensor& bboxes, - const std::map>& selected_indices, - Tensor* outs) { - int predict_dim = scores.dims()[1]; - auto* scores_data = scores.data(); - auto* bboxes_data = bboxes.data(); - auto* odata = outs->data(); - - int count = 0; - for (const auto& it : selected_indices) { - /// one batch - int label = it.first; - const T* sdata = scores_data + label * predict_dim; - const std::vector& indices = it.second; - for (size_t j = 0; j < indices.size(); ++j) { - int idx = indices[j]; - const T* bdata = bboxes_data + idx * kBBoxSize; - odata[count * kOutputDim] = label; // label - odata[count * kOutputDim + 1] = sdata[idx]; // score - // xmin, ymin, xmax, ymax - std::memcpy(odata + count * kOutputDim + 2, bdata, 4 * sizeof(T)); - count++; - } - } -} - template <> -bool MultiClassNMSKernel::Init(MultiClassNMSParam* param) { +bool MultiClassNMSKernel::Init(MultiClassNMSParam *param) { return true; } template <> void MultiClassNMSKernel::Compute( - const MultiClassNMSParam& param) const { - const auto* input_bboxes = param.InputBBoxes(); - const auto& input_bboxes_dims = input_bboxes->dims(); - - const auto* input_scores = param.InputScores(); - const auto& input_scores_dims = input_scores->dims(); - - auto* outs = param.Out(); - auto background_label = param.BackGroundLabel(); - auto nms_top_k = param.NMSTopK(); - auto keep_top_k = param.KeepTopK(); - auto nms_threshold = param.NMSThreshold(); - auto nms_eta = param.NMSEta(); - auto score_threshold = param.ScoreThreshold(); - - int64_t batch_size = input_scores_dims[0]; - int64_t class_num = input_scores_dims[1]; - int64_t predict_dim = input_scores_dims[2]; - int64_t box_dim = input_bboxes_dims[2]; - - std::vector>> all_indices; - std::vector batch_starts = {0}; - for (int64_t i = 0; i < batch_size; ++i) { - Tensor ins_score = input_scores->Slice(i, i + 1); - ins_score.Resize({class_num, predict_dim}); - - Tensor ins_boxes = input_bboxes->Slice(i, i + 1); - ins_boxes.Resize({predict_dim, box_dim}); - - std::map> indices; - int num_nmsed_out = 0; - MultiClassNMS(ins_score, ins_boxes, &indices, &num_nmsed_out, - background_label, nms_top_k, keep_top_k, nms_threshold, - nms_eta, score_threshold); - all_indices.push_back(indices); - batch_starts.push_back(batch_starts.back() + num_nmsed_out); - } - - int num_kept = batch_starts.back(); - if (num_kept == 0) { - float* od = outs->mutable_data({1}); - od[0] = -1; - } else { - outs->mutable_data({num_kept, kOutputDim}); - for (int64_t i = 0; i < batch_size; ++i) { - Tensor ins_score = input_scores->Slice(i, i + 1); - ins_score.Resize({class_num, predict_dim}); - - Tensor ins_boxes = input_bboxes->Slice(i, i + 1); - ins_boxes.Resize({predict_dim, box_dim}); - - int64_t s = batch_starts[i]; - int64_t e = batch_starts[i + 1]; - if (e > s) { - Tensor out = outs->Slice(s, e); - MultiClassOutput(ins_score, ins_boxes, all_indices[i], &out); - } - } - } - - // framework::LoD lod; - // lod.emplace_back(batch_starts); - // - // outs->set_lod(lod); + const MultiClassNMSParam ¶m) const { + MultiClassNMSCompute(param); } } // namespace operators diff --git a/src/operators/kernel/arm/prior_box_kernel.cpp b/src/operators/kernel/arm/prior_box_kernel.cpp index 32d3818ef244e4c2879167b4273b0538eef08c56..217d4b83cb1156a0e942c5ced5917546250e8bb1 100644 --- a/src/operators/kernel/arm/prior_box_kernel.cpp +++ b/src/operators/kernel/arm/prior_box_kernel.cpp @@ -15,17 +15,11 @@ limitations under the License. */ #ifdef PRIORBOX_OP #include "operators/kernel/prior_box_kernel.h" +#include "operators/kernel/central-arm-func/prior_box_arm_func.h" namespace paddle_mobile { namespace operators { -template -struct ClipFunctor { - inline T operator()(T in) const { - return std::min(std::max(in, 0.), 1.); - } -}; - template <> bool PriorBoxKernel::Init(PriorBoxParam *param) { return true; @@ -33,117 +27,7 @@ bool PriorBoxKernel::Init(PriorBoxParam *param) { template <> void PriorBoxKernel::Compute(const PriorBoxParam ¶m) const { - const auto *input_ = param.Input(); - const auto &input_dims = input_->dims(); - - const auto *input_image = param.InputImage(); - const auto &input_image_dims = input_image->dims(); - - const auto &min_sizes = param.MinSizes(); - const auto &max_sizes = param.MaxSizes(); - const auto &variances = param.Variances(); - const auto &input_aspect_ratio = param.AspectRatios(); - const bool &flip = param.Flip(); - const bool &clip = param.Clip(); - const float &step_w = param.StepW(); - const float &step_h = param.StepH(); - const float &offset = param.Offset(); - - Tensor *output_boxes = param.OutputBoxes(); - auto output_boxes_dataptr = output_boxes->mutable_data(); - Tensor *output_variances = param.OutputVariances(); - auto output_variances_dataptr = output_variances->mutable_data(); - - std::vector aspect_ratios; - ExpandAspectRatios(input_aspect_ratio, flip, &aspect_ratios); - - auto img_width = input_image_dims[3]; - auto img_height = input_image_dims[2]; - - auto feature_width = input_dims[3]; - auto feature_height = input_dims[2]; - - auto stride0 = output_boxes->dims()[1] * output_boxes->dims()[2] * - output_boxes->dims()[3]; - auto stride1 = output_boxes->dims()[2] * output_boxes->dims()[3]; - auto stride2 = output_boxes->dims()[3]; - - float step_width, step_height; - /// 300 / 19 - if (step_w == 0 || step_h == 0) { - step_width = static_cast(img_width) / feature_width; - step_height = static_cast(img_height) / feature_height; - } else { - step_width = step_w; - step_height = step_h; - } - - int num_priors = aspect_ratios.size() * min_sizes.size(); - if (!max_sizes.empty()) { - num_priors += max_sizes.size(); - } - - for (int h = 0; h < feature_height; ++h) { - for (int w = 0; w < feature_width; ++w) { - /// map origin image - float center_x = (w + offset) * step_width; - float center_y = (h + offset) * step_height; - float box_width, box_height; - int idx = 0; - for (size_t s = 0; s < min_sizes.size(); ++s) { - auto min_size = min_sizes[s]; - // priors with different aspect ratios - for (float ar : aspect_ratios) { - box_width = min_size * sqrt(ar) / 2.; - box_height = min_size / sqrt(ar) / 2.; - /// box_width/2 , / img_width 为了得到feature map 相对于 - /// 原图的归一化位置的比例。 - output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 0] = - (center_x - box_width) / img_width; - output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 1] = - (center_y - box_height) / img_height; - output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 2] = - (center_x + box_width) / img_width; - output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 3] = - (center_y + box_height) / img_height; - idx++; - } - if (!max_sizes.empty()) { - auto max_size = max_sizes[s]; - // square prior with size sqrt(minSize * maxSize) - box_width = box_height = sqrt(min_size * max_size) / 2.; - output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 0] = - (center_x - box_width) / img_width; - output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 1] = - (center_y - box_height) / img_height; - output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 2] = - (center_x + box_width) / img_width; - output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 3] = - (center_y + box_height) / img_height; - idx++; - } - } - } - } - if (clip) { - math::Transform trans; - ClipFunctor clip_func; - trans(output_boxes_dataptr, output_boxes_dataptr + output_boxes->numel(), - output_boxes_dataptr, clip_func); - } - - if ((variances.size() != 4)) { - LOG(kLOG_ERROR) << " variances.size() must be 4."; - } - - int64_t box_num = feature_height * feature_width * num_priors; - - for (int i = 0; i < box_num; i++) { - output_variances_dataptr[4 * i] = variances[0]; - output_variances_dataptr[4 * i + 1] = variances[1]; - output_variances_dataptr[4 * i + 2] = variances[2]; - output_variances_dataptr[4 * i + 3] = variances[3]; - } + PriorBoxCompute(param); } } // namespace operators diff --git a/src/operators/kernel/arm/relu_kernel.cpp b/src/operators/kernel/arm/relu_kernel.cpp index f6480dea75289cf6615a9737acfd913a3cb13008..63259a0c303f5e186f9eb90b98f2a8685f8ba5ca 100644 --- a/src/operators/kernel/arm/relu_kernel.cpp +++ b/src/operators/kernel/arm/relu_kernel.cpp @@ -15,98 +15,21 @@ limitations under the License. */ #ifdef RELU_OP #include "operators/kernel/relu_kernel.h" -#include +#include "operators/kernel/central-arm-func/relu_arm_func.h" namespace paddle_mobile { namespace operators { -template -struct ReluFunctor { - inline T operator()(T in) const { return in > 0 ? in : 0; } -}; - template <> bool ReluKernel::Init(ReluParam *param) { return true; } -/* - * @b 特化到具体平台的实现, param 从 op 层传入 - * */ template <> void ReluKernel::Compute(const ReluParam ¶m) const { - const auto *input_x = param.InputX(); - auto *input_x_ptr = input_x->data(); - auto *out = param.Out(); - auto *out_ptr = out->mutable_data(); - - int numel = input_x->numel(); - // if (numel > 64) { - // asm volatile( - // "pld [%[input_x_ptr], #0] \n\t" - // "vmov.f32 q8, #0.0 \n\t" - // "subs %[num], %[num], #32 \n\t" - // "blt end_num_%= \n\t" - // "loop_num_%=: \n\t" - // "pld [%[input_x_ptr], #1024] \n\t" - // - // "vld1.32 {q0, q1}, [%[input_x_ptr]]! \n\t" - // "vld1.32 {q2, q3}, [%[input_x_ptr]]! \n\t" - // "vld1.32 {q4, q5}, [%[input_x_ptr]]! \n\t" - // "vld1.32 {q6, q7}, [%[input_x_ptr]]! \n\t" - // - // "vmax.f32 q0, q0, q8 \n\t" - // "vmax.f32 q1, q1, q8 \n\t" - // "vmax.f32 q2, q2, q8 \n\t" - // "vmax.f32 q3, q3, q8 \n\t" - // "vmax.f32 q4, q4, q8 \n\t" - // "vmax.f32 q5, q5, q8 \n\t" - // "vmax.f32 q6, q6, q8 \n\t" - // "vmax.f32 q7, q7, q8 \n\t" - // - // "vst1.32 {q0, q1}, [%[out_ptr]]! \n\t" - // "vst1.32 {q2, q3}, [%[out_ptr]]! \n\t" - // "vst1.32 {q4, q5}, [%[out_ptr]]! \n\t" - // "vst1.32 {q6, q7}, [%[out_ptr]]! \n\t" - // - // "subs %[num], %[num], #32 \n\t" - // "bge loop_num_%= \n\t" - // "end_num_%=: \n\t" - // "cmp %[num], #0 \n\t" - // "bge end_%= \n\t" - // "mov r6, #4 \n\t" - // "mul r5, %[num], r6 \n\t" - // "add %[input_x_ptr], %[input_x_ptr], r5 \n\t" - // "vld1.32 {q0, q1}, [%[input_x_ptr]]! \n\t" - // "vld1.32 {q2, q3}, [%[input_x_ptr]]! \n\t" - // "vld1.32 {q4, q5}, [%[input_x_ptr]]! \n\t" - // "vld1.32 {q6, q7}, [%[input_x_ptr]]! \n\t" - // "vmax.f32 q0, q0, q8 \n\t" - // "vmax.f32 q1, q1, q8 \n\t" - // "vmax.f32 q2, q2, q8 \n\t" - // "vmax.f32 q3, q3, q8 \n\t" - // "vmax.f32 q4, q4, q8 \n\t" - // "vmax.f32 q5, q5, q8 \n\t" - // "vmax.f32 q6, q6, q8 \n\t" - // "vmax.f32 q7, q7, q8 \n\t" - // "add %[out_ptr], %[out_ptr], r5 \n\t" - // "vst1.32 {q0, q1}, [%[out_ptr]]! \n\t" - // "vst1.32 {q2, q3}, [%[out_ptr]]! \n\t" - // "vst1.32 {q4, q5}, [%[out_ptr]]! \n\t" - // "vst1.32 {q6, q7}, [%[out_ptr]]! \n\t" - // "end_%=: \n\t" - // : - // : - // [out_ptr] "r"(out_ptr), [input_x_ptr] "r"(input_x_ptr), [num] - // "r"(numel) : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", - // "q7", "q8", "r5", - // "r6"); - // } else { - ReluFunctor func_; - math::Transform trans; - trans(input_x_ptr, input_x_ptr + numel, out_ptr, func_); - // } + ReluCompute(param); } + } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/kernel/arm/reshape_kernel.cpp b/src/operators/kernel/arm/reshape_kernel.cpp index 9e0fd96d3ecd9772ef6e95bc12bb071a25a1d84a..5ae8e5e3f945d115215652ded58dc8571868fcd7 100644 --- a/src/operators/kernel/arm/reshape_kernel.cpp +++ b/src/operators/kernel/arm/reshape_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef RESHAPE_OP #include "operators/kernel/reshape_kernel.h" +#include "operators/kernel/central-arm-func/reshape_arm_func.h" namespace paddle_mobile { namespace operators { @@ -26,30 +27,7 @@ bool ReshapeKernel::Init(ReshapeParam *param) { template <> void ReshapeKernel::Compute(const ReshapeParam ¶m) const { - const auto *input_x = param.InputX(); - const auto &input_x_dims = input_x->dims(); - auto *out = param.Out(); - framework::DDim out_dims = out->dims(); - const auto *input_shape = param.InputShape(); - - if (input_shape) { - auto *shape_data = input_shape->data(); - framework::Tensor cpu_shape_tensor; - auto shape = - std::vector(shape_data, shape_data + input_shape->numel()); - out_dims = ValidateShape(shape, input_x->dims()); - } - - bool inplace = param.Inplace(); - out->Resize(out_dims); - if (!inplace) { - out->mutable_data(); - framework::TensorCopy(*input_x, out); - out->Resize(out_dims); - } else { - out->ShareDataWith(*input_x); - out->Resize(out_dims); - } + ReshapeCompute(param); } } // namespace operators diff --git a/src/operators/kernel/arm/transpose_kernel.cpp b/src/operators/kernel/arm/transpose_kernel.cpp index f697d4ca473d64b834fe1451afd8e0df7f84b3a6..c358edd76e93cee3f8be6086a70c34671c87d383 100644 --- a/src/operators/kernel/arm/transpose_kernel.cpp +++ b/src/operators/kernel/arm/transpose_kernel.cpp @@ -14,72 +14,19 @@ limitations under the License. */ #ifdef TRANSPOSE_OP #include "operators/kernel/transpose_kernel.h" +#include "operators/kernel/central-arm-func/transpose_arm_func.h" + namespace paddle_mobile { namespace operators { -// vector pos; -// template -// void TransposeFunc(const int numel, const T* input, const vector axis, -// const vector old_strides, const vector -// new_strides, T* output) { -// for (int i = 0; i < numel; ++i) { -// int old_idx = 0; -// int idx = i; -// for (int j = 0; j < axis.size(); ++j) { -// int order = axis[j]; -// old_idx += (idx / new_strides[j]) * old_strides[order]; -// idx %= new_strides[j]; -// } -// output[i] = input[old_idx]; -// } -// } - template <> -bool TransposeKernel::Init(TransposeParam* param) { +bool TransposeKernel::Init(TransposeParam *param) { return true; } template <> -void TransposeKernel::Compute(const TransposeParam& param) const { - const auto* input_x = param.InputX(); - const auto input_x_dims = input_x->dims(); - auto* out = param.Out(); - const auto axis = param.Axis(); - const auto* input_x_data = input_x->data(); - auto* out_data = out->mutable_data(); - - size_t ndim = axis.size(); - std::vector xdim(ndim); - std::vector xstride(ndim); - std::vector xout(ndim); - for (int i = 0; i < ndim; i++) { - int j = ndim - 1 - i; - xdim[j] = input_x_dims[axis[i]]; - xstride[j] = 1; - for (int k = axis[i] + 1; k < ndim; k++) { - xstride[j] *= input_x_dims[k]; - } - xout[j] = xstride[j] * xdim[j]; - } - - auto numel = input_x->numel(); - size_t pind = 0; - std::vector ind(ndim); - for (int i = 0; i < numel; i++) { - out_data[i] = input_x_data[pind]; - ind[0]++; - pind += xstride[0]; - for (int j = 0; j < ndim - 1; j++) { - if (ind[j] == xdim[j]) { - ind[j + 1]++; - ind[j] = 0; - pind += xstride[j + 1]; - pind -= xout[j]; - } else { - break; - } - } - } +void TransposeKernel::Compute(const TransposeParam ¶m) const { + TransposeCompute(param); } } // namespace operators diff --git a/src/operators/kernel/central-arm-func/box_coder_arm_func.h b/src/operators/kernel/central-arm-func/box_coder_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..eeb05f31b744c9e55e78375a495c5a5debf095c2 --- /dev/null +++ b/src/operators/kernel/central-arm-func/box_coder_arm_func.h @@ -0,0 +1,140 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef BOXCODER_OP +#pragma once + +#include + +namespace paddle_mobile { +namespace operators { + +template +void EncodeCenterSize(const framework::Tensor& target_box, + const framework::Tensor& prior_box, + const framework::Tensor& prior_box_var, T* output) { + int64_t row = target_box.dims()[0]; + int64_t col = prior_box.dims()[0]; + int64_t len = prior_box.dims()[1]; + auto* target_box_data = target_box.data(); + auto* prior_box_data = prior_box.data(); + auto* prior_box_var_data = prior_box_var.data(); + + for (int64_t i = 0; i < row; ++i) { + for (int64_t j = 0; j < col; ++j) { + T prior_box_width = prior_box_data[j * len + 2] - prior_box_data[j * len]; + T prior_box_height = + prior_box_data[j * len + 3] - prior_box_data[j * len + 1]; + T prior_box_center_x = + (prior_box_data[j * len + 2] + prior_box_data[j * len]) / 2; + T prior_box_center_y = + (prior_box_data[j * len + 3] + prior_box_data[j * len + 1]) / 2; + + T target_box_center_x = + (target_box_data[i * len + 2] + target_box_data[i * len]) / 2; + T target_box_center_y = + (target_box_data[i * len + 3] + target_box_data[i * len + 1]) / 2; + T target_box_width = + target_box_data[i * len + 2] - target_box_data[i * len]; + T target_box_height = + target_box_data[i * len + 3] - target_box_data[i * len + 1]; + + size_t offset = i * col * len + j * len; + output[offset] = (target_box_center_x - prior_box_center_x) / + prior_box_width / prior_box_var_data[j * len]; + output[offset + 1] = (target_box_center_y - prior_box_center_y) / + prior_box_height / prior_box_var_data[j * len + 1]; + output[offset + 2] = + std::log(std::fabs(target_box_width / prior_box_width)) / + prior_box_var_data[j * len + 2]; + output[offset + 3] = + std::log(std::fabs(target_box_height / prior_box_height)) / + prior_box_var_data[j * len + 3]; + } + } +} + +template +void DecodeCenterSize(const framework::Tensor& target_box, + const framework::Tensor& prior_box, + const framework::Tensor& prior_box_var, T* output) { + int64_t row = target_box.dims()[0]; + int64_t col = prior_box.dims()[0]; + int64_t len = prior_box.dims()[1]; + + auto* target_box_data = target_box.data(); + auto* prior_box_data = prior_box.data(); + auto* prior_box_var_data = prior_box_var.data(); + + for (int64_t i = 0; i < row; ++i) { + for (int64_t j = 0; j < col; ++j) { + size_t offset = i * col * len + j * len; + T prior_box_width = prior_box_data[j * len + 2] - prior_box_data[j * len]; + T prior_box_height = + prior_box_data[j * len + 3] - prior_box_data[j * len + 1]; + T prior_box_center_x = + (prior_box_data[j * len + 2] + prior_box_data[j * len]) / 2; + T prior_box_center_y = + (prior_box_data[j * len + 3] + prior_box_data[j * len + 1]) / 2; + + T target_box_center_x = prior_box_var_data[j * len] * + target_box_data[offset] * prior_box_width + + prior_box_center_x; + T target_box_center_y = prior_box_var_data[j * len + 1] * + target_box_data[offset + 1] * + prior_box_height + + prior_box_center_y; + T target_box_width = std::exp(prior_box_var_data[j * len + 2] * + target_box_data[offset + 2]) * + prior_box_width; + T target_box_height = std::exp(prior_box_var_data[j * len + 3] * + target_box_data[offset + 3]) * + prior_box_height; + + output[offset] = target_box_center_x - target_box_width / 2; + output[offset + 1] = target_box_center_y - target_box_height / 2; + output[offset + 2] = target_box_center_x + target_box_width / 2; + output[offset + 3] = target_box_center_y + target_box_height / 2; + } + } +} + +template +void BoxCoderCompute(const BoxCoderParam& param) { + const auto* input_priorbox = param.InputPriorBox(); + const auto* input_priorboxvar = param.InputPriorBoxVar(); + const auto* input_targetbox = param.InputTargetBox(); + + const auto& code_type = param.CodeType(); + + auto row = input_targetbox->dims()[0]; + auto col = input_priorbox->dims()[0]; + auto len = input_priorbox->dims()[1]; + + Tensor* output_box = param.OutputBox(); + auto* output_box_dataptr = output_box->mutable_data({row, col, len}); + + if (code_type == "encode_center_size") { + EncodeCenterSize(*input_targetbox, *input_priorbox, + *input_priorboxvar, output_box_dataptr); + } + if (code_type == "decode_center_size") { + DecodeCenterSize(*input_targetbox, *input_priorbox, + *input_priorboxvar, output_box_dataptr); + } +} +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/concat_arm_func.h b/src/operators/kernel/central-arm-func/concat_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..e9926505b33b32ee83a16f882cc0f775797f154a --- /dev/null +++ b/src/operators/kernel/central-arm-func/concat_arm_func.h @@ -0,0 +1,90 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef CONCAT_OP +#pragma once + +#include + +namespace paddle_mobile { +namespace operators { +template +class ConcatFunctor { + public: + void operator()(const std::vector &input, const int axis, + framework::Tensor *output) { + size_t num = input.size(); + int rows = 1; + auto dim_0 = input[0].dims(); + for (int i = 0; i < axis; ++i) { + rows *= dim_0[i]; + } + int out_rows = rows, out_cols = 0; + + std::vector input_cols(input.size()); + for (int i = 0; i < num; ++i) { + int t_cols = input[i].numel() / rows; + out_cols += t_cols; + input_cols[i] = t_cols; + } + + // computation + for (int k = 0; k < out_rows; ++k) { + T *dst_ptr = output->data() + k * out_cols; + int col_idx = 0; + for (int j = 0; j < num; ++j) { + int col_len = input_cols[j]; + const T *src_prt = input[j].data() + k * col_len; + memory::Copy(dst_ptr + col_idx, src_prt, sizeof(T) * col_len); + col_idx += col_len; + } + } + } +}; + +template +void ConcatCompute(const ConcatParam ¶m) { + auto inputs = param.Inputs(); + auto *out = param.Out(); + int64_t axis = param.Axis(); + out->mutable_data(); + + /// Sometimes direct copies will be faster, this maybe need deeply analysis. + if (axis == 0 && inputs.size() < 10) { + size_t output_offset = 0; + for (auto *in : inputs) { + auto in_stride = framework::stride_numel(in->dims()); + auto out_stride = framework::stride_numel(out->dims()); + auto dst = out->data() + output_offset; + auto src = in->data(); + PADDLE_MOBILE_ENFORCE( + in_stride.size() == out_stride.size(), + "src and dst tensor should have the same dims size."); + memory::Copy(dst, src, sizeof(float) * in_stride[0]); + output_offset += in_stride[0]; + } + } else { + std::vector inputs_concat(inputs.size()); + for (int j = 0; j < inputs.size(); ++j) { + inputs_concat[j] = *inputs[j]; + } + ConcatFunctor concat_functor; + concat_functor(inputs_concat, static_cast(axis), out); + } +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/conv_add_bn_relu_func.h b/src/operators/kernel/central-arm-func/conv_add_bn_relu_func.h index 6fce2c26347183c47ae756b07156de76f37ea6e5..13fe50bf74ee164c2cc663f5a6a9eeddbfa3804b 100644 --- a/src/operators/kernel/central-arm-func/conv_add_bn_relu_func.h +++ b/src/operators/kernel/central-arm-func/conv_add_bn_relu_func.h @@ -15,14 +15,12 @@ limitations under the License. */ #ifdef FUSION_CONVADDBNRELU_OP #pragma once -#include "operators/kernel/conv_add_bn_relu_kernel.h" #include "operators/math/depthwise_conv_3x3.h" #include "operators/op_param.h" + namespace paddle_mobile { namespace operators { - -template -void ConvAddBNReluCompute(const FusionConvAddBNReluParam ¶m) { +void ConvAddBNReluBasic(const FusionConvAddBNReluParam ¶m) { const Tensor *input = param.Input(); Tensor filter = *param.Filter(); Tensor bias = *param.Bias(); @@ -31,105 +29,122 @@ void ConvAddBNReluCompute(const FusionConvAddBNReluParam ¶m) { auto new_bias_ptr = new_bias.data(); auto new_scale_ptr = new_scale.data(); int axis = param.Axis(); + Tensor *output = param.Output(); + math::expand_bias(bias, axis, output->dims()); + output->ShareDataWith(bias); + int groups = param.Groups(); std::vector strides = param.Strides(); std::vector paddings = param.Paddings(); std::vector dilations = param.Dilations(); - Tensor *output = param.Output(); + + const int batch_size = static_cast(input->dims()[0]); + std::vector filter_shape_vec(framework::vectorize(filter.dims())); - if (filter_shape_vec[2] == 3 && strides[0] == 1 && groups > 1) { - math::DepthwiseConvAddBNRelu3x3s1p1(input, filter, output, &bias, 1, - &new_scale, &new_bias, 1, 1); - } else { - const int batch_size = static_cast(input->dims()[0]); - - math::expand_bias(bias, axis, output->dims()); - output->ShareDataWith(bias); - - std::vector output_shape_vec(framework::vectorize(output->dims())); - size_t data_dim = filter_shape_vec.size() - 2; - std::vector col_shape_vec(1 + 2 * data_dim); - col_shape_vec[0] = input->dims()[1] / groups; - for (size_t j = 0; j < data_dim; ++j) { - col_shape_vec[j + 1] = filter_shape_vec[j + 2]; - col_shape_vec[j + 1 + data_dim] = output_shape_vec[j + 2]; - } - framework::DDim col_shape(framework::make_ddim(col_shape_vec)); - - framework::DDim col_matrix_shape = - framework::flatten_to_2d(col_shape, data_dim + 1); - - bool is_expand = - math::IsExpand(filter_shape_vec, strides, paddings, dilations); - Tensor col; - Tensor col_matrix; - if (is_expand) { - col.mutable_data(col_shape); - col_matrix.ShareDataWith(col); - col_matrix.Resize(col_matrix_shape); - } + std::vector output_shape_vec(framework::vectorize(output->dims())); + size_t data_dim = filter_shape_vec.size() - 2; + std::vector col_shape_vec(1 + 2 * data_dim); + col_shape_vec[0] = input->dims()[1] / groups; + for (size_t j = 0; j < data_dim; ++j) { + col_shape_vec[j + 1] = filter_shape_vec[j + 2]; + col_shape_vec[j + 1 + data_dim] = output_shape_vec[j + 2]; + } + framework::DDim col_shape(framework::make_ddim(col_shape_vec)); + + framework::DDim col_matrix_shape = + framework::flatten_to_2d(col_shape, data_dim + 1); + + bool is_expand = + math::IsExpand(filter_shape_vec, strides, paddings, dilations); + Tensor col; + Tensor col_matrix; + if (is_expand) { + col.mutable_data(col_shape); + col_matrix.ShareDataWith(col); + col_matrix.Resize(col_matrix_shape); + } - framework::DDim input_shape = framework::slice_ddim( - input->dims(), 1, static_cast(input->dims().size())); - - framework::DDim filter_matrix_shape = {filter.dims()[0], - filter.numel() / filter.dims()[0]}; - filter.Resize(filter_matrix_shape); - framework::DDim output_matrix_shape = { - output->dims()[1], - output->numel() / (output->dims()[0] * output->dims()[1])}; - - // convolution operator: im2col(or vol2col) + gemm - int in_step = static_cast(input->dims()[1]) / groups; - int out_step = static_cast(output->dims()[1]) / groups; - - math::Vol2ColFunctor vol2col; - math::Im2ColFunctor im2col; - - for (int i = 0; i < batch_size; i++) { - Tensor in_batch = input->Slice(i, i + 1).Resize(input_shape); - Tensor out_batch = output->Slice(i, i + 1).Resize(output_matrix_shape); - - for (int g = 0; g < groups; g++) { - Tensor in_slice = in_batch.Slice(g * in_step, (g + 1) * in_step); - - if (!is_expand) { - col.ShareDataWith(in_slice); - col_matrix.ShareDataWith(col); - col_matrix.Resize(col_matrix_shape); - } else if (data_dim == 2U) { - // im2col - im2col(in_slice, dilations, strides, - std::vector{paddings[0], paddings[1], paddings[0], - paddings[1]}, - &col); - } else if (data_dim == 3U) { - // vol2col - vol2col(in_slice, dilations, strides, paddings, &col); - } - - // gemm - Tensor out_slice = out_batch.Slice(g * out_step, (g + 1) * out_step); - Tensor filter_slice = filter.Slice(g * out_step, (g + 1) * out_step); - math::matmul(filter_slice, false, col_matrix, false, - static_cast(1), &out_slice, - static_cast(1), false); + framework::DDim input_shape = framework::slice_ddim( + input->dims(), 1, static_cast(input->dims().size())); + + framework::DDim filter_matrix_shape = {filter.dims()[0], + filter.numel() / filter.dims()[0]}; + filter.Resize(filter_matrix_shape); + framework::DDim output_matrix_shape = { + output->dims()[1], + output->numel() / (output->dims()[0] * output->dims()[1])}; + + // convolution operator: im2col(or vol2col) + gemm + int in_step = static_cast(input->dims()[1]) / groups; + int out_step = static_cast(output->dims()[1]) / groups; + + math::Vol2ColFunctor vol2col; + math::Im2ColFunctor im2col; + + for (int i = 0; i < batch_size; i++) { + Tensor in_batch = input->Slice(i, i + 1).Resize(input_shape); + Tensor out_batch = output->Slice(i, i + 1).Resize(output_matrix_shape); + + for (int g = 0; g < groups; g++) { + Tensor in_slice = in_batch.Slice(g * in_step, (g + 1) * in_step); + + if (!is_expand) { + col.ShareDataWith(in_slice); + col_matrix.ShareDataWith(col); + col_matrix.Resize(col_matrix_shape); + } else if (data_dim == 2U) { + // im2col + im2col(in_slice, dilations, strides, + std::vector{paddings[0], paddings[1], paddings[0], + paddings[1]}, + &col); + } else if (data_dim == 3U) { + // vol2col + vol2col(in_slice, dilations, strides, paddings, &col); } + // gemm + Tensor out_slice = out_batch.Slice(g * out_step, (g + 1) * out_step); + Tensor filter_slice = filter.Slice(g * out_step, (g + 1) * out_step); + math::matmul(filter_slice, false, col_matrix, false, + static_cast(1), &out_slice, + static_cast(1)); } - - auto output_ptr = output->data(); - for (int c = 0; c < output_matrix_shape[0]; c++) { - int start = c * output_matrix_shape[1]; - for (int j = 0; j < output_matrix_shape[1]; j++) { - output_ptr[start + j] = - output_ptr[start + j] * new_scale_ptr[c] + new_bias_ptr[c]; - output_ptr[start + j] = - output_ptr[start + j] < 0 ? 0 : output_ptr[start + j]; - } + } + /// todo : use neon in special case instead of 2for(300ms) + auto output_ptr = output->data(); + for (int c = 0; c < output_matrix_shape[0]; c++) { + int start = c * output_matrix_shape[1]; + for (int j = 0; j < output_matrix_shape[1]; j++) { + output_ptr[start + j] = + output_ptr[start + j] * new_scale_ptr[c] + new_bias_ptr[c]; + output_ptr[start + j] = + output_ptr[start + j] < 0 ? 0 : output_ptr[start + j]; } } } +template +void ConvAddBNReluCompute(const FusionConvAddBNReluParam ¶m) { + Tensor Bias; + Bias.mutable_data({param.Groups()}); + if (param.Groups() == param.Input()->dims()[1] && + param.Input()->dims()[1] == param.Output()->dims()[1] && + param.Filter()->dims()[2] == param.Filter()->dims()[3] && + param.Filter()->dims()[2] == 3 && param.Strides()[0] == 1) { + math::DepthwiseConvAddBNRelu3x3s1p1( + param.Input(), param.Filter(), param.Output(), &Bias, 1, + param.NewScale(), param.NewBias(), 1, 1); + } else if (0 && param.Groups() == param.Input()->dims()[1] && + param.Input()->dims()[1] == param.Output()->dims()[1] && + param.Filter()->dims()[2] == param.Filter()->dims()[3] && + param.Filter()->dims()[2] == 3 && param.Strides()[0] == 2) { + math::DepthwiseConv3x3(param.Input(), param.Strides(), param.Paddings(), + param.Filter(), &Bias, param.Output(), false); + } else { + ConvAddBNReluBasic(param); + } +} + } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/kernel/central-arm-func/conv_arm_func.h b/src/operators/kernel/central-arm-func/conv_arm_func.h index d08eebe5493bd9026073c3349631a42024579b95..6accf1937da5343a33d9dd739c125836f080f181 100644 --- a/src/operators/kernel/central-arm-func/conv_arm_func.h +++ b/src/operators/kernel/central-arm-func/conv_arm_func.h @@ -15,19 +15,19 @@ limitations under the License. */ #ifdef CONV_OP #pragma once +#include #include -#include "operators/math/conv_func.h" + #include "operators/op_param.h" namespace paddle_mobile { namespace operators { -template -void ConvCompute(const ConvParam ¶m) { +inline void ConvBasic(const ConvParam ¶m) { const Tensor *input = param.Input(); Tensor filter = *param.Filter(); Tensor *output = param.Output(); - output->mutable_data(); + int groups = param.Groups(); std::vector strides = param.Strides(); std::vector paddings = param.Paddings(); @@ -109,6 +109,27 @@ void ConvCompute(const ConvParam ¶m) { } } +template +void ConvCompute(const ConvParam ¶m) { + Tensor Bias; + Bias.mutable_data({param.Groups()}); + if (param.Groups() == param.Input()->dims()[1] && + param.Input()->dims()[1] == param.Output()->dims()[1] && + param.Filter()->dims()[2] == param.Filter()->dims()[3] && + param.Filter()->dims()[2] == 3 && param.Strides()[0] == 1) { + math::DepthwiseConv3x3s1p1(param.Input(), param.Filter(), param.Output(), + &Bias, false); + } else if (param.Groups() == param.Input()->dims()[1] && + param.Input()->dims()[1] == param.Output()->dims()[1] && + param.Filter()->dims()[2] == param.Filter()->dims()[3] && + param.Filter()->dims()[2] == 3 && param.Strides()[0] == 2) { + math::DepthwiseConv3x3(param.Input(), param.Strides(), param.Paddings(), + param.Filter(), &Bias, param.Output(), false); + } else { + ConvBasic(param); + } +} + } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/kernel/central-arm-func/depthwise_conv_arm_func.h b/src/operators/kernel/central-arm-func/depthwise_conv_arm_func.h index e43e3664cb005bab4d3c5ec8b5b35bd6925c982d..885f2051f645546c2585caa72aa9c80f8d352e6c 100644 --- a/src/operators/kernel/central-arm-func/depthwise_conv_arm_func.h +++ b/src/operators/kernel/central-arm-func/depthwise_conv_arm_func.h @@ -15,8 +15,10 @@ limitations under the License. */ #ifdef DEPTHWISECONV_OP #pragma once +#include #include -#include "operators/math/conv_func.h" +#include "operators/kernel/central-arm-func/conv_arm_func.h" + #include "operators/op_param.h" namespace paddle_mobile { @@ -24,89 +26,21 @@ namespace operators { template void DepthwiseConvCompute(const ConvParam ¶m) { - const Tensor *input = param.Input(); - Tensor filter = *param.Filter(); - Tensor *output = param.Output(); - output->mutable_data(); - int groups = param.Groups(); - std::vector strides = param.Strides(); - std::vector paddings = param.Paddings(); - std::vector dilations = param.Dilations(); - - // DLOG << " compute end get Attrs " << strides[0]; - - const int batch_size = static_cast(input->dims()[0]); - - std::vector filter_shape_vec(framework::vectorize(filter.dims())); - std::vector output_shape_vec(framework::vectorize(output->dims())); - size_t data_dim = filter_shape_vec.size() - 2; - std::vector col_shape_vec(1 + 2 * data_dim); - col_shape_vec[0] = input->dims()[1] / groups; - for (size_t j = 0; j < data_dim; ++j) { - col_shape_vec[j + 1] = filter_shape_vec[j + 2]; - col_shape_vec[j + 1 + data_dim] = output_shape_vec[j + 2]; - } - framework::DDim col_shape(framework::make_ddim(col_shape_vec)); - - framework::DDim col_matrix_shape = - framework::flatten_to_2d(col_shape, data_dim + 1); - - bool is_expand = - math::IsExpand(filter_shape_vec, strides, paddings, dilations); - Tensor col; - Tensor col_matrix; - if (is_expand) { - col.mutable_data(col_shape); - col_matrix.ShareDataWith(col); - col_matrix.Resize(col_matrix_shape); - } - - framework::DDim input_shape = framework::slice_ddim( - input->dims(), 1, static_cast(input->dims().size())); - - framework::DDim filter_matrix_shape = {filter.dims()[0], - filter.numel() / filter.dims()[0]}; - filter.Resize(filter_matrix_shape); - framework::DDim output_matrix_shape = { - output->dims()[1], - output->numel() / (output->dims()[0] * output->dims()[1])}; - - // convolution operator: im2col(or vol2col) + gemm - int in_step = static_cast(input->dims()[1]) / groups; - int out_step = static_cast(output->dims()[1]) / groups; - - math::Vol2ColFunctor vol2col; - math::Im2ColFunctor im2col; - - for (int i = 0; i < batch_size; i++) { - Tensor in_batch = input->Slice(i, i + 1).Resize(input_shape); - Tensor out_batch = output->Slice(i, i + 1).Resize(output_matrix_shape); - - for (int g = 0; g < groups; g++) { - Tensor in_slice = in_batch.Slice(g * in_step, (g + 1) * in_step); - - if (!is_expand) { - col.ShareDataWith(in_slice); - col_matrix.ShareDataWith(col); - col_matrix.Resize(col_matrix_shape); - } else if (data_dim == 2U) { - // im2col - im2col(in_slice, dilations, strides, - std::vector{paddings[0], paddings[1], paddings[0], - paddings[1]}, - &col); - } else if (data_dim == 3U) { - // vol2col - vol2col(in_slice, dilations, strides, paddings, &col); - } - - // gemm - Tensor out_slice = out_batch.Slice(g * out_step, (g + 1) * out_step); - Tensor filter_slice = filter.Slice(g * out_step, (g + 1) * out_step); - math::matmul(filter_slice, false, col_matrix, false, - static_cast(1), &out_slice, - static_cast(0)); - } + Tensor Bias; + Bias.mutable_data({param.Groups()}); + if (param.Groups() == param.Input()->dims()[1] && + param.Filter()->dims()[2] == param.Filter()->dims()[3] && + param.Filter()->dims()[2] == 3 && param.Strides()[0] == 1) { + math::DepthwiseConv3x3s1p1(param.Input(), param.Filter(), param.Output(), + &Bias, false); + } else if (param.Groups() == param.Input()->dims()[1] && + param.Input()->dims()[1] == param.Output()->dims()[1] && + param.Filter()->dims()[2] == param.Filter()->dims()[3] && + param.Filter()->dims()[2] == 3 && param.Strides()[0] == 2) { + math::DepthwiseConv3x3(param.Input(), param.Strides(), param.Paddings(), + param.Filter(), &Bias, param.Output(), false); + } else { + ConvBasic(param); } } diff --git a/src/operators/kernel/central-arm-func/elementwise_add_arm_func.h b/src/operators/kernel/central-arm-func/elementwise_add_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..8b3f5d0a8083b63334319b2054f9bf463efa66c7 --- /dev/null +++ b/src/operators/kernel/central-arm-func/elementwise_add_arm_func.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef ELEMENTWISEADD_OP + +#pragma once + +namespace paddle_mobile { +namespace operators { + +template +struct AddFunctor { + inline T operator()(T a, T b) const { return a + b; } +}; + +template +void ElementwiseAddCompute(const ElementwiseAddParam ¶m) { + const Tensor *input_x = param.InputX(); + const Tensor *input_y = param.InputY(); + Tensor *Out = param.Out(); + Out->mutable_data(); + int axis = param.Axis(); + ElementwiseComputeEx, float>(input_x, input_y, axis, + AddFunctor(), Out); +} + +template class ElementwiseAddKernel; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/fusion_fc_arm_func.h b/src/operators/kernel/central-arm-func/fusion_fc_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..8a01f554140712c6a941b40372cbcfe35a951ce7 --- /dev/null +++ b/src/operators/kernel/central-arm-func/fusion_fc_arm_func.h @@ -0,0 +1,69 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef FUSION_FC_OP + +#pragma once + +namespace paddle_mobile { +namespace operators { + +template +void FusionFcCompute(const FusionFcParam ¶m) { + const Tensor *input_x = param.InputX(); + const Tensor *input_y = param.InputY(); + const Tensor *input_z = param.InputZ(); + auto *input_z_data = input_z->data(); + int axis = param.Axis(); + Tensor *out = param.Out(); + auto *out_data = out->mutable_data(); + const Tensor x_matrix = + input_x->dims().size() > 2 + ? framework::ReshapeToMatrix(*input_x, param.XNumColDims()) + : *input_x; + const Tensor y_matrix = + input_y->dims().size() > 2 + ? framework::ReshapeToMatrix(*input_y, param.YNumColDims()) + : *input_y; + auto out_dim = out->dims(); + if (out_dim.size() != 2) { + out->Resize({x_matrix.dims()[0], y_matrix.dims()[1]}); + } + PADDLE_MOBILE_ENFORCE(out_dim.size() == 2, " out_dim.size must be 2."); + PADDLE_MOBILE_ENFORCE(input_z->dims().size() == 1, "inpu_z size must be 1"); + PADDLE_MOBILE_ENFORCE(out_dim[1] == input_z->dims()[0], + " out_dim.size must be 2."); + axis = (axis == -1 ? out_dim.size() - input_z->dims().size() : axis); + PADDLE_MOBILE_ENFORCE(axis == 1, " to fit broadcast, axis = 1. ") + + int64_t classes = input_z->numel(); + for (int i = 0; i < out_dim[0]; i++) { + memory::Copy(out_data + i * classes, input_z_data, sizeof(float) * classes); + } + + for (int i = 0; i < out->numel(); i++) { + DLOG << out_data[i]; + } + math::matmul(x_matrix, false, y_matrix, false, static_cast(1), + out, static_cast(1)); + PADDLE_MOBILE_ENFORCE(out_dim.size() == 2, " out_dim.size must be 2."); + // if (out_dim.size() != 2) { + // out->Resize(out_dim); + // } +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/lrn_arm_func.h b/src/operators/kernel/central-arm-func/lrn_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..52bb1b67dee83c28f513649a8763034a8d538d73 --- /dev/null +++ b/src/operators/kernel/central-arm-func/lrn_arm_func.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef LRN_OP + +#pragma once + +namespace paddle_mobile { +namespace operators { + +template +void LrnCompute(const LrnParam ¶m) { + const Tensor *input_x = param.InputX(); + auto x_dims = input_x->dims(); + Tensor *out = param.Out(); + out->mutable_data(); + /// data_format = NCHW + const int N = x_dims[0]; + const int C = x_dims[1]; + const int H = x_dims[2]; + const int W = x_dims[3]; + + const int n = param.N(); + const float alpha = param.Alpha(); + const float beta = param.Beta(); + const float k = param.K(); + LRNFunctor lrnFunctor; + lrnFunctor(*input_x, out, N, C, H, W, n, k, alpha, beta); +} + +template class LrnKernel; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/mul_arm_func.h b/src/operators/kernel/central-arm-func/mul_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..9dfb1f48a574156f1b026fc6af3a03d77b81263f --- /dev/null +++ b/src/operators/kernel/central-arm-func/mul_arm_func.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef MUL_OP + +#pragma once + +namespace paddle_mobile { +namespace operators { + +template +void MulCompute(const MulParam ¶m) { + const Tensor *input_x = param.InputX(); + const Tensor *input_y = param.InputY(); + Tensor *out = param.Out(); + out->mutable_data(); + const Tensor x_matrix = + input_x->dims().size() > 2 + ? framework::ReshapeToMatrix(*input_x, param.XNumColDims()) + : *input_x; + const Tensor y_matrix = + input_y->dims().size() > 2 + ? framework::ReshapeToMatrix(*input_y, param.YNumColDims()) + : *input_y; + auto out_dim = out->dims(); + if (out_dim.size() != 2) { + out->Resize({x_matrix.dims()[0], y_matrix.dims()[1]}); + } + math::matmul(x_matrix, false, y_matrix, false, static_cast(1), + out, static_cast(0)); + if (out_dim.size() != 2) { + out->Resize(out_dim); + } +} + +template class MulKernel; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/multiclass_nms_arm_func.h b/src/operators/kernel/central-arm-func/multiclass_nms_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..8833f012d97390e758ac6fc394ef237cb86632b1 --- /dev/null +++ b/src/operators/kernel/central-arm-func/multiclass_nms_arm_func.h @@ -0,0 +1,280 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef MULTICLASSNMS_OP +#pragma once + +#include +#include +#include +#include + +namespace paddle_mobile { +namespace operators { + +constexpr int kOutputDim = 6; +constexpr int kBBoxSize = 4; + +template +bool SortScorePairDescend(const std::pair& pair1, + const std::pair& pair2) { + return pair1.first > pair2.first; +} + +template +static inline void GetMaxScoreIndex( + const std::vector& scores, const T threshold, int top_k, + std::vector>* sorted_indices) { + for (size_t i = 0; i < scores.size(); ++i) { + if (scores[i] > threshold) { + sorted_indices->push_back(std::make_pair(scores[i], i)); + } + } + // Sort the score pair according to the scores in descending order + std::stable_sort(sorted_indices->begin(), sorted_indices->end(), + SortScorePairDescend); + // Keep top_k scores if needed. + if (top_k > -1 && top_k < static_cast(sorted_indices->size())) { + sorted_indices->resize(top_k); + } +} + +template +static inline T BBoxArea(const T* box, const bool normalized) { + if (box[2] < box[0] || box[3] < box[1]) { + // If coordinate values are is invalid + // (e.g. xmax < xmin or ymax < ymin), return 0. + return static_cast(0.); + } else { + const T w = box[2] - box[0]; + const T h = box[3] - box[1]; + if (normalized) { + return w * h; + } else { + // If coordinate values are not within range [0, 1]. + return (w + 1) * (h + 1); + } + } +} + +template +static inline T JaccardOverlap(const T* box1, const T* box2, + const bool normalized) { + if (box2[0] > box1[2] || box2[2] < box1[0] || box2[1] > box1[3] || + box2[3] < box1[1]) { + return static_cast(0.); + } else { + const T inter_xmin = std::max(box1[0], box2[0]); + const T inter_ymin = std::max(box1[1], box2[1]); + const T inter_xmax = std::min(box1[2], box2[2]); + const T inter_ymax = std::min(box1[3], box2[3]); + const T inter_w = inter_xmax - inter_xmin; + const T inter_h = inter_ymax - inter_ymin; + const T inter_area = inter_w * inter_h; + const T bbox1_area = BBoxArea(box1, normalized); + const T bbox2_area = BBoxArea(box2, normalized); + return inter_area / (bbox1_area + bbox2_area - inter_area); + } +} + +template +static inline void NMSFast(const Tensor& bbox, const Tensor& scores, + const T score_threshold, const T nms_threshold, + const T eta, const int64_t top_k, + std::vector* selected_indices) { + // The total boxes for each instance. + int64_t num_boxes = bbox.dims()[0]; + // 4: [xmin ymin xmax ymax] + int64_t box_size = bbox.dims()[1]; + + std::vector scores_data(num_boxes); + std::copy_n(scores.data(), num_boxes, scores_data.begin()); + std::vector> sorted_indices; + GetMaxScoreIndex(scores_data, score_threshold, top_k, &sorted_indices); + + selected_indices->clear(); + T adaptive_threshold = nms_threshold; + const T* bbox_data = bbox.data(); + + while (sorted_indices.size() != 0) { + const int idx = sorted_indices.front().second; + bool keep = true; + for (size_t k = 0; k < selected_indices->size(); ++k) { + if (keep) { + const int kept_idx = (*selected_indices)[k]; + T overlap = JaccardOverlap(bbox_data + idx * box_size, + bbox_data + kept_idx * box_size, true); + keep = overlap <= adaptive_threshold; + } else { + break; + } + } + if (keep) { + selected_indices->push_back(idx); + } + sorted_indices.erase(sorted_indices.begin()); + if (keep && eta < 1 && adaptive_threshold > 0.5) { + adaptive_threshold *= eta; + } + } +} + +template +void MultiClassNMS(const Tensor& scores, const Tensor& bboxes, + std::map>* indices, int* num_nmsed_out, + const int& background_label, const int& nms_top_k, + const int& keep_top_k, const T& nms_threshold, + const T& nms_eta, const T& score_threshold) { + int64_t class_num = scores.dims()[0]; + int64_t predict_dim = scores.dims()[1]; + int num_det = 0; + for (int64_t c = 0; c < class_num; ++c) { + if (c == background_label) continue; + Tensor score = scores.Slice(c, c + 1); + /// [c] is key + NMSFast(bboxes, score, score_threshold, nms_threshold, nms_eta, + nms_top_k, &((*indices)[c])); + num_det += (*indices)[c].size(); + } + + *num_nmsed_out = num_det; + const T* scores_data = scores.data(); + if (keep_top_k > -1 && num_det > keep_top_k) { + std::vector>> score_index_pairs; + for (const auto& it : *indices) { + int label = it.first; + const T* sdata = scores_data + label * predict_dim; + const std::vector& label_indices = it.second; + for (size_t j = 0; j < label_indices.size(); ++j) { + int idx = label_indices[j]; + // PADDLE_ENFORCE_LT(idx, predict_dim); + score_index_pairs.push_back( + std::make_pair(sdata[idx], std::make_pair(label, idx))); + } + } + // Keep top k results per image. + std::stable_sort(score_index_pairs.begin(), score_index_pairs.end(), + SortScorePairDescend>); + score_index_pairs.resize(keep_top_k); + + // Store the new indices. + std::map> new_indices; + for (size_t j = 0; j < score_index_pairs.size(); ++j) { + int label = score_index_pairs[j].second.first; + int idx = score_index_pairs[j].second.second; + new_indices[label].push_back(idx); + } + new_indices.swap(*indices); + *num_nmsed_out = keep_top_k; + } +} + +template +void MultiClassOutput(const Tensor& scores, const Tensor& bboxes, + const std::map>& selected_indices, + Tensor* outs) { + int predict_dim = scores.dims()[1]; + auto* scores_data = scores.data(); + auto* bboxes_data = bboxes.data(); + auto* odata = outs->data(); + + int count = 0; + for (const auto& it : selected_indices) { + /// one batch + int label = it.first; + const T* sdata = scores_data + label * predict_dim; + const std::vector& indices = it.second; + for (size_t j = 0; j < indices.size(); ++j) { + int idx = indices[j]; + const T* bdata = bboxes_data + idx * kBBoxSize; + odata[count * kOutputDim] = label; // label + odata[count * kOutputDim + 1] = sdata[idx]; // score + // xmin, ymin, xmax, ymax + std::memcpy(odata + count * kOutputDim + 2, bdata, 4 * sizeof(T)); + count++; + } + } +} + +template +void MultiClassNMSCompute(const MultiClassNMSParam& param) { + const auto* input_bboxes = param.InputBBoxes(); + const auto& input_bboxes_dims = input_bboxes->dims(); + + const auto* input_scores = param.InputScores(); + const auto& input_scores_dims = input_scores->dims(); + + auto* outs = param.Out(); + auto background_label = param.BackGroundLabel(); + auto nms_top_k = param.NMSTopK(); + auto keep_top_k = param.KeepTopK(); + auto nms_threshold = param.NMSThreshold(); + auto nms_eta = param.NMSEta(); + auto score_threshold = param.ScoreThreshold(); + + int64_t batch_size = input_scores_dims[0]; + int64_t class_num = input_scores_dims[1]; + int64_t predict_dim = input_scores_dims[2]; + int64_t box_dim = input_bboxes_dims[2]; + + std::vector>> all_indices; + std::vector batch_starts = {0}; + for (int64_t i = 0; i < batch_size; ++i) { + Tensor ins_score = input_scores->Slice(i, i + 1); + ins_score.Resize({class_num, predict_dim}); + + Tensor ins_boxes = input_bboxes->Slice(i, i + 1); + ins_boxes.Resize({predict_dim, box_dim}); + + std::map> indices; + int num_nmsed_out = 0; + MultiClassNMS(ins_score, ins_boxes, &indices, &num_nmsed_out, + background_label, nms_top_k, keep_top_k, nms_threshold, + nms_eta, score_threshold); + all_indices.push_back(indices); + batch_starts.push_back(batch_starts.back() + num_nmsed_out); + } + + int num_kept = batch_starts.back(); + if (num_kept == 0) { + float* od = outs->mutable_data({1}); + od[0] = -1; + } else { + outs->mutable_data({num_kept, kOutputDim}); + for (int64_t i = 0; i < batch_size; ++i) { + Tensor ins_score = input_scores->Slice(i, i + 1); + ins_score.Resize({class_num, predict_dim}); + + Tensor ins_boxes = input_bboxes->Slice(i, i + 1); + ins_boxes.Resize({predict_dim, box_dim}); + + int64_t s = batch_starts[i]; + int64_t e = batch_starts[i + 1]; + if (e > s) { + Tensor out = outs->Slice(s, e); + MultiClassOutput(ins_score, ins_boxes, all_indices[i], &out); + } + } + } + + // framework::LoD lod; + // lod.emplace_back(batch_starts); + // + // outs->set_lod(lod); +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/prior_box_arm_func.h b/src/operators/kernel/central-arm-func/prior_box_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..892dceb9254ac423d3591a0fc9e9347bc375831b --- /dev/null +++ b/src/operators/kernel/central-arm-func/prior_box_arm_func.h @@ -0,0 +1,149 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef PRIORBOX_OP +#pragma once + +#include +#include + +namespace paddle_mobile { +namespace operators { + +template +struct ClipFunctor { + inline T operator()(T in) const { + return std::min(std::max(in, 0.), 1.); + } +}; + +template +void PriorBoxCompute(const PriorBoxParam ¶m) { + const auto *input_ = param.Input(); + const auto &input_dims = input_->dims(); + + const auto *input_image = param.InputImage(); + const auto &input_image_dims = input_image->dims(); + + const auto &min_sizes = param.MinSizes(); + const auto &max_sizes = param.MaxSizes(); + const auto &variances = param.Variances(); + const auto &input_aspect_ratio = param.AspectRatios(); + const bool &flip = param.Flip(); + const bool &clip = param.Clip(); + const float &step_w = param.StepW(); + const float &step_h = param.StepH(); + const float &offset = param.Offset(); + + Tensor *output_boxes = param.OutputBoxes(); + auto output_boxes_dataptr = output_boxes->mutable_data(); + Tensor *output_variances = param.OutputVariances(); + auto output_variances_dataptr = output_variances->mutable_data(); + + std::vector aspect_ratios; + ExpandAspectRatios(input_aspect_ratio, flip, &aspect_ratios); + + auto img_width = input_image_dims[3]; + auto img_height = input_image_dims[2]; + + auto feature_width = input_dims[3]; + auto feature_height = input_dims[2]; + + auto stride0 = output_boxes->dims()[1] * output_boxes->dims()[2] * + output_boxes->dims()[3]; + auto stride1 = output_boxes->dims()[2] * output_boxes->dims()[3]; + auto stride2 = output_boxes->dims()[3]; + + float step_width, step_height; + /// 300 / 19 + if (step_w == 0 || step_h == 0) { + step_width = static_cast(img_width) / feature_width; + step_height = static_cast(img_height) / feature_height; + } else { + step_width = step_w; + step_height = step_h; + } + + int num_priors = aspect_ratios.size() * min_sizes.size(); + if (!max_sizes.empty()) { + num_priors += max_sizes.size(); + } + + for (int h = 0; h < feature_height; ++h) { + for (int w = 0; w < feature_width; ++w) { + /// map origin image + float center_x = (w + offset) * step_width; + float center_y = (h + offset) * step_height; + float box_width, box_height; + int idx = 0; + for (size_t s = 0; s < min_sizes.size(); ++s) { + auto min_size = min_sizes[s]; + // priors with different aspect ratios + for (float ar : aspect_ratios) { + box_width = min_size * sqrt(ar) / 2.; + box_height = min_size / sqrt(ar) / 2.; + /// box_width/2 , / img_width 为了得到feature map 相对于 + /// 原图的归一化位置的比例。 + output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 0] = + (center_x - box_width) / img_width; + output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 1] = + (center_y - box_height) / img_height; + output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 2] = + (center_x + box_width) / img_width; + output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 3] = + (center_y + box_height) / img_height; + idx++; + } + if (!max_sizes.empty()) { + auto max_size = max_sizes[s]; + // square prior with size sqrt(minSize * maxSize) + box_width = box_height = sqrt(min_size * max_size) / 2.; + output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 0] = + (center_x - box_width) / img_width; + output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 1] = + (center_y - box_height) / img_height; + output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 2] = + (center_x + box_width) / img_width; + output_boxes_dataptr[h * stride0 + w * stride1 + idx * stride2 + 3] = + (center_y + box_height) / img_height; + idx++; + } + } + } + } + if (clip) { + math::Transform trans; + ClipFunctor clip_func; + trans(output_boxes_dataptr, output_boxes_dataptr + output_boxes->numel(), + output_boxes_dataptr, clip_func); + } + + if ((variances.size() != 4)) { + LOG(kLOG_ERROR) << " variances.size() must be 4."; + } + + int64_t box_num = feature_height * feature_width * num_priors; + + for (int i = 0; i < box_num; i++) { + output_variances_dataptr[4 * i] = variances[0]; + output_variances_dataptr[4 * i + 1] = variances[1]; + output_variances_dataptr[4 * i + 2] = variances[2]; + output_variances_dataptr[4 * i + 3] = variances[3]; + } +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/relu_arm_func.h b/src/operators/kernel/central-arm-func/relu_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..19ccb3e862a29cab79453572b24ed0c5a2a8301d --- /dev/null +++ b/src/operators/kernel/central-arm-func/relu_arm_func.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef RELU_OP +#pragma once + +#include + +namespace paddle_mobile { +namespace operators { + +template +struct ReluFunctor { + inline T operator()(T in) const { return in > 0 ? in : 0; } +}; + +/* + * @b 特化到具体平台的实现, param 从 op 层传入 + * */ +template +void ReluCompute(const ReluParam ¶m) { + const auto *input_x = param.InputX(); + auto *input_x_ptr = input_x->data(); + auto *out = param.Out(); + auto *out_ptr = out->mutable_data(); + + int numel = input_x->numel(); + // if (numel > 64) { + // asm volatile( + // "pld [%[input_x_ptr], #0] \n\t" + // "vmov.f32 q8, #0.0 \n\t" + // "subs %[num], %[num], #32 \n\t" + // "blt end_num_%= \n\t" + // "loop_num_%=: \n\t" + // "pld [%[input_x_ptr], #1024] \n\t" + // + // "vld1.32 {q0, q1}, [%[input_x_ptr]]! \n\t" + // "vld1.32 {q2, q3}, [%[input_x_ptr]]! \n\t" + // "vld1.32 {q4, q5}, [%[input_x_ptr]]! \n\t" + // "vld1.32 {q6, q7}, [%[input_x_ptr]]! \n\t" + // + // "vmax.f32 q0, q0, q8 \n\t" + // "vmax.f32 q1, q1, q8 \n\t" + // "vmax.f32 q2, q2, q8 \n\t" + // "vmax.f32 q3, q3, q8 \n\t" + // "vmax.f32 q4, q4, q8 \n\t" + // "vmax.f32 q5, q5, q8 \n\t" + // "vmax.f32 q6, q6, q8 \n\t" + // "vmax.f32 q7, q7, q8 \n\t" + // + // "vst1.32 {q0, q1}, [%[out_ptr]]! \n\t" + // "vst1.32 {q2, q3}, [%[out_ptr]]! \n\t" + // "vst1.32 {q4, q5}, [%[out_ptr]]! \n\t" + // "vst1.32 {q6, q7}, [%[out_ptr]]! \n\t" + // + // "subs %[num], %[num], #32 \n\t" + // "bge loop_num_%= \n\t" + // "end_num_%=: \n\t" + // "cmp %[num], #0 \n\t" + // "bge end_%= \n\t" + // "mov r6, #4 \n\t" + // "mul r5, %[num], r6 \n\t" + // "add %[input_x_ptr], %[input_x_ptr], r5 \n\t" + // "vld1.32 {q0, q1}, [%[input_x_ptr]]! \n\t" + // "vld1.32 {q2, q3}, [%[input_x_ptr]]! \n\t" + // "vld1.32 {q4, q5}, [%[input_x_ptr]]! \n\t" + // "vld1.32 {q6, q7}, [%[input_x_ptr]]! \n\t" + // "vmax.f32 q0, q0, q8 \n\t" + // "vmax.f32 q1, q1, q8 \n\t" + // "vmax.f32 q2, q2, q8 \n\t" + // "vmax.f32 q3, q3, q8 \n\t" + // "vmax.f32 q4, q4, q8 \n\t" + // "vmax.f32 q5, q5, q8 \n\t" + // "vmax.f32 q6, q6, q8 \n\t" + // "vmax.f32 q7, q7, q8 \n\t" + // "add %[out_ptr], %[out_ptr], r5 \n\t" + // "vst1.32 {q0, q1}, [%[out_ptr]]! \n\t" + // "vst1.32 {q2, q3}, [%[out_ptr]]! \n\t" + // "vst1.32 {q4, q5}, [%[out_ptr]]! \n\t" + // "vst1.32 {q6, q7}, [%[out_ptr]]! \n\t" + // "end_%=: \n\t" + // : + // : + // [out_ptr] "r"(out_ptr), [input_x_ptr] "r"(input_x_ptr), [num] + // "r"(numel) : "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", + // "q7", "q8", "r5", + // "r6"); + // } else { + ReluFunctor func_; + math::Transform trans; + trans(input_x_ptr, input_x_ptr + numel, out_ptr, func_); + // } +} +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/reshape_arm_func.h b/src/operators/kernel/central-arm-func/reshape_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..a2fb836257418923f41e94ceaf499e38033c6b4c --- /dev/null +++ b/src/operators/kernel/central-arm-func/reshape_arm_func.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef RESHAPE_OP +#pragma once + +#include + +namespace paddle_mobile { +namespace operators { + +template +void ReshapeCompute(const ReshapeParam ¶m) { + const auto *input_x = param.InputX(); + const auto &input_x_dims = input_x->dims(); + auto *out = param.Out(); + framework::DDim out_dims = out->dims(); + const auto *input_shape = param.InputShape(); + + if (input_shape) { + auto *shape_data = input_shape->data(); + framework::Tensor cpu_shape_tensor; + auto shape = + std::vector(shape_data, shape_data + input_shape->numel()); + out_dims = ValidateShape(shape, input_x->dims()); + } + + bool inplace = param.Inplace(); + out->Resize(out_dims); + if (!inplace) { + out->mutable_data(); + framework::TensorCopy(*input_x, out); + out->Resize(out_dims); + } else { + out->ShareDataWith(*input_x); + out->Resize(out_dims); + } +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/transpose_arm_func.h b/src/operators/kernel/central-arm-func/transpose_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..1cbebc4525113374061541518775a94c6a64401f --- /dev/null +++ b/src/operators/kernel/central-arm-func/transpose_arm_func.h @@ -0,0 +1,86 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef TRANSPOSE_OP +#pragma once + +#include + +namespace paddle_mobile { +namespace operators { + +// vector pos; +// template +// void TransposeFunc(const int numel, const T* input, const vector axis, +// const vector old_strides, const vector +// new_strides, T* output) { +// for (int i = 0; i < numel; ++i) { +// int old_idx = 0; +// int idx = i; +// for (int j = 0; j < axis.size(); ++j) { +// int order = axis[j]; +// old_idx += (idx / new_strides[j]) * old_strides[order]; +// idx %= new_strides[j]; +// } +// output[i] = input[old_idx]; +// } +// } + +template +void TransposeCompute(const TransposeParam& param) { + const auto* input_x = param.InputX(); + const auto input_x_dims = input_x->dims(); + auto* out = param.Out(); + const auto axis = param.Axis(); + const auto* input_x_data = input_x->data(); + auto* out_data = out->mutable_data(); + + size_t ndim = axis.size(); + std::vector xdim(ndim); + std::vector xstride(ndim); + std::vector xout(ndim); + for (int i = 0; i < ndim; i++) { + int j = ndim - 1 - i; + xdim[j] = input_x_dims[axis[i]]; + xstride[j] = 1; + for (int k = axis[i] + 1; k < ndim; k++) { + xstride[j] *= input_x_dims[k]; + } + xout[j] = xstride[j] * xdim[j]; + } + + auto numel = input_x->numel(); + size_t pind = 0; + std::vector ind(ndim); + for (int i = 0; i < numel; i++) { + out_data[i] = input_x_data[pind]; + ind[0]++; + pind += xstride[0]; + for (int j = 0; j < ndim - 1; j++) { + if (ind[j] == xdim[j]) { + ind[j + 1]++; + ind[j] = 0; + pind += xstride[j + 1]; + pind -= xout[j]; + } else { + break; + } + } + } +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/dropout_kernel.h b/src/operators/kernel/dropout_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..5a3783971959db8fba9ca6b701fb6eb6340fcb3f --- /dev/null +++ b/src/operators/kernel/dropout_kernel.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef DROPOUT_OP + +#include "framework/operator.h" +#include "operators/op_param.h" + +#pragma once; + +namespace paddle_mobile { +namespace operators { + +template +class DropoutKernel : public framework::OpKernelBase { + public: + void Compute(const DropoutParam& param) const; + bool Init(DropoutParam* para); +}; +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/im2sequence_kernel.h b/src/operators/kernel/im2sequence_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..cb592613f73d90dae5a7d6e515f8bc091981776e --- /dev/null +++ b/src/operators/kernel/im2sequence_kernel.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifdef IM2SEQUENCE_OP + +#include "framework/operator.h" +#include "operators/math/im2col.h" +#include "operators/math/math_function.h" +#include "operators/math/vol2col.h" +#include "operators/op_param.h" + +#pragma once; + +namespace paddle_mobile { +namespace operators { + +using namespace framework; + +template +class Im2SequenceKernel + : public framework::OpKernelBase { + public: + void Compute(const Im2SequenceParam& param) const; + bool Init(Im2SequenceParam* para); +}; +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/math/depthwise_conv_3x3.cpp b/src/operators/math/depthwise_conv_3x3.cpp index f74e365c7e087551e55363566d3dbd6ba530bfea..984678e8730ea58d7dc647450dd098d265f0eb39 100644 --- a/src/operators/math/depthwise_conv_3x3.cpp +++ b/src/operators/math/depthwise_conv_3x3.cpp @@ -275,33 +275,40 @@ void DepthwiseConv3x3s1p1(const Tensor *input, const Tensor *filter, float w22 = filter_data_tmp[8]; output_data[0] = w11 * input_data[0] + w12 * input_data[1] + - w21 * input_data[l] + w22 * input_data[l + 1] + - bias_data[j]; + w21 * input_data[l] + w22 * input_data[l + 1]; output_data[l - 1] = w10 * input_data[l - 2] + w11 * input_data[l - 1] + w20 * input_data[2 * l - 2] + - w21 * input_data[2 * l - 1] + bias_data[j]; + w21 * input_data[2 * l - 1]; output_data[(l - 1) * l] = w01 * input_data[(l - 2) * l] + w02 * input_data[(l - 2) * l + 1] + - w11 * input_data[(l - 1) * l] + w12 * input_data[(l - 1) * l + 1] + - bias_data[j]; + w11 * input_data[(l - 1) * l] + w12 * input_data[(l - 1) * l + 1]; output_data[l * l - 1] = w00 * input_data[(l - 2) * (l + 1)] + w01 * input_data[(l - 2) * (l + 1) + 1] + w10 * input_data[l * l - 2] + - w11 * input_data[l * l - 1] + bias_data[j]; + w11 * input_data[l * l - 1]; + if (if_bias) { + output_data[0] += bias_data[j]; + output_data[l - 1] += bias_data[j]; + output_data[(l - 1) * l] += bias_data[j]; + output_data[l * l - 1] += bias_data[j]; + } for (int i = 1; i < l - 1; ++i) { output_data[i * l] = w01 * input_data[i * l - l] + w02 * input_data[i * l - l + 1] + w11 * input_data[i * l] + w12 * input_data[i * l + 1] + - w21 * input_data[i * l + l] + w22 * input_data[i * l + l + 1] + - bias_data[j]; + w21 * input_data[i * l + l] + w22 * input_data[i * l + l + 1]; + output_data[i * l + l - 1] = w00 * input_data[i * l + l - 1 - l - 1] + w01 * input_data[i * l + l - 1 - l] + w10 * input_data[i * l + l - 1 - 1] + w11 * input_data[i * l + l - 1] + w20 * input_data[i * l + l - 1 + l - 1] + - w21 * input_data[i * l + l - 1 + l] + - bias_data[j]; + w21 * input_data[i * l + l - 1 + l]; + if (if_bias) { + output_data[i * l] += bias_data[j]; + output_data[i * l + l - 1] += bias_data[j]; + } } // top 1 row and bottom 1 row @@ -502,12 +509,14 @@ void DepthwiseConv3x3s1p1(const Tensor *input, const Tensor *filter, } } } -void DepthwiseConvAddBNRelu3x3s1p1(const Tensor *input, Tensor filter, + +void DepthwiseConvAddBNRelu3x3s1p1(const Tensor *input, const Tensor *filter, Tensor *output, Tensor *bias, bool if_bias, - Tensor *new_scale, Tensor *new_bias, - bool if_bn, bool if_relu) { + const Tensor *new_scale, + const Tensor *new_bias, bool if_bn, + bool if_relu) { const float *input_data = input->data(); - const float *filter_data = filter.data(); + const float *filter_data = filter->data(); float *output_data = output->data(); const float *bias_data = bias->data(); const float *newscale_data = new_scale->data(); @@ -547,29 +556,35 @@ void DepthwiseConvAddBNRelu3x3s1p1(const Tensor *input, Tensor filter, float w21 = filter_data_tmp[7]; float w22 = filter_data_tmp[8]; - output_data[0] = - (w11 * input_data[0] + w12 * input_data[1] + w21 * input_data[l] + - w22 * input_data[l + 1] + bias_data[j]) * - newscale_data[j] + - newbias_data[j]; - output_data[l - 1] = (w10 * input_data[l - 2] + w11 * input_data[l - 1] + - w20 * input_data[2 * l - 2] + - w21 * input_data[2 * l - 1] + bias_data[j]) * - newscale_data[j] + - newbias_data[j]; + output_data[0] = w11 * input_data[0] + w12 * input_data[1] + + w21 * input_data[l] + w22 * input_data[l + 1]; + + output_data[l - 1] = w10 * input_data[l - 2] + w11 * input_data[l - 1] + + w20 * input_data[2 * l - 2] + + w21 * input_data[2 * l - 1]; output_data[(l - 1) * l] = - (w01 * input_data[(l - 2) * l] + w02 * input_data[(l - 2) * l + 1] + - w11 * input_data[(l - 1) * l] + w12 * input_data[(l - 1) * l + 1] + - bias_data[j]) * - newscale_data[j] + - newbias_data[j]; - output_data[l * l - 1] = (w00 * input_data[(l - 2) * (l + 1)] + - w01 * input_data[(l - 2) * (l + 1) + 1] + - w10 * input_data[l * l - 2] + - w11 * input_data[l * l - 1] + bias_data[j]) * - newscale_data[j] + - newbias_data[j]; + w01 * input_data[(l - 2) * l] + w02 * input_data[(l - 2) * l + 1] + + w11 * input_data[(l - 1) * l] + w12 * input_data[(l - 1) * l + 1]; + output_data[l * l - 1] = w00 * input_data[(l - 2) * (l + 1)] + + w01 * input_data[(l - 2) * (l + 1) + 1] + + w10 * input_data[l * l - 2] + + w11 * input_data[l * l - 1]; + if (if_bias) { + output_data[0] += bias_data[j]; + output_data[l - 1] += bias_data[j]; + output_data[(l - 1) * l] += bias_data[j]; + output_data[l * l - 1] += bias_data[j]; + } + if (if_bn) { + output_data[0] = output_data[0] * newscale_data[j] + newbias_data[j]; + output_data[l - 1] = + output_data[l - 1] * newscale_data[j] + newbias_data[j]; + output_data[(l - 1) * l] = + output_data[(l - 1) * l] * newscale_data[j] + newbias_data[j]; + output_data[l * l - 1] = + output_data[l * l - 1] * newscale_data[j] + newbias_data[j]; + } if (if_relu) { output_data[0] = output_data[0] < 0 ? 0 : output_data[0]; output_data[l - 1] = output_data[l - 1] < 0 ? 0 : output_data[l - 1]; @@ -580,21 +595,25 @@ void DepthwiseConvAddBNRelu3x3s1p1(const Tensor *input, Tensor filter, } for (int i = 1; i < l - 1; ++i) { output_data[i * l] = - (w01 * input_data[i * l - l] + w02 * input_data[i * l - l + 1] + - w11 * input_data[i * l] + w12 * input_data[i * l + 1] + - w21 * input_data[i * l + l] + w22 * input_data[i * l + l + 1] + - bias_data[j]) * - newscale_data[j] + - newbias_data[j]; - output_data[i * l + l - 1] = - (w00 * input_data[i * l + l - 1 - l - 1] + - w01 * input_data[i * l + l - 1 - l] + - w10 * input_data[i * l + l - 1 - 1] + - w11 * input_data[i * l + l - 1] + - w20 * input_data[i * l + l - 1 + l - 1] + - w21 * input_data[i * l + l - 1 + l] + bias_data[j]) * - newscale_data[j] + - newbias_data[j]; + w01 * input_data[i * l - l] + w02 * input_data[i * l - l + 1] + + w11 * input_data[i * l] + w12 * input_data[i * l + 1] + + w21 * input_data[i * l + l] + w22 * input_data[i * l + l + 1]; + output_data[i * l + l - 1] = w00 * input_data[i * l + l - 1 - l - 1] + + w01 * input_data[i * l + l - 1 - l] + + w10 * input_data[i * l + l - 1 - 1] + + w11 * input_data[i * l + l - 1] + + w20 * input_data[i * l + l - 1 + l - 1] + + w21 * input_data[i * l + l - 1 + l]; + if (if_bias) { + output_data[i * l] += bias_data[j]; + output_data[i * l + l - 1] += bias_data[j]; + } + if (if_bn) { + output_data[i * l] = + output_data[i * l] * newscale_data[j] + newbias_data[j]; + output_data[i * l + l - 1] = + output_data[i * l + l - 1] * newscale_data[j] + newbias_data[j]; + } if (if_relu) { output_data[i * l] = output_data[i * l] < 0 ? 0 : output_data[i * l]; output_data[i * l + l - 1] = diff --git a/src/operators/math/depthwise_conv_3x3.h b/src/operators/math/depthwise_conv_3x3.h index 44299295eebad6a90fd994cf74589c09a3573aee..a0beb479926902a71b7e06128aa8cecdd5443196 100644 --- a/src/operators/math/depthwise_conv_3x3.h +++ b/src/operators/math/depthwise_conv_3x3.h @@ -32,10 +32,11 @@ void DepthwiseConv3x3(const Tensor *input, vector strides, Tensor *output, bool if_bias); void DepthwiseConv3x3s1p1(const Tensor *input, const Tensor *filter, Tensor *output, Tensor *bias, bool if_bias); -void DepthwiseConvAddBNRelu3x3s1p1(const Tensor *input, Tensor filter, +void DepthwiseConvAddBNRelu3x3s1p1(const Tensor *input, const Tensor *filter, Tensor *output, Tensor *bias, bool if_bias, - Tensor *new_scale, Tensor *new_bias, - bool if_bn, bool if_relu); + const Tensor *new_scale, + const Tensor *new_bias, bool if_bn, + bool if_relu); } // namespace math } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/op_param.h b/src/operators/op_param.h index 229779a127a8dc828da1a1c7ccb3ffe188073f47..c0f0fbc8a9939bc4609e64359835a685dd4c67f9 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -934,5 +934,57 @@ class FusionConvAddBNReluParam : public OpParam { Print &operator<<(Print &printer, const FusionConvAddParam &conv_param); #endif + +#ifdef IM2SEQUENCE_OP +class Im2SequenceParam : public OpParam { + public: + Im2SequenceParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, const AttributeMap &attrs, + const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + kernels_ = GetAttr>("kernels", attrs); + strides_ = GetAttr>("strides", attrs); + paddings_ = GetAttr>("paddings", attrs); + } + + const Tensor *Input() const { return input_x_; } + + Tensor *Output() const { return out_; } + + const vector &Kernels() const { return kernels_; } + + const vector &Strides() const { return strides_; } + + const vector &Paddings() const { return paddings_; } + + private: + Tensor *input_x_; + Tensor *out_; + vector kernels_; + vector strides_; + vector paddings_; +}; +#endif + +#ifdef DROPOUT_OP +class DropoutParam : public OpParam { + public: + DropoutParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + } + + const Tensor *InputX() const { return input_x_; } + + Tensor *Out() const { return out_; } + + private: + Tensor *input_x_; + Tensor *out_; +}; +#endif + } // namespace operators } // namespace paddle_mobile diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9bfc55c93daa2f69200941bfb49a8a6312fa9eb1..09d1ff031f2d29eb64c83d43724b1039fce9385f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,23 +1,23 @@ set(dir ${CMAKE_CURRENT_SOURCE_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${dir}/build") -if (googlenet) +if (NET STREQUAL "googlenet") # gen test ADD_EXECUTABLE(test-googlenet net/test_googlenet.cpp test_helper.h test_include.h executor_for_test.h) target_link_libraries(test-googlenet paddle-mobile) -elseif (mobilenet) +elseif (NET STREQUAL "mobilenet") # gen test ADD_EXECUTABLE(test-mobilenet net/test_mobilenet.cpp test_helper.h test_include.h executor_for_test.h) target_link_libraries(test-mobilenet paddle-mobile) -elseif (yolo) +elseif (NET STREQUAL "yolo") # gen test ADD_EXECUTABLE(test-yolo net/test_yolo.cpp test_helper.h test_include.h executor_for_test.h) target_link_libraries(test-yolo paddle-mobile) -elseif (squeezenet) +elseif (NET STREQUAL "squeezenet") # gen test ADD_EXECUTABLE(test-squeezenet net/test_squeezenet.cpp test_helper.h test_include.h executor_for_test.h) target_link_libraries(test-squeezenet paddle-mobile) -elseif(resnet) +elseif(NET STREQUAL "resnet") # gen test ADD_EXECUTABLE(test-resnet net/test_resnet.cpp test_helper.h test_include.h executor_for_test.h) target_link_libraries(test-resnet paddle-mobile) diff --git a/test/executor_for_test.h b/test/executor_for_test.h index 0d3051327a57202e2b8d1dcbdda571fd244de108..c9ab4783d6826992ee81ffd63b0391169645576c 100644 --- a/test/executor_for_test.h +++ b/test/executor_for_test.h @@ -19,7 +19,7 @@ limitations under the License. */ #include "common/log.h" #include "framework/op_registry.h" -#include "io/io.h" +#include "io/executor.h" #include "operators/conv_op.h" #include "operators/elementwise_add_op.h" #include "operators/pool_op.h" diff --git a/test/framework/test_load.cpp b/test/framework/test_load.cpp index 8c76eb1dde3ef39a342d19e7f3d4e26fc1be2b2f..f4215de46c2bafd732b0092b58c25bf6fcefdf7a 100644 --- a/test/framework/test_load.cpp +++ b/test/framework/test_load.cpp @@ -13,13 +13,13 @@ See the License for the specific language governing permissions and limitations under the License. */ #include "../test_helper.h" -#include "io/io.h" +#include "io/loader.h" int main() { paddle_mobile::Loader loader; // ../../../test/models/googlenet // ../../../test/models/mobilenet - auto program = loader.Load(g_mobilenet_ssd, false, false); + auto program = loader.Load(g_googlenet, true); // auto program = loader.Load(g_googlenet_combine + "/model", // g_googlenet_combine + // "/params", true); diff --git a/test/framework/test_optimize.cpp b/test/framework/test_optimize.cpp index 32574764e1ba538ab0bea31d1e238096e7098dfc..3cae963eca048da221d69c4c336dd4fdfecbb584 100644 --- a/test/framework/test_optimize.cpp +++ b/test/framework/test_optimize.cpp @@ -15,7 +15,7 @@ limitations under the License. */ #include "../test_helper.h" #include "framework/program/program-optimize/node.h" #include "framework/program/program-optimize/program_optimize.h" -#include "io/io.h" +#include "io/loader.h" int main() { paddle_mobile::Loader loader; diff --git a/test/net/test_googlenet.cpp b/test/net/test_googlenet.cpp index d0a5979516d3256d2ddfc7b042a18ab119d6a202..c6b99a2ed0d76a8e73c4393e67a679b435b9325f 100644 --- a/test/net/test_googlenet.cpp +++ b/test/net/test_googlenet.cpp @@ -17,25 +17,25 @@ limitations under the License. */ #include "../test_include.h" int main() { - paddle_mobile::Loader loader; + paddle_mobile::PaddleMobile paddle_mobile; bool optimize = true; auto time1 = time(); // auto program = loader.Load(g_googlenet, optimize); - auto program = loader.Load(g_googlenet_combine + "/model", - g_googlenet_combine + "/params", optimize); - auto time2 = time(); - DLOG << "load cost :" << time_diff(time1, time2) << "ms\n"; - paddle_mobile::Executor executor(program, 1, optimize); - std::vector input; - std::vector dims{1, 3, 224, 224}; - GetInput(g_test_image_1x3x224x224, &input, dims); - auto time3 = time(); - int count = 1; - for (int i = 0; i < count; i++) { - executor.Predict(input, dims); - } + if (paddle_mobile.Load(g_googlenet_combine + "/model", + g_googlenet_combine + "/params", optimize)) { + auto time2 = time(); + DLOG << "load cost :" << time_diff(time1, time2) << "ms\n"; + std::vector input; + std::vector dims{1, 3, 224, 224}; + GetInput(g_test_image_1x3x224x224, &input, dims); + auto time3 = time(); + + for (int i = 0; i < 10; ++i) { + paddle_mobile.Predict(input, dims); + } - auto time4 = time(); - DLOG << "avg predict cost :" << time_diff(time3, time4) / count << "ms\n"; + auto time4 = time(); + DLOG << "predict cost :" << time_diff(time3, time4) << "ms\n"; + } return 0; } diff --git a/test/net/test_mobilenet+ssd.cpp b/test/net/test_mobilenet+ssd.cpp index 097d03ad710468a881050ff729e8352f029d664f..1a7c4cd49cb1707b9c7783cf74e87e74da39732e 100644 --- a/test/net/test_mobilenet+ssd.cpp +++ b/test/net/test_mobilenet+ssd.cpp @@ -17,23 +17,23 @@ limitations under the License. */ #include "../test_include.h" int main() { - paddle_mobile::Loader loader; + paddle_mobile::PaddleMobile paddle_mobile; auto time1 = time(); - auto program = loader.Load(g_mobilenet_ssd, true); - auto time2 = time(); - DLOG << "load cost :" << time_diff(time1, time1) << "ms"; - paddle_mobile::Executor executor(program, 1, true); + if (paddle_mobile.Load(g_mobilenet_ssd, true)) { + auto time2 = time(); + DLOG << "load cost :" << time_diff(time1, time1) << "ms"; - std::vector dims{1, 3, 300, 300}; - Tensor input_tensor; - SetupTensor(&input_tensor, {1, 3, 300, 300}, static_cast(0), - static_cast(1)); + std::vector dims{1, 3, 300, 300}; + Tensor input_tensor; + SetupTensor(&input_tensor, {1, 3, 300, 300}, static_cast(0), + static_cast(1)); - std::vector input(input_tensor.data(), - input_tensor.data() + input_tensor.numel()); - auto time3 = time(); - executor.Predict(input, dims); - auto time4 = time(); - DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; + std::vector input(input_tensor.data(), + input_tensor.data() + input_tensor.numel()); + auto time3 = time(); + paddle_mobile.Predict(input, dims); + auto time4 = time(); + DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; + } return 0; } diff --git a/test/net/test_mobilenet.cpp b/test/net/test_mobilenet.cpp index 2495fb497e679d75128f3a74fdbb8da98b927f9f..1f38dc5d19d0e7bb54faf75a41419941e8b1f412 100644 --- a/test/net/test_mobilenet.cpp +++ b/test/net/test_mobilenet.cpp @@ -17,24 +17,25 @@ limitations under the License. */ #include "../test_include.h" int main() { - paddle_mobile::Loader loader; + paddle_mobile::PaddleMobile paddle_mobile; auto time1 = time(); - auto program = loader.Load(g_mobilenet, true); - auto time2 = time(); - DLOG << "load cost :" << time_diff(time1, time1) << "ms"; - paddle_mobile::Executor executor(program, 1, true); - - std::vector dims{1, 3, 224, 224}; - Tensor input_tensor; - SetupTensor(&input_tensor, {1, 3, 224, 224}, static_cast(0), - static_cast(1)); - - std::vector input(input_tensor.data(), - input_tensor.data() + input_tensor.numel()); - auto time3 = time(); - auto vec_result = executor.Predict(input, dims); - auto time4 = time(); - - DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; + if (paddle_mobile.Load(g_mobilenet, true)) { + auto time2 = time(); + DLOG << "load cost :" << time_diff(time1, time1) << "ms"; + + std::vector dims{1, 3, 224, 224}; + Tensor input_tensor; + SetupTensor(&input_tensor, {1, 3, 224, 224}, static_cast(0), + static_cast(1)); + + std::vector input(input_tensor.data(), + input_tensor.data() + input_tensor.numel()); + auto time3 = time(); + auto vec_result = paddle_mobile.Predict(input, dims); + auto time4 = time(); + + DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; + } + return 0; } diff --git a/test/net/test_resnet.cpp b/test/net/test_resnet.cpp index 55f4c5efef209c421fc550c1f17422acd64b11b9..883ad95392ad351a2634e1a56ac050f02d8767e6 100644 --- a/test/net/test_resnet.cpp +++ b/test/net/test_resnet.cpp @@ -17,23 +17,23 @@ limitations under the License. */ #include "../test_include.h" int main() { - paddle_mobile::Loader loader; + paddle_mobile::PaddleMobile paddle_mobile; auto time1 = time(); - auto program = loader.Load(g_resnet, false); - auto time2 = time(); - DLOG << "load cost :" << time_diff(time1, time1) << "ms"; - paddle_mobile::Executor executor(program, 1, false); + if (paddle_mobile.Load(g_resnet, false)) { + auto time2 = time(); + DLOG << "load cost :" << time_diff(time1, time1) << "ms"; + std::vector dims{1, 3, 32, 32}; + Tensor input_tensor; + SetupTensor(&input_tensor, {1, 3, 32, 32}, static_cast(0), + static_cast(1)); - std::vector dims{1, 3, 32, 32}; - Tensor input_tensor; - SetupTensor(&input_tensor, {1, 3, 32, 32}, static_cast(0), - static_cast(1)); + std::vector input(input_tensor.data(), + input_tensor.data() + input_tensor.numel()); + auto time3 = time(); + paddle_mobile.Predict(input, dims); + auto time4 = time(); + DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; + } - std::vector input(input_tensor.data(), - input_tensor.data() + input_tensor.numel()); - auto time3 = time(); - executor.Predict(input, dims); - auto time4 = time(); - DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; return 0; } diff --git a/test/net/test_squeezenet.cpp b/test/net/test_squeezenet.cpp index 30460018fe8cc008e0031c1c713150745767fa28..39d4687ff3de37c571ee89213485fb0b6bc939df 100644 --- a/test/net/test_squeezenet.cpp +++ b/test/net/test_squeezenet.cpp @@ -17,25 +17,25 @@ limitations under the License. */ #include "../test_include.h" int main() { - paddle_mobile::Loader loader; + paddle_mobile::PaddleMobile paddle_mobile; // ../../../test/models/googlenet // ../../../test/models/mobilenet auto time1 = time(); - auto program = loader.Load(g_squeezenet, false); - auto time2 = time(); - DLOG << "load cost :" << time_diff(time1, time1) << "ms"; - paddle_mobile::Executor executor(program, 1, false); + if (paddle_mobile.Load(g_squeezenet, false)) { + auto time2 = time(); + DLOG << "load cost :" << time_diff(time1, time1) << "ms"; + std::vector dims{1, 3, 227, 227}; + Tensor input_tensor; + SetupTensor(&input_tensor, {1, 3, 227, 227}, static_cast(0), + static_cast(1)); - std::vector dims{1, 3, 227, 227}; - Tensor input_tensor; - SetupTensor(&input_tensor, {1, 3, 227, 227}, static_cast(0), - static_cast(1)); + std::vector input(input_tensor.data(), + input_tensor.data() + input_tensor.numel()); + auto time3 = time(); + paddle_mobile.Predict(input, dims); + auto time4 = time(); + DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; + } - std::vector input(input_tensor.data(), - input_tensor.data() + input_tensor.numel()); - auto time3 = time(); - executor.Predict(input, dims); - auto time4 = time(); - DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; return 0; } diff --git a/test/net/test_yolo.cpp b/test/net/test_yolo.cpp index c82443e23953def917826fe4ec3b2c484b588f59..65dec59ad0579d362c75ae6ec1d362fb957d4fc5 100644 --- a/test/net/test_yolo.cpp +++ b/test/net/test_yolo.cpp @@ -17,25 +17,25 @@ limitations under the License. */ #include "../test_include.h" int main() { - paddle_mobile::Loader loader; + paddle_mobile::PaddleMobile paddle_mobile; // ../../../test/models/googlenet // ../../../test/models/mobilenet auto time1 = time(); - auto program = loader.Load(g_yolo, false); - auto time2 = time(); - DLOG << "load cost :" << time_diff(time1, time1) << "ms"; - paddle_mobile::Executor executor(program, 1, false); + if (paddle_mobile.Load(g_yolo, false)) { + auto time2 = time(); + DLOG << "load cost :" << time_diff(time1, time1) << "ms"; - std::vector dims{1, 3, 227, 227}; - Tensor input_tensor; - SetupTensor(&input_tensor, {1, 3, 227, 227}, static_cast(0), - static_cast(1)); + std::vector dims{1, 3, 227, 227}; + Tensor input_tensor; + SetupTensor(&input_tensor, {1, 3, 227, 227}, static_cast(0), + static_cast(1)); - std::vector input(input_tensor.data(), - input_tensor.data() + input_tensor.numel()); - auto time3 = time(); - executor.Predict(input, dims); - auto time4 = time(); - DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; + std::vector input(input_tensor.data(), + input_tensor.data() + input_tensor.numel()); + auto time3 = time(); + paddle_mobile.Predict(input, dims); + auto time4 = time(); + DLOG << "predict cost :" << time_diff(time3, time4) << "ms"; + } return 0; } diff --git a/test/operators/test_im2sequence_op.cpp b/test/operators/test_im2sequence_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a7512d3bf3cffcb100fe292e50fc7b7b23fa0aa0 --- /dev/null +++ b/test/operators/test_im2sequence_op.cpp @@ -0,0 +1,62 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#include "../executor_for_test.h" +#include "../test_include.h" +#include "operators/im2sequence_op.h" + +int main() { + paddle_mobile::Loader loader; + auto program = loader.Load(g_ocr_recg); + PADDLE_MOBILE_ENFORCE(program.originProgram != nullptr, + "program file read fail"); + + Executor4Test> + executor(program, "im2sequence"); + + // 1. input_tensors; + vector input_tensors; + + Tensor input1; + auto input1_data = CreateInput(&input1, {2, 2, 3, 3}, -1, 1); + input_tensors.push_back(input1); + + // 2. input_names + vector input_names({ + "conv2d_19.tmp_1", + }); + + // 3. output_names + vector output_names({"im2sequence_0.tmp_0"}); + + // 4. out_dims; + vector out_ddims; + auto out_ddim = paddle_mobile::framework::make_ddim({8, 9}); + out_ddims.push_back(out_ddim); + + auto output = executor.Predict(input_tensors, input_names, + output_names, out_ddims); + + auto output0_data = output[0]->data(); + + for (int j = 0; j < input_tensors[0].numel(); ++j) { + DLOG << " value of input: " << input1_data[j]; + } + + for (int j = 0; j < output[0]->numel(); ++j) { + DLOG << " value of output: " << output0_data[j]; + } + return 0; +} diff --git a/test/operators/test_sigmoid_op.cpp b/test/operators/test_sigmoid_op.cpp index 4ed3efaf28aa986f0b679729c46cb386150583e3..c8fac6b9eee5c5777ddb0147bc81d361d4dd09f5 100644 --- a/test/operators/test_sigmoid_op.cpp +++ b/test/operators/test_sigmoid_op.cpp @@ -14,7 +14,7 @@ limitations under the License. */ #include "../../src/operators/kernel/sigmoid_kernel.h" #include "../test_helper.h" -#include "io/io.h" +#include "io/executor.h" int main() { paddle_mobile::framework::Tensor input; diff --git a/test/test_include.h b/test/test_include.h index 2d89dc8c9ed1de1ad49ebca07724b6649e2a12a7..4728a469334010e7353e6ab1f3695ec23f3e7456 100644 --- a/test/test_include.h +++ b/test/test_include.h @@ -30,4 +30,4 @@ limitations under the License. */ #include "framework/scope.h" #include "framework/tensor.h" #include "framework/variable.h" -#include "io/io.h" +#include "io/paddle_mobile.h" diff --git a/tools/build.sh b/tools/build.sh index 86ae8b5e1aa16c7cab66580bc2eaa6e1e526fc17..80caa4011821270549598aa898b0d31b30b437e6 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -60,7 +60,6 @@ build_for_android() { TOOLCHAIN_FILE="./tools/android-cmake/android.toolchain.cmake" ANDROID_ARM_MODE="arm" if [ $# -eq 1 ]; then - NET=$1 cmake .. \ -B"../build/release/${PLATFORM}" \ -DANDROID_ABI="${ABI}" \ @@ -70,7 +69,7 @@ build_for_android() { -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" \ -DANDROID_STL=c++_static \ -DANDROID=true \ - -D"${NET}=true" \ + -DNET=$1 \ -D"${ARM_PLATFORM}"=true else @@ -99,7 +98,6 @@ build_for_ios() { CXX_FLAGS="-fobjc-abi-version=2 -fobjc-arc -std=gnu++14 -stdlib=libc++ -isysroot ${CMAKE_OSX_SYSROOT}" mkdir -p "${BUILD_DIR}" if [ $# -eq 1 ]; then - NET=$1 cmake .. \ -B"${BUILD_DIR}" \ -DCMAKE_BUILD_TYPE="${MODE}" \ @@ -107,7 +105,7 @@ build_for_ios() { -DIOS_PLATFORM=OS \ -DCMAKE_C_FLAGS="${C_FLAGS}" \ -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" \ - -D"${NET}"=true \ + -DNET=$1 \ -DIS_IOS="true" else cmake .. \ @@ -129,16 +127,12 @@ build_error() { if [ $# -lt 1 ]; then echo "error: target missing!" - echo "available targets: mac|linux|ios|android" - echo "sample usage: ./build.sh mac" + echo "available targets: ios|android" + echo "sample usage: ./build.sh android" else if [ $# -eq 2 ]; then if [ $2 != "googlenet" -a $2 != "mobilenet" -a $2 != "yolo" -a $2 != "squeezenet" -a $2 != "resnet" ]; then - if [ $1 = "mac" ]; then - build_for_mac - elif [ $1 = "linux" ]; then - build_for_linux - elif [ $1 = "android" ]; then + if [ $1 = "android" ]; then build_for_android elif [ $1 = "ios" ]; then build_for_ios @@ -146,11 +140,7 @@ else build_error fi else - if [ $1 = "mac" ]; then - build_for_mac $2 - elif [ $1 = "linux" ]; then - build_for_linux $2 - elif [ $1 = "android" ]; then + if [ $1 = "android" ]; then build_for_android $2 elif [ $1 = "ios" ]; then build_for_ios $2 @@ -159,11 +149,7 @@ else fi fi else - if [ $1 = "mac" ]; then - build_for_mac - elif [ $1 = "linux" ]; then - build_for_linux - elif [ $1 = "android" ]; then + if [ $1 = "android" ]; then build_for_android elif [ $1 = "ios" ]; then build_for_ios diff --git a/tools/op.cmake b/tools/op.cmake index c7d1840bc552d6b45fe2fcc9f8d19e6784598ee6..e5b006ee0e890307275dcd472a2e31f51c3fb891 100644 --- a/tools/op.cmake +++ b/tools/op.cmake @@ -1,7 +1,4 @@ -set(NET "googlenet" CACHE STRING "select net type") -set_property(CACHE NET PROPERTY STRINGS "defult" "googlenet" "mobilenet" "yolo" "squeezenet") - -if (NET EQUAL "googlenet") +if (NET STREQUAL "googlenet") set(CONCAT_OP ON) set(CONV_OP ON) set(LRN_OP ON) @@ -12,7 +9,7 @@ if (NET EQUAL "googlenet") set(RELU_OP ON) set(FUSION_CONVADD_OP ON) set(FUSION_CONVADD_RELU_OP ON) -elseif (NET EQUAL "mobilenet") +elseif (NET STREQUAL "mobilenet") set(CONV_OP ON) set(ELEMENTWISEADD_OP ON) set(RELU_OP ON) @@ -23,12 +20,12 @@ elseif (NET EQUAL "mobilenet") set(POOL_OP ON) set(RESHAPE_OP ON) set(FUSION_CONVADDBNRELU_OP) -elseif (NET EQUAL "yolo") +elseif (NET STREQUAL "yolo") set(BATCHNORM_OP ON) set(CONV_OP ON) set(RELU_OP ON) set(ELEMENTWISEADD_OP ON) -elseif (NET EQUAL "squeezenet") +elseif (NET STREQUAL "squeezenet") set(CONCAT_OP ON) set(CONV_OP ON) set(RELU_OP ON) @@ -36,7 +33,7 @@ elseif (NET EQUAL "squeezenet") set(POOL_OP ON) set(RESHAPE_OP ON) set(SOFTMAX_OP ON) -elseif (NET EQUAL "resnet") +elseif (NET STREQUAL "resnet") set(CONV_OP ON) set(BATCHNORM_OP ON) set(ELEMENTWISEADD_OP ON) @@ -66,7 +63,8 @@ else () set(TRANSPOSE_OP ON) set(FUSION_CONVADD_RELU_OP ON) set(FUSION_CONVADDBNRELU_OP ON) - + set(DROPOUT_OP ON) + set(IM2SEQUENCE_OP ON) # option(BATCHNORM_OP "" ON) # option(BOXCODER_OP "" ON) # option(CONCAT_OP "" ON) @@ -152,3 +150,9 @@ endif() if (FUSION_CONVADDBNRELU_OP) add_definitions(-DFUSION_CONVADDBNRELU_OP) endif() +if (DROPOUT_OP) + add_definitions(-DDROPOUT_OP) +endif() +if (IM2SEQUENCE_OP) + add_definitions(-DIM2SEQUENCE_OP) +endif()