IVGCVSW-4813 Update semantic versioning of ArmNN to 22.0.0 for 20.08 release
[platform/upstream/armnn.git] / python / pyarmnn / README.md
1 # About PyArmNN
2
3 PyArmNN is a python extension for [Arm NN SDK](https://developer.arm.com/ip-products/processors/machine-learning/arm-nn).
4 PyArmNN provides interface similar to Arm NN C++ Api.
5 Before you proceed with the project setup, you will need to checkout and build a corresponding Arm NN version.
6
7 PyArmNN is built around public headers from the armnn/include folder of Arm NN. PyArmNN does not implement any computation kernels itself, all operations are
8 delegated to the Arm NN library.
9
10 The [SWIG](http://www.swig.org/) project is used to generate the Arm NN python shadow classes and C wrapper.
11
12 The following diagram shows the conceptual architecture of this library:
13 ![PyArmNN](./images/pyarmnn.png)
14
15 # Setup development environment
16
17 Before, proceeding to the next steps, make sure that:
18
19 1. You have Python 3.6+ installed system-side. The package is not compatible with older Python versions.
20 2. You have python3.6-dev installed system-side. This contains header files needed to build PyArmNN extension module.
21 3. In case you build Python from sources manually, make sure that the following libraries are installed and available in you system:
22 ``python3.6-dev build-essential checkinstall libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev``
23 4. Install SWIG 4.x. Only 3.x version is typically available in Linux package managers, so you will have to build it and install it from sources. It can be downloaded from the [SWIG project website](http://www.swig.org/download.html) or from [SWIG GitHub](https://github.com/swig/swig). To install it follow the guide on [SWIG GitHub](https://github.com/swig/swig/wiki/Getting-Started).
24
25 ## Setup virtual environment
26
27 Now you can proceed with setting up workspace. It is recommended to create a python virtual environment, so you do not pollute your working folder:
28 ```bash
29 python -m venv env
30 source env/bin/activate
31 ```
32
33 You may run into missing python modules such as *wheel*. Make sure to install those using pip:
34 ```bash
35 pip install wheel
36 ```
37
38 ## Build python distr
39
40 Python supports source and binary distribution packages.
41
42 Source distr contains setup.py script that is executed on the users machine during package installation.
43 When preparing binary distr (wheel), setup.py is executed on the build machine and the resulting package contains only the result
44 of the build (generated files and resources, test results etc).
45
46 In our case, PyArmNN depends on Arm NN installation. Thus, binary distr will be linked with
47 the local build machine libraries and runtime.
48
49 There are 2 ways to build the python packages. Either directly using the python scripts or using CMake.
50
51 ### CMake build
52
53 The recommended aproach is to build PyArmNN together with Arm NN by adding the following options to your CMake command:
54 ```
55 -DBUILD_PYTHON_SRC=1
56 -DBUILD_PYTHON_WHL=1
57 ```
58 This will build either the source package or the wheel or both. Current project headers and build libraries will be used, so there is no need to provide them.
59
60 SWIG is required to generate the wrappers. If CMake did not find the executable during the configure step or it has found an older version, you may provide it manually:
61 ```
62 -DSWIG_EXECUTABLE=<path_to_swig_executable>
63 ```
64
65 After the build finishes, you will find the python packages in `<build_folder>/python/pyarmnn/dist`.
66
67 ### Standalone build
68
69 PyArmNN can also be built using the provided python scripts only. The advantage of that is that you may use prebuilt Arm NN libraries and it is generally much faster if you do not want to build all the Arm NN libraries.
70
71 ##### 1. Set environment:
72
73 *ARMNN_INCLUDE* and *ARMNN_LIB* are mandatory and should point to Arm NN includes and libraries against which you will be generating the wrappers. *SWIG_EXECUTABLE* should only be set if you have multiple versions of SWIG installed or you used a custom location for your installation:
74 ```bash
75 $ export SWIG_EXECUTABLE=<path_to_swig>
76 $ export ARMNN_INCLUDE=<path_to_armnn_include>
77 $ export ARMNN_LIB=<path_to_armnn_libraries>
78 ``` 
79
80 ##### 2. Clean and build SWIG wrappers:
81
82 ```bash
83 $ python setup.py clean --all
84 $ python swig_generate.py -v
85 $ python setup.py build_ext --inplace
86 ```
87 This step will put all generated files under `./src/pyarmnn/_generated` folder and can be used repeatedly to re-generate the wrappers.
88
89 ##### 4. Build the source package
90
91 ```bash
92 $ python setup.py sdist
93 ```
94 As the result you will get `./dist/pyarmnn-22.0.0.tar.gz` file. As you can see it is platform independent.
95
96 ##### 5. Build the binary package
97
98 ```bash
99 $ python setup.py bdist_wheel
100 ```
101 As the result you will get something like `./dist/pyarmnn-22.0.0-cp36-cp36m-linux_x86_64.whl` file. As you can see it is platform dependent.
102
103 # PyArmNN installation
104
105 PyArmNN can be distributed as a source package or a binary package (wheel).
106
107 Binary package is platform dependent, the name of the package will indicate the platform it was built for, e.g.:
108
109 * Linux x86 64bit machine: pyarmnn-22.0.0-cp36-cp36m-*linux_x86_64*.whl
110 * Linux Aarch 64 bit machine: pyarmnn-22.0.0-cp36-cp36m-*linux_aarch64*.whl
111
112 The source package is platform independent but installation involves compilation of Arm NN python extension. You will need to have g++ compatible with C++ 14 standard and a python development library installed on the build machine.
113
114 Both of them, source and binary package, require the Arm NN library to be present on the target/build machine.
115
116 It is strongly suggested to work within a python virtual environment. The further steps assume that the virtual environment was created and activated before running PyArmNN installation commands.
117
118 PyArmNN also depends on the NumPy python library. It will be automatically downloaded and installed alongside PyArmNN. If your machine does not have access to Python pip repositories you might need to install NumPy in advance by following public instructions: https://scipy.org/install.html
119
120 ## Installing from wheel
121
122 Make sure that Arm NN binaries and Arm NN dependencies are installed and can be found in one of the system default library locations. You can check default locations by executing the following command:
123 ```bash
124 $ gcc --print-search-dirs
125 ```
126 Install PyArmNN from binary by pointing to the wheel file:
127 ```bash
128 $ pip install /path/to/pyarmnn-22.0.0-cp36-cp36m-linux_aarch64.whl
129 ```
130
131 ## Installing from source package
132
133 Alternatively, you can install from source. This is the more reliable way but requires a little more effort on the users part.
134
135 While installing from sources, you have the freedom of choosing Arm NN libraries location. Set environment variables *ARMNN_LIB* and *ARMNN_INCLUDE* to point to Arm NN libraries and headers.
136 If you want to use system default locations, just set *ARMNN_INCLUDE* to point to Arm NN headers.
137
138 ```bash
139 $ export  ARMNN_LIB=/path/to/libs
140 $ export  ARMNN_INCLUDE=/path/to/headers
141 ```
142
143 Install PyArmNN as follows:
144 ```bash
145 $ pip install /path/to/pyarmnn-22.0.0.tar.gz
146 ```
147
148 If PyArmNN installation script fails to find Arm NN libraries it will raise an error like this
149
150 `RuntimeError: ArmNN library was not found in ('/usr/lib/gcc/aarch64-linux-gnu/8/', <...> ,'/lib/', '/usr/lib/'). Please install ArmNN to one of the standard locations or set correct ARMNN_INCLUDE and ARMNN_LIB env variables.`
151
152 You can now verify that PyArmNN library is installed and check PyArmNN version using:
153 ```bash
154 $ pip show pyarmnn
155 ```
156 You can also verify it by running the following and getting output similar to below:
157 ```bash
158 $ python -c "import pyarmnn as ann;print(ann.GetVersion())"
159 '22.0.0'
160 ```
161
162 # PyArmNN API overview
163
164 #### Getting started
165 The easiest way to begin using PyArmNN is by using the Parsers. We will demonstrate how to use them below:
166
167 Create a parser object and load your model file.
168 ```python
169 import pyarmnn as ann
170 import imageio
171
172 # ONNX, Caffe and TF parsers also exist.
173 parser = ann.ITfLiteParser()
174 network = parser.CreateNetworkFromBinaryFile('./model.tflite')
175 ```
176
177 Get the input binding information by using the name of the input layer.
178 ```python
179 input_binding_info = parser.GetNetworkInputBindingInfo(0, 'model/input')
180
181 # Create a runtime object that will perform inference.
182 options = ann.CreationOptions()
183 runtime = ann.IRuntime(options)
184 ```
185 Choose preferred backends for execution and optimize the network.
186 ```python
187 # Backend choices earlier in the list have higher preference.
188 preferredBackends = [ann.BackendId('CpuAcc'), ann.BackendId('CpuRef')]
189 opt_network, messages = ann.Optimize(network, preferredBackends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
190
191 # Load the optimized network into the runtime.
192 net_id, _ = runtime.LoadNetwork(opt_network)
193 ```
194 Make workload tensors using input and output binding information.
195 ```python
196 # Load an image and create an inputTensor for inference.
197 img = imageio.imread('./image.png')
198 input_tensors = ann.make_input_tensors([input_binding_info], [img])
199
200 # Get output binding information for an output layer by using the layer name.
201 output_binding_info = parser.GetNetworkOutputBindingInfo(0, 'model/output')
202 output_tensors = ann.make_output_tensors([outputs_binding_info])
203 ```
204
205 Perform inference and get the results back into a numpy array.
206 ```python
207 runtime.EnqueueWorkload(0, input_tensors, output_tensors)
208
209 results = ann.workload_tensors_to_ndarray(output_tensors)
210 print(results)
211 ```
212
213 #### Examples
214
215 To further explore PyArmNN API there are several examples provided in the examples folder running classification on an image. To run them first install the dependencies:
216  ```bash
217 $ pip install -r examples/requirements.txt
218 ```
219 Afterwards simply execute the example scripts, e.g.:
220  ```bash
221 $ python tflite_mobilenetv1_quantized.py
222 ```
223 All resources are downloaded during execution, so if you do not have access to the internet, you may need to download these manually. `example_utils.py` contains code shared between the examples.
224
225 ## Tox for automation
226
227 To make things easier *tox* is available for automating individual tasks or running multiple commands at once such as generating wrappers, running unit tests using multiple python versions or generating documentation. To run it use:
228
229 ```bash
230 $ tox <task_name>
231 ```
232
233 See *tox.ini* for the list of tasks. You may also modify it for your own purposes. To dive deeper into tox read through https://tox.readthedocs.io/en/latest/
234
235 ## Running unit-tests
236
237 Download resources required to run unit tests by executing the script in the scripts folder:
238
239 ```
240 $ python ./scripts/download_test_resources.py
241 ```
242
243 The script will download an archive from the Linaro server and extract it. A folder `test/testdata/shared` will be created. Execute `pytest` from the project root dir:
244 ```bash
245 $ python -m pytest test/ -v
246 ```
247 or run tox which will do both:
248 ```bash
249 $ tox
250 ```