Fix split implementation and test (#4622)
author오형석/On-Device Lab(SR)/Staff Engineer/삼성전자 <hseok82.oh@samsung.com>
Fri, 8 Mar 2019 00:50:55 +0000 (09:50 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Fri, 8 Mar 2019 00:50:55 +0000 (09:50 +0900)
* Fix split implementation and test

Fix plit implementation based on NeuralNetworksEx.h spec
- Fix split in nnapi_delegate.cpp
- Fix pacl implementation
- Fix spli test

Signed-off-by: Hyeongseok Oh <hseok82.oh@samsung.com>
* Fix comment

15 files changed:
libs/tflite/src/ext/nnapi_delegate.cpp
libs/tflite/src/ext/nnapi_delegate_ex_AddOpsAndParams_lambda.inc
runtimes/pure_arm_compute/src/internal/op/Split.cc
runtimes/pure_arm_compute/src/internal/op/Split.h
tests/nnapi/specs/Ex/split_ex_1D_float.mod.py
tests/nnapi/specs/Ex/split_ex_1D_int32.mod.py
tests/nnapi/specs/Ex/split_ex_4D_float_1.mod.py
tests/nnapi/specs/Ex/split_ex_4D_float_2.mod.py
tests/nnapi/specs/Ex/split_ex_4D_float_3.mod.py
tests/nnapi/specs/Ex/split_ex_4D_int32_1.mod.py
tests/nnapi/specs/Ex/split_ex_4D_int32_2.mod.py
tests/nnapi/specs/Ex/split_ex_4D_int32_3.mod.py
tests/nnapi/specs/Ex/split_ex_4D_int32_4.mod.py
tests/nnapi/specs/Ex/split_ex_4D_int32_5.mod.py
tests/nnapi/specs/Ex/split_ex_4D_quant8.mod.py

index 02abe3f..78c3fed 100644 (file)
@@ -720,6 +720,7 @@ TfLiteStatus AddOpsAndParams(
             reinterpret_cast<uint32_t*>(node.outputs->data)));
         continue;
       case tflite::BuiltinOperator_SPLIT:
+        add_split_params(node.builtin_data);
         CHECK_NN(ANeuralNetworksModel_addOperationEx(
             nn_model, ANEURALNETWORKS_SPLIT_EX,
             static_cast<uint32_t>(augmented_inputs.size()),
index 31170a8..cd06de0 100644 (file)
@@ -93,3 +93,8 @@
         }
       }
     };
+
+    auto add_split_params = [&add_scalar_int32](void* data) {
+      auto builtin = reinterpret_cast<TfLiteSplitParams*>(data);
+      add_scalar_int32(builtin->num_splits);
+    };
index cbd863f..6457a10 100644 (file)
@@ -47,13 +47,16 @@ namespace Split
 Param::Param(uint32_t inputCount, const uint32_t *inputs, uint32_t outputCount,
              const uint32_t *outputs)
 {
-  assert(inputCount == 2);
+  assert(inputCount == 3);
 
   // Each input should be interpreted as follows:
-  //  0 -> A 0-D int32 tensor, indicating the dimension along which to split.
-  //  1 -> An n-D tensor, specifying the tensor to be split.
-  axis_index = inputs[0];
-  ifm_index = inputs[1];
+  //  0 -> An n-D tensor, specifying the tensor to be split.
+  //  1 -> A 0-D int32 tensor, indicating the dimension along which to split.
+  //  2 -> A 0-D int32 tensor, indicating the number of outputs
+  //       (It can be ignored on pacl becasue pacl don't support dynamic tensor shape,
+  //        and can be used for verification only)
+  ifm_index = inputs[0];
+  axis_index = inputs[1];
 
   // Each output should be interpreted as follow:
   //  [0, outputCount) -> An n-D tensor.
index b2c6c2f..cb5f3eb 100644 (file)
@@ -42,8 +42,8 @@ namespace Split
  */
 struct Param
 {
-  int32_t axis_index; //!< index for axis
   int32_t ifm_index;  //!< index for input feature map
+  int32_t axis_index; //!< index for axis
 
   std::vector<int32_t> ofm_indexes; //!< index for output feature map
 
index 97b6146..137ece8 100644 (file)
@@ -2,6 +2,7 @@
 model = Model()
 i1 = Input("op1", "TENSOR_FLOAT32", "{8}")
 axis = Int32Scalar("axis", 0)
+num_out = Int32Scalar("num_out", 8)
 i2 = Output("op2", "TENSOR_FLOAT32", "{1}")
 i3 = Output("op3", "TENSOR_FLOAT32", "{1}")
 i4 = Output("op4", "TENSOR_FLOAT32", "{1}")
@@ -11,7 +12,7 @@ i7 = Output("op7", "TENSOR_FLOAT32", "{1}")
 i8 = Output("op8", "TENSOR_FLOAT32", "{1}")
 i9 = Output("op9", "TENSOR_FLOAT32", "{1}")
 
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3, i4, i5, i6, i7, i8, i9])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3, i4, i5, i6, i7, i8, i9])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index 378b377..9bfc215 100644 (file)
@@ -2,6 +2,7 @@
 model = Model()
 i1 = Input("op1", "TENSOR_INT32", "{8}")
 axis = Int32Scalar("axis", 0)
+num_out = Int32Scalar("num_out", 8)
 i2 = Output("op2", "TENSOR_INT32", "{1}")
 i3 = Output("op3", "TENSOR_INT32", "{1}")
 i4 = Output("op4", "TENSOR_INT32", "{1}")
@@ -11,7 +12,7 @@ i7 = Output("op7", "TENSOR_INT32", "{1}")
 i8 = Output("op8", "TENSOR_INT32", "{1}")
 i9 = Output("op9", "TENSOR_INT32", "{1}")
 
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3, i4, i5, i6, i7, i8, i9])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3, i4, i5, i6, i7, i8, i9])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index 3059fae..2353a8a 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_FLOAT32", "{2,2,2,2}")
 axis = Int32Scalar("axis", 0)
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_FLOAT32", "{1,2,2,2}")
 i3 = Output("op3", "TENSOR_FLOAT32", "{1,2,2,2}")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index faa59bc..30ecf24 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_FLOAT32", "{2,2,2,2}")
 axis = Int32Scalar("axis", 3)
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_FLOAT32", "{2,2,2,1}")
 i3 = Output("op3", "TENSOR_FLOAT32", "{2,2,2,1}")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index 2091e4b..1f7a078 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_FLOAT32", "{2,2,2,2}")
 axis = Int32Scalar("axis", -4) # Negative axis
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_FLOAT32", "{1,2,2,2}")
 i3 = Output("op3", "TENSOR_FLOAT32", "{1,2,2,2}")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index 3e9438f..b1c6692 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_INT32", "{2,2,2,2}")
 axis = Int32Scalar("axis", 0)
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_INT32", "{1,2,2,2}")
 i3 = Output("op3", "TENSOR_INT32", "{1,2,2,2}")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index 83253cb..88a7cca 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_INT32", "{2,2,2,2}")
 axis = Int32Scalar("axis", 1)
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_INT32", "{2,1,2,2}")
 i3 = Output("op3", "TENSOR_INT32", "{2,1,2,2}")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index b20b205..6f5cc62 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_INT32", "{2,2,2,2}")
 axis = Int32Scalar("axis", 2)
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_INT32", "{2,2,1,2}")
 i3 = Output("op3", "TENSOR_INT32", "{2,2,1,2}")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index 3c255cc..fb67101 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_INT32", "{2,2,2,2}")
 axis = Int32Scalar("axis", 3)
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_INT32", "{2,2,2,1}")
 i3 = Output("op3", "TENSOR_INT32", "{2,2,2,1}")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index 30e5e24..3387948 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_INT32", "{2,2,2,2}")
 axis = Int32Scalar("axis", -4) # Negative axis
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_INT32", "{1,2,2,2}")
 i3 = Output("op3", "TENSOR_INT32", "{1,2,2,2}")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0
index 46cb3ab..a3dbffa 100644 (file)
@@ -2,9 +2,10 @@
 model = Model()
 i1 = Input("op1", "TENSOR_QUANT8_ASYMM", "{2,2,2,2}, 0.5f, 1")
 axis = Int32Scalar("axis", 0)
+num_out = Int32Scalar("num_out", 2)
 i2 = Output("op2", "TENSOR_QUANT8_ASYMM", "{1,2,2,2}, 0.5f, 1")
 i3 = Output("op3", "TENSOR_QUANT8_ASYMM", "{1,2,2,2}, 0.5f, 1")
-model = model.Operation("SPLIT_EX", axis, i1).To([i2, i3])
+model = model.Operation("SPLIT_EX", i1, axis, num_out).To([i2, i3])
 
 # Example 1. Input in operand 0,
 input0 = {i1: # input 0