From 8cb25fdb989ef94eb8a0f8c905cddee310d0a166 Mon Sep 17 00:00:00 2001 From: Anastasia Kuporosova Date: Mon, 1 Feb 2021 09:12:32 +0300 Subject: [PATCH] [Python API] Support of FP16 blobs (#3893) * [Python API] Support of FP16 blobs * test_Blob refactoring * support fp16 for exec_net.infer method * add precisions Co-authored-by: anastasia.kuporosova --- .../openvino/inference_engine/constants.pyx | 5 +- .../src/openvino/inference_engine/ie_api.pyx | 8 ++- .../ie_bridges/python/tests/test_Blob.py | 69 ++++--------------- 3 files changed, 24 insertions(+), 58 deletions(-) diff --git a/inference-engine/ie_bridges/python/src/openvino/inference_engine/constants.pyx b/inference-engine/ie_bridges/python/src/openvino/inference_engine/constants.pyx index 188d38940bd422..ce5ca4d6dede81 100644 --- a/inference-engine/ie_bridges/python/src/openvino/inference_engine/constants.pyx +++ b/inference-engine/ie_bridges/python/src/openvino/inference_engine/constants.pyx @@ -18,7 +18,7 @@ from .cimport ie_api_impl_defs as C import numpy as np from enum import Enum -supported_precisions = ["FP32", "FP64", "FP16", "I64", "U64", "I32", "U32", "I16", "I8", "U16", "U8"] +supported_precisions = ["FP32", "FP64", "FP16", "I64", "U64", "I32", "U32", "I16", "I8", "U16", "U8", "BOOL"] known_plugins = ['CPU', 'GPU', 'FPGA', 'MYRIAD', 'HETERO', 'HDDL', 'MULTI'] @@ -34,7 +34,8 @@ format_map = { 'U16' : np.uint16, 'I8' : np.int8, 'U8' : np.uint8, - 'I64' : np.int64 + 'I64' : np.int64, + 'BOOL' : np.uint8 } layout_str_to_enum = {'ANY': C.Layout.ANY, diff --git a/inference-engine/ie_bridges/python/src/openvino/inference_engine/ie_api.pyx b/inference-engine/ie_bridges/python/src/openvino/inference_engine/ie_api.pyx index 3a84f61cfa9dcc..c92040d40cf76a 100644 --- a/inference-engine/ie_bridges/python/src/openvino/inference_engine/ie_api.pyx +++ b/inference-engine/ie_bridges/python/src/openvino/inference_engine/ie_api.pyx @@ -173,7 +173,8 @@ cdef class Blob: fp64_array_memview = self._array_data self._ptr = C.make_shared_blob[double](c_tensor_desc, &fp64_array_memview[0], fp64_array_memview.shape[0]) elif precision == "FP16": - raise RuntimeError("Currently, it's impossible to set_blob with FP16 precision") + I16_array_memview = self._array_data.view(dtype=np.int16) + self._ptr = C.make_shared_blob[int16_t](c_tensor_desc, &I16_array_memview[0], I16_array_memview.shape[0]) elif precision == "I16": I16_array_memview = self._array_data self._ptr = C.make_shared_blob[int16_t](c_tensor_desc, &I16_array_memview[0], I16_array_memview.shape[0]) @@ -1222,7 +1223,10 @@ cdef class InferRequest: def _fill_inputs(self, inputs): for k, v in inputs.items(): assert k in self._inputs_list, f"No input with name {k} found in network" - self.input_blobs[k].buffer[:] = v + if self.input_blobs[k].tensor_desc.precision == "FP16": + self.input_blobs[k].buffer[:] = v.view(dtype=np.int16) + else: + self.input_blobs[k].buffer[:] = v ## This class contains the information about the network model read from IR and allows you to manipulate with diff --git a/inference-engine/ie_bridges/python/tests/test_Blob.py b/inference-engine/ie_bridges/python/tests/test_Blob.py index 7220f87cbd8adf..2353e60c61c293 100644 --- a/inference-engine/ie_bridges/python/tests/test_Blob.py +++ b/inference-engine/ie_bridges/python/tests/test_Blob.py @@ -36,87 +36,48 @@ def test_get_buffer(): blob = Blob(tensor_desc, array) assert np.array_equal(blob.buffer, array) - -def test_write_to_buffer_fp32(): - tensor_desc = TensorDesc("FP32", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.float32) +def write_to_buffer(precision, numpy_precision): + tensor_desc = TensorDesc(precision, [1, 3, 127, 127], "NCHW") + array = np.zeros(shape=(1, 3, 127, 127), dtype=numpy_precision) blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.float32) + ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=numpy_precision) blob.buffer[:] = ones_arr assert np.array_equal(blob.buffer, ones_arr) +def test_write_to_buffer_fp32(): + write_to_buffer("FP32", np.float32) + def test_write_to_buffer_fp64(): - tensor_desc = TensorDesc("FP64", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.float64) - blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.float64) - blob.buffer[:] = ones_arr - assert np.array_equal(blob.buffer, ones_arr) + write_to_buffer("FP64", np.float64) -@pytest.mark.skip(reason="Need to figure out how to implement right conversion") def test_write_to_buffer_fp16(): - tensor_desc = TensorDesc("FP16", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.float16) - blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.float16) - blob.buffer[:] = ones_arr - assert np.array_equal(blob.buffer, ones_arr) + write_to_buffer("FP16", np.float16) def test_write_to_buffer_int8(): - tensor_desc = TensorDesc("I8", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.int8) - blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.int8) - blob.buffer[:] = ones_arr - assert np.array_equal(blob.buffer, ones_arr) + write_to_buffer("I8", np.int8) def test_write_to_buffer_uint8(): - tensor_desc = TensorDesc("U8", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.uint8) - blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.uint8) - blob.buffer[:] = ones_arr - assert np.array_equal(blob.buffer, ones_arr) + write_to_buffer("U8", np.uint8) def test_write_to_buffer_int32(): - tensor_desc = TensorDesc("I32", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.int32) - blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.int32) - blob.buffer[:] = ones_arr - assert np.array_equal(blob.buffer, ones_arr) + write_to_buffer("I32", np.int32) def test_write_to_buffer_int16(): - tensor_desc = TensorDesc("I16", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.int16) - blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.int16) - blob.buffer[:] = ones_arr - assert np.array_equal(blob.buffer, ones_arr) + write_to_buffer("I16", np.int16) def test_write_to_buffer_uint16(): - tensor_desc = TensorDesc("U16", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.uint16) - blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.uint16) - blob.buffer[:] = ones_arr - assert np.array_equal(blob.buffer, ones_arr) + write_to_buffer("U16", np.uint16) def test_write_to_buffer_int64(): - tensor_desc = TensorDesc("I64", [1, 3, 127, 127], "NCHW") - array = np.zeros(shape=(1, 3, 127, 127), dtype=np.int64) - blob = Blob(tensor_desc, array) - ones_arr = np.ones(shape=(1, 3, 127, 127), dtype=np.int64) - blob.buffer[:] = ones_arr - assert np.array_equal(blob.buffer, ones_arr) + write_to_buffer("I64", np.int64) def test_write_numpy_scalar_int64():