teflon: Add is_signed parameter to ml_subgraph_invoke and ml_subgraph_read_output

There probably is a better way to provide this information to the
gallium driver, but this allows the driver to apply conversions as
needed when writing input tensors and reading back output tensors.

Reviewed-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31979>
This commit is contained in:
Philipp Zabel 2024-09-24 11:59:45 +02:00
parent 1ca2137a84
commit f9c34a3eb0
4 changed files with 36 additions and 12 deletions

View file

@ -512,7 +512,8 @@ close_batch(struct pipe_context *pctx)
void
etna_ml_subgraph_invoke(struct pipe_context *pctx, struct pipe_ml_subgraph *psubgraph,
unsigned inputs_count, unsigned input_idxs[], void *inputs[])
unsigned inputs_count, unsigned input_idxs[], void *inputs[],
bool is_signed[])
{
struct etna_context *ctx = etna_context(pctx);
unsigned tp_core_count = etna_ml_get_core_info(ctx)->tp_core_count;
@ -629,7 +630,8 @@ etna_ml_subgraph_invoke(struct pipe_context *pctx, struct pipe_ml_subgraph *psub
void
etna_ml_subgraph_read_outputs(struct pipe_context *context, struct pipe_ml_subgraph *psubgraph,
unsigned outputs_count, unsigned output_idxs[], void *outputs[])
unsigned outputs_count, unsigned output_idxs[], void *outputs[],
bool is_signed[])
{
struct etna_ml_subgraph *subgraph = (struct etna_ml_subgraph *)(psubgraph);
unsigned operation_count = util_dynarray_num_elements(&subgraph->operations, struct etna_vip_instruction);

View file

@ -123,11 +123,12 @@ etna_ml_subgraph_create(struct pipe_context *context,
void
etna_ml_subgraph_invoke(struct pipe_context *pctx, struct pipe_ml_subgraph *psubgraph,
unsigned inputs_count, unsigned input_idxs[], void *inputs[]);
unsigned inputs_count, unsigned input_idxs[], void *inputs[], bool is_signed[]);
void
etna_ml_subgraph_read_outputs(struct pipe_context *context, struct pipe_ml_subgraph *subgraph,
unsigned outputs_count, unsigned output_idxs[], void *outputs[]);
unsigned outputs_count, unsigned output_idxs[], void *outputs[],
bool is_signed[]);
void
etna_ml_subgraph_destroy(struct pipe_context *context, struct pipe_ml_subgraph *subgraph);

View file

@ -351,16 +351,34 @@ partition_invoke(TfLiteContext *tf_context, TfLiteNode *node)
}
void **buffers = malloc(tsubgraph->input_count * sizeof(*buffers));
for (unsigned i = 0; i < tsubgraph->input_count; i++)
buffers[i] = tf_context->tensors[tsubgraph->input_tensors[i]].data.data;
context->ml_subgraph_invoke(context, subgraph, tsubgraph->input_count, tsubgraph->input_tensors, buffers);
bool *is_signed = malloc(tsubgraph->input_count * sizeof(*is_signed));
for (unsigned i = 0; i < tsubgraph->input_count; i++) {
TfLiteTensor tf_tensor = tf_context->tensors[tsubgraph->input_tensors[i]];
buffers[i] = tf_tensor.data.data;
is_signed[i] = !(tf_tensor.type == kTfLiteUInt8 ||
tf_tensor.type == kTfLiteUInt16 ||
tf_tensor.type == kTfLiteUInt32 ||
tf_tensor.type == kTfLiteUInt64);
}
context->ml_subgraph_invoke(context, subgraph, tsubgraph->input_count, tsubgraph->input_tensors, buffers, is_signed);
free(buffers);
free(is_signed);
buffers = malloc(tsubgraph->output_count * sizeof(*buffers));
for (unsigned i = 0; i < tsubgraph->output_count; i++)
buffers[i] = tf_context->tensors[tsubgraph->output_tensors[i]].data.data;
context->ml_subgraph_read_output(context, subgraph, tsubgraph->output_count, tsubgraph->output_tensors, buffers);
is_signed = malloc(tsubgraph->output_count * sizeof(*is_signed));
for (unsigned i = 0; i < tsubgraph->output_count; i++) {
TfLiteTensor tf_tensor = tf_context->tensors[tsubgraph->output_tensors[i]];
buffers[i] = tf_tensor.data.data;
is_signed[i] = !(tf_tensor.type == kTfLiteUInt8 ||
tf_tensor.type == kTfLiteUInt16 ||
tf_tensor.type == kTfLiteUInt32 ||
tf_tensor.type == kTfLiteUInt64);
}
context->ml_subgraph_read_output(context, subgraph, tsubgraph->output_count, tsubgraph->output_tensors, buffers, is_signed);
free(buffers);
free(is_signed);
if (unlikely(debug_get_option_debug_teflon() & TEFLON_DEBUG_VERBOSE)) {
struct timespec time;

View file

@ -1261,12 +1261,13 @@ struct pipe_context {
* \param inputs_count number of input tensors to copy in
* \param input_idxs array with the indices of input tensors
* \param inputs array of buffers to copy the tensor data from
* \param is_signed per-buffer signed integer flag
*/
void (*ml_subgraph_invoke)(struct pipe_context *context,
struct pipe_ml_subgraph *subgraph,
unsigned inputs_count,
unsigned input_idxs[],
void *inputs[]);
void *inputs[], bool is_signed[]);
/**
* After a ML subgraph has been invoked, copy the contents of the output
@ -1277,10 +1278,12 @@ struct pipe_context {
* \param outputs_count number of output tensors to copy out
* \param output_idxs array with the indices of output tensors
* \param outputs array of buffers to copy the tensor data to
* \param is_signed per-buffer signed integer flag
*/
void (*ml_subgraph_read_output)(struct pipe_context *context,
struct pipe_ml_subgraph *subgraph,
unsigned outputs_count, unsigned output_idxs[], void *outputs[]);
unsigned outputs_count, unsigned output_idxs[],
void *outputs[], bool is_signed[]);
/**
* Release all resources allocated by the implementation of ml_subgraph_create