@@ -3,6 +3,7 @@
*/
#include <errno.h>
+#include <math.h>
#include <stdio.h>
#include <unistd.h>
@@ -18,11 +19,6 @@
#include "ml_common.h"
#include "test_inference_common.h"
-#define ML_TEST_READ_TYPE(buffer, type) (*((type *)buffer))
-
-#define ML_TEST_CHECK_OUTPUT(output, reference, tolerance) \
- (((float)output - (float)reference) <= (((float)reference * tolerance) / 100.0))
-
#define ML_OPEN_WRITE_GET_ERR(name, buffer, size, err) \
do { \
FILE *fp = fopen(name, "w+"); \
@@ -763,9 +759,9 @@ ml_inference_validation(struct ml_test *test, struct ml_request *req)
{
struct test_inference *t = ml_test_priv((struct ml_test *)test);
struct ml_model *model;
- uint32_t nb_elements;
- uint8_t *reference;
- uint8_t *output;
+ float *reference;
+ float *output;
+ float deviation;
bool match;
uint32_t i;
uint32_t j;
@@ -777,89 +773,30 @@ ml_inference_validation(struct ml_test *test, struct ml_request *req)
match = (rte_hash_crc(model->output, model->out_dsize, 0) ==
rte_hash_crc(model->reference, model->out_dsize, 0));
} else {
- output = model->output;
- reference = model->reference;
+ output = (float *)model->output;
+ reference = (float *)model->reference;
i = 0;
next_output:
- nb_elements =
- model->info.output_info[i].shape.w * model->info.output_info[i].shape.x *
- model->info.output_info[i].shape.y * model->info.output_info[i].shape.z;
j = 0;
next_element:
match = false;
- switch (model->info.output_info[i].dtype) {
- case RTE_ML_IO_TYPE_INT8:
- if (ML_TEST_CHECK_OUTPUT(ML_TEST_READ_TYPE(output, int8_t),
- ML_TEST_READ_TYPE(reference, int8_t),
- t->cmn.opt->tolerance))
- match = true;
-
- output += sizeof(int8_t);
- reference += sizeof(int8_t);
- break;
- case RTE_ML_IO_TYPE_UINT8:
- if (ML_TEST_CHECK_OUTPUT(ML_TEST_READ_TYPE(output, uint8_t),
- ML_TEST_READ_TYPE(reference, uint8_t),
- t->cmn.opt->tolerance))
- match = true;
-
- output += sizeof(float);
- reference += sizeof(float);
- break;
- case RTE_ML_IO_TYPE_INT16:
- if (ML_TEST_CHECK_OUTPUT(ML_TEST_READ_TYPE(output, int16_t),
- ML_TEST_READ_TYPE(reference, int16_t),
- t->cmn.opt->tolerance))
- match = true;
-
- output += sizeof(int16_t);
- reference += sizeof(int16_t);
- break;
- case RTE_ML_IO_TYPE_UINT16:
- if (ML_TEST_CHECK_OUTPUT(ML_TEST_READ_TYPE(output, uint16_t),
- ML_TEST_READ_TYPE(reference, uint16_t),
- t->cmn.opt->tolerance))
- match = true;
-
- output += sizeof(uint16_t);
- reference += sizeof(uint16_t);
- break;
- case RTE_ML_IO_TYPE_INT32:
- if (ML_TEST_CHECK_OUTPUT(ML_TEST_READ_TYPE(output, int32_t),
- ML_TEST_READ_TYPE(reference, int32_t),
- t->cmn.opt->tolerance))
- match = true;
-
- output += sizeof(int32_t);
- reference += sizeof(int32_t);
- break;
- case RTE_ML_IO_TYPE_UINT32:
- if (ML_TEST_CHECK_OUTPUT(ML_TEST_READ_TYPE(output, uint32_t),
- ML_TEST_READ_TYPE(reference, uint32_t),
- t->cmn.opt->tolerance))
- match = true;
-
- output += sizeof(uint32_t);
- reference += sizeof(uint32_t);
- break;
- case RTE_ML_IO_TYPE_FP32:
- if (ML_TEST_CHECK_OUTPUT(ML_TEST_READ_TYPE(output, float),
- ML_TEST_READ_TYPE(reference, float),
- t->cmn.opt->tolerance))
- match = true;
-
- output += sizeof(float);
- reference += sizeof(float);
- break;
- default: /* other types, fp8, fp16, bfloat16 */
+ deviation =
+ (*reference == 0 ? 0 : 100 * fabs(*output - *reference) / fabs(*reference));
+ if (deviation <= t->cmn.opt->tolerance)
match = true;
- }
+ else
+ ml_err("id = %d, element = %d, output = %f, reference = %f, deviation = %f %%\n",
+ i, j, *output, *reference, deviation);
+
+ output++;
+ reference++;
if (!match)
goto done;
+
j++;
- if (j < nb_elements)
+ if (j < model->info.output_info[i].nb_elements)
goto next_element;
i++;
@@ -366,6 +366,12 @@ cn10k_ml_model_addr_update(struct cn10k_ml_model *model, uint8_t *buffer, uint8_
addr->total_input_sz_q = 0;
for (i = 0; i < metadata->model.num_input; i++) {
if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
+ addr->input[i].nb_dims = 4;
+ addr->input[i].shape[0] = metadata->input1[i].shape.w;
+ addr->input[i].shape[1] = metadata->input1[i].shape.x;
+ addr->input[i].shape[2] = metadata->input1[i].shape.y;
+ addr->input[i].shape[3] = metadata->input1[i].shape.z;
+
addr->input[i].nb_elements =
metadata->input1[i].shape.w * metadata->input1[i].shape.x *
metadata->input1[i].shape.y * metadata->input1[i].shape.z;
@@ -386,6 +392,13 @@ cn10k_ml_model_addr_update(struct cn10k_ml_model *model, uint8_t *buffer, uint8_
addr->input[i].sz_q);
} else {
j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
+
+ addr->input[i].nb_dims = 4;
+ addr->input[i].shape[0] = metadata->input2[j].shape.w;
+ addr->input[i].shape[1] = metadata->input2[j].shape.x;
+ addr->input[i].shape[2] = metadata->input2[j].shape.y;
+ addr->input[i].shape[3] = metadata->input2[j].shape.z;
+
addr->input[i].nb_elements =
metadata->input2[j].shape.w * metadata->input2[j].shape.x *
metadata->input2[j].shape.y * metadata->input2[j].shape.z;
@@ -412,6 +425,8 @@ cn10k_ml_model_addr_update(struct cn10k_ml_model *model, uint8_t *buffer, uint8_
addr->total_output_sz_d = 0;
for (i = 0; i < metadata->model.num_output; i++) {
if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
+ addr->output[i].nb_dims = 1;
+ addr->output[i].shape[0] = metadata->output1[i].size;
addr->output[i].nb_elements = metadata->output1[i].size;
addr->output[i].sz_d =
addr->output[i].nb_elements *
@@ -426,6 +441,9 @@ cn10k_ml_model_addr_update(struct cn10k_ml_model *model, uint8_t *buffer, uint8_
model->model_id, i, addr->output[i].sz_d, addr->output[i].sz_q);
} else {
j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
+
+ addr->output[i].nb_dims = 1;
+ addr->output[i].shape[0] = metadata->output2[j].size;
addr->output[i].nb_elements = metadata->output2[j].size;
addr->output[i].sz_d =
addr->output[i].nb_elements *
@@ -498,6 +516,7 @@ void
cn10k_ml_model_info_set(struct rte_ml_dev *dev, struct cn10k_ml_model *model)
{
struct cn10k_ml_model_metadata *metadata;
+ struct cn10k_ml_model_addr *addr;
struct rte_ml_model_info *info;
struct rte_ml_io_info *output;
struct rte_ml_io_info *input;
@@ -508,6 +527,7 @@ cn10k_ml_model_info_set(struct rte_ml_dev *dev, struct cn10k_ml_model *model)
info = PLT_PTR_CAST(model->info);
input = PLT_PTR_ADD(info, sizeof(struct rte_ml_model_info));
output = PLT_PTR_ADD(input, metadata->model.num_input * sizeof(struct rte_ml_io_info));
+ addr = &model->addr;
/* Set model info */
memset(info, 0, sizeof(struct rte_ml_model_info));
@@ -529,24 +549,25 @@ cn10k_ml_model_info_set(struct rte_ml_dev *dev, struct cn10k_ml_model *model)
if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
rte_memcpy(input[i].name, metadata->input1[i].input_name,
MRVL_ML_INPUT_NAME_LEN);
- input[i].dtype = metadata->input1[i].input_type;
- input[i].qtype = metadata->input1[i].model_input_type;
- input[i].shape.format = metadata->input1[i].shape.format;
- input[i].shape.w = metadata->input1[i].shape.w;
- input[i].shape.x = metadata->input1[i].shape.x;
- input[i].shape.y = metadata->input1[i].shape.y;
- input[i].shape.z = metadata->input1[i].shape.z;
+ input[i].nb_dims = addr->input[i].nb_dims;
+ input[i].shape = addr->input[i].shape;
+ input[i].type = metadata->input1[i].model_input_type;
+ input[i].nb_elements = addr->input[i].nb_elements;
+ input[i].size =
+ addr->input[i].nb_elements *
+ rte_ml_io_type_size_get(metadata->input1[i].model_input_type);
} else {
j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
+
rte_memcpy(input[i].name, metadata->input2[j].input_name,
MRVL_ML_INPUT_NAME_LEN);
- input[i].dtype = metadata->input2[j].input_type;
- input[i].qtype = metadata->input2[j].model_input_type;
- input[i].shape.format = metadata->input2[j].shape.format;
- input[i].shape.w = metadata->input2[j].shape.w;
- input[i].shape.x = metadata->input2[j].shape.x;
- input[i].shape.y = metadata->input2[j].shape.y;
- input[i].shape.z = metadata->input2[j].shape.z;
+ input[i].nb_dims = addr->input[i].nb_dims;
+ input[i].shape = addr->input[i].shape;
+ input[i].type = metadata->input2[j].model_input_type;
+ input[i].nb_elements = addr->input[i].nb_elements;
+ input[i].size =
+ addr->input[i].nb_elements *
+ rte_ml_io_type_size_get(metadata->input2[j].model_input_type);
}
}
@@ -555,24 +576,25 @@ cn10k_ml_model_info_set(struct rte_ml_dev *dev, struct cn10k_ml_model *model)
if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
rte_memcpy(output[i].name, metadata->output1[i].output_name,
MRVL_ML_OUTPUT_NAME_LEN);
- output[i].dtype = metadata->output1[i].output_type;
- output[i].qtype = metadata->output1[i].model_output_type;
- output[i].shape.format = RTE_ML_IO_FORMAT_1D;
- output[i].shape.w = metadata->output1[i].size;
- output[i].shape.x = 1;
- output[i].shape.y = 1;
- output[i].shape.z = 1;
+ output[i].nb_dims = addr->output[i].nb_dims;
+ output[i].shape = addr->output[i].shape;
+ output[i].type = metadata->output1[i].model_output_type;
+ output[i].nb_elements = addr->output[i].nb_elements;
+ output[i].size =
+ addr->output[i].nb_elements *
+ rte_ml_io_type_size_get(metadata->output1[i].model_output_type);
} else {
j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
+
rte_memcpy(output[i].name, metadata->output2[j].output_name,
MRVL_ML_OUTPUT_NAME_LEN);
- output[i].dtype = metadata->output2[j].output_type;
- output[i].qtype = metadata->output2[j].model_output_type;
- output[i].shape.format = RTE_ML_IO_FORMAT_1D;
- output[i].shape.w = metadata->output2[j].size;
- output[i].shape.x = 1;
- output[i].shape.y = 1;
- output[i].shape.z = 1;
+ output[i].nb_dims = addr->output[i].nb_dims;
+ output[i].shape = addr->output[i].shape;
+ output[i].type = metadata->output2[j].model_output_type;
+ output[i].nb_elements = addr->output[i].nb_elements;
+ output[i].size =
+ addr->output[i].nb_elements *
+ rte_ml_io_type_size_get(metadata->output2[j].model_output_type);
}
}
}
@@ -409,6 +409,12 @@ struct cn10k_ml_model_addr {
/* Input address and size */
struct {
+ /* Number of dimensions in shape */
+ uint32_t nb_dims;
+
+ /* Shape of input */
+ uint32_t shape[4];
+
/* Number of elements */
uint32_t nb_elements;
@@ -421,6 +427,12 @@ struct cn10k_ml_model_addr {
/* Output address and size */
struct {
+ /* Number of dimensions in shape */
+ uint32_t nb_dims;
+
+ /* Shape of input */
+ uint32_t shape[4];
+
/* Number of elements */
uint32_t nb_elements;
@@ -321,8 +321,8 @@ cn10k_ml_model_print(struct rte_ml_dev *dev, uint16_t model_id, FILE *fp)
fprintf(fp, "\n");
print_line(fp, LINE_LEN);
- fprintf(fp, "%8s %16s %12s %18s %12s %14s\n", "input", "input_name", "input_type",
- "model_input_type", "quantize", "format");
+ fprintf(fp, "%8s %16s %12s %18s %12s\n", "input", "input_name", "input_type",
+ "model_input_type", "quantize");
print_line(fp, LINE_LEN);
for (i = 0; i < model->metadata.model.num_input; i++) {
if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
@@ -335,12 +335,10 @@ cn10k_ml_model_print(struct rte_ml_dev *dev, uint16_t model_id, FILE *fp)
fprintf(fp, "%*s ", 18, str);
fprintf(fp, "%*s", 12,
(model->metadata.input1[i].quantize == 1 ? "Yes" : "No"));
- rte_ml_io_format_to_str(model->metadata.input1[i].shape.format, str,
- STR_LEN);
- fprintf(fp, "%*s", 16, str);
fprintf(fp, "\n");
} else {
j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
+
fprintf(fp, "%8u ", i);
fprintf(fp, "%*s ", 16, model->metadata.input2[j].input_name);
rte_ml_io_type_to_str(model->metadata.input2[j].input_type, str, STR_LEN);
@@ -350,9 +348,6 @@ cn10k_ml_model_print(struct rte_ml_dev *dev, uint16_t model_id, FILE *fp)
fprintf(fp, "%*s ", 18, str);
fprintf(fp, "%*s", 12,
(model->metadata.input2[j].quantize == 1 ? "Yes" : "No"));
- rte_ml_io_format_to_str(model->metadata.input2[j].shape.format, str,
- STR_LEN);
- fprintf(fp, "%*s", 16, str);
fprintf(fp, "\n");
}
}
@@ -86,33 +86,3 @@ rte_ml_io_type_to_str(enum rte_ml_io_type type, char *str, int len)
rte_strlcpy(str, "invalid", len);
}
}
-
-void
-rte_ml_io_format_to_str(enum rte_ml_io_format format, char *str, int len)
-{
- switch (format) {
- case RTE_ML_IO_FORMAT_NCHW:
- rte_strlcpy(str, "NCHW", len);
- break;
- case RTE_ML_IO_FORMAT_NHWC:
- rte_strlcpy(str, "NHWC", len);
- break;
- case RTE_ML_IO_FORMAT_CHWN:
- rte_strlcpy(str, "CHWN", len);
- break;
- case RTE_ML_IO_FORMAT_3D:
- rte_strlcpy(str, "3D", len);
- break;
- case RTE_ML_IO_FORMAT_2D:
- rte_strlcpy(str, "Matrix", len);
- break;
- case RTE_ML_IO_FORMAT_1D:
- rte_strlcpy(str, "Vector", len);
- break;
- case RTE_ML_IO_FORMAT_SCALAR:
- rte_strlcpy(str, "Scalar", len);
- break;
- default:
- rte_strlcpy(str, "invalid", len);
- }
-}
@@ -52,22 +52,6 @@ __rte_internal
void
rte_ml_io_type_to_str(enum rte_ml_io_type type, char *str, int len);
-/**
- * @internal
- *
- * Get the name of an ML IO format.
- *
- * @param[in] type
- * Enumeration of ML IO format.
- * @param[in] str
- * Address of character array.
- * @param[in] len
- * Length of character array.
- */
-__rte_internal
-void
-rte_ml_io_format_to_str(enum rte_ml_io_format format, char *str, int len);
-
/**
* @internal
*
@@ -863,47 +863,6 @@ enum rte_ml_io_type {
/**< 16-bit brain floating point number. */
};
-/**
- * Input and output format. This is used to represent the encoding type of multi-dimensional
- * used by ML models.
- */
-enum rte_ml_io_format {
- RTE_ML_IO_FORMAT_NCHW = 1,
- /**< Batch size (N) x channels (C) x height (H) x width (W) */
- RTE_ML_IO_FORMAT_NHWC,
- /**< Batch size (N) x height (H) x width (W) x channels (C) */
- RTE_ML_IO_FORMAT_CHWN,
- /**< Channels (C) x height (H) x width (W) x batch size (N) */
- RTE_ML_IO_FORMAT_3D,
- /**< Format to represent a 3 dimensional data */
- RTE_ML_IO_FORMAT_2D,
- /**< Format to represent matrix data */
- RTE_ML_IO_FORMAT_1D,
- /**< Format to represent vector data */
- RTE_ML_IO_FORMAT_SCALAR,
- /**< Format to represent scalar data */
-};
-
-/**
- * Input and output shape. This structure represents the encoding format and dimensions
- * of the tensor or vector.
- *
- * The data can be a 4D / 3D tensor, matrix, vector or a scalar. Number of dimensions used
- * for the data would depend on the format. Unused dimensions to be set to 1.
- */
-struct rte_ml_io_shape {
- enum rte_ml_io_format format;
- /**< Format of the data */
- uint32_t w;
- /**< First dimension */
- uint32_t x;
- /**< Second dimension */
- uint32_t y;
- /**< Third dimension */
- uint32_t z;
- /**< Fourth dimension */
-};
-
/** Input and output data information structure
*
* Specifies the type and shape of input and output data.
@@ -911,12 +870,18 @@ struct rte_ml_io_shape {
struct rte_ml_io_info {
char name[RTE_ML_STR_MAX];
/**< Name of data */
- struct rte_ml_io_shape shape;
- /**< Shape of data */
- enum rte_ml_io_type qtype;
- /**< Type of quantized data */
- enum rte_ml_io_type dtype;
- /**< Type of de-quantized data */
+ uint32_t nb_dims;
+ /**< Number of dimensions in shape */
+ uint32_t *shape;
+ /**< Shape of the tensor */
+ enum rte_ml_io_type type;
+ /**< Type of data
+ * @see enum rte_ml_io_type
+ */
+ uint64_t nb_elements;
+ /** Number of elements in tensor */
+ uint64_t size;
+ /** Size of tensor in bytes */
};
/** Model information structure */
@@ -51,7 +51,6 @@ INTERNAL {
rte_ml_io_type_size_get;
rte_ml_io_type_to_str;
- rte_ml_io_format_to_str;
rte_ml_io_float32_to_int8;
rte_ml_io_int8_to_float32;
rte_ml_io_float32_to_uint8;