Publishing R3

This commit is contained in:
openvino-pushbot 2018-10-16 13:45:03 +03:00
parent c37d4661a2
commit 866530fb04
6788 changed files with 1431632 additions and 2 deletions

39
.coveragerc Normal file
View File

@ -0,0 +1,39 @@
# .coveragerc to control coverage.py
[run]
branch = True
source =
mo/
mo.py
omit =
# omit anything in a .local directory anywhere
*/.local/*
# omit everything in /usr
/usr/*
# omit tests
*/test_*.py
# init scripts
*/__init__.py
[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover
# Don't complain about missing debug-only code:
def __repr__
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
# Don't complain if non-runnable code isn't run:
if 0:
if __name__ == .__main__.:
ignore_errors = True
[html]
directory = htmlcov

21
.editorconfig Normal file
View File

@ -0,0 +1,21 @@
root = true
[*]
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
# 4 space indentation
#[*.py]
#indent_style = space
#indent_size = 4
#[{CMakeLists.txt,*.cmake}]
#indent_style = space
#indent_size = 4
#[*.{c,cpp,h,hpp}]
#indent_style = space
#indent_size = 4

65
.gitattributes vendored Normal file
View File

@ -0,0 +1,65 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
*.py text eol=lf
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

343
.gitignore vendored Normal file
View File

@ -0,0 +1,343 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Xx]64/
[Xx]86/
[Bb]uild/
bld/
[Bb]in/
[Oo]bj/
# PY.TEST
*.pyc
tests/integration/report.html
tests/integration/report.xml
tests/integration/assets/
tests/integration/__pycache__/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Un-comment the next line if you do not want to checkin
# your web deploy settings because they may include unencrypted
# passwords
#*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Microsoft Azure ApplicationInsights config file
ApplicationInsights.config
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Target VS files:
vsx64
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# LightSwitch generated files
GeneratedArtifacts/
ModelManifest.xml
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/
*.filters
/External
/Output
/InferenceEngineMain/models
/Test
/HTTPClient/*.a
/InferenceEngineMain/newModels
.DS_Store
# For IDEA
.idea/
VS/
Xcode/
temp/
report/
.kdev4/
*.kdev4
*.kate-swp
/lin-build
/win-build
/CMakeFiles
*.stamp
*.depend
*.vcxproj
*.sln
/CMakeCache.txt
.vimprj/
build_IA32/
doc/
.dir-locals.el
GTAGS
GPATH
GRTAGS
GSYMS
compile_commands.json
service/dot-net-service/Output
**/sublime_build
/.project
.vscode/
/vsx32
/service/dot-net-service/.klocwork/DotNetService
cmake-build-*/
/lin64
.gdb_history
.local_vimrc
.ycm_extra_conf.py
tags
# from Model Optimizer repo
.idea
.project
.cproject
.pydevproject
.settings
/bin/
/gen/
__pycache__
*.swp
/config.xml
# Python-specific
.env3
*.pyc
# Tests-specific
.coverage
htmlcov
pylint_report.txt
pylint_report_comments.txt
# Documentation-generated
docs/build
docs/source/_static
docs/source/_templates
docs/source/generated/
# Artifacts
/*.bin
/*.xml
/*.json
/*.so
/*.txt
/*.mapping
/*.dat
/*.svg

68
.pylintdict Normal file
View File

@ -0,0 +1,68 @@
attrs
arg
args
bfs
bool
caffe
caffemodel
ceil
chw
cli
cls
co-location
concat
config
const
conv
dfs
dict
dsu
eltwise
enum
env
eq
fallback
fc
fcn
fw
hardcoded
http
https
hwc
indices
inplace
inv
io
len
lrn
mul
n-ary
networkx
ndarray
nx
np
numpy
org
oi
params
pb
pbs
priorbox
priorboxes
proto
protobuf
protobufs
prototxt
regex
reorgyolo
regionyolo
replacers
resnet
rcnn
split
splitv
ssd
usr
undead
xml
www

410
.pylintrc Normal file
View File

@ -0,0 +1,410 @@
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
init-hook='sys.path.append(os.path.abspath(os.path.curdir))'
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=proto, tests, docs, automation
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=.env3/*, python3.5, .*_test.py
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Use multiple processes to speed up Pylint.
# jobs=4
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=
# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
# be used to obtain the result of joining multiple strings with the addition
# operator. Joining a lot of strings can lead to a maximum recursion error in
# Pylint and this flag can prevent that. It has one side effect, the resulting
# AST will be different than the one from reality. This option is deprecated
# and it will be removed in Pylint 2.0.
optimize-ast=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=locally-disabled,too-few-public-methods,no-self-use,too-many-ancestors,
missing-docstring,old-style-class,consider-iterating-dictionary,consider-using-enumerate,
superfluous-parens,no-else-return,duplicate-code,wrong-import-order,
too-many-locals,logging-not-lazy,unnecessary-lambda,super-on-old-class,ungrouped-imports,too-many-format-args,
protected-access,too-many-statements,too-many-branches,too-many-return-statements,too-many-public-methods,
super-init-not-called,singleton-comparison,pointless-string-statement,broad-except, invalid-name
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". This option is deprecated
# and it will be removed in Pylint 2.0.
files-output=no
# Tells whether to display a full report or only the messages
reports=yes
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=8
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=120
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator
# Maximum number of lines in a module
max-module-lines=1000
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
[SPELLING]
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=en_US
# List of comma separated words that should not be checked.
spelling-ignore-words=TF, MO, IR, IE
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=.pylintdict
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,future.builtins
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=flask_sqlalchemy,app.extensions.flask_sqlalchemy
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=fget,query,begin,add,merge,delete,commit,rollback
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[BASIC]
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_,log,api,a,c,d,e,ei,f,hp,id,l,l2,ml,mn,n,N,op,p,pb,pb,ph,q,rt,s,s1,s2,si,u,v,wp,x,y
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct argument names
argument-rgx=([a-z_][a-z0-9_]{2,40}$)|(fileName)|(pl)|(t)
# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,40}$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,40}$
# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,40}$
# Regular expression matching correct function names
function-rgx=([a-z_][a-z0-9_]{2,40}$)
# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,40}$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,40}|(__.*__))$
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,40}|(__.*__))$
# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,40}$
# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,40}$
# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,40}$
# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,40}$
# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=5
[ELIF]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=10
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of boolean expressions in a if statement
max-bool-expr=5
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=optparse
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=flask_restplus_patched
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception

201
LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,7 +1,37 @@
# [OpenVINO™ Toolkit](https://01.org/openvinotoolkit) - Deep Learning Deployment Toolkit repository # [OpenVINO™ Toolkit](https://01.org/openvinotoolkit) - Deep Learning Deployment Toolkit repository
[![Stable release](https://img.shields.io/badge/version-2018.R3-green.svg)](https://github.com/opencv/dldt/releases/tag/2018_R3)
[![Apache License Version 2.0](https://img.shields.io/badge/license-Apache_2.0-green.svg)](LICENSE) [![Apache License Version 2.0](https://img.shields.io/badge/license-Apache_2.0-green.svg)](LICENSE)
The master branch will be available as soon as the Continuous Integration system is configured. This toolkit allows developers to deploy pre-trained deep learning models through a high-level C++ Inference Engine API integrated with application logic.
This open source version includes two components, namely Model Optimizer and Inference Engine, as well as CPU, GPU and heterogeneous plugins to accelerate deep learning inferencing on Intel(R) CPUs and Intel(R) Processor Graphics. It supports pre-trained models from the [Open Model Zoo](https://github.com/opencv/open_model_zoo/) along with 100+ open source and public models in popular formats such as Caffe*, Tensorflow*, MXNet* and ONNX*.
## Repository components:
* [Inference Engine](https://software.intel.com/en-us/articles/OpenVINO-InferEngine)
* [Model Optimizer](https://software.intel.com/en-us/articles/OpenVINO-ModelOptimizer)
## License
Deep Learning Deployment Toolkit is licensed under [Apache License Version 2.0](LICENSE).
## Documentation
* [OpenVINO™ Release Notes](https://software.intel.com/en-us/articles/OpenVINO-RelNotes)
* Inference Engine [build instructions](inference-engine/README.md)
## How to Contribute
We welcome community contributions to the Deep Learning Deployment Toolkit repository. If you have an idea how to improve the product, please share it with us doing the following steps:
* Make sure you can build the product and run all tests and samples with your patch
* In case of a larger feature, provide a relevant unit tests and sample
* Submit a pull request at https://github.com/opencv/dldt/pulls
We will review your contribution and, if any additional fixes or modifications are necessary, may give some feedback to guide you. When accepted, your pull request will be merged into GitHub* repositories.
Deep Learning Deployment Toolkit is licensed under Apache License, Version 2.0. By contributing to the project, you agree to the license and copyright terms therein and release your contribution under these terms.
## Support
Please report questions, issues and suggestions using:
* [\#dldt](https://stackoverflow.com/search?q=%23dldt) tag on StackOverflow*
* [GitHub* Issues](https://github.com/opencv/dldt/issues)
* [Forum](https://software.intel.com/en-us/forums/computer-vision)
--- ---
\* Other names and brands may be claimed as the property of others. \* Other names and brands may be claimed as the property of others.

View File

@ -0,0 +1,136 @@
# Copyright (C) 2018 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 3.3)
project(InferenceEngine)
set(DEV_BUILD TRUE)
## WA for problem with gtest submodule. It cannot detect uint32 type.
## remove Gtest submodule and this two lines together
include (CheckTypeSize)
check_type_size (uint32_t uint32_t LANGUAGE CXX)
if (UNIX AND NOT APPLE)
set(LINUX TRUE)
endif()
option (OS_FOLDER "create OS dedicated folder in output" OFF)
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set (ARCH_FOLDER intel64)
else()
set (ARCH_FOLDER ia32)
endif()
if (OS_FOLDER)
message ("**** OS FOLDER IS: [${OS_FOLDER}]")
if ("${OS_FOLDER}" STREQUAL "ON")
message ("**** USING OS FOLDER: [${CMAKE_SYSTEM_NAME}]")
set (BIN_FOLDER bin/${CMAKE_SYSTEM_NAME}/${ARCH_FOLDER})
else()
set (BIN_FOLDER bin/${OS_FOLDER}/${ARCH_FOLDER})
endif()
else()
set (BIN_FOLDER bin/${ARCH_FOLDER})
endif()
set (IE_MAIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set (CMAKE_MODULE_PATH "${IE_MAIN_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
#printing debug messages
include (debug)
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
debug_message(STATUS "CMAKE_BUILD_TYPE not defined, 'Release' will be used")
set(CMAKE_BUILD_TYPE "Release")
endif()
message(STATUS "BUILD_CONFIGURATION: ${CMAKE_BUILD_TYPE}")
if(COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -O0")
endif()
if (UNIX)
SET(LIB_DL ${CMAKE_DL_LIBS})
else()
endif()
set (OUTPUT_ROOT ${IE_MAIN_SOURCE_DIR})
if(NOT(UNIX))
if (WIN32)
#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif()
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER})
set (CMAKE_LIBRARY_PATH ${OUTPUT_ROOT}/${BIN_FOLDER})
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER})
set (CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER})
set (CMAKE_PDB_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER})
set (LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER})
set (LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_DIRECTORY}) # compatibility issue: linux uses LIBRARY_OUTPUT_PATH, windows uses LIBRARY_OUTPUT_DIRECTORY
else ()
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE}/lib)
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE}/lib)
set (CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE})
set (CMAKE_PDB_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE})
set (LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE}/lib)
set (LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_DIRECTORY}/lib)
endif()
include(os_flags)
#resolving rependencies for the project
include (dependencies)
if (APPLE)
set(CMAKE_MACOSX_RPATH 1)
endif(APPLE)
#rpath fully disabled
if (NOT ENABLE_PLUGIN_RPATH)
SET (CMAKE_SKIP_RPATH TRUE)
endif()
#Use solution folders.
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#message("=====================> ${CMAKE_BUILD_TYPE} <=====================")
message (STATUS "PROJECT ............................... " ${PROJECT_NAME})
message (STATUS "CMAKE_BINARY_DIR ...................... " ${CMAKE_BINARY_DIR})
message (STATUS "IE_MAIN_SOURCE_DIR .................... " ${IE_MAIN_SOURCE_DIR})
message (STATUS "CMAKE_GENERATOR ....................... " ${CMAKE_GENERATOR})
message (STATUS "CMAKE_C_COMPILER_ID ................... " ${CMAKE_C_COMPILER_ID})
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
include(sdl)
endif()
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
include (sanitizer)
include(CheckCXXCompilerFlag)
if(UNIX)
CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" COMPILER_SUPPORTS_VISIBILITY)
if (COMPILER_SUPPORTS_VISIBILITY)
#add_definitions(-fvisibility=hidden) todo: should be hidden? if so define default visibiliti explicite for each funtion
add_definitions(-fvisibility=default)
endif(COMPILER_SUPPORTS_VISIBILITY)
endif(UNIX)
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(thirdparty)
if (ENABLE_SAMPLES_CORE)
set(InferenceEngine_DIR "${CMAKE_BINARY_DIR}")
#to be able to link
set (LIB_FOLDER ${IE_MAIN_SOURCE_DIR}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE}/lib)
add_subdirectory(samples)
endif()

View File

@ -0,0 +1,63 @@
## Build on Linux\* Systems
The software was validated on:
- Ubuntu\* 16.04 with default GCC\* 5.4.0
- CentOS\* 7.4 with default GCC\* 4.8.5 (using clDNN library built separately with GCC\* 5.2)
- [Intel® Graphics Compute Runtime for OpenCL™ Driver package 18.28.11080](https://github.com/intel/compute-runtime/releases/tag/18.28.11080).
### Software Requirements
- [CMake\*](https://cmake.org/download/) 3.9 or higher
- GCC\* 4.8 or higher to build the Inference Engine
- GCC\* 5.2 or higher to build the Compute Library for Deep Neural Networks (clDNN library)
- OpenBLAS\*
### Build Steps
1. Install OpenBLAS and other dependencies using the `install_dependencies.sh` script in the project root folder.
2. Create a build folder:
```sh
mkdir build
```
3. Inference Engine uses a CMake-based build system. In the created `build` directory, run `cmake` to fetch project dependencies and create Unix makefiles, then run `make` to build the project:
```sh
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j16
```
You can use the following additional build options:
- Use `BLAS_INCLUDE_DIRS` and `BLAS_LIBRARIES` cmake options to specify path to OpenBLAS headers and library, for example use the following options on CentOS\*: `-DBLAS_INCLUDE_DIRS=/usr/include/openblas -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so.0`
- To build clDNN from sources, please specify the `-DENABLE_CLDNN_BUILD=ON` option for `cmake`. By default pre-built version of the clDNN library is used.
- To switch on/off the CPU and GPU plugins, use `cmake` options `-DENABLE_MKL_DNN=ON/OFF` and `-DENABLE_CLDNN=ON/OFF`.
## Build on Windows\* Systems:
The software was validated on:
- Microsoft\* Windows\* 10 with Visual Studio 2017 and Intel® C++ Compiler 2018 Update 3
- [Intel® Graphics Driver for Windows* [24.20] driver package](https://downloadcenter.intel.com/download/27803/Graphics-Intel-Graphics-Driver-for-Windows-10?v=t).
### Software Requirements
- [CMake\*](https://cmake.org/download/) 3.9 or higher
- [OpenBLAS\*](https://sourceforge.net/projects/openblas/files/v0.2.14/OpenBLAS-v0.2.14-Win64-int64.zip/download) or
- [Intel® C++ Compiler](https://software.intel.com/en-us/intel-parallel-studio-xe) 18.0 to build the Inference Engine on Windows.
### Build Steps
1. Download and install [Intel® C++ Compiler](https://software.intel.com/en-us/intel-parallel-studio-xe) 18.0
2. Install OpenBLAS:
1. Download [OpenBLAS\*](https://sourceforge.net/projects/openblas/files/v0.2.14/OpenBLAS-v0.2.14-Win64-int64.zip/download)
2. Unzip the downloaded package to a directory on your machine. In this document, this directory is referred to as `<OPENBLAS_DIR>`.
3. Create build directory:
```sh
mkdir build
```
4. In the `build` directory, run `cmake` to fetch project dependencies and generate a Visual Studio solution:
```sh
cd build
cmake -G "Visual Studio 15 2017 Win64" -T "Intel C++ Compiler 18.0" -DOS_FOLDER=ON ^
-DBLAS_INCLUDE_DIRS=<OPENBLAS_DIR>\include ^
-DBLAS_LIBRARIES=<OPENBLAS_DIR>\lib\libopenblas.dll.a ^
-DCMAKE_BUILD_TYPE=Release ^
-DICCLIB="C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018\windows\compiler\lib" ..
```
5. Build generated solution in Visual Studio 2017 or run `cmake --build .` to build from the command line.
---
\* Other names and brands may be claimed as the property of others.

View File

@ -0,0 +1,134 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
include ("features")
include("mode")
include("omp")
include("itt")
#64 bits platform
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
message(STATUS "Detected 64 bit architecture")
SET(ARCH_64 ON)
SET(ARCH_32 OFF)
else()
message(STATUS "Detected 32 bit architecture")
SET(ARCH_64 OFF)
SET(ARCH_32 ON)
endif()
if (ARCH_64)
else()
if (UNIX OR APPLE)
SET(ENABLE_CLDNN OFF)
endif()
SET(ENABLE_MKL_DNN OFF)
endif()
#apple specific
if (APPLE)
set(ENABLE_CLDNN OFF)
endif()
#minGW specific - under wine no support for downloading file and applying them using git
if (WIN32)
enable_omp()
if (MINGW)
SET(ENABLE_CLDNN OFF) # dont have mingw dll for linking
set(ENABLE_SAMPLES_CORE OFF)
endif()
endif()
# Linux specific - not all OS'es are supported
if (LINUX)
include("linux_name")
get_linux_name(LINUX_OS_NAME)
if (LINUX_OS_NAME)
if (NOT(
${LINUX_OS_NAME} STREQUAL "Ubuntu 14.04" OR
${LINUX_OS_NAME} STREQUAL "Ubuntu 16.04" OR
${LINUX_OS_NAME} STREQUAL "CentOS 7"))
endif()
else ()
message(WARNING "Cannot detect Linux OS via reading /etc/*-release:\n ${release_data}")
endif ()
endif ()
if (NOT ENABLE_MKL_DNN)
set(GEMM OPENBLAS)
endif()
if (NOT ENABLE_VPU)
set(ENABLE_MYRIAD OFF)
endif()
if (NOT ENABLE_MYRIAD)
set(ENABLE_VPU OFF)
endif()
#next section set defines to be accesible in c++/c code for certain feature
if (ENABLE_PROFILING_RAW)
add_definitions(-DENABLE_PROFILING_RAW=1)
endif()
if (ENABLE_GTEST_PATCHES)
add_definitions(-DENABLE_GTEST_PATCHES=1)
endif()
if (ENABLE_CLDNN)
add_definitions(-DENABLE_CLDNN=1)
endif()
if (ENABLE_MKL_DNN)
add_definitions(-DENABLE_MKL_DNN=1)
endif()
if (ENABLE_STRESS_UNIT_TESTS)
add_definitions(-DENABLE_STRESS_UNIT_TESTS=1)
endif()
if (ENABLE_SEGMENTATION_TESTS)
add_definitions(-DENABLE_SEGMENTATION_TESTS=1)
endif()
if (ENABLE_OBJECT_DETECTION_TESTS)
add_definitions(-DENABLE_OBJECT_DETECTION_TESTS=1)
endif()
#models dependend tests
if (DEVELOPMENT_PLUGIN_MODE)
message (STATUS "Enabled development plugin mode")
set (ENABLE_MKL_DNN OFF)
set (ENABLE_TESTS OFF)
message (STATUS "Initialising submodules")
execute_process (COMMAND git submodule update --init ${IE_MAIN_SOURCE_DIR}/thirdparty/pugixml
RESULT_VARIABLE git_res)
if (NOT ${git_res})
message (STATUS "Initialising submodules - done")
endif()
endif()
if (VERBOSE_BUILD)
set(CMAKE_VERBOSE_MAKEFILE ON)
endif()
if (NOT ENABLE_OMP)
set(ENABLE_INTEL_OMP OFF)
endif()
if (NOT GEMM STREQUAL "MKL" AND NOT GEMM STREQUAL "OPENBLAS")
message("FATAL_ERROR" "GEMM should be set to MKL|OPENBLAS")
endif()
print_enabled_features()
message(STATUS "GEMM = ${GEMM}")

View File

@ -0,0 +1,11 @@
# Copyright (C) 2018 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
if(DEFINED IE_MAIN_SOURCE_DIR AND TARGET inference_engine)
set(InferenceEngine_INCLUDE_DIRS ${IE_MAIN_SOURCE_DIR}/include)
set(InferenceEngine_LIBRARIES inference_engine)
else()
include("${CMAKE_CURRENT_LIST_DIR}/targets.cmake")
get_target_property(InferenceEngine_INCLUDE_DIRS IE::inference_engine INTERFACE_INCLUDE_DIRECTORIES)
set(InferenceEngine_LIBRARIES IE::inference_engine)
endif()

View File

@ -0,0 +1,69 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 2.8)
function (debug_message)
if (VERBOSE_BUILD)
message(${ARGV})
endif()
endfunction()
function(clean_message type)
string (REPLACE ";" "" output_string "${ARGN}")
execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${output_string}")
if(${ARGV0} STREQUAL "FATAL_ERROR")
message (FATAL_ERROR)
endif()
endfunction()
file(REMOVE ${CMAKE_BINARY_DIR}/ld_library_rpath_64.txt)
# log relative path to shared library that has to be used in LD_LIBRARY_PATH
function (log_rpath_remove_top component component_remove_top lib lib_remove_top)
set(top_lib_dir ${${component}})
set(lib_dir ${lib})
# debug_message(STATUS "LIB-IN=${lib} ")
# debug_message(STATUS "TOPLIB-IN=${top_lib_dir} ")
get_filename_component(top_lib_dir ${${component}} DIRECTORY)
if (${component_remove_top} AND ${component})
else()
get_filename_component(add_name ${${component}} NAME)
set(top_lib_dir "${top_lib_dir}/${add_name}")
endif()
if (${lib_remove_top} AND lib)
get_filename_component(lib_dir ${lib} DIRECTORY)
endif()
string (REPLACE "//" "/" top_lib_dir "${top_lib_dir}")
string (REPLACE "//" "/" lib_dir "${lib_dir}")
string (REPLACE "\\\\" "/" top_lib_dir "${top_lib_dir}")
string (REPLACE "\\\\" "/" lib_dir "${lib_dir}")
# debug_message(STATUS "LIB-OUT=${lib_dir}")
# debug_message(STATUS "TOPLIB-OUT=${top_lib_dir}")
string (REPLACE "${top_lib_dir}" "" component_dir "${lib_dir}")
set(RPATH_INFO "${component}=${component_dir}")
debug_message(STATUS "LD_LIBRARY_RPATH: ${RPATH_INFO}")
file(APPEND ${CMAKE_BINARY_DIR}/ld_library_rpath_64.txt "${RPATH_INFO}\n")
endfunction()
function (log_rpath_from_dir component lib_dir)
if(NOT APPLE)
log_rpath_remove_top("${component}" TRUE "${lib_dir}" FALSE)
endif()
endfunction()
function (log_rpath component lib_path)
log_rpath_remove_top(${component} TRUE ${lib_path} TRUE)
endfunction()

View File

@ -0,0 +1,117 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required(VERSION 2.8)
#features trigger supported by build system
include(check_features)
include(debug)
#we have number of dependencies stored on ftp
include(dependency_solver)
#prepare temporary folder
if (DEFINED ENV{${DL_SDK_TEMP}})
if (WIN32)
string(REPLACE "\\" "\\\\" TEMP $ENV{${DL_SDK_TEMP}})
else(WIN32)
set(TEMP $ENV{${DL_SDK_TEMP}})
endif(WIN32)
if (ENABLE_ALTERNATIVE_TEMP)
set(ALTERNATIVE_PATH ${IE_MAIN_SOURCE_DIR}/temp)
endif()
else ()
message(STATUS "DL_SDK_TEMP envionment not set")
set(TEMP ${IE_MAIN_SOURCE_DIR}/temp)
endif ()
include(ExternalProject)
if (ENABLE_SAME_BRANCH_FOR_MODELS)
branchName(MODELS_BRANCH)
else()
set(MODELS_BRANCH "master")
endif()
set(MODELS_PATH "${TEMP}/models")
debug_message(STATUS "MODELS_PATH=" ${MODELS_PATH})
#clDNN
if (ENABLE_CLDNN AND NOT ENABLE_CLDNN_BUILD)
if(NOT IE_SUBMODULE_IN_CLDNN)
RESOLVE_DEPENDENCY(CLDNN
ARCHIVE_UNIFIED "cldnn-main-03988.zip"
TARGET_PATH "${TEMP}/clDNN"
ENVIRONMENT "CLDNN"
VERSION_REGEX ".*_(([a-z]+-)?[a-z]+-[0-9]+)---.*"
FOLDER) #new cldnn package dont have toplevel cldnn folder
debug_message(STATUS "clDNN=" ${CLDNN})
endif ()
endif ()
## enable cblas_gemm from OpenBLAS package
if (GEMM STREQUAL "OPENBLAS")
if(NOT BLAS_LIBRARIES OR NOT BLAS_INCLUDE_DIRS)
find_package(BLAS REQUIRED)
if(BLAS_FOUND)
find_path(BLAS_INCLUDE_DIRS cblas.h)
else()
message(ERROR "OpenBLAS not found: install OpenBLAS or set -DBLAS_INCLUDE_DIRS=<path to dir with cblas.h> and -DBLAS_LIBRARIES=<path to libopenblas.so or openblas.lib>")
endif()
endif()
debug_message(STATUS "openblas=" ${BLAS_LIBRARIES})
endif ()
#MKL-ml package
if (GEMM STREQUAL "MKL" OR ENABLE_INTEL_OMP)
if (WIN32)
RESOLVE_DEPENDENCY(MKL
ARCHIVE_WIN "mkltiny_win_20180512.zip"
TARGET_PATH "${TEMP}/mkltiny_win_20180512"
ENVIRONMENT "MKLROOT"
VERSION_REGEX ".*_([a-z]*_([a-z0-9]+\\.)*[0-9]+).*")
elseif(LINUX)
RESOLVE_DEPENDENCY(MKL
ARCHIVE_LIN "mkltiny_lnx_20180511.tgz"
TARGET_PATH "${TEMP}/mkltiny_lnx_20180511"
ENVIRONMENT "MKLROOT"
VERSION_REGEX ".*_([a-z]*_([a-z0-9]+\\.)*[0-9]+).*")
endif()
debug_message(STATUS "mkl_ml=" ${MKL})
endif ()
if (ENABLE_OPENCV)
if (WIN32)
RESOLVE_DEPENDENCY(OPENCV
ARCHIVE_WIN "opencv_3.4.3.zip"
TARGET_PATH "${TEMP}/opencv"
ENVIRONMENT "OpenCV_DIR"
VERSION_REGEX ".*_([0-9]+.[0-9]+.[0-9]+).*")
log_rpath_from_dir(OPENCV "\\opencv\\x64\\vc14\\bin")
set( ENV{OpenCV_DIR} ${OPENCV} )
elseif(LINUX)
if (${LINUX_OS_NAME} STREQUAL "Ubuntu 16.04")
RESOLVE_DEPENDENCY(OPENCV
ARCHIVE_LIN "opencv_3.4.3_ubuntu16.tar.bz2"
TARGET_PATH "${TEMP}/opencv_ubuntu16"
ENVIRONMENT "OpenCV_DIR"
VERSION_REGEX ".*_([0-9]+.[0-9]+.[0-9]+).*")
log_rpath_from_dir(OPENCV "opencv_ubuntu16/lib")
elseif (${LINUX_OS_NAME} STREQUAL "CentOS 7")
RESOLVE_DEPENDENCY(OPENCV
ARCHIVE_LIN "opencv_3.4.3_centos7.tar.bz2"
TARGET_PATH "${TEMP}/opencv_centos7"
ENVIRONMENT "OpenCV_DIR"
VERSION_REGEX ".*_([0-9]+.[0-9]+.[0-9]+).*")
log_rpath_from_dir(OPENCV "opencv_centos7/lib")
endif()
set( ENV{OpenCV_DIR} ${OPENCV}/share )
endif()
debug_message(STATUS "opencv=" ${OPENCV})
endif()
include(omp)

View File

@ -0,0 +1,140 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 2.8)
include ("download")
function (resolve_archive_dependency VAR COMPONENT ARCHIVE ARCHIVE_UNIFIED ARCHIVE_WIN ARCHIVE_LIN ARCHIVE_MAC TARGET_PATH FOLDER ENVIRONMENT)
if (ENVIRONMENT AND (DEFINED ENV{${ENVIRONMENT}}))
set(HAS_ENV "TRUE")
endif()
if (NOT DEFINED HAS_ENV)
if (ARCHIVE)
#TODO: check wether this is platform specific binary with same name per or it is in common folder
DownloadAndExtract(${COMPONENT} ${ARCHIVE} ${TARGET_PATH} result_path ${FOLDER})
else()
DownloadAndExtractPlatformSpecific(${COMPONENT} ${ARCHIVE_UNIFIED} ${ARCHIVE_WIN} ${ARCHIVE_LIN} ${ARCHIVE_MAC} ${TARGET_PATH} result_path ${FOLDER})
endif()
set (${VAR} ${result_path} PARENT_SCOPE)
else()
set (${VAR} $ENV{${ENVIRONMENT}} PARENT_SCOPE)
endif()
endfunction(resolve_archive_dependency)
function(resolve_pull_request GITHUB_PULL_REQUEST TARGET_PATH)
get_filename_component(FILE_NAME ${GITHUB_PULL_REQUEST} NAME)
set (PATCH_URL "")
DownloadAndApply("${PATCH_URL}/${GITHUB_PULL_REQUEST}" "${IE_MAIN_SOURCE_DIR}/${TARGET_PATH}/${FILE_NAME}")
endfunction(resolve_pull_request)
function(extract_version_from_filename filename regex version)
string(REGEX MATCH ${regex} match ${filename})
if (CMAKE_MATCH_1)
set(${version} ${CMAKE_MATCH_1} PARENT_SCOPE)
else()
set(${version} ${filename} PARENT_SCOPE)
endif()
endfunction(extract_version_from_filename)
function(read_version archive regex version_var)
extract_version_from_filename(${archive} ${regex} version)
set(${version_var} "${version}" CACHE INTERNAL "" FORCE)
debug_message(STATUS "${version_var} = " ${version})
endfunction(read_version)
function (RESOLVE_DEPENDENCY NAME_OF_CMAKE_VAR)
list(REMOVE_AT ARGV 0)
set(SUPPORTED_ARGS FOLDER ARCHIVE ARCHIVE_UNIFIED ARCHIVE_WIN ARCHIVE_LIN ARCHIVE_MAC TARGET_PATH ENVIRONMENT GITHUB_PULL_REQUEST VERSION_REGEX)
#unnecessary vars
foreach(arg ${ARGV})
#message("one_arg=" ${one_arg})
#message("arg=" ${arg})
#parse no arg vars
if (";${SUPPORTED_ARGS};" MATCHES ";${arg};")
if(DEFINED one_arg)
set(${one_arg} TRUE)
endif()
set (one_arg ${arg})
elseif(DEFINED one_arg)
set(${one_arg} ${arg})
unset(one_arg)
else()
message(FATAL_ERROR "invalid argument passed to resolve dependency: " ${arg})
endif()
endforeach(arg)
#if last token was bool
if(DEFINED one_arg)
set(${one_arg} TRUE)
endif()
if (NOT DEFINED ARCHIVE)
SET(ARCHIVE "OFF")
endif()
if (NOT DEFINED ARCHIVE_UNIFIED)
SET(ARCHIVE_UNIFIED "OFF")
endif()
if (NOT DEFINED ARCHIVE_WIN)
SET(ARCHIVE_WIN "OFF")
endif()
if (NOT DEFINED ARCHIVE_LIN)
SET(ARCHIVE_LIN "OFF")
endif()
if (NOT DEFINED ARCHIVE_MAC)
SET(ARCHIVE_MAC "OFF")
endif()
if (NOT DEFINED ENVIRONMENT)
set (ENVIRONMENT "OFF")
endif()
if (NOT DEFINED FOLDER)
set (FOLDER FALSE)
endif()
#for each dependency type have to do separate things
if (ARCHIVE_WIN OR ARCHIVE_LIN OR ARCHIVE_MAC OR ARCHIVE OR ARCHIVE_UNIFIED)
if (NOT DEFINED TARGET_PATH)
message(FATAL_ERROR "TARGET_PATH should be defined for every dependency")
endif()
resolve_archive_dependency(RESULT ${NAME_OF_CMAKE_VAR} ${ARCHIVE} ${ARCHIVE_UNIFIED} ${ARCHIVE_WIN} ${ARCHIVE_LIN} ${ARCHIVE_MAC} ${TARGET_PATH} ${FOLDER} ${ENVIRONMENT})
set(${NAME_OF_CMAKE_VAR} ${RESULT} PARENT_SCOPE)
if (VERSION_REGEX)
GetNameAndUrlToDownload(archive RELATIVE_URL ${ARCHIVE_UNIFIED} ${ARCHIVE_WIN} ${ARCHIVE_LIN} ${ARCHIVE_MAC})
if (archive)
read_version(${archive} ${VERSION_REGEX} "${NAME_OF_CMAKE_VAR}_VERSION")
endif()
endif()
elseif (DEFINED GITHUB_PULL_REQUEST)
resolve_pull_request(${GITHUB_PULL_REQUEST} ${TARGET_PATH})
else()
message(FATAL_ERROR "Dependency of unknowntype, SHOULD set one of ARCHIVE_WIN, ARCHIVE, ARCHIVE_LIN, ARCHIVE_MAC, GITHUB_PULL_REQUEST")
endif()
endfunction(RESOLVE_DEPENDENCY)
function (resolve_model_dependency network archive network_model_path)
RESOLVE_DEPENDENCY(${network_model_path}
ARCHIVE "models_archives/${archive}"
TARGET_PATH "${MODELS_PATH}/${network}")
string (REPLACE ${MODELS_PATH} "" relative_path ${${network_model_path}})
set(${network_model_path} ".${relative_path}" PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,27 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 2.8)
function (Download from to fatal result output)
if((NOT EXISTS "${to}"))
message(STATUS "Downloading from ${from} to ${to} ...")
file(DOWNLOAD ${from} ${to}
TIMEOUT 3600
LOG log
STATUS status
SHOW_PROGRESS)
set (${output} ${status} PARENT_SCOPE)
else()
set (${output} 0 PARENT_SCOPE)
endif()
set(${result} "ON" PARENT_SCOPE)
endfunction(Download)
include ("download_and_apply")
include ("download_and_extract")

View File

@ -0,0 +1,52 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 2.8)
function (DownloadAndApply URL apply_to)
if (EXISTS ${apply_to})
file(READ ${apply_to} patchFile4Bytes LIMIT 4)
endif()
debug_message(STATUS "patchFile=" ${apply_to})
debug_message(STATUS "patchFile4Bytes=" ${patchFileSize} "\"")
if (NOT EXISTS ${apply_to} OR NOT patchFile4Bytes)
#remove empty file
if (EXISTS ${apply_to})
file(REMOVE ${apply_to})
endif()
DownloadAndCheck(${URL} ${apply_to} TRUE result)
else ()
set (MIGHT_BE_APPLIED 1)
endif()
get_filename_component(apply_dir ${apply_to} DIRECTORY)
get_filename_component(patch_name ${apply_to} NAME)
# git apply silently if file wasnot downloaded :
#
if (NOT DEFINED MIGHT_BE_APPLIED)
debug_message(STATUS "applying patch ... ")
endif()
if (NOT MINGW)
execute_process(COMMAND git apply --verbose ${patch_name}
WORKING_DIRECTORY ${apply_dir}
RESULT_VARIABLE rv
ERROR_VARIABLE err)
else()
debug_message("git patch: " ${patch_name} " not applied under MINGW, however it downloaded")
endif()
#TODO:bad patch indicator either it is bad by itself of failed to apply
#currently cannot detect what happened
if (NOT DEFINED MIGHT_BE_APPLIED AND NOT (rv EQUAL 0))
file(REMOVE_RECURSE "${apply_to}")
debug_message(FATAL_ERROR "cannot apply patch ${patch_name} " ${err})
endif()
endfunction(DownloadAndApply)

View File

@ -0,0 +1,56 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 2.8)
include (FindWget)
function (DownloadAndCheck from to fatal result)
set(status_res "ON")
set(output 1)
get_filename_component(download_dir ${to} DIRECTORY)
if (NOT EXISTS ${download_dir})
file(MAKE_DIRECTORY ${download_dir})
endif()
if(NOT EXISTS "${to}")
message(STATUS "Downloading from ${from} to ${to} ...")
find_program(aria2c "aria2c")
if (${aria2c} STREQUAL "aria2c-NOTFOUND")
if (NOT ${WGET_FOUND})
Download(${from} ${to} ${fatal} ${result} output)
list(GET output 0 status_code)
else()
message(STATUS "${WGET_EXECUTABLE} --no-cache ${from}")
execute_process(COMMAND ${WGET_EXECUTABLE} "--no-cache" "${from}" "-O" "${to}"
TIMEOUT 2000
RESULT_VARIABLE status_code)
endif()
else()
message(STATUS "${aria2c} ,*.*.*.* -d ${download_dir} ${from}")
execute_process(COMMAND "${aria2c}" "-s10" "-x10" "--dir=${download_dir}" "${from}"
TIMEOUT 2000
RESULT_VARIABLE status_code)
endif()
if(NOT status_code EQUAL 0)
if (fatal)
message(FATAL_ERROR "fatal error: downloading '${from}' failed
status_code: ${status_code}
status_string: ${status_string}
log: ${log}")
else()
set(status_res "ARCHIVE_DOWNLOAD_FAIL")
message("error: downloading '${from}' failed
status_code: ${status_code}")
endif()
endif()
endif()
file(REMOVE ${to}.md5)
set(${result} "${status_res}" PARENT_SCOPE)
endfunction(DownloadAndCheck)

View File

@ -0,0 +1,216 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 2.8)
include ("extract")
include ("download_and_check")
function (GetNameAndUrlToDownload name url archive_name_unified archive_name_win archive_name_lin archive_name_mac)
if (archive_name_unified)
set (${url} "${archive_name_unified}" PARENT_SCOPE)
set (${name} ${archive_name_unified} PARENT_SCOPE)
else()
if (LINUX OR (APPLE AND NOT archive_name_mac))
if (NOT archive_name_lin)
return()
endif()
set (PLATFORM_FOLDER linux)
set (archive_name ${archive_name_lin})
elseif(APPLE)
if (NOT archive_name_mac)
return()
endif()
set (PLATFORM_FOLDER mac)
set (archive_name ${archive_name_mac})
else()
#if no dependency for target platfrom skip it
if (NOT archive_name_win)
return()
endif()
set (PLATFORM_FOLDER windows)
set (archive_name ${archive_name_win})
endif()
set (${name} ${archive_name} PARENT_SCOPE)
set (${url} "${archive_name}" PARENT_SCOPE)
endif()
endfunction(GetNameAndUrlToDownload)
#download from paltform specific folder from share server
function (DownloadAndExtractPlatformSpecific
component
archive_name_unified
archive_name_win
archive_name_lin
archive_name_mac
unpacked_path
result_path
folder)
GetNameAndUrlToDownload(archive_name RELATIVE_URL ${archive_name_unified} ${archive_name_win} ${archive_name_lin} ${archive_name_mac} )
if (NOT archive_name OR NOT RELATIVE_URL)
return()
endif()
CheckOrDownloadAndExtract(${component} ${RELATIVE_URL} ${archive_name} ${unpacked_path} result_path2 ${folder} TRUE FALSE TRUE)
set (${result_path} ${result_path2} PARENT_SCOPE)
endfunction(DownloadAndExtractPlatformSpecific)
#download from common folder
function (DownloadAndExtract component archive_name unpacked_path result_path folder)
set (RELATIVE_URL "${archive_name}")
set(fattal TRUE)
CheckOrDownloadAndExtract(${component} ${RELATIVE_URL} ${archive_name} ${unpacked_path} result_path2 ${folder} ${fattal} result TRUE)
if (NOT ${result})
DownloadAndExtractPlatformSpecific(${component} ${archive_name} ${archive_name} ${archive_name} ${unpacked_path} ${result_path2} ${folder})
endif()
set (${result_path} ${result_path2} PARENT_SCOPE)
endfunction(DownloadAndExtract)
function (DownloadAndExtractInternal URL archive_path unpacked_path folder fattal result123)
set (status "ON")
DownloadAndCheck(${URL} ${archive_path} ${fattal} result1)
if ("${result1}" STREQUAL "ARCHIVE_DOWNLOAD_FAIL")
#check alternative url as well
set (status "OFF")
file(REMOVE_RECURSE "${archive_path}")
endif()
if ("${result1}" STREQUAL "CHECKSUM_DOWNLOAD_FAIL" OR "${result1}" STREQUAL "HASH_MISMATCH")
set(status FALSE)
file(REMOVE_RECURSE "${archive_path}")
endif()
if("${status}" STREQUAL "ON")
ExtractWithVersion(${URL} ${archive_path} ${unpacked_path} ${folder} result)
endif()
set (result123 ${status} PARENT_SCOPE)
endfunction(DownloadAndExtractInternal)
function (ExtractWithVersion URL archive_path unpacked_path folder result)
debug_message("ExtractWithVersion : ${archive_path} : ${unpacked_path}")
extract(${archive_path} ${unpacked_path} ${folder} status)
#dont need archive actually after unpacking
file(REMOVE_RECURSE "${archive_path}")
if (${status})
set (version_file ${unpacked_path}/ie_dependency.info)
file(WRITE ${version_file} ${URL})
else()
file(REMOVE_RECURSE "${unpacked_path}")
endif()
set (${result} ${status} PARENT_SCOPE)
endfunction (ExtractWithVersion)
function (DownloadOrExtractInternal URL archive_path unpacked_path folder fattal result123)
debug_message("checking wether archive downloaded : ${archive_path}")
if (NOT EXISTS ${archive_path})
DownloadAndExtractInternal(${URL} ${archive_path} ${unpacked_path} ${folder} ${fattal} result)
else()
if (ENABLE_UNSAFE_LOCATIONS)
ExtractWithVersion(${URL} ${archive_path} ${unpacked_path} ${folder} result)
if(NOT ${result})
DownloadAndExtractInternal(${URL} ${archive_path} ${unpacked_path} ${folder} ${fattal} result)
endif()
else()
debug_message("archive found on FS : ${archive_path}, however we cannot check it's checksum and think that it is invalid")
file(REMOVE_RECURSE "${archive_path}")
DownloadAndExtractInternal(${URL} ${archive_path} ${unpacked_path} ${folder} ${fattal} result)
endif()
endif()
if (NOT ${result})
message(FATAL_ERROR "error: extract of '${archive_path}' failed")
endif()
endfunction(DownloadOrExtractInternal)
file(REMOVE ${CMAKE_BINARY_DIR}/dependencies_64.txt)
function (CheckOrDownloadAndExtract component RELATIVE_URL archive_name unpacked_path result_path folder fattal result123 use_alternatives)
set (archive_path ${TEMP}/download/${archive_name})
set (status "ON")
set (on_master FALSE)
set (URL "https://download.01.org/openvinotoolkit/2018_R3/dldt/inference_engine/${RELATIVE_URL}")
#no message on recursive calls
if (${use_alternatives})
set(DEP_INFO "${component}=${URL}")
debug_message (STATUS "DEPENDENCY_URL: ${DEP_INFO}")
file(APPEND ${CMAKE_BINARY_DIR}/dependencies_64.txt "${DEP_INFO}\n")
endif()
debug_message ("checking that unpacked directory exist: ${unpacked_path}")
if (NOT EXISTS ${unpacked_path})
DownloadOrExtractInternal(${URL} ${archive_path} ${unpacked_path} ${folder} ${fattal} status)
else(NOT EXISTS ${unpacked_path})
#path exists, so we would like to check what was unpacked version
set (version_file ${unpacked_path}/ie_dependency.info)
if (DEFINED TEAMCITY_GIT_BRANCH)
if(${TEAMCITY_GIT_BRANCH} STREQUAL "master")
set(on_master TRUE)
debug_message ("On master branch, update data in DL_SDK_TEMP if necessary")
endif()
endif()
if (NOT EXISTS ${version_file} AND NOT ${ENABLE_ALTERNATIVE_TEMP})
clean_message(FATAL_ERROR "error: Dependency doesn't contain version file. Please select actions: \n"
"if you are not sure about your FS dependency - remove it : \n"
"\trm -rf ${unpacked_path}\n"
"and rerun cmake.\n"
"If your dependency is fine, then execute:\n\techo ${URL} > ${unpacked_path}/ie_dependency.info\n")
# file(REMOVE_RECURSE "${unpacked_path}")
# DownloadOrExtractInternal(${URL} ${archive_path} ${unpacked_path} ${fattal} status)
else()
if (EXISTS ${version_file})
file(READ "${version_file}" dependency_url)
string(REGEX REPLACE "\n" ";" dependency_url "${dependency_url}")
#we have decided to stick each dependency to unique url that will be that record in version file
debug_message("dependency_info on FS : \"${dependency_url}\"\n"
"compare to : \"${URL}\"" )
else ()
debug_message("no version file available at ${version_file}")
endif()
if (NOT EXISTS ${version_file} OR NOT ${dependency_url} STREQUAL ${URL})
if (${use_alternatives} AND ALTERNATIVE_PATH AND NOT ${on_master})
#creating alternative_path
string(REPLACE ${TEMP} ${ALTERNATIVE_PATH} unpacked_path ${unpacked_path})
string(REPLACE ${TEMP} ${ALTERNATIVE_PATH} archive_path ${archive_path})
debug_message("dependency different: use local path for fetching updated version: ${alternative_path}")
CheckOrDownloadAndExtract(${component} ${RELATIVE_URL} ${archive_name} ${unpacked_path} ${result_path} ${folder} ${fattal} ${result123} FALSE)
else()
debug_message("dependency updated: download it again")
file(REMOVE_RECURSE "${unpacked_path}")
DownloadOrExtractInternal(${URL} ${archive_path} ${unpacked_path} ${folder} ${fattal} status)
endif()
endif ()
endif()
endif()
if (${use_alternatives} OR ${on_master})
set (${result123} "${status}" PARENT_SCOPE)
set (${result_path} ${unpacked_path} PARENT_SCOPE)
endif()
endfunction(CheckOrDownloadAndExtract)

View File

@ -0,0 +1,48 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 2.8)
function (extract archive_path unpacked_path folder result)
# Slurped from a generated extract-TARGET.cmake file.
if (NOT EXISTS ${unpacked_path})
get_filename_component(unpacked_dir ${unpacked_path} DIRECTORY)
file(MAKE_DIRECTORY ${unpacked_path})
message(STATUS "extracting...
src='${archive_path}'
dst='${unpacked_path}'")
if(NOT EXISTS "${archive_path}")
message(FATAL_ERROR "error: file to extract does not exist: '${archive_path}'")
endif()
# Extract it:
#
# in case of archive dont have top level folder lets create it
if (${folder})
set (unpacked_dir ${unpacked_path})
message("unpacked_dir= ${unpacked_dir}")
endif()
message(STATUS "extracting... [tar xfz]")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xfz ${archive_path}
WORKING_DIRECTORY ${unpacked_dir}
RESULT_VARIABLE rv
ERROR_VARIABLE err)
if (NOT (err STREQUAL ""))
message(STATUS "error: extract of '${archive_path}' failed: ${err}")
#invalid archive
file(REMOVE_RECURSE "${unpacked_path}")
file(REMOVE_RECURSE "${archive_path}")
set(${result} 0 PARENT_SCOPE)
else()
set(${result} 1 PARENT_SCOPE)
endif()
endif()
endfunction (extract)

View File

@ -0,0 +1,63 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required (VERSION 2.8)
include ("options")
#this options are aimed to optimize build time on development system
#backed targets
ie_option (ENABLE_MKL_DNN "MKL-DNN plugin for inference engine" ON)
ie_option (ENABLE_CLDNN "clDnn based plugin for inference engine" ON)
ie_option (ENABLE_CLDNN_BUILD "build clDnn from sources" OFF)
ie_option (ENABLE_PROFILING_ITT "ITT tracing of IE and plugins internals" ON)
ie_option (ENABLE_PROFILING_RAW "Raw counters profiling (just values, no start/stop time or timeline)" OFF)
# "MKL-DNN library might use MKL-ML or OpenBLAS for gemm tasks: OPENBLAS|MKL"
if (NOT GEMM)
set (GEMM "OPENBLAS")
endif()
ie_option (ENABLE_OMP "MKL-DNN library based on OMP implementation" ON)
ie_option (ENABLE_INTEL_OMP "MKL-DNN library based on Intel OMP implementation" ON)
ie_option (ENABLE_TESTS "unit and functional tests" OFF)
ie_option (ENABLE_SAMPLES_CORE "console samples core library" ON)
ie_option (ENABLE_SANITIZER "enable checking memory errors via AddressSanitizer" OFF)
ie_option (COVERAGE "enable code coverage" OFF)
ie_option (ENABLE_STRESS_UNIT_TESTS "stress unit tests" OFF)
ie_option (VERBOSE_BUILD "shows extra information about build" OFF)
ie_option (ENABLE_UNSAFE_LOCATIONS "skip check for MD5 for dependency" OFF)
ie_option (ENABLE_ALTERNATIVE_TEMP "in case of dependency conflict, to avoid modification in master, use local copy of dependency" ON)
ie_option (ENABLE_SEGMENTATION_TESTS "segmentation tests" ON)
ie_option (ENABLE_OBJECT_DETECTION_TESTS "object detection tests" ON)
ie_option (ENABLE_OPENCV "enables OpenCV" ON)
ie_option (OS_FOLDER "create OS dedicated folder in output" OFF)
ie_option (ENABLE_PLUGIN_RPATH "enables rpath information to be present in plugins binary, and in corresponding test_applications" ON)
#environment variables used
#name of environment variable stored path to temp directory"
set (DL_SDK_TEMP "DL_SDK_TEMP")

View File

@ -0,0 +1,62 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
unset(ITT_INCLUDE_DIR CACHE)
unset(ITT_LIB CACHE)
if(NOT DEFINED INTEL_VTUNE_DIR AND DEFINED ENV{INTEL_VTUNE_DIR})
set(INTEL_VTUNE_DIR "$ENV{INTEL_VTUNE_DIR}")
endif()
if(NOT DEFINED INTEL_VTUNE_DIR)
if(EXISTS "/opt/intel/vtune_amplifier_xe/include")
set(INTEL_VTUNE_DIR "/opt/intel/vtune_amplifier_xe")
elseif(EXISTS "/opt/intel/vtune_amplifier/include")
set(INTEL_VTUNE_DIR "/opt/intel/vtune_amplifier")
elseif (EXISTS "C:/Program Files (x86)/IntelSWTools/VTune Amplifier XE")
set(INTEL_VTUNE_DIR "C:/Program Files (x86)/IntelSWTools/VTune Amplifier XE")
elseif (EXISTS "C:/Program Files (x86)/IntelSWTools/VTune Amplifier")
set(INTEL_VTUNE_DIR "C:/Program Files (x86)/IntelSWTools/VTune Amplifier")
endif()
endif()
if(DEFINED INTEL_VTUNE_DIR)
message(STATUS "INTEL_VTUNE_DIR = ${INTEL_VTUNE_DIR}")
find_path(ITT_INCLUDE_DIR
FILES
ittnotify.h
PATHS "${INTEL_VTUNE_DIR}/include/")
find_library(ITT_LIB
"libittnotify${CMAKE_STATIC_LIBRARY_SUFFIX}"
PATHS ${INTEL_VTUNE_DIR}/lib64)
set(Located_ITT_LIBS ${ITT_LIB} ${CMAKE_DL_LIBS})
set(Located_ITT_INCLUDE_DIRS ${ITT_INCLUDE_DIR})
else()
message(STATUS "INTEL_VTUNE_DIR is not defined")
endif()
# Handle find_package() arguments, and set INTEL_ITT_FOUND
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(INTEL_ITT
REQUIRED_VARS
Located_ITT_INCLUDE_DIRS
Located_ITT_LIBS)
if(ENABLE_PROFILING_ITT AND INTEL_ITT_FOUND)
add_definitions(-DENABLE_PROFILING_ITT=1)
set(INTEL_ITT_LIBS ${Located_ITT_LIBS})
set(INTEL_ITT_INCLUDE_DIRS ${Located_ITT_INCLUDE_DIRS})
message(STATUS "INTEL_ITT_INCLUDE_DIRS: ${INTEL_ITT_INCLUDE_DIRS}")
include_directories(${INTEL_ITT_INCLUDE_DIRS})
message(STATUS "INTEL_ITT_LIBS: ${INTEL_ITT_LIBS}")
else()
add_definitions(-DENABLE_PROFILING_ITT=0)
message(STATUS "INTEL_ITT is disabled")
endif()

View File

@ -0,0 +1,35 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required(VERSION 2.8)
if (UNIX)
function(get_linux_name res_var)
if (NOT EXISTS "/etc/lsb-release")
execute_process(COMMAND find /etc/ -maxdepth 1 -type f -name *-release -exec cat {} \;
OUTPUT_VARIABLE release_data RESULT_VARIABLE result)
set(name_regex "NAME=\"([^ \"\n]*).*\"\n")
set(version_regex "VERSION=\"([0-9]+(\\.[0-9]+)?)[^\n]*\"")
else ()
#linux version detection using cat /etc/lsb-release
file(READ "/etc/lsb-release" release_data)
set(name_regex "DISTRIB_ID=([^ \n]*)\n")
set(version_regex "DISTRIB_RELEASE=([0-9]+(\\.[0-9]+)?)")
endif ()
string(REGEX MATCH ${name_regex} name ${release_data})
set(os_name ${CMAKE_MATCH_1})
string(REGEX MATCH ${version_regex} version ${release_data})
set(os_name "${os_name} ${CMAKE_MATCH_1}")
if (os_name)
set(${res_var} ${os_name} PARENT_SCOPE)
else ()
set(${res_var} NOTFOUND PARENT_SCOPE)
endif ()
endfunction()
endif ()

View File

@ -0,0 +1,6 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
option(DEVELOPMENT_PLUGIN_MODE "Disabled build of all plugins" OFF)

View File

@ -0,0 +1,57 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
if (APPLE OR WIN32)
find_path(OMP_INC omp.h)
find_library(OMP_LIB iomp5
PATHS ${MKL}/lib)
if (OMP_INC AND OMP_LIB)
set(HAVE_OMP TRUE)
get_filename_component(OMP_LIB_DIR "${OMP_LIB}" PATH)
else()
if (ENABLE_OMP)
find_package(OpenMP)
if (NOT OPENMP_FOUND)
message(WARNING "OpenMP not found. OpenMP support will be disabled.")
endif()
endif()
endif()
endif()
macro(enable_omp)
if (APPLE) ## MacOS
if (HAVE_OMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp=libiomp5")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L${OMP_LIB_DIR}")
else()
message(WARNING "Was trying to enable OMP for some target. However OpenMP was not detected on system.")
endif()
elseif(UNIX) # Linux
add_definitions(-fopenmp)
elseif(WIN32) # Windows
if (ENABLE_OMP)
set(OPENMP_FLAGS "/Qopenmp /openmp")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CCXX_FLAGS} ${OPENMP_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CCXX_FLAGS} ${OPENMP_FLAGS}")
endif()
endif()
if (ENABLE_INTEL_OMP)
if (WIN32)
find_library(intel_omp_lib
libiomp5md
PATHS ${MKL}/lib ${ICCLIB})
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /nodefaultlib:vcomp")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /nodefaultlib:vcomp")
else()
find_library(intel_omp_lib
iomp5
PATHS ${MKL}/lib)
endif()
endif()
endmacro(enable_omp)

View File

@ -0,0 +1,20 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
function (ie_option variable description value)
option(${variable} "${description}" ${value})
list (APPEND IE_OPTIONS "${variable}")
set (IE_OPTIONS "${IE_OPTIONS}" PARENT_SCOPE)
endfunction()
include(version)
function (print_enabled_features)
message(STATUS "CI_BUILD_NUMBER: ${CI_BUILD_NUMBER}")
foreach(_var ${IE_OPTIONS})
message(STATUS "${_var} = ${${_var}}")
endforeach()
endfunction()

View File

@ -0,0 +1,18 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
if (WIN32)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_SCL_SECURE_NO_WARNINGS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") #no asynchronous structured exception handling
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Werror=return-type ")
if (APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-command-line-argument")
elseif(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuninitialized -Winit-self -Wmaybe-uninitialized")
endif()
endif()

View File

@ -0,0 +1,11 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
if (ENABLE_SANITIZER)
set(CMAKE_CCXX_FLAGS "${CMAKE_CCXX_FLAGS} -fsanitize=address -fuse-ld=gold")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fuse-ld=gold")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
endif()

View File

@ -0,0 +1,36 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
if (UNIX OR APPLE)
set(CMAKE_CCXX_FLAGS "${CMAKE_CCXX_FLAGS} -fPIE -fPIC -Wformat -Wformat-security")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D_FORTIFY_SOURCE=2")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D_FORTIFY_SOURCE=2")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack -z relro -z now")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack -z relro -z now")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
set(CMAKE_CCXX_FLAGS "${CMAKE_CCXX_FLAGS} -fstack-protector-all")
else()
set(CMAKE_CCXX_FLAGS "${CMAKE_CCXX_FLAGS} -fstack-protector-strong")
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CCXX_FLAGS "${CMAKE_CCXX_FLAGS} -fstack-protector-all")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack -z relro -z now")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack -z relro -z now")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CCXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CCXX_FLAGS}")
elseif (WIN32)
elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /sdl")
endif()

View File

@ -0,0 +1,17 @@
# Copyright (C) 2018 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
set(InferenceEngine_VERSION 1.2.0)
set(PACKAGE_VERSION ${InferenceEngine_VERSION})
set(PACKAGE_VERSION_EXACT False)
set(PACKAGE_VERSION_COMPATIBLE False)
if(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT True)
set(PACKAGE_VERSION_COMPATIBLE True)
endif()
if(PACKAGE_FIND_VERSION VERSION_LESS PACKAGE_VERSION)
set(PACKAGE_VERSION_COMPATIBLE True)
endif()

View File

@ -0,0 +1,151 @@
# Copyright (C) 2018 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
# FindIE
# ------
#
# You can specify the path to Inference Engine files in IE_ROOT_DIR
#
# This will define the following variables:
#
# InferenceEngine_FOUND - True if the system has the Inference Engine library
# InferenceEngine_INCLUDE_DIRS - Inference Engine include directories
# InferenceEngine_LIBRARIES - Inference Engine libraries
#
# and the following imported targets:
#
# IE::inference_engine - The Inference Engine library
#
set(InferenceEngine_FOUND FALSE)
if(TARGET IE::inference_engine)
set(InferenceEngine_FOUND TRUE)
get_target_property(InferenceEngine_INCLUDE_DIRS IE::inference_engine INTERFACE_INCLUDE_DIRECTORIES)
set(InferenceEngine_LIBRARIES IE::inference_engine)
else()
if (WIN32)
set(_ARCH intel64)
else()
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(_ARCH intel64)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386")
set(_ARCH ia32)
endif()
endif()
# check whether setvars.sh is sourced
if(NOT IE_ROOT_DIR AND (DEFINED ENV{InferenceEngine_DIR} OR InferenceEngine_DIR OR DEFINED ENV{INTEL_CVSDK_DIR}))
if (EXISTS "${InferenceEngine_DIR}")
# InferenceEngine_DIR manually set via command line params
set(IE_ROOT_DIR "${InferenceEngine_DIR}/..")
elseif (EXISTS "$ENV{InferenceEngine_DIR}")
# InferenceEngine_DIR manually set via env
set(IE_ROOT_DIR "$ENV{InferenceEngine_DIR}/..")
elseif (EXISTS "$ENV{INTEL_CVSDK_DIR}/inference_engine")
# if we installed DL SDK
set(IE_ROOT_DIR "$ENV{INTEL_CVSDK_DIR}/inference_engine")
elseif (EXISTS "$ENV{INTEL_CVSDK_DIR}/deployment_tools/inference_engine")
# CV SDK is installed
set(IE_ROOT_DIR "$ENV{INTEL_CVSDK_DIR}/deployment_tools/inference_engine")
endif()
endif()
if(IE_ROOT_DIR)
if (WIN32)
set(_OS_PATH "")
else()
if (NOT EXISTS "/etc/lsb-release")
execute_process(COMMAND find /etc/ -maxdepth 1 -type f -name *-release -exec cat {} \;
OUTPUT_VARIABLE release_data RESULT_VARIABLE result)
set(name_regex "NAME=\"([^ \"\n]*).*\"\n")
set(version_regex "VERSION=\"([0-9]+(\\.[0-9]+)?)[^\n]*\"")
else()
#linux version detection using cat /etc/lsb-release
file(READ "/etc/lsb-release" release_data)
set(name_regex "DISTRIB_ID=([^ \n]*)\n")
set(version_regex "DISTRIB_RELEASE=([0-9]+(\\.[0-9]+)?)")
endif()
string(REGEX MATCH ${name_regex} name ${release_data})
set(os_name ${CMAKE_MATCH_1})
string(REGEX MATCH ${version_regex} version ${release_data})
set(os_name "${os_name} ${CMAKE_MATCH_1}")
if (NOT os_name)
message(FATAL_ERROR "Cannot detect OS via reading /etc/*-release:\n ${release_data}")
endif()
message (STATUS "/etc/*-release distrib: ${os_name}")
if (${os_name} STREQUAL "Ubuntu 14.04")
set(_OS_PATH "ubuntu_14.04/")
elseif (${os_name} STREQUAL "Ubuntu 16.04")
set(_OS_PATH "ubuntu_16.04/")
elseif (${os_name} STREQUAL "CentOS 7")
set(_OS_PATH "centos_7.4/")
elseif (${os_name} STREQUAL "poky 2.0")
set(_OS_PATH "ubuntu_16.04/")
else()
message(FATAL_ERROR "${os_name} is not supported. List of supported OS: Ubuntu 14.04, Ubuntu 16.04, CentOS 7")
endif()
endif()
endif()
if(IE_INCLUDE_DIR AND NOT "${IE_ROOT_DIR}/include" EQUAL "${IE_INCLUDE_DIR}")
unset(IE_INCLUDE_DIR CACHE)
endif()
if(IE_LIBRARY AND NOT "${IE_ROOT_DIR}/lib/${_OS_PATH}/${_ARCH}" EQUAL "${IE_LIBRARY}")
unset(IE_LIBRARY CACHE)
endif()
set(_IE_ROOT_INCLUDE_DIR "${IE_ROOT_DIR}/include")
set(_IE_ROOT_LIBRARY "${IE_ROOT_DIR}/lib/${_OS_PATH}/${_ARCH}")
find_path(IE_INCLUDE_DIR inference_engine.hpp "${_IE_ROOT_INCLUDE_DIR}")
#message("InferenceEngine_INCLUDE_DIR=${IE_INCLUDE_DIR}:${_IE_ROOT_INCLUDE_DIR}")
include(FindPackageHandleStandardArgs)
if (WIN32)
find_library(IE_RELEASE_LIBRARY inference_engine "${_IE_ROOT_LIBRARY}/Release")
find_library(IE_DEBUG_LIBRARY inference_engine "${_IE_ROOT_LIBRARY}/Debug")
find_package_handle_standard_args( IE
REQUIRED_VARS IE_RELEASE_LIBRARY IE_DEBUG_LIBRARY IE_INCLUDE_DIR
FAIL_MESSAGE "Inference Engine cannot be found at ${_IE_ROOT_LIBRARY}. Please consult InferenceEgnineConfig.cmake module's help page.")
else()
find_library(IE_LIBRARY inference_engine "${_IE_ROOT_LIBRARY}")
find_package_handle_standard_args( IE
REQUIRED_VARS IE_LIBRARY IE_INCLUDE_DIR
FAIL_MESSAGE "Inference Engine cannot be found at ${_IE_ROOT_LIBRARY}. Please consult InferenceEgnineConfig.cmake module's help page.")
endif()
if(IE_FOUND)
add_library(IE::inference_engine SHARED IMPORTED GLOBAL)
if (WIN32)
set_property(TARGET IE::inference_engine APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_property(TARGET IE::inference_engine APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(IE::inference_engine PROPERTIES
IMPORTED_IMPLIB_RELEASE "${IE_RELEASE_LIBRARY}"
IMPORTED_IMPLIB_DEBUG "${IE_DEBUG_LIBRARY}"
MAP_IMPORTED_CONFIG_DEBUG Debug
MAP_IMPORTED_CONFIG_RELEASE Release
MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release
INTERFACE_INCLUDE_DIRECTORIES "${IE_INCLUDE_DIR}")
else()
set_target_properties(IE::inference_engine PROPERTIES
IMPORTED_LOCATION "${IE_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${IE_INCLUDE_DIR}")
target_link_libraries(IE::inference_engine INTERFACE ${CMAKE_DL_LIBS})
endif()
set(InferenceEngine_INCLUDE_DIRS ${IE_INCLUDE_DIR})
set(InferenceEngine_LIBRARIES IE::inference_engine)
set(InferenceEngine_FOUND TRUE)
endif()
endif()

View File

@ -0,0 +1,46 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
cmake_minimum_required(VERSION 2.8)
function (branchName VAR)
execute_process(
COMMAND git rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${IE_MAIN_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
set (${VAR} ${GIT_BRANCH} PARENT_SCOPE)
endfunction()
function (commitHash VAR)
execute_process(
COMMAND git rev-parse HEAD
WORKING_DIRECTORY ${IE_MAIN_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE)
set (${VAR} ${GIT_COMMIT_HASH} PARENT_SCOPE)
endfunction()
if (DEFINED ENV{CI_BUILD_NUMBER})
set(CI_BUILD_NUMBER $ENV{CI_BUILD_NUMBER})
else()
branchName(GIT_BRANCH)
commitHash(GIT_COMMIT_HASH)
set(custom_build "custom_${GIT_BRANCH}_${GIT_COMMIT_HASH}")
set(CI_BUILD_NUMBER "${custom_build}")
endif()
function (addVersionDefines FILE)
foreach (VAR ${ARGN})
if (DEFINED ${VAR} AND NOT "${${VAR}}" STREQUAL "")
set_property(
SOURCE ${FILE}
APPEND
PROPERTY COMPILE_DEFINITIONS
${VAR}="${${VAR}}")
endif()
endforeach()
endfunction()

View File

@ -0,0 +1,42 @@
# Copyright (C) 2018 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
# Defines the CMake commands/policies
cmake_minimum_required( VERSION 2.8.5 )
# Set the project name
project( INFERENCE_ENGINE_DRIVER )
option(COPY_IE_LIBS "Copy Inference Engine libs to package directory" ${WIN32})
set (IE_DEFAULT_PATH computer_vision_sdk/deployment_tools/inference_engine/share)
find_package(InferenceEngine REQUIRED PATHS /opt/intel/${IE_DEFAULT_PATH} $ENV{HOME}/intel/${IE_DEFAULT_PATH})
# Make the scripts available in the 'cmake' directory available for the
# 'include()' command, 'find_package()' command.
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/cmake )
# Include the CMake script UseCython.cmake. This defines add_cython_module().
# Instruction for use can be found at the top of cmake/UseCython.cmake.
include( UseCython )
# With CMake, a clean separation can be made between the source tree and the
# build tree. When all source is compiled, as with pure C/C++, the source is
# no-longer needed in the build tree. However, with pure *.py source, the
# source is processed directly. To handle this, we reproduce the availability
# of the source files in the build tree.
add_custom_target( ReplicatePythonSourceTree ALL ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_SOURCE_DIR}/cmake/ReplicatePythonSourceTree.cmake
${CMAKE_CURRENT_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
add_custom_target( CopyIeLibs ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_SOURCE_DIR}/cmake/CopyIeLibs.cmake
${IE_ROOT_DIR}/bin/${_ARCH}/Release ${_IE_ROOT_LIBRARY}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ie_driver )
include_directories( IE::inference_engine )
# Process the CMakeLists.txt in the 'src' and 'bin' directory.
add_subdirectory( inference_engine )

View File

@ -0,0 +1,39 @@
## Software Requirements
- [CMake\*](https://cmake.org/download/) 3.9 or later
- Microsoft\* Visual Studio 2015 or later on Windows\*
- gcc 4.8 or later on Linux
- Python 2.7 or higher on Linux\*
- Python 3.4 or higher on Windows\*
## Prerequisites
Install the following Python modules:
- opencv-python
- numpy
- cython
## Building on Windows
```shellscript
mkdir build
cd build
set PATH=C:\Program Files\Python36\Scripts;%PATH%
cmake -G "Visual Studio 14 2015 Win64" -DInferenceEngine_DIR=..\..\..\build ^
-DPYTHON_EXECUTABLE="C:\Program Files\Python36\python.exe" ^
-DPYTHON_INCLUDE_DIR="C:\Program Files\Python36\include" ^
-DPYTHON_LIBRARY="C:\Program Files\Python36\libs\python36.lib" ..
```
Then build generated solution INFERENCE_ENGINE_DRIVER.sln using Microsoft\* Visual Studio.
## Building on Linux
```shellscript
mkdir -p build
cd build
cmake -DInferenceEngine_DIR=../../../build -DPYTHON_EXECUTABLE=`which python3.6` \
-DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.6m.so \
-DPYTHON_INCLUDE_DIR=/usr/include/python3.6 ..
make -j16
```
Note: -DInferenceEngine_DIR parameter is needed to specify the folder with generated make files or Visual Studio solution used to build Inference Engine (see readme file in the inference-engine root folder).

View File

@ -0,0 +1,10 @@
set(IE_WIN_LIBS ${CMAKE_ARGV3})
set(IE_LIBS ${CMAKE_ARGV4})
if (WIN32)
file( GLOB IE_LIBS "${IE_WIN_LIBS}/*.dll")
file( COPY ${IE_LIBS} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
else()
file( GLOB IE_LIBS "${IE_LIBS}/*.so")
file( COPY ${IE_LIBS} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
endif()

View File

@ -0,0 +1,44 @@
# Find the Cython compiler.
#
# This code sets the following variables:
#
# CYTHON_EXECUTABLE
#
# See also UseCython.cmake
#=============================================================================
# Copyright 2011 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Use the Cython executable that lives next to the Python executable
# if it is a local installation.
find_package( PythonInterp )
if( PYTHONINTERP_FOUND )
get_filename_component( _python_path ${PYTHON_EXECUTABLE} PATH )
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
HINTS ${_python_path} $ENV{HOME}/.local/bin
)
else()
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
)
endif()
include( FindPackageHandleStandardArgs )
FIND_PACKAGE_HANDLE_STANDARD_ARGS( Cython REQUIRED_VARS CYTHON_EXECUTABLE )
mark_as_advanced( CYTHON_EXECUTABLE )

View File

@ -0,0 +1,7 @@
# Note: when executed in the build dir, then CMAKE_CURRENT_SOURCE_DIR is the
# build dir.
file( COPY setup.py inference_engine tests DESTINATION "${CMAKE_ARGV3}"
FILES_MATCHING PATTERN "*.py" )
file( COPY requirements.txt DESTINATION "${CMAKE_ARGV3}" )

View File

@ -0,0 +1,319 @@
# Define a function to create Cython modules.
#
# For more information on the Cython project, see http://cython.org/.
# "Cython is a language that makes writing C extensions for the Python language
# as easy as Python itself."
#
# This file defines a CMake function to build a Cython Python module.
# To use it, first include this file.
#
# include( UseCython )
#
# Then call cython_add_module to create a module.
#
# cython_add_module( <module_name> <src1> <src2> ... <srcN> )
#
# To create a standalone executable, the function
#
# cython_add_standalone_executable( <executable_name> [MAIN_MODULE src1] <src1> <src2> ... <srcN> )
#
# To avoid dependence on Python, set the PYTHON_LIBRARY cache variable to point
# to a static library. If a MAIN_MODULE source is specified,
# the "if __name__ == '__main__':" from that module is used as the C main() method
# for the executable. If MAIN_MODULE, the source with the same basename as
# <executable_name> is assumed to be the MAIN_MODULE.
#
# Where <module_name> is the name of the resulting Python module and
# <src1> <src2> ... are source files to be compiled into the module, e.g. *.pyx,
# *.py, *.c, *.cxx, etc. A CMake target is created with name <module_name>. This can
# be used for target_link_libraries(), etc.
#
# The sample paths set with the CMake include_directories() command will be used
# for include directories to search for *.pxd when running the Cython complire.
#
# Cache variables that effect the behavior include:
#
# CYTHON_ANNOTATE
# CYTHON_NO_DOCSTRINGS
# CYTHON_FLAGS
#
# Source file properties that effect the build process are
#
# CYTHON_IS_CXX
#
# If this is set of a *.pyx file with CMake set_source_files_properties()
# command, the file will be compiled as a C++ file.
#
# See also FindCython.cmake
#=============================================================================
# Copyright 2011 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Configuration options.
set( CYTHON_ANNOTATE OFF
CACHE BOOL "Create an annotated .html file when compiling *.pyx." )
set( CYTHON_NO_DOCSTRINGS OFF
CACHE BOOL "Strip docstrings from the compiled module." )
set( CYTHON_FLAGS "" CACHE STRING
"Extra flags to the cython compiler." )
mark_as_advanced( CYTHON_ANNOTATE CYTHON_NO_DOCSTRINGS CYTHON_FLAGS )
find_package( Cython REQUIRED )
find_package( PythonLibs REQUIRED )
set( CYTHON_CXX_EXTENSION "cxx" )
set( CYTHON_C_EXTENSION "c" )
# Create a *.c or *.cxx file from a *.pyx file.
# Input the generated file basename. The generate file will put into the variable
# placed in the "generated_file" argument. Finally all the *.py and *.pyx files.
function( compile_pyx _name generated_file )
# Default to assuming all files are C.
set( cxx_arg "" )
set( extension ${CYTHON_C_EXTENSION} )
set( pyx_lang "C" )
set( comment "Compiling Cython C source for ${_name}..." )
set( cython_include_directories "" )
set( pxd_dependencies "" )
set( pxi_dependencies "" )
set( c_header_dependencies "" )
set( pyx_locations "" )
foreach( pyx_file ${ARGN} )
get_filename_component( pyx_file_basename "${pyx_file}" NAME_WE )
# Determine if it is a C or C++ file.
get_source_file_property( property_is_cxx ${pyx_file} CYTHON_IS_CXX )
if( ${property_is_cxx} )
set( cxx_arg "--cplus" )
set( extension ${CYTHON_CXX_EXTENSION} )
set( pyx_lang "CXX" )
set( comment "Compiling Cython CXX source for ${_name}..." )
endif()
# Get the include directories.
get_source_file_property( pyx_location ${pyx_file} LOCATION )
get_filename_component( pyx_path ${pyx_location} PATH )
get_directory_property( cmake_include_directories DIRECTORY ${pyx_path} INCLUDE_DIRECTORIES )
list( APPEND cython_include_directories ${cmake_include_directories} )
list( APPEND pyx_locations "${pyx_location}" )
# Determine dependencies.
# Add the pxd file will the same name as the given pyx file.
unset( corresponding_pxd_file CACHE )
find_file( corresponding_pxd_file ${pyx_file_basename}.pxd
PATHS "${pyx_path}" ${cmake_include_directories}
NO_DEFAULT_PATH )
if( corresponding_pxd_file )
list( APPEND pxd_dependencies "${corresponding_pxd_file}" )
endif()
# Look for included pxi files
file(STRINGS "${pyx_file}" include_statements REGEX "include +['\"]([^'\"]+).*")
foreach(statement ${include_statements})
string(REGEX REPLACE "include +['\"]([^'\"]+).*" "\\1" pxi_file "${statement}")
unset(pxi_location CACHE)
find_file(pxi_location ${pxi_file}
PATHS "${pyx_path}" ${cmake_include_directories} NO_DEFAULT_PATH)
if (pxi_location)
list(APPEND pxi_dependencies ${pxi_location})
get_filename_component( found_pyi_file_basename "${pxi_file}" NAME_WE )
get_filename_component( found_pyi_path ${pxi_location} PATH )
unset( found_pyi_pxd_file CACHE )
find_file( found_pyi_pxd_file ${found_pyi_file_basename}.pxd
PATHS "${found_pyi_path}" ${cmake_include_directories} NO_DEFAULT_PATH )
if (found_pyi_pxd_file)
list( APPEND pxd_dependencies "${found_pyi_pxd_file}" )
endif()
endif()
endforeach() # for each include statement found
# pxd files to check for additional dependencies.
set( pxds_to_check "${pyx_file}" "${pxd_dependencies}" )
set( pxds_checked "" )
set( number_pxds_to_check 1 )
while( ${number_pxds_to_check} GREATER 0 )
foreach( pxd ${pxds_to_check} )
list( APPEND pxds_checked "${pxd}" )
list( REMOVE_ITEM pxds_to_check "${pxd}" )
# check for C header dependencies
file( STRINGS "${pxd}" extern_from_statements
REGEX "cdef[ ]+extern[ ]+from.*$" )
foreach( statement ${extern_from_statements} )
# Had trouble getting the quote in the regex
string( REGEX REPLACE "cdef[ ]+extern[ ]+from[ ]+[\"]([^\"]+)[\"].*" "\\1" header "${statement}" )
unset( header_location CACHE )
find_file( header_location ${header} PATHS ${cmake_include_directories} )
if( header_location )
list( FIND c_header_dependencies "${header_location}" header_idx )
if( ${header_idx} LESS 0 )
list( APPEND c_header_dependencies "${header_location}" )
endif()
endif()
endforeach()
# check for pxd dependencies
# Look for cimport statements.
set( module_dependencies "" )
file( STRINGS "${pxd}" cimport_statements REGEX cimport )
foreach( statement ${cimport_statements} )
if( ${statement} MATCHES from )
string( REGEX REPLACE "from[ ]+([^ ]+).*" "\\1" module "${statement}" )
else()
string( REGEX REPLACE "cimport[ ]+([^ ]+).*" "\\1" module "${statement}" )
endif()
list( APPEND module_dependencies ${module} )
endforeach()
list( REMOVE_DUPLICATES module_dependencies )
# Add the module to the files to check, if appropriate.
foreach( module ${module_dependencies} )
unset( pxd_location CACHE )
find_file( pxd_location ${module}.pxd
PATHS "${pyx_path}" ${cmake_include_directories} NO_DEFAULT_PATH )
if( pxd_location )
list( FIND pxds_checked ${pxd_location} pxd_idx )
if( ${pxd_idx} LESS 0 )
list( FIND pxds_to_check ${pxd_location} pxd_idx )
if( ${pxd_idx} LESS 0 )
list( APPEND pxds_to_check ${pxd_location} )
list( APPEND pxd_dependencies ${pxd_location} )
endif() # if it is not already going to be checked
endif() # if it has not already been checked
endif() # if pxd file can be found
endforeach() # for each module dependency discovered
endforeach() # for each pxd file to check
list( LENGTH pxds_to_check number_pxds_to_check )
endwhile()
endforeach() # pyx_file
# Set additional flags.
if( CYTHON_ANNOTATE )
set( annotate_arg "--annotate" )
endif()
if( CYTHON_NO_DOCSTRINGS )
set( no_docstrings_arg "--no-docstrings" )
endif()
if( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" OR
"${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo" )
set( cython_debug_arg "--gdb" )
endif()
if( "${PYTHONLIBS_VERSION_STRING}" MATCHES "^2." )
set( version_arg "-2" )
elseif( "${PYTHONLIBS_VERSION_STRING}" MATCHES "^3." )
set( version_arg "-3" )
else()
set( version_arg )
endif()
# Include directory arguments.
list( REMOVE_DUPLICATES cython_include_directories )
set( include_directory_arg "" )
foreach( _include_dir ${cython_include_directories} )
set( include_directory_arg ${include_directory_arg} "-I" "${_include_dir}" )
endforeach()
# Determining generated file name.
set( _generated_file "${CMAKE_CURRENT_BINARY_DIR}/${_name}.${extension}" )
set_source_files_properties( ${_generated_file} PROPERTIES GENERATED TRUE )
set( ${generated_file} ${_generated_file} PARENT_SCOPE )
list( REMOVE_DUPLICATES pxd_dependencies )
list( REMOVE_DUPLICATES c_header_dependencies )
# Add the command to run the compiler.
add_custom_command( OUTPUT ${_generated_file}
COMMAND ${CYTHON_EXECUTABLE}
ARGS ${cxx_arg} ${include_directory_arg} ${version_arg}
${annotate_arg} ${no_docstrings_arg} ${cython_debug_arg} ${CYTHON_FLAGS}
--output-file ${_generated_file} ${pyx_locations}
DEPENDS ${pyx_locations} ${pxd_dependencies} ${pxi_dependencies}
IMPLICIT_DEPENDS ${pyx_lang} ${c_header_dependencies}
COMMENT ${comment}
)
# Remove their visibility to the user.
set( corresponding_pxd_file "" CACHE INTERNAL "" )
set( header_location "" CACHE INTERNAL "" )
set( pxd_location "" CACHE INTERNAL "" )
endfunction()
# cython_add_module( <name> src1 src2 ... srcN )
# Build the Cython Python module.
function( cython_add_module _name )
set( pyx_module_sources "" )
set( other_module_sources "" )
foreach( _file ${ARGN} )
if( ${_file} MATCHES ".*\\.py[x]?$" )
list( APPEND pyx_module_sources ${_file} )
else()
list( APPEND other_module_sources ${_file} )
endif()
endforeach()
compile_pyx( ${_name} generated_file ${pyx_module_sources} )
include_directories( ${PYTHON_INCLUDE_DIRS} )
python_add_module( ${_name} ${generated_file} ${other_module_sources} )
if( APPLE )
set_target_properties( ${_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" )
else()
target_link_libraries( ${_name} PRIVATE ${PYTHON_LIBRARIES} )
endif()
endfunction()
include( CMakeParseArguments )
# cython_add_standalone_executable( _name [MAIN_MODULE src3.py] src1 src2 ... srcN )
# Creates a standalone executable the given sources.
function( cython_add_standalone_executable _name )
set( pyx_module_sources "" )
set( other_module_sources "" )
set( main_module "" )
cmake_parse_arguments( cython_arguments "" "MAIN_MODULE" "" ${ARGN} )
include_directories( ${PYTHON_INCLUDE_DIRS} )
foreach( _file ${cython_arguments_UNPARSED_ARGUMENTS} )
if( ${_file} MATCHES ".*\\.py[x]?$" )
get_filename_component( _file_we ${_file} NAME_WE )
if( "${_file_we}" STREQUAL "${_name}" )
set( main_module "${_file}" )
elseif( NOT "${_file}" STREQUAL "${cython_arguments_MAIN_MODULE}" )
set( PYTHON_MODULE_${_file_we}_static_BUILD_SHARED OFF )
compile_pyx( "${_file_we}_static" generated_file "${_file}" )
list( APPEND pyx_module_sources "${generated_file}" )
endif()
else()
list( APPEND other_module_sources ${_file} )
endif()
endforeach()
if( cython_arguments_MAIN_MODULE )
set( main_module ${cython_arguments_MAIN_MODULE} )
endif()
if( NOT main_module )
message( FATAL_ERROR "main module not found." )
endif()
get_filename_component( main_module_we "${main_module}" NAME_WE )
set( CYTHON_FLAGS ${CYTHON_FLAGS} --embed )
compile_pyx( "${main_module_we}_static" generated_file ${main_module} )
add_executable( ${_name} ${generated_file} ${pyx_module_sources} ${other_module_sources} )
target_link_libraries( ${_name} PRIVATE ${PYTHON_LIBRARIES} ${pyx_module_libs} )
endfunction()

View File

@ -0,0 +1,516 @@
# Overview of Inference Engine Python* API {#InferEnginePythonAPI}
**NOTE:** It is a preview version of the Inference Engine Python\* API for evaluation purpose only.
Module structure and API itself may be changed in future releases.
This API provides a simplified interface for Inference Engine functionality that allows to:
* handle the models
* load and configure Inference Engine plugins based on device names
* perform inference in synchronous and asynchronous modes with arbitrary number of infer requests (the number of infer requests may be limited by target device capabilities)
## Supported OSes
Currently the Inference Engine Python\* API is supported on Ubuntu* 16.04, Microsoft Windows* 10 and CentOS* 7.3 OSes.
Supported Python* versions:
* On Ubuntu 16.04: 2.7, 3.5, 3.6
* On Windows 10: 3.5, 3.6
* On CentOS 7.3: 3.4, 3.5, 3.6
## Setting Up the Environment
To configure the environment for the Inference Engine Python\* API, run:
* On Ubuntu 16.04: `source <INSTALL_DIR>/bin/setupvars.sh .`
* On Windows 10: `call <INSTALL_DIR>\deployment_tools\inference_engine\python_api\setenv.bat`
The script automatically detects latest installed Python\* version and configures required environment if the version is supported.
If you want to use certain version of Python\*, set the environment variable `PYTHONPATH=<INSTALL_DIR>/deployment_tools/inference_engine/python_api/<desired_python_version>`
after running the environment configuration script.
## <a name="ienetlayer-class"></a>IENetLayer
This class stores main information about the layer and allow to modify some layer parameters
### Class attributes:
* `name` - name of the layer
* `type` - layer type
* `precision` - layer base operating precision
* `affinity` - layer affinity set by user or default affinity set by IEPlugin.set_initial_affinity() method.
The affinity attribute provides getter and setter interface, so the layer affinity can be modified directly in following way
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> plugin = IEPlugin(device="HETERO:FPGA,CPU")
>>> plugin.set_config({"TARGET_FALLBACK": "HETERO:FPGA,CPU"})
>>> plugin.set_initial_affinity(net)
>>> for l in net.layers.values():
... if l.type == "Convolution":
... l.affinity = "CPU"
```
To correctly set affinity for the network, you must first initialize and properly configure the HETERO plugin.
`set_config({"TARGET_FALLBACK": "HETERO:FPGA,GPU"})` function configures the plugin fallback devices and their order.
`plugin.set_initial_affinity(net)` function sets affinity parameter of model layers according to its support
on specified devices.
After default affinity is set by the plugin, override the default values by setting affinity manually how it's
described in example above
To understand how default and non-default affinities are set:
1. Call `net.layers` function right after model loading and check that layer affinity parameter is empty.
2. Call `plugin.set_default_affinity(net)`.
3. Call `net.layers` and check layer affinity parameters to see how plugin set default affinity
4. Set layer affinity how it's described above
5. Call `net.layers` again and check layer affinity parameters to see how it was changed after manual affinity
setting
Please refer to `affinity_setting_sample.py` to see the full usage pipeline.
* `weights` - dictionary with layer weights, biases or custom blobs if any
* `params` - layer specific parameters. Provides getter and setter interface which allows to get and\or modify layer parameters.
Please note that some modifications can be ignored and\or overwriten by target plugin (e.g. modification of
convolution kernel size will be reflected in layer parameters but finally the plugin will ignore it and will
use initial kernel size)
## <a name="ienetwork-class"></a>IENetwork
This class contains the information about the network model read from IR and allows you to manipulate with some model parameters such as
layers affinity and output layers.
### Class Constructor
There is no explicit class constructor. Use `from_ir` class method to read the Intermediate Representation (IR) and initialize a correct instance of the `IENetwork` class.
### Class attributes:
* `name` - Name of the loaded network
* `inputs` - a dictionary of input layer name as a key and input data shape as a value
* Usage example:
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> net.inputs
{'data': [1, 3, 224, 224]}
```
* `outputs` - a list of output layer names
* Usage example:
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> net.outputs
['prob']
```
* `batch_size` - Batch size of the network. Provides getter and setter interface which allows to get and modify the
network batch size in the following way:
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> net.batch_size
1
>>> net.batch_size = 4
>>> net.batch_size
4
```
* `layers` - return dictionary with the network layer names as key and <a name="ienetlayer-class"></a>IENetLayer objects containing layer properties
as value
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> net.layers
{'conv0': <inference_engine.ie_api.IENetLayer object at 0x7f3a4c102370>}
```
### Class Methods
* `from_ir(model: str, weights: str)`
* Description:
The class method serves to read the model from the `.xml` and `.bin` files of the IR.
* Parameters:
* model - path to `.xml` file of the IR
* weights - path to `.bin` file of the IR
* Return value:
An instance of the `IENetwork` class
* Usage example:
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> net
<inference_engine.ie_api.IENetwork object at 0x7fd7dbce54b0>
```
### Instance Methods
* `add_outputs(outputs)`:
* Description:
The method serves to mark any intermediate layer as output layer to retrieve the inference results
from the specified layers.
* Parameters:
* `outputs` - a list of layer names to be set as model outputs. In case of setting one layer as output, string with one layer can be provided.
* Return value:
None
* Usage example:
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> net.add_outputs(["conv5_1/dwise', conv2_1/expand'])]
>>> net.outputs
['prob', 'conv5_1/dwise', 'conv2_1/expand']
```
Note that the last layers (nodes without successors in graph representation of the model) are set as output
by default. In the case above, `prob` layer is a default output and `conv5_1/dwise`, `conv2_1/expand` are user-defined
outputs.
## <a name="ieplugin-class"></a>IEPlugin Class
This class is the main plugin interface and serves to initialize and configure the plugin.
### Class Constructor
* `__init__(device: str, plugin_dirs=None)`
* Parameters:
* `device` - target device name. Supported devices: CPU, GPU, FPGA, MYRIAD, HETERO
* `plugin_dirs` - list of paths to plugin directories
### Properties
* `device` - a name of the device that was specified to initialize IEPlugin
* `version` - a version of the plugin
### Instance Methods
* `load(network: IENetwork, num_requests: int=1, config=None)`
* Description:
Loads a network that was read from the IR to the plugin and creates an executable network from a network object.
You can create as many networks as you need and use them simultaneously (up to the limitation of the hardware
resources).
* Parameters:
* `network` - a valid IENetwork instance created by `IENetwork.from_ir()` method
* `num_requests` - a positive integer value of infer requests to be created. Number of infer requests may be limited
by device capabilities.
* `config` - a dictionary of plugin configuration keys and their values
* Return value:
None
* Usage example:
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> plugin = IEPlugin(device="CPU")
>>> exec_net = plugin.load(network=net, num_requsts=2)
>>> exec_net
<inference_engine.ie_api.ExecutableNetwork object at 0x7f5140bbcd38>
```
* `set_initial_affinity(net: IENetwork)`
* Description:
Sets initial affinity for model layers according to the HETERO plugin logic. Applicable only if
IEPlugin was initialized for HETERO device.
* Parameters:
* `net` - a valid instance of IENetwork
* Return value:
None
* Usage example:
See `affinity` attribute of the `IENetLayer` class.
* `add_cpu_extension(extension_path: str)`
* Description:
Loads extensions library to the plugin. Applicable only for CPU device and HETERO device with CPU
* Parameters:
* `extension_path` - a full path to CPU extensions library
* Return value:
None
* Usage example:
```py
>>> plugin = IEPlugin(device="CPU")
>>> plugin.add_cpu_extenstions(ext_lib_path)
```
* `set_config(config: dict)`
* Description:
Sets a configuration for the plugin. Refer to `SetConfig()` in Inference Engine C++ documentation for acceptable
keys and values list.
* Parameters:
* `config` - a dictionary of keys and values of acceptable configuration parameters
* Return value:
None
* Usage examples:
See `set_affinity` method of the `IENetwork` class.
* `get_supported_layers(net: IENetwork)`
* Description:
Returns the set of layers supported by the plugin. Please note that in case of CPU plugin support of
a layer may depends on extension loaded by `add_cpu_extenstion()` method
* Parameters:
* `net` - a valid instance of IENetwork
* Return value:
Set of layers supported by the plugin
* Usage example:
See `affinity` attribute of the `IENetLayer` class.
## <a name="executablenetwork"></a>ExecutableNetwork Class
This class represents a network instance loaded to plugin and ready for inference.
### Class Constructor
There is no explicit class constructor. To make a valid instance of `ExecutableNetwork`, use `load()` method of the `IEPlugin` class.
### Class attributes
* `requests` - a tuple of InferRequest instances
* Usage example:
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> plugin = IEPlugin(device="CPU")
>>> exec_net = plugin.load(network=net, num_requsts=2)
>>> exec_net.requests
(<inference_engine.ie_api.InferRequest object at 0x7f66f56c57e0>, <inference_engine.ie_api.InferRequest object at 0x7f66f56c58b8>, <inference_engine.ie_api.InferRequest object at 0x7f66f56c5900>)
```
### Instance Methods
* `infer(inputs=None)`
* Description:
Starts synchronous inference for the first infer request of the executable network and returns output data.
Wraps `infer()` method of the `InferRequest` class
* Parameters:
* `inputs` - a dictionary of input layer name as a key and `numpy.ndarray` of proper shape with input data for the layer as a value
* Return value:
A dictionary of output layer name as a key and `numpy.ndarray` with output data of the layer as a value
* Usage example:
```py
>>> net = IENetwork.from_ir(model=path_to_xml_file, weights=path_to_bin_file)
>>> plugin = IEPlugin(device="CPU")
>>> exec_net = plugin.load(network=net, num_requsts=2)
>>> res = exec_net.infer({'data': img})
>>> res
{'prob': array([[[[2.83426580e-08]],
[[2.40166020e-08]],
[[1.29469613e-09]],
[[2.95946148e-08]]
......
]])}
```
For illustration of input data preparation, please see samples (for example, `classification_sample.py`).
* `start_async(request_id, inputs=None)`
* Description:
Starts asynchronous inference for specified infer request.
Wraps `async_infer()` method of the `InferRequest` class
* Parameters:
* `request_id` - index of infer request to start inference
* `inputs` - a dictionary of input layer name as a key and `numpy.ndarray` of proper shape with input data for the layer as a value
* Return value:
A handler of specified infer request, which is an instance of the `InferRequest` class.
* Usage example:
```py
>>> infer_request_handle = exec_net.start_async(request_id=0, inputs={input_blob: image})
>>> infer_status = infer_request_handle.wait()
>>> res = infer_request_handle.outputs[out_blob]
```
For more details about infer requests processing, see `classification_sample_async.py` (simplified case) and
`object_detection_demo_ssd_async.py` (real synchronous use case) samples.
## <a name="inferrequest"></a>InferRequest Class
This class provides an interface to infer requests of `ExecutableNetwork` and serves to handle infer requests execution
and to set and get output data.
### Class Constructor
There is no explicit class constructor. To make a valid `InferRequest` instance, use `load()` method of the `IEPlugin`
class with specified number of requests to get `ExecutableNetwork` instance which stores infer requests.
### Class attributes
* `inputs` - a dictionary of input layer name as a key and `numpy.ndarray` of proper shape with input data for the layer as a value
* `outputs` - a dictionary of output layer name as a key and `numpy.ndarray` with output data of the layer as a value
* Usage example:
```py
>>> exec_net.requests[0].inputs['data'][:] = image
>>> exec_net.requests[0].infer()
>>> res = exec_net.requests[0].outputs['prob']
>>> np.flip(np.sort(np.squeeze(res)),0)
array([4.85416055e-01, 1.70385033e-01, 1.21873841e-01, 1.18894853e-01,
5.45198545e-02, 2.44456064e-02, 5.41366823e-03, 3.42589128e-03,
2.26027006e-03, 2.12283316e-03 ...])
```
### Instance Methods
It is not recommended to run inference directly on `InferRequest` instance.
To run inference, please use simplified methods `infer()` and `start_async()` of `ExecutableNetwork`.
* `infer(inputs=None)`
* Description:
Starts synchronous inference of the infer request and fill outputs array
* Parameters:
* `inputs` - a dictionary of input layer name as a key and `numpy.ndarray` of proper shape with input data for the layer as a value
* Return value:
None
* Usage example:
```py
>>> exec_net = plugin.load(network=net, num_requests=2)
>>> exec_net.requests[0].infer({input_blob: image})
>>> res = exec_net.requests[0].outputs['prob']
>>> np.flip(np.sort(np.squeeze(res)),0)
array([4.85416055e-01, 1.70385033e-01, 1.21873841e-01, 1.18894853e-01,
5.45198545e-02, 2.44456064e-02, 5.41366823e-03, 3.42589128e-03,
2.26027006e-03, 2.12283316e-03 ...])
```
* `async_infer(inputs=None)`
* Description:
Starts asynchronous inference of the infer request and fill outputs array
* Parameters:
* `inputs` - a dictionary of input layer name as a key and `numpy.ndarray` of proper shape with input data for the layer as a value
* Return value:
None
* Usage example:
```py
>>> exec_net = plugin.load(network=net, num_requests=2)
>>> exec_net.requests[0].async_infer({input_blob: image})
>>> exec_net.requests[0].wait()
>>> res = exec_net.requests[0].outputs['prob']
>>> np.flip(np.sort(np.squeeze(res)),0)
array([4.85416055e-01, 1.70385033e-01, 1.21873841e-01, 1.18894853e-01,
5.45198545e-02, 2.44456064e-02, 5.41366823e-03, 3.42589128e-03,
2.26027006e-03, 2.12283316e-03 ...])
```
* `wait(timeout=-1)`
* Description:
Waits for the result to become available. Blocks until specified timeout elapses or the result
becomes available, whichever comes first.
**Note:**
There are special values of the timeout parameter:
* 0 - immediately returns the inference status. It does not block or interrupt execution.
To find statuses meaning, please refer to InferenceEngine::StatusCode in Inference Engine C++ documentation
* -1 - waits until inference result becomes available (default value)
* Parameters:
* `timeout` - time to wait in milliseconds or special (0, -1) cases described above.
If not specified, `timeout` value is set to -1 by default.
* Usage example:
See `async_infer()` method of the the `InferRequest` class.
* `get_perf_counts()`
* Description:
Queries performance measures per layer to get feedback of what is the most time consuming layer. .
**Note**:
Performance counters data and format depends on the plugin
* Parameters:
None
* Usage example:
```py
>>> exec_net = plugin.load(network=net, num_requests=2)
>>> exec_net.requests[0].infer({input_blob: image})
>>> exec_net.requests[0].get_perf_counts()
{'Conv2D': {'exec_type': 'jit_avx2_1x1',
'real_time': 154,
'cpu_time': 154,
'status': 'EXECUTED',
'layer_type': 'Convolution'},
'Relu6': {'exec_type': 'undef',
'real_time': 0,
'cpu_time': 0,
'status': 'NOT_RUN',
'layer_type': 'Clamp'}
...
}

View File

@ -0,0 +1,69 @@
# Copyright (C) 2018 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
# If the pyx file is a C++ file, we should specify that here.
set(CMAKE_INCLUDE_CURRENT_DIR ON)
if (COPY_IE_LIBS)
if (UNIX)
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "$ORIGIN")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
endif (UNIX)
endif()
set_source_files_properties(
ie_api_impl_defs.pxd
ie_api_impl.hpp
ie_api_impl.cpp
ie_api.pyx
ie_api.pxd
PROPERTIES CYTHON_IS_CXX TRUE
)
cython_add_module(
ie_api
ie_api_impl_defs.pxd
ie_api_impl.hpp
ie_api_impl.cpp
ie_api.pyx
)
target_link_libraries(ie_api PRIVATE IE::inference_engine)
set_target_properties(ie_api PROPERTIES CXX_STANDARD 11 LINKER_LANGUAGE CXX)
#if (NOT UNIX AND ${PYTHON_VERSION_STRING} MATCHES "^1.4")
# set(python_subdir "python2.7")
#else()
# set(python_subdir "python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
#endif()
#
#
# Copy required build artifacts to structure which will be used in final package
#add_custom_command(TARGET ie_api POST_BUILD
#
# COMMAND ${CMAKE_COMMAND} -E make_directory
# ${CMAKE_SOURCE_DIR}/bin/${python_subdir}/openvino/inference_engine/
#
# COMMAND ${CMAKE_COMMAND} -E touch
# ${CMAKE_SOURCE_DIR}/bin/${python_subdir}/openvino/__init__.py)
#
#if (${WIN32})
#add_custom_command(TARGET ie_api POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy
# ${CMAKE_CURRENT_BINARY_DIR}/Release/ie_api.pyd ${CMAKE_SOURCE_DIR}/bin/${python_subdir}/openvino/inference_engine/
#
# COMMAND ${CMAKE_COMMAND} -E copy
# ${CMAKE_CURRENT_BINARY_DIR}/__init__.py ${CMAKE_SOURCE_DIR}/bin/${python_subdir}/openvino/inference_engine/)
#else()
#add_custom_command(TARGET ie_api POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy
# ${CMAKE_CURRENT_BINARY_DIR}/ie_api.so ${CMAKE_SOURCE_DIR}/bin/${python_subdir}/openvino/inference_engine/
#
# COMMAND ${CMAKE_COMMAND} -E copy
# ${CMAKE_CURRENT_BINARY_DIR}/__init__.py ${CMAKE_SOURCE_DIR}/bin/${python_subdir}/openvino/inference_engine/)
#endif()

View File

@ -0,0 +1,3 @@
from .ie_api import *
__version__ = get_version()
__all__ = ['IENetwork', "IEPlugin", "IENetReader"]

View File

@ -0,0 +1,59 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
from .cimport ie_api_impl_defs as C
from .ie_api_impl_defs cimport Blob, TensorDesc
from libcpp.string cimport string
from libcpp.vector cimport vector
from libcpp.memory cimport unique_ptr
from libcpp cimport bool
cdef class BlobBuffer:
cdef Blob.Ptr ptr
cdef char*format
cdef vector[Py_ssize_t] shape
cdef vector[Py_ssize_t] strides
cdef reset(self, Blob.Ptr &)
cdef char*_get_blob_format(self, const TensorDesc & desc)
cdef public:
total_stride, item_size
cdef class InferRequest:
cdef C.InferRequestWrap *impl
cpdef BlobBuffer _get_input_buffer(self, const string & blob_name)
cpdef BlobBuffer _get_output_buffer(self, const string & blob_name)
cpdef infer(self, inputs = ?)
cpdef async_infer(self, inputs = ?)
cpdef wait(self, timeout = ?)
cpdef get_perf_counts(self)
cdef public:
_inputs, _outputs
cdef class IENetwork:
cdef C.IENetwork impl
cdef class ExecutableNetwork:
cdef unique_ptr[C.IEExecNetwork] impl
cdef public:
_requests, async, _request_iterator
cdef class IEPlugin:
cdef C.IEPlugin impl
cpdef ExecutableNetwork load(self, IENetwork network, int num_requests = ?, config = ?)
cpdef void set_config(self, config)
cpdef void add_cpu_extension(self, str extension_path) except *
cpdef void set_initial_affinity(self, IENetwork network) except *
cpdef set get_supported_layers(self, IENetwork net)
cdef class IENetReader:
cdef C.IENetReader impl
cdef class IENetLayer:
cdef C.IENetLayer impl

View File

@ -0,0 +1,374 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
#distutils: language=c++
from cython.operator cimport dereference as deref
from .cimport ie_api_impl_defs as C
from .ie_api_impl_defs cimport Blob, TensorDesc, SizeVector, Precision
from libcpp.string cimport string
from libcpp.vector cimport vector
from libcpp.map cimport map
from libcpp.memory cimport unique_ptr
from libc.stdint cimport int64_t
import os
import numpy as np
cdef extern from "<utility>" namespace "std" nogil:
cdef unique_ptr[C.IEExecNetwork] move(unique_ptr[C.IEExecNetwork])
cdef string to_std_string(str py_string):
return py_string.encode()
cdef to_py_string(const string & std_string):
return bytes(std_string).decode()
cdef dict_to_c_map(py_dict):
cdef map[string, string] c_map
for k, v in py_dict.items():
if type(k) != str or type(v) != str:
raise TypeError("Only string keys and values are allowed!")
c_map[k.encode()] = v.encode()
return c_map
supported_precisions = ["fp32", "fp16", "q78", "i32", "i16", "i8", "u32", "u16"]
known_plugins = ['CPU', 'GPU', 'FPGA', 'MYRIAD', 'HETERO']
def get_version():
return C.get_version().decode()
cdef class IENetLayer:
@property
def name(self):
return self.impl.name.decode()
@property
def type(self):
return self.impl.type.decode()
@property
def precision(self):
return self.impl.precision.decode()
@property
def affinity(self):
return self.impl.affinity.decode()
@property
def weights(self):
cdef map[string, Blob.Ptr] c_weights_map
c_weights_map = self.impl.getWeights()
weights_map = {}
cdef BlobBuffer weights_buffer
for weights in c_weights_map:
weights_buffer = BlobBuffer()
weights_buffer.reset(weights.second)
weights_map[weights.first.decode()] = weights_buffer.to_numpy()
return weights_map
@property
def params(self):
return {k.decode(): v.decode() for k, v in self.impl.params}
@affinity.setter
def affinity(self, target_affinity):
self.impl.setAffinity(target_affinity.encode())
@params.setter
def params(self, params_map):
self.impl.setParams(dict_to_c_map(params_map))
cdef class ExecutableNetwork:
def __init__(self):
self._requests = []
def infer(self, inputs=None):
current_request = self.requests[0]
current_request.infer(inputs)
if inputs is not None:
return {k: v for k, v in current_request.outputs.items()}
def start_async(self, request_id, inputs=None):
if request_id not in list(range(len(self.requests))):
raise ValueError("Incorrect request_id specified!")
current_request = self.requests[request_id]
current_request.async_infer(inputs)
return current_request
@property
def requests(self):
return self._requests
cdef class InferRequest:
def __init__(self):
self._inputs = {}
self._outputs = {}
cpdef BlobBuffer _get_input_buffer(self, const string & blob_name):
cdef BlobBuffer buffer = BlobBuffer()
buffer.reset(deref(self.impl).getInputBlob(blob_name))
return buffer
cpdef BlobBuffer _get_output_buffer(self, const string & blob_name):
cdef BlobBuffer buffer = BlobBuffer()
buffer.reset(deref(self.impl).getOutputBlob(blob_name))
return buffer
cpdef infer(self, inputs=None):
if inputs is not None:
self._fill_inputs(inputs)
deref(self.impl).infer()
cpdef async_infer(self, inputs=None):
if inputs is not None:
self._fill_inputs(inputs)
deref(self.impl).infer_async()
cpdef wait(self, timeout=None):
if timeout is None:
timeout = -1
return deref(self.impl).wait(<int64_t> timeout)
cpdef get_perf_counts(self):
cdef map[string, C.ProfileInfo] c_profile = deref(self.impl).getPerformanceCounts()
profile = {}
for l in c_profile:
info = l.second
# TODO: add execution index. Check if unsigned int is properly converted to int in python.
profile[l.first.decode()] = {"status": info.status.decode(), "exec_type": info.exec_type.decode(),
"layer_type": info.layer_type.decode(), "real_time": info.real_time,
"cpu_time": info.cpu_time}
return profile
@property
def inputs(self):
return self._inputs
@property
def outputs(self):
return self._outputs
def _fill_inputs(self, inputs):
for k, v in inputs.items():
self.inputs[k][:] = v
cdef class IENetwork:
@property
def name(self):
name = bytes(self.impl.name)
return name.decode()
@property
def inputs(self):
return {k.decode(): v for k, v in self.impl.inputs}
@property
def outputs(self):
return [k.decode() for k in self.impl.outputs]
@property
def batch_size(self):
return self.impl.batch_size
@batch_size.setter
def batch_size(self, batch: int):
if batch <= 0:
raise AttributeError("Invalid batch size {}! Batch size should be positive integer value".format(batch))
self.impl.setBatch(batch)
self.impl.batch_size = batch
@property
def layers(self):
cdef map[string, C.IENetLayer] c_layers = <map[string, C.IENetLayer]>self.impl.getLayers()
layers = {}
cdef IENetLayer net_l = IENetLayer()
for l in c_layers:
net_l = IENetLayer()
net_l.impl = l.second
layers[l.first.decode()] = net_l
return layers
@classmethod
def from_ir(cls, model: str, weights: str):
if not os.path.isfile(model):
raise FileNotFoundError("Path to the model {} doesn't exists or it's a directory".format(model))
if not os.path.isfile(weights):
raise FileNotFoundError("Path to the weights {} doesn't exists or it's a directory".format(weights))
net_reader = IENetReader()
return net_reader.read(model, weights)
# TODO: Use enum with precision type instead of srting parameter when python2 support will not be required.
def add_outputs(self, outputs, precision="FP32"):
if precision.lower() not in supported_precisions:
raise AttributeError("Unsupported precision {}! List of supported precisions: {}".format(precision, supported_precisions))
if not isinstance(outputs, list):
outputs = [outputs]
cdef vector[string] _outputs
for l in outputs:
_outputs.push_back(l.encode())
self.impl.addOutputs(_outputs, precision.lower().encode())
def reshape(self, input_shapes: dict):
cdef map[string, vector[size_t]] c_input_shapes;
cdef vector[size_t] c_shape
net_inputs = self.inputs
for input, shape in input_shapes.items():
if input not in net_inputs:
raise AttributeError("Specified {} layer not in network inputs {}! ".format(input, net_inputs))
for v in shape:
c_shape.push_back(v)
c_input_shapes[input.encode()] = c_shape
self.impl.reshape(c_input_shapes)
cdef class IEPlugin:
def __cinit__(self, device: str, plugin_dirs=None):
plugin_base = device.split(':')[0]
if plugin_base not in known_plugins:
raise ValueError("Unknown plugin: {}, expected one of: {}"
.format(plugin_base, ",".join(known_plugins)))
if plugin_dirs is None:
plugin_dirs = [""]
elif isinstance(plugin_dirs, str):
plugin_dirs = [plugin_dirs]
# add package directory to plugin_dirs
lib_location = os.path.dirname(os.path.realpath(__file__))
plugin_dirs.append(lib_location)
cpdef string device_ = <string> device.encode()
cdef vector[string] dirs_
for d in plugin_dirs:
dirs_.push_back(<string> d.encode())
self.impl = C.IEPlugin(device_, dirs_)
cpdef ExecutableNetwork load(self, IENetwork network, int num_requests=1, config=None):
if num_requests <= 0:
raise ValueError("Incorrect number of requests specified: {}. Expected positive integer number.".format(num_requests))
cdef ExecutableNetwork exec_net = ExecutableNetwork()
cdef vector[string] inputs_list
cdef vector[string] outputs_list
cdef map[string, string] c_config
if config:
for k, v in config.items():
c_config[to_std_string(k)] = to_std_string(v)
exec_net.impl = move(self.impl.load(network.impl, num_requests, c_config))
requests = []
for i in range(deref(exec_net.impl).infer_requests.size()):
infer_request = InferRequest()
infer_request.impl = &(deref(exec_net.impl).infer_requests[i])
inputs_list = infer_request.impl.getInputsList()
outputs_list = infer_request.impl.getOutputsList()
for input_b in inputs_list:
input_s = input_b.decode()
infer_request._inputs[input_s] = infer_request._get_input_buffer(input_b).to_numpy()
for output_b in outputs_list:
output_s = output_b.decode()
infer_request._outputs[output_s] = infer_request._get_output_buffer(output_b).to_numpy()
# create blob buffers
requests.append(infer_request)
exec_net._requests = tuple(requests)
return exec_net
cpdef void set_initial_affinity(self,IENetwork net) except *:
if self.device.find("HETERO") == -1:
raise RuntimeError("set_initial_affinity method applicable only for HETERO device")
self.impl.setInitialAffinity(net.impl)
cpdef set get_supported_layers(self,IENetwork net):
return set([l.decode() for l in self.impl.queryNetwork(net.impl)])
@property
def device(self):
device_name = bytes(self.impl.device_name)
return to_py_string(device_name)
@property
def version(self):
version = bytes(self.impl.version)
return version.decode()
cpdef void add_cpu_extension(self, extension_path: str) except *:
if self.device.find("CPU") == -1:
raise RuntimeError("add_cpu_extension method applicable only for CPU or HETERO devices")
cdef string extension_str = extension_path.encode()
self.impl.addCpuExtension(extension_str)
cpdef void set_config(self, config):
cdef map[string, string] c_config
for k, v in config.items():
c_config[to_std_string(k)] = to_std_string(v)
self.impl.setConfig(c_config)
cdef class IENetReader:
def read(self, model: str, weights: str) -> IENetwork:
cdef IENetwork net = IENetwork()
net.impl = self.impl.read(model.encode(), weights.encode())
return net
cdef class BlobBuffer:
"""Copy-less accessor for Inference Engine Blob"""
cdef reset(self, Blob.Ptr & ptr):
self.ptr = ptr
cdef TensorDesc desc = deref(ptr).getTensorDesc()
cdef SizeVector shape = desc.getDims()
cdef Py_ssize_t itemsize = deref(ptr).element_size()
self.strides.resize(shape.size())
self.shape.resize(shape.size())
total_stride = itemsize
# dims are in row major (C - style),
# thence strides are computed starting from latest dimension
for i in reversed(range(shape.size())):
self.strides[i] = total_stride
self.shape[i] = shape[i]
total_stride *= shape[i]
self.total_stride = total_stride
self.format = self._get_blob_format(desc)
self.item_size = itemsize
def __getbuffer__(self, Py_buffer *buffer, int flags):
buffer.buf = C.get_buffer[char](deref(self.ptr))
buffer.format = self.format
buffer.internal = NULL
buffer.itemsize = self.item_size
buffer.len = self.total_stride
buffer.ndim = self.shape.size()
buffer.obj = self
buffer.readonly = 0
buffer.shape = self.shape.data()
buffer.strides = self.strides.data()
buffer.suboffsets = NULL
cdef char*_get_blob_format(self, const TensorDesc & desc):
cdef Precision precision = desc.getPrecision()
name = bytes(precision.name()).decode()
# todo: half floats
precision_to_format = {
'FP32': 'f', # float
'FP16': 'h', # signed short
'Q78': 'h', # signed short
'I16': 'h', # signed short
'U8': 'B', # unsigned char
'I8': 'b', # signed char
'U16': 'H', # unsigned short
'I32': 'i' # signed int
}
if name not in precision_to_format:
raise ValueError("Unknown Blob precision: {}".format(name))
return precision_to_format[name].encode()
def to_numpy(self):
return np.asarray(self)

View File

@ -0,0 +1,349 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
#include "ie_api_impl.hpp"
#include "hetero/hetero_plugin_config.hpp"
#include "ie_iinfer_request.hpp"
#define stringify( name ) # name
#define IE_CHECK_CALL(expr) { \
auto ret = (expr); \
if (ret != InferenceEngine::StatusCode::OK) { \
THROW_IE_EXCEPTION << response.msg; \
} \
} \
InferenceEnginePython::IENetwork InferenceEnginePython::IENetReader::read(std::string const &model,
std::string const &weights)
{
InferenceEngine::CNNNetReader net_reader;
net_reader.ReadNetwork(model);
net_reader.ReadWeights(weights);
const std::string &net_name = net_reader.getName();
std::map<std::string, std::vector<size_t>> inputs;
const InferenceEngine::InputsDataMap &inputsInfo = net_reader.getNetwork().getInputsInfo();
for (auto &item : inputsInfo)
{
const InferenceEngine::TensorDesc &inputTensorDesc = item.second->getTensorDesc();
InferenceEngine::SizeVector dims = inputTensorDesc.getDims();
inputs[item.first] = dims;
}
// TODO: store output shapes for each output
std::vector<std::string> outputs;
const InferenceEngine::OutputsDataMap &outputsInfo = net_reader.getNetwork().getOutputsInfo();
for (auto &item : outputsInfo)
{
outputs.push_back(item.first);
}
InferenceEngine::CNNNetwork network = net_reader.getNetwork();
std::size_t batch_size = network.getBatchSize();
return {network, net_name, batch_size, inputs, outputs};
}
std::map<std::string, InferenceEnginePython::IENetLayer> InferenceEnginePython::IENetwork::getLayers()
{
std::map<std::string, InferenceEnginePython::IENetLayer> result;
std::unordered_set<std::string> visisted;
const InferenceEngine::InputsDataMap &networkInputs = actual.getInputsInfo();
using CNNLayerPtrCref = const InferenceEngine::CNNLayerPtr &;
std::function<void(CNNLayerPtrCref)> DFS = [&](CNNLayerPtrCref layer) {
InferenceEnginePython::IENetLayer layer_info;
/* Assumes no cycles in graph */
for (auto &od : layer->outData)
{
for (auto nl : od->getInputTo())
{
auto i = visisted.find(nl.second->name);
if (i != visisted.end())
{
continue;
}
DFS(nl.second);
}
}
visisted.emplace(layer->name);
layer_info.layer_ptr = layer;
layer_info.name = layer->name;
layer_info.type = layer->type;
std::string precision = layer->precision.name();
layer_info.precision = precision;
layer_info.params = layer->params;
layer_info.affinity = layer->affinity;
result[layer->name] = layer_info;
};
std::set<InferenceEngine::CNNLayerPtr> inputs;
for (auto input : networkInputs) {
for (auto l : input.second->getInputData()->inputTo) {
inputs.insert(l.second);
}
}
for (auto &layer : inputs)
{
DFS(layer);
}
return result;
}
void InferenceEnginePython::IENetwork::addOutputs(const std::vector<std::string> & out_layers, const std::string &precision)
{
std::map <std::string,InferenceEngine::Precision> precision_map = {{"fp32", InferenceEngine::Precision::FP32},
{"fp16", InferenceEngine::Precision::FP16},
{"q78", InferenceEngine::Precision::Q78},
{"i32", InferenceEngine::Precision::I32},
{"i16", InferenceEngine::Precision::I16},
{"i8", InferenceEngine::Precision::I8},
{"u16", InferenceEngine::Precision::U16},
{"u8", InferenceEngine::Precision::U8}};
for (auto && l : out_layers)
{
InferenceEngine::OutputsDataMap outputsDataMap = actual.getOutputsInfo();
if (outputsDataMap.find(l) != outputsDataMap.end())
{
continue;
}
InferenceEngine::CNNLayerPtr cnnLayer = actual.getLayerByName(l.c_str());
std::vector<InferenceEngine::DataPtr> outData = cnnLayer->outData;
if (outData.size() != 1) {
std::cout << "Layer " << l << " has " << outData.size() << " output blobs and can not be set as output." << std::endl;
continue;
}
actual.addOutput(l);
InferenceEngine::OutputsDataMap outputsDataMapUpd = actual.getOutputsInfo();
outputsDataMapUpd[l]->setPrecision(precision_map[precision]);
outputs.push_back(l);
}
}
void InferenceEnginePython::IENetwork::setBatch(const size_t size)
{
actual.setBatchSize(size);
const InferenceEngine::InputsDataMap &inputsInfo = actual.getInputsInfo();
for (auto &item : inputsInfo)
{
const InferenceEngine::TensorDesc &inputTensorDesc = item.second->getTensorDesc();
InferenceEngine::SizeVector dims = inputTensorDesc.getDims();
inputs[item.first] = dims;
}
}
void InferenceEnginePython::IENetwork::reshape(const std::map<std::string, std::vector<size_t>> & input_shapes){
actual.reshape(input_shapes);
const InferenceEngine::InputsDataMap &inputsInfo = actual.getInputsInfo();
for (auto &item : inputsInfo)
{
const InferenceEngine::TensorDesc &inputTensorDesc = item.second->getTensorDesc();
InferenceEngine::SizeVector dims = inputTensorDesc.getDims();
inputs[item.first] = dims;
}
}
InferenceEnginePython::IEPlugin::IEPlugin(const std::string &device, const std::vector<std::string> &plugin_dirs)
{
InferenceEngine::PluginDispatcher dispatcher{plugin_dirs};
actual = dispatcher.getPluginByDevice(device);
const InferenceEngine::Version *pluginVersion;
actual->GetVersion(pluginVersion);
version = std::to_string(pluginVersion->apiVersion.major) + ".";
version += std::to_string(pluginVersion->apiVersion.minor) + ".";
version += pluginVersion->buildNumber;
device_name = device;
}
void InferenceEnginePython::IEPlugin::setInitialAffinity(InferenceEnginePython::IENetwork &net)
{
InferenceEngine::HeteroPluginPtr hetero_plugin(actual);
InferenceEngine::ResponseDesc response;
auto &network = net.actual;
IE_CHECK_CALL(hetero_plugin->SetAffinity(network, {}, &response));
}
std::set<std::string> InferenceEnginePython::IEPlugin::queryNetwork(InferenceEnginePython::IENetwork &net)
{
InferenceEngine::CNNNetwork &network = net.actual;
InferenceEngine::QueryNetworkResult queryRes;
actual->QueryNetwork(network, queryRes);
return queryRes.supportedLayers;
}
void InferenceEnginePython::IENetLayer::setAffinity(const std::string & target_affinity){
layer_ptr->affinity = target_affinity;
}
void InferenceEnginePython::IENetLayer::setParams(const std::map<std::string, std::string> & params_map){
layer_ptr->params = params_map;
}
std::map<std::string, InferenceEngine::Blob::Ptr> InferenceEnginePython::IENetLayer::getWeights(){
auto w_layer = std::dynamic_pointer_cast<InferenceEngine::WeightableLayer>(layer_ptr);
// IF current layer is weightable gather weights and biases from casted WeightableLayer and all other blobs
// considered as custom and gathered from blobs field pf CNNLayer.
std::map<std::string, InferenceEngine::Blob::Ptr> weights;
if (w_layer != nullptr){
if (w_layer->_weights != nullptr){
weights["weights"] = w_layer->_weights;
}
if (w_layer->_biases != nullptr){
weights["biases"] = w_layer->_biases;
}
for (auto it : w_layer->blobs){
if (it.first == "weights" || it.first == "biases"){
continue;
}
weights[it.first] = it.second;
}
}
// Otherwise all layer's blobs are considered as custom and gathered from CNNLayer
else {
std::map<std::string, InferenceEngine::Blob::Ptr> map_placeholder;
weights = map_placeholder; // If layer has no blobs it should not be missed from weights map
for (auto it : layer_ptr->blobs){
weights[it.first] = it.second;
}
}
return weights;
}
void InferenceEnginePython::IEPlugin::addCpuExtension(const std::string &extension_path)
{
InferenceEngine::ResponseDesc response;
auto extension_ptr = InferenceEngine::make_so_pointer<InferenceEngine::IExtension>(extension_path);
auto extension = std::dynamic_pointer_cast<InferenceEngine::IExtension>(extension_ptr);
IE_CHECK_CALL(actual->AddExtension(extension, &response))
}
std::unique_ptr<InferenceEnginePython::IEExecNetwork>
InferenceEnginePython::IEPlugin::load(InferenceEnginePython::IENetwork &net,
int num_requests,
const std::map<std::string, std::string> &config)
{
InferenceEngine::ResponseDesc response;
auto exec_network = InferenceEnginePython::make_unique<InferenceEnginePython::IEExecNetwork>(net.name, num_requests);
IE_CHECK_CALL(actual->LoadNetwork(exec_network->actual, net.actual, config, &response))
const InferenceEngine::InputsDataMap &inputs_info = net.actual.getInputsInfo();
const InferenceEngine::OutputsDataMap &outputs_info = net.actual.getOutputsInfo();
for (size_t i = 0; i < num_requests; ++i) {
InferRequestWrap &infer_request = exec_network->infer_requests[i];
IE_CHECK_CALL(exec_network->actual->CreateInferRequest(infer_request.request_ptr, &response))
for (const auto& input : inputs_info) {
infer_request.inputs[input.first] = nullptr;
infer_request.request_ptr->GetBlob(input.first.c_str(), infer_request.inputs[input.first], &response);
}
for (const auto& output : outputs_info) {
infer_request.request_ptr->GetBlob(output.first.c_str(), infer_request.outputs[output.first], &response);
}
}
return exec_network;
}
void InferenceEnginePython::IEPlugin::setConfig(const std::map<std::string, std::string> & config) {
InferenceEngine::ResponseDesc response;
IE_CHECK_CALL(actual->SetConfig(config, &response))
}
InferenceEnginePython::IEExecNetwork::IEExecNetwork(const std::string &name, size_t num_requests) :
infer_requests(num_requests), name(name)
{
}
void InferenceEnginePython::IEExecNetwork::infer()
{
InferenceEngine::ResponseDesc response;
InferRequestWrap &request = infer_requests[0];
request.request_ptr->Infer(&response);
}
InferenceEngine::Blob::Ptr &InferenceEnginePython::InferRequestWrap::getInputBlob(const std::string &blob_name)
{
return inputs.at(blob_name);
}
InferenceEngine::Blob::Ptr &InferenceEnginePython::InferRequestWrap::getOutputBlob(const std::string &blob_name)
{
return outputs.at(blob_name);
}
std::vector<std::string> InferenceEnginePython::InferRequestWrap::getInputsList() {
std::vector<std::string> inputs_list;
inputs_list.reserve(inputs.size());
std::transform(inputs.begin(), inputs.end(), std::back_inserter(inputs_list), [] (InferenceEngine::BlobMap::value_type it) -> std::string {
return it.first;
});
return inputs_list;
}
std::vector<std::string> InferenceEnginePython::InferRequestWrap::getOutputsList() {
std::vector<std::string> outputs_list;
outputs_list.reserve(inputs.size());
std::transform(outputs.begin(), outputs.end(), std::back_inserter(outputs_list), [] (InferenceEngine::BlobMap::value_type it) -> std::string {
return it.first;
});
return outputs_list;
}
void InferenceEnginePython::InferRequestWrap::infer() {
InferenceEngine::ResponseDesc responseDesc;
request_ptr->Infer(&responseDesc);
}
void InferenceEnginePython::InferRequestWrap::infer_async() {
InferenceEngine::ResponseDesc responseDesc;
request_ptr->StartAsync(&responseDesc);
}
int InferenceEnginePython::InferRequestWrap::wait(int64_t timeout) {
InferenceEngine::ResponseDesc responseDesc;
InferenceEngine::StatusCode code = request_ptr->Wait(timeout, &responseDesc);
return static_cast<int >(code);
}
std::map<std::string, InferenceEnginePython::ProfileInfo> InferenceEnginePython::InferRequestWrap::getPerformanceCounts(){
std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> perf_counts;
InferenceEngine::ResponseDesc response;
request_ptr->GetPerformanceCounts(perf_counts, &response);
std::map<std::string, InferenceEnginePython::ProfileInfo> perf_map;
for (auto it : perf_counts){
InferenceEnginePython::ProfileInfo profile_info;
switch (it.second.status) {
case InferenceEngine::InferenceEngineProfileInfo::EXECUTED:
profile_info.status = "EXECUTED";
break;
case InferenceEngine::InferenceEngineProfileInfo::NOT_RUN:
profile_info.status = "NOT_RUN";
break;
case InferenceEngine::InferenceEngineProfileInfo::OPTIMIZED_OUT:
profile_info.status = "OPTIMIZED_OUT";
break;
default:
profile_info.status = "UNKNOWN";
}
profile_info.exec_type = it.second.exec_type;
profile_info.layer_type = it.second.layer_type;
profile_info.cpu_time = it.second.cpu_uSec;
profile_info.real_time = it.second.realTime_uSec;
perf_map[it.first] = profile_info;
}
return perf_map;
}
std::string InferenceEnginePython::get_version() {
auto version = InferenceEngine::GetInferenceEngineVersion();
std::string version_str = std::to_string(version->apiVersion.major) + ".";
version_str += std::to_string(version->apiVersion.minor) + ".";
version_str += version->buildNumber;
return version_str;
}

View File

@ -0,0 +1,124 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef INFERENCE_ENGINE_DRIVER_IE_API_IMPL_HPP
#define INFERENCE_ENGINE_DRIVER_IE_API_IMPL_HPP
#include <string>
#include <inference_engine.hpp>
#include <iterator>
#include <iostream>
#include <algorithm>
#include <sstream>
#include "ie_extension.h"
namespace InferenceEnginePython {
//struct BlobInfo {
// int layout;
// std::vector<std::size_t> dims;
// std::string name;
// std::vector<std::string> inputTo;
//};
struct IENetLayer {
InferenceEngine::CNNLayerPtr layer_ptr;
std::string name;
std::string type;
std::string precision;
std::string affinity;
std::map<std::string, std::string> params;
// std::map<std::string, InferenceEnginePython::BlobInfo> blob_info;
// std::map<std::string, InferenceEngine::Blob::Ptr> weights;
void setAffinity(const std::string & target_affinity);
void setParams(const std::map<std::string, std::string> & params_map);
std::map<std::string, InferenceEngine::Blob::Ptr> getWeights();
};
struct ProfileInfo {
std::string status;
std::string exec_type;
std::string layer_type;
long long real_time;
long long cpu_time;
unsigned execution_index;
};
struct IENetwork {
InferenceEngine::CNNNetwork actual;
std::string name;
std::size_t batch_size;
std::map<std::string, std::vector<size_t>> inputs;
std::vector<std::string> outputs;
void setPrecision() {
InferenceEngine::CNNNetwork one;
InferenceEngine::CNNNetwork second(std::move(one));
}
void setBatch(const size_t size);
void addOutputs(const std::vector<std::string> &out_layers, const std::string &precision);
std::map<std::string, InferenceEnginePython::IENetLayer> getLayers();
void reshape(const std::map<std::string, std::vector<size_t>> & input_shapes);
};
struct IENetReader {
static IENetwork read(std::string const &model, std::string const &weights);
std::vector<std::pair<std::string, std::string>> getLayers();
};
struct InferRequestWrap {
InferenceEngine::IInferRequest::Ptr request_ptr;
InferenceEngine::BlobMap inputs;
InferenceEngine::BlobMap outputs;
void infer();
void infer_async();
int wait(int64_t timeout);
InferenceEngine::Blob::Ptr &getInputBlob(const std::string &blob_name);
InferenceEngine::Blob::Ptr &getOutputBlob(const std::string &blob_name);
std::vector<std::string> getInputsList();
std::vector<std::string> getOutputsList();
std::map<std::string, InferenceEnginePython::ProfileInfo> getPerformanceCounts();
};
struct IEExecNetwork {
InferenceEngine::IExecutableNetwork::Ptr actual;
std::vector<InferRequestWrap> infer_requests;
IEExecNetwork(const std::string &name, size_t num_requests);
std::string name;
int next_req_index = 0;
bool async;
void infer();
};
struct IEPlugin {
std::unique_ptr<InferenceEnginePython::IEExecNetwork> load(InferenceEnginePython::IENetwork &net,
int num_requests,
const std::map<std::string,std::string> &config);
std::string device_name;
std::string version;
void setConfig(const std::map<std::string, std::string> &);
void addCpuExtension(const std::string &extension_path);
void setInitialAffinity(InferenceEnginePython::IENetwork &net);
IEPlugin(const std::string &device, const std::vector<std::string> &plugin_dirs);
IEPlugin() = default;
std::set<std::string> queryNetwork(InferenceEnginePython::IENetwork &net);
InferenceEngine::InferenceEnginePluginPtr actual;
};
template<class T>
T* get_buffer(InferenceEngine::Blob& blob) {
return blob.buffer().as<T *>();
}
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
std::string get_version();
}; // InferenceEnginePython
#endif //INFERENCE_ENGINE_DRIVER_IE_API_IMPL_HPP

View File

@ -0,0 +1,108 @@
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
from libc.stddef cimport size_t
from libcpp.string cimport string
from libcpp.vector cimport vector
from libcpp.map cimport map
from libcpp.set cimport set
from libcpp.pair cimport pair
from libcpp.memory cimport unique_ptr, shared_ptr
from libcpp cimport bool
from libc.stdint cimport int64_t
cdef extern from "<inference_engine.hpp>" namespace "InferenceEngine":
ctypedef vector[size_t] SizeVector
cdef cppclass TensorDesc:
SizeVector& getDims()
const Precision& getPrecision() const
cdef cppclass Blob:
ctypedef shared_ptr[Blob] Ptr
const TensorDesc& getTensorDesc() const
size_t element_size() const
cdef cppclass Precision:
const char* name() const
cdef extern from "ie_api_impl.hpp" namespace "InferenceEnginePython":
cdef cppclass IENetLayer:
string name
string type
string precision
string affinity
map[string, string] params
# map[string, BlobInfo] blob_info
# map[string, Blob.Ptr] weights;
void setAffinity(const string & target_affinity) except +
void setParams(const map[string, string] & params_map) except +
map[string, Blob.Ptr] getWeights() except +
# cdef cppclass BlobInfo:
# int layout
# vector[size_t] dims
# string name
# vector[string] inputTo
cdef cppclass ProfileInfo:
string status
string exec_type
string layer_type
long long real_time
long long cpu_time
unsigned int execution_index
cdef cppclass WeightsInfo:
Blob.Ptr &weights;
Blob.Ptr &biases;
map[string, Blob.Ptr] custom_blobs;
cdef cppclass IEExecNetwork:
vector[InferRequestWrap] infer_requests
cdef cppclass IENetwork:
string name
size_t batch_size
map[string, vector[size_t]] inputs
vector[string] outputs
map[string, IENetLayer] getLayers() except +
void addOutputs(vector[string] &, string &) except +
void setAffinity(map[string, string] &types_affinity_map, map[string, string] &layers_affinity_map) except +
void setBatch(size_t size) except +
void setLayerParams(map[string, map[string, string]] params_map) except +
void reshape(map[string, vector[size_t]] input_shapes) except +
cdef cppclass IEPlugin:
IEPlugin() except +
IEPlugin(const string &, const vector[string] &) except +
unique_ptr[IEExecNetwork] load(IENetwork & net, int num_requests, const map[string, string]& config) except +
void addCpuExtension(const string &) except +
void setConfig(const map[string, string]&) except +
void setInitialAffinity(IENetwork & net) except +
set[string] queryNetwork(const IENetwork &net) except +
string device_name
string version
cdef cppclass IENetReader:
IENetwork read(const string &, const string &) except +
cdef cppclass InferRequestWrap:
vector[string] getInputsList() except +
vector[string] getOutputsList() except +
Blob.Ptr& getOutputBlob(const string &blob_name) except +
Blob.Ptr& getInputBlob(const string &blob_name) except +
map[string, ProfileInfo] getPerformanceCounts() except +
void infer() except +
void infer_async() except +
int wait(int64_t timeout) except +
cdef T* get_buffer[T](Blob &)
cdef string get_version()

View File

@ -0,0 +1,3 @@
opencv-python
numpy
cython

View File

@ -0,0 +1,112 @@
#!/usr/bin/env python
"""
Copyright (c) 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import print_function
import sys
import os
from argparse import ArgumentParser
import cv2
import numpy as np
import logging as log
from openvino.inference_engine import IENetwork, IEPlugin
def build_argparser():
parser = ArgumentParser()
parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str)
parser.add_argument("-i", "--input", help="Path to a folder with images or path to an image files", required=True,
type=str)
parser.add_argument("-l", "--cpu_extension",
help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels "
"impl.", type=str, default=None)
parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None)
parser.add_argument("-d", "--device",
help="Specify hetero plugin configuration; e.g. HETERO:FPGA,CPU", default="HETERO:CPU,GPU",
type=str)
parser.add_argument("-nt", "--number_top", help="Number of top results", default=10, type=int)
return parser
def main():
log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
args = build_argparser().parse_args()
assert args.device.split(':')[0] == "HETERO", "This sample supports only Hetero Plugin. " \
"Please specify correct device, e.g. HETERO:FPGA,CPU"
model_xml = args.model
model_bin = os.path.splitext(model_xml)[0] + ".bin"
# Plugin initialization for specified device and load extensions library if specified
plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir)
if args.cpu_extension and 'CPU' in args.device:
plugin.add_cpu_extension(args.cpu_extension)
# Read IR
net = IENetwork.from_ir(model=model_xml, weights=model_bin)
if "CPU" in plugin.device:
supported_layers = plugin.get_supported_layers(net)
not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers]
if len(not_supported_layers) != 0:
log.error("Following layers are not supported by the plugin for specified device {}:\n {}".
format(plugin.device, ', '.join(not_supported_layers)))
log.error("Please try to specify cpu extensions library path in sample's command line parameters using -l "
"or --cpu_extension command line argument")
sys.exit(1)
net_ops = set([l.type for l in net.layers.values()])
if not any([op == "Convolution" for op in net_ops]):
log.warning("Specified IR doesn't contain any Convolution operations for which affinity going to be set.\n"
"Try to use another topology to make the affinity setting result more visible.")
# Configure the plugin to initialize default affinity for network in set_initial_affinity() function.
plugin.set_config({"TARGET_FALLBACK": args.device.split(':')[1]})
# Enable graph visualization
plugin.set_config({"HETERO_DUMP_GRAPH_DOT": "YES"})
plugin.set_initial_affinity(net)
for l in net.layers.values():
if l.type == "Convolution":
l.affinity = "GPU"
assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
assert len(net.outputs) == 1, "Sample supports only single output topologies"
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
# Read and pre-process input image
n, c, h, w = net.inputs[input_blob]
image = cv2.imread(args.input)
image = cv2.resize(image, (w, h))
image = image.transpose((2, 0, 1)) # Change data layout from HWC to CHW
image = image.reshape((n, c, h, w))
# Load network to the plugin
exec_net = plugin.load(network=net)
del net
# Start sync inference
res = exec_net.infer(inputs={input_blob: image})
top_ind = np.argsort(res[out_blob], axis=1)[0, -args.number_top:][::-1]
for i in top_ind:
log.info("%f #%d" % (res[out_blob][0, i], i))
del exec_net
del plugin
cwd = os.getcwd()
log.info(
"Graphs representing default and resulting affinities dumped to {} and {} files respectively"
.format(os.path.join(cwd, 'hetero_affinity.dot'), os.path.join(cwd, 'hetero_subgraphs.dot'))
)
if __name__ == '__main__':
sys.exit(main() or 0)

View File

@ -0,0 +1,137 @@
#!/usr/bin/env python
"""
Copyright (c) 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import print_function
import sys
import os
from argparse import ArgumentParser
import cv2
import numpy as np
import logging as log
from time import time
from openvino.inference_engine import IENetwork, IEPlugin
def build_argparser():
parser = ArgumentParser()
parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str)
parser.add_argument("-i", "--input", help="Path to a folder with images or path to an image files", required=True,
type=str, nargs="+")
parser.add_argument("-l", "--cpu_extension",
help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels "
"impl.", type=str, default=None)
parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None)
parser.add_argument("-d", "--device",
help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Sample "
"will look for a suitable plugin for device specified (CPU by default)", default="CPU",
type=str)
parser.add_argument("--labels", help="Labels mapping file", default=None, type=str)
parser.add_argument("-nt", "--number_top", help="Number of top results", default=10, type=int)
parser.add_argument("-ni", "--number_iter", help="Number of inference iterations", default=1, type=int)
parser.add_argument("-pc", "--perf_counts", help="Report performance counters", default=False, action="store_true")
return parser
def main():
log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
args = build_argparser().parse_args()
model_xml = args.model
model_bin = os.path.splitext(model_xml)[0] + ".bin"
# Plugin initialization for specified device and load extensions library if specified
plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir)
if args.cpu_extension and 'CPU' in args.device:
plugin.add_cpu_extension(args.cpu_extension)
# Read IR
log.info("Loading network files:\n\t{}\n\t{}".format(model_xml, model_bin))
net = IENetwork.from_ir(model=model_xml, weights=model_bin)
if "CPU" in plugin.device:
supported_layers = plugin.get_supported_layers(net)
not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers]
if len(not_supported_layers) != 0:
log.error("Following layers are not supported by the plugin for specified device {}:\n {}".
format(plugin.device, ', '.join(not_supported_layers)))
log.error("Please try to specify cpu extensions library path in sample's command line parameters using -l "
"or --cpu_extension command line argument")
sys.exit(1)
assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
assert len(net.outputs) == 1, "Sample supports only single output topologies"
log.info("Preparing input blobs")
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
net.batch_size = len(args.input)
# Read and pre-process input images
n, c, h, w = net.inputs[input_blob]
images = np.ndarray(shape=(n, c, h, w))
for i in range(n):
image = cv2.imread(args.input[i])
if image.shape[:-1] != (h, w):
log.warning("Image {} is resized from {} to {}".format(args.input[i], image.shape[:-1], (h, w)))
image = cv2.resize(image, (w, h))
image = image.transpose((2, 0, 1)) # Change data layout from HWC to CHW
images[i] = image
log.info("Batch size is {}".format(n))
# Loading model to the plugin
log.info("Loading model to the plugin")
exec_net = plugin.load(network=net)
del net
# Start sync inference
log.info("Starting inference ({} iterations)".format(args.number_iter))
infer_time = []
for i in range(args.number_iter):
t0 = time()
res = exec_net.infer(inputs={input_blob: images})
infer_time.append((time()-t0)*1000)
log.info("Average running time of one iteration: {} ms".format(np.average(np.asarray(infer_time))))
if args.perf_counts:
perf_counts = exec_net.requests[0].get_perf_counts()
log.info("Performance counters:")
print("{:<70} {:<15} {:<15} {:<15} {:<10}".format('name', 'layer_type', 'exet_type', 'status', 'real_time, us'))
for layer, stats in perf_counts.items():
print ("{:<70} {:<15} {:<15} {:<15} {:<10}".format(layer, stats['layer_type'], stats['exec_type'],
stats['status'], stats['real_time']))
# Processing output blob
log.info("Processing output blob")
res = res[out_blob]
log.info("Top {} results: ".format(args.number_top))
if args.labels:
with open(args.labels, 'r') as f:
labels_map = [x.split(sep=' ', maxsplit=1)[-1].strip() for x in f]
else:
labels_map = None
for i, probs in enumerate(res):
probs = np.squeeze(probs)
top_ind = np.argsort(probs)[-args.number_top:][::-1]
print("Image {}\n".format(args.input[i]))
for id in top_ind:
det_label = labels_map[id] if labels_map else "#{}".format(id)
print("{:.7f} label {}".format(probs[id], det_label))
print("\n")
del exec_net
del plugin
if __name__ == '__main__':
sys.exit(main() or 0)

View File

@ -0,0 +1,136 @@
#!/usr/bin/env python
"""
Copyright (c) 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import print_function
import sys
import os
from argparse import ArgumentParser
import cv2
import numpy as np
import logging as log
from time import time
from openvino.inference_engine import IENetwork, IEPlugin
def build_argparser():
parser = ArgumentParser()
parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str)
parser.add_argument("-i", "--input", help="Path to a folder with images or path to an image files", required=True,
type=str, nargs="+")
parser.add_argument("-l", "--cpu_extension",
help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels "
"impl.", type=str, default=None)
parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None)
parser.add_argument("-d", "--device",
help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Sample "
"will look for a suitable plugin for device specified (CPU by default)", default="CPU",
type=str)
parser.add_argument("--labels", help="Labels mapping file", default=None, type=str)
parser.add_argument("-nt", "--number_top", help="Number of top results", default=10, type=int)
parser.add_argument("-ni", "--number_iter", help="Number of inference iterations", default=1, type=int)
parser.add_argument("-pc", "--perf_counts", help="Report performance counters", default=False, action="store_true")
return parser
def main():
log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
args = build_argparser().parse_args()
model_xml = args.model
model_bin = os.path.splitext(model_xml)[0] + ".bin"
# Plugin initialization for specified device and load extensions library if specified
plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir)
if args.cpu_extension and 'CPU' in args.device:
plugin.add_cpu_extension(args.cpu_extension)
# Read IR
log.info("Loading network files:\n\t{}\n\t{}".format(model_xml, model_bin))
net = IENetwork.from_ir(model=model_xml, weights=model_bin)
if "CPU" in plugin.device:
supported_layers = plugin.get_supported_layers(net)
not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers]
if len(not_supported_layers) != 0:
log.error("Following layers are not supported by the plugin for specified device {}:\n {}".
format(plugin.device, ', '.join(not_supported_layers)))
log.error("Please try to specify cpu extensions library path in sample's command line parameters using -l "
"or --cpu_extension command line argument")
sys.exit(1)
assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
assert len(net.outputs) == 1, "Sample supports only single output topologies"
log.info("Preparing input blobs")
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
net.batch_size = len(args.input)
# Read and pre-process input images
n, c, h, w = net.inputs[input_blob]
images = np.ndarray(shape=(n, c, h, w))
for i in range(n):
image = cv2.imread(args.input[i])
if image.shape[:-1] != (h, w):
log.warning("Image {} is resized from {} to {}".format(args.input[i], image.shape[:-1], (h, w)))
image = cv2.resize(image, (w, h))
image = image.transpose((2, 0, 1)) # Change data layout from HWC to CHW
images[i] = image
log.info("Batch size is {}".format(n))
# Loading model to the plugin
log.info("Loading model to the plugin")
exec_net = plugin.load(network=net)
del net
# Start sync inference
log.info("Starting inference ({} iterations)".format(args.number_iter))
infer_time = []
for i in range(args.number_iter):
t0 = time()
infer_request_handle = exec_net.start_async(request_id=0, inputs={input_blob: images})
infer_request_handle.wait()
infer_time.append((time() - t0) * 1000)
log.info("Average running time of one iteration: {} ms".format(np.average(np.asarray(infer_time))))
if args.perf_counts:
perf_counts = infer_request_handle.get_perf_counts()
log.info("Performance counters:")
print ("{:<70} {:<15} {:<15} {:<15} {:<10}".format('name', 'layer_type', 'exet_type', 'status', 'real_time, us'))
for layer, stats in perf_counts.items():
print ("{:<70} {:<15} {:<15} {:<15} {:<10}".format(layer, stats['layer_type'], stats['exec_type'],
stats['status'], stats['real_time']))
# Processing output blob
log.info("Processing output blob")
res = infer_request_handle.outputs[out_blob]
log.info("Top {} results: ".format(args.number_top))
if args.labels:
with open(args.labels, 'r') as f:
labels_map = [x.split(sep=' ', maxsplit=1)[-1].strip() for x in f]
else:
labels_map = None
for i, probs in enumerate(res):
probs = np.squeeze(probs)
top_ind = np.argsort(probs)[-args.number_top:][::-1]
print("Image {}\n".format(args.input[i]))
for id in top_ind:
det_label = labels_map[id] if labels_map else "#{}".format(id)
print("{:.7f} {}".format(probs[id], det_label))
print("\n")
del exec_net
del plugin
if __name__ == '__main__':
sys.exit(main() or 0)

View File

@ -0,0 +1,49 @@
# This README demonstrates use of all GreenGrass samples
# GreenGrass Classification Sample
This topic demonstrates how to build and run the GreenGrass Image Classification sample application, which does inference using image classification networks like AlexNet and GoogLeNet on on Intel® Processors, Intel® HD Graphics and Intel® FPGA.
## Running
1. Modify the "accelerator" parameter inside the sample to deploy the sample on any accelerator option of your choice(CPU/GPU/FPGA)
For CPU, please specify "CPU"
For GPU, please specify "GPU"
For FPGA, please specify "HETERO:FPGA,CPU"
2. Enable the option(s) on how output is displayed/consumed
3. Now follow the instructions listed in the Greengrass-FaaS-User-Guide.pdf to create the lambda and deploy on edge device using Greengrass
### Outputs
The application publishes top-10 results on AWS IoT Cloud every second by default. For other output consumption options, please refer to Greengrass-FaaS-User-Guide.pdf
### How it works
Upon deployment,the sample application loads a network and an image to the Inference Engine plugin. When inference is done, the application publishes results to AWS IoT Cloud
=====================================================================================================
# GreenGrass Object Detection Sample SSD
This topic demonstrates how to run the GreenGrass Object Detection SSD sample application, which does inference using object detection networks like Squeezenet-SSD on Intel® Processors, Intel® HD Graphics and Intel® FPGA.
## Running
1. Modify the "accelerator" parameter inside the sample to deploy the sample on any accelerator option of your choice(CPU/GPU/FPGA)
For CPU, please specify "CPU"
For GPU, please specify "GPU"
For FPGA, please specify "HETERO:FPGA,CPU"
2. Enable the option(s) on how output is displayed/consumed
3. Set the variable is_async_mode to 'True' for Asynchronous execution and 'False' for Synchronous execution
3. Now follow the instructions listed in the Greengrass-FaaS-User-Guide.pdf to create the lambda and deploy on edge device using Greengrass
### Outputs
The application publishes detection outputs such as class label, class confidence, and bounding box coordinates on AWS IoT Cloud every second. For other output consumption options, please refer to Greengrass-FaaS-User-Guide.pdf
### How it works
Upon deployment,the sample application loads a network and an image to the Inference Engine plugin. When inference is done, the application publishes results to AWS IoT Cloud

View File

@ -0,0 +1,176 @@
"""
BSD 3-clause "New" or "Revised" license
Copyright (C) 2018 Intel Coporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
import sys
import os
import cv2
import numpy as np
import greengrasssdk
import boto3
import timeit
import datetime
import json
from collections import OrderedDict
from openvino.inference_engine import IENetwork, IEPlugin
# Specify the delta in seconds between each report
reporting_interval = 1.0
# Parameters for IoT Cloud
enable_iot_cloud_output = True
# Parameters for Kinesis
enable_kinesis_output = False
kinesis_stream_name = ""
kinesis_partition_key = ""
kinesis_region = ""
# Parameters for S3
enable_s3_jpeg_output = False
s3_bucket_name = ""
# Parameters for jpeg output on local disk
enable_local_jpeg_output = False
# Create a Greengrass Core SDK client for publishing messages to AWS Cloud
client = greengrasssdk.client("iot-data")
# Create an S3 client for uploading files to S3
if enable_s3_jpeg_output:
s3_client = boto3.client("s3")
# Create a Kinesis client for putting records to streams
if enable_kinesis_output:
kinesis_client = boto3.client("kinesis", "us-west-2")
# Read environment variables set by Lambda function configuration
PARAM_MODEL_XML = os.environ.get("PARAM_MODEL_XML")
PARAM_INPUT_SOURCE = os.environ.get("PARAM_INPUT_SOURCE")
PARAM_DEVICE = os.environ.get("PARAM_DEVICE")
PARAM_OUTPUT_DIRECTORY = os.environ.get("PARAM_OUTPUT_DIRECTORY")
PARAM_CPU_EXTENSION_PATH = os.environ.get("PARAM_CPU_EXTENSION_PATH")
PARAM_LABELMAP_FILE = os.environ.get("PARAM_LABELMAP_FILE")
PARAM_TOPIC_NAME = os.environ.get("PARAM_TOPIC_NAME", "intel/faas/classification")
PARAM_NUM_TOP_RESULTS = int(os.environ.get("PARAM_NUM_TOP_RESULTS", "10"))
def report(res_json, frame):
now = datetime.datetime.now()
date_prefix = str(now).replace(" ", "_")
if enable_iot_cloud_output:
data = json.dumps(res_json)
client.publish(topic=PARAM_TOPIC_NAME, payload=data)
if enable_kinesis_output:
kinesis_client.put_record(StreamName=kinesis_stream_name, Data=json.dumps(res_json), PartitionKey=kinesis_partition_key)
if enable_s3_jpeg_output:
temp_image = os.path.join(PARAM_OUTPUT_DIRECTORY, "inference_result.jpeg")
cv2.imwrite(temp_image, frame)
with open(temp_image) as file:
image_contents = file.read()
s3_client.put_object(Body=image_contents, Bucket=s3_bucket_name, Key=date_prefix + ".jpeg")
if enable_local_jpeg_output:
cv2.imwrite(os.path.join(PARAM_OUTPUT_DIRECTORY, date_prefix + ".jpeg"), frame)
def greengrass_classification_sample_run():
client.publish(topic=PARAM_TOPIC_NAME, payload="OpenVINO: Initializing...")
model_bin = os.path.splitext(PARAM_MODEL_XML)[0] + ".bin"
# Plugin initialization for specified device and load extensions library if specified
plugin = IEPlugin(device=PARAM_DEVICE, plugin_dirs="")
if "CPU" in PARAM_DEVICE:
plugin.add_cpu_extension(PARAM_CPU_EXTENSION_PATH)
# Read IR
net = IENetwork.from_ir(model=PARAM_MODEL_XML, weights=model_bin)
assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
assert len(net.outputs) == 1, "Sample supports only single output topologies"
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
# Read and pre-process input image
n, c, h, w = net.inputs[input_blob]
cap = cv2.VideoCapture(PARAM_INPUT_SOURCE)
exec_net = plugin.load(network=net)
del net
client.publish(topic=PARAM_TOPIC_NAME, payload="Starting inference on %s" % PARAM_INPUT_SOURCE)
start_time = timeit.default_timer()
inf_seconds = 0.0
frame_count = 0
res_json = []
labeldata = None
if PARAM_LABELMAP_FILE is not None:
with open(PARAM_LABELMAP_FILE) as labelmap_file:
labeldata = json.load(labelmap_file)
while (cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
frameid = cap.get(cv2.CAP_PROP_POS_FRAMES)
initial_w = cap.get(3)
initial_h = cap.get(4)
in_frame = cv2.resize(frame, (w, h))
in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW
in_frame = in_frame.reshape((n, c, h, w))
# Start synchronous inference
inf_start_time = timeit.default_timer()
res = exec_net.infer(inputs={input_blob: in_frame})
inf_seconds += timeit.default_timer() - inf_start_time
top_ind = np.argsort(res[out_blob], axis=1)[0, -PARAM_NUM_TOP_RESULTS:][::-1]
# Parse detection results of the current request
res_json = OrderedDict()
res_json["Candidates"] = OrderedDict()
frame_timestamp = datetime.datetime.now()
for i in top_ind:
classlabel = labeldata[str(i)] if labeldata else str(i)
res_json["Candidates"][classlabel] = round(res[out_blob][0, i], 2)
frame_count += 1
# Measure elapsed seconds since the last report
seconds_elapsed = timeit.default_timer() - start_time
if seconds_elapsed >= reporting_interval:
res_json["timestamp"] = frame_timestamp.isoformat()
res_json["frame_id"] = int(frameid)
res_json["inference_fps"] = frame_count / inf_seconds
start_time = timeit.default_timer()
report(res_json, frame)
frame_count = 0
inf_seconds = 0.0
client.publish(topic=PARAM_TOPIC_NAME, payload="End of the input, exiting...")
del exec_net
del plugin
greengrass_classification_sample_run()
def function_handler(event, context):
client.publish(topic=PARAM_TOPIC_NAME, payload='HANDLER_CALLED!')
return

View File

@ -0,0 +1,179 @@
"""
BSD 3-clause "New" or "Revised" license
Copyright (C) 2018 Intel Coporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
import sys
import os
import cv2
import numpy as np
import greengrasssdk
import boto3
import timeit
import datetime
import json
from collections import OrderedDict
from openvino.inference_engine import IENetwork, IEPlugin
# Specify the delta in seconds between each report
reporting_interval = 1.0
# Parameters for IoT Cloud
enable_iot_cloud_output = True
# Parameters for Kinesis
enable_kinesis_output = False
kinesis_stream_name = ""
kinesis_partition_key = ""
kinesis_region = ""
# Parameters for S3
enable_s3_jpeg_output = False
s3_bucket_name = "ssd_test"
# Parameters for jpeg output on local disk
enable_local_jpeg_output = False
# Create a Greengrass Core SDK client for publishing messages to AWS Cloud
client = greengrasssdk.client("iot-data")
# Create an S3 client for uploading files to S3
if enable_s3_jpeg_output:
s3_client = boto3.client("s3")
# Create a Kinesis client for putting records to streams
if enable_kinesis_output:
kinesis_client = boto3.client("kinesis", "us-west-2")
# Read environment variables set by Lambda function configuration
PARAM_MODEL_XML = os.environ.get("PARAM_MODEL_XML")
PARAM_INPUT_SOURCE = os.environ.get("PARAM_INPUT_SOURCE")
PARAM_DEVICE = os.environ.get("PARAM_DEVICE")
PARAM_OUTPUT_DIRECTORY = os.environ.get("PARAM_OUTPUT_DIRECTORY")
PARAM_CPU_EXTENSION_PATH = os.environ.get("PARAM_CPU_EXTENSION_PATH")
PARAM_LABELMAP_FILE = os.environ.get("PARAM_LABELMAP_FILE")
PARAM_TOPIC_NAME = os.environ.get("PARAM_TOPIC_NAME", "intel/faas/ssd")
def report(res_json, frame):
now = datetime.datetime.now()
date_prefix = str(now).replace(" ", "_")
if enable_iot_cloud_output:
data = json.dumps(res_json)
client.publish(topic=PARAM_TOPIC_NAME, payload=data)
if enable_kinesis_output:
kinesis_client.put_record(StreamName=kinesis_stream_name, Data=json.dumps(res_json), PartitionKey=kinesis_partition_key)
if enable_s3_jpeg_output:
temp_image = os.path.join(PARAM_OUTPUT_DIRECTORY, "inference_result.jpeg")
cv2.imwrite(temp_image, frame)
with open(temp_image) as file:
image_contents = file.read()
s3_client.put_object(Body=image_contents, Bucket=s3_bucket_name, Key=date_prefix + ".jpeg")
if enable_local_jpeg_output:
cv2.imwrite(os.path.join(PARAM_OUTPUT_DIRECTORY, date_prefix + ".jpeg"), frame)
def greengrass_object_detection_sample_ssd_run():
client.publish(topic=PARAM_TOPIC_NAME, payload="OpenVINO: Initializing...")
model_bin = os.path.splitext(PARAM_MODEL_XML)[0] + ".bin"
# Plugin initialization for specified device and load extensions library if specified
plugin = IEPlugin(device=PARAM_DEVICE, plugin_dirs="")
if "CPU" in PARAM_DEVICE:
plugin.add_cpu_extension(PARAM_CPU_EXTENSION_PATH)
# Read IR
net = IENetwork.from_ir(model=PARAM_MODEL_XML, weights=model_bin)
assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
assert len(net.outputs) == 1, "Sample supports only single output topologies"
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
# Read and pre-process input image
n, c, h, w = net.inputs[input_blob]
cap = cv2.VideoCapture(PARAM_INPUT_SOURCE)
exec_net = plugin.load(network=net)
del net
client.publish(topic=PARAM_TOPIC_NAME, payload="Starting inference on %s" % PARAM_INPUT_SOURCE)
start_time = timeit.default_timer()
inf_seconds = 0.0
frame_count = 0
labeldata = None
if PARAM_LABELMAP_FILE is not None:
with open(PARAM_LABELMAP_FILE) as labelmap_file:
labeldata = json.load(labelmap_file)
while (cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
frameid = cap.get(cv2.CAP_PROP_POS_FRAMES)
initial_w = cap.get(3)
initial_h = cap.get(4)
in_frame = cv2.resize(frame, (w, h))
in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW
in_frame = in_frame.reshape((n, c, h, w))
# Start synchronous inference
inf_start_time = timeit.default_timer()
res = exec_net.infer(inputs={input_blob: in_frame})
inf_seconds += timeit.default_timer() - inf_start_time
# Parse detection results of the current request
res_json = OrderedDict()
frame_timestamp = datetime.datetime.now()
object_id = 0
for obj in res[out_blob][0][0]:
if obj[2] > 0.5:
xmin = int(obj[3] * initial_w)
ymin = int(obj[4] * initial_h)
xmax = int(obj[5] * initial_w)
ymax = int(obj[6] * initial_h)
cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (255, 165, 20), 4)
obj_id = "Object" + str(object_id)
classlabel = labeldata[str(int(obj[1]))] if labeldata else ""
res_json[obj_id] = {"label": int(obj[1]), "class": classlabel, "confidence": round(obj[2], 2), "xmin": round(obj[3], 2), "ymin": round(obj[4], 2), "xmax": round(obj[5], 2), "ymax": round(obj[6], 2)}
object_id += 1
frame_count += 1
# Measure elapsed seconds since the last report
seconds_elapsed = timeit.default_timer() - start_time
if seconds_elapsed >= reporting_interval:
res_json["timestamp"] = frame_timestamp.isoformat()
res_json["frame_id"] = int(frameid)
res_json["inference_fps"] = frame_count / inf_seconds
start_time = timeit.default_timer()
report(res_json, frame)
frame_count = 0
inf_seconds = 0.0
client.publish(topic=PARAM_TOPIC_NAME, payload="End of the input, exiting...")
del exec_net
del plugin
greengrass_object_detection_sample_ssd_run()
def function_handler(event, context):
client.publish(topic=PARAM_TOPIC_NAME, payload='HANDLER_CALLED!')
return

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,176 @@
#!/usr/bin/env python
"""
Copyright (c) 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import print_function
import sys
import os
from argparse import ArgumentParser
import cv2
import time
import logging as log
from openvino.inference_engine import IENetwork, IEPlugin
def build_argparser():
parser = ArgumentParser()
parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str)
parser.add_argument("-i", "--input",
help="Path to video file or image. 'cam' for capturing video stream from camera", required=True,
type=str)
parser.add_argument("-l", "--cpu_extension",
help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels "
"impl.", type=str, default=None)
parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None)
parser.add_argument("-d", "--device",
help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Sample "
"will look for a suitable plugin for device specified (CPU by default)", default="CPU",
type=str)
parser.add_argument("--labels", help="Labels mapping file", default=None, type=str)
parser.add_argument("-pt", "--prob_threshold", help="Probability threshold for detections filtering",
default=0.5, type=float)
return parser
def main():
log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
args = build_argparser().parse_args()
model_xml = args.model
model_bin = os.path.splitext(model_xml)[0] + ".bin"
# Plugin initialization for specified device and load extensions library if specified
log.info("Initializing plugin for {} device...".format(args.device))
plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir)
if args.cpu_extension and 'CPU' in args.device:
plugin.add_cpu_extension(args.cpu_extension)
# Read IR
log.info("Reading IR...")
net = IENetwork.from_ir(model=model_xml, weights=model_bin)
if "CPU" in plugin.device:
supported_layers = plugin.get_supported_layers(net)
not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers]
if len(not_supported_layers) != 0:
log.error("Following layers are not supported by the plugin for specified device {}:\n {}".
format(plugin.device, ', '.join(not_supported_layers)))
log.error("Please try to specify cpu extensions library path in sample's command line parameters using -l "
"or --cpu_extension command line argument")
sys.exit(1)
assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
assert len(net.outputs) == 1, "Sample supports only single output topologies"
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
log.info("Loading IR to the plugin...")
exec_net = plugin.load(network=net, num_requests=2)
# Read and pre-process input image
n, c, h, w = net.inputs[input_blob]
del net
if args.input == 'cam':
input_stream = 0
else:
input_stream = args.input
assert os.path.isfile(args.input), "Specified input file doesn't exist"
if args.labels:
with open(args.labels, 'r') as f:
labels_map = [x.strip() for x in f]
else:
labels_map = None
cap = cv2.VideoCapture(input_stream)
cur_request_id = 0
next_request_id = 1
log.info("Starting inference in async mode...")
log.info("To switch between sync and async modes press Tab button")
log.info("To stop the sample execution press Esc button")
is_async_mode = True
render_time = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
initial_w = cap.get(3)
initial_h = cap.get(4)
in_frame = cv2.resize(frame, (w, h))
in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW
in_frame = in_frame.reshape((n, c, h, w))
# Main sync point:
# in the truly Async mode we start the NEXT infer request, while waiting for the CURRENT to complete
# in the regular mode we start the CURRENT request and immediately wait for it's completion
inf_start = time.time()
if is_async_mode:
exec_net.start_async(request_id=next_request_id, inputs={input_blob: in_frame})
else:
exec_net.start_async(request_id=cur_request_id, inputs={input_blob: in_frame})
if exec_net.requests[cur_request_id].wait(-1) == 0:
inf_end = time.time()
det_time = inf_end - inf_start
# Parse detection results of the current request
res = exec_net.requests[cur_request_id].outputs[out_blob]
for obj in res[0][0]:
# Draw only objects when probability more than specified threshold
if obj[2] > args.prob_threshold:
xmin = int(obj[3] * initial_w)
ymin = int(obj[4] * initial_h)
xmax = int(obj[5] * initial_w)
ymax = int(obj[6] * initial_h)
class_id = int(obj[1])
# Draw box and label\class_id
color = (min(class_id * 12.5, 255), min(class_id * 7, 255), min(class_id * 5, 255))
cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), color, 2)
det_label = labels_map[class_id] if labels_map else str(class_id)
cv2.putText(frame, det_label + ' ' + str(round(obj[2] * 100, 1)) + ' %', (xmin, ymin - 7),
cv2.FONT_HERSHEY_COMPLEX, 0.6, color, 1)
# Draw performance stats
inf_time_message = "Inference time: N\A for async mode" if is_async_mode else \
"Inference time: {:.3f} ms".format(det_time * 1000)
render_time_message = "OpenCV rendering time: {:.3f} ms".format(render_time * 1000)
async_mode_message = "Async mode is on. Processing request {}".format(cur_request_id) if is_async_mode else \
"Async mode is off. Processing request {}".format(cur_request_id)
cv2.putText(frame, inf_time_message, (15, 15), cv2.FONT_HERSHEY_COMPLEX, 0.5, (200, 10, 10), 1)
cv2.putText(frame, render_time_message, (15, 30), cv2.FONT_HERSHEY_COMPLEX, 0.5, (10, 10, 200), 1)
cv2.putText(frame, async_mode_message, (10, int(initial_h - 20)), cv2.FONT_HERSHEY_COMPLEX, 0.5,
(10, 10, 200), 1)
#
render_start = time.time()
cv2.imshow("Detection Results", frame)
render_end = time.time()
render_time = render_end - render_start
key = cv2.waitKey(1)
if key == 27:
break
if (9 == key):
is_async_mode = not is_async_mode
log.info("Switched to {} mode".format("async" if is_async_mode else "sync"))
if is_async_mode:
cur_request_id, next_request_id = next_request_id, cur_request_id
cv2.destroyAllWindows()
del exec_net
del plugin
if __name__ == '__main__':
sys.exit(main() or 0)

View File

@ -0,0 +1,2 @@
opencv-python
numpy

View File

@ -0,0 +1,154 @@
#!/usr/bin/env python
"""
Copyright (c) 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import print_function
import sys
import os
from argparse import ArgumentParser
import cv2
import numpy as np
import logging as log
from time import time
from openvino.inference_engine import IENetwork, IEPlugin
classes_color_map = [
(150, 150, 150),
(58, 55, 169),
(211, 51, 17),
(157, 80, 44),
(23, 95, 189),
(210, 133, 34),
(76, 226, 202),
(101, 138, 127),
(223, 91, 182),
(80, 128, 113),
(235, 155, 55),
(44, 151, 243),
(159, 80, 170),
(239, 208, 44),
(128, 50, 51),
(82, 141, 193),
(9, 107, 10),
(223, 90, 142),
(50, 248, 83),
(178, 101, 130),
(71, 30, 204)
]
def build_argparser():
parser = ArgumentParser()
parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str)
parser.add_argument("-i", "--input", help="Path to a folder with images or path to an image files", required=True,
type=str, nargs="+")
parser.add_argument("-l", "--cpu_extension",
help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels "
"impl.", type=str, default=None)
parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None)
parser.add_argument("-d", "--device",
help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Sample "
"will look for a suitable plugin for device specified (CPU by default)", default="CPU",
type=str)
parser.add_argument("-nt", "--number_top", help="Number of top results", default=10, type=int)
parser.add_argument("-ni", "--number_iter", help="Number of inference iterations", default=1, type=int)
parser.add_argument("-pc", "--perf_counts", help="Report performance counters", default=False, action="store_true")
return parser
def main():
log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
args = build_argparser().parse_args()
model_xml = args.model
model_bin = os.path.splitext(model_xml)[0] + ".bin"
# Plugin initialization for specified device and load extensions library if specified
plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir)
if args.cpu_extension and 'CPU' in args.device:
plugin.add_cpu_extension(args.cpu_extension)
# Read IR
log.info("Loading network files:\n\t{}\n\t{}".format(model_xml, model_bin))
net = IENetwork.from_ir(model=model_xml, weights=model_bin)
if "CPU" in plugin.device:
supported_layers = plugin.get_supported_layers(net)
not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers]
if len(not_supported_layers) != 0:
log.error("Following layers are not supported by the plugin for specified device {}:\n {}".
format(plugin.device, ', '.join(not_supported_layers)))
log.error("Please try to specify cpu extensions library path in sample's command line parameters using -l "
"or --cpu_extension command line argument")
sys.exit(1)
assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
assert len(net.outputs) == 1, "Sample supports only single output topologies"
log.info("Preparing input blobs")
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
net.batch_size = len(args.input)
# Read and pre-process input images
n, c, h, w = net.inputs[input_blob]
images = np.ndarray(shape=(n, c, h, w))
for i in range(n):
image = cv2.imread(args.input[i])
if image.shape[:-1] != (h, w):
log.warning("Image {} is resized from {} to {}".format(args.input[i], image.shape[:-1], (h, w)))
image = cv2.resize(image, (w, h))
image = image.transpose((2, 0, 1)) # Change data layout from HWC to CHW
images[i] = image
log.info("Batch size is {}".format(n))
# Loading model to the plugin
log.info("Loading model to the plugin")
exec_net = plugin.load(network=net)
del net
# Start sync inference
log.info("Starting inference ({} iterations)".format(args.number_iter))
infer_time = []
for i in range(args.number_iter):
t0 = time()
res = exec_net.infer(inputs={input_blob: images})
infer_time.append((time() - t0) * 1000)
log.info("Average running time of one iteration: {} ms".format(np.average(np.asarray(infer_time))))
if args.perf_counts:
perf_counts = exec_net.requests[0].get_perf_counts()
log.info("Performance counters:")
print("{:<70} {:<15} {:<15} {:<15} {:<10}".format('name', 'layer_type', 'exet_type', 'status', 'real_time, us'))
for layer, stats in perf_counts.items():
print ("{:<70} {:<15} {:<15} {:<15} {:<10}".format(layer, stats['layer_type'], stats['exec_type'],
stats['status'], stats['real_time']))
# Processing output blob
log.info("Processing output blob")
res = res[out_blob]
for batch, data in enumerate(res):
classes_map = np.zeros(shape=(h, w, c), dtype=np.int)
for i in range(h):
for j in range(w):
if len(data[:, i, j]) == 1:
pixel_class = int(data[:, i, j])
else:
pixel_class = np.argmax(data[:, i, j])
classes_map[i, j, :] = classes_color_map[min(pixel_class, 20)]
out_img = os.path.join(os.path.dirname(__file__), "out_{}.bmp".format(batch))
cv2.imwrite(out_img, classes_map)
log.info("Result image was saved to {}".format(out_img))
del exec_net
del plugin
if __name__ == '__main__':
sys.exit(main() or 0)

View File

@ -0,0 +1,142 @@
#!/usr/bin/env python
"""
Copyright (c) 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import print_function
import sys
import os
from argparse import ArgumentParser
import cv2
import numpy as np
import logging as log
from time import time
from openvino.inference_engine import IENetwork, IEPlugin
def build_argparser():
parser = ArgumentParser()
parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str)
parser.add_argument("-i", "--input", help="Path to a folder with images or path to an image files", required=True,
type=str, nargs="+")
parser.add_argument("-l", "--cpu_extension",
help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels "
"impl.", type=str, default=None)
parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None)
parser.add_argument("-d", "--device",
help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Sample "
"will look for a suitable plugin for device specified (CPU by default)", default="CPU",
type=str)
parser.add_argument("-nt", "--number_top", help="Number of top results", default=10, type=int)
parser.add_argument("-ni", "--number_iter", help="Number of inference iterations", default=1, type=int)
parser.add_argument("--mean_val_r", "-mean_val_r",
help="Mean value of red chanel for mean value subtraction in postprocessing ", default=0,
type=float)
parser.add_argument("--mean_val_g", "-mean_val_g",
help="Mean value of green chanel for mean value subtraction in postprocessing ", default=0,
type=float)
parser.add_argument("--mean_val_b", "-mean_val_b",
help="Mean value of blue chanel for mean value subtraction in postprocessing ", default=0,
type=float)
parser.add_argument("-pc", "--perf_counts", help="Report performance counters", default=False, action="store_true")
return parser
def main():
log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
args = build_argparser().parse_args()
model_xml = args.model
model_bin = os.path.splitext(model_xml)[0] + ".bin"
# Plugin initialization for specified device and load extensions library if specified
plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir)
if args.cpu_extension and 'CPU' in args.device:
plugin.add_cpu_extension(args.cpu_extension)
# Read IR
log.info("Loading network files:\n\t{}\n\t{}".format(model_xml, model_bin))
net = IENetwork.from_ir(model=model_xml, weights=model_bin)
if "CPU" in plugin.device:
supported_layers = plugin.get_supported_layers(net)
not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers]
if len(not_supported_layers) != 0:
log.error("Following layers are not supported by the plugin for specified device {}:\n {}".
format(plugin.device, ', '.join(not_supported_layers)))
log.error("Please try to specify cpu extensions library path in sample's command line parameters using -l "
"or --cpu_extension command line argument")
sys.exit(1)
assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
assert len(net.outputs) == 1, "Sample supports only single output topologies"
log.info("Preparing input blobs")
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
net.batch_size = len(args.input)
# Read and pre-process input images
n, c, h, w = net.inputs[input_blob]
images = np.ndarray(shape=(n, c, h, w))
for i in range(n):
image = cv2.imread(args.input[i])
if image.shape[:-1] != (h, w):
log.warning("Image {} is resized from {} to {}".format(args.input[i], image.shape[:-1], (h, w)))
image = cv2.resize(image, (w, h))
image = image.transpose((2, 0, 1)) # Change data layout from HWC to CHW
images[i] = image
log.info("Batch size is {}".format(n))
# Loading model to the plugin
log.info("Loading model to the plugin")
exec_net = plugin.load(network=net)
del net
# Start sync inference
log.info("Starting inference ({} iterations)".format(args.number_iter))
infer_time = []
for i in range(args.number_iter):
t0 = time()
res = exec_net.infer(inputs={input_blob: images})
infer_time.append((time() - t0) * 1000)
log.info("Average running time of one iteration: {} ms".format(np.average(np.asarray(infer_time))))
if args.perf_counts:
perf_counts = exec_net.requests[0].get_perf_counts()
log.info("Performance counters:")
print("{:<70} {:<15} {:<15} {:<15} {:<10}".format('name', 'layer_type', 'exet_type', 'status', 'real_time, us'))
for layer, stats in perf_counts.items():
print ("{:<70} {:<15} {:<15} {:<15} {:<10}".format(layer, stats['layer_type'], stats['exec_type'],
stats['status'], stats['real_time']))
# Processing output blob
log.info("Processing output blob")
res = res[out_blob]
# Post process output
for batch, data in enumerate(res):
# Clip values to [0, 255] range
data = np.swapaxes(data, 0, 2)
data = np.swapaxes(data, 0, 1)
data = cv2.cvtColor(data, cv2.COLOR_BGR2RGB)
data[data < 0] = 0
data[data > 255] = 255
data = data[::] - (args.mean_val_r, args.mean_val_g, args.mean_val_b)
out_img = os.path.join(os.path.dirname(__file__), "out_{}.bmp".format(batch))
cv2.imwrite(out_img, data)
log.info("Result image was saved to {}".format(out_img))
del exec_net
del plugin
if __name__ == '__main__':
sys.exit(main() or 0)

View File

@ -0,0 +1,21 @@
background
aeroplane
bicycle
bird
boat
bottle
bus
car
cat
chair
cow
diningtable
dog
horse
motorbike
person
pottedplant
sheep
sofa
train
tvmonitor

View File

@ -0,0 +1,202 @@
import subprocess
from pathlib import Path
import platform
import sys
from itertools import chain
from distutils.command.build_py import build_py as _build_py
from distutils.command.clean import clean as _clean
import shutil
from setuptools import setup, Extension, find_packages
from setuptools.command.build_ext import build_ext as _build_ext
from setuptools.command.install import install as _install
IS_WINDOWS = (platform.system() == 'Windows')
IS_DARWIN = (platform.system() == 'Darwin')
IS_LINUX = (platform.system() == 'Linux')
REQUIREMENTS_FILE = 'requirements.txt'
PACKAGE_NAME = 'inference_engine'
PACKAGE = Path(PACKAGE_NAME)
C_LIB_NAME = '{}._C'.format(PACKAGE_NAME)
_build_cmd = ['cmake', '--build', '.']
INFERENCE_ENGINE_DIR = None
BUNDLE_INFERENCE_ENGINE = False
def parse_command_line_options(cls):
"""Propagates command line options to sub-commands.
Allows to run install command with build_ext options"""
base_user_options = getattr(cls, 'user_options', [])
base_boolean_options = getattr(cls, 'boolean_options', [])
base_run = cls.run
base_init_options = cls.initialize_options
cls.user_options = base_user_options + [
('copy-ie-libs', None, 'Copy Inference Engine Libraries to package directory'),
('inference-engine-dir=', None, 'Path to Inference Engine directory')
]
cls.boolean_options = base_boolean_options + [
'copy-ie-libs'
]
def initialize_options(self):
self.copy_ie_libs = False
self.inference_engine_dir = None
base_init_options(self)
def run(self):
global INFERENCE_ENGINE_DIR
global BUNDLE_INFERENCE_ENGINE
if self.copy_ie_libs:
BUNDLE_INFERENCE_ENGINE = True
if self.inference_engine_dir:
INFERENCE_ENGINE_DIR = self.inference_engine_dir
base_run(self)
cls.initialize_options = initialize_options
cls.run = run
return cls
@parse_command_line_options
class install(_install):
pass
@parse_command_line_options
class build_py(_build_py):
pass
@parse_command_line_options
class build_ext(_build_ext):
def run(self):
if not self.extensions:
return
for i, ext in enumerate(self.extensions):
if ext.name == C_LIB_NAME:
self._build_cmake()
self.extensions.pop(i)
break
super().run()
def _build_cmake(self):
print("Building C++ extension")
if Path.cwd().joinpath("Makefile").is_file():
# in build directory, run make only
subprocess.call(_build_cmd)
else:
# compile extension library and
self.build_cmake_lib()
print("Built C++ extension")
def build_cmake_lib(self):
def save_call(*args, error_msg=None, **kwargs):
if subprocess.call(*args, **kwargs) != 0:
if error_msg:
print(error_msg)
shutil.rmtree(tmp_build_dir.as_posix(), ignore_errors=True)
sys.exit(1)
tmp_build_dir = Path("tmp_build")
destination = Path(self.build_lib) / PACKAGE_NAME if not self.inplace else Path(PACKAGE_NAME)
tmp_build_dir.mkdir(exist_ok=False)
_python_executable_opt = ['-DPYTHON_EXECUTABLE={}'.format(sys.executable)]
_build_type_opt = ['-DCMAKE_BUILD_TYPE=Release']
_generator_opt = ['-G', 'NMake Makefiles' if IS_WINDOWS else "Unix Makefiles"]
_optional = []
if BUNDLE_INFERENCE_ENGINE:
_optional.append('-DCOPY_IE_LIBS=ON')
if INFERENCE_ENGINE_DIR:
_optional.append('-DInferenceEngine_DIR={}'.format(INFERENCE_ENGINE_DIR))
_cmake_cmd = list(chain(['cmake'], _generator_opt, _build_type_opt, _python_executable_opt, _optional, ['..']))
save_call(_cmake_cmd, cwd=tmp_build_dir.as_posix(), error_msg="Cmake generator failed")
save_call(_build_cmd, cwd=tmp_build_dir.as_posix(), error_msg="Build command failed")
build_ext.copy_compiled_libs(tmp_build_dir / PACKAGE_NAME, destination)
shutil.rmtree(tmp_build_dir.as_posix(), ignore_errors=False)
@staticmethod
def copy_compiled_libs(source_dir, destination):
extensions = ['so', 'dll', 'pyd']
for path in chain.from_iterable(source_dir.glob("*.%s" % ext) for ext in extensions):
shutil.copy(path.as_posix(), destination.as_posix())
class clean(_clean):
def run(self):
shutil.rmtree("tmp_build", ignore_errors=True)
extensions = ['so', 'dll', 'pyd']
for path in chain.from_iterable(PACKAGE.glob("*.%s" % ext) for ext in extensions):
path.unlink()
super().run()
def paths_to_str(paths):
return [p.as_posix() for p in paths]
with open(REQUIREMENTS_FILE) as reqs:
requirements = set(reqs.read().splitlines())
# do not spoil pre-installed opencv (in case it was built from source)
_opencv_package = "opencv-python"
try:
import cv2
if _opencv_package in requirements:
requirements.remove(_opencv_package)
except ImportError:
requirements.add(_opencv_package)
c_sources = [
PACKAGE / 'ie_driver.cpp',
PACKAGE / 'ie_driver.hpp',
PACKAGE / 'c_ie_driver.pxd',
PACKAGE / 'ie_driver.pyx',
PACKAGE / 'ie_driver.pxd',
]
extensions = [
Extension(C_LIB_NAME, paths_to_str(c_sources))
]
cmdclass = {
'build_ext': build_ext,
'build_py': build_py,
'clean': clean,
'install': install,
}
setup(
name="inference_engine",
version='0.1.1',
description='Python inference for Inference Engine',
packages=find_packages(exclude=['tests']),
package_data={PACKAGE_NAME: ['*.so', '*.dll', '*dylib*', '*.pyd']},
include_package_data=True,
ext_modules=extensions,
cmdclass=cmdclass,
author='', author_email='',
tests_require=['pytest'],
install_requires=list(requirements),
zip_safe=False,
)

View File

@ -0,0 +1,61 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief a header for advanced hardware related properties for clDNN plugin
* To use in SetConfig() method of plugins
*
* @file ie_plugin_config.hpp
*/
#pragma once
#include <string>
#include "../ie_plugin_config.hpp"
namespace InferenceEngine {
namespace CLDNNConfigParams {
/**
* @brief shortcut for defining configuration keys
*/
#define CLDNN_CONFIG_KEY(name) InferenceEngine::CLDNNConfigParams::_CONFIG_KEY(CLDNN_##name)
#define DECLARE_CLDNN_CONFIG_KEY(name) DECLARE_CONFIG_KEY(CLDNN_##name)
#define DECLARE_CLDNN_CONFIG_VALUE(name) DECLARE_CONFIG_VALUE(CLDNN_##name)
/**
* @brief This key instructs the clDNN plugin to use the OpenCL queue priority hint
* as defined in https://www.khronos.org/registry/OpenCL/specs/opencl-2.1-extensions.pdf
* this option should be used with an unsigned integer value (1 is lowest priority)
* 0 means no priority hint is set and default queue is created.
*/
DECLARE_CLDNN_CONFIG_KEY(PLUGIN_PRIORITY);
/**
* @brief This key instructs the clDNN plugin to use throttle hints the OpenCL queue throttle hint
* as defined in https://www.khronos.org/registry/OpenCL/specs/opencl-2.1-extensions.pdf,
* chapter 9.19. This option should be used with an unsigned integer value (1 is lowest energy consumption)
* 0 means no throttle hint is set and default queue created.
*/
DECLARE_CLDNN_CONFIG_KEY(PLUGIN_THROTTLE);
/**
* @brief This key controls clDNN memory pool optimization.
* Turned off by default.
*/
DECLARE_CLDNN_CONFIG_KEY(MEM_POOL);
/**
* @brief This key defines the directory name to which clDNN graph visualization will be dumped.
*/
DECLARE_CLDNN_CONFIG_KEY(GRAPH_DUMPS_DIR);
/**
* @brief This key defines the directory name to which full program sources will be dumped.
*/
DECLARE_CLDNN_CONFIG_KEY(SOURCES_DUMPS_DIR);
} // namespace CLDNNConfigParams
} // namespace InferenceEngine

View File

@ -0,0 +1,122 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This is a header file for the Network reader class (wrapper) used to build networks from a given IR
* @file ie_cnn_net_reader.h
*/
#pragma once
#include <string>
#include <vector>
#include <memory>
#include <map>
#include "ie_blob.h"
#include "ie_cnn_network.h"
#include "ie_common.h"
#include "ie_icnn_net_reader.h"
#include "details/ie_exception_conversion.hpp"
namespace InferenceEngine {
/**
* @brief This is a wrapper class used to build and parse a network from the given IR.
* All the methods here can throw exceptions.
*/
class CNNNetReader {
public:
/**
* @brief A smart pointer to this class
*/
using Ptr = std::shared_ptr<CNNNetReader>;
/**
* @brief A default constructor
*/
CNNNetReader() : actual(shared_from_irelease(InferenceEngine::CreateCNNNetReader())) {}
/**
* @brief Wraps original method
* ICNNNetReader::ReadNetwork
*/
void ReadNetwork(const std::string &filepath) {
CALL_STATUS_FNC(ReadNetwork, filepath.c_str());
}
/**
* @brief Wraps original method
* ICNNNetReader::ReadNetwork(const void*, size_t, ResponseDesc*)
*/
void ReadNetwork(const void *model, size_t size) {
CALL_STATUS_FNC(ReadNetwork, model, size);
}
/**
* @brief Wraps original method
* ICNNNetReader::SetWeights
*/
void SetWeights(const TBlob<uint8_t>::Ptr &weights) const {
CALL_STATUS_FNC(SetWeights, weights);
}
/**
* @brief Wraps original method
* ICNNNetReader::ReadWeights
*/
void ReadWeights(const std::string &filepath) const {
CALL_STATUS_FNC(ReadWeights, filepath.c_str());
}
/**
* @brief Gets a copy of built network object
* @return A copy of the CNNNetwork object to be loaded
*/
CNNNetwork getNetwork() {
// network obj are to be updated upon this call
if (network.get() == nullptr) {
network.reset(new CNNNetwork(actual));
}
return *network.get();
}
/**
* @brief Wraps original method
* ICNNNetReader::isParseSuccess
*/
bool isParseSuccess() const {
CALL_FNC_NO_ARGS(isParseSuccess);
}
/**
* @brief Wraps original method
* ICNNNetReader::getDescription
*/
std::string getDescription() const {
CALL_STATUS_FNC_NO_ARGS(getDescription);
return resp.msg;
}
/**
* @brief Wraps original method
* ICNNNetReader::getName
*/
std::string getName() const {
char name[64];
CALL_STATUS_FNC(getName, name, sizeof(name) / sizeof(*name));
return name;
}
/**
* @brief Wraps original method
* ICNNNetReader::getVersion
*/
int getVersion() const {
CALL_FNC_NO_ARGS(getVersion);
}
private:
std::shared_ptr<ICNNNetReader> actual;
std::shared_ptr<CNNNetwork> network;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,234 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file that provides wrapper for ICNNNetwork object
* @file ie_cnn_network.h
*/
#pragma once
#include <details/ie_exception_conversion.hpp>
#include <details/ie_cnn_network_iterator.hpp>
#include <ie_icnn_network.hpp>
#include <ie_icnn_net_reader.h>
#include "ie_common.h"
#include "ie_data.h"
#include "ie_blob.h"
#include <vector>
#include <string>
#include <map>
#include <utility>
#include <memory>
namespace InferenceEngine {
/**
* @brief This class contains all the information about the Neural Network and the related binary information
*/
class CNNNetwork {
public:
/**
* @brief A default constructor
*/
CNNNetwork() = default;
/**
* @brief Initialises helper class from externally managed pointer
* @deprecated use shared_pointers based version of CNNNetworks constructor
* @param actual Pointer to the network object
*/
explicit CNNNetwork(ICNNNetwork* actual) : actual(actual) {
if (actual == nullptr) {
THROW_IE_EXCEPTION << "CNNNetwork was not initialized.";
}
}
/**
* @brief Allows helper class to manage lifetime of network object
* @param network Pointer to the network object
*/
explicit CNNNetwork(std::shared_ptr<ICNNNetwork> network)
: network(network) {
actual = network.get();
if (actual == nullptr) {
THROW_IE_EXCEPTION << "CNNNetwork was not initialized.";
}
}
/**
* @brief A constructor from ICNNNetReader object
* @param reader Pointer to the ICNNNetReader object
*/
explicit CNNNetwork(std::shared_ptr<ICNNNetReader> reader)
: reader(reader)
, actual(reader->getNetwork(nullptr)) {
if (actual == nullptr) {
THROW_IE_EXCEPTION << "CNNNetwork was not initialized.";
}
}
/**
* @brief Wraps original method
* ICNNNetwork::getPrecision
*/
virtual Precision getPrecision() const {
return actual->getPrecision();
}
/**
* @brief Wraps original method
* ICNNNetwork::getOutputsInfo
*/
virtual OutputsDataMap getOutputsInfo() const {
OutputsDataMap outputs;
actual->getOutputsInfo(outputs);
return std::move(outputs);
}
/**
* @brief Wraps original method
* ICNNNetwork::getInputsInfo
*/
virtual InputsDataMap getInputsInfo() const {
InputsDataMap inputs;
actual->getInputsInfo(inputs);
return std::move(inputs);
}
/**
* @brief Wraps original method
* ICNNNetwork::layerCount
*/
size_t layerCount() const {
return actual->layerCount();
}
/**
* @brief Wraps original method
* ICNNNetwork::setBatchSize
*/
virtual void setBatchSize(const size_t size) {
CALL_STATUS_FNC(setBatchSize, size);
}
/**
* @brief Wraps original method
* ICNNNetwork::getBatchSize
*/
virtual size_t getBatchSize() const {
return actual->getBatchSize();
}
/**
* @brief An overloaded operator & to get current network
* @return An instance of the current network
*/
operator ICNNNetwork &() const {
return *actual;
}
/**
* @brief Sets tha target device
* @param device Device instance to set
*/
void setTargetDevice(TargetDevice device) {
actual->setTargetDevice(device);
}
/**
* @brief Wraps original method
* ICNNNetwork::addOutput
*/
void addOutput(const std::string &layerName, size_t outputIndex = 0) {
CALL_STATUS_FNC(addOutput, layerName, outputIndex);
}
/**
* @brief Wraps original method
* ICNNNetwork::getLayerByName
*/
CNNLayerPtr getLayerByName(const char *layerName) const {
CNNLayerPtr layer;
CALL_STATUS_FNC(getLayerByName, layerName, layer);
return layer;
}
/**
* @brief Begin layer iterator
* Order of layers is implementation specific,
* and can be changed in future
*/
details::CNNNetworkIterator begin() const {
return details::CNNNetworkIterator(actual);
}
/**
* @brief End layer iterator
*/
details::CNNNetworkIterator end() const {
return details::CNNNetworkIterator();
}
/**
* @brief number of layers in network object
* @return
*/
size_t size() const {
return std::distance(std::begin(*this), std::end(*this));
}
/**
* @brief Registers extension within the plugin
* @param extension Pointer to already loaded reader extension with shape propagation implementations
*/
void AddExtension(InferenceEngine::IShapeInferExtensionPtr extension) {
CALL_STATUS_FNC(AddExtension, extension);
}
/**
* @brief - Helper method to get collect all input shapes with names of corresponding Data objects
* @return Map of pairs: input's name and its dimension.
*/
virtual ICNNNetwork::InputShapes getInputShapes() {
ICNNNetwork::InputShapes shapes;
InputsDataMap inputs;
actual->getInputsInfo(inputs);
for (const auto& pair : inputs) {
auto info = pair.second;
if (info) {
auto data = info->getInputData();
if (data) {
shapes[data->name] = data->getTensorDesc().getDims();
}
}
}
return std::move(shapes);
}
virtual void reshape(const ICNNNetwork::InputShapes &inputShapes) {
CALL_STATUS_FNC(reshape, inputShapes);
}
protected:
/**
* @brief reader extra reference, might be nullptr
*/
std::shared_ptr<ICNNNetReader> reader;
/**
* @brief network extra interface, might be nullptr
*/
std::shared_ptr<ICNNNetwork> network;
/**
* @brief A pointer to the current network
*/
ICNNNetwork *actual = nullptr;
/**
* @brief A pointer to output data
*/
DataPtr output;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,137 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file that provides wrapper classes for IExecutableNetwork
* @file ie_executable_network.hpp
*/
#pragma once
#include <map>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>
#include "ie_iexecutable_network.hpp"
#include "cpp/ie_infer_request.hpp"
#include "cpp/ie_memory_state.hpp"
#include "details/ie_exception_conversion.hpp"
namespace InferenceEngine {
/**
* @brief wrapper over IExecutableNetwork
*/
class ExecutableNetwork {
IExecutableNetwork::Ptr actual;
public:
ExecutableNetwork() = default;
explicit ExecutableNetwork(IExecutableNetwork::Ptr actual) : actual(actual) {}
/**
* @brief Wraps original method
* IExecutableNetwork::getOutputsInfo
*/
ConstOutputsDataMap GetOutputsInfo() const {
ConstOutputsDataMap data;
CALL_STATUS_FNC(GetOutputsInfo, data);
return data;
}
/**
* @brief Wraps original method
* IExecutableNetwork::getInputsInfo
*/
ConstInputsDataMap GetInputsInfo() const {
ConstInputsDataMap info;
CALL_STATUS_FNC(GetInputsInfo, info);
return info;
}
/**
* @brief reset owned object to new pointer, essential for cases when simultaneously loaded networks not expected
* @param actual actual pointed object
*/
void reset(IExecutableNetwork::Ptr newActual) {
this->actual.swap(newActual);
}
/**
* @brief Wraps original method
* IExecutableNetwork::CreateInferRequest
*/
InferRequest CreateInferRequest() {
IInferRequest::Ptr req;
CALL_STATUS_FNC(CreateInferRequest, req);
if (req.get() == nullptr) THROW_IE_EXCEPTION << "Internal error: pointer to infer request is null";
return InferRequest(req);
}
/**
* @brief Wraps original method
* IExecutableNetwork::CreateInferRequestPtr
* @return shared pointer on InferRequest object
*/
InferRequest::Ptr CreateInferRequestPtr() {
IInferRequest::Ptr req;
CALL_STATUS_FNC(CreateInferRequest, req);
return std::make_shared<InferRequest>(req);
}
/**
* @brief Exports the current executable network so it can be used later in the Import() main API
* @param modelFileName Full path to the location of the exported file
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
*/
void Export(const std::string &modelFileName) {
CALL_STATUS_FNC(Export, modelFileName);
}
/**
* @brief Gets the mapping of IR layer names to implemented kernels
* @param deployedTopology Map of PrimitiveInfo objects that represent the deployed topology
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
*/
void GetMappedTopology(std::map<std::string, std::vector<PrimitiveInfo::Ptr>> &deployedTopology) {
CALL_STATUS_FNC(GetMappedTopology, deployedTopology);
}
/**
* cast operator is used when this wrapper initialized by LoadNetwork
* @return
*/
operator IExecutableNetwork::Ptr &() {
return actual;
}
/**
*@brief see original function InferenceEngine::IExecutableNetwork::QueryState
*/
std::vector<MemoryState> QueryState() {
IMemoryState::Ptr pState = nullptr;
auto res = OK;
std::vector<MemoryState> controller;
for (size_t idx = 0; res == OK; ++idx) {
ResponseDesc resp;
res = actual->QueryState(pState, idx, &resp);
if (res != OK && res != OUT_OF_BOUNDS) {
THROW_IE_EXCEPTION << resp.msg;
}
if (res != OUT_OF_BOUNDS) {
controller.push_back(MemoryState(pState));
}
}
return controller;
}
using Ptr = std::shared_ptr<ExecutableNetwork>;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,218 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file that provides wrapper classes for infer requests and callbacks.
* @file ie_infer_request.hpp
*/
#pragma once
#include <memory>
#include <string>
#include <map>
#include "ie_iinfer_request.hpp"
#include "details/ie_exception_conversion.hpp"
namespace InferenceEngine {
namespace details {
class ICompletionCallbackWrapper {
public:
virtual ~ICompletionCallbackWrapper() = default;
virtual void call(InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode code) const noexcept = 0;
};
template<class T>
class CompletionCallbackWrapper : public ICompletionCallbackWrapper {
T lambda;
public:
explicit CompletionCallbackWrapper(const T &lambda) : lambda(lambda) {}
void call(InferenceEngine::IInferRequest::Ptr /*request*/,
InferenceEngine::StatusCode /*code*/) const noexcept override {
lambda();
}
};
template<>
class CompletionCallbackWrapper<IInferRequest::CompletionCallback> : public ICompletionCallbackWrapper {
IInferRequest::CompletionCallback callBack;
public:
explicit CompletionCallbackWrapper(const IInferRequest::CompletionCallback &callBack) : callBack(callBack) {}
void call(InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode code) const noexcept override {
callBack(request, code);
}
};
} // namespace details
/**
* @brief This class is a wrapper of IInferRequest to provide setters/getters
* of input/output which operates with BlobMaps.
* It can throw exceptions safely for the application, where it is properly handled.
*/
class InferRequest {
IInferRequest::Ptr actual;
std::shared_ptr<details::ICompletionCallbackWrapper> callback;
static void callWrapper(InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode code) {
details::ICompletionCallbackWrapper *pWrapper = nullptr;
ResponseDesc dsc;
request->GetUserData(reinterpret_cast<void**>(&pWrapper), &dsc);
pWrapper->call(request, code);
}
public:
InferRequest() = default;
/**
* @brief Sets input/output data to infer
* @note: Memory allocation does not happen
* @param name Name of input or output blob.
* @param data Reference to input or output blob. The type of a blob must match the network input precision and size.
*/
void SetBlob(const std::string &name, const Blob::Ptr &data) {
CALL_STATUS_FNC(SetBlob, name.c_str(), data);
}
/**
* @brief Wraps original method
* IInferRequest::GetBlob
*/
Blob::Ptr GetBlob(const std::string &name) {
Blob::Ptr data;
CALL_STATUS_FNC(GetBlob, name.c_str(), data);
std::string error = "Internal error: blob with name `" + name + "` is not allocated!";
auto blobPtr = data.get();
if (blobPtr == nullptr) THROW_IE_EXCEPTION << error;
if (blobPtr->buffer() == nullptr) THROW_IE_EXCEPTION << error;
return data;
}
/**
* @brief Wraps original method
* IInferRequest::Infer
*/
void Infer() {
CALL_STATUS_FNC_NO_ARGS(Infer);
}
/**
* @brief Wraps original method
* IInferRequest::GetPerformanceCounts
*/
std::map<std::string, InferenceEngineProfileInfo> GetPerformanceCounts() const {
std::map<std::string, InferenceEngineProfileInfo> perfMap;
CALL_STATUS_FNC(GetPerformanceCounts, perfMap);
return perfMap;
}
/**
* @brief Sets input data to infer
* @note: Memory allocation doesn't happen
* @param inputs - a reference to a map of input blobs accessed by input names.
* The type of Blob must correspond to the network input precision and size.
*/
void SetInput(const BlobMap &inputs) {
for (auto &&input : inputs) {
CALL_STATUS_FNC(SetBlob, input.first.c_str(), input.second);
}
}
/**
* @brief Sets data that will contain result of the inference
* @note: Memory allocation doesn't happen
* @param results - a reference to a map of result blobs accessed by output names.
* The type of Blob must correspond to the network output precision and size.
*/
void SetOutput(const BlobMap &results) {
for (auto &&result : results) {
CALL_STATUS_FNC(SetBlob, result.first.c_str(), result.second);
}
}
/**
* @brief Sets data that will contain result of the inference
* @param results - a reference to a map of result blobs accessed by output names.
* The type of Blob must correspond to the network output precision and size.
*/
void SetBatch(const int batch) {
CALL_STATUS_FNC(SetBatch, batch);
}
/**
* constructs InferRequest from initialised shared_pointer
* @param actual
*/
explicit InferRequest(IInferRequest::Ptr request) : actual(request) {}
/**
* @brief Start inference of specified input(s) in asynchronous mode
* @note: It returns immediately. Inference starts also immediately.
*/
void StartAsync() {
CALL_STATUS_FNC_NO_ARGS(StartAsync);
}
/**
* @brief Wraps original method
* IInferRequest::Wait
*/
StatusCode Wait(int64_t millis_timeout) {
return actual->Wait(millis_timeout, nullptr);
}
/**
* @brief Wraps original method
* IInferRequest::SetCompletionCallback
*
* @param callbackToSet Lambda callback object which will be called on processing finish.
*/
template <class T>
void SetCompletionCallback(const T & callbackToSet) {
callback.reset(new details::CompletionCallbackWrapper<T>(callbackToSet));
CALL_STATUS_FNC(SetUserData, callback.get());
actual->SetCompletionCallback(callWrapper);
}
/**
* @brief IInferRequest pointer to be used directly in CreateInferRequest functions
*/
operator IInferRequest::Ptr &() {
return actual;
}
bool operator!() const noexcept {
return !actual;
}
explicit operator bool() const noexcept {
return !!actual;
}
using Ptr = std::shared_ptr<InferRequest>;
};
namespace details {
template<>
class CompletionCallbackWrapper<std::function<void(InferRequest, StatusCode)>>
: public ICompletionCallbackWrapper {
std::function<void(InferRequest, StatusCode)> lambda;
public:
explicit CompletionCallbackWrapper(const std::function<void(InferRequest, InferenceEngine::StatusCode)> &lambda)
: lambda(lambda) {}
void call(InferenceEngine::IInferRequest::Ptr request,
InferenceEngine::StatusCode code) const noexcept override {
lambda(InferRequest(request), code);
}
};
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,54 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <string>
namespace InferenceEngine {
/**
* @brief c++ exception based error reporting wrapper of API class IMemoryState
*/
class MemoryState {
IMemoryState::Ptr actual = nullptr;
public:
explicit MemoryState(IMemoryState::Ptr pState) : actual(pState) {}
/**
* @brief Wraps original method
* IMemoryState::Reset
*/
void Reset() {
CALL_STATUS_FNC_NO_ARGS(Reset);
}
/**
* @brief Wraps original method
* IMemoryState::GetName
*/
std::string GetName() const {
char name[256];
CALL_STATUS_FNC(GetName, name, sizeof(name));
return name;
}
/**
* @brief Wraps original method
* IMemoryState::GetLastState
*/
Blob::CPtr GetLastState() const {
Blob::CPtr stateBlob;
CALL_STATUS_FNC(GetLastState, stateBlob);
return stateBlob;
}
/**
* @brief Wraps original method
* IMemoryState::SetState
*/
void SetState(Blob::Ptr state) {
CALL_STATUS_FNC(SetState, state);
}
};
} // namespace InferenceEngine

View File

@ -0,0 +1,162 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This is a header file for the Inference Engine plugin C++ API
* @file ie_plugin_cpp.hpp
*/
#pragma once
#include <map>
#include <string>
#include <memory>
#include "ie_plugin.hpp"
#include "details/ie_exception_conversion.hpp"
#include "cpp/ie_executable_network.hpp"
#include "ie_plugin_ptr.hpp"
#include "ie_cnn_network.h"
namespace InferenceEngine {
/**
* @brief This class is a C++ API wrapper for IInferencePlugin.
* It can throw exceptions safely for the application, where it is properly handled.
*/
class InferencePlugin {
InferenceEnginePluginPtr actual;
public:
/** @brief A default constructor */
InferencePlugin() = default;
/**
* @brief Constructs a plugin instance from the given pointer.
*/
explicit InferencePlugin(const InferenceEnginePluginPtr &pointer) : actual(pointer) {}
/**
* @brief Wraps original method
* IInferencePlugin::GetVersion
*/
const Version *GetVersion() {
const Version *versionInfo = nullptr;
actual->GetVersion(versionInfo);
return versionInfo;
}
/**
* @brief Wraps original method
* IInferencePlugin::LoadNetwork
*/
void LoadNetwork(ICNNNetwork &network) {
CALL_STATUS_FNC(LoadNetwork, network);
}
/**
* @brief Wraps original method
* IInferencePlugin::LoadNetwork(IExecutableNetwork::Ptr&, ICNNNetwork&, const std::map<std::string, std::string> &, ResponseDesc*).
*/
ExecutableNetwork LoadNetwork(ICNNNetwork &network, const std::map<std::string, std::string> &config) {
IExecutableNetwork::Ptr ret;
CALL_STATUS_FNC(LoadNetwork, ret, network, config);
return ExecutableNetwork(ret);
}
/**
* @brief Wraps original method
* IInferencePlugin::LoadNetwork(IExecutableNetwork::Ptr&, ICNNNetwork&, const std::map<std::string, std::string> &, ResponseDesc*).
*/
ExecutableNetwork LoadNetwork(CNNNetwork network, const std::map<std::string, std::string> &config) {
IExecutableNetwork::Ptr ret;
CALL_STATUS_FNC(LoadNetwork, ret, network, config);
if (ret.get() == nullptr) THROW_IE_EXCEPTION << "Internal error: pointer to executable network is null";
return ExecutableNetwork(ret);
}
/**
* @brief Wraps original method
* IInferencePlugin::Infer(const BlobMap&, BlobMap&, ResponseDesc *resp)
*/
void Infer(const BlobMap &input, BlobMap &result) {
CALL_STATUS_FNC(Infer, input, result);
}
/**
* @brief Wraps original method
* IInferencePlugin::GetPerformanceCounts
*/
std::map<std::string, InferenceEngineProfileInfo> GetPerformanceCounts() const {
std::map<std::string, InferenceEngineProfileInfo> perfMap;
CALL_STATUS_FNC(GetPerformanceCounts, perfMap);
return perfMap;
}
/**
* @brief Wraps original method
* IInferencePlugin::AddExtension
*/
void AddExtension(InferenceEngine::IExtensionPtr extension) {
CALL_STATUS_FNC(AddExtension, extension);
}
/**
* @brief Wraps original method
* IInferencePlugin::SetConfig
*/
void SetConfig(const std::map<std::string, std::string> &config) {
CALL_STATUS_FNC(SetConfig, config);
}
/**
* @brief Wraps original method
* IInferencePlugin::ImportNetwork
*/
ExecutableNetwork ImportNetwork(const std::string &modelFileName, const std::map<std::string, std::string> &config) {
IExecutableNetwork::Ptr ret;
CALL_STATUS_FNC(ImportNetwork, ret, modelFileName, config);
return ExecutableNetwork(ret);
}
/**
* @depricated Use the version with config parameter
* @brief Wraps original method
* IInferencePlugin::QueryNetwork
*/
void QueryNetwork(const ICNNNetwork &network, QueryNetworkResult &res) const {
actual->QueryNetwork(network, res);
if (res.rc != OK) THROW_IE_EXCEPTION << res.resp.msg;
}
/**
* @brief Wraps original method
* IInferencePlugin::QueryNetwork
*/
void QueryNetwork(const ICNNNetwork &network, const std::map<std::string, std::string> &config, QueryNetworkResult &res) const {
actual->QueryNetwork(network, config, res);
if (res.rc != OK) THROW_IE_EXCEPTION << res.resp.msg;
}
/**
* @brief Returns wrapped object
*/
operator InferenceEngine::InferenceEnginePluginPtr() {
return actual;
}
/**
* @return wrapped Hetero object if underlined object is HeteroPlugin instance, nullptr otherwise
*/
operator InferenceEngine::HeteroPluginPtr() {
return actual;
}
/**
* @brief Shared pointer on InferencePlugin object
*/
using Ptr = std::shared_ptr<InferencePlugin>;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,86 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for the BlobIterator class
* @file ie_blob_iterator.hpp
*/
#include "ie_locked_memory.hpp"
#include <utility>
namespace InferenceEngine {
namespace details {
/**
* @brief This class provides range loops support for TBlob objects
*/
template<class T>
class BlobIterator {
LockedMemory<T> _mem;
size_t _offset;
public:
/**
* @brief A move constructor to create a BlobIterator instance from a LockedMemory instance.
* Explicitly rejects implicit conversions.
* @param lk Rvalue of the memory instance to move from
* @param offset Size of offset in memory
*/
explicit BlobIterator(LockedMemory<T> &&lk, size_t offset = 0)
: _mem(std::move(lk)), _offset(offset) {
}
/**
* @brief Increments an offset of the current BlobIterator instance
* @return The current BlobIterator instance
*/
BlobIterator &operator++() {
_offset++;
return *this;
}
/**
* @brief An overloaded postfix incrementation operator
* Implementation does not follow std interface since only move semantics is used
*/
void operator++(int) {
_offset++;
}
/**
* @brief Checks if the given iterator is not equal to the current one
* @param that Iterator to compare with
* @return true if the given iterator is not equal to the current one, false - otherwise
*/
bool operator!=(const BlobIterator &that) const {
return !operator==(that);
}
/**
* @brief Gets a value by the pointer to the current iterator
* @return The value stored in memory for the current offset value
*/
const T &operator*() const {
return *(_mem.template as<const T *>() + _offset);
}
/**
* @brief Gets a value by the pointer to the current iterator
* @return The value stored in memory for the current offset value
*/
T &operator*() {
return *(_mem.template as<T *>() + _offset);
}
/**
* @brief Compares the given iterator with the current one
* @param that Iterator to compare with
* @return true if the given iterator is equal to the current one, false - otherwise
*/
bool operator==(const BlobIterator &that) const {
return &operator*() == &that.operator*();
}
};
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,151 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for the CNNNetworkIterator class
* @file ie_cnn_network_iterator.hpp
*/
#pragma once
#include <utility>
#include <unordered_set>
#include <list>
#include <iterator>
#include "ie_locked_memory.hpp"
#include "ie_icnn_network.hpp"
namespace InferenceEngine {
namespace details {
/**
* @brief This class enables range loops for CNNNetwork objects
*/
class CNNNetworkIterator {
std::unordered_set<CNNLayer*> visited;
std::list<CNNLayerPtr> nextLayersTovisit;
InferenceEngine::CNNLayerPtr currentLayer;
ICNNNetwork * network = nullptr;
public:
/**
* iterator trait definitions
*/
typedef std::forward_iterator_tag iterator_category;
typedef CNNLayerPtr value_type;
typedef int difference_type;
typedef CNNLayerPtr pointer;
typedef CNNLayerPtr reference;
/**
* @brief Default constructor
*/
CNNNetworkIterator() = default;
/**
* @brief Constructor. Creates an iterator for specified CNNNetwork instance.
* @param network Network to iterate. Make sure the network object is not destroyed before iterator goes out of scope.
*/
explicit CNNNetworkIterator(ICNNNetwork * network) {
InputsDataMap inputs;
network->getInputsInfo(inputs);
if (!inputs.empty()) {
auto & nextLayers = inputs.begin()->second->getInputData()->getInputTo();
if (!nextLayers.empty()) {
currentLayer = nextLayers.begin()->second;
nextLayersTovisit.push_back(currentLayer);
visited.insert(currentLayer.get());
}
}
}
/**
* @brief Performs pre-increment
* @return This CNNNetworkIterator instance
*/
CNNNetworkIterator &operator++() {
currentLayer = next();
return *this;
}
/**
* @brief Performs post-increment.
* Implementation does not follow the std interface since only move semantics is used
*/
void operator++(int) {
currentLayer = next();
}
/**
* @brief Checks if the given iterator is not equal to this one
* @param that Iterator to compare with
* @return true if the given iterator is not equal to this one, false - otherwise
*/
bool operator!=(const CNNNetworkIterator &that) const {
return !operator==(that);
}
/**
* @brief Gets const layer pointer referenced by this iterator
*/
const CNNLayerPtr &operator*() const {
if (nullptr == currentLayer) {
THROW_IE_EXCEPTION << "iterator of ouf bound";
}
return currentLayer;
}
/**
* @brief Gets a layer pointer referenced by this iterator
*/
CNNLayerPtr &operator*() {
if (nullptr == currentLayer) {
THROW_IE_EXCEPTION << "iterator out of bound";
}
return currentLayer;
}
/**
* @brief Compares the given iterator with this one
* @param that Iterator to compare with
* @return true if the given iterator is equal to this one, false - otherwise
*/
bool operator==(const CNNNetworkIterator &that) const {
return network == that.network && currentLayer == that.currentLayer;
}
private:
/**
* @brief implementation based on BFS
*/
CNNLayerPtr next() {
if (nextLayersTovisit.empty()) {
return nullptr;
}
auto nextLayer = nextLayersTovisit.front();
nextLayersTovisit.pop_front();
// visit child that not visited
for (auto && output : nextLayer->outData) {
for (auto && child : output->getInputTo()) {
if (visited.find(child.second.get()) == visited.end()) {
nextLayersTovisit.push_back(child.second);
visited.insert(child.second.get());
}
}
}
// visit parents
for (auto && parent : nextLayer->insData) {
auto parentLayer = parent.lock()->getCreatorLayer().lock();
if (parentLayer && visited.find(parentLayer.get()) == visited.end()) {
nextLayersTovisit.push_back(parentLayer);
visited.insert(parentLayer.get());
}
}
return nextLayersTovisit.empty() ? nullptr : nextLayersTovisit.front();
}
};
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,154 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for the main Inference Engine exception
* \file ie_exception.hpp
*/
#pragma once
#include <memory>
#include <string>
#include <sstream>
#include <vector>
#include <functional>
#include <utility>
/**
* @def THROW_IE_EXCEPTION
* @brief A macro used to throw the exception with a notable description
*/
#define THROW_IE_EXCEPTION\
throw InferenceEngine::details::InferenceEngineException(__FILE__, __LINE__)\
/**
* @def IE_ASSERT
* @brief Uses assert() function if NDEBUG is not defined, InferenceEngine exception otherwise
*/
#ifdef NDEBUG
#define IE_ASSERT(EXPRESSION)\
if (!(EXPRESSION)) throw InferenceEngine::details::InferenceEngineException(__FILE__, __LINE__) << "AssertionFailed: " << #EXPRESSION // NOLINT
#else
#include <cassert>
#define IE_ASSERT(EXPRESSION)\
assert((EXPRESSION)); std::stringstream()
#endif // NDEBUG
namespace InferenceEngine {
enum StatusCode: int;
namespace details {
/**
* @brief The InferenceEngineException class implements the main Inference Engine exception
*/
class InferenceEngineException : public std::exception {
mutable std::string errorDesc;
StatusCode status_code = static_cast<StatusCode>(0);
std::string _file;
int _line;
std::shared_ptr<std::stringstream> exception_stream;
bool save_to_status_code = false;
public:
/**
* @brief A C++ std::exception API member
* @return An exception description with a file name and file line
*/
const char *what() const noexcept override {
if (errorDesc.empty() && exception_stream) {
errorDesc = exception_stream->str();
#ifndef NDEBUG
errorDesc += "\n" + _file + ":" + std::to_string(_line);
#endif
}
return errorDesc.c_str();
}
/**
* @brief A constructor. Creates an InferenceEngineException object from a specific file and line
* @param filename File where exception has been thrown
* @param line Line of the exception emitter
*/
InferenceEngineException(const std::string &filename, const int line)
: _file(filename), _line(line) {
}
/**
* @brief noexcept required for copy ctor
* @details The C++ Standard, [except.throw], paragraph 3 [ISO/IEC 14882-2014]
*/
InferenceEngineException(const InferenceEngineException & that) noexcept {
errorDesc = that.errorDesc;
status_code = that.status_code;
_file = that._file;
_line = that._line;
exception_stream = that.exception_stream;
}
/**
* @brief A stream output operator to be used within exception
* @param arg Object for serialization in the exception message
*/
template<class T>
InferenceEngineException& operator<<(const T &arg) {
if (save_to_status_code) {
auto can_convert = status_code_assign(arg);
save_to_status_code = false;
if (can_convert.second) {
this->status_code = can_convert.first;
return *this;
}
}
if (!exception_stream) {
exception_stream.reset(new std::stringstream());
}
(*exception_stream) << arg;
return *this;
}
/**
* @brief Manipulator to indicate that next item has to be converted to StatusCode to save
* @param iex InferenceEngineException object
*/
friend InferenceEngineException& as_status(InferenceEngineException& iex) {
iex.save_to_status_code = true;
return iex;
}
/**
* @brief A stream output operator to catch InferenceEngineException manipulators
* @param manip InferenceEngineException manipulator to call
*/
InferenceEngineException& operator<<(InferenceEngineException& (*manip)(InferenceEngineException &)) {
return manip(*this);
}
/** @brief Check if it has StatusCode value */
bool hasStatus() const {
return this->status_code == 0 ? false : true;
}
/** @brief Get StatusCode value */
StatusCode getStatus() const {
return this->status_code;
}
private:
std::pair<StatusCode, bool> status_code_assign(const StatusCode& status) {
return {status, true};
}
template <typename T>
std::pair<StatusCode, bool> status_code_assign(const T & arg) {
return {static_cast<StatusCode>(0), false};
}
};
InferenceEngineException& as_status(InferenceEngineException& iex);
static_assert(std::is_nothrow_copy_constructible<InferenceEngineException>::value,
"InferenceEngineException must be nothrow copy constructible");
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,76 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file that provides macros to handle no exception methods
* @file ie_exception_conversion.hpp
*/
#pragma once
#include <ie_common.h>
#define CALL_STATUS_FNC(function, ...)\
ResponseDesc resp;\
auto res = actual->function(__VA_ARGS__, &resp);\
if (res != OK) InferenceEngine::details::extract_exception(res, resp.msg);
#define CALL_STATUS_FNC_NO_ARGS(function)\
ResponseDesc resp;\
auto res = actual->function(&resp);\
if (res != OK) InferenceEngine::details::extract_exception(res, resp.msg);
#define CALL_FNC(function, ...)\
ResponseDesc resp;\
auto result = actual->function(__VA_ARGS__, &resp);\
if (resp.msg[0] != '\0') {\
THROW_IE_EXCEPTION << resp.msg;\
}\
return result;
#define CALL_FNC_REF(function, ...)\
ResponseDesc resp;\
auto & result = actual->function(__VA_ARGS__, &resp);\
if (resp.msg[0] != '\0') {\
THROW_IE_EXCEPTION << resp.msg;\
}\
return result;
#define CALL_FNC_NO_ARGS(function)\
ResponseDesc resp;\
auto result = actual->function(&resp);\
if (resp.msg[0] != '\0') {\
THROW_IE_EXCEPTION << resp.msg;\
}\
return result;
#define CALL_FNC_NO_ARGS_REF(function)\
ResponseDesc resp;\
auto & result = actual->function(&resp);\
if (resp.msg[0] != '\0') {\
THROW_IE_EXCEPTION << resp.msg;\
}\
return result;
namespace InferenceEngine {
namespace details {
inline void extract_exception(StatusCode status, char *msg) {
switch (status) {
case NOT_IMPLEMENTED:throw NotImplemented(msg);
case NETWORK_NOT_LOADED:throw NetworkNotLoaded(msg);
case PARAMETER_MISMATCH:throw ParameterMismatch(msg);
case NOT_FOUND:throw NotFound(msg);
case OUT_OF_BOUNDS:throw OutOfBounds(msg);
case UNEXPECTED:throw Unexpected(msg);
case REQUEST_BUSY:throw RequestBusy(msg);
case RESULT_NOT_READY:throw ResultNotReady(msg);
case NOT_ALLOCATED:throw NotAllocated(msg);
case INFER_NOT_STARTED:throw InferNotStarted(msg);
default:THROW_IE_EXCEPTION << msg;
}
}
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,45 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for the Inference Engine plugins destruction mechanism
* @file ie_irelease.hpp
*/
#pragma once
#include "ie_no_copy.hpp"
#include <memory>
namespace InferenceEngine {
namespace details {
/**
* @brief This class is used for objects allocated by a shared module (in *.so)
*/
class IRelease : public no_copy {
public:
/**
* @brief Releases current allocated object and all related resources.
* Once this method is called, the pointer to this interface is no longer valid
*/
virtual void Release() noexcept = 0;
protected:
/**
* @brief Default destructor
*/
~IRelease() override = default;
};
template <class T> inline std::shared_ptr<T> shared_from_irelease(T * ptr) {
std::shared_ptr<T> pointer(ptr, [](IRelease *p) {
p->Release();
});
return pointer;
}
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,50 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief header file for no_copy class
* @file ie_no_copy.hpp
*/
#pragma once
namespace InferenceEngine {
namespace details {
/**
* @brief This class is used for objects returned from the shared library factory to prevent copying
*/
class no_copy {
protected:
/**
* @brief A default constructor
*/
no_copy() = default;
/**
* @brief A default destructor
*/
virtual ~no_copy() = default;
/**
* @brief A removed copy constructor
*/
no_copy(no_copy const &) = delete;
/**
* @brief A removed assign operator
*/
no_copy &operator=(no_copy const &) = delete;
/**
* @brief A removed move constructor
*/
no_copy(no_copy &&) = delete;
/**
* @brief A removed move operator
*/
no_copy &operator=(no_copy &&) = delete;
};
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,25 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief Utility header file. Provides no release base class
* @file ie_no_release.hpp
*/
#pragma once
namespace InferenceEngine {
namespace details {
/**
* @brief prevent Release method from being called on specific objects
*/
template<class T>
class NoReleaseOn : public T {
private :
void Release() noexcept = 0;
};
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,87 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief The header file defines utility PreAllocator class
* @file ie_pre_allocator.hpp
*/
#pragma once
#include <details/ie_exception.hpp>
#include "ie_allocator.hpp"
#include <memory>
namespace InferenceEngine {
namespace details {
/*
* @brief This is a helper class to wrap external memory
*/
class PreAllocator : public IAllocator {
void * _actualData;
size_t _sizeInBytes;
public:
PreAllocator(void *ptr, size_t bytes_size)
: _actualData(ptr), _sizeInBytes(bytes_size) {}
/**
* @brief Locks a handle to heap memory accessible by any memory manipulation routines
* @return The generic pointer to a memory buffer
*/
void * lock(void * handle, LockOp = LOCK_FOR_WRITE) noexcept override {
if (handle != _actualData) {
return nullptr;
}
return handle;
}
/**
* @brief The PreAllocator class does not utilize this function
* @param handle Memory handle to unlock
*/
void unlock(void * handle) noexcept override {}
/**
* @brief Returns a pointer to preallocated memory
* @param size Size in bytes
* @return A handle to the preallocated memory or nullptr
*/
void * alloc(size_t size) noexcept override {
if (size <= _sizeInBytes) {
return _actualData;
}
return this;
}
/**
* @brief The PreAllocator class cannot release the handle
* @param handle Memory handle to release
* @return false
*/
bool free(void* handle) noexcept override { return false;}
/**
* @brief Deletes current allocator.
* Can be used if a shared_from_irelease pointer is used
*/
void Release() noexcept override {
delete this;
}
protected:
virtual ~PreAllocator() = default;
};
/**
* @brief Creates a special allocator that only works on external memory
* @param ptr Pointer to preallocated memory
* @param size Number of elements allocated
* @return A new allocator
*/
template <class T>
std::shared_ptr<IAllocator> make_pre_allocator(T *ptr, size_t size) {
return shared_from_irelease(new PreAllocator(ptr, size * sizeof(T)));
}
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,16 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for definition of abstraction over platform specific shared objects
* @file ie_so_loader.h
*/
#pragma once
#ifndef _WIN32
#include "os/lin_shared_object_loader.h"
#else
#include "os/win_shared_object_loader.h"
#endif

View File

@ -0,0 +1,166 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This is a wrapper class for handling plugin instantiation and releasing resources
* @file ie_so_pointer.hpp
*/
#pragma once
#include <memory>
#include "ie_so_loader.h"
#include "ie_common.h"
#include "ie_plugin.hpp"
#include "details/ie_exception.hpp"
#include "details/ie_no_release.hpp"
#include <string>
#include <cassert>
namespace InferenceEngine {
namespace details {
/**
* @brief This class is a C++ helper to load a symbol from a library and create its instance
*/
template<class Loader>
class SymbolLoader {
private:
std::shared_ptr<Loader> _so_loader;
public:
/**
* @brief The main constructor
* @param loader Library to load from
*/
explicit SymbolLoader(std::shared_ptr<Loader> loader) : _so_loader(loader) {}
/**
* @brief Calls a function from the library that creates an object and returns StatusCode
* @param name Name of function to load object with
* @return If StatusCode provided by function is OK then returns the loaded object. Throws an exception otherwise
*/
template<class T>
T* instantiateSymbol(const std::string& name) const {
T* instance = nullptr;
ResponseDesc desc;
StatusCode sts = bind_function<StatusCode(T*&, ResponseDesc*)>(name)(instance, &desc);
if (sts != OK) {
THROW_IE_EXCEPTION << desc.msg;
}
return instance;
}
/**
* @brief Loads function from the library and returns a pointer to it
* @param functionName Name of function to load
* @return The loaded function
*/
template<class T>
std::function<T> bind_function(const std::string &functionName) const {
std::function<T> ptr(reinterpret_cast<T *>(_so_loader->get_symbol(functionName.c_str())));
return ptr;
}
};
/**
* @brief This class is a trait class that provides a creator with a function name corresponding to the templated class parameter
*/
template<class T>
class SOCreatorTrait {};
/**
* @brief This class instantiate object using shared library
*/
template <class T, class Loader = SharedObjectLoader>
class SOPointer {
template <class U, class W> friend class SOPointer;
public:
/**
* @brief Default constructor
*/
SOPointer() = default;
/**
* @brief The main constructor
* @param name Name of a shared library file
*/
explicit SOPointer(const std::string &name)
: _so_loader(new Loader(name.c_str()))
, _pointedObj(details::shared_from_irelease(
SymbolLoader<Loader>(_so_loader).template instantiateSymbol<T>(SOCreatorTrait<T>::name))) {
}
/**
* @brief The copy-like constructor, can create So Pointer that dereferenced into child type if T is derived of U
* @param that copied SOPointer object
*/
template<class U, class W>
SOPointer(const SOPointer<U, W> & that) :
_so_loader(std::dynamic_pointer_cast<Loader>(that._so_loader)),
_pointedObj(std::dynamic_pointer_cast<T>(that._pointedObj)) {
}
/**
* @brief Standard pointer operator
* @return underlined interface with disabled Release method
*/
details::NoReleaseOn<T>* operator->() const noexcept {
return reinterpret_cast<details::NoReleaseOn<T>*>(_pointedObj.get());
}
/**
* @brief Standard dereference operator
* @return underlined interface with disabled Release method
*/
details::NoReleaseOn<T>* operator*() const noexcept {
return this->operator->();
}
explicit operator bool() const noexcept {
return (nullptr != _so_loader) && (nullptr != _pointedObj);
}
friend bool operator == (std::nullptr_t, const SOPointer& ptr) noexcept {
return !ptr;
}
friend bool operator == (const SOPointer& ptr, std::nullptr_t) noexcept {
return !ptr;
}
friend bool operator != (std::nullptr_t, const SOPointer& ptr) noexcept {
return static_cast<bool>(ptr);
}
friend bool operator != (const SOPointer& ptr, std::nullptr_t) noexcept {
return static_cast<bool>(ptr);
}
SOPointer& operator=(const SOPointer & pointer) noexcept {
_pointedObj = pointer._pointedObj;
_so_loader = pointer._so_loader;
return *this;
}
protected:
/**
* @brief Gets a smart pointer to the DLL
*/
std::shared_ptr<Loader> _so_loader;
/**
* @brief Gets a smart pointer to the custom object
*/
std::shared_ptr<T> _pointedObj;
};
} // namespace details
/**
* @brief Creates a special shared_pointer wrapper for the given type from a specific shared module
* @param name Name of the shared library file
*/
template <class T>
inline std::shared_ptr<T> make_so_pointer(const std::string & name) = delete;
} // namespace InferenceEngine

View File

@ -0,0 +1,62 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief POSIX compatible loader for a shared object
* @file lin_shared_object_loader.h
*/
#pragma once
#include <dlfcn.h>
#include "../../ie_api.h"
#include "../ie_exception.hpp"
namespace InferenceEngine {
namespace details {
/**
* @brief This class provides an OS shared module abstraction
*/
class SharedObjectLoader {
private:
void *shared_object = nullptr;
public:
/**
* @brief Loads a library with the name specified. The library is loaded according to
* the POSIX rules for dlopen
* @param pluginName Full or relative path to the library
*/
explicit SharedObjectLoader(const char* pluginName) {
shared_object = dlopen(pluginName, RTLD_LAZY);
if (shared_object == nullptr)
THROW_IE_EXCEPTION << "Cannot load library '" << pluginName << "': " << dlerror();
}
~SharedObjectLoader() noexcept(false) {
if (0 != dlclose(shared_object)) {
THROW_IE_EXCEPTION << "dlclose failed: " << dlerror();
}
}
/**
* @brief Searches for a function symbol in the loaded module
* @param symbolName Name of the function to find
* @return A pointer to the function if found
* @throws InferenceEngineException if the function is not found
*/
void *get_symbol(const char* symbolName) const {
void * procAddr = nullptr;
procAddr = dlsym(shared_object, symbolName);
if (procAddr == nullptr)
THROW_IE_EXCEPTION << "dlSym cannot locate method '" << symbolName << "': " << dlerror();
return procAddr;
}
};
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,71 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief WINAPI compatible loader for a shared object
* @file win_shared_object_loader.h
*/
#pragma once
#include "../../ie_api.h"
#include "../ie_exception.hpp"
// Avoidance of Windows.h to include winsock library.
#define _WINSOCKAPI_
// Avoidance of Windows.h to define min/max.
#define NOMINMAX
#include <windows.h>
#include <direct.h>
namespace InferenceEngine {
namespace details {
/**
* @brief This class provides an OS shared module abstraction
*/
class SharedObjectLoader {
private:
HMODULE shared_object;
public:
/**
* @brief Loads a library with the name specified. The library is loaded according to the
* WinAPI LoadLibrary rules
* @param pluginName Full or relative path to the plugin library
*/
explicit SharedObjectLoader(const char* pluginName) {
char cwd[1024];
shared_object = LoadLibrary(pluginName);
if (!shared_object) {
THROW_IE_EXCEPTION << "Cannot load library '"
<< pluginName << "': "
<< GetLastError()
<< " from cwd: " << _getcwd(cwd, 1024);
}
}
~SharedObjectLoader() {
FreeLibrary(shared_object);
}
/**
* @brief Searches for a function symbol in the loaded module
* @param symbolName Name of function to find
* @return A pointer to the function if found
* @throws InferenceEngineException if the function is not found
*/
void *get_symbol(const char* symbolName) const {
if (!shared_object) {
THROW_IE_EXCEPTION << "Cannot get '" << symbolName << "' content from unknown library!";
}
auto procAddr = reinterpret_cast<void*>(GetProcAddress(shared_object, symbolName));
if (procAddr == nullptr)
THROW_IE_EXCEPTION << "GetProcAddress cannot locate method '" << symbolName << "': " << GetLastError();
return procAddr;
}
};
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,34 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header that defines advanced related properties for Heterogeneous plugins.
* These properties should be used in SetConfig() and LoadNetwork() methods of plugins
*
* @file hetero_plugin_config.hpp
*/
#pragma once
#include <string>
#include "../ie_plugin_config.hpp"
namespace InferenceEngine {
namespace HeteroConfigParams {
#define HETERO_CONFIG_KEY(name) InferenceEngine::HeteroConfigParams::_CONFIG_KEY(HETERO_##name)
#define DECLARE_HETERO_CONFIG_KEY(name) DECLARE_CONFIG_KEY(HETERO_##name)
#define DECLARE_HETERO_CONFIG_VALUE(name) DECLARE_CONFIG_VALUE(HETERO_##name)
/**
* @brief The key for enabling of dumping the topology with details of layers and details how
* this network would be executed on different devices to the disk in GraphViz format.
* This option should be used with values: CONFIG_VALUE(NO) (default) or CONFIG_VALUE(YES)
*/
DECLARE_HETERO_CONFIG_KEY(DUMP_GRAPH_DOT);
} // namespace HeteroConfigParams
} // namespace InferenceEngine

View File

@ -0,0 +1,66 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file that provides Allocator interface
* @file ie_allocator.hpp
*/
#pragma once
#include <details/ie_irelease.hpp>
#include <ie_api.h>
namespace InferenceEngine {
/**
* @brief Allocator handle mapping type
*/
enum LockOp {
LOCK_FOR_READ = 0,
LOCK_FOR_WRITE
};
/**
* @brief Allocator concept to be used for memory management and is used as part of the Blob.
*/
class IAllocator : public details::IRelease {
public:
/**
* @brief Maps handle to heap memory accessible by any memory manipulation routines.
* @return Generic pointer to memory
*/
virtual void * lock(void * handle, LockOp = LOCK_FOR_WRITE) noexcept = 0;
/**
* @brief Unmaps memory by handle with multiple sequential mappings of the same handle.
* The multiple sequential mappings of the same handle are suppose to get the same
* result while there isn't a ref counter supported.
*/
virtual void unlock(void * handle) noexcept = 0;
/**
* @brief Allocates memory
* @param size The size in bytes to allocate
* @return Handle to the allocated resource
*/
virtual void * alloc(size_t size) noexcept = 0;
/**
* @brief Releases handle and all associated memory resources which invalidates the handle.
* @return false if handle cannot be released, otherwise - true.
*/
virtual bool free(void* handle) noexcept = 0;
protected:
/**
* @brief Disables the ability of deleting the object without release.
*/
~IAllocator()override = default;
};
/**
* @brief Creates the default implementation of the Inference Engine allocator per plugin.
* @return The Inference Engine IAllocator* instance
*/
INFERENCE_ENGINE_API(InferenceEngine::IAllocator*)CreateDefaultAllocator() noexcept;
} // namespace InferenceEngine

View File

@ -0,0 +1,30 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief The macro defines a symbol import/export mechanism essential for Microsoft Windows(R) OS.
* @file ie_api.h
*/
#pragma once
#include "details/ie_no_copy.hpp"
#if defined(_WIN32) && !defined(USE_STATIC_IE)
#define INFERENCE_ENGINE_CDECL
#ifdef IMPLEMENT_INFERENCE_ENGINE_API
#define INFERENCE_ENGINE_API(type) extern "C" __declspec(dllexport) type __cdecl
#define INFERENCE_ENGINE_API_CPP(type) __declspec(dllexport) type __cdecl
#define INFERENCE_ENGINE_API_CLASS(type) __declspec(dllexport) type
#else
#define INFERENCE_ENGINE_API(type) extern "C" __declspec(dllimport) type __cdecl
#define INFERENCE_ENGINE_API_CPP(type) __declspec(dllimport) type __cdecl
#define INFERENCE_ENGINE_API_CLASS(type) __declspec(dllimport) type
#endif
#else
#define INFERENCE_ENGINE_API(TYPE) extern "C" TYPE
#define INFERENCE_ENGINE_API_CPP(type) type
#define INFERENCE_ENGINE_API_CLASS(type) type
#define INFERENCE_ENGINE_CDECL __attribute__((cdecl))
#endif

View File

@ -0,0 +1,778 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for Blob and generic TBlob<>
* @file ie_blob.h
*/
#pragma once
#include <memory>
#include <vector>
#include <string>
#include <numeric>
#include <cstring>
#include <utility>
#include <functional>
#include <map>
#include "ie_common.h"
#include "details/ie_exception.hpp"
#include "details/ie_blob_iterator.hpp"
#include "ie_allocator.hpp"
#include "ie_locked_memory.hpp"
#include "ie_precision.hpp"
#include "ie_layouts.h"
#include "details/ie_pre_allocator.hpp"
namespace InferenceEngine {
/**
* @brief This class implements a container object that represents a tensor in memory (host and remote/accelerated)
*/
class Blob {
public:
/**
* @brief A smart pointer containing Blob object
*/
using Ptr = std::shared_ptr<Blob>;
/**
* @brief A smart pointer to the const Blob object
*/
using CPtr = std::shared_ptr<const Blob>;
/**
* @deprecated Please use TensorDesc to get the precision
* @brief Returns the tensor precision of the current Blob object
*/
Precision type() const noexcept {
return tensorDesc.getPrecision();
}
/**
* @deprecated Please use TensorDesc to get the precision
* @brief Returns the tensor precision of the current Blob object
*/
Precision precision() const noexcept {
return tensorDesc.getPrecision();
}
/**
* @deprecated Please use TensorDesc to get the current layout
* @brief Returns the tensor layout of the current Blob object
*/
Layout layout() const noexcept {
return tensorDesc.getLayout();
}
/**
* @brief Creates a TBlob<> object from a Data node
* @param Data reference to a smart pointer of the Data node
* @return Smart pointer to TBlob<> with the relevant C type to the precision of the data node
*/
static Ptr CreateFromData(const DataPtr &data);
/**
* @brief Blob virtual destructor
*/
virtual ~Blob() = default;
/**
* @brief Constructor. Creates an empty Blob object with the specified precision.
* @param tensorDesc Defines the layout and dims of the blob
*/
explicit Blob(TensorDesc tensorDesc): tensorDesc(tensorDesc) {}
/**
* @deprecated Please use TensorDesc for Blob initialization
* @brief Constructor. Creates an empty Blob object with the specified precision.
* @param p Precision type
*/
explicit Blob(Precision p) : Blob(p, NCHW) {}
/**
* @deprecated Please use TensorDesc for Blob initialization
* @brief The constructor creates an empty Blob object with the specified precision and layout.
* @param p Precision type
* @param l Layout
*/
Blob(Precision p, Layout l) : tensorDesc(p, l) {}
/**
* @deprecated Please use TensorDesc for Blob initialization
* @brief The constructor creates an empty Blob object with the specified precision and dimensions.
* @param p Tensor precision type
* @param dims Tensor dimensions vector
*/
Blob(Precision p, const SizeVector &dims)
: Blob(p, TensorDesc::getLayoutByDims(dims), dims) {}
/**
* @deprecated Please use TensorDesc for Blob initialization
* @brief The constructor creates an empty Blob object with the specified precision, layout and dimensions.
* @param p tensor precision type
* @param l tensor layout
* @param dims Tensor dimensions vector with reversed order
*/
Blob(Precision p, Layout l, const SizeVector &dims)
: tensorDesc(p, SizeVector(dims.rbegin(), dims.rend()), l) {}
/**
* @depricated It works with reversed dimensions. Please create a new blob if you want to change a size.
* @brief Changes Tensor size to the specified dimensions. If it was allocated, the previous data is deallocated and lost.
* @param dims New dimensions to set
* @param layout New layout to set
* @return Total number of elements (a product of all the dimensions)
*/
size_t Resize(const SizeVector &dims, Layout layout = Layout::ANY) {
bool bret = deallocate();
if (layout != Layout::ANY) {
tensorDesc = TensorDesc(tensorDesc.getPrecision(), SizeVector(dims.rbegin(), dims.rend()), layout);
} else {
tensorDesc.setDims(SizeVector(dims.rbegin(), dims.rend()));
}
if (!bret) {
allocate();
}
return product(tensorDesc.getDims());
}
/**
* @deprecated It works with reversed dimensions. Please use TensorDescriptor.reshape().
* @brief Changes tensor size to the specified dimensions without changing memory. The total size remains unchanged as well as the memory layout.
* @param dims New dimensions to set
* @param layout New layout to set
* @return The total number of elements (a product of all the dims)
*/
size_t Reshape(const SizeVector &dims, Layout layout = Layout::ANY) {
if (product(tensorDesc.getDims()) != product(dims)) {
THROW_IE_EXCEPTION << "cannot reshape when total size changes";
}
if (layout != Layout::ANY) {
tensorDesc = TensorDesc(tensorDesc.getPrecision(), SizeVector(dims.rbegin(), dims.rend()), layout);
} else {
tensorDesc.setDims(SizeVector(dims.rbegin(), dims.rend()));
}
return product(tensorDesc.getDims());
}
/**
* @deprecated Please use TensorDesc for working with dimensions.
* @brief Returns the tensor dimensions vector with reversed order.
*/
const SizeVector dims() const {
return SizeVector(tensorDesc.getDims().rbegin(), tensorDesc.getDims().rend());
}
/**
* @brief Returns the tensor description
*/
const TensorDesc &getTensorDesc() const {
return tensorDesc;
}
/**
* @brief Returns the total number of elements (a product of all the dims)
*/
size_t size() const {
return product(tensorDesc.getDims());
}
/**
* @brief Returns the size of the current Blob in bytes.
*/
size_t byteSize() const {
return product(tensorDesc.getDims()) * element_size();
}
/**
* @brief Returns the number of bytes per element. The overall Blob capacity is size() * element_size().
* Abstract method.
*/
virtual size_t element_size() const noexcept = 0;
/**
* @brief Allocates memory to store the data.
* Abstract method.
*/
virtual void allocate() = 0;
/**
* @brief Releases previously allocated data.
* Abstract method.
*/
virtual bool deallocate() = 0;
/**
* @brief Gets access to the allocated memory.
* Abstract method.
* @return A LockedMemory object
*/
virtual LockedMemory<void> buffer() = 0;
/**
* @brief Gets read-only access to the allocated memory.
* Abstract method.
* @return A LockedMemory object
*/
virtual LockedMemory<const void> cbuffer() const = 0;
protected:
/**
* @brief The tensor descriptor of the given blob.
*/
TensorDesc tensorDesc;
/**
* @brief Multiplies the dimension vector's values.
* @param dims Reference to a vector with dimension values of type size_t
* @return Result of multiplication
*/
static size_t product(const SizeVector &dims) {
if (dims.empty())
return 0;
return std::accumulate(std::begin(dims), std::end(dims), (size_t) 1, std::multiplies<size_t>());
}
/**
* @brief Gets the allocator for allocator-based blobs.
* @return The allocator for allocator-based blobs or if there is none then a nullptr.
*/
virtual const std::shared_ptr<IAllocator> &getAllocator() const noexcept = 0;
/**
* @brief Gets the handle to allocated memory.
* @return The handle to allocated memory for allocator-based blobs or if there is none then a nullptr.
*/
virtual void *getHandle() const noexcept = 0;
template<typename> friend
class TBlobProxy;
};
/**
* @brief This is a convenient type for working with a map containing pairs(string, pointer to a Blob instance).
*/
using BlobMap = std::map<std::string, Blob::Ptr>;
/**
* @brief Represents real host memory allocated for a Tensor/Blob per C type.
*/
template<typename T,
typename = std::enable_if<std::is_pod<T>::value>>
class TBlob : public Blob {
template<typename, typename> friend
class TBlob;
public:
/**
* @brief Smart Pointer to this TBlob object.
*/
using Ptr = std::shared_ptr<TBlob<T>>;
/**
* @brief Creates a TBlob object with the specified dimensions and layout but does not allocate the memory.
* Please use the allocate() method to allocate memory.
* @param tensorDesc Tensor description
*/
explicit TBlob(const TensorDesc& tensorDesc): Blob(tensorDesc) {}
/**
* @brief The constructor creates a TBlob object with the specified dimensions and layout
* on the pre-allocated memory. The allocate() call is not required.
* @param tensorDesc Tensor description
* @param ptr Pointer to the pre-allocated memory
* @param data_size Length of the pre-allocated array. If not set, size is assumed equal
* to the dot product of dims.
*/
TBlob(const TensorDesc& tensorDesc, T* ptr, size_t data_sze = 0): Blob(tensorDesc) {
if (size() != 0 && ptr == nullptr) {
THROW_IE_EXCEPTION << "Using Blob on external nullptr memory";
}
_allocator = details::make_pre_allocator(ptr, size());
// blob on attached memory is always allocated, so we are not forcing the user to call allocate()
allocate();
}
/**
* @deprecated Please use TensorDesc for Blob initialization.
*/
explicit TBlob(Precision p, Layout l) : Blob(p, l) {}
/**
* @deprecated Please use TensorDesc for Blob initialization.
* @brief Creates a TBlob object with the specified dimensions but does not allocate the memory. Please use the allocate() method to allocate memory.
* @param p Precision
* @param l Layout
* @param dims Tensor dimensions
*/
TBlob(Precision p, Layout l, const SizeVector& dims)
: Blob(p, l, dims) {
}
/**
* @deprecated Please use TensorDesc for Blob initialization.
* @brief The constructor creates a TBlob object with the specified dimensions on the pre-allocated memory. Therefore, the allocate() call is not required.
* @details The TBlob object doesn't own memory that is pointed to by the ptr. Therefore, it doesn't free the memory after the TBlob object is destroyed.
* Also certain operations might fail:
* After the blob is constructed with this pointer its size is stored in the TBlob instance.
* If the resize() operation happens which requires more memory, then the call to allocate() fails.
* @param p Precision
* @param dims Tensor dimensions
* @param ptr Pointer to the pre-allocated memory
* @param data_size Length of the pre-allocated array. If not set, size is assumed equal to dot product of dims.
*/
TBlob(Precision p, Layout l, const SizeVector& dims, T* ptr, size_t data_sze = 0) : Blob(p, l, dims) {
if (size() != 0 && ptr == nullptr) {
THROW_IE_EXCEPTION << "Using Blob on external nullptr memory";
}
_allocator = details::make_pre_allocator(ptr, size());
// blob on attached memory is always allocated, so we are not forcing user to call allocate
allocate();
}
/**
* @deprecated Please use TensorDesc for Blob initialization.
* @brief Constructor. Creates a TBlob object with the specified precision, layout, dimensions and custom memory allocator.
* @param p Precision
* @param l Layout
* @param dims Tensor dimensions
* @param alloc Allocator to be used
*/
TBlob(Precision p, Layout l, const SizeVector &dims, std::shared_ptr<IAllocator> alloc)
: Blob(p, l, dims), _allocator(alloc) {
}
/**
* @brief The copy constructor data is reallocated and copied from the source to the target blob.
* @param blob Source blob
*/
TBlob(const TBlob<T> &blob) : Blob(blob.getTensorDesc()) {
copyFrom(blob);
}
/**
* @brief A move constructor.
* @param blob rvalue to make a move from
*/
TBlob(TBlob<T> &&blob) : Blob(blob.getTensorDesc()) {
moveFrom(blob);
}
/**
* @brief Copy operator for the TBlob object.
* @param blob object reference to copy from
* @return Newly copied object
*/
TBlob &operator=(const TBlob &blob) {
copyFrom(blob);
return *this;
}
/**
*@brief Virtual destructor.
*/
virtual ~TBlob() {
free();
}
/**
* @brief Gets the size of the given type.
* @return Size of the type
*/
size_t element_size() const noexcept override {
return sizeof(T);
}
/**
* @brief Creates an new empty rvalue LockedMemory object.
* @return rvalue for the empty locked object of type T
*/
virtual LockedMemory<T> data() {
return std::move(lockme<T>());
}
/**
* @brief Creates a new empty rvalue read-only LockedMemory object.
* @return rvalue for the empty locked const object of type T.
*/
virtual LockedMemory<const T> readOnly() const {
return std::move(lockme<const T>());
}
/**
* @deprecated Deprecated to avoid memcpy() calls.
* @brief Copies data from the given vector to the blob.
* @param that Vector of values to copy to the blob
*/
void set(const std::vector<T> &that) {
if (tensorDesc.getDims().size() != 0 && that.size() != product(tensorDesc.getDims()))
THROW_IE_EXCEPTION << "Size mismatch between dims and vector";
if (tensorDesc.getDims().size() == 0) {
tensorDesc.setDims({static_cast<unsigned int>(that.size())});
}
allocate();
auto memptr = data();
memcpy(memptr, that.data(), product(tensorDesc.getDims()) * sizeof(T));
}
/**
* @brief Allocates or reallocates memory
*/
void allocate() override {
if (_handle != nullptr) {
getAllocator()->free(_handle);
}
_handle = getAllocator()->alloc(TBlob<T>::product(tensorDesc.getDims()) * sizeof(T));
}
/**
* @brief Frees all allocated data
*/
bool deallocate() override {
return free();
}
/**
* @brief Creates a new LockedMemory instance holding void pointer.
* @return LockedMemory instance holding void pointer
*/
LockedMemory<void> buffer() override {
return std::move(lockme<void>());
}
/**
* @brief Creates a new LockedMemory instance holding constant void pointer.
* @return LockedMemory instance holding constant void pointer
*/
LockedMemory<const void> cbuffer() const override {
return std::move(lockme<const void>());
}
/**
* @brief Gets BlobIterator for the data.
* Enables a ranged loop support for the TBlob object.
* @return BlobIterator object of type T
*/
details::BlobIterator<T> begin() {
return details::BlobIterator<T>(data());
}
/**
* @brief Gets BlobIterator for the end of data.
* Enables a ranged loop support for the TBlob object.
* @return BlobIterator object of type T representing end of the data
*/
details::BlobIterator<T> end() {
return details::BlobIterator<T>(data(), size());
}
/**
* @brief Gets a const BlobIterator for the read-only data.
* Enables a ranged loop support for the TBlob object.
* @return BlobIterator object of type const T
*/
details::BlobIterator<const T> begin() const {
return details::BlobIterator<const T>(readOnly());
}
/**
* @brief Gets a const BlobIterator for the end of read-only data.
* Enables a ranged loop support for the TBlob object.
* @return BlobIterator object of type const T representing end of data
*/
details::BlobIterator<const T> end() const {
return details::BlobIterator<const T>(readOnly(), size());
}
protected:
/**
* @brief Local instance of IAllocator to manipulate memory.
*/
mutable std::shared_ptr<IAllocator> _allocator;
/**
* @brief A handle for the stored memory returned from _allocator.alloc().
*/
void *_handle = nullptr;
/**
* @brief Copies dimensions and data from the TBlob object.
* @param blob object reference to copy from
*/
void copyFrom(const TBlob<T> &blob) {
tensorDesc = blob.tensorDesc;
this->allocate();
auto memptr = data();
memcpy(memptr, blob.readOnly(), product(tensorDesc.getDims()) * sizeof(T));
}
/**
* @brief Swaps memory handlers between the current blob and the given one.
* @tparam U Type of the blob to move from
* @param blob TBlob instance to move from
*/
template<class U>
void moveFrom(TBlob<U> &blob) {
tensorDesc = blob.tensorDesc;
this->_allocator = std::move(blob._allocator);
std::swap(this->_handle, blob._handle);
}
/**
* @brief Frees handler and cleans up the stored data.
*/
virtual bool free() {
bool bCanRelease = true;
if (_handle == nullptr) return bCanRelease;
bCanRelease = getAllocator()->free(_handle);
_handle = nullptr;
return bCanRelease;
}
/**
* @brief Creates a LockedMemory instance.
* @tparam S Type of the LockedMemory to be created
* @return A created instance of LockedMemory
*/
template<class S>
LockedMemory<S> lockme() const {
return LockedMemory<S>(_allocator.get(), _handle, 0);
}
/**
* @brief Gets an allocator or creates a default one.
* @return IAllocator instance
*/
const std::shared_ptr<IAllocator> &getAllocator() const noexcept override {
// in case when constructor without allocator was used
if (!_allocator) {
_allocator = shared_from_irelease(CreateDefaultAllocator());
}
return _allocator;
}
/**
* @brief Returns handle to the stored data.
*/
void *getHandle() const noexcept override {
return _handle;
}
};
/**
* @deprecated Use TensorDesc to create Blob::Ptr.
* @brief Creates a blob with given precision and dimensions.
* @tparam Type Type of the shared pointer to be created
* @param p Given precision
* @param dims Given dimensions
* @return A shared pointer to the created blob
*/
template<class Type>
inline typename TBlob<Type>::Ptr make_shared_blob(Precision p, Layout l, const SizeVector &dims) {
return std::make_shared<TBlob<Type>>(p, l, dims);
}
/**
* @deprecated Use TensorDesc to create Blob::Ptr
* @brief Creates a blob with the NCHW layout, given precision, and given dimensions.
* @tparam Type Type of the shared pointer to be created
* @param p Given precision
* @param dims Given dimensions
* @return A shared pointer to the created blob
*/
template<class Type>
inline typename TBlob<Type>::Ptr make_shared_blob(Precision p, const SizeVector &dims) {
return make_shared_blob<Type>(p, TensorDesc::getLayoutByDims(dims), dims);
}
/**
* @deprecated Use TensorDesc to create Blob::Ptr
* @brief Creates a blob with the given precision.
* @tparam Type Type of the shared pointer to be created
* @param p Given precision
* @param arg Shared pointer to IAllocator to use in the blob
* @return A shared pointer to the blob created
*/
template<typename Type, class TArg>
inline typename InferenceEngine::TBlob<Type>::Ptr make_shared_blob(Precision p, Layout l, const TArg &arg) {
return std::make_shared<InferenceEngine::TBlob<Type>>(p, l, arg);
}
/**
* @deprecated Use TensorDesc in order to create Blob::Ptr
* @brief Creates a blob with the NCHW layout and given tensor precision.
* @tparam Type Type of the shared pointer to be created
* @param p Given precision
* @param arg Shared pointer to IAllocator to use in the blob
* @return A shared pointer to the blob created
*/
template<typename Type, class TArg>
inline typename InferenceEngine::TBlob<Type>::Ptr make_shared_blob(Precision p, const TArg &arg) {
return make_shared_blob<Type, TArg>(p, TensorDesc::getLayoutByDims(arg), arg);
}
/**
* @brief Creates a blob with the given tensor descriptor.
* @tparam Type Type of the shared pointer to be created
* @param tensorDesc Tensor descriptor for Blob creation
* @return A shared pointer to the newly created blob of the given type
*/
template<typename Type>
inline typename InferenceEngine::TBlob<Type>::Ptr make_shared_blob(const TensorDesc& tensorDesc) {
return std::make_shared<InferenceEngine::TBlob<Type>>(tensorDesc);
}
/**
* @brief Creates a blob with the given tensor descriptor from the pointer to the pre-allocated memory.
* @tparam Type Type of the shared pointer to be created
* @param tensorDesc TensorDesc for Blob creation
* @param ptr Pointer to the pre-allocated memory
* @param size Length of the pre-allocated array
* @return A shared pointer to the newly created blob of the given type
*/
template<typename Type>
inline typename InferenceEngine::TBlob<Type>::Ptr make_shared_blob(const TensorDesc& tensorDesc, Type * ptr, size_t size = 0) {
return std::make_shared<InferenceEngine::TBlob<Type>>(tensorDesc, ptr, size);
}
/**
* @deprecated Use TensorDesc in order to create Blob::Ptr.
* @brief Gets a shared pointer for the new TBlob instance.
* The created instance is based on move semantics from the given TBlob instance.
* @tparam TypeTo Type of the shared pointer to be created
* @param arg rvalue for the blob to move from
* @return A shared pointer to the newly created blob of the given type
*/
template<typename TypeTo>
inline typename InferenceEngine::TBlob<TypeTo>::Ptr make_shared_blob(TBlob<TypeTo> &&arg) {
return std::make_shared<InferenceEngine::TBlob<TypeTo>>(std::move(arg));
}
/**
* @brief Creates a copy of given TBlob instance.
* @tparam TypeTo Type of the shared pointer to be created
* @param arg given pointer to blob
* @return A shared pointer to the newly created blob of the given type
*/
template<typename TypeTo>
inline typename InferenceEngine::TBlob<TypeTo>::Ptr make_shared_blob(const TBlob<TypeTo> &arg) {
return std::make_shared<InferenceEngine::TBlob<TypeTo>>(arg);
}
/**
* @deprecated Use TensorDesc in order to create Blob::Ptr.
* @brief Creates a blob with the given precision.
* @tparam Type Type of the shared pointer to be created
* @param p Given precision
* @return A shared pointer to the blob created
*/
template<typename Type>
inline typename InferenceEngine::TBlob<Type>::Ptr make_shared_blob(Precision p, Layout l = NCHW) {
return std::make_shared<TBlob<Type>>(p, l);
}
/**
* @deprecated Use TensorDesc in order to create Blob::Ptr.
* @brief Creates a blob with the given precision, layout and dimensions from the vector of values.
* @tparam TypeTo Type of the shared pointer to be created
* @param p Given precision
* @param l Given Layout
* @param dims Given dimensions
* @param arg Vector of values
* @return A shared pointer to the blob created
*/
template<typename TypeTo>
inline typename TBlob<TypeTo>::Ptr make_shared_blob(Precision p, Layout l, SizeVector dims, const std::vector<TypeTo> &arg) {
auto blob = std::make_shared<TBlob<TypeTo>>(p, l, dims);
blob->set(arg);
return blob;
}
/**
* @deprecated Use TensorDesc in order to create Blob::Ptr.
* @brief Creates a blob with the given precision from the vector of values.
* @tparam TypeTo Type of the shared pointer to be created
* @param p Given precision
* @param l Layout
* @param arg Vector of values
* @return A shared pointer to the blob created
*/
template<typename TypeTo>
inline typename TBlob<TypeTo>::Ptr make_shared_blob(Precision p, Layout l, const std::vector<TypeTo> &arg) {
auto blob = std::make_shared<TBlob<TypeTo>>(p, l);
blob->set(arg);
return blob;
}
/**
* @deprecated Use TensorDesc in order to create Blob::Ptr.
* @brief Creates a blob with the NCHW layout and the given precision from the vector of values.
* @tparam TypeTo Type of the shared pointer to be created
* @param p Given precision
* @param arg Vector of values
* @return A shared pointer to the blob created
*/
template<typename TypeTo>
inline typename TBlob<TypeTo>::Ptr make_shared_blob(Precision p, const std::vector<TypeTo> &arg) {
return make_shared_blob<TypeTo>(p, TensorDesc::getLayoutByDims(arg), arg);
}
/**
* @deprecated Use TensorDesc in order to create Blob::Ptr.
* @brief Creates a blob with the given precision from the pointer to the pre-allocated memory.
* @param p Given precision
* @param l Layout
* @param dims Given dimensions
* @param ptr Pointer to the pre-allocated memory
* @param size Length of the pre-allocated array
* @return A shared pointer to the blob created
*/
template <typename TypeTo>
inline typename TBlob<TypeTo>::Ptr make_shared_blob(Precision p, Layout l, const SizeVector &dims, TypeTo * ptr, size_t size = 0) {
auto blob = std::make_shared<TBlob<TypeTo>>(p, l, dims, ptr, size);
return blob;
}
/**
* @deprecated Use TensorDesc in order to create Blob::Ptr.
* @brief Creates a blob with the NCHW layout and the given precision from the pointer to the pre-allocated memory
* @param p Given precision
* @param dims Given dimensions
* @param ptr Pointer to the pre-allocated memory
* @param size Length of the pre-allocated array
* @return A shared pointer to the blob created
*/
template <typename TypeTo>
inline typename TBlob<TypeTo>::Ptr make_shared_blob(Precision p, const SizeVector &dims, TypeTo * ptr, size_t size = 0) {
return make_shared_blob<TypeTo>(p, TensorDesc::getLayoutByDims(dims), dims, ptr, size);
}
/**
* @brief This structure describes ROI data.
*/
struct ROI {
size_t id; // ID of a ROI
size_t posX; // W upper left coordinate of ROI
size_t posY; // H upper left coordinate of ROI
size_t sizeX; // W size of ROI
size_t sizeY; // H size of ROI
};
/**
* @brief Creates a blob describing given ROI object based on the given blob with pre-allocated memory.
* @param inputBlob original blob with pre-allocated memory.
* @param roi A ROI object inside of the original blob.
* @return A shared pointer to the newly created blob.
*/
INFERENCE_ENGINE_API_CPP(Blob::Ptr) make_shared_blob(const Blob::Ptr &inputBlob, const ROI &roi);
} // namespace InferenceEngine

View File

@ -0,0 +1,223 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This is a header file with common inference engine definitions.
* @file ie_common.h
*/
#pragma once
#include <vector>
#include <memory>
#include <string>
#include <ostream>
#include <algorithm>
#include <details/ie_exception.hpp>
namespace InferenceEngine {
/**
* @brief Represents tensor size.
* The order is opposite to the order in Caffe*: (w,h,n,b) where the most frequently changing element in memory is first.
*/
using SizeVector = std::vector<size_t>;
/**
* @brief This class represents the generic layer.
*/
class CNNLayer;
/**
* @brief A smart pointer to the CNNLayer
*/
using CNNLayerPtr = std::shared_ptr<CNNLayer>;
/**
* @brief A smart weak pointer to the CNNLayer
*/
using CNNLayerWeakPtr = std::weak_ptr<CNNLayer>;
/**
* @brief The main data representation node
*/
class Data;
/**
* @brief Smart pointer to Data
*/
using DataPtr = std::shared_ptr<Data>;
/**
* @brief Smart pointer to constant Data
*/
using CDataPtr = std::shared_ptr<const Data>;
/**
* @brief Smart weak pointer to Data
*/
using DataWeakPtr = std::weak_ptr<Data>;
/**
* @union UserValue
* @brief The method holds the user values to enable binding of data per graph node.
*/
union UserValue {
int v_int;
float v_float;
void *v_ptr;
};
/**
* @enum Layout
* @brief Layouts that the inference engine supports
*/
enum Layout : uint8_t {
ANY = 0, // "any" layout
// I/O data layouts
NCHW = 1,
NHWC = 2,
// weight layouts
OIHW = 64,
// bias layouts
C = 96,
// Single image layout (for mean image)
CHW = 128,
// 2D
HW = 192,
NC = 193,
CN = 194,
BLOCKED = 200,
};
/**
* @struct InferenceEngineProfileInfo
* @brief Represents basic inference profiling information per layer.
* If the layer is executed using tiling, the sum time per each tile is indicated as the total execution time.
* Due to parallel execution, the total execution time for all layers might be greater than the total inference time.
*/
struct InferenceEngineProfileInfo {
/**
* @brief Defines the general status of the layer
*/
enum LayerStatus {
NOT_RUN,
OPTIMIZED_OUT,
EXECUTED
};
LayerStatus status;
/**
* @brief The absolute time in microseconds that the layer ran (in total)
*/
long long realTime_uSec;
/**
* @brief The net host cpu time that the layer ran
*/
long long cpu_uSec;
/**
* @brief An execution type of unit
*/
char exec_type[256] = {};
/**
* @brief A layer type
*/
char layer_type[256] = {};
/**
* @brief An execution index of the unit
*/
unsigned execution_index;
};
/**
* @enum StatusCode
* @brief This enum contains codes for all possible return values of the interface functions
*/
enum StatusCode : int {
OK = 0,
GENERAL_ERROR = -1,
NOT_IMPLEMENTED = -2,
NETWORK_NOT_LOADED = -3,
PARAMETER_MISMATCH = -4,
NOT_FOUND = -5,
OUT_OF_BOUNDS = -6,
/*
* @brief exception not of std::exception derived type was thrown
*/
UNEXPECTED = -7,
REQUEST_BUSY = -8,
RESULT_NOT_READY = -9,
NOT_ALLOCATED = -10,
INFER_NOT_STARTED = -11
};
/**
* @struct ResponseDesc
* @brief Represents detailed information for an error
*/
struct ResponseDesc {
/**
* @brief A character buffer that holds the detailed information for an error.
*/
char msg[256] = {};
};
/** @brief This class represents StatusCode::GENERIC_ERROR exception */
class GeneralError : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::NOT_IMPLEMENTED exception */
class NotImplemented : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::NETWORK_NOT_LOADED exception */
class NetworkNotLoaded : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::PARAMETER_MISMATCH exception */
class ParameterMismatch : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::NOT_FOUND exception */
class NotFound : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::OUT_OF_BOUNDS exception */
class OutOfBounds : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::UNEXPECTED exception */
class Unexpected : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::REQUEST_BUSY exception */
class RequestBusy : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::RESULT_NOT_READY exception */
class ResultNotReady : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::NOT_ALLOCATED exception */
class NotAllocated : public std::logic_error
{ using std::logic_error::logic_error; };
/** @brief This class represents StatusCode::INFER_NOT_STARTED exception */
class InferNotStarted : public std::logic_error
{ using std::logic_error::logic_error; };
} // namespace InferenceEngine
#if defined(_WIN32)
#define __PRETTY_FUNCTION__ __FUNCSIG__
#else
#define __PRETTY_FUNCTION__ __PRETTY_FUNCTION__
#endif

View File

@ -0,0 +1,165 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This header file defines the main Data representation node.
* @file ie_data.h
*/
#pragma once
#include <map>
#include <memory>
#include <vector>
#include "ie_api.h"
#include "ie_common.h"
#include "details/ie_exception.hpp"
#include "ie_precision.hpp"
#include "ie_layouts.h"
#include <string>
namespace InferenceEngine {
/**
* @brief This class represents the main Data representation node.
*
* The NN graphs are di-graphs consisting of data nodes and layer nodes.
*/
class INFERENCE_ENGINE_API_CLASS(Data) {
public:
/**
* @deprecated Deprecated. Please use getPrecision()
* @brief A precision type of this Data instance
*/
Precision precision;
/**
* @deprecated Deprecated. Please use getFormat()
* @brief A data layout of this Data instance
*/
Layout layout;
/**
* @deprecated Deprecated. Please use getDims()
* @brief A tensor dimension array (the order is opposite to the order in the IR: w,h,c,n) of this Data instance
*/
SizeVector dims;
/**
* @deprecated Deprecated. Please use getCreatorLayer()
* @brief A pointer to the layer that creates this data element, null for input data elements
*/
CNNLayerWeakPtr creatorLayer;
/**
* @deprecated Deprecated. Please use getName()
* @brief A unique name that identifies this data node
*/
std::string name;
/**
* @deprecated Deprecated. Please use getInputTo()
* @brief A map of layers that use this node as input.
* It is useful for recursive NN graph traversal.
*/
std::map<std::string, CNNLayerPtr> inputTo;
/**
* @deprecated Deprecated. Please use getUserObject()
* @brief A user utility place holder
*/
UserValue userObject;
/**
* @brief An empty constructor (dimensionless)
* @param name Name of the data node
* @param _precision Precision of the data
*/
Data(const std::string &name, Precision _precision, Layout layout = NCHW);
/**
* @brief A full constructor (with dimensions)
* @param name Name of the data node
* @param a_dims Data tensor dimensions
* @param _precision Precision of the data
*/
Data(const std::string &name, const SizeVector &a_dims, Precision _precision, Layout layout = NCHW);
/**
* @brief A constructor with tensor descriptor
* @param name Name of the data node
* @param desc Tensor descriptor
*/
Data(const std::string &name, const TensorDesc& desc);
/**
* @brief Checks if the current node is resolved
* @return true if resolved, false otherwise.
*/
bool isInitialized() const;
/**
* @brief Sets the data dimensions.
* After the current node is marked as resolved.
* @param a_dims Tensor dimensions to set
*/
void setDims(const SizeVector &a_dims);
/**
* @deprecated
* @brief Sets the batch value in the data dimensions.
* Batch is defined as the last element in the dimensions vector.
* @param batch_size Batch size to set
*/
inline void setBatchSize(size_t batch_size);
/**
* @brief Sets the layout value for this Data instance
* @param layout Layout value to set
*/
void setLayout(Layout layout);
/**
* @brief Gets the layout value for this Data instance
*/
Layout getLayout() const;
/**
* @brief Gets Tensor descriptor reference
@return reference to TensorDesc
*/
const TensorDesc& getTensorDesc() const;
/**
* @brief Gets a precision type of this Data instance
* @return Precision type
*/
const Precision& getPrecision() const;
/**
* @brief Gets a precision type of this Data instance
* @return Precision type
*/
void setPrecision(const Precision& precision);
/**
* @return data dimensions
*/
const SizeVector& getDims() const;
/**
* @return owner of this data layer, parent layer in di-graph
*/
CNNLayerWeakPtr& getCreatorLayer();
/**
* @return name of the data object
*/
const std::string& getName() const;
/**
* @brief returns child layers in di-graph
*/
std::map<std::string, CNNLayerPtr>& getInputTo();
/**
* @return convenient arbitrary user data holder
*/
const UserValue& getUserObject() const;
private:
TensorDesc tensorDesc;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,129 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This header file contains aspects of working on different devices like CPU, GEN, FPGA, etc.
* @file ie_device.hpp
*/
#pragma once
#include <string>
#include <vector>
#include <map>
#include <ie_api.h>
#include <ie_common.h>
namespace InferenceEngine {
/**
* @enum TargetDevice
* @brief Describes known device types
*/
enum class TargetDevice : uint8_t {
eDefault = 0,
eBalanced = 1,
eCPU = 2,
eGPU = 3,
eFPGA = 4,
eMYRIAD = 5,
eGNA = 7,
eHETERO = 8
};
/**
* @brief Describes the relationship between the enumerator type and the actual device's name
*/
class TargetDeviceInfo {
struct Info {
TargetDevice device;
std::string name;
Info(TargetDevice device, std::string name) : device(device), name(name){}
};
static const std::vector<Info> & getAll() {
#define DECL_DEVICE(device_type) {TargetDevice::e##device_type, #device_type}
static std::vector<Info> g_allDeviceInfos = {
DECL_DEVICE(Default),
DECL_DEVICE(Balanced),
DECL_DEVICE(CPU),
DECL_DEVICE(GPU),
DECL_DEVICE(FPGA),
DECL_DEVICE(MYRIAD),
DECL_DEVICE(GNA),
DECL_DEVICE(HETERO)
};
#undef DECLARE
return g_allDeviceInfos;
}
public:
static TargetDevice fromStr(const std::string &deviceName) {
static std::map<std::string, InferenceEngine::TargetDevice> deviceFromNameMap = {
{ "CPU", InferenceEngine::TargetDevice::eCPU },
{ "GPU", InferenceEngine::TargetDevice::eGPU },
{ "FPGA", InferenceEngine::TargetDevice::eFPGA },
{ "MYRIAD", InferenceEngine::TargetDevice::eMYRIAD },
{ "GNA", InferenceEngine::TargetDevice::eGNA },
{ "BALANCED", InferenceEngine::TargetDevice::eBalanced },
{ "HETERO", InferenceEngine::TargetDevice::eHETERO }
};
auto val = deviceFromNameMap.find(deviceName);
return val != deviceFromNameMap.end() ? val->second : InferenceEngine::TargetDevice::eDefault;
}
static const char * name(TargetDevice device) {
auto res = std::find_if(getAll().cbegin(), getAll().cend(), [&](const Info & info){
return device == info.device;
});
if (res == getAll().cend()) {
return "Unknown device";
}
return res->name.c_str();
}
};
/**
* @brief Returns the device name
* @param device Instance of TargetDevice
* @return A c-string with the name
*/
inline const char *getDeviceName(TargetDevice device) {
return TargetDeviceInfo::name(device);
}
/**
* @struct FindPluginRequest
* @brief Defines a message that contains the TargetDevice object to find a plugin for
*/
struct FindPluginRequest {
/**
* @brief object of TargetDevice to find a plugin for
*/
TargetDevice device;
};
/**
* @struct FindPluginResponse
* @brief Defines a message that contains a list of appropriate plugin names
*/
struct FindPluginResponse {
/**
* @brief A list of appropriate plugin names
*/
std::vector<std::string> names;
};
/**
* @brief Finds an appropriate plugin for requested target device
* @param req A requested target device
* @param result The results of the request
* @param resp The response message description
* @return A response message
*/
FindPluginResponse findPlugin(const FindPluginRequest &req);
INFERENCE_ENGINE_API(StatusCode) findPlugin(const FindPluginRequest &req, FindPluginResponse &result,
ResponseDesc *resp) noexcept;
} // namespace InferenceEngine

View File

@ -0,0 +1,25 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for a plugin logging mechanism
* @file ie_error.hpp
*/
#pragma once
namespace InferenceEngine {
/**
* @brief This class represents a custom error listener.
* Plugin consumers can provide it via InferenceEngine::SetLogCallback
*/
class IErrorListener {
public:
/**
* @brief The plugin calls this method with a null terminated error message (in case of error)
* @param msg Error message
*/
virtual void onError(const char *msg) noexcept = 0;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,214 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file that defines a wrapper class for handling extension instantiation and releasing resources
* @file ie_extension.h
*/
#pragma once
#include "details/ie_so_pointer.hpp"
#include "ie_iextension.h"
#include "mkldnn/mkldnn_extension_ptr.hpp"
#include <string>
#include <memory>
#include <map>
namespace InferenceEngine {
namespace details {
/**
* @brief The SOCreatorTrait class specialization for IExtension case, defines the name of the fabric method for creating IExtension object in DLL
*/
template<>
class SOCreatorTrait<IExtension> {
public:
/**
* @brief A name of the fabric method for creating an IExtension object in DLL
*/
static constexpr auto name = "CreateExtension";
};
/**
* @brief The SOCreatorTrait class specialization for IExtension case, defines the name of the fabric method for creating IExtension object in DLL
*/
template<>
class SOCreatorTrait<IShapeInferExtension> {
public:
/**
* @brief A name of the fabric method for creating an IShapeInferExtension object in DLL
*/
static constexpr auto name = "CreateShapeInferExtension";
};
} // namespace details
/**
* @brief This class is a C++ helper to work with objects created using extensions.
*/
class Extension : public IExtension {
public:
/**
* @brief Loads extension from a shared library
* @param name Full or relative path to extension library
*/
explicit Extension(const std::string &name)
: actual(name) {}
/**
* @brief Gets the extension version information
* @param versionInfo A pointer to version info, set by the plugin
*/
void GetVersion(const InferenceEngine::Version *&versionInfo) const noexcept override {
actual->GetVersion(versionInfo);
}
/**
* @brief Sets a log callback that is used to track what is going on inside
* @param listener Logging listener
*/
void SetLogCallback(InferenceEngine::IErrorListener &listener) noexcept override {
actual->SetLogCallback(listener);
}
/**
* @brief Cleans the resources up
*/
void Unload() noexcept override {
actual->Unload();
}
/**
* @brief Does nothing since destruction is done via the regular mechanism
*/
void Release() noexcept override {}
/**
* @brief Gets the array with types of layers which are included in the extension
* @param types Types array
* @param size Size of the types array
* @param resp Response descriptor
* @return Status code
*/
StatusCode getPrimitiveTypes(char**& types, unsigned int& size, ResponseDesc* resp) noexcept override {
return actual->getPrimitiveTypes(types, size, resp);
}
/**
* @brief Gets the factory with implementations for a given layer
* @param factory Factory with implementations
* @param cnnLayer A layer to get the factory for
* @param resp Response descriptor
* @return Status code
*/
StatusCode getFactoryFor(ILayerImplFactory *&factory, const CNNLayer *cnnLayer,
ResponseDesc *resp) noexcept override {
return actual->getFactoryFor(factory, cnnLayer, resp);
}
StatusCode getShapeInferImpl(IShapeInferImpl::Ptr& impl, const char* type, ResponseDesc* resp) noexcept override {
return actual->getShapeInferImpl(impl, type, resp);
}
protected:
/**
* @brief A SOPointer instance to the loaded templated object
*/
InferenceEngine::details::SOPointer<IExtension> actual;
};
/**
* @brief This class is a C++ helper to work with objects created using extensions.
*/
class ShapeInferExtension : public IShapeInferExtension {
public:
/**
* @brief Loads extension from a shared library
* @param name Full or relative path to extension library
*/
explicit ShapeInferExtension(const std::string &name)
: actual(name) {}
/**
* @brief Gets the extension version information
* @param versionInfo A pointer to version info, set by the plugin
*/
void GetVersion(const InferenceEngine::Version *&versionInfo) const noexcept override {
actual->GetVersion(versionInfo);
}
/**
* @brief Sets a log callback that is used to track what is going on inside
* @param listener Logging listener
*/
void SetLogCallback(InferenceEngine::IErrorListener &listener) noexcept override {
actual->SetLogCallback(listener);
}
/**
* @brief Cleans the resources up
*/
void Unload() noexcept override {
actual->Unload();
}
/**
* @brief Does nothing since destruction is done via the regular mechanism
*/
void Release() noexcept override {}
/**
* @brief Gets the array with types of layers which are included in the extension
* @param types Types array
* @param size Size of the types array
* @param resp Response descriptor
* @return Status code
*/
StatusCode getPrimitiveTypes(char**& types, unsigned int& size, ResponseDesc* resp) noexcept override {
return actual->getPrimitiveTypes(types, size, resp);
}
/**
* @brief Gets shape propagation implementation for the given string-type of cnn Layer
* @param impl the vector with implementations which is ordered by priority
* @param resp response descriptor
* @return status code
*/
StatusCode getShapeInferImpl(IShapeInferImpl::Ptr& impl, const char* type, ResponseDesc* resp) noexcept override {
return actual->getShapeInferImpl(impl, type, resp);
}
protected:
/**
* @brief A SOPointer instance to the loaded templated object
*/
InferenceEngine::details::SOPointer<IShapeInferExtension> actual;
};
/**
* @brief Creates a special shared_pointer wrapper for the given type from a specific shared module
* @param name Name of the shared library file
* @return shared_pointer A wrapper for the given type from a specific shared module
*/
template<>
inline std::shared_ptr<IShapeInferExtension> make_so_pointer(const std::string &name) {
return std::make_shared<ShapeInferExtension>(name);
}
/**
* @brief Creates a special shared_pointer wrapper for the given type from a specific shared module
* @param name Name of the shared library file
* @return shared_pointer A wrapper for the given type from a specific shared module
*/
template<>
inline std::shared_ptr<IExtension> make_so_pointer(const std::string &name) {
try {
return std::make_shared<Extension>(name);
} catch (InferenceEngine::details::InferenceEngineException& ex) {
return std::make_shared<MKLDNNPlugin::MKLDNNExtension>(name);
}
}
} // namespace InferenceEngine

View File

@ -0,0 +1,108 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file that provides interface for network reader that is used to build networks from a given IR
* @file ie_icnn_net_reader.h
*/
#pragma once
#include <map>
#include <string>
#include "ie_blob.h"
#include "ie_common.h"
#include "ie_icnn_network.hpp"
#include "details/ie_no_copy.hpp"
#include "ie_api.h"
namespace InferenceEngine {
/**
* @brief This class is the main interface to build and parse a network from a given IR
*
* All methods here do not throw exceptions and return a StatusCode and ResponseDesc object.
* Alternatively, to use methods that throw exceptions, refer to the CNNNetReader wrapper class.
*/
class ICNNNetReader : public details::IRelease {
public:
/**
* @brief Parses the topology part of the IR (.xml)
* @param filepath The full path to the .xml file of the IR
* @param resp Response message
* @return Result code
*/
virtual StatusCode ReadNetwork(const char *filepath, ResponseDesc *resp) noexcept = 0;
/**
* @brief Parses the topology part of the IR (.xml) given the xml as a buffer
* @param model Pointer to a char array with the IR
* @param resp Response message
* @param size Size of the char array in bytes
* @return Result code
*/
virtual StatusCode ReadNetwork(const void *model, size_t size, ResponseDesc *resp) noexcept = 0;
/**
* @brief Sets the weights buffer (.bin part) from the IR.
* Weights Blob must always be of bytes - the casting to precision is done per-layer to support mixed
* networks and to ease of use.
* This method can be called more than once to reflect updates in the .bin.
* @param weights Blob of bytes that holds all the IR binary data
* @param resp Response message
* @return Result code
*/
virtual StatusCode SetWeights(const TBlob<uint8_t>::Ptr &weights, ResponseDesc *resp) noexcept = 0;
/**
* @brief Loads and sets the weights buffer directly from the IR .bin file.
* This method can be called more than once to reflect updates in the .bin.
* @param filepath Full path to the .bin file
* @param resp Response message
* @return Result code
*/
virtual StatusCode ReadWeights(const char *filepath, ResponseDesc *resp) noexcept = 0;
/**
* @brief Returns a pointer to the built network
* @param resp Response message
*/
virtual ICNNNetwork *getNetwork(ResponseDesc *resp) noexcept = 0;
/**
* @brief Retrieves the last building status
* @param resp Response message
*/
virtual bool isParseSuccess(ResponseDesc *resp) noexcept = 0;
/**
* @brief Retrieves the last building failure message if failed
* @param resp Response message
* @return StatusCode that indicates the network status
*/
virtual StatusCode getDescription(ResponseDesc *resp) noexcept = 0;
/**
* @brief Gets network name
* @param name Pointer to preallocated buffer that receives network name
* @param len Length of the preallocated buffer, network name will be trimmed by this lenght
* @param resp Response message
* @return Result code
*/
virtual StatusCode getName(char *name, size_t len, ResponseDesc *resp) noexcept = 0;
/**
* @brief Returns a version of IR
* @param resp Response message
* @return IR version number: 1 or 2
*/
virtual int getVersion(ResponseDesc *resp) noexcept = 0;
};
/**
* @brief Creates a CNNNetReader instance
* @return An object that implements the ICNNNetReader interface
*/
INFERENCE_ENGINE_API(ICNNNetReader*)CreateCNNNetReader() noexcept;
} // namespace InferenceEngine

View File

@ -0,0 +1,181 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This is a header file for the ICNNNetwork class
* @file ie_icnn_network.hpp
*/
#pragma once
#include "ie_common.h"
#include "ie_layers.h"
#include "ie_data.h"
#include "ie_device.hpp"
#include "ie_blob.h"
#include "details/ie_irelease.hpp"
#include "ie_preprocess.hpp"
#include "ie_input_info.hpp"
#include "ie_iextension.h"
#include <memory>
#include <map>
#include <string>
namespace InferenceEngine {
/**
* @brief A collection that contains string as key, and Data smart pointer as value
*/
using OutputsDataMap = std::map<std::string, DataPtr>;
/**
* @brief This is the main interface to describe the NN topology
*/
class ICNNNetwork : public details::IRelease {
public:
/**
* @brief Returns the main network operating precision.
* This may be MIXED if not homogeneous.
* @return A precision type
*/
virtual Precision getPrecision() const noexcept = 0;
/**
* @brief Gets the network output Data node information. The received info is stored in the given Data node.
* For single and multiple outputs networks.
* @param out Reference to the OutputsDataMap object
*/
virtual void getOutputsInfo(OutputsDataMap& out) const noexcept = 0;
/**
* @brief Gets the network input Data node information. The received info is stored in the given InputsDataMap object.
* For single and multiple inputs networks.
* This method must be called to find out input names for using them later during filling of a map
* of blobs passed later to InferenceEngine::IInferencePlugin::Infer()
* @param inputs Reference to InputsDataMap object.
*/
virtual void getInputsInfo(InputsDataMap& inputs) const noexcept = 0;
/**
* @brief Returns information on certain input pointed by inputName
* @param inputName Name of input layer to get info on
* @return A smart pointer to the input information
*/
virtual InputInfo::Ptr getInput(const std::string& inputName) const noexcept = 0;
/**
* @brief Gets the network name. The name is stored in the given pName string.
* @param pName - will receive actual network name, specified in IR file,
* pName should point to valid memory address before invoking this function
* @param len - size in bytes of pName buffer, actual name is trimmed by this size
*/
virtual void getName(char* pName, size_t len) const noexcept = 0;
/**
* @brief Returns the network name.
* @return Network name
*/
virtual const std::string& getName() const noexcept = 0;
/**
* @brief Returns the number of layers in the network as an integer value
* @return The number of layers as an integer value
*/
virtual size_t layerCount() const noexcept = 0;
/**
* @brief Returns a smart pointer reference to a Data node given its name.
* If the Data node is missing, returns reference to a default initialized new empty data pointer with given name.
* @param dname Name of the Data node
* @return Data node smart pointer
*/
virtual DataPtr& getData(const char* dname) noexcept = 0;
/**
* @brief Insert a layer into the network. A user is responsible to connect it to other data elements.
* @param layer Const reference to a layer smart pointer
*/
virtual void addLayer(const CNNLayerPtr& layer) noexcept = 0;
/**
* @brief Adds output to the layer
* @param layerName Name of the layer
* @param outputIndex Index of the output
* @param resp Response message
* @return Status code of the operation
*/
virtual StatusCode
addOutput(const std::string& layerName, size_t outputIndex = 0, ResponseDesc* resp = nullptr) noexcept = 0;
/**
* @brief Gets network layer with the given name
* @param layerName Given name of the layer
* @param out Pointer to the found CNNLayer object with the given name
* @param resp Pointer to the response message that holds a description of an error if any occurred
* @return Status code of the operation. OK if succeeded
*/
virtual StatusCode getLayerByName(const char* layerName, CNNLayerPtr& out, ResponseDesc* resp) const noexcept = 0;
/**
* @brief Sets a desirable device to perform all work on.
* Some plug-ins might not support some target devices and may abort execution with an appropriate error message.
* @param device Device to set as a target
*/
virtual void setTargetDevice(TargetDevice device) noexcept = 0;
/**
* @brief Gets the target device.
* If setTargetDevice() was not called before, returns eDefault
* @return A TargetDevice instance
*/
virtual TargetDevice getTargetDevice() const noexcept = 0;
/**
* @deprecated use setBatchSize with ResponseDesc to get error message
* @brief Changes the inference batch size
*/
virtual StatusCode setBatchSize(const size_t size) noexcept = 0;
/**
* @brief Changes the inference batch size.
* @note There are several limitations and it's not recommended to use it. Set batch to the input shape and call @reshape.
* @param size Size of batch to set
* @return Status code of the operation
* @note: Current implementation of the function sets batch size to the first dimension of 4D input layers in the networks
* and starts shape inference for IR starting from v3, for IR v2 it sets batch to the first dimension for all layers.
* Custom layers might require custom shape infer implementation, use @IShapeInferExtension interface to register them.
*/
virtual StatusCode setBatchSize(size_t size, ResponseDesc* responseDesc) noexcept = 0;
/**
* @brief Gets the inference batch size
* @return The size of batch as a size_t value
*/
virtual size_t getBatchSize() const noexcept = 0;
/**
* @brief Map of pairs: name of corresponding data and its dimension.
*/
using InputShapes = std::map<std::string, SizeVector>;
/**
* @brief - Run shape inference with new input shapes for the network
* @param inputShapes - map of pairs: name of corresponding data and its dimension.
* @note currently all inputs are required
* @param resp Pointer to the response message that holds a description of an error if any occurred
* @return Status code of the operation
*/
virtual StatusCode reshape(const InputShapes& inputShapes, ResponseDesc* resp) noexcept { return NOT_IMPLEMENTED; };
/**
* @brief Registers extension within the plugin
* @param extension Pointer to already loaded reader extension with shape propagation implementations
* @param resp Pointer to the response message that holds a description of an error if any occurred
* @return Status code of the operation. OK if succeeded
*/
virtual StatusCode
AddExtension(const IShapeInferExtensionPtr& extension, ResponseDesc* resp) noexcept { return NOT_IMPLEMENTED; };
};
} // namespace InferenceEngine

View File

@ -0,0 +1,56 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This is a header file for the ICNNNetworkStats class
* @file ie_icnn_network_stats.hpp
*/
#pragma once
#include <string>
#include <memory>
#include <limits>
#include <vector>
namespace InferenceEngine {
/**
* @class ICNNNetworkStats
* @brief This is the interface to describe the NN topology scoring statistics
*/
class ICNNNetworkStats : public details::IRelease {
public:
virtual void SaveToFile(const std::string& xmlPath, const std::string& binPath) const = 0;
virtual void LoadFromFile(const std::string& xmlPath, const std::string& binPath) = 0;
virtual bool isEmpty() const = 0;
};
class NetworkNodeStats;
using NetworkNodeStatsPtr = std::shared_ptr<NetworkNodeStats>;
using NetworkNodeStatsWeakPtr = std::weak_ptr<NetworkNodeStats>;
class NetworkNodeStats {
public:
NetworkNodeStats() { }
explicit NetworkNodeStats(int statCount) {
float min = std::numeric_limits<float>::max();
float max = std::numeric_limits<float>::min();
for (int i = 0; i < statCount; i++) {
_minOutputs.push_back(min);
_maxOutputs.push_back(max);
}
}
public:
std::vector<float> _minOutputs;
std::vector<float> _maxOutputs;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,94 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief a header file for IExecutableNetwork interface
* @file ie_iexecutable_network.hpp
*/
#pragma once
#include "ie_common.h"
#include "ie_primitive_info.hpp"
#include "ie_iinfer_request.hpp"
#include "ie_imemory_state.hpp"
#include "ie_input_info.hpp"
#include <string>
#include <vector>
#include <memory>
#include <map>
namespace InferenceEngine {
/**
* @brief A collection that contains string as key, and const Data smart pointer as value
*/
using ConstOutputsDataMap = std::map<std::string, CDataPtr>;
/**
* @brief This is an interface of an executable network
*/
class IExecutableNetwork : public details::IRelease {
public:
/**
* @brief A smart pointer to the current IExecutableNetwork object
*/
using Ptr = std::shared_ptr<IExecutableNetwork>;
/**
* @brief Gets the Executable network output Data node information. The received info is stored in the given ConstOutputsDataMap node.
* This method need to be called to find output names for using them later during filling of a map
* of blobs passed to InferenceEngine::IInferencePlugin::Infer()
* @param out Reference to the ConstOutputsDataMap object
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode GetOutputsInfo(ConstOutputsDataMap &out, ResponseDesc *resp) const noexcept = 0;
/**
* @brief Gets the Executable network input Data node information. The received info is stored in the given ConstInputsDataMap object.
* This method need to be called to find out input names for using them later during filling of a map
* of blobs passed to InferenceEngine::IInferencePlugin::Infer()
* @param inputs Reference to ConstInputsDataMap object.
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode GetInputsInfo(ConstInputsDataMap &inputs, ResponseDesc *resp) const noexcept = 0;
/**
* @brief Creates an inference request object used to infer the network.
* The created request has allocated input and output blobs (that can be changed later).
* @param req Shared pointer to the created request object
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode CreateInferRequest(IInferRequest::Ptr& req, ResponseDesc *resp) noexcept = 0;
/**
* @brief Exports the current executable network so it can be used later in the Import() main API
* @param modelFileName Full path to the location of the exported file
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode Export(const std::string& modelFileName, ResponseDesc *resp) noexcept = 0;
/**
* @brief Gets the mapping of IR layer names to implemented kernels
* @param deployedTopology Map of PrimitiveInfo objects that represent the deployed topology
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode GetMappedTopology(std::map<std::string, std::vector<PrimitiveInfo::Ptr>> &deployedTopology, ResponseDesc *resp) noexcept = 0;
/**
* @brief Gets state control interface for given executable network, State control essential for recurrent networks
* @param pState reference to a pointer that receives internal states
* @param idx requested index for receiving memory state
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success, OUT_OF_BOUNDS (-6) no memory state for given index
*/
virtual StatusCode QueryState(IMemoryState::Ptr & pState, size_t idx, ResponseDesc *resp) noexcept = 0;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,248 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief This is a header file for Inference Engine Extension Interface
* @file ie_iextension.h
*/
#pragma once
#include "ie_api.h"
#include "ie_device.hpp"
#include "ie_layers.h"
#include "ie_error.hpp"
#include "ie_version.hpp"
#include <vector>
#include <string>
#include <memory>
#include <map>
#include "details/ie_no_copy.hpp"
#if defined(_WIN32) && defined(IMPLEMENT_INFERENCE_EXTENSION_API)
#define INFERENCE_EXTENSION_API(TYPE) extern "C" __declspec(dllexport) TYPE
#else
#define INFERENCE_EXTENSION_API(TYPE) INFERENCE_ENGINE_API(TYPE)
#endif
namespace InferenceEngine {
/**
* @struct DataConfig
* @brief This structure describes data configuration
*/
struct DataConfig {
/**
* @brief Format of memory descriptor
*/
TensorDesc desc;
/**
* @brief Index of in-place memory. If -1 memory cannot be in-place
*/
int inPlace = -1;
/**
* @brief Flag for determination of the constant memory. If layer contains all constant memory we can calculate it on the load stage.
*/
bool constant = false;
};
/**
* @struct LayerConfig
* @brief This structure describes Layer configuration
*/
struct LayerConfig {
/**
* @brief Supported dynamic batch. If false, dynamic batch is not supported
*/
bool dynBatchSupport = false;
/**
* @brief Vector of input data configs
*/
std::vector<DataConfig> inConfs;
/**
* @brief Vector of output data configs
*/
std::vector<DataConfig> outConfs;
};
/**
* @brief This class provides interface for extension implementations
*/
class ILayerImpl {
public:
using Ptr = std::shared_ptr<ILayerImpl>;
/**
* @brief Destructor
*/
virtual ~ILayerImpl() = default;
/**
* @brief Gets all supported configurations for the current layer
* @param conf Vector with supported configurations
* @param resp Response descriptor
* @return Status code
*/
virtual StatusCode getSupportedConfigurations(std::vector<LayerConfig>& conf, ResponseDesc* resp) noexcept = 0;
/**
* @brief Initializes the implementation
* @param config Selected supported configuration
* @param resp Response descriptor
* @return Status code
*/
virtual StatusCode init(LayerConfig& config, ResponseDesc* resp) noexcept = 0;
};
/**
* @brief This class provides interface for the implementation with the custom execution code
*/
class ILayerExecImpl : public ILayerImpl {
public:
/**
* @brief Execute method
* @param inputs Vector of blobs with input memory
* @param outputs Vector of blobs with output memory
* @param resp Response descriptor
* @return Status code
*/
virtual StatusCode execute(std::vector<Blob::Ptr>& inputs,
std::vector<Blob::Ptr>& outputs, ResponseDesc* resp) noexcept = 0;
};
/**
* @brief This class provides interface for extension factories
*/
class ILayerImplFactory {
public:
using Ptr = std::shared_ptr<ILayerImplFactory>;
using ImplCreator = std::function<ILayerImpl*()>;
/**
* @brief Destructor
*/
virtual ~ILayerImplFactory() = default;
/**
* @deprecated
* @brief Sets output shapes by input shapes.
* @param inShapes Shapes of all inputs coming in this layer
* @param outShapes Generated shapes coming from this layer given the input
* @param resp Response descriptor
* @return Status code
*/
virtual StatusCode getShapes(const std::vector<TensorDesc>& inShapes, std::vector<TensorDesc>& outShapes,
ResponseDesc* resp) noexcept = 0;
/**
* @brief Gets all possible implementations for the given cnn Layer
* @param impls the vector with implementations which is ordered by priority
* @param resp response descriptor
* @return status code
*/
virtual StatusCode getImplementations(std::vector<ILayerImpl::Ptr>& impls, ResponseDesc* resp) noexcept = 0;
};
/**
* @class IShapeInferImpl
* @brief This class provides interface for the implementation with the custom execution code
*/
class IShapeInferImpl {
public:
using Ptr = std::shared_ptr<IShapeInferImpl>;
/**
* @brief check that reshape can be applied, that parameters and shapes are valid
*/
virtual StatusCode inferShapes(const std::vector<SizeVector>& inShapes,
const std::map<std::string, std::string>& params,
const std::map<std::string, Blob::Ptr>& blobs,
std::vector<SizeVector>& outShapes,
ResponseDesc* resp) noexcept = 0;
};
/**
* @class IShapeInferExtension
* @brief This class is the reader extension interface to provide implementation for shape propagation
*/
class IShapeInferExtension : public InferenceEngine::details::IRelease {
public:
/**
* @brief Sets logging callback.
* Logging is used to track what is going on inside.
* @param listener Logging sink
*/
virtual void SetLogCallback(InferenceEngine::IErrorListener& listener) noexcept = 0;
/**
* @brief Gets extension version information and stores in versionInfo
* @param versionInfo Pointer to version info, will be set by plugin
*/
virtual void GetVersion(const InferenceEngine::Version*& versionInfo) const noexcept = 0;
/**
* @brief Cleans resources up
*/
virtual void Unload() noexcept = 0;
/**
* @brief Gets the array with types of layers which are included in the extension
* @param types Array to store the layer types
* @param size Size of the layer types array
* @param resp Response descriptor
* @return Status code
*/
virtual StatusCode getPrimitiveTypes(char**& types, unsigned int& size, ResponseDesc* resp) noexcept = 0;
/**
* @brief Gets shape propagation implementation for the given string-type of cnn Layer
* @param impl the vector with implementations which is ordered by priority
* @param resp response descriptor
* @return status code
*/
virtual StatusCode getShapeInferImpl(IShapeInferImpl::Ptr& impl,
const char* type,
ResponseDesc* resp) noexcept = 0;
};
/**
* @brief This class is the main extension interface
*/
class IExtension : public IShapeInferExtension {
public:
virtual StatusCode getFactoryFor(ILayerImplFactory*& factory, const CNNLayer* cnnLayer,
ResponseDesc* resp) noexcept = 0;
StatusCode getShapeInferImpl(IShapeInferImpl::Ptr& impl,
const char* type,
ResponseDesc* resp) noexcept override {
return NOT_IMPLEMENTED;
};
};
using IExtensionPtr = std::shared_ptr<IExtension>;
using IShapeInferExtensionPtr = std::shared_ptr<IShapeInferExtension>;
/**
* @brief Creates the default instance of the extension
* @param ext Extension interface
* @param resp Response description
* @return Status code
*/
INFERENCE_EXTENSION_API(StatusCode) CreateExtension(IExtension*& ext, ResponseDesc* resp) noexcept;
/**
* @brief Creates the default instance of the shape infer extension
* @param ext Shape Infer Extension interface
* @param resp Response description
* @return Status code
*/
INFERENCE_EXTENSION_API(StatusCode) CreateShapeInferExtension(IShapeInferExtension*& ext, ResponseDesc* resp) noexcept;
} // namespace InferenceEngine

View File

@ -0,0 +1,121 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file that provides interface to register custom hetero functionality
* @file ie_ihetero_plugin.hpp
*/
#pragma once
#include <map>
#include <string>
#include <memory>
#include <ie_icnn_network.hpp>
#include <ie_iexecutable_network.hpp>
#include <ie_plugin.hpp>
namespace InferenceEngine {
/**
* This interface describes a mechanism of custom loaders to be used in heterogeneous
* plugin during setting of affinity and loading of split sub-network to the plugins
* The custom loader can define addition settings for the plugins or network loading
* Examples of cases when this interface should be implemented in the application:
* 1. add custom layers to existing plugins if it is not pointed to the heterogeneous plugin
* or registration of custom layer is different than supported in available public plugins
* 2. set affinity manually for the same plugin being initialized by different parameters,
* e.g different device id
* In this case there will be mapping of
* Device1 > HeteroDeviceLoaderImpl1
* Device2 > HeteroDeviceLoaderImpl2
* the affinity should be pointed manually, the implementation of HeteroDeviceLoaderImpl1 and
* HeteroDeviceLoaderImpl2 should be in the application, and these device loaders should be registered
* through calling of
* IHeteroInferencePlugin::SetDeviceLoader("Device1", HeteroDeviceLoaderImpl1)
* IHeteroInferencePlugin::SetDeviceLoader("Device2", HeteroDeviceLoaderImpl2)
*/
class IHeteroDeviceLoader {
public:
using Ptr = std::shared_ptr<IHeteroDeviceLoader>;
virtual ~IHeteroDeviceLoader() = default;
/**
* Loads network to the device. The instantiation of plugin should be in the implementation
* of the IHeteroDeviceLoader. As well setting of special config option should happen in the
* implementation as well
* @param device Loading of network should happen for this device
* @param ret Reference to a shared ptr of the returned executable network instance
* @param network Network object acquired from CNNNetReader
* @param config Map of configuration settings relevant only for current load operation
* @param resp Pointer to the response message that holds a description of an error if any occurred
* @return Status code of the operation. OK if succeeded
*/
virtual StatusCode LoadNetwork(
const std::string& device,
IExecutableNetwork::Ptr &ret,
ICNNNetwork &network,
const std::map<std::string, std::string> &config,
ResponseDesc *resp) noexcept = 0;
/**
* @depricated Use the version with config parameter
* This function calls plugin function QueryNetwork for the plugin being instantiated
* in the implementation of IHeteroDeviceLoader
* @param device QueryNetwork will be executed for this device
* @param network Network object acquired from CNNNetReader
* @param res
*/
virtual void QueryNetwork(const std::string &device,
const ICNNNetwork &network,
QueryNetworkResult &res) noexcept = 0;
/**
* This function calls plugin function QueryNetwork for the plugin being instantiated
* in the implementation of IHeteroDeviceLoader
* @param device QueryNetwork will be executed for this device
* @param network Network object acquired from CNNNetReader
* @param config Network configuration parameters
* @param res
*/
virtual void QueryNetwork(const std::string &device,
const ICNNNetwork &network,
const std::map<std::string, std::string>& config,
QueryNetworkResult &res) noexcept {
QueryNetwork(device, network, res);
};
};
using MapDeviceLoaders = std::map<std::string, InferenceEngine::IHeteroDeviceLoader::Ptr>;
/**
* This interface extends regular plugin interface for heterogeneous case. Not all plugins
* implements it. The main purpose of this interface - to register loaders and have an ability
* to get default settings for affinity on certain devices.
*/
class IHeteroInferencePlugin : public IInferencePlugin {
public:
/**
* Registers device loader for the device
* @param device - the device name being used in CNNNLayer::affinity
* @param loader - helper class allowing to analyze if layers are supported and allow
* to load network to the plugin being defined in the IHeteroDeviceLoader implementation
*/
virtual void SetDeviceLoader(const std::string &device, IHeteroDeviceLoader::Ptr loader) noexcept = 0;
/**
* The main goal of this function to set affinity according to the options set for the plugin\
* implementing IHeteroInferencePlugin.
* This function works only if all affinity in the network are empty.
* @param network Network object acquired from CNNNetReader
* @param config Map of configuration settings
* @param resp Pointer to the response message that holds a description of an error if any occurred
* @return Status code of the operation. OK if succeeded
*/
virtual StatusCode SetAffinity(
ICNNNetwork& network,
const std::map<std::string, std::string> &config,
ResponseDesc *resp) noexcept = 0;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,138 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief a header file for IInferRequest interface
* @file ie_iinfer_request.hpp
*/
#pragma once
#include "ie_common.h"
#include <ie_blob.h>
#include <memory>
#include <string>
#include <map>
#include <details/ie_irelease.hpp>
namespace InferenceEngine {
/**
* @brief This is an interface of asynchronous infer request
*/
class IInferRequest : public details::IRelease {
public:
/**
* @enum WaitMode
* @brief Enumeration to hold wait mode for IInferRequest
*/
enum WaitMode : int64_t {
/** Wait until inference result becomes available */
RESULT_READY = -1,
/** IInferRequest doesn't block or interrupt current thread and immediately returns inference status */
STATUS_ONLY = 0,
};
using Ptr = std::shared_ptr<IInferRequest>;
using WeakPtr = std::weak_ptr<IInferRequest>;
/**
* @brief Sets input/output data to infer
* @note: Memory allocation does not happen
* @param name Name of input or output blob.
* @param data Reference to input or output blob. The type of a blob must match the network input precision and size.
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode SetBlob(const char *name, const Blob::Ptr &data, ResponseDesc *resp) noexcept = 0;
/**
* @brief Gets input/output data for inference
* @note: Memory allocation does not happen
* @param name Name of input or output blob.
* @param data Reference to input or output blob. The type of Blob must match the network input precision and size.
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode GetBlob(const char *name, Blob::Ptr &data, ResponseDesc *resp) noexcept = 0;
/**
* @brief Infers specified input(s) in synchronous mode
* @note blocks all methods of IInferRequest while request is ongoing (running or waiting in queue)
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode Infer(ResponseDesc *resp) noexcept = 0;
/**
* @brief Queries performance measures per layer to get feedback of what is the most time consuming layer
* @note: not all plugins provide meaningful data
* @param perfMap Map of layer names to profiling information for that layer
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode GetPerformanceCounts(std::map<std::string, InferenceEngineProfileInfo> &perfMap,
ResponseDesc *resp) const noexcept = 0;
/**
* @brief Waits for the result to become available. Blocks until specified millis_timeout has elapsed or the result becomes available, whichever comes first.
* @param millis_timeout Maximum duration in milliseconds to block for
* @note There are special cases when millis_timeout is equal some value of the WaitMode enum:
* * STATUS_ONLY - immediately returns inference status (IInferRequest::RequestStatus). It does not block or interrupt current thread
* * RESULT_READY - waits until inference result becomes available
* @param resp Optional: a pointer to an already allocated object to contain extra information of a failure (if occurred)
* @return Enumeration of the resulted action: OK (0) for success
*/
virtual InferenceEngine::StatusCode Wait(int64_t millis_timeout, ResponseDesc *resp) noexcept = 0;
/**
* @brief Starts inference of specified input(s) in asynchronous mode
* @note: It returns immediately. Inference starts also immediately
* @param resp Optional: a pointer to an already allocated object to contain extra information of a failure (if occurred)
* @return Enumeration of the resulted action: OK (0) for success
*/
virtual StatusCode StartAsync(ResponseDesc *resp) noexcept = 0;
/**
* @brief Completion callback definition as pointer to a function
* @param context Pointer to request for providing context inside callback
* @param code Completion result status: OK (0) for success
*/
typedef void (*CompletionCallback)(InferenceEngine::IInferRequest::Ptr context,
InferenceEngine::StatusCode code);
/**
* @brief Sets a callback function that will be called on success or failure of asynchronous request
* @param callback A function to be called
* @return Enumeration of the resulted action: OK (0) for success
*/
virtual StatusCode SetCompletionCallback(CompletionCallback callback) noexcept = 0;
/**
* @brief Gets arbitrary data for the request and stores a pointer to a pointer to the obtained data
* @param data Pointer to a pointer to the gotten arbitrary data
* @param resp Optional: a pointer to an already allocated object to contain extra information of a failure (if occurred)
* @return Enumeration of the resulted action: OK (0) for success
*/
virtual StatusCode GetUserData(void **data, ResponseDesc *resp) noexcept = 0;
/**
* @brief Sets arbitrary data for the request
* @param data Pointer to a pointer to arbitrary data to set
* @param resp Optional: a pointer to an already allocated object to contain extra information of a failure (if occurred)
* @return Enumeration of the resulted action: OK (0) for success
*/
virtual StatusCode SetUserData(void *data, ResponseDesc *resp) noexcept = 0;
/**
* @brief Sets new batch size when dynamic batching is enabled in executable network that created this request.
* @param batch_size new batch size to be used by all the following inference calls for this request.
* @param resp Optional: a pointer to an already allocated object to contain extra information of a failure (if occurred)
* @return Enumeration of the resulted action: OK (0) for success
*/
virtual InferenceEngine::StatusCode SetBatch(int batch_size, ResponseDesc *resp) noexcept = 0;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,61 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief a header file for IMemoryState interface
* @file ie_imemory_state.hpp
*/
#pragma once
#include <memory>
#include "details/ie_no_copy.hpp"
#include "ie_common.h"
#include "ie_blob.h"
namespace InferenceEngine {
/**
* @brief manages data for reset operations
*/
class IMemoryState : public details::no_copy {
public:
using Ptr = std::shared_ptr<IMemoryState>;
/**
* @brief Gets name of current memory state, if length of array is not enough name is truncated by len, null terminator is inserted as well.
* @param name preallocated buffer for receiving name
* @param len Length of the buffer
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode GetName(char *name, size_t len, ResponseDesc *resp) const noexcept = 0;
/**
* @brief reset internal memory state for relevant iexecutable network, to a value specified in SetState
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success*
*/
virtual StatusCode Reset(ResponseDesc *resp) noexcept = 0;
/**
* @brief Sets the new state that is used for all future Reset() operations as a base.
* This method can fail if Blob size does not match the internal state size or precision
* @param newState is the data to use as base state
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
*/
virtual StatusCode SetState(Blob::Ptr newState, ResponseDesc *resp) noexcept = 0;
/**
* @brief returns the value of the last memory state.
* @details Since we roll memory after each infer, we can query the input state always and still get the last state.
* @param lastState
* @param resp Optional: pointer to an already allocated object to contain information in case of failure
* @return Status code of the operation: OK (0) for success
* */
virtual StatusCode GetLastState(Blob::CPtr & lastState, ResponseDesc *resp) const noexcept = 0;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,201 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief a header file for InputInfo class
* @file ie_input_info.hpp
*/
#pragma once
#include <string>
#include <memory>
#include <map>
#include "ie_common.h"
#include "ie_data.h"
#include "ie_preprocess.hpp"
#include "ie_blob.h"
#include "ie_precision.hpp"
namespace InferenceEngine {
/**
* @brief This class contains information about each input of the network
*/
class InputInfo {
public:
/** @brief A smart pointer to the InputInfo instance */
using Ptr = std::shared_ptr<InputInfo>;
/** @brief A smart pointer to the constant InputInfo instance */
using CPtr = std::shared_ptr<const InputInfo>;
/**
* @deprecated it will be removed from public API. Please use getPrecision()
* @brief Gets a precision of the input data provided by user
*
* By default it matches the layers precision, but there are exceptions of this rule
* For Q78 precision networks the input is expected in I16 by default
* For FP16 precision networks the input is expected in FP32 by default
*
* @details By default it matches the layers precision, but there are exceptions of this rule.
* For Q78 precision networks the input is expected in I16 by default.
* For FP16 precision networks the input is expected in FP32 by default.
* The default input precision might be changed preferred one using setInputPrecision()
* function.
* For example, for a Q78 precision network you can pass FP32 input data
* @return The precision used for input blob creation
*/
Precision getInputPrecision() const {
return getPrecision();
}
/**
* @deprecated it will be removed from public API. Please use setPrecision()
* @brief Changes the precision of the input data provided by the user.
* This function should be called before loading the network to the plugin
* @param p A new precision of the input data to set
*/
void setInputPrecision(Precision p) {
setPrecision(p);
}
/**
* @brief Gets a precision of the input data provided by user
*
* By default it matches the layers precision, but there are exceptions of this rule
* For Q78 precision networks the input is expected in I16 by default
* For FP16 precision networks the input is expected in FP32 by default
*
* @details By default it matches the layers precision, but there are exceptions of this rule.
* For Q78 precision networks the input is expected in I16 by default.
* For FP16 precision networks the input is expected in FP32 by default.
* The default input precision might be changed preferred one using setInputPrecision()
* function.
* For example, for a Q78 precision network you can pass FP32 input data
* @return The precision used for input blob creation
*/
Precision getPrecision() const {
if (!_inputData) {
THROW_IE_EXCEPTION << "Data is empty!";
}
return _inputData->getPrecision();
}
/**
* @brief Changes the precision of the input data provided by the user.
* This function should be called before loading the network to the plugin
* @param p A new precision of the input data to set
*/
void setPrecision(Precision p) {
if (!_inputData) {
THROW_IE_EXCEPTION << "Data is empty!";
}
_inputData->setPrecision(p);
}
/**
* @brief Gets a layout of the input data provided by user
* @details By default it matches the layers precision and depends on number of its dimensions:
* C - for 1-dimensional,
* NC - for 2-dimensional,
* CHW - for 3-dimensional,
* NCHW - for 4-dimensional
* The default input layout might be changed preferred one using setLayout() function.
* @return The precision used for input blob creation
*/
Layout getLayout() {
if (!_inputData) {
THROW_IE_EXCEPTION << "Data is empty!";
}
return _inputData->getLayout();
}
/**
* @brief Changes the layout of the input data provided by the user.
* This function should be called before loading the network to the plugin
* @param p A new layout of the input data to set
*/
void setLayout(Layout l) {
if (!_inputData) {
THROW_IE_EXCEPTION << "Data is empty!";
}
_inputData->setLayout(l);
}
/**
* @brief Gets the name of the input
* @return A string - the name of the input
*/
const std::string &name() const { return _inputData->getName(); }
/**
* @brief Gets the input data
* @return A smart pointer to the input data
*/
DataPtr getInputData() {
return _inputData;
}
/**
* @brief Initializes the pointer to the input data that stores the main input parameters like dims, etc.
* This method initializes the precision with the information from the inputPtr if it was not set
* explicitly through setInputPrecision(). If setInputPrecision() was called, this method does not overwrite the precision.
* @param inputPtr Pointer to the input data to set
*/
void setInputData(DataPtr inputPtr) {
_inputData = inputPtr;
}
/**
* @deprecated Please use getTensorDesc for working with layouts and dimensions
* @brief Gets dimensions/shape of the input data with reversed order
* @return A SizeVector object that contains dimensions of the input data. If the data is not set, the method returns an empty SizeVector object.
*/
SizeVector getDims() const {
if (_inputData) {
return _inputData->dims;
} else {
return SizeVector();
}
}
/**
* @brief Returns the tensor descriptor
*/
const TensorDesc &getTensorDesc() const {
if (!_inputData) {
THROW_IE_EXCEPTION << "Data is empty!";
}
return _inputData->getTensorDesc();
}
/**
* @brief Gets pre-process info for the input
* @return A reference to the PreProcessInfo instance that contains pre-process info for this input
*/
PreProcessInfo &getPreProcess() { return _preProcessInfo; }
protected:
/**
* @brief Pre-process info for the input
*/
PreProcessInfo _preProcessInfo;
/**
* @brief A smart pointer to the input data
*/
DataPtr _inputData;
};
/**
* @brief A collection that contains string as key, and InputInfo smart pointer as value
*/
using InputsDataMap = std::map<std::string, InputInfo::Ptr>;
/**
* @brief A collection that contains string as key, and const InputInfo smart pointer as value
*/
using ConstInputsDataMap = std::map<std::string, InputInfo::CPtr>;
} // namespace InferenceEngine

View File

@ -0,0 +1,975 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief a header file for internal Layers structure to describe layers information
* @file ie_layers.h
*/
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <iterator>
#include <cctype>
#include "ie_common.h"
#include "ie_data.h"
#include "ie_blob.h"
#include "ie_device.hpp"
namespace InferenceEngine {
/**
* @brief This is an internal common Layer parameter parsing arguments
*/
struct LayerParams {
/// @brief Layer name
std::string name;
/// @brief Layer type
std::string type;
/// @brief Layer precision
Precision precision;
};
/**
* @brief This is a base abstraction Layer - all DNN Layers inherit from this class
*/
class CNNLayer {
public:
/**
* @brief A shared pointer to CNNLayer
*/
using Ptr = std::shared_ptr<CNNLayer>;
/**
* @brief Layer name
*/
std::string name;
/**
* @brief Layer type
*/
std::string type;
/**
* @brief Layer base operating precision
*/
Precision precision;
/**
* @brief A vector of pointers to the output data elements of this layer in the di-graph (order matters)
*/
std::vector<DataPtr> outData;
/**
* @brief A vector of weak pointers to the input data elements of this layer in the di-graph (order matters)
*/
std::vector<DataWeakPtr> insData;
/**
* @brief If suggested to fuse - a pointer to the layer which needs to be fused with this layer
*/
Ptr _fusedWith;
/**
* @brief Convenience user values to store in this object as extra data
*/
UserValue userValue;
/**
* @brief Layer affinity set by user.
*/
std::string affinity;
/**
* @brief A constructor. Creates a new CNNLayer instance and initializes layer parameters with the given values.
* @param prms Basic common parsing parameters
*/
explicit CNNLayer(const LayerParams &prms) : name(prms.name), type(prms.type),
precision(prms.precision), userValue({0}) {
}
/**
* @brief A virtual destructor
*/
virtual ~CNNLayer() = default;
/**
* @brief Sets a layer to be fused with
* @param layer Reference to the layer to be fused with
*/
void fuse(Ptr &layer) {
_fusedWith = layer;
}
/**
* @brief Returns the first element of the input data for this layer
* @return A smart pointer to the input data element
*/
virtual const DataPtr input() const {
if (insData.empty()) {
THROW_IE_EXCEPTION << "Internal error: input data is empty";
}
auto lockedFirstInsData = insData[0].lock();
if (!lockedFirstInsData) {
THROW_IE_EXCEPTION << "Internal error: unable to lock weak_ptr\n";
}
return lockedFirstInsData;
}
/**
* @brief Checks if the input data and layer data are legitimate
*/
INFERENCE_ENGINE_API_CPP(void) validateLayer();
/**
* @brief Gets float value for the given parameter
* @param param - name of the parameter to find
* @param def - default value of the parameter if not found
* @return float value
*/
float GetParamAsFloat(const char* param, float def) const {
std::string val = GetParamAsString(param, std::to_string(def).c_str());
try {
return std::stof(val);
} catch (...) {
THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " from IR for layer " << name
<< ". Value " << val << " cannot be casted to float.";
}
}
/**
* @brief Returns a float value for the given layer parameter
* @param param Name of the layer parameter
* @return A float value for the specified parameter
*/
float GetParamAsFloat(const char *param) const {
std::string val = GetParamAsString(param);
try {
return std::stof(val);
} catch (...) {
THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " from IR for layer " << name
<< ". Value " << val << " cannot be casted to float.";
}
}
/**
* @brief Returns a vector of float values for the given parameter or returns the default value
* @param param Name of the layer parameter
* @param def Default value of the parameter if not found
* @return vector of float values
*/
std::vector<float> GetParamAsFloats(const char *param, std::vector<float> def) const {
std::string vals = GetParamAsString(param, "");
std::vector<float> result;
std::istringstream stream(vals);
std::string str;
if (vals.empty())
return def;
while (getline(stream, str, ',')) {
try {
result.push_back(std::stof(str));
} catch (...) {
THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " " << str << " from IR for layer " << name
<< ". Value " << vals << " cannot be casted to floats.";
}
}
return result;
}
/**
* @brief Returns a vector of float values for the given parameter
* @param param Name of the layer parameter
* @return vector of float values
*/
std::vector<float> GetParamAsFloats(const char *param) const {
std::string vals = GetParamAsString(param);
std::vector<float> result;
std::istringstream stream(vals);
std::string str;
while (getline(stream, str, ',')) {
try {
result.push_back(std::stof(str));
} catch (...) {
THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " " << str << " from IR for layer " << name
<< ". Value " << vals << " cannot be casted to floats.";
}
}
return result;
}
/**
* @brief Returns an integer value for the given parameter or returns the default value
* @param param Name of the layer parameter
* @param def Default value of the parameter if not found
* @return An int value for the specified parameter
*/
int GetParamAsInt(const char *param, int def) const {
std::string val = GetParamAsString(param, std::to_string(def).c_str());
try {
return std::stoi(val);
} catch (...) {
THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " from IR for layer " << name
<< ". Value " << val << " cannot be casted to int.";
}
}
/**
* @brief Returns an integer value for the given parameter
* @param param Name of the layer parameter
* @return An int value for the specified parameter
*/
int GetParamAsInt(const char *param) const {
std::string val = GetParamAsString(param);
try {
return std::stoi(val);
} catch (...) {
THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " from IR for layer " << name
<< ". Value " << val << " cannot be casted to int.";
}
}
/**
* @brief Returns a vector of int values for the given parameter or returns the default value
* @param param Name of the layer parameter
* @param def Default value of the parameter if not found
* @return vector of int values
*/
std::vector<int> GetParamAsInts(const char *param, std::vector<int> def) const {
std::string vals = GetParamAsString(param, "");
std::vector<int> result;
std::istringstream stream(vals);
std::string str;
if (vals.empty())
return def;
while (getline(stream, str, ',')) {
try {
result.push_back(std::stoi(str));
} catch (...) {
THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " " << str << " from IR for layer " << name
<< ". Value " << vals << " cannot be casted to int.";
}
}
return result;
}
/**
* @brief Returns a vector of int values for the given parameter
* @param param Name of the layer parameter
* @return vector of int values
*/
std::vector<int> GetParamAsInts(const char *param) const {
std::string vals = GetParamAsString(param);
std::vector<int> result;
std::istringstream stream(vals);
std::string str;
while (getline(stream, str, ',')) {
try {
result.push_back(std::stoi(str));
} catch (...) {
THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " " << str << " from IR for layer " << name
<< ". Value " << vals << " cannot be casted to int.";
}
}
return result;
}
/**
* @brief Returns an unsigned integer value for the given parameter or returns the default value
* @param param Name of the layer parameter
* @param def Default value of the parameter if not found
* @return An unsigned integer value for the specified parameter
*/
unsigned int GetParamAsUInt(const char *param, unsigned int def) const {
std::string val = GetParamAsString(param, std::to_string(def).c_str());
std::string message = "Cannot parse parameter " + std::string(param) + " from IR for layer " + name
+ ". Value " + val + " cannot be casted to int.";
try {
int value = std::stoi(val);
if (value < 0) {
THROW_IE_EXCEPTION << message;
}
return static_cast<unsigned int>(value);
} catch (...) {
THROW_IE_EXCEPTION << message;
}
}
/**
* @brief Returns an unsigned integer value for the given parameter
* @param param Name of the layer parameter
* @return An unsigned integer value for the specified parameter
*/
unsigned int GetParamAsUInt(const char *param) const {
std::string val = GetParamAsString(param);
std::string message = "Cannot parse parameter " + std::string(param) + " from IR for layer " + name
+ ". Value " + val + " cannot be casted to int.";
try {
int value = std::stoi(val);
if (value < 0) {
THROW_IE_EXCEPTION << message;
}
return static_cast<unsigned int>(value);
} catch (...) {
THROW_IE_EXCEPTION << message;
}
}
/**
* @brief Returns a vector of unsigned int values for the given parameter or returns the default value
* @param param Name of the layer parameter
* @param def Default value of the parameter if not found
* @return vector of unsigned int values
*/
std::vector<unsigned int> GetParamAsUInts(const char *param, std::vector<unsigned int> def) const {
std::string vals = GetParamAsString(param, "");
std::vector<unsigned int> result;
std::istringstream stream(vals);
std::string str;
std::string message = "Cannot parse parameter " + std::string(param) + " " + str + " from IR for layer " + name
+ ". Value " + vals + " cannot be casted to int.";
if (vals.empty())
return def;
while (getline(stream, str, ',')) {
try {
int value = std::stoi(str);
if (value < 0) {
THROW_IE_EXCEPTION << message;
}
result.push_back(static_cast<unsigned int>(value));
} catch (...) {
THROW_IE_EXCEPTION << message;
}
}
return result;
}
/**
* @brief Returns a vector of unsigned int values for the given parameter
* @param param Name of the layer parameter
* @return vector of unsigned int values
*/
std::vector<unsigned int> GetParamAsUInts(const char *param) const {
std::string vals = GetParamAsString(param);
std::vector<unsigned int> result;
std::istringstream stream(vals);
std::string str;
std::string message = "Cannot parse parameter " + std::string(param) + " " + str + " from IR for layer " + name
+ ". Value " + vals + " cannot be casted to int.";
while (getline(stream, str, ',')) {
try {
int value = std::stoi(str);
if (value < 0) {
THROW_IE_EXCEPTION << message;
}
result.push_back(static_cast<unsigned int>(value));
} catch (...) {
THROW_IE_EXCEPTION << message;
}
}
return result;
}
/**
* @brief Returns an boolean value for the given parameter.
* The valid values are (true, false, 1, 0).
* @param param Name of the layer parameter
* @param def Default value of the parameter if not found
* @return An bool value for the specified parameter
*/
bool GetParamsAsBool(const char *param, bool def) const {
std::string val = GetParamAsString(param, std::to_string(def).c_str());
std::string loweredCaseValue;
std::transform(val.begin(), val.end(), std::back_inserter(loweredCaseValue), [](char value) {
return std::tolower(value);
});
bool result = false;
if (!(std::istringstream(loweredCaseValue) >> std::boolalpha >> result)) {
// attempting parse using non alpha bool
return static_cast<bool>(GetParamAsInt(param, def));
}
return result;
}
/**
* @brief Returns a string value for the given parameter or returns the default one
* @param param Name of the layer parameter
* @param def Default value of the parameter if not found
* @return A string value
*/
std::string GetParamAsString(const char *param, const char *def) const {
auto it = params.find(param);
if (it == params.end()) {
return def;
}
return (*it).second;
}
/**
* @brief Returns a string value for the given parameter.
* Throws exception if parameter was not found.
* @param param Name of the layer parameter
* @return A string value
*/
std::string GetParamAsString(const char *param) const {
auto it = params.find(param);
if (it == params.end()) {
THROW_IE_EXCEPTION << "No such parameter name '" << param << "' for layer " << name;
}
return (*it).second;
}
/**
* @brief Map of pairs: (parameter name, parameter value)
*/
std::map<std::string, std::string> params;
/**
* @brief Map of pairs: (name, weights/biases blob)
*/
std::map<std::string, Blob::Ptr> blobs;
};
/**
* @brief Alias for CNNLayer object
*/
using GenericLayer = class CNNLayer;
/**
* @brief This class represents a layer with Weights and/or Biases (e.g. Convolution/Fully Connected, etc.)
*/
class WeightableLayer : public CNNLayer {
public:
/**
* @brief A default constructor. Constructs a WeightableLayer instance and initiates layer parameters with the given values
* @param prms Initial layer parameters
*/
explicit WeightableLayer(const LayerParams &prms) : CNNLayer(prms) {}
/**
* @brief A pointer to a weights blob
*/
Blob::Ptr _weights;
/**
* @brief A pointer to a biases blob
*/
Blob::Ptr _biases;
/**
* @brief Constructs a WeightableLayer instance and initiates layer parameters with the given values
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a standard 3D Convolution Layer
*/
class ConvolutionLayer : public WeightableLayer {
public:
/**
* @brief A convolution kernel width
*/
unsigned int _kernel_x = 0;
/**
* @brief A convolution kernel height
*/
unsigned int _kernel_y = 0;
/**
* @brief An input convolution stride width
*/
unsigned int _stride_x = 1;
/**
* @brief An Input convolution stride height
*/
unsigned int _stride_y = 1;
/**
* @brief A number of output feature maps (size) generating the 3'rd output dimension
*/
unsigned int _out_depth = 0;
/**
* @brief Input padding width
*/
unsigned int _padding_x = 0;
/**
* @brief Input padding height
*/
unsigned int _padding_y = 0;
/**
* @brief Dilation width
*/
unsigned int _dilation_x = 1;
/**
* @brief Dilation height
*/
unsigned int _dilation_y = 1;
/**
* @brief Number of groups
*/
unsigned int _group = 1;
/**
* @brief Creates a new ConvolutionLayer instance.
*/
using WeightableLayer::WeightableLayer;
};
/**
* @brief This class represents a standard deconvolution layer
*/
class DeconvolutionLayer : public WeightableLayer {
public:
/**
* @brief Deconvolution kernel width
*/
unsigned int _kernel_x = 0;
/**
* @brief Deconvolution kernel height
*/
unsigned int _kernel_y = 0;
/**
* @brief Input Deconvolution stride width
*/
unsigned int _stride_x = 0;
/**
* @brief Input Deconvolution stride height
*/
unsigned int _stride_y = 0;
/**
* @brief number of output feature maps (size) generating the 3'rd output dimension
*/
unsigned int _out_depth = 0;
/**
* @brief Input padding width
*/
unsigned int _padding_x = 0;
/**
* @brief Input padding height
*/
unsigned int _padding_y = 0;
/**
* @brief Dilation width
*/
unsigned int _dilation_x = 0;
/**
* @brief Dilation height
*/
unsigned int _dilation_y = 0;
/**
* @brief Number of groups
*/
unsigned int _group = 0;
/**
* @brief Creates a new DeconvolutionLayer instance.
*/
using WeightableLayer::WeightableLayer;
};
/**
* @brief This class represents a standard pooling layer
*/
class PoolingLayer : public CNNLayer {
public:
/**
* @brief Pooling kernel width
*/
unsigned int _kernel_x = 0;
/**
* @brief Pooling kernel height
*/
unsigned int _kernel_y = 0;
/**
* @brief Input Pooling stride width
*/
unsigned int _stride_x = 0;
/**
* @brief Input Pooling stride height
*/
unsigned int _stride_y = 0;
/**
* @brief Input padding width
*/
unsigned int _padding_x = 0;
/**
* @brief Input padding height
*/
unsigned int _padding_y = 0;
/**
* @enum PoolType
* @brief Defines available pooling types
*/
enum PoolType {
MAX = 1,
AVG = 2,
STOCH = 3,
ROI = 4,
SPACIAL_PYRAMID = 5
};
/**
* @brief A pooling type
*/
PoolType _type = MAX;
/**
* @brief A flag that indicates if padding is excluded or not
*/
bool _exclude_pad = false;
/**
* @brief Creates a new PoolingLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a fully connected layer
*/
class FullyConnectedLayer : public WeightableLayer {
public:
/**
* @brief A size of output
*/
unsigned int _out_num = 0;
/**
* @brief Creates a new FullyConnectedLayer instance and initializes layer parameters with the given values.
*/
using WeightableLayer::WeightableLayer;
};
/**
* @brief This class represents concatenation layer
* Takes as input several data elements and merges them to one using the supplied axis
*/
class ConcatLayer : public CNNLayer {
public:
/**
* @brief An axis on which concatenation operation is performed
*/
unsigned int _axis = 1;
/**
* @brief Creates a new ConcatLayer instance and initializes layer parameters with the given values.
* If batch is used, then batch needs to be specified as an input dimension also
* In current implementation 1 means channels, 0 - batch
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a layer that evenly splits the input into the supplied outputs
*/
class SplitLayer : public CNNLayer {
public:
/**
* @brief An axis on which split operation is performed
*/
unsigned int _axis = 1;
/**
* @brief Creates a new SplitLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a Linear Response Normalization (LRN) Layer
*/
class NormLayer : public CNNLayer {
public:
/**
* @brief Response size
*/
unsigned int _size = 0;
/**
* @deprecated
*/
unsigned int _k = 1;
/**
* @brief Alpha coefficient
*/
float _alpha = 0;
/**
* @brief Beta coefficient
*/
float _beta = 0;
/**
* @brief Flag to specify normalization across feature maps (true) or across channels
*/
bool _isAcrossMaps = false;
/**
* @brief Creates a new NormLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents standard softmax Layer
*/
class SoftMaxLayer : public CNNLayer {
public:
/**
* @brief Axis number for a softmax operation
*/
int axis = 1;
/**
* @brief Creates a new SoftMaxLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @class GRNLayer
* @brief This class represents standard GRN Layer
*/
class GRNLayer : public CNNLayer {
public:
/**
* @brief A default constructor. Creates a new GRNLayer instance and initializes layer parameters with the given values.
* @param prms Initial layer parameters
*/
explicit GRNLayer(const LayerParams &prms) : CNNLayer(prms), bias(0.f) {}
/**
* @brief Bias for squares sum
*/
float bias = 0.f;
};
/**
* @class MVNLayer
* @brief This class represents standard MVN Layer
*/
class MVNLayer : public CNNLayer {
public:
/**
* @brief A default constructor. Creates a new MVNLayer instance and initializes layer parameters with the given values.
* @param prms Initial layer parameters
*/
explicit MVNLayer(const LayerParams &prms) : CNNLayer(prms), across_channels(0), normalize(1) {}
/**
* @brief Indicate that mean value is calculated across channels
*/
int across_channels;
/**
* @brief Indicate that the result needs to be normalized
*/
int normalize = 1;
};
/**
* @brief This class represents a Rectified Linear activation layer
*/
class ReLULayer : public CNNLayer {
public:
/**
* @brief Negative slope is used to takle negative inputs instead of setting them to 0
*/
float negative_slope = 0.0f;
/**
* @brief Creates a new ReLULayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a Clamp activation layer
* Clamps all tensor elements into the range [min_value, max_value]
*/
class ClampLayer : public CNNLayer {
public:
/**
* @brief A minimum value
*/
float min_value = 0.0f;
/**
* @brief A maximum value
*/
float max_value = 1.0f;
/**
* @brief Creates a new ClampLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents an element wise operation layer
*/
class EltwiseLayer : public CNNLayer {
public:
/**
* @enum eOperation
* @brief Defines possible operations that can be used
*/
enum eOperation {
Sum = 0, Prod, Max
};
/**
* @brief A type of the operation to use
*/
eOperation _operation = Sum;
/**
* @brief A vector of coefficients to scale the operands
*/
std::vector<float> coeff;
/**
* @brief Creates a new EltwiseLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a standard crop layer
*/
class CropLayer : public CNNLayer {
public:
/**
* @brief A vector of dimensions for cropping
*/
std::vector<int> axis;
/**
* @deprecated result size is defined by second input
* @brief A vector of dimensions to be preserved
*/
std::vector<int> dim;
/**
* @brief A vector of offsets for each dimension
*/
std::vector<int> offset;
/**
* @brief Creates a new CropLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a standard reshape layer
*/
class ReshapeLayer : public CNNLayer {
public:
/**
* @brief A vector of sizes of the shape
*/
std::vector<int> shape;
/**
* @brief A number of axis to be taken for a reshape
*/
int axis = 0;
/**
* @brief A number of first axises to be taken for a reshape
*/
int num_axes = -1;
/**
* @brief Creates a new ReshapeLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a standard Tile Layer
*/
class TileLayer : public CNNLayer {
public:
/**
* @brief An index of the axis to tile
*/
int axis = -1;
/**
* @brief A number of copies to be made
*/
int tiles = -1;
/**
* @brief Creates a new TileLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a Layer which performs Scale and Shift
*/
class ScaleShiftLayer : public WeightableLayer {
public:
/**
* @brief A flag that indicates if the same value is used for all the features. If false, the value is used pixel wise
*/
unsigned int _broadcast = 0;
/**
* @brief Creates a new ScaleShiftLayer instance.
*/
using WeightableLayer::WeightableLayer;
};
/**
* @class PReLULayer
* @brief This class represents a Layer which performs Scale and Shift
*/
class PReLULayer : public WeightableLayer {
public:
/**
* @brief A flag that indicates if the same negative_slope value is used for all the features. If false, the value is used pixel wise
*/
bool _channel_shared;
public:
/**
* @brief A default constructor. Creates a new PReLULayer instance and initializes layer parameters with the given values.
* @param prms Initial layer parameters
*/
explicit PReLULayer(const LayerParams &prms) : WeightableLayer(prms), _channel_shared(false) {}
};
/**
* @brief This class represents a standard Power Layer
* Formula is: output = (offset + scale * input) ^ power
*/
class PowerLayer : public CNNLayer {
public:
/**
* @brief An exponent value
*/
float power = 1.f;
/**
* @brief A scale factor
*/
float scale = 1.f;
/**
* @brief An offset value
*/
float offset = 0.f;
/**
* @brief Creates a new PowerLayer instance.
*/
using CNNLayer::CNNLayer;
};
/**
* @brief This class represents a Batch Normalization Layer
*/
class BatchNormalizationLayer : public WeightableLayer {
public:
/**
* @brief A small value to add to the variance estimate to avoid division by zero
*/
float epsilon = 1e-3f;
/**
* @brief Creates a new BatchNormalizationLayer instance.
*/
using WeightableLayer::WeightableLayer;
};
} // namespace InferenceEngine

View File

@ -0,0 +1,392 @@
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for data layouts and conversion between them
* @file ie_layouts.h
*/
#pragma once
#include <algorithm>
#include "ie_api.h"
#include "ie_common.h"
#include "ie_precision.hpp"
namespace InferenceEngine {
/**
* @brief This class describes blocking layouts
*/
class INFERENCE_ENGINE_API_CLASS(BlockingDesc) {
public:
/**
* @brief The default constructor which creates empty blocking descriptor
*/
BlockingDesc();
/**
* @brief The constructor which allows to create blocking descriptors for standard layouts
* @param dims real dimensions
* @param layout memory layout
*/
BlockingDesc(const SizeVector& dims, Layout layout);
/**
* @brief The constructor allows to create blocking descriptors for blocked memory
* @param blocked_dims blocked dimensions
* @param order the order of dimensions
*/
BlockingDesc(const SizeVector& blocked_dims, const SizeVector& order);
/**
* @brief The constructor allows to create blocking descriptors for blocked memory
* @param blocked_dims blocked dimensions
* @param order the order of dimensions
* @param offset offset to the current memory block
*/
BlockingDesc(const SizeVector& blocked_dims, const SizeVector& order, size_t offset);
/**
* @brief The constructor allows to create blocking descriptors for blocked memory
* @param blocked_dims blocked dimensions
* @param order the order of dimensions
* @param offset offset to the current memory block
* @param dimOffsets per-dimension offset from the padding to actual data,
*/
BlockingDesc(const SizeVector& blocked_dims, const SizeVector& order, size_t offset, SizeVector dimOffsets);
/**
* @brief The constructor allows to create blocking descriptors for blocked memory
* @param blocked_dims blocked dimensions
* @param order the order of dimensions
* @param offset offset to the current memory block
* @param dimOffsets per-dimension offset from the padding to actual data,
* @param strides strides for each dimension
*/
BlockingDesc(const SizeVector& blocked_dims, const SizeVector& order, size_t offset, SizeVector dimOffsets, SizeVector strides);
/**
* @brief Destructor
*/
virtual ~BlockingDesc() = default;
/**
* @brief Returns the blocked dimensions vector
* @return blocked dimensions
*/
const SizeVector& getBlockDims() const {
return blockedDims;
}
/**
* @brief Returns the vector of order
* @return order
*/
const SizeVector& getOrder() const {
return order;
}
/**
* @brief Returns the per-dimension offset vector
* @return offsets
*/
const SizeVector& getOffsetPaddingToData() const {
return offsetPaddingToData;
}
/**
* @brief Returns the offset to the current memory block
* @return offset
*/
size_t getOffsetPadding() const {
return offsetPadding;
}
/**
* @brief Returns strides for each dimension
* @return strides
*/
const SizeVector& getStrides() const {
return strides;
}
/**
* @brief The comparison operator for the BlockingDesc
* @param rhs object to compare
* @return true if objects are equal
*/
bool operator == (const BlockingDesc& rhs) const;
/**
* @brief The comparison operator for the BlockingDesc
* @param rhs object to compare
* @return true if objects aren't equal
*/
bool operator != (const BlockingDesc& rhs) const;
protected:
void fillDesc(const SizeVector& blocked_dims, const SizeVector& order);
private:
/** Blocked dimensions. */
SizeVector blockedDims;
/** Strides for blocked dimensions */
SizeVector strides;
/** The order of blocked dimensions **/
SizeVector order;
/** Per-dimension offset from the padding to actual data, the top-level
* tensor with offsets applied must lie within the padding area. */
SizeVector offsetPaddingToData;
/** Offset from memory origin to the current block, non-zero only in
* a description of a memory sub-block. */
size_t offsetPadding;
};
/**
* @brief This class defines Tensor description
*/
class INFERENCE_ENGINE_API_CLASS(TensorDesc) {
public:
/**
* @brief The constructor creates the tensor descriptor using blocking descriptor
* @param precision memory precision
* @param dims memory dimensions
* @param blockDesc blocking descriptor
*/
TensorDesc(const Precision& precision, SizeVector dims, const BlockingDesc& blockDesc);
/**
* @brief The constructor creates the tensor descriptor using standard layout
* @param precision memory precision
* @param dims memory dimensions
* @param layout memory layout
*/
TensorDesc(const Precision& precision, SizeVector dims, Layout layout);
/**
* @brief The constructor creates the empty tensor descriptor with precision and layout
* @param precision memory precision
* @param layout memory layout
*/
TensorDesc(const Precision& precision, Layout layout);
/**
* @brief The default constructor which creates empty tensor descriptor
*/
TensorDesc();
/**
* @brief Destructor
*/
virtual ~TensorDesc() = default;
/**
* @brief Reshapes the tensor descriptor
* @param dims new dimensions
* @param layout new layout if it is necessary
*/
void reshape(const SizeVector &dims, Layout layout = Layout::ANY);
/**
* @brief Reshapes the tensor descriptor
* @param dims new dimensions
* @param blockDesc new blocking descriptor
*/
void reshape(const SizeVector &dims, const BlockingDesc &blockDesc);
/**
* @brief Returns the vector of dimensions
* @return dimensions
*/
SizeVector& getDims() {
return dims;
}
/**
* @brief Returns the constant vector of dimensions
* @return dimensions
*/
const SizeVector& getDims() const {
return dims;
}
/**
* @brief Sets dimensions
* @param dims new dimensions
*/
void setDims(const SizeVector& dims);
/**
* @brief Returns the memory layout
* @return layout
*/
Layout getLayout() const {
return layout;
}
/**
* @brief Sets the layout
* @param l memory layout
*/
void setLayout(Layout l) {
bool inconsistentLayout = false;
switch (layout) {
case Layout::C:
inconsistentLayout = dims.size() != 1;
break;
case Layout::OIHW:
case Layout::NCHW:
case Layout::NHWC:
inconsistentLayout = dims.size() != 4;
break;
case Layout::CHW:
inconsistentLayout = dims.size() != 3;
break;
case Layout::CN:
case Layout::NC:
case Layout::HW:
inconsistentLayout = dims.size() != 2;
break;
default:
break;
}
if (inconsistentLayout)
THROW_IE_EXCEPTION << "Dims and format are inconsistent.";
layout = l;
}
/**
* @brief Returns the memory precision
* @return precision
*/
const Precision& getPrecision() const {
return precision;
}
/**
* @brief Sets the memory precision
* @param p precision
*/
void setPrecision(const Precision& p) {
precision = p;
}
/**
* @brief Returns the blocking descriptor
* @return blocking descriptor
*/
const BlockingDesc& getBlockingDesc() const {
return blockingDesc;
}
/**
* @brief The comparison operator for the TensorDesc
* @param rhs object to compare
* @return true if objects are equal
*/
bool operator == (const TensorDesc& rhs) const;
/**
* @brief The comparison operator for the TensorDesc
* @param rhs object to compare
* @return true if objects aren't equal
*/
bool operator != (const TensorDesc& rhs) const;
/**
* @brief Calculates offset for the vector of dimensions
* @param v vector of dimensions
* @return offset
*/
size_t offset(const SizeVector& v) const;
/**
* @brief Calculates offset for the local offset
* @param l local offset
* @return offset
*/
size_t offset(size_t l) const;
/**
* @brief Returns the standard layout for dimensions
* @param dims the vector of dimensions
* @return the standard memory layout
*/
static Layout getLayoutByDims(SizeVector dims);
private:
/**
* Memory layout
*/
Layout layout;
/**
* @brief blob's dimensions
*/
SizeVector dims;
/**
* @brief memory precision
*/
Precision precision;
/**
* Detailed information about layout construction
*/
BlockingDesc blockingDesc;
};
/**
* @deprecated
*/
static const size_t I_N = 3;
static const size_t I_C = 2;
static const size_t I_H = 1;
static const size_t I_W = 0;
/**
* @deprecated Uses TensorDesc working with layouts
* @brief This class helps calculating offset in different layouts
*/
class INFERENCE_ENGINE_API_CLASS(LayoutOffsetCounter) {
private:
Layout _layout;
SizeVector _dims;
size_t _dims_count;
/**
* @brief Stores multipliers that are calculated during the LayoutOffsetCounter construction.
* The multipliers are used for conversion.
*/
SizeVector _muls;
public:
/**
* @brief A default constructor
* @param dims Tensor dimension array (reverse NCHW order as in the IR: w,h,c,n)
*/
LayoutOffsetCounter(Layout layout, SizeVector dims);
/**
* @brief Calculates an offset for the specified layout
* @param pos Tensor position array (reverse NCHW order as in the IR: w,h,c,n)
*/
size_t Offset(SizeVector pos);
};
/**
* @deprecated Please use TensorDescriptors for conversion
*/
template<typename T> void ConvertLayout(Layout sourceLayout, Layout destLayout, const T* sourceBuffer, T* destBuffer, SizeVector dims) {
if (dims.size() == 0) return;
SizeVector pos(dims.size(), 0);
LayoutOffsetCounter srcOffsetCounter(sourceLayout, dims);
LayoutOffsetCounter destOffsetCounter(destLayout, dims);
while (true) {
// Setting the current item
size_t ps = srcOffsetCounter.Offset(pos);
size_t pd = destOffsetCounter.Offset(pos);
destBuffer[pd] = sourceBuffer[ps];
// Advancing pos
size_t caret = 0;
pos[caret]++;
while (pos[caret] >= dims[caret]) {
pos[caret] = 0;
caret++;
if (caret == pos.size()) {
// We have finished converting
return;
}
pos[caret]++;
}
}
}
} // namespace InferenceEngine

Some files were not shown because too many files have changed in this diff Show More