ethosu: fix RESIZE upscale mode

The upscale field was a bool which happened to work since true maps
to 1 which is NEAREST in the hardware. Change from bool to an enum
ethosu_upscale_mode so the intent is clear and we dont rely on the
bool-to-int mapping.

Also add a check in operation_supported so RESIZE only accepts 2x
upscaling since thats what the NPU can do with IFM_UPSCALE. Other
sizes fall back to CPU.

Keep the original zero_points from tensors in RESIZE and STRIDED_SLICE
instead of forcing them to 0 since the requantization needs them.

Fixes the RESIZE_NEAREST_NEIGHBOR operations in EfficientDet-Lite
models that use BiFPN with 2x nearest neighbor upsampling.

Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39594>
This commit is contained in:
Anders Roxell 2026-01-19 11:47:39 +01:00 committed by Marge Bot
parent e27ba5b437
commit 69d3f080be
3 changed files with 19 additions and 7 deletions

View file

@ -3,6 +3,7 @@
* SPDX-License-Identifier: MIT
*/
#include "ethosu_device.h"
#include "ethosu_lower.h"
#include "ethosu_coefs.h"
#include "ethosu_sched.h"
@ -261,8 +262,6 @@ ethosu_lower_resize(struct ethosu_subgraph *subgraph,
operation->pooling.avg = true;
set_feature_maps(poperation->input_tensors[0], poperation->output_tensors[0], operation);
operation->ifm.zero_point = 0;
operation->ofm.zero_point = 0;
operation->kernel.height = 1;
operation->kernel.width = 1;
@ -271,7 +270,7 @@ ethosu_lower_resize(struct ethosu_subgraph *subgraph,
operation->kernel.dilation_y = 1;
operation->kernel.dilation_x = 1;
operation->upscale = true;
operation->upscale = ETHOSU_UPSCALE_NEAREST;
allocate_feature_maps(subgraph, operation);
ethosu_sched_operation(subgraph, operation);
@ -287,8 +286,6 @@ ethosu_lower_strided_slice(struct ethosu_subgraph *subgraph,
set_feature_maps(poperation->input_tensors[0], poperation->output_tensors[0], operation);
operation->ifm.shape = operation->ofm.shape;
operation->ifm.zero_point = 0;
operation->ofm.zero_point = 0;
operation->kernel.height = 1;
operation->kernel.width = 1;

View file

@ -161,9 +161,17 @@ ethosu_ml_operation_supported(struct pipe_context *pcontext,
case PIPE_ML_OPERATION_TYPE_POOLING:
case PIPE_ML_OPERATION_TYPE_STRIDED_SLICE:
case PIPE_ML_OPERATION_TYPE_PAD:
case PIPE_ML_OPERATION_TYPE_RESIZE:
supported = true;
break;
case PIPE_ML_OPERATION_TYPE_RESIZE: {
/* NPU only supports 2x nearest neighbor upscaling */
struct pipe_tensor *input = operation->input_tensors[0];
struct pipe_tensor *output = operation->output_tensors[0];
bool is_2x_height = (output->dims[1] == 2 * input->dims[1]);
bool is_2x_width = (output->dims[2] == 2 * input->dims[2]);
supported = is_2x_height && is_2x_width;
break;
}
case PIPE_ML_OPERATION_TYPE_CONCATENATION:
supported = operation->conc.axis == 3 ||
operation->conc.axis == -1;

View file

@ -62,6 +62,13 @@ enum ethosu_rounding_mode {
ETHOSU_ROUNDING_TRUNCATE,
ETHOSU_ROUNDING_NATURAL,
};
enum ethosu_upscale_mode {
ETHOSU_UPSCALE_NONE = 0,
ETHOSU_UPSCALE_NEAREST = 1,
ETHOSU_UPSCALE_ZEROS = 2,
};
struct ethosu_feature_map {
unsigned tensor_idx;
struct ethosu_block shape;
@ -158,7 +165,7 @@ struct ethosu_operation {
struct ethosu_kernel kernel;
struct ethosu_padding pad;
bool upscale;
enum ethosu_upscale_mode upscale;
enum ethosu_rounding_mode round_mode;
struct ethosu_address_range read_accesses[MAX_MEMORY_ACCESSES];