[nnc] Scale and BiasAdd realizations on Eigen (#2956)
authorПавел Ильютченко/AI Tools Lab /SRR/Engineer/삼성전자 <p.iliutchenk@samsung.com>
Wed, 30 Jan 2019 11:03:25 +0000 (14:03 +0300)
committerEfimov Alexander/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Wed, 30 Jan 2019 11:03:25 +0000 (14:03 +0300)
Refactor Scale and BiasAdd ops on SoftBackend to use eigen functions

Signed-off-by: Pavel Iliutchenko <p.iliutchenk@samsung.com>
contrib/nnc/passes/soft_backend/code_snippets/cpp_add_bias.def
contrib/nnc/passes/soft_backend/code_snippets/cpp_operations.def
contrib/nnc/passes/soft_backend/code_snippets/cpp_scale.def

index 7033dcd..903c7a8 100644 (file)
@@ -14,12 +14,12 @@ limitations under the License.
 ==============================================================================*/
 
 inline void AddBiasAndEvalActivationFunction(const float* bias_data,
-                                             const Dims<4>& bias_dims,
+                                             const RuntimeShape& bias_shape,
                                              float* array_data,
-                                             const Dims<4>& array_dims) {
+                                             const RuntimeShape& array_shape) {
 #ifdef USE_NEON
-  const int bias_size = FlatSize(bias_dims);
-  const int array_size = FlatSize(array_dims);
+  const int bias_size = bias_shape.FlatSize();
+  const int array_size = array_shape.FlatSize();
   TFLITE_DCHECK_EQ((array_size % bias_size), 0);
   float* array_ptr = array_data;
   float* array_end_ptr = array_ptr + array_size;
@@ -55,14 +55,10 @@ inline void AddBiasAndEvalActivationFunction(const float* bias_data,
   }
 #else  // not NEON
 
-  const int bias_size = FlatSize(bias_dims);
-  const int array_size = FlatSize(array_dims);
-  TFLITE_DCHECK_EQ((array_size % bias_size), 0);
-  for (int array_offset = 0; array_offset < array_size;
-       array_offset += bias_size) {
-    for (int i = 0; i < bias_size; i++) {
-      array_data[array_offset + i] = array_data[array_offset + i] + bias_data[i];
-    }
-  }
+  assert(bias_shape.DimensionsCount() == 1 &&
+         bias_shape.Dims(0) == array_shape.Dims(array_shape.DimensionsCount() - 1));
+  const auto bias_vec = MapAsVector(bias_data, bias_shape);
+  auto out_mat = MapAsMatrixWithLastDimAsRows(array_data, array_shape);
+  out_mat.colwise() += bias_vec;
 #endif
 }
index 050f4b8..f3e88a4 100644 (file)
@@ -413,13 +413,13 @@ void cappedRelu(Tensor &out, const char *params, const Tensor &in)
   CappedRelu(input, input_d, cap, out.getData(), input_d);
 }
 
-void biasAdd(Tensor &out, const char *params, const Tensor &in1, const Tensor& in2)
+void biasAdd(Tensor& out, const char* params, const Tensor& in1, const Tensor& in2)
 {
   out.reshape(in1.getShape());
   out.fillData(in1.getData(), in1.getShape().getNumElems());
 
-  AddBiasAndEvalActivationFunction(in2.getData(), shapeToDims(in2.getShape()),
-                                   out.getData(), shapeToDims(out.getShape()));
+  AddBiasAndEvalActivationFunction(in2.getData(), shapeToRuntimeShape(in2.getShape()),
+                                   out.getData(), shapeToRuntimeShape(out.getShape()));
 }
 
 void slice(Tensor& out, const char* params, const Tensor& in) {
index 3afa077..7026254 100644 (file)
  */
 
 void scale(Tensor& out, const char* params, const Tensor& in1, const Tensor& in2) {
-  const Shape& in1_shape = in1.getShape();
-  const Shape& in2_shape = in2.getShape();
-  assert(in2_shape.getDims() == 1 && in2_shape[0] == in1_shape[in1_shape.getDims() - 1]);
-  out.reshape(in1_shape);
+  const auto in1_shape = shapeToRuntimeShape(in1.getShape());
+  const auto in2_shape = shapeToRuntimeShape(in2.getShape());
+  assert(in2_shape.DimensionsCount() == 1 &&
+    in2_shape.Dims(0) == in1_shape.Dims(in1_shape.DimensionsCount() - 1));
 
-  const float* in1_data = in1.getData();
-  const float* in2_data = in2.getData();
-  float* out_data = out.getData();
-  int32_t w_size = in2_shape[0];
-  int32_t data_size = in1_shape.getNumElems();
+  out.reshape(in1.getShape());
+  const auto out_shape = shapeToRuntimeShape(out.getShape());
 
-  assert(data_size % w_size == 0);
-  for (int32_t slice_offset = 0; slice_offset < data_size; slice_offset += w_size) {
-    for (int i = 0; i < w_size; i++) {
-      out_data[slice_offset + i] = in1_data[slice_offset + i] * in2_data[i];
-    }
-  }
+  const auto in1_mat = MapAsMatrixWithLastDimAsRows(in1.getData(), in1_shape);
+  const auto in2_vec = MapAsVector(in2.getData(), in2_shape);
+  auto out_mat = MapAsMatrixWithLastDimAsRows(out.getData(), out_shape);
+  out_mat.colwise() = in2_vec;
+  out_mat.array() = out_mat.array() * in1_mat.array();
 }