{
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));
{
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));
{
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>();
{
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));