Low precision types support in Convert operation (#5640)
* Add initial version of u1 type support. * Turn off u8_to_u1 test in IE.CPU. * Fix compilation issue. * Replace std::memset with std::fill. * Add u4 type support. * Add i4 support. * LP types support generalized. * Remove std::copy optimization. * Fix backend test for LP types. * Fixed arm plugin compilation. * Add LP types to Serialization SLT. * Add Convert to summarize.py report.
This commit is contained in:
1 parent
5ea8437c91
commit
9e46be75af
6 files changed
+336
-63
No files matched your search
+8
-7
@@ -12,13 +12,14 @@ namespace {
|
||||
const std::vector<std::vector<size_t>> inShape = {{1, 2, 3, 4}};
|
||||
|
||||
const std::vector<InferenceEngine::Precision> precisions = {
|
||||
InferenceEngine::Precision::BOOL, InferenceEngine::Precision::U8,
|
||||
InferenceEngine::Precision::I8, InferenceEngine::Precision::U16,
|
||||
InferenceEngine::Precision::I16, InferenceEngine::Precision::U32,
|
||||
InferenceEngine::Precision::I32, InferenceEngine::Precision::U64,
|
||||
InferenceEngine::Precision::I64, InferenceEngine::Precision::BF16,
|
||||
InferenceEngine::Precision::FP16, InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::FP64};
|
||||
InferenceEngine::Precision::BOOL, InferenceEngine::Precision::BIN,
|
||||
InferenceEngine::Precision::U4, InferenceEngine::Precision::U8,
|
||||
InferenceEngine::Precision::I4, InferenceEngine::Precision::I8,
|
||||
InferenceEngine::Precision::U16, InferenceEngine::Precision::I16,
|
||||
InferenceEngine::Precision::U32, InferenceEngine::Precision::I32,
|
||||
InferenceEngine::Precision::U64, InferenceEngine::Precision::I64,
|
||||
InferenceEngine::Precision::BF16, InferenceEngine::Precision::FP16,
|
||||
InferenceEngine::Precision::FP32, InferenceEngine::Precision::FP64};
|
||||
|
||||
TEST_P(ConvertLayerTest, Serialize) {
|
||||
Serialize();
|
||||
|
||||
+1
@@ -16,6 +16,7 @@ VERIFIED_OP_REFERENCES = [
|
||||
'CTCGreedyDecoder-1',
|
||||
'CTCGreedyDecoderSeqLen-6',
|
||||
'Concat-1',
|
||||
'Convert-1',
|
||||
'ConvertLike-1',
|
||||
'Convolution-1',
|
||||
'Constant-1',
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
#include "ngraph/type/float16.hpp"
|
||||
|
||||
namespace ngraph
|
||||
@@ -14,6 +15,118 @@ namespace ngraph
|
||||
{
|
||||
namespace reference
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline void set_u1(uint8_t* buf, size_t idx, uint8_t val)
|
||||
{
|
||||
const int byte_idx = idx / 8;
|
||||
const int bit_idx = 7 - (idx % 8);
|
||||
if (val)
|
||||
{
|
||||
buf[byte_idx] |= (1 << bit_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[byte_idx] &= ~(1 << bit_idx);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8_t get_u1(const uint8_t* buf, size_t idx)
|
||||
{
|
||||
const int byte_idx = idx / 8;
|
||||
const int bit_idx = 7 - (idx % 8);
|
||||
return (buf[byte_idx] & (1 << bit_idx)) ? 1 : 0;
|
||||
}
|
||||
|
||||
inline void set_u4(uint8_t* buf, size_t idx, uint8_t val)
|
||||
{
|
||||
const int byte_idx = idx / 2;
|
||||
const int bit_shift = 4 * (++idx % 2);
|
||||
buf[byte_idx] &= ~(0xF << bit_shift); // half byte zeroed
|
||||
buf[byte_idx] |= (val << bit_shift); // set 1's
|
||||
}
|
||||
|
||||
inline uint8_t get_u4(const uint8_t* buf, size_t idx)
|
||||
{
|
||||
const int byte_idx = idx / 2;
|
||||
const int bit_shift = 4 * (++idx % 2);
|
||||
return (buf[byte_idx] >> bit_shift) & 0xF;
|
||||
}
|
||||
|
||||
inline void set_i4(uint8_t* buf, size_t idx, int8_t val)
|
||||
{
|
||||
const int byte_idx = idx / 2;
|
||||
const int bit_shift = 4 * (++idx % 2);
|
||||
buf[byte_idx] &= ~(0xF << bit_shift); // half byte zeroed
|
||||
buf[byte_idx] |= (val << bit_shift); // set 1's
|
||||
}
|
||||
|
||||
inline int8_t get_i4(const uint8_t* buf, size_t idx)
|
||||
{
|
||||
const int byte_idx = idx / 2;
|
||||
const int bit_shift = 4 * (++idx % 2);
|
||||
uint8_t val = (buf[byte_idx] >> bit_shift) & 0xF;
|
||||
if (val & 0x08)
|
||||
{ // negative number
|
||||
val |= 0xF0;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
template <typename T>
|
||||
T get_value(const uint8_t* buf, size_t idx, element::Type type)
|
||||
{
|
||||
if (type == element::u1)
|
||||
{
|
||||
return detail::get_u1(buf, idx);
|
||||
}
|
||||
|
||||
if (type == element::u4)
|
||||
{
|
||||
return detail::get_u4(buf, idx);
|
||||
}
|
||||
|
||||
if (type == element::i4)
|
||||
{
|
||||
return detail::get_i4(buf, idx);
|
||||
}
|
||||
|
||||
return static_cast<T>(buf[idx]);
|
||||
}
|
||||
|
||||
template <typename TI, typename TO>
|
||||
void lp_convert(const TI* arg,
|
||||
TO* out,
|
||||
size_t count,
|
||||
element::Type_t src_type,
|
||||
element::Type_t dst_type)
|
||||
{
|
||||
const uint8_t* input = reinterpret_cast<const uint8_t*>(arg);
|
||||
uint8_t* output = reinterpret_cast<uint8_t*>(out);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (dst_type == element::u1)
|
||||
{
|
||||
detail::set_u1(
|
||||
output, i, detail::get_value<uint8_t>(input, i, src_type));
|
||||
}
|
||||
else if (dst_type == element::u4)
|
||||
{
|
||||
detail::set_u4(
|
||||
output, i, detail::get_value<uint8_t>(input, i, src_type));
|
||||
}
|
||||
else if (dst_type == element::i4)
|
||||
{
|
||||
detail::set_i4(
|
||||
output, i, detail::get_value<int8_t>(input, i, src_type));
|
||||
}
|
||||
else
|
||||
{
|
||||
out[i] = detail::get_value<TO>(input, i, src_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename TI, typename TO>
|
||||
typename std::enable_if<!std::is_same<TO, char>::value>::type
|
||||
convert(const TI* arg, TO* out, size_t count)
|
||||
|
||||
@@ -26,22 +26,6 @@ op::Convert::Convert(const Output<Node>& arg, const element::Type& destination_t
|
||||
void op::Convert::validate_and_infer_types()
|
||||
{
|
||||
NGRAPH_OP_SCOPE(v0_Convert_validate_and_infer_types);
|
||||
const element::Type data_et = get_input_element_type(0);
|
||||
const element::Type destination_et = m_destination_type;
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
data_et != element::u1 && data_et != element::u4 &&
|
||||
data_et != element::i4,
|
||||
"Input element type '",
|
||||
data_et,
|
||||
"' is not supported.");
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
destination_et != element::u1 && destination_et != element::u4 &&
|
||||
destination_et != element::i4,
|
||||
"Destination element type '",
|
||||
destination_et,
|
||||
"' is not supported.");
|
||||
|
||||
set_output_type(0, m_destination_type, get_input_partial_shape(0));
|
||||
}
|
||||
@@ -68,10 +52,27 @@ namespace convert
|
||||
{
|
||||
out->set_shape(arg->get_shape());
|
||||
size_t element_count = shape_size(out->get_shape());
|
||||
return (INPUT_ET == arg->get_element_type()) && OUTPUT_ET == out->get_element_type() &&
|
||||
(runtime::reference::convert(
|
||||
arg->get_data_ptr<INPUT_ET>(), out->get_data_ptr<OUTPUT_ET>(), element_count),
|
||||
true);
|
||||
|
||||
if ((INPUT_ET != arg->get_element_type()) || OUTPUT_ET != out->get_element_type())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (((INPUT_ET == element::u1) || (OUTPUT_ET == element::u1)) ||
|
||||
((INPUT_ET == element::u4) || (OUTPUT_ET == element::u4)) ||
|
||||
((INPUT_ET == element::i4) || (OUTPUT_ET == element::i4)))
|
||||
{
|
||||
runtime::reference::detail::lp_convert(arg->get_data_ptr<INPUT_ET>(),
|
||||
out->get_data_ptr<OUTPUT_ET>(),
|
||||
element_count,
|
||||
INPUT_ET,
|
||||
OUTPUT_ET);
|
||||
}
|
||||
else
|
||||
{
|
||||
runtime::reference::convert(
|
||||
arg->get_data_ptr<INPUT_ET>(), out->get_data_ptr<OUTPUT_ET>(), element_count);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TYPE_OUT_CASE(a, ...) \
|
||||
@@ -89,10 +90,13 @@ namespace convert
|
||||
|
||||
switch (out->get_element_type())
|
||||
{
|
||||
TYPE_OUT_CASE(i4, arg, out);
|
||||
TYPE_OUT_CASE(i8, arg, out);
|
||||
TYPE_OUT_CASE(i16, arg, out);
|
||||
TYPE_OUT_CASE(i32, arg, out);
|
||||
TYPE_OUT_CASE(i64, arg, out);
|
||||
TYPE_OUT_CASE(u1, arg, out);
|
||||
TYPE_OUT_CASE(u4, arg, out);
|
||||
TYPE_OUT_CASE(u8, arg, out);
|
||||
TYPE_OUT_CASE(u16, arg, out);
|
||||
TYPE_OUT_CASE(u32, arg, out);
|
||||
@@ -112,7 +116,10 @@ namespace convert
|
||||
bool rc = true;
|
||||
switch (arg->get_element_type())
|
||||
{
|
||||
NGRAPH_TYPE_CASE(evaluate_convert, u1, arg, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_convert, u4, arg, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_convert, u8, arg, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_convert, i4, arg, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_convert, i8, arg, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_convert, i32, arg, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_convert, i16, arg, out);
|
||||
|
||||
@@ -23,6 +23,15 @@ static string s_manifest = "${MANIFEST}";
|
||||
using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
|
||||
namespace
|
||||
{
|
||||
std::shared_ptr<Function> CreateFunction(const Shape& input_shape,
|
||||
const element::Type& input_type,
|
||||
const element::Type& expected_output_type)
|
||||
{
|
||||
const auto in = make_shared<op::Parameter>(input_type, input_shape);
|
||||
const auto convert = make_shared<op::Convert>(in, expected_output_type);
|
||||
return make_shared<Function>(NodeVector{convert}, ParameterVector{in});
|
||||
}
|
||||
|
||||
template <typename T_IN, typename T_OUT>
|
||||
void ConvertTest(const std::vector<T_IN>& input,
|
||||
const Shape& input_shape,
|
||||
@@ -30,16 +39,34 @@ namespace
|
||||
const std::vector<T_OUT>& expected_output,
|
||||
const ngraph::element::Type& expected_output_type)
|
||||
{
|
||||
const auto in = make_shared<op::Parameter>(input_type, input_shape);
|
||||
const auto convert = make_shared<op::Convert>(in, expected_output_type);
|
||||
const auto f = make_shared<Function>(NodeVector{convert}, ParameterVector{in});
|
||||
|
||||
const auto f = CreateFunction(input_shape, input_type, expected_output_type);
|
||||
auto test_case = test::TestCase<TestEngine>(f);
|
||||
test_case.add_input(input);
|
||||
test_case.add_expected_output(expected_output);
|
||||
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
// TestCase doesn't support LP types
|
||||
template <typename T_IN, typename T_OUT>
|
||||
void LPConvertTest(const std::vector<T_IN>& input,
|
||||
const Shape& input_shape,
|
||||
const ngraph::element::Type& input_type,
|
||||
const std::vector<T_OUT>& expected_output,
|
||||
const ngraph::element::Type& expected_output_type)
|
||||
{
|
||||
const auto f = CreateFunction(input_shape, input_type, expected_output_type);
|
||||
auto backend = runtime::Backend::create("${BACKEND_NAME}");
|
||||
auto input_tesnor = backend->create_tensor(input_type, input_shape);
|
||||
copy_data(input_tesnor, input);
|
||||
auto output = backend->create_tensor(expected_output_type, input_shape);
|
||||
auto handle = backend->compile(f);
|
||||
handle->call_with_validate({output}, {input_tesnor});
|
||||
|
||||
std::vector<uint8_t> result(expected_output.size());
|
||||
output->read(result.data(), result.size() * sizeof(uint8_t));
|
||||
EXPECT_TRUE(test::all_close(expected_output, result));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// destination: boolean
|
||||
@@ -119,17 +146,28 @@ NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_f16)
|
||||
}
|
||||
|
||||
// destination: f32
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_i4_to_f32_is_not_supported_yet)
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_i4_to_f32)
|
||||
{
|
||||
const std::vector<int8_t> input{0x00, 0x00};
|
||||
const std::vector<uint8_t> input{0xFE, 0xF2};
|
||||
const Shape input_shape{2, 2};
|
||||
const element::Type input_type = ngraph::element::i4;
|
||||
|
||||
const std::vector<float> expected_output{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
const std::vector<float> expected_output{-1.0f, -2.0f, -1.0f, 2.0f};
|
||||
const element::Type expected_output_type = ngraph::element::f32;
|
||||
|
||||
ASSERT_THROW(ConvertTest(input, input_shape, input_type, expected_output, expected_output_type),
|
||||
ngraph::NodeValidationFailure);
|
||||
{
|
||||
const auto f = CreateFunction(input_shape, input_type, expected_output_type);
|
||||
auto backend = runtime::Backend::create("${BACKEND_NAME}");
|
||||
auto input_tesnor = backend->create_tensor(input_type, input_shape);
|
||||
copy_data(input_tesnor, input);
|
||||
auto output = backend->create_tensor(expected_output_type, input_shape);
|
||||
auto handle = backend->compile(f);
|
||||
handle->call_with_validate({output}, {input_tesnor});
|
||||
|
||||
std::vector<float> result(expected_output.size());
|
||||
output->read(result.data(), result.size() * sizeof(float));
|
||||
EXPECT_TRUE(test::all_close_f(expected_output, result));
|
||||
}
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_i8_to_f32)
|
||||
@@ -180,30 +218,52 @@ NGRAPH_TEST(${BACKEND_NAME}, convert_i64_to_f32)
|
||||
ConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u1_to_f32_is_not_supported_yet)
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u1_to_f32)
|
||||
{
|
||||
const std::vector<uint8_t> input{0x00};
|
||||
const std::vector<uint8_t> input{0xA0};
|
||||
const Shape input_shape{2, 2};
|
||||
const element::Type input_type = ngraph::element::u1;
|
||||
|
||||
const std::vector<float> expected_output{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
const std::vector<float> expected_output{1.0f, 0.0f, 1.0f, 0.0f};
|
||||
const element::Type expected_output_type = ngraph::element::f32;
|
||||
|
||||
ASSERT_THROW(ConvertTest(input, input_shape, input_type, expected_output, expected_output_type),
|
||||
ngraph::NodeValidationFailure);
|
||||
{
|
||||
const auto f = CreateFunction(input_shape, input_type, expected_output_type);
|
||||
auto backend = runtime::Backend::create("${BACKEND_NAME}");
|
||||
auto input_tesnor = backend->create_tensor(input_type, input_shape);
|
||||
copy_data(input_tesnor, input);
|
||||
auto output = backend->create_tensor(expected_output_type, input_shape);
|
||||
auto handle = backend->compile(f);
|
||||
handle->call_with_validate({output}, {input_tesnor});
|
||||
|
||||
std::vector<float> result(expected_output.size());
|
||||
output->read(result.data(), result.size() * sizeof(float));
|
||||
EXPECT_TRUE(test::all_close_f(expected_output, result));
|
||||
}
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u4_to_f32_is_not_supported_yet)
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u4_to_f32)
|
||||
{
|
||||
const std::vector<uint8_t> input{0x00, 0x00};
|
||||
const std::vector<uint8_t> input{0xFB, 0x0A};
|
||||
const Shape input_shape{2, 2};
|
||||
const element::Type input_type = ngraph::element::u4;
|
||||
|
||||
const std::vector<float> expected_output{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
const std::vector<float> expected_output{15.0f, 11.0f, 0.0f, 10.0f};
|
||||
const element::Type expected_output_type = ngraph::element::f32;
|
||||
|
||||
ASSERT_THROW(ConvertTest(input, input_shape, input_type, expected_output, expected_output_type),
|
||||
ngraph::NodeValidationFailure);
|
||||
{
|
||||
const auto f = CreateFunction(input_shape, input_type, expected_output_type);
|
||||
auto backend = runtime::Backend::create("${BACKEND_NAME}");
|
||||
auto input_tesnor = backend->create_tensor(input_type, input_shape);
|
||||
copy_data(input_tesnor, input);
|
||||
auto output = backend->create_tensor(expected_output_type, input_shape);
|
||||
auto handle = backend->compile(f);
|
||||
handle->call_with_validate({output}, {input_tesnor});
|
||||
|
||||
std::vector<float> result(expected_output.size());
|
||||
output->read(result.data(), result.size() * sizeof(float));
|
||||
EXPECT_TRUE(test::all_close_f(expected_output, result));
|
||||
}
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_f32)
|
||||
@@ -295,17 +355,28 @@ NGRAPH_TEST(${BACKEND_NAME}, convert_f32_to_f32)
|
||||
// not supported by IE, hence no tests
|
||||
|
||||
// destination: i4
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_i4_is_not_supported_yet)
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_i4)
|
||||
{
|
||||
const std::vector<uint8_t> input{0, 0, 0, 0};
|
||||
const std::vector<uint8_t> input{1, 2, 0, 3};
|
||||
const Shape input_shape{4};
|
||||
const element::Type input_type = ngraph::element::u8;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0x00, 0x00};
|
||||
const std::vector<uint8_t> expected_output{0x12, 0x03};
|
||||
const element::Type expected_output_type = ngraph::element::i4;
|
||||
|
||||
ASSERT_THROW(ConvertTest(input, input_shape, input_type, expected_output, expected_output_type),
|
||||
ngraph::NodeValidationFailure);
|
||||
{
|
||||
const auto f = CreateFunction(input_shape, input_type, expected_output_type);
|
||||
auto backend = runtime::Backend::create("${BACKEND_NAME}");
|
||||
auto input_tesnor = backend->create_tensor(input_type, input_shape);
|
||||
copy_data(input_tesnor, input);
|
||||
auto output = backend->create_tensor(expected_output_type, input_shape);
|
||||
auto handle = backend->compile(f);
|
||||
handle->call_with_validate({output}, {input_tesnor});
|
||||
|
||||
std::vector<uint8_t> result(expected_output.size());
|
||||
output->read(result.data(), result.size() * sizeof(uint8_t));
|
||||
EXPECT_TRUE(test::all_close(expected_output, result));
|
||||
}
|
||||
}
|
||||
|
||||
// destination: i8
|
||||
@@ -361,31 +432,102 @@ NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_i64)
|
||||
}
|
||||
|
||||
// destination: u1
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_u1_is_not_supported_yet)
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u1_to_u1)
|
||||
{
|
||||
const std::vector<uint8_t> input{0, 0, 0, 0};
|
||||
const Shape input_shape{4};
|
||||
const element::Type input_type = ngraph::element::u8;
|
||||
const std::vector<uint8_t> input{0xF0};
|
||||
const Shape input_shape{8};
|
||||
const element::Type input_type = ngraph::element::u1;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0x00};
|
||||
const std::vector<uint8_t> expected_output{0xF0};
|
||||
const element::Type expected_output_type = ngraph::element::u1;
|
||||
|
||||
ASSERT_THROW(ConvertTest(input, input_shape, input_type, expected_output, expected_output_type),
|
||||
ngraph::NodeValidationFailure);
|
||||
LPConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u4_to_u1)
|
||||
{
|
||||
const std::vector<uint8_t> input{0x10, 0x01, 0x00, 0x00};
|
||||
const Shape input_shape{8};
|
||||
const element::Type input_type = ngraph::element::u4;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0x90};
|
||||
const element::Type expected_output_type = ngraph::element::u1;
|
||||
|
||||
LPConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_u1)
|
||||
{
|
||||
const std::vector<uint8_t> input{1, 0, 1, 0, 0, 0, 0, 1};
|
||||
const Shape input_shape{8};
|
||||
const element::Type input_type = ngraph::element::u8;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0xA1};
|
||||
const element::Type expected_output_type = ngraph::element::u1;
|
||||
|
||||
LPConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_i4_to_u1)
|
||||
{
|
||||
const std::vector<uint8_t> input{0x10, 0x01, 0x00, 0x00};
|
||||
const Shape input_shape{8};
|
||||
const element::Type input_type = ngraph::element::u4;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0x90};
|
||||
const element::Type expected_output_type = ngraph::element::u1;
|
||||
|
||||
LPConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
// destination: u4
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_u4_is_not_supported_yet)
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u1_to_u4)
|
||||
{
|
||||
const std::vector<uint8_t> input{0, 0, 0, 0};
|
||||
const std::vector<uint8_t> input{0xF0};
|
||||
const Shape input_shape{4};
|
||||
const element::Type input_type = ngraph::element::u1;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0x11, 0x11};
|
||||
const element::Type expected_output_type = ngraph::element::u4;
|
||||
|
||||
LPConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u4_to_u4)
|
||||
{
|
||||
const std::vector<uint8_t> input{0x22, 0x33};
|
||||
const Shape input_shape{4};
|
||||
const element::Type input_type = ngraph::element::u4;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0x22, 0x33};
|
||||
const element::Type expected_output_type = ngraph::element::u4;
|
||||
|
||||
LPConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_u8_to_u4)
|
||||
{
|
||||
const std::vector<uint8_t> input{7, 0, 1, 15};
|
||||
const Shape input_shape{4};
|
||||
const element::Type input_type = ngraph::element::u8;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0x00, 0x00};
|
||||
const std::vector<uint8_t> expected_output{0x70, 0x1F};
|
||||
const element::Type expected_output_type = ngraph::element::u4;
|
||||
|
||||
ASSERT_THROW(ConvertTest(input, input_shape, input_type, expected_output, expected_output_type),
|
||||
ngraph::NodeValidationFailure);
|
||||
LPConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, convert_i4_to_u4)
|
||||
{
|
||||
const std::vector<uint8_t> input{0x22, 0x33};
|
||||
const Shape input_shape{4};
|
||||
const element::Type input_type = ngraph::element::i4;
|
||||
|
||||
const std::vector<uint8_t> expected_output{0x22, 0x33};
|
||||
const element::Type expected_output_type = ngraph::element::u4;
|
||||
|
||||
LPConvertTest(input, input_shape, input_type, expected_output, expected_output_type);
|
||||
}
|
||||
|
||||
// destination: u8
|
||||
|
||||
@@ -1050,8 +1050,11 @@ roll_negative_axes
|
||||
# convert operation
|
||||
IE_CPU.convert_f16_to_f32
|
||||
IE_CPU.convert_u8_to_f16
|
||||
IE_CPU.convert_u8_to_i4
|
||||
IE_CPU.convert_u8_to_i16
|
||||
IE_CPU.convert_u8_to_i64
|
||||
IE_CPU.convert_u8_to_u1
|
||||
IE_CPU.convert_u8_to_u4
|
||||
IE_CPU.convert_u8_to_u16
|
||||
IE_CPU.convert_u8_to_u32
|
||||
IE_CPU.convert_u8_to_u64
|
||||
@@ -1062,6 +1065,12 @@ IE_CPU.convert_u32_to_f32 # NOT_IMPLEMENTED
|
||||
IE_CPU.convert_i4_to_f32 # NOT_IMPLEMENTED
|
||||
IE_CPU.convert_u1_to_f32 # NOT_IMPLEMENTED
|
||||
IE_CPU.convert_u4_to_f32 # NOT_IMPLEMENTED
|
||||
IE_CPU.convert_u1_to_u1
|
||||
IE_CPU.convert_u4_to_u1
|
||||
IE_CPU.convert_i4_to_u1
|
||||
IE_CPU.convert_u1_to_u4
|
||||
IE_CPU.convert_u4_to_u4
|
||||
IE_CPU.convert_i4_to_u4
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
Reference in new issue
Block a user