This tutorial will walk you through cross compiling the PaddlePaddle library for iOS from the source in MacOS.
## Preparation
Apple provides Xcode for cross-compiling and IDE for iOS development. Download from App store or [here](https://developer.apple.com/cn/xcode/). To verify your installation, run command as follows
```bash
$ xcodebuild -version
Xcode 9.0
Build version 9A235
```
## Cross-compiling configurations
PaddlePaddle provides cross-compiling toolchain configuration documentation [cmake/cross_compiling/ios.cmake](https://github.com/PaddlePaddle/Paddle/blob/develop/cmake/cross_compiling/ios.cmake), which has some default settings for frequently used compilers.
There are some mandatory environment variables need to be set before cross compiling PaddlePaddle for iOS:
- `CMAKE_SYSTEM_NAME`, CMake compiling target platform name, has to be `iOS`. PaddlePaddle CMake will compile all the third party dependencies and enforce some parameters (`WITH_C_API=ON`、`WITH_GPU=OFF`、`WITH_AVX=OFF`、`WITH_PYTHON=OFF`、`WITH_RDMA=OFF`) when this variable is set with value `iOS`.
- `WITH_C_API`, Whether to compile inference C-API library, has to be `ON`, since C-API is the only supported interface for inferencing in iOS.
- `WITH_SWIG_PY`, has to be `ON`. It's not supported to inference or train via swig in iOS.
Optional environment variables for iOS are:
- `IOS_PLATFORM`, either `OS` (default) or `SIMULATOR`.
- `OS`, build targets ARM-based physical devices like iPhone or iPad.
- `SIMULATOR`, build targets x86 architecture simulators.
- `IOS_ARCH`, target architecture. By default, all architecture types will be compiled. If you need to specify the architecture to compile for, please find valid values for different `IOS_PLATFORM` settings from the table below:
<table class="docutils">
<colgroup>
<col width="35%" />
<col width="65%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd">
<th class="head">IOS_PLATFORM</th>
<th class="head">IOS_ARCH</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even">
<td>OS</td>
<td>armv7, armv7s, arm64 </td>
</tr>
<tr class="row-odd">
<td>SIMULATOR</td>
<td>i386, x86_64 </td>
</tr>
</tbody>
</table>
- `IOS_DEPLOYMENT_TARGET`, minimum iOS version to deployment, `7.0` by default.
- `IOS_ENABLE_BITCODE`, whether to enable [Bitcode](https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/AppThinning/AppThinning.html#//apple_ref/doc/uid/TP40012582-CH35-SW3), values can be `ON/OFF`, `ON` by default.
- `IOS_USE_VECLIB_FOR_BLAS`, whether to use [vecLib](https://developer.apple.com/documentation/accelerate/veclib) framework for BLAS computing. values can be `ON/OFF`, `OFF` by default.
- `IOS_DEVELOPMENT_ROOT`, the path to `Developer` directory, can be explicitly set with your `/path/to/platform/Developer`. If left blank, PaddlePaddle will automatically pick the Xcode corresponding `platform`'s `Developer` directory based on your `IOS_PLATFORM` value.
- `IOS_SDK_ROOT`, the path to `SDK` root, can be explicitly set with your `/path/to/platform/Developer/SDKs/SDK`. if left black, PaddlePaddle will pick the latest SDK in the directory of `IOS_DEVELOPMENT_ROOT`.
other settings:
- `USE_EIGEN_FOR_BLAS`, whether to use Eigen for matrix computing. effective when `IOS_USE_VECLIB_FOR_BLAS=OFF`. Values can be `ON/OFF`, `OFF` by default.
- `HOST_C/CXX_COMPILER`, host C/C++ compiler. Uses value from environment variable `CC/CXX` by default or `cc/c++` if `CC/CXX` doesn't exist.
some typical cmake configurations:
```bash
cmake -DCMAKE_SYSTEM_NAME=iOS \
-DIOS_PLATFORM=OS \
-DIOS_ARCH="armv7;arm64" \
-DIOS_ENABLE_BITCODE=ON \
-DIOS_USE_VECLIB_FOR_BLAS=ON \
-DCMAKE_INSTALL_PREFIX=your/path/to/install \
-DWITH_C_API=ON \
-DWITH_TESTING=OFF \
-DWITH_SWIG_PY=OFF \
..
```
```bash
cmake -DCMAKE_SYSTEM_NAME=iOS \
-DIOS_PLATFORM=SIMULATOR \
-DIOS_ARCH="x86_64" \
-DIOS_USE_VECLIB_FOR_BLAS=ON \
-DCMAKE_INSTALL_PREFIX=your/path/to/install \
-DWITH_C_API=ON \
-DWITH_TESTING=OFF \
-DWITH_SWIG_PY=OFF \
..
```
You can set other compiling parameters for your own need. I.E. if you are trying to minimize the library size, set `CMAKE_BUILD_TYPE` with `MinSizeRel`; or if the performance is your concern, set `CMAKE_BUILD_TYPE` with `Release`. You can even manipulate the PaddlePaddle compiling procedure by manually set `CMAKE_C/CXX_FLAGS` values.
**TIPS for a better performance**:
- set `CMAKE_BUILD_TYPE` with `Release`
- set `IOS_USE_VECLIB_FOR_BLAS` with `ON`
## Compile and install
After CMake, run following commands, PaddlePaddle will download the compile 3rd party dependencies, compile and install PaddlePaddle inference library.
```
$ make
$ make install
```
Please Note: if you compiled PaddlePaddle in the source directory for other platforms, do remove `third_party` and `build` directory within the source with `rm -rf` to ensure that all the 3rd party libraries dependencies and PaddlePaddle is newly compiled with current CMake configuration.
`your/path/to/install` directory will have following directories after `compile` and `install`:
- `third_party` contains all the 3rd party libraries.
Please note: if PaddlePaddle library need to support both physical devices and simulators, you will need to compile correspondingly, then merge fat library with `lipo`
Now you will have PaddlePaddle library compiled and installed, the fat library can be used in deep learning related iOS APPs. Please refer to C-API documentation for usage guides.
<liclass="toctree-l2"><aclass="reference internal"href="../howto/usage/k8s/k8s_en.html">Paddle On Kubernetes</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="../howto/usage/k8s/k8s_aws_en.html">Distributed PaddlePaddle Training on AWS with Kubernetes</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="../howto/dev/new_layer_en.html">Write New Layers</a></li>
<spanid="paddlepaddle-compiling-guide-for-ios"></span><h1>PaddlePaddle Compiling Guide for iOS<aclass="headerlink"href="#paddlepaddle-compiling-guide-for-ios"title="Permalink to this headline">¶</a></h1>
<p>This tutorial will walk you through cross compiling the PaddlePaddle library for iOS from the source in MacOS.</p>
<divclass="section"id="preparation">
<spanid="preparation"></span><h2>Preparation<aclass="headerlink"href="#preparation"title="Permalink to this headline">¶</a></h2>
<p>Apple provides Xcode for cross-compiling and IDE for iOS development. Download from App store or <aclass="reference external"href="https://developer.apple.com/cn/xcode/">here</a>. To verify your installation, run command as follows</p>
<spanid="cross-compiling-configurations"></span><h2>Cross-compiling configurations<aclass="headerlink"href="#cross-compiling-configurations"title="Permalink to this headline">¶</a></h2>
<p>PaddlePaddle provides cross-compiling toolchain configuration documentation <aclass="reference external"href="https://github.com/PaddlePaddle/Paddle/blob/develop/cmake/cross_compiling/ios.cmake">cmake/cross_compiling/ios.cmake</a>, which has some default settings for frequently used compilers.</p>
<p>There are some mandatory environment variables need to be set before cross compiling PaddlePaddle for iOS:</p>
<ulclass="simple">
<li><codeclass="docutils literal"><spanclass="pre">CMAKE_SYSTEM_NAME</span></code>, CMake compiling target platform name, has to be <codeclass="docutils literal"><spanclass="pre">iOS</span></code>. PaddlePaddle CMake will compile all the third party dependencies and enforce some parameters (<codeclass="docutils literal"><spanclass="pre">WITH_C_API=ON</span></code>、<codeclass="docutils literal"><spanclass="pre">WITH_GPU=OFF</span></code>、<codeclass="docutils literal"><spanclass="pre">WITH_AVX=OFF</span></code>、<codeclass="docutils literal"><spanclass="pre">WITH_PYTHON=OFF</span></code>、<codeclass="docutils literal"><spanclass="pre">WITH_RDMA=OFF</span></code>) when this variable is set with value <codeclass="docutils literal"><spanclass="pre">iOS</span></code>.</li>
<li><codeclass="docutils literal"><spanclass="pre">WITH_C_API</span></code>, Whether to compile inference C-API library, has to be <codeclass="docutils literal"><spanclass="pre">ON</span></code>, since C-API is the only supported interface for inferencing in iOS.</li>
<li><codeclass="docutils literal"><spanclass="pre">WITH_SWIG_PY</span></code>, has to be <codeclass="docutils literal"><spanclass="pre">ON</span></code>. It’s not supported to inference or train via swig in iOS.</li>
</ul>
<p>Optional environment variables for iOS are:</p>
<ul>
<li><pclass="first"><codeclass="docutils literal"><spanclass="pre">IOS_PLATFORM</span></code>, either <codeclass="docutils literal"><spanclass="pre">OS</span></code> (default) or <codeclass="docutils literal"><spanclass="pre">SIMULATOR</span></code>.</p>
<ulclass="simple">
<li><codeclass="docutils literal"><spanclass="pre">OS</span></code>, build targets ARM-based physical devices like iPhone or iPad.</li>
<li><codeclass="docutils literal"><spanclass="pre">SIMULATOR</span></code>, build targets x86 architecture simulators.</li>
</ul>
</li>
<li><pclass="first"><codeclass="docutils literal"><spanclass="pre">IOS_ARCH</span></code>, target architecture. By default, all architecture types will be compiled. If you need to specify the architecture to compile for, please find valid values for different <codeclass="docutils literal"><spanclass="pre">IOS_PLATFORM</span></code> settings from the table below:</p>
<tableclass="docutils">
<colgroup>
<colwidth="35%"/>
<colwidth="65%"/>
</colgroup>
<theadvalign="bottom">
<trclass="row-odd">
<thclass="head">IOS_PLATFORM</th>
<thclass="head">IOS_ARCH</th>
</tr>
</thead>
<tbodyvalign="top">
<trclass="row-even">
<td>OS</td>
<td>armv7, armv7s, arm64 </td>
</tr>
<trclass="row-odd">
<td>SIMULATOR</td>
<td>i386, x86_64 </td>
</tr>
</tbody>
</table></li>
<li><pclass="first"><codeclass="docutils literal"><spanclass="pre">IOS_DEPLOYMENT_TARGET</span></code>, minimum iOS version to deployment, <codeclass="docutils literal"><spanclass="pre">7.0</span></code> by default.</p>
</li>
<li><pclass="first"><codeclass="docutils literal"><spanclass="pre">IOS_ENABLE_BITCODE</span></code>, whether to enable <aclass="reference external"href="https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/AppThinning/AppThinning.html#//apple_ref/doc/uid/TP40012582-CH35-SW3">Bitcode</a>, values can be <codeclass="docutils literal"><spanclass="pre">ON/OFF</span></code>, <codeclass="docutils literal"><spanclass="pre">ON</span></code> by default.</p>
</li>
<li><pclass="first"><codeclass="docutils literal"><spanclass="pre">IOS_USE_VECLIB_FOR_BLAS</span></code>, whether to use <aclass="reference external"href="https://developer.apple.com/documentation/accelerate/veclib">vecLib</a> framework for BLAS computing. values can be <codeclass="docutils literal"><spanclass="pre">ON/OFF</span></code>, <codeclass="docutils literal"><spanclass="pre">OFF</span></code> by default.</p>
</li>
<li><pclass="first"><codeclass="docutils literal"><spanclass="pre">IOS_DEVELOPMENT_ROOT</span></code>, the path to <codeclass="docutils literal"><spanclass="pre">Developer</span></code> directory, can be explicitly set with your <codeclass="docutils literal"><spanclass="pre">/path/to/platform/Developer</span></code>. If left blank, PaddlePaddle will automatically pick the Xcode corresponding <codeclass="docutils literal"><spanclass="pre">platform</span></code>‘s <codeclass="docutils literal"><spanclass="pre">Developer</span></code> directory based on your <codeclass="docutils literal"><spanclass="pre">IOS_PLATFORM</span></code> value.</p>
</li>
<li><pclass="first"><codeclass="docutils literal"><spanclass="pre">IOS_SDK_ROOT</span></code>, the path to <codeclass="docutils literal"><spanclass="pre">SDK</span></code> root, can be explicitly set with your <codeclass="docutils literal"><spanclass="pre">/path/to/platform/Developer/SDKs/SDK</span></code>. if left black, PaddlePaddle will pick the latest SDK in the directory of <codeclass="docutils literal"><spanclass="pre">IOS_DEVELOPMENT_ROOT</span></code>.</p>
</li>
</ul>
<p>other settings:</p>
<ulclass="simple">
<li><codeclass="docutils literal"><spanclass="pre">USE_EIGEN_FOR_BLAS</span></code>, whether to use Eigen for matrix computing. effective when <codeclass="docutils literal"><spanclass="pre">IOS_USE_VECLIB_FOR_BLAS=OFF</span></code>. Values can be <codeclass="docutils literal"><spanclass="pre">ON/OFF</span></code>, <codeclass="docutils literal"><spanclass="pre">OFF</span></code> by default.</li>
<li><codeclass="docutils literal"><spanclass="pre">HOST_C/CXX_COMPILER</span></code>, host C/C++ compiler. Uses value from environment variable <codeclass="docutils literal"><spanclass="pre">CC/CXX</span></code> by default or <codeclass="docutils literal"><spanclass="pre">cc/c++</span></code> if <codeclass="docutils literal"><spanclass="pre">CC/CXX</span></code> doesn’t exist.</li>
<p>You can set other compiling parameters for your own need. I.E. if you are trying to minimize the library size, set <codeclass="docutils literal"><spanclass="pre">CMAKE_BUILD_TYPE</span></code> with <codeclass="docutils literal"><spanclass="pre">MinSizeRel</span></code>; or if the performance is your concern, set <codeclass="docutils literal"><spanclass="pre">CMAKE_BUILD_TYPE</span></code> with <codeclass="docutils literal"><spanclass="pre">Release</span></code>. You can even manipulate the PaddlePaddle compiling procedure by manually set <codeclass="docutils literal"><spanclass="pre">CMAKE_C/CXX_FLAGS</span></code> values.</p>
<p><strong>TIPS for a better performance</strong>:</p>
<ulclass="simple">
<li>set <codeclass="docutils literal"><spanclass="pre">CMAKE_BUILD_TYPE</span></code> with <codeclass="docutils literal"><spanclass="pre">Release</span></code></li>
<li>set <codeclass="docutils literal"><spanclass="pre">IOS_USE_VECLIB_FOR_BLAS</span></code> with <codeclass="docutils literal"><spanclass="pre">ON</span></code></li>
</ul>
</div>
<divclass="section"id="compile-and-install">
<spanid="compile-and-install"></span><h2>Compile and install<aclass="headerlink"href="#compile-and-install"title="Permalink to this headline">¶</a></h2>
<p>After CMake, run following commands, PaddlePaddle will download the compile 3rd party dependencies, compile and install PaddlePaddle inference library.</p>
<divclass="highlight-default"><divclass="highlight"><pre><span></span>$ make
$ make install
</pre></div>
</div>
<p>Please Note: if you compiled PaddlePaddle in the source directory for other platforms, do remove <codeclass="docutils literal"><spanclass="pre">third_party</span></code> and <codeclass="docutils literal"><spanclass="pre">build</span></code> directory within the source with <codeclass="docutils literal"><spanclass="pre">rm</span><spanclass="pre">-rf</span></code> to ensure that all the 3rd party libraries dependencies and PaddlePaddle is newly compiled with current CMake configuration.</p>
<p><codeclass="docutils literal"><spanclass="pre">your/path/to/install</span></code> directory will have following directories after <codeclass="docutils literal"><spanclass="pre">compile</span></code> and <codeclass="docutils literal"><spanclass="pre">install</span></code>:</p>
<ulclass="simple">
<li><codeclass="docutils literal"><spanclass="pre">include</span></code>, contains all the C-API header files.</li>
<li><codeclass="docutils literal"><spanclass="pre">third_party</span></code> contains all the 3rd party libraries.</li>
</ul>
<p>Please note: if PaddlePaddle library need to support both physical devices and simulators, you will need to compile correspondingly, then merge fat library with <codeclass="docutils literal"><spanclass="pre">lipo</span></code></p>
<p>Now you will have PaddlePaddle library compiled and installed, the fat library can be used in deep learning related iOS APPs. Please refer to C-API documentation for usage guides.</p>
Built with <ahref="http://sphinx-doc.org/">Sphinx</a> using a <ahref="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <ahref="https://readthedocs.org">Read the Docs</a>.