agent-enviroments/builder/libs/seastar/dpdk/lib/mldev/rte_mldev.c
2024-09-10 17:06:08 +03:00

949 lines
22 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2022 Marvell.
*/
#include <rte_errno.h>
#include <rte_log.h>
#include <rte_mldev.h>
#include <rte_mldev_pmd.h>
#include <stdlib.h>
static struct rte_ml_dev_global ml_dev_globals = {
.devs = NULL, .data = NULL, .nb_devs = 0, .max_devs = RTE_MLDEV_DEFAULT_MAX};
/*
* Private data structure of an operation pool.
*
* A structure that contains ml op_pool specific data that is
* appended after the mempool structure (in private data).
*/
struct rte_ml_op_pool_private {
uint16_t user_size;
/*< Size of private user data with each operation. */
};
struct rte_ml_dev *
rte_ml_dev_pmd_get_dev(int16_t dev_id)
{
return &ml_dev_globals.devs[dev_id];
}
struct rte_ml_dev *
rte_ml_dev_pmd_get_named_dev(const char *name)
{
struct rte_ml_dev *dev;
int16_t dev_id;
if (name == NULL)
return NULL;
for (dev_id = 0; dev_id < ml_dev_globals.max_devs; dev_id++) {
dev = rte_ml_dev_pmd_get_dev(dev_id);
if ((dev->attached == ML_DEV_ATTACHED) && (strcmp(dev->data->name, name) == 0))
return dev;
}
return NULL;
}
struct rte_ml_dev *
rte_ml_dev_pmd_allocate(const char *name, uint8_t socket_id)
{
char mz_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
struct rte_ml_dev *dev;
int16_t dev_id;
/* implicit initialization of library before adding first device */
if (ml_dev_globals.devs == NULL) {
if (rte_ml_dev_init(RTE_MLDEV_DEFAULT_MAX) != 0)
return NULL;
}
if (rte_ml_dev_pmd_get_named_dev(name) != NULL) {
RTE_MLDEV_LOG(ERR, "ML device with name %s already allocated!", name);
return NULL;
}
/* Get a free device ID */
for (dev_id = 0; dev_id < ml_dev_globals.max_devs; dev_id++) {
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (dev->attached == ML_DEV_DETACHED)
break;
}
if (dev_id == ml_dev_globals.max_devs) {
RTE_MLDEV_LOG(ERR, "Reached maximum number of ML devices");
return NULL;
}
if (dev->data == NULL) {
/* Reserve memzone name */
sprintf(mz_name, "rte_ml_dev_data_%d", dev_id);
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
mz = rte_memzone_reserve(mz_name, sizeof(struct rte_ml_dev_data), socket_id,
0);
RTE_MLDEV_LOG(DEBUG, "PRIMARY: reserved memzone for %s (%p)", mz_name, mz);
} else {
mz = rte_memzone_lookup(mz_name);
RTE_MLDEV_LOG(DEBUG, "SECONDARY: looked up memzone for %s (%p)", mz_name,
mz);
}
if (mz == NULL)
return NULL;
ml_dev_globals.data[dev_id] = mz->addr;
if (rte_eal_process_type() == RTE_PROC_PRIMARY)
memset(ml_dev_globals.data[dev_id], 0, sizeof(struct rte_ml_dev_data));
dev->data = ml_dev_globals.data[dev_id];
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
strlcpy(dev->data->name, name, RTE_ML_STR_MAX);
dev->data->dev_id = dev_id;
dev->data->socket_id = socket_id;
dev->data->dev_started = 0;
RTE_MLDEV_LOG(DEBUG, "PRIMARY: init mldev data");
}
RTE_MLDEV_LOG(DEBUG, "Data for %s: dev_id %d, socket %u", dev->data->name,
dev->data->dev_id, dev->data->socket_id);
dev->attached = ML_DEV_ATTACHED;
ml_dev_globals.nb_devs++;
}
dev->enqueue_burst = NULL;
dev->dequeue_burst = NULL;
return dev;
}
int
rte_ml_dev_pmd_release(struct rte_ml_dev *dev)
{
char mz_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
int16_t dev_id;
int ret = 0;
if (dev == NULL)
return -EINVAL;
dev_id = dev->data->dev_id;
/* Memzone lookup */
sprintf(mz_name, "rte_ml_dev_data_%d", dev_id);
mz = rte_memzone_lookup(mz_name);
if (mz == NULL)
return -ENOMEM;
RTE_ASSERT(ml_dev_globals.data[dev_id] == mz->addr);
ml_dev_globals.data[dev_id] = NULL;
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
RTE_MLDEV_LOG(DEBUG, "PRIMARY: free memzone of %s (%p)", mz_name, mz);
ret = rte_memzone_free(mz);
} else {
RTE_MLDEV_LOG(DEBUG, "SECONDARY: don't free memzone of %s (%p)", mz_name, mz);
}
dev->attached = ML_DEV_DETACHED;
ml_dev_globals.nb_devs--;
return ret;
}
int
rte_ml_dev_init(size_t dev_max)
{
if (dev_max == 0 || dev_max > INT16_MAX) {
RTE_MLDEV_LOG(ERR, "Invalid dev_max = %zu (> %d)\n", dev_max, INT16_MAX);
rte_errno = EINVAL;
return -rte_errno;
}
/* No lock, it must be called before or during first probing. */
if (ml_dev_globals.devs != NULL) {
RTE_MLDEV_LOG(ERR, "Device array already initialized");
rte_errno = EBUSY;
return -rte_errno;
}
ml_dev_globals.devs = calloc(dev_max, sizeof(struct rte_ml_dev));
if (ml_dev_globals.devs == NULL) {
RTE_MLDEV_LOG(ERR, "Cannot initialize MLDEV library");
rte_errno = ENOMEM;
return -rte_errno;
}
ml_dev_globals.data = calloc(dev_max, sizeof(struct rte_ml_dev_data *));
if (ml_dev_globals.data == NULL) {
RTE_MLDEV_LOG(ERR, "Cannot initialize MLDEV library");
rte_errno = ENOMEM;
return -rte_errno;
}
ml_dev_globals.max_devs = dev_max;
return 0;
}
uint16_t
rte_ml_dev_count(void)
{
return ml_dev_globals.nb_devs;
}
int
rte_ml_dev_is_valid_dev(int16_t dev_id)
{
struct rte_ml_dev *dev = NULL;
if (dev_id >= ml_dev_globals.max_devs || ml_dev_globals.devs[dev_id].data == NULL)
return 0;
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (dev->attached != ML_DEV_ATTACHED)
return 0;
else
return 1;
}
int
rte_ml_dev_socket_id(int16_t dev_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
return dev->data->socket_id;
}
int
rte_ml_dev_info_get(int16_t dev_id, struct rte_ml_dev_info *dev_info)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_info_get == NULL)
return -ENOTSUP;
if (dev_info == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, dev_info cannot be NULL\n", dev_id);
return -EINVAL;
}
memset(dev_info, 0, sizeof(struct rte_ml_dev_info));
return (*dev->dev_ops->dev_info_get)(dev, dev_info);
}
int
rte_ml_dev_configure(int16_t dev_id, const struct rte_ml_dev_config *config)
{
struct rte_ml_dev_info dev_info;
struct rte_ml_dev *dev;
int ret;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_configure == NULL)
return -ENOTSUP;
if (dev->data->dev_started) {
RTE_MLDEV_LOG(ERR, "Device %d must be stopped to allow configuration", dev_id);
return -EBUSY;
}
if (config == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, config cannot be NULL\n", dev_id);
return -EINVAL;
}
ret = rte_ml_dev_info_get(dev_id, &dev_info);
if (ret < 0)
return ret;
if (config->nb_queue_pairs > dev_info.max_queue_pairs) {
RTE_MLDEV_LOG(ERR, "Device %d num of queues %u > %u\n", dev_id,
config->nb_queue_pairs, dev_info.max_queue_pairs);
return -EINVAL;
}
return (*dev->dev_ops->dev_configure)(dev, config);
}
int
rte_ml_dev_close(int16_t dev_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_close == NULL)
return -ENOTSUP;
/* Device must be stopped before it can be closed */
if (dev->data->dev_started == 1) {
RTE_MLDEV_LOG(ERR, "Device %d must be stopped before closing", dev_id);
return -EBUSY;
}
return (*dev->dev_ops->dev_close)(dev);
}
int
rte_ml_dev_start(int16_t dev_id)
{
struct rte_ml_dev *dev;
int ret;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_start == NULL)
return -ENOTSUP;
if (dev->data->dev_started != 0) {
RTE_MLDEV_LOG(ERR, "Device %d is already started", dev_id);
return -EBUSY;
}
ret = (*dev->dev_ops->dev_start)(dev);
if (ret == 0)
dev->data->dev_started = 1;
return ret;
}
int
rte_ml_dev_stop(int16_t dev_id)
{
struct rte_ml_dev *dev;
int ret;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_stop == NULL)
return -ENOTSUP;
if (dev->data->dev_started == 0) {
RTE_MLDEV_LOG(ERR, "Device %d is not started", dev_id);
return -EBUSY;
}
ret = (*dev->dev_ops->dev_stop)(dev);
if (ret == 0)
dev->data->dev_started = 0;
return ret;
}
int
rte_ml_dev_queue_pair_setup(int16_t dev_id, uint16_t queue_pair_id,
const struct rte_ml_dev_qp_conf *qp_conf, int socket_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_queue_pair_setup == NULL)
return -ENOTSUP;
if (queue_pair_id >= dev->data->nb_queue_pairs) {
RTE_MLDEV_LOG(ERR, "Invalid queue_pair_id = %d", queue_pair_id);
return -EINVAL;
}
if (qp_conf == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, qp_conf cannot be NULL\n", dev_id);
return -EINVAL;
}
if (dev->data->dev_started) {
RTE_MLDEV_LOG(ERR, "Device %d must be stopped to allow configuration", dev_id);
return -EBUSY;
}
return (*dev->dev_ops->dev_queue_pair_setup)(dev, queue_pair_id, qp_conf, socket_id);
}
int
rte_ml_dev_stats_get(int16_t dev_id, struct rte_ml_dev_stats *stats)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_stats_get == NULL)
return -ENOTSUP;
if (stats == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, stats cannot be NULL\n", dev_id);
return -EINVAL;
}
memset(stats, 0, sizeof(struct rte_ml_dev_stats));
return (*dev->dev_ops->dev_stats_get)(dev, stats);
}
void
rte_ml_dev_stats_reset(int16_t dev_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_stats_reset == NULL)
return;
(*dev->dev_ops->dev_stats_reset)(dev);
}
int
rte_ml_dev_xstats_names_get(int16_t dev_id, enum rte_ml_dev_xstats_mode mode, int32_t model_id,
struct rte_ml_dev_xstats_map *xstats_map, uint32_t size)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_xstats_names_get == NULL)
return -ENOTSUP;
return (*dev->dev_ops->dev_xstats_names_get)(dev, mode, model_id, xstats_map, size);
}
int
rte_ml_dev_xstats_by_name_get(int16_t dev_id, const char *name, uint16_t *stat_id, uint64_t *value)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_xstats_by_name_get == NULL)
return -ENOTSUP;
if (name == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, name cannot be NULL\n", dev_id);
return -EINVAL;
}
if (value == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, value cannot be NULL\n", dev_id);
return -EINVAL;
}
return (*dev->dev_ops->dev_xstats_by_name_get)(dev, name, stat_id, value);
}
int
rte_ml_dev_xstats_get(int16_t dev_id, enum rte_ml_dev_xstats_mode mode, int32_t model_id,
const uint16_t stat_ids[], uint64_t values[], uint16_t nb_ids)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_xstats_get == NULL)
return -ENOTSUP;
if (stat_ids == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, stat_ids cannot be NULL\n", dev_id);
return -EINVAL;
}
if (values == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, values cannot be NULL\n", dev_id);
return -EINVAL;
}
return (*dev->dev_ops->dev_xstats_get)(dev, mode, model_id, stat_ids, values, nb_ids);
}
int
rte_ml_dev_xstats_reset(int16_t dev_id, enum rte_ml_dev_xstats_mode mode, int32_t model_id,
const uint16_t stat_ids[], uint16_t nb_ids)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_xstats_reset == NULL)
return -ENOTSUP;
return (*dev->dev_ops->dev_xstats_reset)(dev, mode, model_id, stat_ids, nb_ids);
}
int
rte_ml_dev_dump(int16_t dev_id, FILE *fd)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_dump == NULL)
return -ENOTSUP;
if (fd == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, file descriptor cannot be NULL\n", dev_id);
return -EINVAL;
}
return (*dev->dev_ops->dev_dump)(dev, fd);
}
int
rte_ml_dev_selftest(int16_t dev_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->dev_selftest == NULL)
return -ENOTSUP;
return (*dev->dev_ops->dev_selftest)(dev);
}
int
rte_ml_model_load(int16_t dev_id, struct rte_ml_model_params *params, uint16_t *model_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->model_load == NULL)
return -ENOTSUP;
if (params == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, params cannot be NULL\n", dev_id);
return -EINVAL;
}
if (model_id == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, model_id cannot be NULL\n", dev_id);
return -EINVAL;
}
return (*dev->dev_ops->model_load)(dev, params, model_id);
}
int
rte_ml_model_unload(int16_t dev_id, uint16_t model_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->model_unload == NULL)
return -ENOTSUP;
return (*dev->dev_ops->model_unload)(dev, model_id);
}
int
rte_ml_model_start(int16_t dev_id, uint16_t model_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->model_start == NULL)
return -ENOTSUP;
return (*dev->dev_ops->model_start)(dev, model_id);
}
int
rte_ml_model_stop(int16_t dev_id, uint16_t model_id)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->model_stop == NULL)
return -ENOTSUP;
return (*dev->dev_ops->model_stop)(dev, model_id);
}
int
rte_ml_model_info_get(int16_t dev_id, uint16_t model_id, struct rte_ml_model_info *model_info)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->model_info_get == NULL)
return -ENOTSUP;
if (model_info == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, model_id %u, model_info cannot be NULL\n", dev_id,
model_id);
return -EINVAL;
}
return (*dev->dev_ops->model_info_get)(dev, model_id, model_info);
}
int
rte_ml_model_params_update(int16_t dev_id, uint16_t model_id, void *buffer)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->model_params_update == NULL)
return -ENOTSUP;
if (buffer == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, buffer cannot be NULL\n", dev_id);
return -EINVAL;
}
return (*dev->dev_ops->model_params_update)(dev, model_id, buffer);
}
int
rte_ml_io_input_size_get(int16_t dev_id, uint16_t model_id, uint32_t nb_batches,
uint64_t *input_qsize, uint64_t *input_dsize)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->io_input_size_get == NULL)
return -ENOTSUP;
return (*dev->dev_ops->io_input_size_get)(dev, model_id, nb_batches, input_qsize,
input_dsize);
}
int
rte_ml_io_output_size_get(int16_t dev_id, uint16_t model_id, uint32_t nb_batches,
uint64_t *output_qsize, uint64_t *output_dsize)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->io_output_size_get == NULL)
return -ENOTSUP;
return (*dev->dev_ops->io_output_size_get)(dev, model_id, nb_batches, output_qsize,
output_dsize);
}
int
rte_ml_io_quantize(int16_t dev_id, uint16_t model_id, uint16_t nb_batches, void *dbuffer,
void *qbuffer)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->io_quantize == NULL)
return -ENOTSUP;
if (dbuffer == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, dbuffer cannot be NULL\n", dev_id);
return -EINVAL;
}
if (qbuffer == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, qbuffer cannot be NULL\n", dev_id);
return -EINVAL;
}
return (*dev->dev_ops->io_quantize)(dev, model_id, nb_batches, dbuffer, qbuffer);
}
int
rte_ml_io_dequantize(int16_t dev_id, uint16_t model_id, uint16_t nb_batches, void *qbuffer,
void *dbuffer)
{
struct rte_ml_dev *dev;
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dev_ops->io_dequantize == NULL)
return -ENOTSUP;
if (qbuffer == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, qbuffer cannot be NULL\n", dev_id);
return -EINVAL;
}
if (dbuffer == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, dbuffer cannot be NULL\n", dev_id);
return -EINVAL;
}
return (*dev->dev_ops->io_dequantize)(dev, model_id, nb_batches, qbuffer, dbuffer);
}
/** Initialise rte_ml_op mempool element */
static void
ml_op_init(struct rte_mempool *mempool, __rte_unused void *opaque_arg, void *_op_data,
__rte_unused unsigned int i)
{
struct rte_ml_op *op = _op_data;
memset(_op_data, 0, mempool->elt_size);
op->status = RTE_ML_OP_STATUS_NOT_PROCESSED;
op->mempool = mempool;
}
struct rte_mempool *
rte_ml_op_pool_create(const char *name, unsigned int nb_elts, unsigned int cache_size,
uint16_t user_size, int socket_id)
{
struct rte_ml_op_pool_private *priv;
struct rte_mempool *mp;
unsigned int elt_size;
/* lookup mempool in case already allocated */
mp = rte_mempool_lookup(name);
elt_size = sizeof(struct rte_ml_op) + user_size;
if (mp != NULL) {
priv = (struct rte_ml_op_pool_private *)rte_mempool_get_priv(mp);
if (mp->elt_size != elt_size || mp->cache_size < cache_size || mp->size < nb_elts ||
priv->user_size < user_size) {
mp = NULL;
RTE_MLDEV_LOG(ERR,
"Mempool %s already exists but with incompatible parameters",
name);
return NULL;
}
return mp;
}
mp = rte_mempool_create(name, nb_elts, elt_size, cache_size,
sizeof(struct rte_ml_op_pool_private), NULL, NULL, ml_op_init, NULL,
socket_id, 0);
if (mp == NULL) {
RTE_MLDEV_LOG(ERR, "Failed to create mempool %s", name);
return NULL;
}
priv = (struct rte_ml_op_pool_private *)rte_mempool_get_priv(mp);
priv->user_size = user_size;
return mp;
}
void
rte_ml_op_pool_free(struct rte_mempool *mempool)
{
rte_mempool_free(mempool);
}
uint16_t
rte_ml_enqueue_burst(int16_t dev_id, uint16_t qp_id, struct rte_ml_op **ops, uint16_t nb_ops)
{
struct rte_ml_dev *dev;
#ifdef RTE_LIBRTE_ML_DEV_DEBUG
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
rte_errno = -EINVAL;
return 0;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->enqueue_burst == NULL) {
rte_errno = -ENOTSUP;
return 0;
}
if (ops == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, ops cannot be NULL\n", dev_id);
rte_errno = -EINVAL;
return 0;
}
if (qp_id >= dev->data->nb_queue_pairs) {
RTE_MLDEV_LOG(ERR, "Invalid qp_id %u\n", qp_id);
rte_errno = -EINVAL;
return 0;
}
#else
dev = rte_ml_dev_pmd_get_dev(dev_id);
#endif
return (*dev->enqueue_burst)(dev, qp_id, ops, nb_ops);
}
uint16_t
rte_ml_dequeue_burst(int16_t dev_id, uint16_t qp_id, struct rte_ml_op **ops, uint16_t nb_ops)
{
struct rte_ml_dev *dev;
#ifdef RTE_LIBRTE_ML_DEV_DEBUG
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
rte_errno = -EINVAL;
return 0;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->dequeue_burst == NULL) {
rte_errno = -ENOTSUP;
return 0;
}
if (ops == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, ops cannot be NULL\n", dev_id);
rte_errno = -EINVAL;
return 0;
}
if (qp_id >= dev->data->nb_queue_pairs) {
RTE_MLDEV_LOG(ERR, "Invalid qp_id %u\n", qp_id);
rte_errno = -EINVAL;
return 0;
}
#else
dev = rte_ml_dev_pmd_get_dev(dev_id);
#endif
return (*dev->dequeue_burst)(dev, qp_id, ops, nb_ops);
}
int
rte_ml_op_error_get(int16_t dev_id, struct rte_ml_op *op, struct rte_ml_op_error *error)
{
struct rte_ml_dev *dev;
#ifdef RTE_LIBRTE_ML_DEV_DEBUG
if (!rte_ml_dev_is_valid_dev(dev_id)) {
RTE_MLDEV_LOG(ERR, "Invalid dev_id = %d\n", dev_id);
return -EINVAL;
}
dev = rte_ml_dev_pmd_get_dev(dev_id);
if (*dev->op_error_get == NULL)
return -ENOTSUP;
if (op == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, op cannot be NULL\n", dev_id);
return -EINVAL;
}
if (error == NULL) {
RTE_MLDEV_LOG(ERR, "Dev %d, error cannot be NULL\n", dev_id);
return -EINVAL;
}
#else
dev = rte_ml_dev_pmd_get_dev(dev_id);
#endif
return (*dev->op_error_get)(dev, op, error);
}
RTE_LOG_REGISTER_DEFAULT(rte_ml_dev_logtype, INFO);