Added ie_core_read_network_from_memory to the C API ie_bridge. (#674)
authoremmanuelattia-philips <66060489+emmanuelattia-philips@users.noreply.github.com>
Sat, 30 May 2020 23:25:39 +0000 (01:25 +0200)
committerGitHub <noreply@github.com>
Sat, 30 May 2020 23:25:39 +0000 (02:25 +0300)
* * Added ie_core_read_network_from_memory to the C ie_bridge.

* Added size argument for xml_content, fixed const correctness of the weight_blob, fixed unit test

* * Removed debug message

* Changed variables names from model_xxx to weights_xxx to be more consistent with the argument name of the tested function.

* Added a description for xml_content_size in ie_core_read_network_from_memory.

* * xml_content is now passed as uint8_t
* reading function factorized in the unit-test

inference-engine/ie_bridges/c/include/c_api/ie_c_api.h
inference-engine/ie_bridges/c/src/ie_c_api.cpp
inference-engine/ie_bridges/c/tests/ie_c_api_test.cpp

index b5fef84..4299639 100644 (file)
@@ -372,6 +372,19 @@ INFERENCE_ENGINE_C_API(void) ie_core_versions_free(ie_core_versions_t *vers);
 INFERENCE_ENGINE_C_API(IE_NODISCARD IEStatusCode) ie_core_read_network(ie_core_t *core, const char *xml, const char *weights_file, ie_network_t **network);
 
 /**
+ * @brief Reads the model from an xml string and a blob of the bin part of the IR. Use the ie_network_free() method to free memory.
+ * @ingroup Core
+ * @param core A pointer to ie_core_t instance.
+ * @param xml_content Xml content of the IR.
+ * @param xml_content_size Number of bytes in the xml content of the IR.
+ * @param weight_blob Blob containing the bin part of the IR.
+ * @param network A pointer to the newly created network.
+ * @return Status code of the operation: OK(0) for success.
+ */
+INFERENCE_ENGINE_C_API(IE_NODISCARD IEStatusCode) ie_core_read_network_from_memory(ie_core_t *core, const uint8_t *xml_content, size_t xml_content_size,
+    const ie_blob_t *weight_blob, ie_network_t **network);
+
+/**
  * @brief Creates an executable network from a network object. Users can create as many networks as they need and use
  * them simultaneously (up to the limitation of the hardware resources). Use the ie_exec_network_free() method to free memory.
  * @ingroup Core
index fe31c56..d814c32 100644 (file)
@@ -310,6 +310,28 @@ IEStatusCode ie_core_read_network(ie_core_t *core, const char *xml, const char *
     return status;
 }
 
+IEStatusCode ie_core_read_network_from_memory(ie_core_t *core, const uint8_t *xml_content, size_t xml_content_size, \
+        const ie_blob_t *weight_blob, ie_network_t **network) {
+    if (core == nullptr || xml_content == nullptr || network == nullptr || weight_blob == nullptr) {
+        return IEStatusCode::GENERAL_ERROR;
+    }
+
+    IEStatusCode status = IEStatusCode::OK;
+
+    try {
+        std::unique_ptr<ie_network_t> network_result(new ie_network_t);
+        network_result->object = core->object.ReadNetwork(std::string(reinterpret_cast<const char *>(xml_content),
+            reinterpret_cast<const char *>(xml_content + xml_content_size)), weight_blob->object);
+        *network = network_result.release();
+    } catch (const IE::details::InferenceEngineException& e) {
+        return e.hasStatus() ? status_map[e.getStatus()] : IEStatusCode::UNEXPECTED;
+    } catch (...) {
+        return IEStatusCode::UNEXPECTED;
+    }
+
+    return status;
+}
+
 IEStatusCode ie_core_load_network(ie_core_t *core, const ie_network_t *network, const char *device_name, \
         const ie_config_t *config, ie_executable_network_t **exe_network) {
     IEStatusCode status = IEStatusCode::OK;
index 752b240..561ede3 100644 (file)
@@ -11,6 +11,7 @@
 #include <c_api/ie_c_api.h>
 #include <inference_engine.hpp>
 #include "test_model_repo.hpp"
+#include <fstream>
 
 std::string xml_std = TestDataHelpers::generate_model_path("test_model", "test_model_fp32.xml"),
             bin_std = TestDataHelpers::generate_model_path("test_model", "test_model_fp32.bin"),
@@ -281,6 +282,49 @@ TEST(ie_core_read_network, networkRead) {
     ie_core_free(&core);
 }
 
+static std::vector<uint8_t> content_from_file(const char * filename, bool is_binary) {
+    std::vector<uint8_t> result;
+    {
+        std::ifstream is(filename, is_binary ? std::ifstream::binary | std::ifstream::in : std::ifstream::in);
+        if (is) {
+            is.seekg(0, std::ifstream::end);
+            result.resize(is.tellg());
+            if (result.size() > 0) {
+                is.seekg(0, std::ifstream::beg);
+                is.read(reinterpret_cast<char *>(&result[0]), result.size());
+            }
+        }
+    }
+    return result;
+}
+
+TEST(ie_core_read_network_from_memory, networkReadFromMemory) {
+    ie_core_t *core = nullptr;
+    IE_ASSERT_OK(ie_core_create("", &core));
+    ASSERT_NE(nullptr, core);
+
+    std::vector<uint8_t> weights_content(content_from_file(bin, true));
+
+    tensor_desc_t weights_desc { ANY, { 1, { weights_content.size() } }, U8 };
+    ie_blob_t *weights_blob = nullptr;
+    IE_EXPECT_OK(ie_blob_make_memory_from_preallocated(&weights_desc, weights_content.data(), weights_content.size(), &weights_blob));
+    EXPECT_NE(nullptr, weights_blob);
+
+    if (weights_blob != nullptr) {
+        std::vector<uint8_t> xml_content(content_from_file(xml, false));
+        
+        ie_network_t *network = nullptr;
+        IE_EXPECT_OK(ie_core_read_network_from_memory(core, xml_content.data(), xml_content.size(), weights_blob, &network));
+        EXPECT_NE(nullptr, network);
+        if (network != nullptr) {
+            ie_network_free(&network);
+        }
+        ie_blob_free(&weights_blob);
+    }
+
+    ie_core_free(&core);
+}
+
 TEST(ie_core_load_network, loadNetwork) {
     ie_core_t *core = nullptr;
     IE_ASSERT_OK(ie_core_create("", &core));