ethosu: Support element wise op with constant IFM buffer

Element wise operations can have a constant data buffer.

Re-order things a bit to group all the IFM2 setup together.

Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39975>
This commit is contained in:
Rob Herring (Arm) 2026-04-14 09:39:39 -05:00 committed by Marge Bot
parent 1f579379c1
commit d55a574898
3 changed files with 25 additions and 12 deletions

View file

@ -551,7 +551,7 @@ emit_ifm2(struct ethosu_subgraph *subgraph, struct ethosu_operation *operation,
EMIT1(NPU_SET_OP_SCALAR, 0, operation->ifm2.scalar);
}
} else {
EMIT0(NPU_SET_IFM2_REGION, IO_REGION);
EMIT0(NPU_SET_IFM2_REGION, operation->ifm2.region);
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);

View file

@ -390,22 +390,34 @@ ethosu_lower_eltwise(struct ethosu_subgraph *subgraph,
set_feature_map(subgraph, poperation->input_tensors[ifm2_idx], &operation->ifm2);
if (poperation->input_tensors[ifm2_idx]->data &&
operation->ifm2.shape.width == 1 &&
operation->ifm2.shape.height == 1 &&
operation->ifm2.shape.depth == 1) {
operation->ifm2.scalar = *poperation->input_tensors[ifm2_idx]->data;
if (poperation->input_tensors[ifm2_idx]->data) {
if (operation->ifm2.shape.width == 1 &&
operation->ifm2.shape.height == 1 &&
operation->ifm2.shape.depth == 1)
operation->ifm2.scalar = *poperation->input_tensors[ifm2_idx]->data;
else {
size_t size = operation->ifm2.shape.height * operation->ifm2.shape.width *
operation->ifm2.shape.depth * poperation->input_tensors[ifm2_idx]->type_size;
operation->ifm2.region = COEFS_REGION;
operation->ifm2.tiles.addresses[0] = subgraph->coefs_used;
subgraph->coefs_used += size;
subgraph->coefs = realloc(subgraph->coefs, subgraph->coefs_used);
memcpy(subgraph->coefs + operation->ifm2.tiles.addresses[0],
poperation->input_tensors[ifm2_idx]->data, size);
}
} else {
operation->ifm2.region = IO_REGION;
operation->ifm2.tiles.addresses[0] = ethosu_allocate_feature_map(subgraph, operation->ifm2.tensor);
}
if (poperation->add.relu)
operation->eltwise.activation_min = operation->ofm.zero_point;
allocate_feature_maps(subgraph, operation);
operation->ifm2.tiles.addresses[0] = ethosu_allocate_feature_map(subgraph, operation->ifm2.tensor);
operation->ifm2.tiles.height_0 = operation->ifm2.shape.height;
operation->ifm2.tiles.height_1 = operation->ifm2.shape.height;
operation->ifm2.tiles.width_0 = operation->ifm2.shape.width;
if (poperation->add.relu)
operation->eltwise.activation_min = operation->ofm.zero_point;
allocate_feature_maps(subgraph, operation);
ethosu_sched_operation(subgraph, operation);
}

View file

@ -84,6 +84,7 @@ struct ethosu_feature_map {
unsigned zero_point;
float scale;
uint16_t scalar;
uint8_t region;
};
struct ethosu_kernel {