| 84 | REGISTER_QASYMM8_SIGNED_NEON(arm_compute::cpu::topkv_qasymm8_signed_neon)}}; |
| 85 | |
| 86 | Status |
| 87 | validate_arguments(const ITensorInfo &predictions, const ITensorInfo &targets, const ITensorInfo &dst, uint32_t k) |
| 88 | { |
| 89 | ARM_COMPUTE_RETURN_ERROR_ON_SIZE_UNSUPPORTED(&predictions, &targets); |
| 90 | ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(&predictions); |
| 91 | |
| 92 | // predictions (logical shape [C, N], where N defaults to 1 if dimension 1 is absent) |
| 93 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&predictions, ITensorInfo::one_channel, DataType::QASYMM8, |
| 94 | DataType::QASYMM8_SIGNED, DataType::S32, DataType::F16, |
| 95 | DataType::F32); |
| 96 | |
| 97 | // targets (class indices) |
| 98 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&targets, ITensorInfo::one_channel, DataType::U32); |
| 99 | |
| 100 | const unsigned int C = predictions.tensor_shape()[0]; // classes |
| 101 | const unsigned int N = predictions.tensor_shape()[1]; // batch (defaults to 1 if not present) |
| 102 | |
| 103 | // k constraints |
| 104 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(k == 0, "k must be > 0"); |
| 105 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(C == 0, "predictions classes dimension must be > 0"); |
| 106 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(N == 0, "predictions batch dimension must be > 0"); |
| 107 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(k > C, "k must be <= number of classes (C)"); |
| 108 | |
| 109 | // targets must match batch |
| 110 | // targets is expected to contain N elements (shape [N]) |
| 111 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(targets.tensor_shape()[0] != N, |
| 112 | "targets dimension must match predictions batch dimension (N)"); |
| 113 | |
| 114 | ARM_COMPUTE_RETURN_ERROR_ON(predictions.num_dimensions() > 2); |
| 115 | ARM_COMPUTE_RETURN_ERROR_ON(targets.num_dimensions() > 1); |
| 116 | |
| 117 | // Output is one byte per batch element: shape [N] |
| 118 | const TensorShape out_shape(N); |
| 119 | |
| 120 | // If dst is already configured, validate it |
| 121 | if (dst.total_size() != 0) |
| 122 | { |
| 123 | ARM_COMPUTE_RETURN_ERROR_ON_SIZE_UNSUPPORTED(&dst); |
| 124 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&dst, ITensorInfo::one_channel, DataType::U8); |
| 125 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(dst.tensor_shape() != out_shape, "dst shape must be [N]"); |
| 126 | } |
| 127 | else |
| 128 | { |
| 129 | const auto dst_info = TensorInfo(out_shape, ITensorInfo::one_channel, DataType::U8); |
| 130 | ARM_COMPUTE_RETURN_ERROR_ON_SIZE_UNSUPPORTED(&dst_info); |
| 131 | } |
| 132 | |
| 133 | const auto uk = CpuTopKVKernel::get_implementation<CpuTopKVKernelDataTypeISASelectorData>( |
| 134 | CpuTopKVKernelDataTypeISASelectorData{predictions.data_type(), CPUInfo::get().get_isa()}); |
| 135 | |
| 136 | ARM_COMPUTE_RETURN_ERROR_ON(uk == nullptr || uk->ukernel == nullptr); |
| 137 | |
| 138 | return Status{}; |
| 139 | } |
| 140 | |
| 141 | } // namespace |
| 142 |
no test coverage detected