| 37 | namespace |
| 38 | { |
| 39 | Status |
| 40 | validate_config(const ITensorInfo *input, const Coordinates &reduction_axis, bool keep_dims, const ITensorInfo *output) |
| 41 | { |
| 42 | ARM_COMPUTE_UNUSED(keep_dims); |
| 43 | ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, output); |
| 44 | ARM_COMPUTE_RETURN_ERROR_ON_DYNAMIC_SHAPE(input, output); |
| 45 | ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(input); |
| 46 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::QASYMM8_SIGNED, DataType::QASYMM8, |
| 47 | DataType::F16, DataType::F32); |
| 48 | ARM_COMPUTE_RETURN_ERROR_ON(reduction_axis.num_dimensions() < 1); |
| 49 | ARM_COMPUTE_RETURN_ERROR_ON(reduction_axis.num_dimensions() > input->num_dimensions()); |
| 50 | |
| 51 | const unsigned int reduction_ops = reduction_axis.num_dimensions(); |
| 52 | const int input_dims = input->num_dimensions(); |
| 53 | Coordinates axis_local = reduction_axis; |
| 54 | |
| 55 | for (unsigned int i = 0; i < axis_local.num_dimensions(); ++i) |
| 56 | { |
| 57 | //axis: The dimensions to reduce. Must be in the range [-rank(input_tensor), rank(input_tensor)). |
| 58 | ARM_COMPUTE_RETURN_ERROR_ON(axis_local[i] < (-static_cast<int>(input->num_dimensions()))); |
| 59 | ARM_COMPUTE_RETURN_ERROR_ON(axis_local[i] >= static_cast<int>(input->num_dimensions())); |
| 60 | } |
| 61 | |
| 62 | if (output->tensor_shape().total_size() != 0) |
| 63 | { |
| 64 | // Only validate if not using auto_init for the output tensor |
| 65 | TensorShape out_shape = input->tensor_shape(); |
| 66 | // Validate output_shape only if not using auto_init |
| 67 | convert_negative_axis(axis_local, input_dims); |
| 68 | |
| 69 | // Suppress warning produced by a compiler bug in GCC |
| 70 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104165 |
| 71 | #pragma GCC diagnostic push |
| 72 | #pragma GCC diagnostic ignored "-Warray-bounds" |
| 73 | std::sort(axis_local.begin(), axis_local.begin() + reduction_ops); |
| 74 | #pragma GCC diagnostic pop |
| 75 | |
| 76 | for (unsigned int i = 0; i < reduction_ops; ++i) |
| 77 | { |
| 78 | ARM_COMPUTE_RETURN_ERROR_ON(axis_local[i] > 3); |
| 79 | ARM_COMPUTE_RETURN_ERROR_ON(static_cast<unsigned int>(axis_local[i]) > input->num_dimensions() - 1); |
| 80 | if (output->total_size() > 0 && keep_dims) |
| 81 | { |
| 82 | ARM_COMPUTE_RETURN_ERROR_ON(output->dimension(axis_local[i]) != 1); |
| 83 | } |
| 84 | if (keep_dims) |
| 85 | { |
| 86 | out_shape.set(axis_local[i], 1); |
| 87 | } |
| 88 | else |
| 89 | { |
| 90 | ARM_COMPUTE_RETURN_ERROR_ON(i > static_cast<unsigned int>(axis_local[i])); |
| 91 | const unsigned int remove_index = axis_local[i] - i; |
| 92 | ARM_COMPUTE_RETURN_ERROR_ON(remove_index >= out_shape.num_dimensions()); |
| 93 | out_shape.remove_dimension(remove_index, false); |
| 94 | } |
| 95 | } |
| 96 | const TensorInfo out_info = input->clone()->set_tensor_shape(out_shape); |
no test coverage detected