ie.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. //
  5. // Copyright (C) 2019-2021 Intel Corporation
  6. #ifndef OPENCV_GAPI_INFER_IE_HPP
  7. #define OPENCV_GAPI_INFER_IE_HPP
  8. #include <unordered_map>
  9. #include <unordered_set>
  10. #include <string>
  11. #include <array>
  12. #include <tuple> // tuple, tuple_size
  13. #include <map>
  14. #include <opencv2/gapi/opencv_includes.hpp>
  15. #include <opencv2/gapi/util/any.hpp>
  16. #include <opencv2/core/cvdef.h> // GAPI_EXPORTS
  17. #include <opencv2/gapi/gkernel.hpp> // GKernelPackage
  18. #include <opencv2/gapi/infer.hpp> // Generic
  19. #include <opencv2/gapi/streaming/onevpl/accel_types.hpp> // Preproc Dev & Ctx
  20. namespace cv {
  21. namespace gapi {
  22. // FIXME: introduce a new sub-namespace for NN?
  23. /**
  24. * @brief This namespace contains G-API OpenVINO backend functions,
  25. * structures, and symbols.
  26. */
  27. namespace ie {
  28. GAPI_EXPORTS cv::gapi::GBackend backend();
  29. /**
  30. * Specifies how G-API and IE should trait input data
  31. *
  32. * In OpenCV, the same cv::Mat is used to represent both
  33. * image and tensor data. Sometimes those are hardly distinguishable,
  34. * so this extra parameter is used to give G-API a hint.
  35. *
  36. * This hint controls how G-API reinterprets the data when converting
  37. * it to IE Blob format (and which layout/etc is assigned to this data).
  38. */
  39. enum class TraitAs: int
  40. {
  41. TENSOR, //!< G-API traits an associated cv::Mat as a raw tensor and passes dimensions as-is
  42. IMAGE //!< G-API traits an associated cv::Mat as an image so creates an "image" blob (NCHW/NHWC, etc)
  43. };
  44. using IEConfig = std::map<std::string, std::string>;
  45. namespace detail {
  46. struct ParamDesc {
  47. std::string model_path;
  48. std::string weights_path;
  49. std::string device_id;
  50. std::vector<std::string> input_names;
  51. std::vector<std::string> output_names;
  52. using ConstInput = std::pair<cv::Mat, TraitAs>;
  53. std::unordered_map<std::string, ConstInput> const_inputs;
  54. std::size_t num_in;
  55. std::size_t num_out;
  56. enum class Kind {Load, Import};
  57. Kind kind;
  58. bool is_generic;
  59. IEConfig config;
  60. std::map<std::string, std::vector<std::size_t>> reshape_table;
  61. std::unordered_set<std::string> layer_names_to_reshape;
  62. // NB: Number of asyncrhonious infer requests
  63. size_t nireq;
  64. // NB: An optional config to setup RemoteContext for IE
  65. cv::util::any context_config;
  66. // NB: batch_size can't be equal to 1 by default, because some of models
  67. // have 2D (Layout::NC) input and if the first dimension not equal to 1
  68. // net.setBatchSize(1) will overwrite it.
  69. cv::optional<size_t> batch_size;
  70. cv::optional<cv::gapi::wip::onevpl::Device> vpl_preproc_device;
  71. cv::optional<cv::gapi::wip::onevpl::Context> vpl_preproc_ctx;
  72. };
  73. } // namespace detail
  74. // FIXME: this is probably a shared (reusable) thing
  75. template<typename Net>
  76. struct PortCfg {
  77. using In = std::array
  78. < std::string
  79. , std::tuple_size<typename Net::InArgs>::value >;
  80. using Out = std::array
  81. < std::string
  82. , std::tuple_size<typename Net::OutArgs>::value >;
  83. };
  84. /**
  85. * @brief This structure provides functions
  86. * that fill inference parameters for "OpenVINO Toolkit" model.
  87. */
  88. template<typename Net> class Params {
  89. public:
  90. /** @brief Class constructor.
  91. Constructs Params based on model information and specifies default values for other
  92. inference description parameters. Model is loaded and compiled using "OpenVINO Toolkit".
  93. @param model Path to topology IR (.xml file).
  94. @param weights Path to weights (.bin file).
  95. @param device target device to use.
  96. */
  97. Params(const std::string &model,
  98. const std::string &weights,
  99. const std::string &device)
  100. : desc{ model, weights, device, {}, {}, {}
  101. , std::tuple_size<typename Net::InArgs>::value // num_in
  102. , std::tuple_size<typename Net::OutArgs>::value // num_out
  103. , detail::ParamDesc::Kind::Load
  104. , false
  105. , {}
  106. , {}
  107. , {}
  108. , 1u
  109. , {}
  110. , {}
  111. , {}
  112. , {}} {
  113. };
  114. /** @overload
  115. Use this constructor to work with pre-compiled network.
  116. Model is imported from a pre-compiled blob.
  117. @param model Path to model.
  118. @param device target device to use.
  119. */
  120. Params(const std::string &model,
  121. const std::string &device)
  122. : desc{ model, {}, device, {}, {}, {}
  123. , std::tuple_size<typename Net::InArgs>::value // num_in
  124. , std::tuple_size<typename Net::OutArgs>::value // num_out
  125. , detail::ParamDesc::Kind::Import
  126. , false
  127. , {}
  128. , {}
  129. , {}
  130. , 1u
  131. , {}
  132. , {}
  133. , {}
  134. , {}} {
  135. };
  136. /** @brief Specifies sequence of network input layers names for inference.
  137. The function is used to associate cv::gapi::infer<> inputs with the model inputs.
  138. Number of names has to match the number of network inputs as defined in G_API_NET().
  139. In case a network has only single input layer, there is no need to specify name manually.
  140. @param layer_names std::array<std::string, N> where N is the number of inputs
  141. as defined in the @ref G_API_NET. Contains names of input layers.
  142. @return reference to this parameter structure.
  143. */
  144. Params<Net>& cfgInputLayers(const typename PortCfg<Net>::In &layer_names) {
  145. desc.input_names.clear();
  146. desc.input_names.reserve(layer_names.size());
  147. std::copy(layer_names.begin(), layer_names.end(),
  148. std::back_inserter(desc.input_names));
  149. return *this;
  150. }
  151. /** @brief Specifies sequence of network output layers names for inference.
  152. The function is used to associate cv::gapi::infer<> outputs with the model outputs.
  153. Number of names has to match the number of network outputs as defined in G_API_NET().
  154. In case a network has only single output layer, there is no need to specify name manually.
  155. @param layer_names std::array<std::string, N> where N is the number of outputs
  156. as defined in the @ref G_API_NET. Contains names of output layers.
  157. @return reference to this parameter structure.
  158. */
  159. Params<Net>& cfgOutputLayers(const typename PortCfg<Net>::Out &layer_names) {
  160. desc.output_names.clear();
  161. desc.output_names.reserve(layer_names.size());
  162. std::copy(layer_names.begin(), layer_names.end(),
  163. std::back_inserter(desc.output_names));
  164. return *this;
  165. }
  166. /** @brief Specifies a constant input.
  167. The function is used to set a constant input. This input has to be
  168. a preprocessed tensor if its type is TENSOR. Need to provide name of the
  169. network layer which will receive provided data.
  170. @param layer_name Name of network layer.
  171. @param data cv::Mat that contains data which will be associated with network layer.
  172. @param hint Input type @sa cv::gapi::ie::TraitAs.
  173. @return reference to this parameter structure.
  174. */
  175. Params<Net>& constInput(const std::string &layer_name,
  176. const cv::Mat &data,
  177. TraitAs hint = TraitAs::TENSOR) {
  178. desc.const_inputs[layer_name] = {data, hint};
  179. return *this;
  180. }
  181. /** @brief Specifies OpenVINO plugin configuration.
  182. The function is used to set configuration for OpenVINO plugin. Some parameters
  183. can be different for each plugin. Please follow https://docs.openvinotoolkit.org/latest/index.html
  184. to check information about specific plugin.
  185. @param cfg Map of pairs: (config parameter name, config parameter value).
  186. @return reference to this parameter structure.
  187. */
  188. Params& pluginConfig(const IEConfig& cfg) {
  189. desc.config = cfg;
  190. return *this;
  191. }
  192. /** @overload
  193. Function with a rvalue parameter.
  194. @param cfg rvalue map of pairs: (config parameter name, config parameter value).
  195. @return reference to this parameter structure.
  196. */
  197. Params& pluginConfig(IEConfig&& cfg) {
  198. desc.config = std::move(cfg);
  199. return *this;
  200. }
  201. /** @brief Specifies configuration for RemoteContext in InferenceEngine.
  202. When RemoteContext is configured the backend imports the networks using the context.
  203. It also expects cv::MediaFrames to be actually remote, to operate with blobs via the context.
  204. @param ctx_cfg cv::util::any value which holds InferenceEngine::ParamMap.
  205. @return reference to this parameter structure.
  206. */
  207. Params& cfgContextParams(const cv::util::any& ctx_cfg) {
  208. desc.context_config = ctx_cfg;
  209. return *this;
  210. }
  211. /** @overload
  212. Function with an rvalue parameter.
  213. @param ctx_cfg cv::util::any value which holds InferenceEngine::ParamMap.
  214. @return reference to this parameter structure.
  215. */
  216. Params& cfgContextParams(cv::util::any&& ctx_cfg) {
  217. desc.context_config = std::move(ctx_cfg);
  218. return *this;
  219. }
  220. /** @brief Specifies number of asynchronous inference requests.
  221. @param nireq Number of inference asynchronous requests.
  222. @return reference to this parameter structure.
  223. */
  224. Params& cfgNumRequests(size_t nireq) {
  225. GAPI_Assert(nireq > 0 && "Number of infer requests must be greater than zero!");
  226. desc.nireq = nireq;
  227. return *this;
  228. }
  229. /** @brief Specifies new input shapes for the network inputs.
  230. The function is used to specify new input shapes for the network inputs.
  231. Follow https://docs.openvinotoolkit.org/latest/classInferenceEngine_1_1networkNetwork.html
  232. for additional information.
  233. @param reshape_table Map of pairs: name of corresponding data and its dimension.
  234. @return reference to this parameter structure.
  235. */
  236. Params<Net>& cfgInputReshape(const std::map<std::string, std::vector<std::size_t>>& reshape_table) {
  237. desc.reshape_table = reshape_table;
  238. return *this;
  239. }
  240. /** @overload */
  241. Params<Net>& cfgInputReshape(std::map<std::string, std::vector<std::size_t>>&& reshape_table) {
  242. desc.reshape_table = std::move(reshape_table);
  243. return *this;
  244. }
  245. /** @overload
  246. @param layer_name Name of layer.
  247. @param layer_dims New dimensions for this layer.
  248. @return reference to this parameter structure.
  249. */
  250. Params<Net>& cfgInputReshape(const std::string& layer_name, const std::vector<size_t>& layer_dims) {
  251. desc.reshape_table.emplace(layer_name, layer_dims);
  252. return *this;
  253. }
  254. /** @overload */
  255. Params<Net>& cfgInputReshape(std::string&& layer_name, std::vector<size_t>&& layer_dims) {
  256. desc.reshape_table.emplace(layer_name, layer_dims);
  257. return *this;
  258. }
  259. /** @overload
  260. @param layer_names set of names of network layers that will be used for network reshape.
  261. @return reference to this parameter structure.
  262. */
  263. Params<Net>& cfgInputReshape(const std::unordered_set<std::string>& layer_names) {
  264. desc.layer_names_to_reshape = layer_names;
  265. return *this;
  266. }
  267. /** @overload
  268. @param layer_names rvalue set of the selected layers will be reshaped automatically
  269. its input image size.
  270. @return reference to this parameter structure.
  271. */
  272. Params<Net>& cfgInputReshape(std::unordered_set<std::string>&& layer_names) {
  273. desc.layer_names_to_reshape = std::move(layer_names);
  274. return *this;
  275. }
  276. /** @brief Specifies the inference batch size.
  277. The function is used to specify inference batch size.
  278. Follow https://docs.openvinotoolkit.org/latest/classInferenceEngine_1_1CNNNetwork.html#a8e9d19270a48aab50cb5b1c43eecb8e9 for additional information
  279. @param size batch size which will be used.
  280. @return reference to this parameter structure.
  281. */
  282. Params<Net>& cfgBatchSize(const size_t size) {
  283. desc.batch_size = cv::util::make_optional(size);
  284. return *this;
  285. }
  286. Params<Net>& cfgPreprocessingParams(const cv::gapi::wip::onevpl::Device &device,
  287. const cv::gapi::wip::onevpl::Context &ctx) {
  288. desc.vpl_preproc_device = cv::util::make_optional(device);
  289. desc.vpl_preproc_ctx = cv::util::make_optional(ctx);
  290. return *this;
  291. }
  292. // BEGIN(G-API's network parametrization API)
  293. GBackend backend() const { return cv::gapi::ie::backend(); }
  294. std::string tag() const { return Net::tag(); }
  295. cv::util::any params() const { return { desc }; }
  296. // END(G-API's network parametrization API)
  297. protected:
  298. detail::ParamDesc desc;
  299. };
  300. /*
  301. * @brief This structure provides functions for generic network type that
  302. * fill inference parameters.
  303. * @see struct Generic
  304. */
  305. template<>
  306. class Params<cv::gapi::Generic> {
  307. public:
  308. /** @brief Class constructor.
  309. Constructs Params based on model information and sets default values for other
  310. inference description parameters. Model is loaded and compiled using OpenVINO Toolkit.
  311. @param tag string tag of the network for which these parameters are intended.
  312. @param model path to topology IR (.xml file).
  313. @param weights path to weights (.bin file).
  314. @param device target device to use.
  315. */
  316. Params(const std::string &tag,
  317. const std::string &model,
  318. const std::string &weights,
  319. const std::string &device)
  320. : desc{ model, weights, device, {}, {}, {}, 0u, 0u,
  321. detail::ParamDesc::Kind::Load, true, {}, {}, {}, 1u,
  322. {}, {}, {}, {}},
  323. m_tag(tag) {
  324. };
  325. /** @overload
  326. This constructor for pre-compiled networks. Model is imported from pre-compiled
  327. blob.
  328. @param tag string tag of the network for which these parameters are intended.
  329. @param model path to model.
  330. @param device target device to use.
  331. */
  332. Params(const std::string &tag,
  333. const std::string &model,
  334. const std::string &device)
  335. : desc{ model, {}, device, {}, {}, {}, 0u, 0u,
  336. detail::ParamDesc::Kind::Import, true, {}, {}, {}, 1u,
  337. {}, {}, {}, {}},
  338. m_tag(tag) {
  339. };
  340. /** @see ie::Params::pluginConfig. */
  341. Params& pluginConfig(const IEConfig& cfg) {
  342. desc.config = cfg;
  343. return *this;
  344. }
  345. /** @overload */
  346. Params& pluginConfig(IEConfig&& cfg) {
  347. desc.config = std::move(cfg);
  348. return *this;
  349. }
  350. /** @see ie::Params::constInput. */
  351. Params& constInput(const std::string &layer_name,
  352. const cv::Mat &data,
  353. TraitAs hint = TraitAs::TENSOR) {
  354. desc.const_inputs[layer_name] = {data, hint};
  355. return *this;
  356. }
  357. /** @see ie::Params::cfgNumRequests. */
  358. Params& cfgNumRequests(size_t nireq) {
  359. GAPI_Assert(nireq > 0 && "Number of infer requests must be greater than zero!");
  360. desc.nireq = nireq;
  361. return *this;
  362. }
  363. /** @see ie::Params::cfgInputReshape */
  364. Params& cfgInputReshape(const std::map<std::string, std::vector<std::size_t>>&reshape_table) {
  365. desc.reshape_table = reshape_table;
  366. return *this;
  367. }
  368. /** @overload */
  369. Params& cfgInputReshape(std::map<std::string, std::vector<std::size_t>> && reshape_table) {
  370. desc.reshape_table = std::move(reshape_table);
  371. return *this;
  372. }
  373. /** @overload */
  374. Params& cfgInputReshape(std::string && layer_name, std::vector<size_t> && layer_dims) {
  375. desc.reshape_table.emplace(layer_name, layer_dims);
  376. return *this;
  377. }
  378. /** @overload */
  379. Params& cfgInputReshape(const std::string & layer_name, const std::vector<size_t>&layer_dims) {
  380. desc.reshape_table.emplace(layer_name, layer_dims);
  381. return *this;
  382. }
  383. /** @overload */
  384. Params& cfgInputReshape(std::unordered_set<std::string> && layer_names) {
  385. desc.layer_names_to_reshape = std::move(layer_names);
  386. return *this;
  387. }
  388. /** @overload */
  389. Params& cfgInputReshape(const std::unordered_set<std::string>&layer_names) {
  390. desc.layer_names_to_reshape = layer_names;
  391. return *this;
  392. }
  393. /** @see ie::Params::cfgBatchSize */
  394. Params& cfgBatchSize(const size_t size) {
  395. desc.batch_size = cv::util::make_optional(size);
  396. return *this;
  397. }
  398. // BEGIN(G-API's network parametrization API)
  399. GBackend backend() const { return cv::gapi::ie::backend(); }
  400. std::string tag() const { return m_tag; }
  401. cv::util::any params() const { return { desc }; }
  402. // END(G-API's network parametrization API)
  403. protected:
  404. detail::ParamDesc desc;
  405. std::string m_tag;
  406. };
  407. } // namespace ie
  408. } // namespace gapi
  409. } // namespace cv
  410. #endif // OPENCV_GAPI_INFER_IE_HPP