ie_infer_request.hpp
Go to the documentation of this file.
1 // Copyright (C) 2018-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 /**
6  * @brief A header file that provides wrapper classes for infer requests and callbacks.
7  *
8  * @file ie_infer_request.hpp
9  */
10 #pragma once
11 
12 #include <map>
13 #include <memory>
14 #include <string>
15 
16 #include "cpp/ie_memory_state.hpp"
17 #include "ie_iinfer_request.hpp"
19 #include "details/ie_so_loader.h"
20 
21 namespace InferenceEngine {
22 
23 namespace details {
24 
25 class ICompletionCallbackWrapper {
26 public:
27  virtual ~ICompletionCallbackWrapper() = default;
28 
29  virtual void call(InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode code) const noexcept = 0;
30 };
31 
32 template <class T>
33 class CompletionCallbackWrapper : public ICompletionCallbackWrapper {
34  T lambda;
35 
36 public:
37  explicit CompletionCallbackWrapper(const T& lambda): lambda(lambda) {}
38 
39  void call(InferenceEngine::IInferRequest::Ptr /*request*/, InferenceEngine::StatusCode /*code*/) const
40  noexcept override {
41  lambda();
42  }
43 };
44 
45 template <>
46 class CompletionCallbackWrapper<IInferRequest::CompletionCallback> : public ICompletionCallbackWrapper {
48 
49 public:
50  explicit CompletionCallbackWrapper(const IInferRequest::CompletionCallback& callBack): callBack(callBack) {}
51 
52  void call(InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode code) const noexcept override {
53  callBack(request, code);
54  }
55 };
56 
57 } // namespace details
58 
59 /**
60  * @copybrief IInferRequest
61  *
62  * Wraps IInferRequest
63  * It can throw exceptions safely for the application, where it is properly handled.
64  */
65 class InferRequest {
66  IInferRequest::Ptr actual;
67  InferenceEngine::details::SharedObjectLoader::Ptr plg;
68  std::shared_ptr<details::ICompletionCallbackWrapper> callback;
69 
70  static void callWrapper(InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode code) {
71  details::ICompletionCallbackWrapper* pWrapper = nullptr;
72  ResponseDesc dsc;
73  request->GetUserData(reinterpret_cast<void**>(&pWrapper), &dsc);
74  pWrapper->call(request, code);
75  }
76 
77 public:
78  /**
79  * @brief Default constructor
80  */
81  InferRequest() = default;
82 
83  /**
84  * constructs InferRequest from the initialized shared_pointer
85  * @param request Initialized shared pointer to IInferRequest interface
86  * @param splg Plugin to use. This is required to ensure that InferRequest can work properly even if plugin object is destroyed.
87  */
88  explicit InferRequest(IInferRequest::Ptr request,
89  InferenceEngine::details::SharedObjectLoader::Ptr splg = {}):
90  actual(request), plg(splg) {
91  // plg can be null, but not the actual
92  if (actual == nullptr) THROW_IE_EXCEPTION << "InferRequest was not initialized.";
93  }
94 
95  /**
96  * @brief Destructor
97  */
99  actual = nullptr;
100  }
101 
102  /**
103  * @brief Sets input/output data to infer
104  *
105  * @note Memory allocation does not happen
106  * @param name Name of input or output blob.
107  * @param data Reference to input or output blob. The type of a blob must match the network input precision and
108  * size.
109  */
110  void SetBlob(const std::string& name, const Blob::Ptr& data) {
111  CALL_STATUS_FNC(SetBlob, name.c_str(), data);
112  }
113 
114  /**
115  * @copybrief IInferRequest::GetBlob
116  *
117  * Wraps IInferRequest::GetBlob
118  * @param name A name of Blob to get
119  * @return A shared pointer to a Blob with a name @p name. If a blob is not found, an exception is thrown.
120  */
121  Blob::Ptr GetBlob(const std::string& name) {
122  Blob::Ptr data;
123  CALL_STATUS_FNC(GetBlob, name.c_str(), data);
124  std::string error = "Internal error: blob with name `" + name + "` is not allocated!";
125  auto blobPtr = data.get();
126  if (blobPtr == nullptr) THROW_IE_EXCEPTION << error;
127  if (blobPtr->buffer() == nullptr) THROW_IE_EXCEPTION << error;
128  return data;
129  }
130 
131  /**
132  * @brief Sets blob with a pre-process information
133  * @note Returns an error in case if data blob is output
134  * @param name Name of input blob.
135  * @param data A reference to input. The type of Blob must correspond to the network input precision and size.
136  * @param info Preprocess info for blob.
137  */
138  void SetBlob(const std::string &name, const Blob::Ptr &data, const PreProcessInfo& info) {
139  CALL_STATUS_FNC(SetBlob, name.c_str(), data, info);
140  }
141 
142  /**
143  * @brief Gets pre-process for input data
144  * @param name Name of input blob.
145  * @return pointer to pre-process info of blob with name
146  */
147  const PreProcessInfo& GetPreProcess(const std::string& name) const {
148  const PreProcessInfo* info = nullptr;
149  CALL_STATUS_FNC(GetPreProcess, name.c_str(), &info);
150  return *info;
151  }
152 
153  /**
154  * @copybrief IInferRequest::Infer
155  * @note blocks all methods of InferRequest while request is ongoing (running or waiting in queue)
156  *
157  * Wraps IInferRequest::Infer
158  */
159  void Infer() {
160  CALL_STATUS_FNC_NO_ARGS(Infer);
161  }
162 
163  /**
164  * @copybrief IInferRequest::GetPerformanceCounts
165  *
166  * Wraps IInferRequest::GetPerformanceCounts
167  * @return Map of layer names to profiling information for that layer
168  */
169  std::map<std::string, InferenceEngineProfileInfo> GetPerformanceCounts() const {
170  std::map<std::string, InferenceEngineProfileInfo> perfMap;
171  CALL_STATUS_FNC(GetPerformanceCounts, perfMap);
172  return perfMap;
173  }
174 
175  /**
176  * @brief Sets input data to infer
177  *
178  * @note Memory allocation doesn't happen
179  * @param inputs A reference to a map of input blobs accessed by input names.
180  * The type of Blob must correspond to the network input precision and size.
181  */
182  void SetInput(const BlobMap& inputs) {
183  for (auto&& input : inputs) {
184  CALL_STATUS_FNC(SetBlob, input.first.c_str(), input.second);
185  }
186  }
187 
188  /**
189  * @brief Sets data that will contain result of the inference
190  *
191  * @note Memory allocation doesn't happen
192  * @param results - a reference to a map of result blobs accessed by output names.
193  * The type of Blob must correspond to the network output precision and size.
194  */
195  void SetOutput(const BlobMap& results) {
196  for (auto&& result : results) {
197  CALL_STATUS_FNC(SetBlob, result.first.c_str(), result.second);
198  }
199  }
200 
201  /**
202  * @brief Sets new batch size when dynamic batching is enabled in executable network that created this request.
203  *
204  * @param batch new batch size to be used by all the following inference calls for this request.
205  */
206  void SetBatch(const int batch) {
207  CALL_STATUS_FNC(SetBatch, batch);
208  }
209 
210  /**
211  * @brief Start inference of specified input(s) in asynchronous mode
212  *
213  * @note It returns immediately. Inference starts also immediately.
214  */
215  void StartAsync() {
216  CALL_STATUS_FNC_NO_ARGS(StartAsync);
217  }
218 
219  /**
220  * @copybrief IInferRequest::Wait
221  *
222  * Wraps IInferRequest::Wait
223  * @param millis_timeout Maximum duration in milliseconds to block for
224  * @note There are special cases when millis_timeout is equal some value of the WaitMode enum:
225  * * STATUS_ONLY - immediately returns inference status (IInferRequest::RequestStatus). It does not block or
226  * interrupt current thread
227  * * RESULT_READY - waits until inference result becomes available
228  * @return A status code of operation
229  */
230  StatusCode Wait(int64_t millis_timeout) {
231  ResponseDesc resp;
232  if (actual == nullptr) THROW_IE_EXCEPTION << "InferRequest was not initialized.";
233  auto res = actual->Wait(millis_timeout, &resp);
234  if (res != OK && res != RESULT_NOT_READY && res != INFER_NOT_STARTED) {
235  InferenceEngine::details::extract_exception(res, resp.msg);
236  }
237  return res;
238  }
239 
240  /**
241  * @copybrief IInferRequest::SetCompletionCallback
242  *
243  * Wraps IInferRequest::SetCompletionCallback
244  *
245  * @param callbackToSet Lambda callback object which will be called on processing finish.
246  */
247  template <class T>
248  void SetCompletionCallback(const T& callbackToSet) {
249  callback.reset(new details::CompletionCallbackWrapper<T>(callbackToSet));
250  CALL_STATUS_FNC(SetUserData, callback.get());
251  actual->SetCompletionCallback(callWrapper);
252  }
253 
254  /**
255  * @copybrief IExecutableNetwork::QueryState
256  *
257  * Wraps IExecutableNetwork::QueryState
258  * @return A vector of Memory State objects
259  */
260  std::vector<VariableState> QueryState() {
261  if (actual == nullptr) THROW_IE_EXCEPTION << "ExecutableNetwork was not initialized.";
262  IVariableState::Ptr pState = nullptr;
263  auto res = OK;
264  std::vector<VariableState> controller;
265  for (size_t idx = 0; res == OK; ++idx) {
266  ResponseDesc resp;
267  res = actual->QueryState(pState, idx, &resp);
268  if (res != OK && res != OUT_OF_BOUNDS) {
269  THROW_IE_EXCEPTION << resp.msg;
270  }
271  if (res != OUT_OF_BOUNDS) {
272  controller.push_back(VariableState(pState, plg));
273  }
274  }
275 
276  return controller;
277  }
278 
279  /**
280  * @brief IInferRequest pointer to be used directly in CreateInferRequest functions
281  * @return A shared pointer to underlying IInferRequest interface
282  */
283  operator IInferRequest::Ptr&() {
284  if (actual == nullptr) THROW_IE_EXCEPTION << "InferRequest was not initialized.";
285  return actual;
286  }
287 
288  /**
289  * @brief Checks if current InferRequest object is not initialized
290  * @return true if current InferRequest object is not initialized, false - otherwise
291  */
292  bool operator!() const noexcept {
293  return !actual;
294  }
295 
296  /**
297  * @brief Checks if current InferRequest object is initialized
298  * @return true if current InferRequest object is initialized, false - otherwise
299  */
300  explicit operator bool() const noexcept {
301  return !!actual;
302  }
303 
304  /**
305  * @brief A smart pointer to the InferRequest object
306  */
307  using Ptr = std::shared_ptr<InferRequest>;
308 };
309 
310 namespace details {
311 
312 template <>
313 class CompletionCallbackWrapper<std::function<void(InferRequest, StatusCode)>> : public ICompletionCallbackWrapper {
314  std::function<void(InferRequest, StatusCode)> lambda;
315 
316 public:
317  explicit CompletionCallbackWrapper(const std::function<void(InferRequest, InferenceEngine::StatusCode)>& lambda)
318  : lambda(lambda) {}
319 
320  void call(InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode code) const noexcept override {
321  lambda(InferRequest(request), code);
322  }
323 };
324 
325 } // namespace details
326 } // namespace InferenceEngine
std::shared_ptr< Blob > Ptr
A smart pointer containing Blob object.
Definition: ie_blob.h:43
void(* CompletionCallback)(InferenceEngine::IInferRequest::Ptr context, InferenceEngine::StatusCode code)
Completion callback definition as pointer to a function.
Definition: ie_iinfer_request.hpp:142
std::shared_ptr< IInferRequest > Ptr
A shared pointer to the IInferRequest object.
Definition: ie_iinfer_request.hpp:44
std::shared_ptr< IVariableState > Ptr
A shared pointer to the IVariableState interface.
Definition: ie_imemory_state.hpp:30
This is an interface of asynchronous infer request.
Definition: ie_infer_request.hpp:65
InferRequest(IInferRequest::Ptr request, InferenceEngine::details::SharedObjectLoader::Ptr splg={})
Definition: ie_infer_request.hpp:88
std::vector< VariableState > QueryState()
Gets state control interface for given executable network.
Definition: ie_infer_request.hpp:260
std::map< std::string, InferenceEngineProfileInfo > GetPerformanceCounts() const
Queries performance measures per layer to get feedback of what is the most time consuming layer.
Definition: ie_infer_request.hpp:169
void SetInput(const BlobMap &inputs)
Sets input data to infer.
Definition: ie_infer_request.hpp:182
void SetBlob(const std::string &name, const Blob::Ptr &data, const PreProcessInfo &info)
Sets blob with a pre-process information.
Definition: ie_infer_request.hpp:138
void SetBlob(const std::string &name, const Blob::Ptr &data)
Sets input/output data to infer.
Definition: ie_infer_request.hpp:110
void SetBatch(const int batch)
Sets new batch size when dynamic batching is enabled in executable network that created this request.
Definition: ie_infer_request.hpp:206
void Infer()
Infers specified input(s) in synchronous mode.
Definition: ie_infer_request.hpp:159
const PreProcessInfo & GetPreProcess(const std::string &name) const
Gets pre-process for input data.
Definition: ie_infer_request.hpp:147
void StartAsync()
Start inference of specified input(s) in asynchronous mode.
Definition: ie_infer_request.hpp:215
InferRequest()=default
Default constructor.
void SetCompletionCallback(const T &callbackToSet)
Sets a callback function that will be called on success or failure of asynchronous request.
Definition: ie_infer_request.hpp:248
bool operator!() const noexcept
Checks if current InferRequest object is not initialized.
Definition: ie_infer_request.hpp:292
void SetOutput(const BlobMap &results)
Sets data that will contain result of the inference.
Definition: ie_infer_request.hpp:195
Blob::Ptr GetBlob(const std::string &name)
Gets input/output data for inference.
Definition: ie_infer_request.hpp:121
std::shared_ptr< InferRequest > Ptr
A smart pointer to the InferRequest object.
Definition: ie_infer_request.hpp:307
StatusCode Wait(int64_t millis_timeout)
Waits for the result to become available. Blocks until specified millis_timeout has elapsed or the re...
Definition: ie_infer_request.hpp:230
~InferRequest()
Destructor.
Definition: ie_infer_request.hpp:98
This class stores pre-process information for the input.
Definition: ie_preprocess.hpp:55
C++ exception based error reporting wrapper of API class IVariableState.
Definition: ie_memory_state.hpp:24
std::map< std::string, Blob::Ptr > BlobMap
This is a convenient type for working with a map containing pairs(string, pointer to a Blob instance)...
Definition: ie_blob.h:486
StatusCode
This enum contains codes for all possible return values of the interface functions.
Definition: ie_common.h:222
#define THROW_IE_EXCEPTION
A macro used to throw the exception with a notable description.
Definition: ie_exception.hpp:25
A header file that provides macros to handle no exception methods.
a header file for IInferRequest interface
A header file that provides wrapper classes for IVariableState.
A header file for definition of abstraction over platform specific shared objects.
Represents detailed information for an error.
Definition: ie_common.h:245
char msg[4096]
A character buffer that holds the detailed information for an error.
Definition: ie_common.h:249