aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md16
-rw-r--r--docs/driver_library_component.puml3
-rw-r--r--docs/driver_library_component.svg16
-rw-r--r--docs/driver_library_sequence.puml11
-rw-r--r--docs/driver_library_sequence.svg18
-rw-r--r--docs/kernel_network.puml8
-rw-r--r--docs/kernel_network.svg15
-rw-r--r--driver_library/include/ethosu.hpp10
-rw-r--r--driver_library/python/README.md14
-rw-r--r--driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py3
-rw-r--r--driver_library/python/src/ethosu_driver/swig/driver.i51
-rw-r--r--driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i23
-rw-r--r--driver_library/python/test/test_driver.py86
-rw-r--r--driver_library/src/ethosu.cpp15
-rw-r--r--kernel/ethosu_device.c3
-rw-r--r--kernel/ethosu_inference.c4
-rw-r--r--kernel/ethosu_mailbox.c14
-rw-r--r--kernel/ethosu_mailbox.h14
-rw-r--r--kernel/ethosu_network.c46
-rw-r--r--kernel/ethosu_network.h7
-rw-r--r--kernel/ethosu_network_info.c4
-rw-r--r--kernel/uapi/ethosu.h18
-rw-r--r--tests/cancel_inference_test.cpp8
-rw-r--r--tests/run_inference_test.cpp48
-rw-r--r--utils/inference_runner/inference_runner.cpp13
25 files changed, 259 insertions, 209 deletions
diff --git a/README.md b/README.md
index 1b9a692..cdab1d4 100644
--- a/README.md
+++ b/README.md
@@ -219,7 +219,7 @@ dispatching inferences to the Ethos-U kernel driver.
As the component diagram below illustrates the network is separated from the
inference, allowing multiple inferences to share the same network. The buffer
-class is used to store any data.
+class is used to store IFM and OFM data.
![Driver library](docs/driver_library_component.svg "Driver library component diagram")
@@ -232,9 +232,9 @@ The `Device` class opens a file descriptor to the device node `/dev/ethosu<nr>`.
This file descriptor is used to issue IOCTL request to kernel space to create
buffers and networks.
-The `Network` class uses the `Device` object to create a new network object. The
-network model is stored in a `Buffer` that the network parses to discover the
-dimensions of the network model.
+The `Network` class uses the `Device` object to create a new network object.
+The network model is provided in a user buffer that is copied into an internal
+buffer and parsed to discover the dimensions of the network model.
The `Inference` class uses the `Network` object to create an inference. The
array of IFM `Buffers` need to be populated with data before the inference
@@ -259,13 +259,11 @@ for reading and/or writing.
## Network
Creating a network assumes that the device node has already been opened, and
-that a buffer has been allocated and populated with the network model.
+that a user buffer populated with the network model is available.
A new network is created by issuing an IOCTL command on the device node file
-descriptor. A file descriptor to a buffer - containing the network model - is
-passed in the IOCTL data. The network class increases the reference count on the
-buffer, preventing the buffer from being freed before the network object has
-been destructed.
+descriptor. A pointer to the user buffer - containing the network model - and
+its size is passed in the IOCTL data.
![Create network](docs/kernel_network.svg "Create network")
diff --git a/docs/driver_library_component.puml b/docs/driver_library_component.puml
index 1b640e2..6e39456 100644
--- a/docs/driver_library_component.puml
+++ b/docs/driver_library_component.puml
@@ -11,8 +11,7 @@ inf -> net
inf -> buf: IFM and OFM
net --> dev
-net --> buf: Network model
buf -> dev
-@enduml \ No newline at end of file
+@enduml
diff --git a/docs/driver_library_component.svg b/docs/driver_library_component.svg
index bcb43f9..715da50 100644
--- a/docs/driver_library_component.svg
+++ b/docs/driver_library_component.svg
@@ -1,4 +1,12 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="168px" preserveAspectRatio="none" style="width:322px;height:168px;background:#FEFEFE;" version="1.1" viewBox="0 0 322 168" width="322px" zoomAndPan="magnify"><defs><filter height="300%" id="f1cgoct9zpmo59" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><!--entity inf--><rect fill="#FEFECE" filter="url(#f1cgoct9zpmo59)" height="36.2969" style="stroke: #A80036; stroke-width: 1.5;" width="85" x="6" y="8"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="1" y="13"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="1" y="34.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="16" y="30.9951">Inference</text><!--entity net--><rect fill="#FEFECE" filter="url(#f1cgoct9zpmo59)" height="36.2969" style="stroke: #A80036; stroke-width: 1.5;" width="77" x="129" y="8"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="124" y="13"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="124" y="34.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="139" y="30.9951">Network</text><!--entity buf--><rect fill="#FEFECE" filter="url(#f1cgoct9zpmo59)" height="36.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="137" y="121"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="132" y="126"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="132" y="147.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="147" y="143.9951">Buffer</text><!--entity dev--><rect fill="#FEFECE" filter="url(#f1cgoct9zpmo59)" height="36.2969" style="stroke: #A80036; stroke-width: 1.5;" width="67" x="244" y="121"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="239" y="126"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="239" y="147.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="254" y="143.9951">Device</text><!--link inf to net--><path d="M91.2656,26 C102.014,26 112.7624,26 123.5108,26 " fill="none" id="inf-net" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="128.7872,26,119.7872,22,123.7872,26,119.7872,30,128.7872,26" style="stroke: #A80036; stroke-width: 1.0;"/><!--link inf to buf--><path d="M51.77,44.1326 C55.1308,58.3191 61.6089,77.7906 73.5,91 C89.0965,108.3256 112.4057,120.2854 131.9103,127.9336 " fill="none" id="inf-buf" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="136.7801,129.7858,129.7901,122.8475,132.1067,128.0083,126.946,130.3249,136.7801,129.7858" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="81" x="74.5" y="87.0669">IFM and OFM</text><!--link net to dev--><path d="M206.4926,35.4978 C227.4666,42.6282 251.9451,54.5931 266.5,74 C275.351,85.8015 278.0778,102.1963 278.6036,115.5676 " fill="none" id="net-dev" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="278.7058,120.7148,282.5263,111.6371,278.6065,115.7158,274.5279,111.796,278.7058,120.7148" style="stroke: #A80036; stroke-width: 1.0;"/><!--link net to buf--><path d="M166.0926,44.2219 C165.4689,53.1847 164.8074,64.1523 164.5,74 C164.0682,87.8318 164.7366,103.3096 165.5511,115.691 " fill="none" id="net-buf" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="165.9063,120.794,169.2715,111.5379,165.559,115.8061,161.2909,112.0936,165.9063,120.794" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="96" x="165.5" y="87.0669">Network model</text><!--link buf to dev--><path d="M198.0078,139 C211.6511,139 225.2944,139 238.9377,139 " fill="none" id="buf-dev" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="243.9642,139,234.9642,135,238.9642,139,234.9642,143,243.9642,139" style="stroke: #A80036; stroke-width: 1.0;"/><!--
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="187px" preserveAspectRatio="none" style="width:214px;height:187px;background:#FEFEFE;" version="1.1" viewBox="0 0 214 187" width="214px" zoomAndPan="magnify"><defs><filter height="300%" id="fpjgrf9isy925" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><!--MD5=[e700746e0efa2c4773b8fec71443b5b6]
+entity inf--><rect fill="#FEFECE" filter="url(#fpjgrf9isy925)" height="36.2969" style="stroke: #A80036; stroke-width: 1.5;" width="85" x="6" y="8"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="1" y="13"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="1" y="34.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="16" y="30.9951">Inference</text><!--MD5=[27d8026e1e607fa992f9f5b0cd222a86]
+entity net--><rect fill="#FEFECE" filter="url(#fpjgrf9isy925)" height="36.2969" style="stroke: #A80036; stroke-width: 1.5;" width="77" x="126" y="8"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="121" y="13"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="121" y="34.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="136" y="30.9951">Network</text><!--MD5=[0026c2bef77b3322991a49ea733d1063]
+entity buf--><rect fill="#FEFECE" filter="url(#fpjgrf9isy925)" height="36.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="49" y="74"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="44" y="79"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="44" y="100.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="59" y="96.9951">Buffer</text><!--MD5=[3d99d59a27ec55cd9b0b1490801f78bc]
+entity dev--><rect fill="#FEFECE" filter="url(#fpjgrf9isy925)" height="36.2969" style="stroke: #A80036; stroke-width: 1.5;" width="67" x="73" y="140"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="68" y="145"/><rect fill="#FEFECE" height="5" style="stroke: #A80036; stroke-width: 1.5;" width="10" x="68" y="166.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="83" y="162.9951">Device</text><!--MD5=[2ff72c400cccaeb19456038b10d7a192]
+link inf to net--><path d="M91.09,26 C100.94,26 110.79,26 120.64,26 " fill="none" id="inf-&gt;net" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="125.79,26,116.79,22,120.79,26,116.79,30,125.79,26" style="stroke: #A80036; stroke-width: 1.0;"/><!--MD5=[683c956fb43f11bd9ac76d5bc8360245]
+link inf to buf--><path d="M56.81,44.15 C60.49,51.76 64.87,60.8 68.8,68.9 " fill="none" id="inf-&gt;buf" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="71.17,73.8,70.8612,63.956,68.9971,69.2969,63.6562,67.4327,71.17,73.8" style="stroke: #A80036; stroke-width: 1.0;"/><!--MD5=[c137ea9796ba7150be1b84493d485127]
+link net to dev--><path d="M156.8,44.26 C146.35,67.67 127.7,109.49 116.28,135.08 " fill="none" id="net-&gt;dev" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="114.23,139.67,121.5367,133.066,116.258,135.0998,114.2243,129.8211,114.23,139.67" style="stroke: #A80036; stroke-width: 1.0;"/><!--MD5=[f081c634ca37a6c48a522a149df97049]
+link buf to dev--><path d="M86.74,110.15 C89.94,117.76 93.76,126.8 97.18,134.9 " fill="none" id="buf-&gt;dev" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="99.24,139.8,99.3972,129.9524,97.2825,135.1991,92.0358,133.0844,99.24,139.8" style="stroke: #A80036; stroke-width: 1.0;"/><!--MD5=[8c816b15a51d6b9c34284e9b0bbcc4d9]
@startuml
skinparam backgroundColor #FEFEFE
@@ -12,19 +20,17 @@ inf -> net
inf -> buf: IFM and OFM
net - -> dev
-net - -> buf: Network model
buf -> dev
@enduml
-PlantUML version 1.2017.15(Mon Jul 03 18:45:34 CEST 2017)
+PlantUML version 1.2020.02(Sun Mar 01 11:22:07 CET 2020)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
-Java Version: 11.0.11+9-Ubuntu-0ubuntu2.18.04
+Java Version: 11.0.20.1+1-post-Ubuntu-0ubuntu122.04
Operating System: Linux
-OS Version: 5.4.0-73-generic
Default Encoding: UTF-8
Language: en
Country: US
diff --git a/docs/driver_library_sequence.puml b/docs/driver_library_sequence.puml
index adac2f9..0e8c799 100644
--- a/docs/driver_library_sequence.puml
+++ b/docs/driver_library_sequence.puml
@@ -30,19 +30,10 @@ main -> ddev++: Device()
return
note over dnet
- Allocate and fill network buffer
-end note
-
-main -> dbuf++: Buffer(device)
- dbuf -> kbuf++: ioctl(BUFFER_CREATE)
- return file descriptor
-return
-
-note over dnet
Create network, parse network model
end note
-main -> dnet++: Network(device, buffer)
+main -> dnet++: Network(device, user_buffer, size)
dnet -> knet++: ioctl(NETWORK_CREATE)
return file descriptor
diff --git a/docs/driver_library_sequence.svg b/docs/driver_library_sequence.svg
index 1103a05..b1ac54c 100644
--- a/docs/driver_library_sequence.svg
+++ b/docs/driver_library_sequence.svg
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="1083px" preserveAspectRatio="none" style="width:831px;height:1083px;background:#FEFEFE;" version="1.1" viewBox="0 0 831 1083" width="831px" zoomAndPan="magnify"><defs><filter height="300%" id="f528w0w85mfwd" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#0091BD" height="1068.3125" style="stroke: #A80036; stroke-width: 1.0;" width="89" x="9" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="83" x="12" y="16.0669">Application</text><rect fill="#00C1DE" height="1068.3125" style="stroke: #A80036; stroke-width: 1.0;" width="389" x="109" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="96" x="255.5" y="16.0669">Driver library</text><rect fill="#7D868C" height="1068.3125" style="stroke: #A80036; stroke-width: 1.0;" width="320" x="500" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="95" x="612.5" y="16.0669">Kernel driver</text><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="956.5859" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="48.5" y="68.4297"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="140.5" y="128.5625"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="269.0938"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="577.2891"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="709.8203"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="114.5313" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="289.5" y="409.625"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="447.5" y="857.3516"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="57.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="447.5" y="958.75"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="531.5" y="157.6953"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="603.5" y="298.2266"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="603.5" y="606.4219"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="603.5" y="738.9531"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="680.5" y="438.7578"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="769.5" y="886.4844"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="14.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="769.5" y="987.8828"/><rect fill="#FEFEFE" filter="url(#f528w0w85mfwd)" height="118.5313" style="stroke: #000000; stroke-width: 2.0;" width="635" x="13" y="539.1563"/><rect fill="#FEFEFE" filter="url(#f528w0w85mfwd)" height="118.5313" style="stroke: #000000; stroke-width: 2.0;" width="635" x="13" y="671.6875"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="53" x2="53" y1="58.4297" y2="1034.0156"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="145" x2="145" y1="58.4297" y2="1034.0156"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="217" x2="217" y1="58.4297" y2="1034.0156"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="294" x2="294" y1="58.4297" y2="1034.0156"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="452" x2="452" y1="58.4297" y2="1034.0156"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="536" x2="536" y1="58.4297" y2="1034.0156"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="608" x2="608" y1="58.4297" y2="1034.0156"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="685" x2="685" y1="58.4297" y2="1034.0156"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="774" x2="774" y1="58.4297" y2="1034.0156"/><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="57" x="23" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="30" y="43.1279">main()</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="57" x="23" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="30" y="1053.0107">main()</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="113" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="120" y="43.1279">Device</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="113" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="120" y="1053.0107">Device</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="188" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="195" y="43.1279">Buffer</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="188" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="195" y="1053.0107">Buffer</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="257" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="264" y="43.1279">Network</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="257" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="264" y="1053.0107">Network</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="411" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="418" y="43.1279">Inference</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="411" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="418" y="1053.0107">Inference</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="504" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="511" y="43.1279">Device</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="504" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="511" y="1053.0107">Device</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="579" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="586" y="43.1279">Buffer</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="579" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="586" y="1053.0107">Buffer</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="648" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="655" y="43.1279">Network</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="648" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="655" y="1053.0107">Network</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="733" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="740" y="43.1279">Inference</text><rect fill="#FEFECE" filter="url(#f528w0w85mfwd)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="733" y="1033.0156"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="740" y="1053.0107">Inference</text><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="956.5859" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="48.5" y="68.4297"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="140.5" y="128.5625"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="269.0938"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="577.2891"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="709.8203"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="114.5313" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="289.5" y="409.625"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="72.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="447.5" y="857.3516"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="57.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="447.5" y="958.75"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="531.5" y="157.6953"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="603.5" y="298.2266"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="603.5" y="606.4219"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="603.5" y="738.9531"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="680.5" y="438.7578"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="769.5" y="886.4844"/><rect fill="#FFFFFF" filter="url(#f528w0w85mfwd)" height="14.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="769.5" y="987.8828"/><polygon fill="#FBFB77" filter="url(#f528w0w85mfwd)" points="89,73.4297,89,98.4297,198,98.4297,198,83.4297,188,73.4297,89,73.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="188" x2="188" y1="73.4297" y2="83.4297"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="198" x2="188" y1="83.4297" y2="83.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="88" x="95" y="90.4966">Create device</text><polygon fill="#A80036" points="128.5,124.5625,138.5,128.5625,128.5,132.5625,132.5,128.5625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="134.5" y1="128.5625" y2="128.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="53" x="65.5" y="123.6294">Device()</text><polygon fill="#A80036" points="519.5,153.6953,529.5,157.6953,519.5,161.6953,523.5,157.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="150.5" x2="525.5" y1="157.6953" y2="157.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="157.5" y="152.7622">open(&lt;device node&gt;)</text><polygon fill="#A80036" points="161.5,182.8281,151.5,186.8281,161.5,190.8281,157.5,186.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="155.5" x2="535.5" y1="186.8281" y2="186.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="167.5" y="181.895">file descriptor</text><polygon fill="#A80036" points="69.5,196.9609,59.5,200.9609,69.5,204.9609,65.5,200.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="144.5" y1="200.9609" y2="200.9609"/><polygon fill="#FBFB77" filter="url(#f528w0w85mfwd)" points="186,213.9609,186,238.9609,398,238.9609,398,223.9609,388,213.9609,186,213.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="388" x2="388" y1="213.9609" y2="223.9609"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="398" x2="388" y1="223.9609" y2="223.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="191" x="192" y="231.0278">Allocate and fill network buffer</text><polygon fill="#A80036" points="200.5,265.0938,210.5,269.0938,200.5,273.0938,204.5,269.0938" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="206.5" y1="269.0938" y2="269.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="89" x="65.5" y="264.1606">Buffer(device)</text><polygon fill="#A80036" points="591.5,294.2266,601.5,298.2266,591.5,302.2266,595.5,298.2266" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="222.5" x2="597.5" y1="298.2266" y2="298.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="229.5" y="293.2935">ioctl(BUFFER_CREATE)</text><polygon fill="#A80036" points="233.5,323.3594,223.5,327.3594,233.5,331.3594,229.5,327.3594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="227.5" x2="607.5" y1="327.3594" y2="327.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="239.5" y="322.4263">file descriptor</text><polygon fill="#A80036" points="69.5,337.4922,59.5,341.4922,69.5,345.4922,65.5,341.4922" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="216.5" y1="341.4922" y2="341.4922"/><polygon fill="#FBFB77" filter="url(#f528w0w85mfwd)" points="162,354.4922,162,379.4922,422,379.4922,422,364.4922,412,354.4922,162,354.4922" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="412" x2="412" y1="354.4922" y2="364.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="422" x2="412" y1="364.4922" y2="364.4922"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="239" x="168" y="371.5591">Create network, parse network model</text><polygon fill="#A80036" points="277.5,405.625,287.5,409.625,277.5,413.625,281.5,409.625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="283.5" y1="409.625" y2="409.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="148" x="65.5" y="404.6919">Network(device, buffer)</text><polygon fill="#A80036" points="668.5,434.7578,678.5,438.7578,668.5,442.7578,672.5,438.7578" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="299.5" x2="674.5" y1="438.7578" y2="438.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="154" x="306.5" y="433.8247">ioctl(NETWORK_CREATE)</text><polygon fill="#A80036" points="310.5,463.8906,300.5,467.8906,310.5,471.8906,306.5,467.8906" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="304.5" x2="684.5" y1="467.8906" y2="467.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="316.5" y="462.9575">file descriptor</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="299.5" x2="341.5" y1="497.1563" y2="497.1563"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="341.5" x2="341.5" y1="497.1563" y2="510.1563"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="300.5" x2="341.5" y1="510.1563" y2="510.1563"/><polygon fill="#A80036" points="310.5,506.1563,300.5,510.1563,310.5,514.1563,306.5,510.1563" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="134" x="306.5" y="492.0903">Parse network model</text><polygon fill="#A80036" points="69.5,520.1563,59.5,524.1563,69.5,528.1563,65.5,524.1563" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="293.5" y1="524.1563" y2="524.1563"/><rect fill="none" height="118.5313" style="stroke: #000000; stroke-width: 2.0;" width="635" x="13" y="539.1563"/><polygon fill="#EEEEEE" points="13,539.1563,90,539.1563,90,546.1563,80,556.1563,13,556.1563,13,539.1563" style="stroke: #000000; stroke-width: 2.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="32" x="28" y="552.2231">loop</text><text fill="#000000" font-family="sans-serif" font-size="11" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="188" x="105" y="551.3667">[Allocate and fill IFM buffers]</text><polygon fill="#A80036" points="200.5,573.2891,210.5,577.2891,200.5,581.2891,204.5,577.2891" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="206.5" y1="577.2891" y2="577.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="89" x="65.5" y="572.356">Buffer(device)</text><polygon fill="#A80036" points="591.5,602.4219,601.5,606.4219,591.5,610.4219,595.5,606.4219" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="222.5" x2="597.5" y1="606.4219" y2="606.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="229.5" y="601.4888">ioctl(BUFFER_CREATE)</text><polygon fill="#A80036" points="233.5,631.5547,223.5,635.5547,233.5,639.5547,229.5,635.5547" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="227.5" x2="607.5" y1="635.5547" y2="635.5547"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="239.5" y="630.6216">file descriptor</text><polygon fill="#A80036" points="69.5,645.6875,59.5,649.6875,69.5,653.6875,65.5,649.6875" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="216.5" y1="649.6875" y2="649.6875"/><rect fill="none" height="118.5313" style="stroke: #000000; stroke-width: 2.0;" width="635" x="13" y="671.6875"/><polygon fill="#EEEEEE" points="13,671.6875,90,671.6875,90,678.6875,80,688.6875,13,688.6875,13,671.6875" style="stroke: #000000; stroke-width: 2.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="32" x="28" y="684.7544">loop</text><text fill="#000000" font-family="sans-serif" font-size="11" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="145" x="105" y="683.8979">[Allocate OFM buffers]</text><polygon fill="#A80036" points="200.5,705.8203,210.5,709.8203,200.5,713.8203,204.5,709.8203" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="206.5" y1="709.8203" y2="709.8203"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="89" x="65.5" y="704.8872">Buffer(device)</text><polygon fill="#A80036" points="591.5,734.9531,601.5,738.9531,591.5,742.9531,595.5,738.9531" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="222.5" x2="597.5" y1="738.9531" y2="738.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="229.5" y="734.02">ioctl(BUFFER_CREATE)</text><polygon fill="#A80036" points="233.5,764.0859,223.5,768.0859,233.5,772.0859,229.5,768.0859" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="227.5" x2="607.5" y1="768.0859" y2="768.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="239.5" y="763.1528">file descriptor</text><polygon fill="#A80036" points="69.5,778.2188,59.5,782.2188,69.5,786.2188,65.5,782.2188" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="216.5" y1="782.2188" y2="782.2188"/><polygon fill="#FBFB77" filter="url(#f528w0w85mfwd)" points="360,802.2188,360,827.2188,540,827.2188,540,812.2188,530,802.2188,360,802.2188" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="530" x2="530" y1="802.2188" y2="812.2188"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="540" x2="530" y1="812.2188" y2="812.2188"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="159" x="366" y="819.2856">Create and run inference</text><polygon fill="#A80036" points="435.5,853.3516,445.5,857.3516,435.5,861.3516,439.5,857.3516" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="441.5" y1="857.3516" y2="857.3516"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="180" x="65.5" y="852.4185">Inference(network, ifm, ofm)</text><polygon fill="#A80036" points="757.5,882.4844,767.5,886.4844,757.5,890.4844,761.5,886.4844" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="457.5" x2="763.5" y1="886.4844" y2="886.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="163" x="464.5" y="881.5513">ioctl(INFERENCE_CREATE)</text><polygon fill="#A80036" points="468.5,911.6172,458.5,915.6172,468.5,919.6172,464.5,915.6172" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="462.5" x2="773.5" y1="915.6172" y2="915.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="474.5" y="910.6841">file descriptor</text><polygon fill="#A80036" points="69.5,925.75,59.5,929.75,69.5,933.75,65.5,929.75" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="451.5" y1="929.75" y2="929.75"/><polygon fill="#A80036" points="435.5,954.75,445.5,958.75,435.5,962.75,439.5,958.75" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="441.5" y1="958.75" y2="958.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="121" x="65.5" y="953.8169">wait(file descriptor)</text><polygon fill="#A80036" points="757.5,983.8828,767.5,987.8828,757.5,991.8828,761.5,987.8828" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="457.5" x2="763.5" y1="987.8828" y2="987.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="118" x="464.5" y="982.9497">poll(file descriptor)</text><polygon fill="#A80036" points="468.5,998.0156,458.5,1002.0156,468.5,1006.0156,464.5,1002.0156" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="462.5" x2="773.5" y1="1002.0156" y2="1002.0156"/><polygon fill="#A80036" points="69.5,1012.0156,59.5,1016.0156,69.5,1020.0156,65.5,1016.0156" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="451.5" y1="1016.0156" y2="1016.0156"/><!--
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="942px" preserveAspectRatio="none" style="width:845px;height:942px;background:#FEFEFE;" version="1.1" viewBox="0 0 845 942" width="845px" zoomAndPan="magnify"><defs><filter height="300%" id="f105wwwd7nmw4q" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#0091BD" height="927.7813" style="stroke: #A80036; stroke-width: 1.0;" width="89" x="9" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="83" x="12" y="16.0669">Application</text><rect fill="#00C1DE" height="927.7813" style="stroke: #A80036; stroke-width: 1.0;" width="403" x="109" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="96" x="262.5" y="16.0669">Driver library</text><rect fill="#7D868C" height="927.7813" style="stroke: #A80036; stroke-width: 1.0;" width="320" x="514" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="95" x="626.5" y="16.0669">Kernel driver</text><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="816.0547" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="48.5" y="68.4297"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="72.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="140.5" y="128.6953"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="72.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="436.8906"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="72.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="569.4219"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="114.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="303.5" y="269.2266"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="72.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="461.5" y="716.9531"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="57.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="461.5" y="818.3516"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="545.5" y="157.8281"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="617.5" y="466.0234"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="617.5" y="598.5547"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="694.5" y="298.3594"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="783.5" y="746.0859"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="14" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="783.5" y="847.4844"/><rect fill="#FEFEFE" filter="url(#f105wwwd7nmw4q)" height="118.5313" style="stroke: #000000; stroke-width: 2.0;" width="649" x="13" y="398.625"/><rect fill="#FEFEFE" filter="url(#f105wwwd7nmw4q)" height="118.5313" style="stroke: #000000; stroke-width: 2.0;" width="649" x="13" y="531.1563"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="53" x2="53" y1="58.4297" y2="893.4844"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="145" x2="145" y1="58.4297" y2="893.4844"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="217" x2="217" y1="58.4297" y2="893.4844"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="308" x2="308" y1="58.4297" y2="893.4844"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="466" x2="466" y1="58.4297" y2="893.4844"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="550" x2="550" y1="58.4297" y2="893.4844"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="622" x2="622" y1="58.4297" y2="893.4844"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="699" x2="699" y1="58.4297" y2="893.4844"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="788" x2="788" y1="58.4297" y2="893.4844"/><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="57" x="23" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="30" y="43.1279">main()</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="57" x="23" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="30" y="912.4795">main()</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="113" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="120" y="43.1279">Device</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="113" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="120" y="912.4795">Device</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="188" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="195" y="43.1279">Buffer</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="188" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="195" y="912.4795">Buffer</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="271" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="278" y="43.1279">Network</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="271" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="278" y="912.4795">Network</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="425" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="432" y="43.1279">Inference</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="425" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="432" y="912.4795">Inference</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="518" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="525" y="43.1279">Device</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="518" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="525" y="912.4795">Device</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="593" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="600" y="43.1279">Buffer</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="593" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="600" y="912.4795">Buffer</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="662" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="669" y="43.1279">Network</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="662" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="669" y="912.4795">Network</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="747" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="754" y="43.1279">Inference</text><rect fill="#FEFECE" filter="url(#f105wwwd7nmw4q)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="747" y="892.4844"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="754" y="912.4795">Inference</text><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="816.0547" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="48.5" y="68.4297"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="72.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="140.5" y="128.6953"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="72.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="436.8906"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="72.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="212.5" y="569.4219"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="114.3984" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="303.5" y="269.2266"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="72.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="461.5" y="716.9531"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="57.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="461.5" y="818.3516"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="545.5" y="157.8281"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="617.5" y="466.0234"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="617.5" y="598.5547"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="694.5" y="298.3594"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="783.5" y="746.0859"/><rect fill="#FFFFFF" filter="url(#f105wwwd7nmw4q)" height="14" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="783.5" y="847.4844"/><path d="M89,73.4297 L89,98.4297 L198,98.4297 L198,83.4297 L188,73.4297 L89,73.4297 " fill="#FBFB77" filter="url(#f105wwwd7nmw4q)" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M188,73.4297 L188,83.4297 L198,83.4297 L188,73.4297 " fill="#FBFB77" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="88" x="95" y="90.4966">Create device</text><polygon fill="#A80036" points="128.5,124.6953,138.5,128.6953,128.5,132.6953,132.5,128.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="134.5" y1="128.6953" y2="128.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="53" x="65.5" y="123.6294">Device()</text><polygon fill="#A80036" points="533.5,153.8281,543.5,157.8281,533.5,161.8281,537.5,157.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="150.5" x2="539.5" y1="157.8281" y2="157.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="157.5" y="152.7622">open(&lt;device node&gt;)</text><polygon fill="#A80036" points="161.5,182.9609,151.5,186.9609,161.5,190.9609,157.5,186.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="155.5" x2="549.5" y1="186.9609" y2="186.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="167.5" y="181.895">file descriptor</text><polygon fill="#A80036" points="69.5,196.9609,59.5,200.9609,69.5,204.9609,65.5,200.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="144.5" y1="200.9609" y2="200.9609"/><path d="M176,213.9609 L176,238.9609 L436,238.9609 L436,223.9609 L426,213.9609 L176,213.9609 " fill="#FBFB77" filter="url(#f105wwwd7nmw4q)" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M426,213.9609 L426,223.9609 L436,223.9609 L426,213.9609 " fill="#FBFB77" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="239" x="182" y="231.0278">Create network, parse network model</text><polygon fill="#A80036" points="291.5,265.2266,301.5,269.2266,291.5,273.2266,295.5,269.2266" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="297.5" y1="269.2266" y2="269.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="216" x="65.5" y="264.1606">Network(device, user_buffer, size)</text><polygon fill="#A80036" points="682.5,294.3594,692.5,298.3594,682.5,302.3594,686.5,298.3594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="313.5" x2="688.5" y1="298.3594" y2="298.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="154" x="320.5" y="293.2935">ioctl(NETWORK_CREATE)</text><polygon fill="#A80036" points="324.5,323.4922,314.5,327.4922,324.5,331.4922,320.5,327.4922" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="318.5" x2="698.5" y1="327.4922" y2="327.4922"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="330.5" y="322.4263">file descriptor</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="313.5" x2="355.5" y1="356.625" y2="356.625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="355.5" x2="355.5" y1="356.625" y2="369.625"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="314.5" x2="355.5" y1="369.625" y2="369.625"/><polygon fill="#A80036" points="324.5,365.625,314.5,369.625,324.5,373.625,320.5,369.625" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="134" x="320.5" y="351.5591">Parse network model</text><polygon fill="#A80036" points="69.5,379.625,59.5,383.625,69.5,387.625,65.5,383.625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="307.5" y1="383.625" y2="383.625"/><path d="M13,398.625 L90,398.625 L90,405.625 L80,415.625 L13,415.625 L13,398.625 " fill="#EEEEEE" style="stroke: #000000; stroke-width: 1.0;"/><rect fill="none" height="118.5313" style="stroke: #000000; stroke-width: 2.0;" width="649" x="13" y="398.625"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="32" x="28" y="411.6919">loop</text><text fill="#000000" font-family="sans-serif" font-size="11" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="188" x="105" y="410.8354">[Allocate and fill IFM buffers]</text><polygon fill="#A80036" points="200.5,432.8906,210.5,436.8906,200.5,440.8906,204.5,436.8906" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="206.5" y1="436.8906" y2="436.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="89" x="65.5" y="431.8247">Buffer(device)</text><polygon fill="#A80036" points="605.5,462.0234,615.5,466.0234,605.5,470.0234,609.5,466.0234" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="222.5" x2="611.5" y1="466.0234" y2="466.0234"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="229.5" y="460.9575">ioctl(BUFFER_CREATE)</text><polygon fill="#A80036" points="233.5,491.1563,223.5,495.1563,233.5,499.1563,229.5,495.1563" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="227.5" x2="621.5" y1="495.1563" y2="495.1563"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="239.5" y="490.0903">file descriptor</text><polygon fill="#A80036" points="69.5,505.1563,59.5,509.1563,69.5,513.1563,65.5,509.1563" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="216.5" y1="509.1563" y2="509.1563"/><path d="M13,531.1563 L90,531.1563 L90,538.1563 L80,548.1563 L13,548.1563 L13,531.1563 " fill="#EEEEEE" style="stroke: #000000; stroke-width: 1.0;"/><rect fill="none" height="118.5313" style="stroke: #000000; stroke-width: 2.0;" width="649" x="13" y="531.1563"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="32" x="28" y="544.2231">loop</text><text fill="#000000" font-family="sans-serif" font-size="11" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="145" x="105" y="543.3667">[Allocate OFM buffers]</text><polygon fill="#A80036" points="200.5,565.4219,210.5,569.4219,200.5,573.4219,204.5,569.4219" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="206.5" y1="569.4219" y2="569.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="89" x="65.5" y="564.356">Buffer(device)</text><polygon fill="#A80036" points="605.5,594.5547,615.5,598.5547,605.5,602.5547,609.5,598.5547" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="222.5" x2="611.5" y1="598.5547" y2="598.5547"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="229.5" y="593.4888">ioctl(BUFFER_CREATE)</text><polygon fill="#A80036" points="233.5,623.6875,223.5,627.6875,233.5,631.6875,229.5,627.6875" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="227.5" x2="621.5" y1="627.6875" y2="627.6875"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="239.5" y="622.6216">file descriptor</text><polygon fill="#A80036" points="69.5,637.6875,59.5,641.6875,69.5,645.6875,65.5,641.6875" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="216.5" y1="641.6875" y2="641.6875"/><path d="M374,661.6875 L374,686.6875 L554,686.6875 L554,671.6875 L544,661.6875 L374,661.6875 " fill="#FBFB77" filter="url(#f105wwwd7nmw4q)" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M544,661.6875 L544,671.6875 L554,671.6875 L544,661.6875 " fill="#FBFB77" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="159" x="380" y="678.7544">Create and run inference</text><polygon fill="#A80036" points="449.5,712.9531,459.5,716.9531,449.5,720.9531,453.5,716.9531" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="455.5" y1="716.9531" y2="716.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="180" x="65.5" y="711.8872">Inference(network, ifm, ofm)</text><polygon fill="#A80036" points="771.5,742.0859,781.5,746.0859,771.5,750.0859,775.5,746.0859" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="471.5" x2="777.5" y1="746.0859" y2="746.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="163" x="478.5" y="741.02">ioctl(INFERENCE_CREATE)</text><polygon fill="#A80036" points="482.5,771.2188,472.5,775.2188,482.5,779.2188,478.5,775.2188" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="476.5" x2="787.5" y1="775.2188" y2="775.2188"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="488.5" y="770.1528">file descriptor</text><polygon fill="#A80036" points="69.5,785.2188,59.5,789.2188,69.5,793.2188,65.5,789.2188" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="465.5" y1="789.2188" y2="789.2188"/><polygon fill="#A80036" points="449.5,814.3516,459.5,818.3516,449.5,822.3516,453.5,818.3516" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="58.5" x2="455.5" y1="818.3516" y2="818.3516"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="121" x="65.5" y="813.2856">wait(file descriptor)</text><polygon fill="#A80036" points="771.5,843.4844,781.5,847.4844,771.5,851.4844,775.5,847.4844" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="471.5" x2="777.5" y1="847.4844" y2="847.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="118" x="478.5" y="842.4185">poll(file descriptor)</text><polygon fill="#A80036" points="482.5,857.4844,472.5,861.4844,482.5,865.4844,478.5,861.4844" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="476.5" x2="787.5" y1="861.4844" y2="861.4844"/><polygon fill="#A80036" points="69.5,871.4844,59.5,875.4844,69.5,879.4844,65.5,875.4844" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="63.5" x2="465.5" y1="875.4844" y2="875.4844"/><!--MD5=[aa4ced5da24ed5aa951387ff7db834b9]
@startuml
skinparam backgroundColor #FEFEFE
@@ -31,19 +31,10 @@ main -> ddev++: Device()
return
note over dnet
- Allocate and fill network buffer
-end note
-
-main -> dbuf++: Buffer(device)
- dbuf -> kbuf++: ioctl(BUFFER_CREATE)
- return file descriptor
-return
-
-note over dnet
Create network, parse network model
end note
-main -> dnet++: Network(device, buffer)
+main -> dnet++: Network(device, user_buffer, size)
dnet -> knet++: ioctl(NETWORK_CREATE)
return file descriptor
@@ -79,13 +70,12 @@ return
@enduml
-PlantUML version 1.2017.15(Mon Jul 03 18:45:34 CEST 2017)
+PlantUML version 1.2020.02(Sun Mar 01 11:22:07 CET 2020)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
-Java Version: 11.0.11+9-Ubuntu-0ubuntu2.18.04
+Java Version: 11.0.20.1+1-post-Ubuntu-0ubuntu122.04
Operating System: Linux
-OS Version: 5.4.0-73-generic
Default Encoding: UTF-8
Language: en
Country: US
diff --git a/docs/kernel_network.puml b/docs/kernel_network.puml
index 39c7f55..b9136ce 100644
--- a/docs/kernel_network.puml
+++ b/docs/kernel_network.puml
@@ -24,16 +24,16 @@ activate main
note over main
Create device
- Allocate and fill network buffer
+ Provide user buffer with network model
end note
-main -> dnet++: Network(device, buffer)
- dnet -> kdev++: ioctl(NETWORK_CREATE, buffer)
+main -> dnet++: Network(device, user_buffer, size)
+ dnet -> kdev++: ioctl(NETWORK_CREATE, user_buffer, size)
note over knet
Create network and return file descriptor
end note
- kdev -> knet++: create(buffer)
+ kdev -> knet++: create(user_buffer, size)
return file descriptor
return file descriptor
return
diff --git a/docs/kernel_network.svg b/docs/kernel_network.svg
index 8b3b4a3..2b8f753 100644
--- a/docs/kernel_network.svg
+++ b/docs/kernel_network.svg
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="380px" preserveAspectRatio="none" style="width:874px;height:380px;background:#FEFEFE;" version="1.1" viewBox="0 0 874 380" width="874px" zoomAndPan="magnify"><defs><filter height="300%" id="fflf1tczznf06" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#0091BD" height="365.7891" style="stroke: #A80036; stroke-width: 1.0;" width="89" x="71" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="83" x="74" y="16.0669">Application</text><rect fill="#00C1DE" height="365.7891" style="stroke: #A80036; stroke-width: 1.0;" width="320" x="162" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="96" x="274" y="16.0669">Driver library</text><rect fill="#7D868C" height="365.7891" style="stroke: #A80036; stroke-width: 1.0;" width="320" x="539" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="95" x="651.5" y="16.0669">Kernel driver</text><rect fill="#FFFFFF" filter="url(#fflf1tczznf06)" height="254.0625" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="110.5" y="68.4297"/><rect fill="#FFFFFF" filter="url(#fflf1tczznf06)" height="169.7969" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="342.5" y="143.6953"/><rect fill="#FFFFFF" filter="url(#fflf1tczznf06)" height="126.5313" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="570.5" y="172.8281"/><rect fill="#FFFFFF" filter="url(#fflf1tczznf06)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="719.5" y="241.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="115" x2="115" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="198" x2="198" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="270" x2="270" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="347" x2="347" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="436" x2="436" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="575" x2="575" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="647" x2="647" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="724" x2="724" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="813" x2="813" y1="58.4297" y2="331.4922"/><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="57" x="85" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="92" y="43.1279">main()</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="57" x="85" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="92" y="350.4873">main()</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="166" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="173" y="43.1279">Device</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="166" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="173" y="350.4873">Device</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="241" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="248" y="43.1279">Buffer</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="241" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="248" y="350.4873">Buffer</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="310" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="317" y="43.1279">Network</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="310" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="317" y="350.4873">Network</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="395" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="402" y="43.1279">Inference</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="395" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="402" y="350.4873">Inference</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="543" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="550" y="43.1279">Device</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="543" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="550" y="350.4873">Device</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="618" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="625" y="43.1279">Buffer</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="618" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="625" y="350.4873">Buffer</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="687" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="694" y="43.1279">Network</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="687" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="694" y="350.4873">Network</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="772" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="779" y="43.1279">Inference</text><rect fill="#FEFECE" filter="url(#fflf1tczznf06)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="772" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="779" y="350.4873">Inference</text><rect fill="#FFFFFF" filter="url(#fflf1tczznf06)" height="254.0625" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="110.5" y="68.4297"/><rect fill="#FFFFFF" filter="url(#fflf1tczznf06)" height="169.7969" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="342.5" y="143.6953"/><rect fill="#FFFFFF" filter="url(#fflf1tczznf06)" height="126.5313" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="570.5" y="172.8281"/><rect fill="#FFFFFF" filter="url(#fflf1tczznf06)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="719.5" y="241.0938"/><polygon fill="#FBFB77" filter="url(#fflf1tczznf06)" points="8,73.4297,8,113.4297,220,113.4297,220,83.4297,210,73.4297,8,73.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="210" x2="210" y1="73.4297" y2="83.4297"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="220" x2="210" y1="83.4297" y2="83.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="88" x="14" y="90.4966">Create device</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="191" x="14" y="105.6294">Allocate and fill network buffer</text><polygon fill="#A80036" points="330.5,139.6953,340.5,143.6953,330.5,147.6953,334.5,143.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="120.5" x2="336.5" y1="143.6953" y2="143.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="148" x="127.5" y="138.7622">Network(device, buffer)</text><polygon fill="#A80036" points="558.5,168.8281,568.5,172.8281,558.5,176.8281,562.5,172.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="352.5" x2="564.5" y1="172.8281" y2="172.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="199" x="359.5" y="167.895">ioctl(NETWORK_CREATE, buffer)</text><polygon fill="#FBFB77" filter="url(#fflf1tczznf06)" points="583,185.9609,583,210.9609,862,210.9609,862,195.9609,852,185.9609,583,185.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="852" x2="852" y1="185.9609" y2="195.9609"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="862" x2="852" y1="195.9609" y2="195.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="258" x="589" y="203.0278">Create network and return file descriptor</text><polygon fill="#A80036" points="707.5,237.0938,717.5,241.0938,707.5,245.0938,711.5,241.0938" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="580.5" x2="713.5" y1="241.0938" y2="241.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="88" x="587.5" y="236.1606">create(buffer)</text><polygon fill="#A80036" points="591.5,266.2266,581.5,270.2266,591.5,274.2266,587.5,270.2266" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="585.5" x2="723.5" y1="270.2266" y2="270.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="597.5" y="265.2935">file descriptor</text><polygon fill="#A80036" points="363.5,295.3594,353.5,299.3594,363.5,303.3594,359.5,299.3594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="357.5" x2="574.5" y1="299.3594" y2="299.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="369.5" y="294.4263">file descriptor</text><polygon fill="#A80036" points="131.5,309.4922,121.5,313.4922,131.5,317.4922,127.5,313.4922" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="125.5" x2="346.5" y1="313.4922" y2="313.4922"/><!--
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="380px" preserveAspectRatio="none" style="width:1029px;height:380px;background:#FEFEFE;" version="1.1" viewBox="0 0 1029 380" width="1029px" zoomAndPan="magnify"><defs><filter height="300%" id="fppms3ru5k1wp" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#0091BD" height="365.7891" style="stroke: #A80036; stroke-width: 1.0;" width="89" x="99" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="83" x="102" y="16.0669">Application</text><rect fill="#00C1DE" height="365.7891" style="stroke: #A80036; stroke-width: 1.0;" width="343" x="190" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="96" x="313.5" y="16.0669">Driver library</text><rect fill="#7D868C" height="365.7891" style="stroke: #A80036; stroke-width: 1.0;" width="356" x="658" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="95" x="788.5" y="16.0669">Kernel driver</text><rect fill="#FFFFFF" filter="url(#fppms3ru5k1wp)" height="254.0625" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="138.5" y="68.4297"/><rect fill="#FFFFFF" filter="url(#fppms3ru5k1wp)" height="169.6641" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="393.5" y="143.8281"/><rect fill="#FFFFFF" filter="url(#fppms3ru5k1wp)" height="126.5313" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="689.5" y="172.9609"/><rect fill="#FFFFFF" filter="url(#fppms3ru5k1wp)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="874.5" y="241.2266"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="143" x2="143" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="226" x2="226" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="298" x2="298" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="398" x2="398" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="487" x2="487" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="694" x2="694" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="766" x2="766" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="879" x2="879" y1="58.4297" y2="331.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="968" x2="968" y1="58.4297" y2="331.4922"/><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="57" x="113" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="120" y="43.1279">main()</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="57" x="113" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="43" x="120" y="350.4873">main()</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="194" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="201" y="43.1279">Device</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="194" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="201" y="350.4873">Device</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="269" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="276" y="43.1279">Buffer</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="269" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="276" y="350.4873">Buffer</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="361" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="368" y="43.1279">Network</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="361" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="368" y="350.4873">Network</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="446" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="453" y="43.1279">Inference</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="446" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="453" y="350.4873">Inference</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="662" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="669" y="43.1279">Device</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="61" x="662" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="669" y="350.4873">Device</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="737" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="744" y="43.1279">Buffer</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="55" x="737" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="41" x="744" y="350.4873">Buffer</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="842" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="849" y="43.1279">Network</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="71" x="842" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="57" x="849" y="350.4873">Network</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="927" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="934" y="43.1279">Inference</text><rect fill="#FEFECE" filter="url(#fppms3ru5k1wp)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="79" x="927" y="330.4922"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="65" x="934" y="350.4873">Inference</text><rect fill="#FFFFFF" filter="url(#fppms3ru5k1wp)" height="254.0625" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="138.5" y="68.4297"/><rect fill="#FFFFFF" filter="url(#fppms3ru5k1wp)" height="169.6641" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="393.5" y="143.8281"/><rect fill="#FFFFFF" filter="url(#fppms3ru5k1wp)" height="126.5313" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="689.5" y="172.9609"/><rect fill="#FFFFFF" filter="url(#fppms3ru5k1wp)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="874.5" y="241.2266"/><path d="M8,73.4297 L8,113.4297 L276,113.4297 L276,83.4297 L266,73.4297 L8,73.4297 " fill="#FBFB77" filter="url(#fppms3ru5k1wp)" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M266,73.4297 L266,83.4297 L276,83.4297 L266,73.4297 " fill="#FBFB77" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="88" x="14" y="90.4966">Create device</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="247" x="14" y="105.6294">Provide user buffer with network model</text><polygon fill="#A80036" points="381.5,139.8281,391.5,143.8281,381.5,147.8281,385.5,143.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="148.5" x2="387.5" y1="143.8281" y2="143.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="216" x="155.5" y="138.7622">Network(device, user_buffer, size)</text><polygon fill="#A80036" points="677.5,168.9609,687.5,172.9609,677.5,176.9609,681.5,172.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="403.5" x2="683.5" y1="172.9609" y2="172.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="267" x="410.5" y="167.895">ioctl(NETWORK_CREATE, user_buffer, size)</text><path d="M738,185.9609 L738,210.9609 L1017,210.9609 L1017,195.9609 L1007,185.9609 L738,185.9609 " fill="#FBFB77" filter="url(#fppms3ru5k1wp)" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M1007,185.9609 L1007,195.9609 L1017,195.9609 L1007,185.9609 " fill="#FBFB77" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="258" x="744" y="203.0278">Create network and return file descriptor</text><polygon fill="#A80036" points="862.5,237.2266,872.5,241.2266,862.5,245.2266,866.5,241.2266" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="699.5" x2="868.5" y1="241.2266" y2="241.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="156" x="706.5" y="236.1606">create(user_buffer, size)</text><polygon fill="#A80036" points="710.5,266.3594,700.5,270.3594,710.5,274.3594,706.5,270.3594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="704.5" x2="878.5" y1="270.3594" y2="270.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="716.5" y="265.2935">file descriptor</text><polygon fill="#A80036" points="414.5,295.4922,404.5,299.4922,414.5,303.4922,410.5,299.4922" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="408.5" x2="693.5" y1="299.4922" y2="299.4922"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="86" x="420.5" y="294.4263">file descriptor</text><polygon fill="#A80036" points="159.5,309.4922,149.5,313.4922,159.5,317.4922,155.5,313.4922" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="153.5" x2="397.5" y1="313.4922" y2="313.4922"/><!--MD5=[237279265ff59fe4aa02ccba32edf4aa]
@startuml
skinparam backgroundColor #FEFEFE
@@ -25,29 +25,28 @@ activate main
note over main
Create device
- Allocate and fill network buffer
+ Provide user buffer with network model
end note
-main -> dnet++: Network(device, buffer)
- dnet -> kdev++: ioctl(NETWORK_CREATE, buffer)
+main -> dnet++: Network(device, user_buffer, size)
+ dnet -> kdev++: ioctl(NETWORK_CREATE, user_buffer, size)
note over knet
Create network and return file descriptor
end note
- kdev -> knet++: create(buffer)
+ kdev -> knet++: create(user_buffer, size)
return file descriptor
return file descriptor
return
@enduml
-PlantUML version 1.2017.15(Mon Jul 03 18:45:34 CEST 2017)
+PlantUML version 1.2020.02(Sun Mar 01 11:22:07 CET 2020)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
-Java Version: 11.0.11+9-Ubuntu-0ubuntu2.18.04
+Java Version: 11.0.20.1+1-post-Ubuntu-0ubuntu122.04
Operating System: Linux
-OS Version: 5.4.0-73-generic
Default Encoding: UTF-8
Language: en
Country: US
diff --git a/driver_library/include/ethosu.hpp b/driver_library/include/ethosu.hpp
index 47c1868..eaa1ce7 100644
--- a/driver_library/include/ethosu.hpp
+++ b/driver_library/include/ethosu.hpp
@@ -39,12 +39,12 @@
namespace EthosU {
-constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 2;
+constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 3;
constexpr uint32_t DRIVER_LIBRARY_VERSION_MINOR = 0;
constexpr uint32_t DRIVER_LIBRARY_VERSION_PATCH = 0;
-constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 2;
-constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 2;
+constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 3;
+constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 3;
class Exception : public std::exception {
public:
@@ -168,12 +168,11 @@ private:
class Network {
public:
- Network(const Device &device, std::shared_ptr<Buffer> &buffer);
+ Network(const Device &device, const unsigned char *networkData, size_t networkSize);
Network(const Device &device, const unsigned index);
virtual ~Network() noexcept(false);
int ioctl(unsigned long cmd, void *data = nullptr);
- std::shared_ptr<Buffer> getBuffer();
const std::vector<size_t> &getIfmDims() const;
size_t getIfmSize() const;
const std::vector<size_t> &getOfmDims() const;
@@ -183,7 +182,6 @@ private:
void collectNetworkInfo();
int fd;
- std::shared_ptr<Buffer> buffer;
std::vector<size_t> ifmDims;
std::vector<size_t> ofmDims;
};
diff --git a/driver_library/python/README.md b/driver_library/python/README.md
index 7fae749..cc67ad9 100644
--- a/driver_library/python/README.md
+++ b/driver_library/python/README.md
@@ -165,8 +165,8 @@ object:
```python
# from file:
-network_file = "/path/to/model.tflite"
-network_buffer = driver.Buffer(device, network_file)
+data_file = "/path/to/data.bin"
+buffer = driver.Buffer(device, data_file)
# from numpy:
ifm_zeros = numpy.zeros(ifm_size, dtype=np.uint8)
@@ -174,11 +174,15 @@ ifm_buffer = driver.Buffer(device, ifm_size)
ifm_buffer.from_buffer(ifm_zeros.data)
```
-To create a network object, provide memory buffer for the model file and
-created device:
+To create a network object, provide the model file or a byte array with the
+network data and the created device:
```python
-network = driver.Network(device, network_buffer)
+# from file:
+network = driver.Network(device, "path/to/model.tflite")
+
+# from byte array:
+network = driver.Network(device, network_data)
```
Inference object is instantiated with a network object and lists of input
diff --git a/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py b/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
index fcea91f..ca39751 100644
--- a/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
+++ b/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
@@ -30,8 +30,7 @@ def load_model(device: Device, model: str) -> Network:
`Network`: Return the object that represent the neural __network file descriptor received from the Ethos-U device.
"""
logging.info("Creating network")
- network_buffer = Buffer(device, model)
- return Network(device, network_buffer)
+ return Network(device, model)
def populate_buffers(input_data: List[bytearray], buffers: List[Buffer]):
diff --git a/driver_library/python/src/ethosu_driver/swig/driver.i b/driver_library/python/src/ethosu_driver/swig/driver.i
index 3e4e384..6e0ad25 100644
--- a/driver_library/python/src/ethosu_driver/swig/driver.i
+++ b/driver_library/python/src/ethosu_driver/swig/driver.i
@@ -293,12 +293,12 @@ public:
buffer: data to be copied to the mapped memory.
") from_buffer;
- %mutable_buffer(char* buffer, size_t size);
+ %buffer_in(char* buffer, size_t size, BUFFER_FLAG_RW);
void from_buffer(char* buffer, size_t size) {
char* data = $self->data();
std::memcpy(data, buffer, size);
}
- %clear_mutable_buffer(char* buffer, size_t size);
+ %clear_buffer_in(char* buffer, size_t size);
}
%feature("docstring",
@@ -329,15 +329,6 @@ public:
%feature("docstring",
"
- Returns associated memory buffer.
-
- Returns:
- `Buffer`: buffer object used during initialisation.
- ") getBuffer;
- std::shared_ptr<Buffer> getBuffer();
-
- %feature("docstring",
- "
Returns saved sizes of the neural network model input feature maps.
Returns:
@@ -374,21 +365,41 @@ public:
};
%extend Network {
- Network(const Device &device, std::shared_ptr<Buffer> &buffer)
+
+ Network(const Device &device, const std::string& filename)
{
- if(buffer == nullptr){
- throw EthosU::Exception(std::string("Failed to create the network, buffer is nullptr.").c_str());
+ std::ifstream stream(filename, std::ios::binary);
+ if (!stream.is_open()) {
+ throw EthosU::Exception(std::string("Failed to open file: ").append(filename).c_str());
}
- auto network = new EthosU::Network(device, buffer);
- return network;
+
+ stream.seekg(0, std::ios_base::end);
+ size_t size = stream.tellg();
+ stream.seekg(0, std::ios_base::beg);
+
+ std::unique_ptr<unsigned char[]> buffer = std::make_unique<unsigned char[]>(size);
+ stream.read(reinterpret_cast<char*>(buffer.get()), size);
+ return new EthosU::Network(device, buffer.get(), size);
}
-}
-%extend Network {
+ %buffer_in(const unsigned char* networkData, size_t networkSize, BUFFER_FLAG_RO);
+ Network(const Device &device, const unsigned char* networkData, size_t networkSize)
+ {
+ if(networkData == nullptr){
+ throw EthosU::Exception(std::string("Failed to create the network, networkData is nullptr.").c_str());
+ }
+
+ if(networkSize == 0U){
+ throw EthosU::Exception(std::string("Failed to create the network, networkSize is zero.").c_str());
+ }
+
+ return new EthosU::Network(device, networkData, networkSize);
+ }
+ %clear_buffer_in(const unsigned char* networkData, size_t networkSize);
+
Network(const Device &device, const unsigned int index)
{
- auto network = new EthosU::Network(device, index);
- return network;
+ return new EthosU::Network(device, index);
}
}
diff --git a/driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i b/driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i
index 13b7909..bb4627c 100644
--- a/driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i
+++ b/driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i
@@ -1,19 +1,25 @@
//
-// SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+// SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
// SPDX-License-Identifier: Apache-2.0
//
-%define %mutable_buffer(TYPEMAP, SIZE)
+
+%define BUFFER_FLAG_RO 0 %enddef
+%define BUFFER_FLAG_RW PyBUF_WRITABLE %enddef
+
+%define %buffer_in(TYPEMAP, SIZE, FLAG)
%typemap(in) (TYPEMAP, SIZE) {
- int res; void *buf = 0; size_t size = 0;
Py_buffer view;
- res = PyObject_GetBuffer($input, &view, PyBUF_WRITABLE);
- buf = view.buf;
- size = view.len;
- PyBuffer_Release(&view);
+
+ int res = PyObject_GetBuffer($input, &view, FLAG);
if (res < 0) {
PyErr_Clear();
%argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
}
+
+ void *buf = view.buf;
+ size_t size = view.len;
+ PyBuffer_Release(&view);
+
$1 = ($1_ltype) buf;
$2 = ($2_ltype) size;
}
@@ -23,12 +29,11 @@
}
%enddef
-%define %clear_mutable_buffer(TYPEMAP, SIZE)
+%define %clear_buffer_in(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE);
%typemap(typecheck) (TYPEMAP, SIZE);
%enddef
-
%define %driver_buffer_out
%typemap(out) (char*) {
auto size = arg1->size();
diff --git a/driver_library/python/test/test_driver.py b/driver_library/python/test/test_driver.py
index 0dd207f..e9cb5c8 100644
--- a/driver_library/python/test/test_driver.py
+++ b/driver_library/python/test/test_driver.py
@@ -15,11 +15,14 @@ def device(device_name):
@pytest.fixture()
-def network_buffer(device, model_name, shared_data_folder):
+def network_file(model_name, shared_data_folder):
network_file = os.path.join(shared_data_folder, model_name)
- network_buffer = driver.Buffer(device, network_file)
- yield network_buffer
+ yield network_file
+@pytest.fixture()
+def network(device, network_file):
+ network = driver.Network(device, network_file)
+ yield network
@pytest.mark.parametrize('device_name', ['ethosu0'])
def test_check_device_swig_ownership(device):
@@ -44,12 +47,33 @@ def test_device_wrong_name(device_name):
@pytest.mark.parametrize('device_name', ['ethosu0'])
-def test_driver_network_filenotfound_exception(device, shared_data_folder):
+@pytest.mark.parametrize('model_name', ['model.tflite'])
+def test_driver_network_from_bytearray(device, network_file):
+ network_data = None
+ with open(network_file, 'rb') as file:
+ network_data = file.read()
+ network = driver.Network(device, network_data)
- network_file = os.path.join(shared_data_folder, "some_unknown_model.tflite")
+@pytest.mark.parametrize('device_name', ['ethosu0'])
+def test_driver_network_from_empty_bytearray(device):
with pytest.raises(RuntimeError) as err:
- network_buffer = driver.Buffer(device, network_file)
+ network = driver.Network(device, bytearray())
+
+ assert 'Failed to create the network, networkSize is zero' in str(err.value)
+
+
+@pytest.mark.parametrize('device_name', ['ethosu0'])
+@pytest.mark.parametrize('model_name', ['model.tflite'])
+def test_driver_network_from_file(device, network_file):
+ network = driver.Network(device, network_file)
+
+
+@pytest.mark.parametrize('device_name', ['ethosu0'])
+@pytest.mark.parametrize('model_name', ['some_unknown_model.tflite'])
+def test_driver_network_filenotfound_exception(device, network_file):
+ with pytest.raises(RuntimeError) as err:
+ network = driver.Network(device, network_file)
# Only check for part of the exception since the exception returns
# absolute path which will change on different machines.
@@ -58,57 +82,51 @@ def test_driver_network_filenotfound_exception(device, shared_data_folder):
@pytest.mark.parametrize('device_name', ['ethosu0'])
@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_swig_ownership(network_buffer):
+def test_check_network_swig_ownership(network):
# Check to see that SWIG has ownership for parser. This instructs SWIG to take
# ownership of the return value. This allows the value to be automatically
# garbage-collected when it is no longer in use
- assert network_buffer.thisown
+ assert network.thisown
@pytest.mark.parametrize('device_name', ['ethosu0'])
@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_size(network_buffer):
- assert network_buffer.size() > 0
+def test_check_network_ifm_size(device, network):
+ assert network.getIfmSize() > 0
@pytest.mark.parametrize('device_name', ['ethosu0'])
@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_clear(network_buffer):
- network_buffer.clear()
- for i in range(network_buffer.size()):
- assert network_buffer.data()[i] == 0
+def test_check_network_ofm_size(device, network):
+ assert network.getOfmSize() > 0
@pytest.mark.parametrize('device_name', ['ethosu0'])
-@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_getFd(network_buffer):
- assert network_buffer.getFd() >= 0
+def test_check_buffer_swig_ownership(device):
+ buffer = driver.Buffer(device, 1024)
+ assert buffer.thisown
@pytest.mark.parametrize('device_name', ['ethosu0'])
-@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_network_ifm_size(device, network_buffer):
- network = driver.Network(device, network_buffer)
- assert network.getIfmSize() > 0
- assert network_buffer.thisown
-
-
-@pytest.mark.parametrize('device_name', [('ethosu0')])
-def test_check_network_buffer_none(device):
+def test_check_buffer_getFd(device):
+ buffer = driver.Buffer(device, 1024)
+ assert buffer.getFd() >= 0
- with pytest.raises(RuntimeError) as err:
- driver.Network(device, None)
- # Only check for part of the exception since the exception returns
- # absolute path which will change on different machines.
- assert 'Failed to create the network' in str(err.value)
+@pytest.mark.parametrize('device_name', ['ethosu0'])
+def test_check_buffer_size(device):
+ buffer = driver.Buffer(device, 1024)
+ assert buffer.size() == 1024
@pytest.mark.parametrize('device_name', ['ethosu0'])
@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_network_ofm_size(device, network_buffer):
- network = driver.Network(device, network_buffer)
- assert network.getOfmSize() > 0
+def test_check_buffer_clear(device, network_file):
+ buffer = driver.Buffer(device, network_file)
+
+ buffer.clear()
+ for i in range(buffer.size()):
+ assert buffer.data()[i] == 0
def test_getMaxPmuEventCounters():
diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp
index 3c7dc31..7aec696 100644
--- a/driver_library/src/ethosu.cpp
+++ b/driver_library/src/ethosu.cpp
@@ -333,12 +333,13 @@ int Buffer::getFd() const {
* Network
****************************************************************************/
-Network::Network(const Device &device, shared_ptr<Buffer> &buffer) : fd(-1), buffer(buffer) {
+Network::Network(const Device &device, const unsigned char *networkData, size_t networkSize) : fd(-1) {
// Create buffer handle
ethosu_uapi_network_create uapi;
- uapi.type = ETHOSU_UAPI_NETWORK_BUFFER;
- uapi.fd = buffer->getFd();
- fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
+ uapi.type = ETHOSU_UAPI_NETWORK_USER_BUFFER;
+ uapi.network.data_ptr = reinterpret_cast<uintptr_t>(networkData);
+ uapi.network.size = networkSize;
+ fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
try {
collectNetworkInfo();
} catch (std::exception &e) {
@@ -348,7 +349,7 @@ Network::Network(const Device &device, shared_ptr<Buffer> &buffer) : fd(-1), buf
throw;
}
- Log(Severity::Info) << "Network(" << &device << ", " << &*buffer << "), this=" << this << ", fd=" << fd << endl;
+ Log(Severity::Info) << "Network(" << &device << "), this=" << this << ", fd=" << fd << endl;
}
Network::Network(const Device &device, const unsigned index) : fd(-1) {
@@ -391,10 +392,6 @@ int Network::ioctl(unsigned long cmd, void *data) {
return eioctl(fd, cmd, data);
}
-shared_ptr<Buffer> Network::getBuffer() {
- return buffer;
-}
-
const std::vector<size_t> &Network::getIfmDims() const {
return ifmDims;
}
diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c
index 73ddb2e..6e2351d 100644
--- a/kernel/ethosu_device.c
+++ b/kernel/ethosu_device.c
@@ -312,8 +312,7 @@ static long ethosu_ioctl(struct file *file,
return ret;
dev_dbg(dev,
- "Device ioctl: Network create. type=%u, fd/index=%u",
- uapi.type, uapi.fd);
+ "Device ioctl: Network create. type=%u\n", uapi.type);
ret = ethosu_network_create(dev, &edev->mailbox, &uapi);
diff --git a/kernel/ethosu_inference.c b/kernel/ethosu_inference.c
index b985e75..57529f9 100644
--- a/kernel/ethosu_inference.c
+++ b/kernel/ethosu_inference.c
@@ -98,9 +98,7 @@ static int ethosu_inference_send(struct ethosu_inference *inf)
ret = ethosu_mailbox_inference(inf->mailbox, &inf->msg,
inf->ifm_count, inf->ifm,
inf->ofm_count, inf->ofm,
- inf->net->buf,
- inf->net->index,
- inf->pmu_event_config,
+ inf->net, inf->pmu_event_config,
ETHOSU_PMU_EVENT_MAX,
inf->pmu_cycle_counter_enable);
if (ret) {
diff --git a/kernel/ethosu_mailbox.c b/kernel/ethosu_mailbox.c
index 9b9cd18..005e83e 100644
--- a/kernel/ethosu_mailbox.c
+++ b/kernel/ethosu_mailbox.c
@@ -239,8 +239,7 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
struct ethosu_buffer **ifm,
uint32_t ofm_count,
struct ethosu_buffer **ofm,
- struct ethosu_buffer *network,
- uint32_t network_index,
+ struct ethosu_network *network,
uint8_t *pmu_event_config,
uint8_t pmu_event_config_count,
uint8_t pmu_cycle_counter_enable)
@@ -279,13 +278,13 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
for (i = 0; i < ETHOSU_CORE_PMU_MAX; i++)
inf_req->pmu_event_config[i] = pmu_event_config[i];
- if (network != NULL) {
+ if (network->dma_mem != NULL) {
inf_req->network.type = ETHOSU_CORE_NETWORK_BUFFER;
ethosu_core_buffer_dma_mem_set(network->dma_mem,
&inf_req->network.buffer);
} else {
inf_req->network.type = ETHOSU_CORE_NETWORK_INDEX;
- inf_req->network.index = network_index;
+ inf_req->network.index = network->index;
}
return ethosu_send_locked(mbox, &rpmsg,
@@ -294,8 +293,7 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
int ethosu_mailbox_network_info_request(struct ethosu_mailbox *mbox,
struct ethosu_mailbox_msg *msg,
- struct ethosu_buffer *network,
- uint32_t network_index)
+ struct ethosu_network *network)
{
struct ethosu_core_rpmsg rpmsg = {
.header = {
@@ -308,13 +306,13 @@ int ethosu_mailbox_network_info_request(struct ethosu_mailbox *mbox,
msg->type = rpmsg.header.type;
- if (network != NULL) {
+ if (network->dma_mem != NULL) {
info_req->network.type = ETHOSU_CORE_NETWORK_BUFFER;
ethosu_core_buffer_dma_mem_set(network->dma_mem,
&info_req->network.buffer);
} else {
info_req->network.type = ETHOSU_CORE_NETWORK_INDEX;
- info_req->network.index = network_index;
+ info_req->network.index = network->index;
}
return ethosu_send_locked(mbox, &rpmsg,
diff --git a/kernel/ethosu_mailbox.h b/kernel/ethosu_mailbox.h
index c4c71a9..ab19613 100644
--- a/kernel/ethosu_mailbox.h
+++ b/kernel/ethosu_mailbox.h
@@ -1,5 +1,6 @@
/*
- * Copyright 2020-2023 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-License-Identifier: GPL-2.0-only
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -14,8 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
- *
- * SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef ETHOSU_MAILBOX_H
@@ -37,9 +36,10 @@
struct device;
struct ethosu_buffer;
-struct ethosu_device;
struct ethosu_core_msg;
struct ethosu_core_queue;
+struct ethosu_device;
+struct ethosu_network;
struct resource;
typedef void (*ethosu_mailbox_cb)(void *user_arg);
@@ -168,8 +168,7 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
struct ethosu_buffer **ifm,
uint32_t ofm_count,
struct ethosu_buffer **ofm,
- struct ethosu_buffer *network,
- uint32_t network_index,
+ struct ethosu_network *network,
uint8_t *pmu_event_config,
uint8_t pmu_event_config_count,
uint8_t pmu_cycle_counter_enable);
@@ -181,8 +180,7 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
*/
int ethosu_mailbox_network_info_request(struct ethosu_mailbox *mbox,
struct ethosu_mailbox_msg *msg,
- struct ethosu_buffer *network,
- uint32_t network_index);
+ struct ethosu_network *network);
/**
* ethosu_mailbox_cancel_inference() - Send inference cancellation
diff --git a/kernel/ethosu_network.c b/kernel/ethosu_network.c
index f7871de..58d5c77 100644
--- a/kernel/ethosu_network.c
+++ b/kernel/ethosu_network.c
@@ -23,8 +23,8 @@
#include "ethosu_network.h"
-#include "ethosu_buffer.h"
#include "ethosu_device.h"
+#include "ethosu_dma_mem.h"
#include "ethosu_inference.h"
#include "ethosu_network_info.h"
#include "uapi/ethosu.h"
@@ -70,8 +70,8 @@ static void ethosu_network_destroy(struct kref *kref)
dev_dbg(dev, "Network destroy. net=0x%pK\n", net);
- if (net->buf != NULL)
- ethosu_buffer_put(net->buf);
+ if (net->dma_mem != NULL)
+ ethosu_dma_mem_free(&net->dma_mem);
memset(net, 0, sizeof(*net));
devm_kfree(dev, net);
@@ -151,7 +151,8 @@ int ethosu_network_create(struct device *dev,
struct ethosu_uapi_network_create *uapi)
{
struct ethosu_network *net;
- int ret = -ENOMEM;
+ const void __user *data;
+ int ret;
net = devm_kzalloc(dev, sizeof(*net), GFP_KERNEL);
if (!net)
@@ -159,17 +160,34 @@ int ethosu_network_create(struct device *dev,
net->dev = dev;
net->mailbox = mailbox;
- net->buf = NULL;
kref_init(&net->kref);
switch (uapi->type) {
- case ETHOSU_UAPI_NETWORK_BUFFER:
- net->buf = ethosu_buffer_get_from_fd(uapi->fd);
- if (IS_ERR(net->buf)) {
- ret = PTR_ERR(net->buf);
+ case ETHOSU_UAPI_NETWORK_USER_BUFFER:
+ if (!uapi->network.data_ptr) {
+ dev_err(dev, "Invalid network data ptr\n");
+ ret = -EINVAL;
goto free_net;
}
+ if (!uapi->network.size) {
+ dev_err(dev, "Invalid network data size\n");
+ ret = -EINVAL;
+ goto free_net;
+ }
+
+ net->dma_mem = ethosu_dma_mem_alloc(dev, uapi->network.size);
+ if (IS_ERR(net->dma_mem)) {
+ ret = PTR_ERR(net->dma_mem);
+ goto free_net;
+ }
+
+ data = u64_to_user_ptr(uapi->network.data_ptr);
+ ret = copy_from_user(net->dma_mem->cpu_addr, data,
+ uapi->network.size);
+ if (ret)
+ goto free_dma_mem;
+
break;
case ETHOSU_UAPI_NETWORK_INDEX:
net->index = uapi->index;
@@ -182,20 +200,20 @@ int ethosu_network_create(struct device *dev,
ret = anon_inode_getfd("ethosu-network", &ethosu_network_fops, net,
O_RDWR | O_CLOEXEC);
if (ret < 0)
- goto put_buf;
+ goto free_dma_mem;
net->file = fget(ret);
fput(net->file);
dev_dbg(dev,
"Network create. file=0x%pK, fd=%d, net=0x%pK, buf=0x%pK, index=%u",
- net->file, ret, net, net->buf, net->index);
+ net->file, ret, net, net->dma_mem, net->index);
return ret;
-put_buf:
- if (net->buf != NULL)
- ethosu_buffer_put(net->buf);
+free_dma_mem:
+ if (net->dma_mem != NULL)
+ ethosu_dma_mem_free(&net->dma_mem);
free_net:
memset(net, 0, sizeof(*net));
diff --git a/kernel/ethosu_network.h b/kernel/ethosu_network.h
index e0d41b1..5484bac 100644
--- a/kernel/ethosu_network.h
+++ b/kernel/ethosu_network.h
@@ -1,5 +1,6 @@
/*
- * Copyright 2020,2022-2023 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2020,2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-License-Identifier: GPL-2.0-only
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -14,8 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
- *
- * SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef ETHOSU_NETWORK_H
@@ -42,7 +41,7 @@ struct ethosu_network {
struct ethosu_mailbox *mailbox;
struct file *file;
struct kref kref;
- struct ethosu_buffer *buf;
+ struct ethosu_dma_mem *dma_mem;
uint32_t index;
};
diff --git a/kernel/ethosu_network_info.c b/kernel/ethosu_network_info.c
index feabcae..011a0b4 100644
--- a/kernel/ethosu_network_info.c
+++ b/kernel/ethosu_network_info.c
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
- *
*/
/****************************************************************************
@@ -39,8 +38,7 @@ static inline int ethosu_network_info_send(struct ethosu_network_info *info,
/* Send network info request to firmware */
return ethosu_mailbox_network_info_request(mailbox,
&info->msg,
- info->net->buf,
- info->net->index);
+ info->net);
}
static void ethosu_network_info_fail(struct ethosu_mailbox_msg *msg)
diff --git a/kernel/uapi/ethosu.h b/kernel/uapi/ethosu.h
index 4e4d180..35eaf60 100644
--- a/kernel/uapi/ethosu.h
+++ b/kernel/uapi/ethosu.h
@@ -67,7 +67,7 @@ namespace EthosU {
#define ETHOSU_PMU_EVENT_MAX 8
/* Kernel driver version */
-#define ETHOSU_KERNEL_DRIVER_VERSION_MAJOR 2
+#define ETHOSU_KERNEL_DRIVER_VERSION_MAJOR 3
#define ETHOSU_KERNEL_DRIVER_VERSION_MINOR 0
#define ETHOSU_KERNEL_DRIVER_VERSION_PATCH 0
@@ -109,13 +109,14 @@ struct ethosu_uapi_buffer_create {
/**
* enum ethosu_uapi_network_type - Network buffer type.
- * @ETHOSU_UAPI_NETWORK_BUFFER: Network is stored in a buffer handle.
- * @ETHOSU_UAPI_NETWORK_INDEX: Network is built into firmware and referenced by
- * index.
+ * @ETHOSU_UAPI_NETWORK_USER_BUFFER: Network data is provided in a user
+ * buffer.
+ * @ETHOSU_UAPI_NETWORK_INDEX: Network is built into firmware and
+ * referenced by index.
*/
enum ethosu_uapi_network_type {
- ETHOSU_UAPI_NETWORK_BUFFER = 1,
- ETHOSU_UAPI_NETWORK_INDEX
+ ETHOSU_UAPI_NETWORK_USER_BUFFER = 1,
+ ETHOSU_UAPI_NETWORK_INDEX,
};
/**
@@ -127,7 +128,10 @@ enum ethosu_uapi_network_type {
struct ethosu_uapi_network_create {
uint32_t type;
union {
- __u32 fd;
+ struct {
+ __u64 data_ptr;
+ __u32 size;
+ } network;
__u32 index;
};
};
diff --git a/tests/cancel_inference_test.cpp b/tests/cancel_inference_test.cpp
index 846a29f..7f3fe74 100644
--- a/tests/cancel_inference_test.cpp
+++ b/tests/cancel_inference_test.cpp
@@ -40,9 +40,7 @@ int64_t defaultTimeout = 60000000000;
void testCancelInference(const Device &device) {
try {
- auto networkBuffer = std::make_shared<Buffer>(device, sizeof(networkModelData));
- std::memcpy(networkBuffer->data(), networkModelData, sizeof(networkModelData));
- auto network = std::make_shared<Network>(device, networkBuffer);
+ auto network = std::make_shared<Network>(device, networkModelData, sizeof(networkModelData));
std::vector<std::shared_ptr<Buffer>> inputBuffers;
std::vector<std::shared_ptr<Buffer>> outputBuffers;
@@ -79,9 +77,7 @@ void testCancelInference(const Device &device) {
void testRejectInference(const Device &device) {
try {
- auto networkBuffer = std::make_shared<Buffer>(device, sizeof(networkModelData));
- std::memcpy(networkBuffer->data(), networkModelData, sizeof(networkModelData));
- auto network = std::make_shared<Network>(device, networkBuffer);
+ auto network = std::make_shared<Network>(device, networkModelData, sizeof(networkModelData));
std::vector<std::shared_ptr<Buffer>> inputBuffers;
std::vector<std::shared_ptr<Buffer>> outputBuffers;
diff --git a/tests/run_inference_test.cpp b/tests/run_inference_test.cpp
index 6b17ac2..512a2a0 100644
--- a/tests/run_inference_test.cpp
+++ b/tests/run_inference_test.cpp
@@ -111,10 +111,7 @@ void testNetworkInfoNotExistentIndex(const Device &device) {
void testNetworkInfoBuffer(const Device &device) {
try {
- std::shared_ptr<Buffer> buffer = std::make_shared<Buffer>(device, sizeof(networkModelData));
- std::memcpy(buffer->data(), networkModelData, sizeof(networkModelData));
- Network network(device, buffer);
-
+ Network network(device, networkModelData, sizeof(networkModelData));
TEST_ASSERT(network.getIfmDims().size() == 1);
TEST_ASSERT(network.getOfmDims().size() == 1);
} catch (std::exception &e) { throw TestFailureException("NetworkInfo buffer test: ", e.what()); }
@@ -122,11 +119,8 @@ void testNetworkInfoBuffer(const Device &device) {
void testNetworkInfoUnparsableBuffer(const Device &device) {
try {
- auto buffer = std::make_shared<Buffer>(device, sizeof(networkModelData) / 4);
- std::memcpy(buffer->data(), networkModelData + sizeof(networkModelData) / 4, sizeof(networkModelData) / 4);
-
try {
- Network network(device, buffer);
+ Network network(device, networkModelData + sizeof(networkModelData) / 4, sizeof(networkModelData) / 4);
FAIL();
} catch (Exception) {
// good, it should have thrown!
@@ -148,11 +142,41 @@ void testNetworkInvalidType(const Device &device) {
} catch (std::exception &e) { throw TestFailureException("NetworkCreate invalid type test: ", e.what()); }
}
+void testNetworkInvalidDataPtr(const Device &device) {
+ const std::string expected_error =
+ std::string("IOCTL cmd=") + std::to_string(ETHOSU_IOCTL_NETWORK_CREATE) + " failed: " + std::strerror(EINVAL);
+ struct ethosu_uapi_network_create net_req = {};
+ net_req.type = ETHOSU_UAPI_NETWORK_USER_BUFFER;
+ net_req.network.data_ptr = 0U;
+ net_req.network.size = 128U;
+ try {
+ int r = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, &net_req);
+ FAIL();
+ } catch (Exception &e) {
+ // The call is expected to throw
+ TEST_ASSERT(expected_error.compare(e.what()) == 0);
+ } catch (std::exception &e) { throw TestFailureException("NetworkCreate invalid data ptr: ", e.what()); }
+}
+
+void testNetworkInvalidDataSize(const Device &device) {
+ const std::string expected_error =
+ std::string("IOCTL cmd=") + std::to_string(ETHOSU_IOCTL_NETWORK_CREATE) + " failed: " + std::strerror(EINVAL);
+ struct ethosu_uapi_network_create net_req = {};
+ net_req.type = ETHOSU_UAPI_NETWORK_USER_BUFFER;
+ net_req.network.data_ptr = reinterpret_cast<uintptr_t>(networkModelData);
+ net_req.network.size = 0U;
+ try {
+ int r = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, &net_req);
+ FAIL();
+ } catch (Exception &e) {
+ // The call is expected to throw
+ TEST_ASSERT(expected_error.compare(e.what()) == 0);
+ } catch (std::exception &e) { throw TestFailureException("NetworkCreate invalid data size: ", e.what()); }
+}
+
void testRunInferenceBuffer(const Device &device) {
try {
- auto networkBuffer = std::make_shared<Buffer>(device, sizeof(networkModelData));
- std::memcpy(networkBuffer->data(), networkModelData, sizeof(networkModelData));
- auto network = std::make_shared<Network>(device, networkBuffer);
+ auto network = std::make_shared<Network>(device, networkModelData, sizeof(networkModelData));
std::vector<std::shared_ptr<Buffer>> inputBuffers;
std::vector<std::shared_ptr<Buffer>> outputBuffers;
@@ -197,6 +221,8 @@ int main() {
testCapabilties(device);
testBufferSeek(device);
testNetworkInvalidType(device);
+ testNetworkInvalidDataPtr(device);
+ testNetworkInvalidDataSize(device);
testNetworkInfoNotExistentIndex(device);
testNetworkInfoBuffer(device);
testNetworkInfoUnparsableBuffer(device);
diff --git a/utils/inference_runner/inference_runner.cpp b/utils/inference_runner/inference_runner.cpp
index c7a18b0..721cd57 100644
--- a/utils/inference_runner/inference_runner.cpp
+++ b/utils/inference_runner/inference_runner.cpp
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <string>
#include <unistd.h>
+#include <utility>
using namespace std;
using namespace EthosU;
@@ -56,7 +57,7 @@ void rangeCheck(const int i, const int argc, const string arg) {
}
}
-shared_ptr<Buffer> allocAndFill(Device &device, const string filename) {
+pair<unique_ptr<unsigned char[]>, size_t> getNetworkData(const string filename) {
ifstream stream(filename, ios::binary);
if (!stream.is_open()) {
cerr << "Error: Failed to open '" << filename << "'" << endl;
@@ -67,10 +68,10 @@ shared_ptr<Buffer> allocAndFill(Device &device, const string filename) {
size_t size = stream.tellg();
stream.seekg(0, ios_base::beg);
- shared_ptr<Buffer> buffer = make_shared<Buffer>(device, size);
- stream.read(buffer->data(), size);
+ unique_ptr<unsigned char[]> data = std::make_unique<unsigned char[]>(size);
+ stream.read(reinterpret_cast<char *>(data.get()), size);
- return buffer;
+ return make_pair(std::move(data), size);
}
shared_ptr<Inference> createInference(Device &device,
@@ -234,8 +235,8 @@ int main(int argc, char *argv[]) {
shared_ptr<Network> network;
if (networkIndex < 0) {
- shared_ptr<Buffer> networkBuffer = allocAndFill(device, networkArg);
- network = make_shared<Network>(device, networkBuffer);
+ auto networkData = getNetworkData(networkArg);
+ network = make_shared<Network>(device, networkData.first.get(), networkData.second);
} else {
network = make_shared<Network>(device, networkIndex);
}