ONE - On-device Neural Engine
Loading...
Searching...
No Matches
ReduceMean.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _NNC_CORE_BACKEND_INTERPRETER_REDUCE_MEAN_
18#define _NNC_CORE_BACKEND_INTERPRETER_REDUCE_MEAN_
19
20#include "ReduceMean.h"
21#include "Common.h"
22
24#include "mir/Tensor.h"
25#include "mir/ShapeRange.h"
26
27namespace mir_interpreter
28{
29
30template <typename T> struct ReduceMeanImpl
31{
32 static void run(const mir::TensorVariant &inputv, const mir::ops::ReduceMeanOp &op,
33 mir::TensorVariant &output);
34};
35
36template <typename T>
38 mir::TensorVariant &output)
39{
40 const auto &input_shape = op.getInputShape(0);
41 const auto &output_shape = op.getOutputShape(0);
42 const auto &reduction_dims = op.getReductionDims();
43 const bool keep_dims = op.getKeepDims();
44
45 const auto reductor = [](T result, T x) { return result + x; };
46
47 mir::Tensor<T> input(inputv);
48 mir::Tensor<T> res_accessor(output);
49
50 erase<T>(output);
51
52 // This mask contains 'true' for dimensions that should be reduced. For example, if we want
53 // to reduce dimensions 1 and 3 with total number of dimensions of 4, the mask will be
54 // [false, true, false, true].
55 std::vector<bool> reduction_dims_mask(input_shape.rank(), false);
56 for (const int dim : reduction_dims)
57 {
58 reduction_dims_mask[dim] = true;
59 }
60
61 mir::Index out_index(output_shape.rank());
62 for (const mir::Index &in_index : mir::ShapeRange(input_shape))
63 {
64 int out_index_dim = 0;
65 for (int dim = 0; dim < input_shape.rank(); ++dim)
66 {
67 if (keep_dims)
68 {
69 out_index.at(out_index_dim++) = reduction_dims_mask[dim] ? 0 : in_index.at(dim);
70 }
71 else
72 {
73 if (!reduction_dims_mask[dim])
74 {
75 out_index.at(out_index_dim++) = in_index.at(dim);
76 }
77 }
78 }
79 res_accessor.at(out_index) = reductor(res_accessor.at(out_index), input.at(in_index));
80 }
81
82 const std::int32_t reduction_factor = input_shape.numElements() / output_shape.numElements();
83
84 for (const auto &index : mir::ShapeRange(output_shape))
85 {
86 res_accessor.at(index) /= reduction_factor;
87 }
88}
89
91 mir::TensorVariant &output)
92{
93 dispatch<ReduceMeanImpl>(input.getElementType(), input, op, output);
94};
95
96} // namespace mir_interpreter
97
98#endif //_NNC_CORE_BACKEND_INTERPRETER_REDUCE_MEAN_
int32_t & at(int32_t axis)
return position on given axis
Definition Index.h:64
const Shape & getInputShape(std::size_t index) const
Definition Operation.h:161
const Shape & getOutputShape(std::size_t index) const
Definition Operation.h:163
T at(const Index &id) const
Definition Tensor.h:31
const std::vector< int > & getReductionDims() const
Definition ReduceOp.h:38
bool getKeepDims() const
Definition ReduceOp.h:40
const luci_interpreter::RuntimeShape output_shape
void ReduceMean(const mir::TensorVariant &input, const mir::ops::ReduceMeanOp &op, mir::TensorVariant &output)
static void run(const mir::TensorVariant &inputv, const mir::ops::ReduceMeanOp &op, mir::TensorVariant &output)