Documentation - update 'Using the API' chapter
[tidl/tidl-api.git] / docs / source / example.rst
1 .. _examples:
3 ********
4 Examples
5 ********
7 .. list-table:: TIDL API Examples
8    :header-rows: 1
9    :widths: 12 43 20 25
11    * - Example
12      - Description
13      - Compute cores
14      - Input image
15    * - one_eo_per_frame
16      - Processes a single frame with one :term:`EO` using the j11_v2 network. Throughput is increased by distributing frame processing across EOs. Refer :ref:`use-case-1`.
17      - EVE or C66x
18      - Pre-processed image read from file.
19    * - two_eo_per_frame
20      - Processes a single frame with an :term:`EOP` using the j11_v2 network to reduce per-frame processing latency. Also increases throughput by distributing frame processing across EOPs. The EOP consists of two EOs. Refer :ref:`use-case-2`.
21      - EVE and C66x (network is split across both EVE and C66x)
22      - Pre-processed image read from file.
23    * - two_eo_per_frame_opt
24      - Builds on ``two_eo_per_frame``. Adds double buffering to improve performance. Refer :ref:`use-case-3`.
25      - EVE and C66x (network is split across both EVE and C66x)
26      - Pre-processed image read from file.
28    * - imagenet
29      - Classification example
30      - EVE or C66x
31      - OpenCV used to read input image from file or capture from camera.
32    * - segmentation
33      - Pixel level segmentation example
34      - EVE or C66x
35      - OpenCV used to read input image from file or capture from camera.
36    * - ssd_multibox
37      - Object detection
38      - EVE and C66x (network is split across both EVE and C66x)
39      - OpenCV used to read input image from file or capture from camera.
40    * - classification
41      - Classification example, called from the Matrix GUI.
42      - EVE or C66x
43      - OpenCV used to read input image from file or capture from camera.
44    * - mcbench
45      - Used to benchmark supported networks. Refer ``mcbench/scripts`` for command line options.
46      - EVE or C66x
47      - Pre-processed image read from file.
48    * - layer_output
49      - Illustrates using TIDL APIs to access output buffers of intermediate :term:`layers<Layer>` in the network.
50      - EVE or C66x
51      - Pre-processed image read from file.
52    * - test
53      - This example is used to test pre-converted networks included in the TIDL API package (``test/testvecs/config/tidl_models``). When run without any arguments, the program ``test_tidl`` will run all available networks on the C66x DSPs and EVEs available on the SoC. Use the ``-c`` option to specify a single network. Run ``test_tidl -h``  for details.
54      - C66x and EVEs (if available)
55      - Pre-processed image read from file.
57 The included examples demonstrate three categories of deep learning networks: classification, segmentation and object detection.  ``imagenet`` and ``segmentation`` can run on AM57x processors with either EVE or C66x cores.  ``ssd_multibox`` requires AM57x processors with both EVE and C66x. The examples are available at ``/usr/share/ti/tidl/examples`` on the EVM file system and in the linux devkit.
59 The performance numbers were obtained using:
61 * `AM574x IDK EVM`_ with the Sitara `AM5749`_ Processor - 2 Arm Cortex-A15 cores running at 1.0GHz, 2 EVE cores at 650MHz, and 2 C66x cores at 750MHz.
62 * `Processor SDK Linux`_ v5.1 with TIDL API v1.1
64 For each example, device processing time, host processing time,
65 and TIDL API overhead is reported.
67 * **Device processing time** is measured on the device, from the moment processing starts for a frame till processing finishes.
68 * **Host processing time** is measured on the host, from the moment ``ProcessFrameStartAsync()`` is called till ``ProcessFrameWait()`` returns in user application.  It includes the TIDL API overhead, the OpenCL runtime overhead, and the time to copy user input data into padded TIDL internal buffers. ``Host processing time = Device processing time + TIDL API overhead``.
71 Imagenet
72 --------
74 The imagenet example takes an image as input and outputs 1000 probabilities.
75 Each probability corresponds to one object in the 1000 objects that the
76 network is pre-trained with.  The example outputs top 5 predictions for a given input image.
78 The following figure and tables shows an input image, top 5 predicted
79 objects as output, and the processing time on either EVE or C66x.
81 .. image:: ../../examples/test/testvecs/input/objects/cat-pet-animal-domestic-104827.jpeg
82    :width: 600
85 ==== ==============
86 Rank Object Classes
87 ==== ==============
88 1    tabby
89 2    Egyptian_cat
90 3    tiger_cat
91 4    lynx
92 5    Persian_cat
93 ==== ==============
95 =======   ====================== ==================== ============
96 Device    Device Processing Time Host Processing Time API Overhead
97 =======   ====================== ==================== ============
98 EVE       106.5 ms               107.9 ms             1.37 %
99 C66x      117.9 ms               118.7 ms             0.93 %
100 =======   ====================== ==================== ============
102 The :term:`network<Network>` used in the example is jacintonet11v2. It has
103 14 layers. Input to the network is RGB image of 224x224. Users can specify whether to run the network on EVE or C66x.
105 The example code sets ``buffer_factor`` to 2 to create duplicated
106 ExecutionObjectPipelines with identical ExecutionObjects to
107 perform double buffering, so that host pre/post-processing can be overlapped
108 with device processing (see comments in the code for details).
109 The following table shows the loop overall time over 10 frames
110 with single buffering and double buffering,
111 ``./imagenet -f 10 -d <num> -e <num>``.
113 .. list-table:: Loop overall time over 10 frames
114    :header-rows: 1
116    * - Device(s)
117      - Single Buffering (buffer_factor=1)
118      - Double Buffering (buffer_factor=2)
119    * - 1 EVE
120      - 1744 ms
121      - 1167 ms
122    * - 2 EVEs
123      - 966 ms
124      - 795 ms
125    * - 1 C66x
126      - 1879 ms
127      - 1281 ms
128    * - 2 C66xs
129      - 1021 ms
130      - 814 ms
132 .. note::
133     The predicitions reported here are based on the output of the softmax
134     layer in the network, which are not normalized to the real probabilities.
136 Segmentation
137 ------------
139 The segmentation example takes an image as input and performs pixel-level
140 classification according to pre-trained categories.  The following figures
141 show a street scene as input and the scene overlaid with pixel-level
142 classifications as output: road in green, pedestrians in red, vehicles
143 in blue and background in gray.
145 .. image:: ../../examples/test/testvecs/input/roads/pexels-photo-972355.jpeg
146    :width: 600
148 .. image:: images/pexels-photo-972355-seg.jpg
149    :width: 600
151 The :term:`network<Network>` used in the example is jsegnet21v2. It has
152 26 layers.  Users can specify whether to run the network on EVE or C66x.
153 Input to the network is RGB image of size 1024x512.  The output is 1024x512
154 values, each value indicates which pre-trained category the current pixel
155 belongs to.  The example will take the network output, create an overlay,
156 and blend the overlay onto the original input image to create an output image.
157 From the reported time in the following table, we can see that this network
158 runs significantly faster on EVE than on C66x.
160 =======     ====================== ==================== ============
161 Device      Device Processing Time Host Processing Time API Overhead
162 =======     ====================== ==================== ============
163 EVE         251.8 ms               254.2 ms             0.96 %
164 C66x        812.7 ms               815.0 ms             0.27 %
165 =======     ====================== ==================== ============
167 The example code sets ``buffer_factor`` to 2 to create duplicated
168 ExecutionObjectPipelines with identical ExecutionObjects to
169 perform double buffering, so that host pre/post-processing can be overlapped
170 with device processing (see comments in the code for details).
171 The following table shows the loop overall time over 10 frames
172 with single buffering and double buffering,
173 ``./segmentation -f 10 -d <num> -e <num>``.
175 .. list-table:: Loop overall time over 10 frames
176    :header-rows: 1
178    * - Device(s)
179      - Single Buffering (buffer_factor=1)
180      - Double Buffering (buffer_factor=2)
181    * - 1 EVE
182      - 5233 ms
183      - 3017 ms
184    * - 2 EVEs
185      - 3032 ms
186      - 3015 ms
187    * - 1 C66x
188      - 10890 ms
189      - 8416 ms
190    * - 2 C66xs
191      - 5742 ms
192      - 4638 ms
194 .. _ssd-example:
196 SSD
197 ---
199 SSD is the abbreviation for Single Shot multi-box Detector.
200 The ssd_multibox example takes an image as input and detects multiple
201 objects with bounding boxes according to pre-trained categories.
202 The following figures show another street scene as input and the scene
203 with recognized objects boxed as output: pedestrians in red,
204 vehicles in blue and road signs in yellow.
206 .. image:: ../../examples/test/testvecs/input/roads/pexels-photo-378570.jpeg
207    :width: 600
209 .. image:: images/pexels-photo-378570-ssd.jpg
210    :width: 600
212 The network we ran in this category is jdenet_ssd, which has 43 layers.
213 Input to the network is RGB image of size 768x320.  Output is a list of
214 boxes (up to 20), each box has information about the box coordinates, and
215 which pre-trained category that the object inside the box belongs to.
216 The example will take the network output, draw boxes accordingly,
217 and create an output image.
218 The network can be run entirely on either EVE or C66x.  However, the best
219 performance comes with running the first 30 layers as a group on EVE
220 and the next 13 layers as another group on C66x.
221 Our end-to-end example shows how easy it is to assign a :term:`Layer Group` id
222 to an :term:`Executor` and how easy it is to construct an :term:`ExecutionObjectPipeline` to connect the output of one *Executor*'s :term:`ExecutionObject`
223 to the input of another *Executor*'s *ExecutionObject*.
225 ========      ====================== ==================== ============
226 Device        Device Processing Time Host Processing Time API Overhead
227 ========      ====================== ==================== ============
228 EVE+C66x      169.5ms                172.0ms              1.68 %
229 ========      ====================== ==================== ============
231 The example code sets ``pipeline_depth`` to 2 to create duplicated
232 ExecutionObjectPipelines with identical ExecutionObjects to
233 perform pipelined execution at the ExecutionObject level.
234 The side effect is that it also overlaps host pre/post-processing
235 with device processing (see comments in the code for details).
236 The following table shows the loop overall time over 10 frames
237 with pipelining at ExecutionObjectPipeline level
238 versus ExecutionObject level.
239 ``./ssd_multibox -f 10 -d <num> -e <num>``.
241 .. list-table:: Loop overall time over 10 frames
242    :header-rows: 1
244    * - Device(s)
245      - pipeline_depth=1
246      - pipeline_depth=2
247    * - 1 EVE + 1 C66x
248      - 2900 ms
249      - 1735 ms
250    * - 2 EVEs + 2 C66xs
251      - 1630 ms
252      - 1408 ms
254 Running Examples
255 ----------------
257 The examples are located in ``/usr/share/ti/tidl/examples`` on
258 the EVM file system.  **Each example needs to be run in its own directory** due to relative paths to configuration files.
259 Running an example with ``-h`` will show help message with option set.
260 The following listing illustrates how to build and run the examples.
262 .. code-block:: shell
264    root@am57xx-evm:~/tidl-api/examples/imagenet# ./imagenet
265    Input: ../test/testvecs/input/objects/cat-pet-animal-domestic-104827.jpeg
266    frame[  0]: Time on EVE0: 106.50 ms, host: 107.96 ms API overhead: 1.35 %
267    1: tabby
268    2: Egyptian_cat
269    3: tiger_cat
270    4: lynx
271    5: Persian_cat
272    Loop total time (including read/write/opencv/print/etc):  202.6ms
273    imagenet PASSED
275    root@am57xx-evm:~/tidl-api/examples/segmentation# ./segmentation
276    Input: ../test/testvecs/input/000100_1024x512_bgr.y
277    frame[  0]: Time on EVE0: 251.74 ms, host: 258.02 ms API overhead: 2.43 %
278    Saving frame 0 to: frame_0.png
279    Saving frame 0 overlayed with segmentation to: overlay_0.png
280    frame[  1]: Time on EVE0: 251.76 ms, host: 255.79 ms API overhead: 1.58 %
281    Saving frame 1 to: frame_1.png
282    Saving frame 1 overlayed with segmentation to: overlay_1.png
283    ...
284    frame[  8]: Time on EVE0: 251.75 ms, host: 254.21 ms API overhead: 0.97 %
285    Saving frame 8 to: frame_8.png
286    Saving frame 8 overlayed with segmentation to: overlay_8.png
287    Loop total time (including read/write/opencv/print/etc):   4809ms
288    segmentation PASSED
290    root@am57xx-evm:~/tidl-api/examples/ssd_multibox# ./ssd_multibox
291    Input: ../test/testvecs/input/preproc_0_768x320.y
292    frame[  0]: Time on EVE0+DSP0: 169.44 ms, host: 173.56 ms API overhead: 2.37 %
293    Saving frame 0 to: frame_0.png
294    Saving frame 0 with SSD multiboxes to: multibox_0.png
295    Loop total time (including read/write/opencv/print/etc):  320.2ms
296    ssd_multibox PASSED
299 Image input
300 ^^^^^^^^^^^
302 The image input option, ``-i <image>``, takes an image file as input.
303 You can supply an image file with format that OpenCV can read, since
304 we use OpenCV for image pre/post-processing.  When ``-f <number>`` option
305 is used, the same image will be processed repeatedly.
307 Camera (live video) input
308 ^^^^^^^^^^^^^^^^^^^^^^^^^
310 The input option, ``-i camera<number>``, enables live frame inputs
311 from camera.  ``<number>`` is the video input port number
312 of your camera in Linux.  Use the following command to check video
313 input ports.  The number defaults to ``1`` for TMDSCM572X camera module
314 used on AM57x EVMs.  You can use ``-f <number>`` to specify the number
315 of frames you want to process.
317 .. code-block:: shell
319   root@am57xx-evm:~# v4l2-ctl --list-devices
320   omapwb-cap (platform:omapwb-cap):
321         /dev/video11
323   omapwb-m2m (platform:omapwb-m2m):
324         /dev/video10
326   vip (platform:vip):
327         /dev/video1
329   vpe (platform:vpe):
330         /dev/video0
333 Pre-recorded video (mp4/mov/avi) input
334 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
336 The input option, ``-i <name>.{mp4,mov,avi}``, enables frame inputs from
337 pre-recorded video file in mp4, mov or avi format.  If you have a video in
338 a different OpenCV-supported format/suffix, you can simply create a softlink
339 with one of the mp4, mov or avi suffixes and feed it into the example.
340 Again, use ``-f <number>`` to specify the number of frames you want to process.
342 Displaying video output
343 ^^^^^^^^^^^^^^^^^^^^^^^
345 When using video input, live or pre-recorded, the example will display
346 the output in a window using OpenCV.  If you have a LCD screen attached
347 to the EVM, you will need to kill the ``matrix-gui`` first in order to
348 see the example display window, as shown in the following example.
350 .. code-block:: shell
352   root@am57xx-evm:/usr/share/ti/tidl/examples/ssd_multibox# /etc/init.d/matrix-gui-2.0 stop
353   Stopping Matrix GUI application.
354   root@am57xx-evm:/usr/share/ti/tidl/examples/ssd_multibox# ./ssd_multibox -i camera -f 100
355   Input: camera
356   init done
357   Using Wayland-EGL
358   wlpvr: PVR Services Initialised
359   Using the 'xdg-shell-v5' shell integration
360   ... ...
361   root@am57xx-evm:/usr/share/ti/tidl/examples/ssd_multibox# /etc/init.d/matrix-gui-2.0 start
362   /usr/share/ti/tidl/examples/ssd_multibox
363   Removing stale PID file /var/run/matrix-gui-2.0.pid.
364   Starting Matrix GUI application.
367 .. _AM574x IDK EVM:  http://www.ti.com/tool/tmdsidk574
368 .. _AM5749: http://www.ti.com/product/AM5749/
369 .. _Processor SDK Linux: http://software-dl.ti.com/processor-sdk-linux/esd/AM57X/latest/index_FDS.html