[neurun/acl_neon] Simplify code using Operand::asVector (#9039)
authorSergei Barannikov/AI Tools Lab /SRR/Engineer/Samsung Electronics <s.barannikov@samsung.com>
Wed, 20 Nov 2019 05:37:54 +0000 (08:37 +0300)
committer오형석/On-Device Lab(SR)/Staff Engineer/삼성전자 <hseok82.oh@samsung.com>
Wed, 20 Nov 2019 05:37:54 +0000 (14:37 +0900)
Simplify code using newly introduced `Operand::asVector`.

Signed-off-by: Sergei Barannikov <s.barannikov@samsung.com>
runtime/neurun/backend/acl_cl/KernelGenerator.cc

index 908b779..825318d 100644 (file)
@@ -524,34 +524,27 @@ void KernelGenerator::visit(const model::operation::ReduceSum &node)
 {
   const auto output_index{node.getOutputs().at(0)};
   const auto input_index{node.getInputs().at(model::operation::ReduceSum::Input::INPUT)};
-  const auto axis_index{node.param().axis_index};
-
-  const auto axis_base = _ctx.at(axis_index).data().base();
-  const auto axis_size = _ctx.at(axis_index).shape().num_elements();
-  const auto input_rank = _ctx.at(input_index).shape().rank();
+  const auto &axes{_ctx.at(node.param().axis_index).asVector<int>()};
 
   auto output_alloc = _tensor_builder->at(output_index).get();
   auto input_alloc = _tensor_builder->at(input_index).get();
   const auto frontend_layout = _current_subg_layout;
   const auto backend_layout = input_alloc->layout();
-  // The axis's data must exist as constant values
-  assert(axis_base != nullptr);
-  std::set<uint32_t> axes;
-  for (size_t n = 0; n < axis_size; ++n)
+
+  // Convert to ACL axes taking into account negative values and possible duplicates.
+  std::set<std::uint32_t> acl_axes;
+  const auto input_rank = _ctx.at(input_index).shape().rank();
+  for (int axis : axes)
   {
-    int32_t axis_value = *(reinterpret_cast<const int32_t *>(axis_base) + n);
-    if (axis_value < 0)
-    {
-      axis_value += input_rank;
-    }
-    axes.insert(::neurun::backend::acl_common::ToARMComputeAxis(input_rank, axis_value,
-                                                                frontend_layout, backend_layout)
-                    .value());
+    if (axis < 0)
+      axis += input_rank;
+    acl_axes.insert(
+        acl_common::ToARMComputeAxis(input_rank, axis, frontend_layout, backend_layout).value());
   }
 
   auto fn = nnfw::cpp14::make_unique<::arm_compute::CLReduceOperation>();
 
-  fn->configure(input_alloc->handle(), output_alloc->handle(), axes,
+  fn->configure(input_alloc->handle(), output_alloc->handle(), acl_axes,
                 ::arm_compute::ReduceOperation::SUM);
 
   auto acl_fn = asAclFunction(std::move(fn));
@@ -1060,62 +1053,28 @@ void KernelGenerator::visit(const model::operation::ReduceMax &node)
 {
   const auto output_index{node.getOutputs().at(0)};
   const auto input_index{node.getInputs().at(model::operation::ReduceMax::Input::INPUT)};
-  const auto axis_index{node.param().axis_index};
-
-  auto input_shape = _ctx.at(input_index).shape();
-  auto axis_shape = _ctx.at(axis_index).shape();
+  const auto &axes{_ctx.at(node.param().axis_index).asVector<int>()};
 
   auto ofm_alloc = _tensor_builder->at(output_index).get();
   auto ifm_alloc = _tensor_builder->at(input_index).get();
-  std::set<uint32_t> axes;
   const auto frontend_layout = _current_subg_layout;
   const auto backend_layout = ifm_alloc->layout();
+
+  // Convert to ACL axes taking into account negative values and possible duplicates.
+  std::set<std::uint32_t> acl_axes;
+  const int ifm_rank = _ctx.at(input_index).shape().rank();
+  for (int axis : axes)
   {
-    const auto ifm_rank = input_shape.rank();
-    switch (axis_shape.rank())
-    {
-      case 0: // scalar
-      {
-        int32_t axis_value = _ctx.at(axis_index).asScalar<int32_t>();
-        if (axis_value < 0)
-        {
-          axis_value += ifm_rank;
-        }
-        axes.insert(::neurun::backend::acl_common::ToARMComputeAxis(ifm_rank, axis_value,
-                                                                    frontend_layout, backend_layout)
-                        .value());
-        break;
-      }
-      case 1: // vector
-      {
-        const auto axis_base = _ctx.at(axis_index).data().base();
-        const int axis_size = axis_shape.num_elements();
-
-        // If axis's data does not exist as constant values and can be gotten as input data, we have
-        // to find a way to infer output shape when sinking output.
-        assert(axis_base != nullptr);
-        for (int32_t n = 0; n < axis_size; ++n)
-        {
-          int32_t axis_value = *(reinterpret_cast<const int32_t *>(axis_base) + n);
-          if (axis_value < 0)
-          {
-            axis_value += ifm_rank;
-          }
-          axes.insert(::neurun::backend::acl_common::ToARMComputeAxis(
-                          ifm_rank, axis_value, frontend_layout, backend_layout)
-                          .value());
-        }
-        break;
-      }
-      default:
-        throw std::runtime_error("Not supported");
-        break;
-    }
+    if (axis < 0)
+      axis += ifm_rank;
+    acl_axes.insert(
+        acl_common::ToARMComputeAxis(ifm_rank, axis, frontend_layout, backend_layout).value());
   }
 
   auto fn = nnfw::cpp14::make_unique<::arm_compute::CLReduceOperation>();
 
-  fn->configure(ifm_alloc->handle(), ofm_alloc->handle(), axes, arm_compute::ReduceOperation::MAX);
+  fn->configure(ifm_alloc->handle(), ofm_alloc->handle(), acl_axes,
+                arm_compute::ReduceOperation::MAX);
 
   auto acl_fn = asAclFunction(std::move(fn));
 
@@ -1848,63 +1807,29 @@ void KernelGenerator::visit(const model::operation::Mean &node)
 {
   const auto ofm_index{node.getOutputs().at(0)};
   const auto ifm_index{node.getInputs().at(model::operation::Mean::Input::INPUT)};
-
-  const auto axis_index{node.param().axis_index};
+  const auto &axes{_ctx.at(node.param().axis_index).asVector<int>()};
   const auto keep_dims{node.param().keep_dims};
 
-  const auto ifm_shape = _ctx.at(ifm_index).shape();
-
   auto ofm_alloc = _tensor_builder->at(ofm_index).get();
   auto ifm_alloc = _tensor_builder->at(ifm_index).get();
-  std::set<uint32_t> axes;
+  const auto frontend_layout = _current_subg_layout;
+  const auto backend_layout = ifm_alloc->layout();
+
+  // Convert to ACL axes taking into account negative values and possible duplicates.
+  std::set<std::uint32_t> acl_axes;
+  const int ifm_rank = _ctx.at(ifm_index).shape().rank();
+  for (auto axis : axes)
   {
-    const auto ifm_rank = ifm_shape.rank();
-    const auto frontend_layout = _current_subg_layout;
-    const auto backend_layout = ifm_alloc->layout();
-    const auto axis_shape = _ctx.at(axis_index).shape();
-    switch (axis_shape.rank())
-    {
-      case 0: // scalar
-      {
-        auto axis_value = _ctx.at(axis_index).asScalar<int32_t>();
-        if (axis_value < 0)
-        {
-          axis_value += ifm_rank;
-        }
-        axes.insert(::neurun::backend::acl_common::ToARMComputeAxis(ifm_rank, axis_value,
-                                                                    frontend_layout, backend_layout)
-                        .value());
-        break;
-      }
-      case 1: // vector
-      {
-        const auto axis_base = _ctx.at(axis_index).data().base();
-        const int axis_size = axis_shape.num_elements();
-
-        // If axis's data does not exist as constant values and can be gotten as input data, we have
-        // to find a way to infer output shape when sinking output.
-        assert(axis_base != nullptr);
-        for (int32_t n = 0; n < axis_size; ++n)
-        {
-          int32_t axis_value = *(reinterpret_cast<const int32_t *>(axis_base) + n);
-          if (axis_value < 0)
-          {
-            axis_value += ifm_rank;
-          }
-          axes.insert(::neurun::backend::acl_common::ToARMComputeAxis(
-                          ifm_rank, axis_value, frontend_layout, backend_layout)
-                          .value());
-        }
-        break;
-      }
-      default:
-        throw std::runtime_error("Not supported");
-    }
+    if (axis < 0)
+      axis += ifm_rank;
+    acl_axes.insert(
+        acl_common::ToARMComputeAxis(ifm_rank, axis, frontend_layout, backend_layout).value());
   }
+
   arm_compute::Coordinates reduce_axes;
-  for (const auto &a : axes)
+  for (const auto axis : acl_axes)
   {
-    reduce_axes.set(reduce_axes.num_dimensions(), a);
+    reduce_axes.set(reduce_axes.num_dimensions(), axis);
   }
 
   auto fn = nnfw::cpp14::make_unique<::arm_compute::CLReduceMean>();
@@ -1966,63 +1891,27 @@ void KernelGenerator::visit(const model::operation::ReduceMin &node)
 {
   const auto ofm_index{node.getOutputs().at(0)};
   const auto ifm_index{node.getInputs().at(model::operation::ReduceMin::Input::INPUT)};
-  const auto axis_index{node.param().axis_index};
+  const auto &axes{_ctx.at(node.param().axis_index).asVector<int>()};
 
-  auto ifm_shape = _ctx.at(ifm_index).shape();
-  auto ofm_shape = _ctx.at(ofm_index).shape();
-  auto axis_shape = _ctx.at(axis_index).shape();
-
-  const auto ifm_rank = ifm_shape.rank();
   auto ofm_alloc = _tensor_builder->at(ofm_index).get();
   auto ifm_alloc = _tensor_builder->at(ifm_index).get();
-  std::set<uint32_t> axes;
+  const auto frontend_layout = _current_subg_layout;
+  const auto backend_layout = ifm_alloc->layout();
+
+  // Convert to ACL axes taking into account negative values and possible duplicates.
+  std::set<std::uint32_t> acl_axes;
+  const auto ifm_rank = _ctx.at(ifm_index).shape().rank();
+  for (int axis : axes)
   {
-    const auto frontend_layout = _current_subg_layout;
-    const auto backend_layout = ifm_alloc->layout();
-    switch (axis_shape.rank())
-    {
-      case 0: // scalar
-      {
-        auto axis_value = _ctx.at(axis_index).asScalar<int32_t>();
-        if (axis_value < 0)
-        {
-          axis_value += ifm_rank;
-        }
-        axes.insert(::neurun::backend::acl_common::ToARMComputeAxis(ifm_rank, axis_value,
-                                                                    frontend_layout, backend_layout)
-                        .value());
-        break;
-      }
-      case 1: // vector
-      {
-        const auto axis_base = _ctx.at(axis_index).data().base();
-        const int axis_size = axis_shape.num_elements();
-
-        // If axis's data does not exist as constant values and can be gotten as input data, we have
-        // to find a way to infer output shape when sinking output.
-        assert(axis_base != nullptr);
-        for (int32_t n = 0; n < axis_size; ++n)
-        {
-          int32_t axis_value = *(reinterpret_cast<const int32_t *>(axis_base) + n);
-          if (axis_value < 0)
-          {
-            axis_value += ifm_rank;
-          }
-          axes.insert(::neurun::backend::acl_common::ToARMComputeAxis(
-                          ifm_rank, axis_value, frontend_layout, backend_layout)
-                          .value());
-        }
-        break;
-      }
-      default:
-        throw std::runtime_error("Not supported");
-        break;
-    }
+    if (axis < 0)
+      axis += ifm_rank;
+    acl_axes.insert(
+        acl_common::ToARMComputeAxis(ifm_rank, axis, frontend_layout, backend_layout).value());
   }
 
   auto fn = nnfw::cpp14::make_unique<::arm_compute::CLReduceOperation>();
 
-  fn->configure(ifm_alloc->handle(), ofm_alloc->handle(), axes,
+  fn->configure(ifm_alloc->handle(), ofm_alloc->handle(), acl_axes,
                 ::arm_compute::ReduceOperation::MIN);
 
   auto acl_fn = asAclFunction(std::move(fn));