Enable scalar initializer support in NNAPI (#5875)

* Add scalar initializer support in NNAPI
This commit is contained in:
Guoyu Wang 2020-11-20 03:40:49 -08:00 committed by GitHub
parent 00412a76e9
commit 44313970d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 52 deletions

View file

@ -181,7 +181,10 @@ Status ModelBuilder::RegisterInitializers() {
shape.push_back(SafeInt<uint32_t>(dim));
}
ORT_RETURN_IF_NOT(!shape.empty(), "NNAPI does not support scalar initializer, tensor name, ", name);
// If we have an empty shape, this is a scalar initializer, since NNAPI does not allow empty shape,
// we will make the scalar initializer a {1} tensor
if (shape.empty())
shape.push_back(1);
Type type = Type::TENSOR_FLOAT32;
switch (tensor.data_type()) {

View file

@ -196,21 +196,38 @@ TEST(MathOpTest, Add_Broadcast_0x0) {
}
TEST(MathOpTest, Add_Broadcast_0x1) {
OpTester test("Add");
auto run = [](bool scalar_as_initializer) {
OpTester test("Add");
test.AddInput<float>("A", {}, {10.0f});
test.AddInput<float>("B", {1}, {2.0f});
test.AddOutput<float>("C", {1}, {12.0f});
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kNnapiExecutionProvider}); // NNAPI: Add does not support scalar input
test.AddInput<float>("A", {}, {10.0f}, scalar_as_initializer);
test.AddInput<float>("B", {1}, {2.0f});
test.AddOutput<float>("C", {1}, {12.0f});
test.Run(OpTester::ExpectResult::kExpectSuccess, "");
};
// NNAPI only supports scalar initializer, not scalar input
#ifndef USE_NNAPI
run(false);
#endif
run(true);
}
TEST(MathOpTest, Add_Broadcast_1x0) {
OpTester test("Add");
auto run = [](bool scalar_as_initializer) {
OpTester test("Add");
test.AddInput<float>("A", {1}, {10.0f});
test.AddInput<float>("B", {}, {2.0f});
test.AddOutput<float>("C", {1}, {12.0f});
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kNnapiExecutionProvider}); // NNAPI: Add does not support scalar input
test.AddInput<float>("A", {1}, {10.0f});
test.AddInput<float>("B", {}, {2.0f}, scalar_as_initializer);
test.AddOutput<float>("C", {1}, {12.0f});
test.Run(OpTester::ExpectResult::kExpectSuccess, "");
};
// NNAPI only supports scalar initializer, not scalar input
#ifndef USE_NNAPI
run(false);
#endif
run(true);
}
TEST(MathOpTest, Add_Broadcast_1x1) {
@ -366,18 +383,27 @@ TEST(MathOpTest, Sub) {
}
TEST(MathOpTest, Sub_Broadcast_Scalar) {
OpTester test("Sub");
std::vector<int64_t> dims{3, 3};
test.AddInput<float>("A", dims,
{1.0f, 2.0f, -1.0f,
0.0f, 1.5f, -100.0f,
-5.4f, 9.3f, -10000.0f});
test.AddInput<float>("B", {}, {5.0f});
test.AddOutput<float>("C", dims,
{-4.0f, -3.0f, -6.0f,
-5.0f, -3.5f, -105.0f,
-10.4f, 4.3f, -10005.0f});
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kNnapiExecutionProvider}); // NNAPI: Sub does not support scalar input
auto run = [](bool scalar_as_initializer) {
OpTester test("Sub");
std::vector<int64_t> dims{3, 3};
test.AddInput<float>("A", dims,
{1.0f, 2.0f, -1.0f,
0.0f, 1.5f, -100.0f,
-5.4f, 9.3f, -10000.0f});
test.AddInput<float>("B", {}, {5.0f}, scalar_as_initializer);
test.AddOutput<float>("C", dims,
{-4.0f, -3.0f, -6.0f,
-5.0f, -3.5f, -105.0f,
-10.4f, 4.3f, -10005.0f});
test.Run(OpTester::ExpectResult::kExpectSuccess, "");
};
// NNAPI only supports scalar initializer, not scalar input
#ifndef USE_NNAPI
run(false);
#endif
run(true);
}
TEST(MathOpTest, Mul_int32) {
@ -424,11 +450,11 @@ TEST(MathOpTest, Div_int32) {
test.AddInput<int32_t>("A", {3}, {4, 8, 8});
test.AddInput<int32_t>("B", {3}, {1, 3, 2});
test.AddOutput<int32_t>("C", {3}, {4, 2, 4});
#if defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M)
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kOpenVINOExecutionProvider}); // OpenVINO EP: Hardware limitation
#else
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT parser:elementwise inputs must not be Int32
#endif
#if defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M)
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kOpenVINOExecutionProvider}); // OpenVINO EP: Hardware limitation
#else
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT parser:elementwise inputs must not be Int32
#endif
}
TEST(MathOpTest, Div_int64) {
@ -436,11 +462,11 @@ TEST(MathOpTest, Div_int64) {
test.AddInput<int64_t>("A", {3}, {4, 8, 8});
test.AddInput<int64_t>("B", {3}, {2, 3, 4});
test.AddOutput<int64_t>("C", {3}, {2, 2, 2});
#if defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M)
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kOpenVINOExecutionProvider}); // OpenVINO EP: Hardware limitation
#else
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT parser:elementwise inputs must not be Int32
#endif
#if defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M)
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kOpenVINOExecutionProvider}); // OpenVINO EP: Hardware limitation
#else
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); //TensorRT parser:elementwise inputs must not be Int32
#endif
}
TEST(MathOpTest, Div) {
@ -549,13 +575,13 @@ TEST(MathOpTest, Ceil) {
test.AddOutput<float>("Y", dims,
{-1.0f, 1.0f,
0.0f, 11.0f});
#if defined(OPENVINO_CONFIG_GPU_FP16) || defined(OPENVINO_CONFIG_GPU_FP32) || defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M)
#if defined(OPENVINO_CONFIG_GPU_FP16) || defined(OPENVINO_CONFIG_GPU_FP32) || defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M)
//OpenVINO: Disabled due to software limitation for GPU and VPU Plugins.
//This test runs fine on CPU Plugin
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kOpenVINOExecutionProvider});
#else
test.Run();
#endif
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kOpenVINOExecutionProvider});
#else
test.Run();
#endif
}
TEST(MathOpTest, Reciprocal) {
@ -1518,11 +1544,11 @@ TEST(MathOpTest, Equal_int64) {
test.AddInput<int64_t>("A", dims, {1, 0, -1, -1});
test.AddInput<int64_t>("B", dims, {1, 1, 2, -1});
test.AddOutput<bool>("C", dims, {true, false, false, true});
#if defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M)
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kOpenVINOExecutionProvider});
#else
test.Run();
#endif
#if defined(OPENVINO_CONFIG_MYRIAD) || defined(OPENVINO_CONFIG_VAD_M)
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kOpenVINOExecutionProvider});
#else
test.Run();
#endif
}
TEST(MathOpTest, Equal_float) {
@ -1713,9 +1739,9 @@ TEST(MathOpTest, Expand_8_3x3_string) {
test.AddInput<std::string>("data_0", {1}, {"1"});
test.AddInput<int64_t>("data_1", {2}, {3, 3});
test.AddOutput<std::string>("result", {3, 3},
{"1", "1", "1",
"1", "1", "1",
"1", "1", "1"});
{"1", "1", "1",
"1", "1", "1",
"1", "1", "1"});
test.Run();
}
@ -1724,9 +1750,9 @@ TEST(MathOpTest, Expand_8_3x1_string) {
test.AddInput<std::string>("data_0", {3}, {"1", "2", "3"});
test.AddInput<int64_t>("data_1", {2}, {3, 1});
test.AddOutput<std::string>("result", {3, 3},
{"1", "2", "3",
"1", "2", "3",
"1", "2", "3"});
{"1", "2", "3",
"1", "2", "3",
"1", "2", "3"});
test.Run();
}
@ -1735,9 +1761,9 @@ TEST(MathOpTest, Expand_8_1x3_string) {
test.AddInput<std::string>("data_0", {3, 1}, {"1", "2", "3"});
test.AddInput<int64_t>("data_1", {2}, {1, 3});
test.AddOutput<std::string>("result", {3, 3},
{"1", "1", "1",
"2", "2", "2",
"3", "3", "3"});
{"1", "1", "1",
"2", "2", "2",
"3", "3", "3"});
test.Run();
}