ethosu: Add scalar ADD support

An input tensor can contain a single scalar value to add to the IFM.

Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40525>
This commit is contained in:
Rob Herring (Arm) 2026-03-19 13:21:53 -05:00 committed by Marge Bot
parent 5606fd1ea6
commit d962160e95
4 changed files with 20 additions and 7 deletions

View file

@ -372,14 +372,16 @@ emit_ifm2(struct ethosu_subgraph *subgraph, struct ethosu_operation *operation,
emit_addresses(subgraph, &operation->ifm2, NPU_SET_IFM2_BASE0, NPU_SET_IFM2_BASE1, NPU_SET_IFM2_BASE2, NPU_SET_IFM2_BASE3);
emit_tiles(subgraph, &operation->ifm2, NPU_SET_IFM2_HEIGHT0_M1, NPU_SET_IFM2_HEIGHT1_M1, NPU_SET_IFM2_WIDTH0_M1);
emit_strides(subgraph, &operation->ifm2, NPU_SET_IFM2_STRIDE_C, NPU_SET_IFM2_STRIDE_Y, NPU_SET_IFM2_STRIDE_X);
} else {
EMIT0(NPU_SET_IFM2_SCALAR, operation->ifm2.scalar);
}
EMIT0(NPU_SET_IFM2_ZERO_POINT, operation->ifm2.zero_point);
}
static void
emit_ifm2_broadcast(struct ethosu_subgraph *subgraph, struct ethosu_operation *operation)
emit_ifm2_broadcast(struct ethosu_subgraph *subgraph, struct ethosu_operation *operation, bool has_scalar)
{
unsigned ifm2_broadcast = 0;
unsigned ifm2_broadcast = has_scalar ? NPU_SET_IFM2_BROADCAST_BROADCAST_SCALAR(1) : 0;
EMIT0(NPU_SET_IFM2_BROADCAST, ifm2_broadcast);
}
@ -433,7 +435,7 @@ advanced_elementwise_add_sub_scale(
static void
emit_eltwise(struct ethosu_subgraph *subgraph, struct ethosu_operation *operation)
{
bool has_scalar = false;
bool has_scalar = operation->ifm2.scalar != 0;
enum ethosu_op_to_scale op_to_scale;
op_to_scale = advanced_elementwise_add_sub_scale(
@ -446,7 +448,7 @@ emit_eltwise(struct ethosu_subgraph *subgraph, struct ethosu_operation *operatio
emit_ifm2(subgraph, operation, has_scalar);
emit_ifm_precision(subgraph, &operation->ifm2, OP_NONE, NPU_SET_IFM2_PRECISION);
emit_ifm2_broadcast(subgraph, operation);
emit_ifm2_broadcast(subgraph, operation, has_scalar);
}
static void

View file

@ -3,6 +3,8 @@
* SPDX-License-Identifier: MIT
*/
#include "util/u_inlines.h"
#include "ethosu_device.h"
#include "ethosu_lower.h"
#include "ethosu_coefs.h"
@ -337,6 +339,17 @@ ethosu_lower_add(struct ethosu_subgraph *subgraph,
operation->ifm2.scale = poperation->input_tensors[1]->scale;
operation->ifm2.is_signed = poperation->input_tensors[1]->is_signed;
operation->ifm2.precision = log2(poperation->input_tensors[1]->type_size);
if (operation->ifm2.shape.width == 1 &&
operation->ifm2.shape.height == 1 &&
operation->ifm2.shape.depth == 1) {
struct pipe_transfer *transfer_in;
uint8_t *scalar = pipe_buffer_map(subgraph->base.context, poperation->input_tensors[1]->resource,
PIPE_MAP_READ, &transfer_in);
operation->ifm2.scalar = *scalar;
pipe_buffer_unmap(subgraph->base.context, transfer_in);
}
operation->kernel.height = 1;
operation->kernel.width = 1;

View file

@ -161,9 +161,6 @@ ethosu_ml_operation_supported(struct pipe_context *pcontext,
break;
}
case PIPE_ML_OPERATION_TYPE_ADD:
supported = operation->input_tensors[0]->resource == NULL &&
operation->input_tensors[1]->resource == NULL;
break;
case PIPE_ML_OPERATION_TYPE_POOLING:
case PIPE_ML_OPERATION_TYPE_STRIDED_SLICE:
case PIPE_ML_OPERATION_TYPE_PAD:

View file

@ -77,6 +77,7 @@ struct ethosu_feature_map {
struct ethosu_tile_box tiles;
unsigned zero_point;
float scale;
uint16_t scalar;
};
struct ethosu_kernel {