diff --git a/src/gallium/drivers/etnaviv/etnaviv_ml.c b/src/gallium/drivers/etnaviv/etnaviv_ml.c index 4813c2d0e98..757f7f02c6d 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_ml.c +++ b/src/gallium/drivers/etnaviv/etnaviv_ml.c @@ -5,7 +5,6 @@ #include #include -#include "drm/etnaviv_drmif.h" #include #include "util/u_inlines.h" @@ -38,6 +37,9 @@ etna_ml_allocate_tensor(struct etna_ml_subgraph *subgraph) unsigned *offsets = util_dynarray_grow(&subgraph->offsets, unsigned, 1); offsets[0] = 0; + unsigned *sizes = util_dynarray_grow(&subgraph->sizes, unsigned, 1); + sizes[0] = 0; + return util_dynarray_num_elements(&subgraph->tensors, struct pipe_resource *) - 1; } @@ -46,6 +48,7 @@ etna_ml_create_tensor(struct etna_ml_subgraph *subgraph, unsigned idx, unsigned { struct pipe_context *context = subgraph->base.context; struct pipe_resource **tensors = util_dynarray_begin(&subgraph->tensors); + unsigned *sizes = util_dynarray_begin(&subgraph->sizes); assert(idx < util_dynarray_num_elements(&subgraph->tensors, struct pipe_resource *)); @@ -58,10 +61,23 @@ etna_ml_create_tensor(struct etna_ml_subgraph *subgraph, unsigned idx, unsigned res = etna_ml_create_resource(context, size); tensors[idx] = res; + sizes[idx] = size; ML_DBG("created resource %p for tensor %d with size %d\n", res, idx, size); } +static void +etna_ml_destroy_tensor(struct etna_ml_subgraph *subgraph, unsigned idx) +{ + struct pipe_resource **tensors = util_dynarray_begin(&subgraph->tensors); + unsigned *offsets = util_dynarray_begin(&subgraph->offsets); + unsigned *sizes = util_dynarray_begin(&subgraph->sizes); + + pipe_resource_reference(&tensors[idx], NULL); + offsets[idx] = 0; + sizes[idx] = 0; +} + struct etna_bo * etna_ml_create_bo(struct pipe_context *pctx, size_t size) { @@ -104,7 +120,7 @@ needs_reshuffle(struct etna_ml_subgraph *subgraph, const struct pipe_ml_operatio unsigned nn_core_version = ctx->screen->specs.nn_core_version; bool has_stride = poperation->conv.stride_x > 1 || poperation->conv.stride_y > 1; bool pointwise = poperation->conv.pointwise; - unsigned input_width = poperation->input_tensor->dims[1]; + unsigned input_width = poperation->input_tensors[0]->dims[1]; if (!has_stride) return false; @@ -112,7 +128,7 @@ needs_reshuffle(struct etna_ml_subgraph *subgraph, const struct pipe_ml_operatio if (nn_core_version < 8) return !(poperation->conv.depthwise && (input_width > 5 || input_width < 3)) && !pointwise; else { - unsigned input_channels = poperation->input_tensor->dims[3]; + unsigned input_channels = poperation->input_tensors[0]->dims[3]; if (poperation->conv.depthwise) return false; @@ -127,16 +143,86 @@ needs_reshuffle(struct etna_ml_subgraph *subgraph, const struct pipe_ml_operatio } } +static const struct pipe_ml_operation * +etna_ml_find_producer(const struct pipe_ml_operation *poperations, + unsigned count, + unsigned tensor_idx) +{ + for (unsigned i = 0; i < count; i++) { + const struct pipe_ml_operation *poperation = &poperations[i]; + + for (unsigned j = 0; j < poperation->output_count; j++) + if (poperation->output_tensors[j]->index == tensor_idx) + return poperation; + } + + return NULL; +} + +static const struct pipe_ml_operation * +etna_ml_find_consumer(const struct pipe_ml_operation *poperations, + unsigned count, + unsigned tensor_idx) +{ + for (unsigned i = 0; i < count; i++) { + const struct pipe_ml_operation *poperation = &poperations[i]; + + for (unsigned j = 0; j < poperation->input_count; j++) + if (poperation->input_tensors[j]->index == tensor_idx) + return poperation; + } + + return NULL; +} + +static bool +needs_transpose(const struct pipe_ml_operation *poperations, + unsigned count, + const struct pipe_ml_operation *poperation) +{ + const struct pipe_ml_operation *producer; + + if (poperation->input_tensors[0]->dims[3] == 1) + return false; + + producer = etna_ml_find_producer(poperations, count, poperation->input_tensors[0]->index); + if (!producer) + return true; + + return false; +} + +static bool +needs_detranspose(const struct pipe_ml_operation *poperations, + unsigned count, + const struct pipe_ml_operation *poperation) +{ + const struct pipe_ml_operation *consumer; + + if (poperation->output_tensors[0]->dims[3] == 1) + return false; + + /* TODO: Support multiple consumers */ + consumer = etna_ml_find_consumer(poperations, count, poperation->output_tensors[0]->index); + if (!consumer) + return true; + + return false; +} + static void reference_tensor_with_offset(struct etna_ml_subgraph *subgraph, unsigned src_tensor, unsigned dst_tensor, - unsigned offset) + unsigned offset, + unsigned size) { struct pipe_resource **tensors = util_dynarray_begin(&subgraph->tensors); unsigned *offsets = util_dynarray_begin(&subgraph->offsets); + unsigned *sizes = util_dynarray_begin(&subgraph->sizes); pipe_resource_reference(&tensors[dst_tensor], tensors[src_tensor]); offsets[dst_tensor] = offset; + sizes[dst_tensor] = size; } static void @@ -153,11 +239,11 @@ dump_graph(struct list_head *etna_operations) switch(operation->type) { case ETNA_JOB_TYPE_TP: ML_DBG("%3d %-4s %3d %3d", - i, "TP", operation->input_tensor, operation->output_tensor); + i, "TP", operation->input_tensors[0], operation->output_tensor); break; case ETNA_JOB_TYPE_NN: ML_DBG("%3d %-4s %3d %3d in2: %3d", - i, "NN", operation->input_tensor, operation->output_tensor, operation->add_input_tensor); + i, "NN", operation->input_tensors[0], operation->output_tensor, operation->input_tensors[1]); break; } ML_DBG("\n"); @@ -177,23 +263,51 @@ lower_operations(struct etna_ml_subgraph *subgraph, switch(poperation->type) { case PIPE_ML_OPERATION_TYPE_CONVOLUTION: { - unsigned input_tensor = poperation->input_tensor->index; - if (needs_reshuffle(subgraph, poperation)) { + unsigned input_tensor = poperation->input_tensors[0]->index; + + if (needs_transpose(poperations, count, poperation)) { + ML_DBG("Adding transpose for convolution operation.\n"); struct etna_operation *operation = calloc(1, sizeof(*operation)); - etna_ml_lower_reshuffle(subgraph, poperation, operation, &input_tensor); + etna_ml_lower_transpose(subgraph, poperation, operation, &input_tensor); list_addtail(&operation->link, etna_operations); } + if (needs_reshuffle(subgraph, poperation)) { + ML_DBG("Adding reshuffle for convolution operation.\n"); + struct etna_operation *operation = calloc(1, sizeof(*operation)); + unsigned temp = 0; + etna_ml_lower_reshuffle(subgraph, poperation, operation, &temp); + operation->input_tensors[0] = input_tensor; + input_tensor = temp; + list_addtail(&operation->link, etna_operations); + } + + ML_DBG("Adding convolution.\n"); struct etna_operation *operation = calloc(1, sizeof(*operation)); etna_ml_lower_convolution(subgraph, poperation, operation); - operation->input_tensor = input_tensor; + operation->input_tensors[0] = input_tensor; list_addtail(&operation->link, etna_operations); + + if (needs_detranspose(poperations, count, poperation)) { + ML_DBG("Adding detranspose for convolution operation.\n"); + struct etna_operation *detranspose = calloc(1, sizeof(*operation)); + etna_ml_lower_detranspose(subgraph, operation, detranspose); + operation->output_tensor = detranspose->input_tensors[0]; + list_addtail(&detranspose->link, etna_operations); + } break; } case PIPE_ML_OPERATION_TYPE_ADD: { struct etna_operation *operation = calloc(1, sizeof(*operation)); etna_ml_lower_add(subgraph, poperation, operation); list_addtail(&operation->link, etna_operations); + + if (needs_detranspose(poperations, count, poperation)) { + struct etna_operation *detranspose = calloc(1, sizeof(*operation)); + etna_ml_lower_detranspose(subgraph, operation, detranspose); + operation->output_tensor = detranspose->input_tensors[0]; + list_addtail(&detranspose->link, etna_operations); + } break; } default: @@ -201,47 +315,16 @@ lower_operations(struct etna_ml_subgraph *subgraph, } } - /* TODO: Support graphs with more than one input */ - if (poperations[0].input_tensor->dims[3] > 1) { - struct etna_operation *operation = calloc(1, sizeof(*operation)); - unsigned input_tensor = poperations[0].input_tensor->index; - unsigned output_tensor; - etna_ml_lower_transpose(subgraph, &poperations[0], operation, &output_tensor); - list_for_each_entry(struct etna_operation, operation, etna_operations, link) { - if (operation->input_tensor == input_tensor) - operation->input_tensor = output_tensor; - if (operation->type == ETNA_JOB_TYPE_NN && operation->addition) { - if (operation->add_input_tensor == input_tensor) - operation->add_input_tensor = output_tensor; - } - } - list_add(&operation->link, etna_operations); - } - list_for_each_entry(struct etna_operation, operation, etna_operations, link) { - etna_ml_create_tensor(subgraph, operation->input_tensor, operation->input_tensor_size); + etna_ml_create_tensor(subgraph, operation->input_tensors[0], operation->input_tensor_size); - if (operation->type == ETNA_JOB_TYPE_NN && operation->addition) + for (int i = 1; i < operation->input_count; i++) reference_tensor_with_offset(subgraph, - operation->input_tensor, - operation->add_input_tensor, - operation->input_tensor_size / 2); - } + operation->input_tensors[0], + operation->input_tensors[i], + i * operation->input_tensor_size / operation->input_count, + operation->input_tensor_size / operation->input_count); - /* Detranspose any output tensors that aren't inputs to other operations - * and have output channels, these are the outputs of the graph. - */ - list_for_each_entry_safe(struct etna_operation, operation, etna_operations, link) { - struct pipe_resource *res = etna_ml_get_tensor(subgraph, operation->output_tensor); - if (res != NULL) - continue; - - if (operation->output_channels > 1) { - struct etna_operation *transpose_operation = calloc(1, sizeof(*operation)); - etna_ml_lower_detranspose(subgraph, operation, transpose_operation); - operation->output_tensor = transpose_operation->input_tensor; - list_add(&transpose_operation->link, &operation->link); - } } /* Create any output tensors that aren't inputs to other operations, these @@ -269,15 +352,19 @@ count_tensors(const struct pipe_ml_operation *poperations, for (unsigned i = 0; i < count; i++) { const struct pipe_ml_operation *poperation = &poperations[i]; - tensor_count = MAX2(tensor_count, poperation->input_tensor->index); - tensor_count = MAX2(tensor_count, poperation->output_tensor->index); + + for (unsigned j = 0; j < poperation->input_count; j++) + tensor_count = MAX2(tensor_count, poperation->input_tensors[j]->index); + + for (unsigned j = 0; j < poperation->output_count; j++) + tensor_count = MAX2(tensor_count, poperation->output_tensors[j]->index); + switch (poperation->type) { case PIPE_ML_OPERATION_TYPE_CONVOLUTION: tensor_count = MAX2(tensor_count, poperation->conv.weight_tensor->index); tensor_count = MAX2(tensor_count, poperation->conv.bias_tensor->index); break; case PIPE_ML_OPERATION_TYPE_ADD: - tensor_count = MAX2(tensor_count, poperation->add.input_tensor->index); break; default: unreachable("Unsupported ML operation type"); @@ -321,6 +408,11 @@ etna_ml_subgraph_create(struct pipe_context *pcontext, return NULL; memset(util_dynarray_begin(&subgraph->offsets), 0, subgraph->offsets.size); + util_dynarray_init(&subgraph->sizes, NULL); + if (!util_dynarray_resize(&subgraph->sizes, unsigned, tensor_count)) + return NULL; + memset(util_dynarray_begin(&subgraph->sizes), 0, subgraph->sizes.size); + lower_operations(subgraph, poperations, count, &operations); list_for_each_entry(struct etna_operation, operation, &operations, link) { @@ -419,11 +511,14 @@ close_batch(struct pipe_context *pctx) } void -etna_ml_subgraph_invoke(struct pipe_context *pctx, struct pipe_ml_subgraph *psubgraph, struct pipe_tensor *input) +etna_ml_subgraph_invoke(struct pipe_context *pctx, struct pipe_ml_subgraph *psubgraph, + unsigned inputs_count, unsigned input_idxs[], void *inputs[]) { struct etna_context *ctx = etna_context(pctx); unsigned tp_core_count = etna_ml_get_core_info(ctx)->tp_core_count; struct etna_ml_subgraph *subgraph = (struct etna_ml_subgraph *)(psubgraph); + unsigned *offsets = util_dynarray_begin(&subgraph->offsets); + unsigned *sizes = util_dynarray_begin(&subgraph->sizes); struct etna_cmd_stream *stream = ctx->stream; static bool is_initialized = false; @@ -444,22 +539,13 @@ etna_ml_subgraph_invoke(struct pipe_context *pctx, struct pipe_ml_subgraph *psub etna_cmd_stream_emit(stream, 0x0); } + for (int i = 0; i < inputs_count; i++) { + struct pipe_resource *res = etna_ml_get_tensor(subgraph, input_idxs[i]); + pipe_buffer_write(pctx, res, offsets[input_idxs[i]], sizes[input_idxs[i]], inputs[i]); + } + unsigned i = 0; util_dynarray_foreach(&subgraph->operations, struct etna_vip_instruction, operation) { - #if 0 - if (i == util_dynarray_num_elements(&subgraph->operations, struct etna_vip_instruction) - 1) { - /* TODO: This may be necessary when bypassing all-zero kernels */ - etna_bo_cpu_prep(etna_resource(operation->output)->bo, DRM_ETNA_PREP_WRITE); - uint8_t *dst_map = etna_bo_map(etna_resource(operation->output)->bo); - memset(dst_map, 0x77, etna_bo_size(etna_resource(operation->output)->bo)); - etna_bo_cpu_fini(etna_resource(operation->output)->bo); - } - #endif - - if (i == 0) { - unsigned size = input->dims[0] * input->dims[1] * input->dims[2] * input->dims[3]; - pipe_buffer_copy(pctx, operation->input, input->resource, 0, 0, size); - } if (DBG_ENABLED(ETNA_DBG_DUMP_SHADERS)) { switch (operation->type) { @@ -597,6 +683,7 @@ etna_ml_subgraph_destroy(struct pipe_context *context, struct pipe_ml_subgraph * } util_dynarray_fini(&subgraph->tensors); util_dynarray_fini(&subgraph->offsets); + util_dynarray_fini(&subgraph->sizes); free(subgraph); } diff --git a/src/gallium/drivers/etnaviv/etnaviv_ml.h b/src/gallium/drivers/etnaviv/etnaviv_ml.h index 48e40250fec..909df16a03c 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_ml.h +++ b/src/gallium/drivers/etnaviv/etnaviv_ml.h @@ -38,9 +38,10 @@ struct etna_ml_subgraph { struct util_dynarray operations; - /* Bother are indexed by tensor index */ + /* The three are indexed by tensor index */ struct util_dynarray tensors; /* Contains struct pipe_resource* */ struct util_dynarray offsets; /* These are integers */ + struct util_dynarray sizes; /* These are integers */ }; struct etna_vip_instruction { @@ -49,11 +50,14 @@ struct etna_vip_instruction { struct etna_bo *configs[MAX_CONFIG_BOS]; struct etna_bo *coefficients; struct pipe_resource *input; + unsigned input_offset; struct pipe_resource *output; + unsigned output_offset; struct etna_bo *kernel; }; +#define MAX_INPUTS 10 struct etna_operation { struct list_head link; @@ -68,9 +72,9 @@ struct etna_operation { unsigned stride; - unsigned input_tensor; + unsigned input_tensors[MAX_INPUTS]; + unsigned input_count; unsigned input_tensor_size; - unsigned add_input_tensor; unsigned input_width; unsigned input_height; unsigned input_channels; @@ -117,8 +121,8 @@ etna_ml_subgraph_create(struct pipe_context *context, unsigned count); void -etna_ml_subgraph_invoke(struct pipe_context *context, struct pipe_ml_subgraph *subgraph, - struct pipe_tensor *input); +etna_ml_subgraph_invoke(struct pipe_context *pctx, struct pipe_ml_subgraph *psubgraph, + unsigned inputs_count, unsigned input_idxs[], void *inputs[]); void etna_ml_subgraph_read_outputs(struct pipe_context *context, struct pipe_ml_subgraph *subgraph, diff --git a/src/gallium/drivers/etnaviv/etnaviv_ml_nn.c b/src/gallium/drivers/etnaviv/etnaviv_ml_nn.c index 7cb88f3fe76..7eb34b76f59 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_ml_nn.c +++ b/src/gallium/drivers/etnaviv/etnaviv_ml_nn.c @@ -268,7 +268,7 @@ transpose(struct etna_ml_subgraph *subgraph, struct etna_operation *operation) struct pipe_resource *output_res; uint8_t *output; unsigned output_channels = operation->output_channels; - unsigned input_channels = operation->input_channels; + unsigned input_channels; if (nn_core_version == 8 && operation->depthwise) input_channels = 1; @@ -392,8 +392,8 @@ calc_pooling_first_pixel(struct etna_ml_subgraph *subgraph, { struct pipe_context *context = subgraph->base.context; unsigned nn_core_version = etna_context(context)->screen->specs.nn_core_version; - unsigned input_width = poperation->input_tensor->dims[1]; - unsigned input_channels = poperation->input_tensor->dims[3]; + unsigned input_width = poperation->input_tensors[0]->dims[1]; + unsigned input_channels = poperation->input_tensors[0]->dims[3]; if (poperation->conv.stride_x == 1) return false; @@ -436,19 +436,20 @@ etna_ml_lower_convolution(struct etna_ml_subgraph *subgraph, operation->padding_same = poperation->conv.padding_same; operation->stride = poperation->conv.stride_x; - operation->input_tensor = poperation->input_tensor->index; - operation->input_width = poperation->input_tensor->dims[1]; - operation->input_height = poperation->input_tensor->dims[2]; - operation->input_channels = poperation->input_tensor->dims[3]; - operation->input_zero_point = poperation->input_tensor->zero_point; - operation->input_scale = poperation->input_tensor->scale; + operation->input_tensors[0] = poperation->input_tensors[0]->index; + operation->input_count = 1; + operation->input_width = poperation->input_tensors[0]->dims[1]; + operation->input_height = poperation->input_tensors[0]->dims[2]; + operation->input_channels = poperation->input_tensors[0]->dims[3]; + operation->input_zero_point = poperation->input_tensors[0]->zero_point; + operation->input_scale = poperation->input_tensors[0]->scale; - operation->output_tensor = poperation->output_tensor->index; - operation->output_width = poperation->output_tensor->dims[1]; - operation->output_height = poperation->output_tensor->dims[2]; - operation->output_channels = poperation->output_tensor->dims[3]; - operation->output_zero_point = poperation->output_tensor->zero_point; - operation->output_scale = poperation->output_tensor->scale; + operation->output_tensor = poperation->output_tensors[0]->index; + operation->output_width = poperation->output_tensors[0]->dims[1]; + operation->output_height = poperation->output_tensors[0]->dims[2]; + operation->output_channels = poperation->output_tensors[0]->dims[3]; + operation->output_zero_point = poperation->output_tensors[0]->zero_point; + operation->output_scale = poperation->output_tensors[0]->scale; pipe_resource_reference(&operation->weight_tensor, poperation->conv.weight_tensor->resource); operation->weight_width = poperation->conv.weight_tensor->dims[1]; @@ -534,40 +535,25 @@ etna_ml_lower_add(struct etna_ml_subgraph *subgraph, operation->padding_same = false; operation->stride = 1; - operation->input_tensor = poperation->input_tensor->index; - operation->add_input_tensor = poperation->add.input_tensor->index; - operation->input_width = poperation->input_tensor->dims[1]; - operation->input_height = poperation->input_tensor->dims[2]; - operation->input_channels = poperation->input_tensor->dims[3]; - operation->input_zero_point = poperation->input_tensor->zero_point; - operation->input_scale = poperation->input_tensor->scale; + operation->input_tensors[0] = poperation->input_tensors[0]->index; + operation->input_tensors[1] = poperation->input_tensors[1]->index; + operation->input_count = 2; + operation->input_width = poperation->input_tensors[0]->dims[1]; + operation->input_height = poperation->input_tensors[0]->dims[2]; + operation->input_channels = poperation->input_tensors[0]->dims[3]; + operation->input_zero_point = poperation->input_tensors[0]->zero_point; + operation->input_scale = poperation->input_tensors[0]->scale; operation->input_tensor_size = operation->input_width * operation->input_height * operation->input_channels * 2; - operation->output_tensor = poperation->output_tensor->index; - operation->output_width = poperation->output_tensor->dims[1]; - operation->output_height = poperation->output_tensor->dims[2]; - operation->output_channels = poperation->output_tensor->dims[3]; - operation->output_zero_point = poperation->output_tensor->zero_point; - operation->output_scale = poperation->output_tensor->scale; - - operation->weight_tensor = etna_ml_create_resource(context, 8); - operation->weight_width = 2; - operation->weight_height = 2; - operation->weight_zero_point = 0x0; - operation->weight_scale = compute_weight_scale_add(poperation->add.input_tensor->scale, poperation->input_tensor->scale); - operation->addition_offset = compute_addition_offset(poperation->add.input_tensor->scale, poperation->input_tensor->scale, operation->weight_scale); - - uint8_t *weight_map = map_resource(operation->weight_tensor); - weight_map[0] = compute_weight_add(poperation->add.input_tensor->scale, poperation->input_tensor->scale, operation->weight_scale); - - operation->bias_tensor = etna_ml_create_resource(context, 4); - int32_t *bias_map = map_resource(operation->bias_tensor); - bias_map[0] = compute_bias_add(poperation->add.input_tensor->scale, poperation->input_tensor->scale, - poperation->add.input_tensor->zero_point, poperation->input_tensor->zero_point, - operation->weight_scale); + operation->output_tensor = poperation->output_tensors[0]->index; + operation->output_width = poperation->output_tensors[0]->dims[1]; + operation->output_height = poperation->output_tensors[0]->dims[2]; + operation->output_channels = poperation->output_tensors[0]->dims[3]; + operation->output_zero_point = poperation->output_tensors[0]->zero_point; + operation->output_scale = poperation->output_tensors[0]->scale; } void @@ -681,8 +667,8 @@ create_nn_config(struct etna_ml_subgraph *subgraph, const struct etna_operation map->further7 = 0x0; map->further8 = 0x0; - struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensor); - unsigned offset = etna_ml_get_offset(subgraph, operation->input_tensor); + struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensors[0]); + unsigned offset = etna_ml_get_offset(subgraph, operation->input_tensors[0]); map->in_image_address = etna_bo_gpu_va(etna_resource(input)->bo) + offset; map->in_image_x_size = input_width; map->in_image_y_size = input_height; @@ -901,7 +887,7 @@ etna_ml_compile_operation_nn(struct etna_ml_subgraph *subgraph, const struct etn else instruction->coefficients = etna_ml_create_coeffs_v8(subgraph, operation, &coef_cache_size); - struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensor); + struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensors[0]); assert(input); pipe_resource_reference(&instruction->input, input); diff --git a/src/gallium/drivers/etnaviv/etnaviv_ml_tp.c b/src/gallium/drivers/etnaviv/etnaviv_ml_tp.c index df20bc96b40..c1a1d63c7d6 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_ml_tp.c +++ b/src/gallium/drivers/etnaviv/etnaviv_ml_tp.c @@ -262,7 +262,7 @@ create_transpose_config(struct etna_ml_subgraph *subgraph, const struct etna_ope map->in_tile_y_size = operation->input_height; map->in_tile_y_inc = operation->input_height; - struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensor); + struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensors[0]); map->in_image_base_address = etna_bo_gpu_va(etna_resource(input)->bo); struct pipe_resource *output = etna_ml_get_tensor(subgraph, operation->output_tensor); @@ -311,7 +311,7 @@ create_detranspose_config(struct etna_ml_subgraph *subgraph, const struct etna_o map->in_tile_y_size = 0x1; map->in_tile_y_inc = 0x1; - struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensor); + struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensors[0]); map->in_image_base_address = etna_bo_gpu_va(etna_resource(input)->bo); struct pipe_resource *output = etna_ml_get_tensor(subgraph, operation->output_tensor); @@ -461,8 +461,8 @@ create_reshuffle_config(struct etna_ml_subgraph *subgraph, const struct etna_ope map->in_tile_y_size = out_dims[1] * 2; map->in_tile_y_inc = out_dims[1] * 2; - struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensor); - unsigned offset = etna_ml_get_offset(subgraph, operation->input_tensor); + struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensors[0]); + unsigned offset = etna_ml_get_offset(subgraph, operation->input_tensors[0]); map->in_image_base_address = etna_bo_gpu_va(etna_resource(input)->bo) + offset; struct pipe_resource *output = etna_ml_get_tensor(subgraph, operation->output_tensor); @@ -544,23 +544,23 @@ etna_ml_lower_transpose(struct etna_ml_subgraph *subgraph, operation->type = ETNA_JOB_TYPE_TP; operation->tp_type = ETNA_ML_TP_TRANSPOSE; - operation->input_tensor = first_operation->input_tensor->index; - operation->input_width = first_operation->input_tensor->dims[1]; - operation->input_height = first_operation->input_tensor->dims[2]; - operation->input_channels = first_operation->input_tensor->dims[3]; - operation->input_zero_point = first_operation->input_tensor->zero_point; - operation->input_scale = first_operation->input_tensor->scale; + operation->input_tensors[0] = first_operation->input_tensors[0]->index; + operation->input_width = first_operation->input_tensors[0]->dims[1]; + operation->input_height = first_operation->input_tensors[0]->dims[2]; + operation->input_channels = first_operation->input_tensors[0]->dims[3]; + operation->input_zero_point = first_operation->input_tensors[0]->zero_point; + operation->input_scale = first_operation->input_tensors[0]->scale; operation->input_tensor_size = operation->input_width * operation->input_height * operation->input_channels; *output_tensor = etna_ml_allocate_tensor(subgraph); operation->output_tensor = *output_tensor; - operation->output_width = first_operation->input_tensor->dims[1]; - operation->output_height = first_operation->input_tensor->dims[2]; - operation->output_channels = first_operation->input_tensor->dims[3]; - operation->output_zero_point = first_operation->input_tensor->zero_point; - operation->output_scale = first_operation->input_tensor->scale; + operation->output_width = first_operation->input_tensors[0]->dims[1]; + operation->output_height = first_operation->input_tensors[0]->dims[2]; + operation->output_channels = first_operation->input_tensors[0]->dims[3]; + operation->output_zero_point = first_operation->input_tensors[0]->zero_point; + operation->output_scale = first_operation->input_tensors[0]->scale; } void @@ -571,7 +571,8 @@ etna_ml_lower_detranspose(struct etna_ml_subgraph *subgraph, operation->type = ETNA_JOB_TYPE_TP; operation->tp_type = ETNA_ML_TP_DETRANSPOSE; - operation->input_tensor = etna_ml_allocate_tensor(subgraph); + operation->input_tensors[0] = etna_ml_allocate_tensor(subgraph); + operation->input_count = 1; operation->input_width = convolution->output_width; operation->input_height = convolution->output_height; operation->input_channels = convolution->output_channels; @@ -600,12 +601,13 @@ etna_ml_lower_reshuffle(struct etna_ml_subgraph *subgraph, operation->stride = convolution->conv.stride_x; operation->padding_same = convolution->conv.padding_same; - operation->input_tensor = convolution->input_tensor->index; - operation->input_width = convolution->input_tensor->dims[1]; - operation->input_height = convolution->input_tensor->dims[2]; - operation->input_channels = convolution->input_tensor->dims[3]; - operation->input_zero_point = convolution->input_tensor->zero_point; - operation->input_scale = convolution->input_tensor->scale; + operation->input_tensors[0] = convolution->input_tensors[0]->index; + operation->input_count = 1; + operation->input_width = convolution->input_tensors[0]->dims[1]; + operation->input_height = convolution->input_tensors[0]->dims[2]; + operation->input_channels = convolution->input_tensors[0]->dims[3]; + operation->input_zero_point = convolution->input_tensors[0]->zero_point; + operation->input_scale = convolution->input_tensors[0]->scale; operation->input_tensor_size = operation->input_width * operation->input_height * operation->input_channels; @@ -615,8 +617,8 @@ etna_ml_lower_reshuffle(struct etna_ml_subgraph *subgraph, operation->output_width = DIV_ROUND_UP(operation->input_width, operation->stride); operation->output_height = DIV_ROUND_UP(operation->input_height, operation->stride); operation->output_channels = operation->input_channels * operation->stride * operation->stride; - operation->output_zero_point = convolution->input_tensor->zero_point; - operation->output_scale = convolution->input_tensor->scale; + operation->output_zero_point = convolution->input_tensors[0]->zero_point; + operation->output_scale = convolution->input_tensors[0]->scale; /* When destriding a convolution, the transformation to be made to the input * tensor will depend on the size of the weight tensor. @@ -641,7 +643,7 @@ etna_ml_compile_operation_tp(struct etna_ml_subgraph *subgraph, struct etna_vip_instruction *instruction) { struct etna_context *ctx = etna_context(subgraph->base.context); - struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensor); + struct pipe_resource *input = etna_ml_get_tensor(subgraph, operation->input_tensors[0]); assert(input); pipe_resource_reference(&instruction->input, input);