ethosu: Add support for 16-bit tensors

Ethos-U can support 16-bit tensors. So far the driver just assumed 8-bit
tensors.

There's a few cases where 32-bit tensors are supported, but exactly what
those are hasn't been determined, so just reject them for now.

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 17:35:58 -05:00 committed by Marge Bot
parent 7613788f06
commit 5606fd1ea6
4 changed files with 16 additions and 1 deletions

View file

@ -133,6 +133,8 @@ emit_ifm_precision(struct ethosu_subgraph *subgraph,
if (tensor->layout == ETHOSU_LAYOUT_NHCWB16)
prec |= NPU_SET_IFM_PRECISION_FORMAT(1);
prec |= NPU_SET_IFM_PRECISION_PRECISION(feature_map->precision);
if (feature_map->is_signed)
prec |= NPU_SET_IFM_PRECISION_ACTIVATION(1); // signed activation
@ -179,6 +181,8 @@ emit_ofm_precision(struct ethosu_subgraph *subgraph, struct ethosu_operation *op
if (tensor->layout == ETHOSU_LAYOUT_NHCWB16)
prec |= NPU_SET_OFM_PRECISION_FORMAT(1);
prec |= NPU_SET_OFM_PRECISION_PRECISION(operation->ofm.precision);
if (operation->ofm.is_signed)
prec |= NPU_SET_OFM_PRECISION_ACTIVATION(1);

View file

@ -62,6 +62,7 @@ set_feature_maps(struct pipe_tensor *input_tensor,
operation->ifm.zero_point = input_tensor->zero_point;
operation->ifm.scale = input_tensor->scale;
operation->ifm.is_signed = input_tensor->is_signed;
operation->ifm.precision = log2(input_tensor->type_size);
operation->ofm.tensor_idx = output_tensor->index;
operation->ofm.shape.height = output_tensor->dims[1];
@ -70,6 +71,7 @@ set_feature_maps(struct pipe_tensor *input_tensor,
operation->ofm.zero_point = output_tensor->zero_point;
operation->ofm.scale = output_tensor->scale;
operation->ofm.is_signed = output_tensor->is_signed;
operation->ofm.precision = log2(output_tensor->type_size);
}
static const struct pipe_ml_operation *
@ -334,6 +336,7 @@ ethosu_lower_add(struct ethosu_subgraph *subgraph,
operation->ifm2.zero_point = poperation->input_tensors[1]->zero_point;
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);
operation->kernel.height = 1;
operation->kernel.width = 1;
@ -480,4 +483,4 @@ ethosu_lower_graph(struct ethosu_subgraph *subgraph,
UNREACHABLE("Unsupported ML operation type");
}
}
}
}

View file

@ -57,6 +57,7 @@ ethosu_register_tensor(struct ethosu_subgraph *subgraph,
new_tensor.shape.width = ptensor->dims[2];
new_tensor.shape.depth = ptensor->dims[3];
new_tensor.layout = ETHOSU_LAYOUT_NHWC;
new_tensor.type_size = ptensor->type_size;
util_dynarray_append(&subgraph->tensors, new_tensor);
}
@ -74,6 +75,7 @@ ethosu_allocate_feature_map(struct ethosu_subgraph *subgraph, struct ethosu_feat
assert(0 && "Unsupported layout");
size = 0; // This should never happen
}
size *= tensor->type_size;
assert(tensor);
@ -143,6 +145,10 @@ ethosu_ml_operation_supported(struct pipe_context *pcontext,
{
bool supported = false;
if (operation->input_tensors[0]->type_size == 4 ||
operation->output_tensors[0]->type_size == 4)
return false;
switch (operation->type) {
case PIPE_ML_OPERATION_TYPE_CONVOLUTION: {
/*

View file

@ -73,6 +73,7 @@ struct ethosu_feature_map {
unsigned tensor_idx;
struct ethosu_block shape;
bool is_signed;
uint8_t precision;
struct ethosu_tile_box tiles;
unsigned zero_point;
float scale;
@ -176,6 +177,7 @@ struct ethosu_tensor {
unsigned index;
unsigned offset;
unsigned size;
uint8_t type_size;
struct ethosu_block shape;
enum ethosu_layout layout;
};