| 60 | const float32x4_t positive_round_f32q = vdupq_n_f32(0.5f); |
| 61 | |
| 62 | inline Status validate_arguments(const ITensorInfo *src1, |
| 63 | const ITensorInfo *src2, |
| 64 | const ITensorInfo *dst, |
| 65 | float scale, |
| 66 | ConvertPolicy overflow_policy, |
| 67 | RoundingPolicy rounding_policy) |
| 68 | { |
| 69 | ARM_COMPUTE_UNUSED(overflow_policy); |
| 70 | ARM_COMPUTE_UNUSED(rounding_policy); |
| 71 | |
| 72 | ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(src1); |
| 73 | ARM_COMPUTE_RETURN_ERROR_ON_SIZE_UNSUPPORTED(src1, src2); |
| 74 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(src1, 1, DataType::U8, DataType::QASYMM8, |
| 75 | DataType::QASYMM8_SIGNED, DataType::S16, DataType::S32, |
| 76 | DataType::QSYMM16, DataType::F16, DataType::F32); |
| 77 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(src2, 1, DataType::U8, DataType::QASYMM8, |
| 78 | DataType::QASYMM8_SIGNED, DataType::S16, DataType::S32, |
| 79 | DataType::QSYMM16, DataType::F16, DataType::F32); |
| 80 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(dst, 1, DataType::U8, DataType::QASYMM8, |
| 81 | DataType::QASYMM8_SIGNED, DataType::S16, DataType::QSYMM16, |
| 82 | DataType::S32, DataType::F16, DataType::F32); |
| 83 | if (is_data_type_quantized(src1->data_type()) || is_data_type_quantized(src2->data_type())) |
| 84 | { |
| 85 | ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(src1, src2); |
| 86 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(overflow_policy == ConvertPolicy::WRAP, |
| 87 | "ConvertPolicy cannot be WRAP if datatype is quantized"); |
| 88 | } |
| 89 | |
| 90 | const TensorShape &out_shape = TensorShape::broadcast_shape(src1->tensor_shape(), src2->tensor_shape()); |
| 91 | if (dst->total_size() > 0) |
| 92 | { |
| 93 | ARM_COMPUTE_RETURN_ERROR_ON_SIZE_UNSUPPORTED(dst); |
| 94 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(detail::have_different_dimensions(out_shape, dst->tensor_shape(), 0), |
| 95 | "Wrong shape for dst"); |
| 96 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(out_shape.total_size() == 0, "Inputs are not broadcast compatible"); |
| 97 | // clang-format off |
| 98 | ARM_COMPUTE_RETURN_ERROR_ON_MSG( |
| 99 | !(src1->data_type() == src2->data_type() && src2->data_type() == dst->data_type()) && |
| 100 | !(src1->data_type() == DataType::U8 && src2->data_type() == DataType::U8 && dst->data_type() == DataType::S16) && |
| 101 | !(src1->data_type() == DataType::U8 && src2->data_type() == DataType::S16 && dst->data_type() == DataType::S16) && |
| 102 | !(src1->data_type() == DataType::S16 && src2->data_type() == DataType::U8 && dst->data_type() == DataType::S16) && |
| 103 | !(src1->data_type() == DataType::S16 && src2->data_type() == DataType::U8 && dst->data_type() == DataType::S16) && |
| 104 | !(src1->data_type() == DataType::QSYMM16 && src2->data_type() == DataType::QSYMM16 && dst->data_type() == DataType::S32) |
| 105 | , "Invalid data type combination"); |
| 106 | // clang-format on |
| 107 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(src1->data_type() == DataType::S16 && dst->data_type() == DataType::S32 && |
| 108 | scale != 1.f, |
| 109 | "Unsupported scale for QSYMM16 inputs and S32 dst"); |
| 110 | } |
| 111 | else |
| 112 | { |
| 113 | const auto dst_info = TensorInfo(out_shape, 1, dst->data_type()); |
| 114 | ARM_COMPUTE_RETURN_ERROR_ON_SIZE_UNSUPPORTED(&dst_info); |
| 115 | } |
| 116 | |
| 117 | if (std::abs(scale - scale255_constant) < 0.00001f) |
| 118 | { |
| 119 | ARM_COMPUTE_RETURN_ERROR_ON(rounding_policy != RoundingPolicy::TO_NEAREST_UP && |
no test coverage detected