Updated MVTVM layer of the driver to call TVM C runtime
API functions, instead on the TVMDP wrapper library APIs.

Drop all dependencies on TVMDP wrapper library.

Signed-off-by: Srikanth Yalavarthi <[email protected]>
---
 doc/guides/mldevs/cnxk.rst       |  35 +-
 drivers/ml/cnxk/cnxk_ml_io.h     |  20 +-
 drivers/ml/cnxk/cnxk_ml_ops.c    |  12 +-
 drivers/ml/cnxk/meson.build      |  14 +-
 drivers/ml/cnxk/mvtvm_ml_dev.h   |   3 -
 drivers/ml/cnxk/mvtvm_ml_model.c | 638 ++++++++++++++++++++++++++++---
 drivers/ml/cnxk/mvtvm_ml_model.h |  81 +++-
 drivers/ml/cnxk/mvtvm_ml_ops.c   | 440 ++++++++++++++-------
 drivers/ml/cnxk/mvtvm_ml_ops.h   |   5 +-
 drivers/ml/cnxk/mvtvm_ml_stubs.c |  17 -
 drivers/ml/cnxk/mvtvm_ml_stubs.h |   2 -
 11 files changed, 985 insertions(+), 282 deletions(-)

diff --git a/doc/guides/mldevs/cnxk.rst b/doc/guides/mldevs/cnxk.rst
index fc1bcd9cdb4..17e58d81c0b 100644
--- a/doc/guides/mldevs/cnxk.rst
+++ b/doc/guides/mldevs/cnxk.rst
@@ -111,13 +111,13 @@ on CPU cores or hardware accelerators.
 
 .. note::
 
-   DPDK CNXK ML driver requires TVM version 0.10.0
+   DPDK CNXK ML driver requires TVM version legacy-v0.19.post branch.
 
 .. code-block:: console
 
    git clone https://github.com/apache/tvm.git
    cd tvm
-   git checkout v0.11.0 -b v0.11.0
+   git checkout legacy-v0.19.post -b legacy-v0.19.post
    git submodule update --init
    cmake -S ./ -B build \
       -DCMAKE_INSTALL_PREFIX=<install_prefix> \
@@ -135,37 +135,6 @@ When cross-compiling, more options must be provided to 
CMake:
    -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
    -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY
 
-TVMDP
-~~~~~
-
-  Marvell's `TVM Dataplane Library 
<https://github.com/MarvellEmbeddedProcessors/tvmdp>`_
-  works as an interface between TVM runtime and DPDK drivers.
-  TVMDP library provides a simplified C interface
-  for TVM's runtime based on C++.
-
-.. note::
-
-   TVMDP library is dependent on TVM, dlpack, jansson and dmlc-core libraries.
-
-.. code-block:: console
-
-   git clone https://github.com/MarvellEmbeddedProcessors/tvmdp.git
-   cd tvmdp
-   git checkout main
-   cmake -S ./ -B build \
-      -DCMAKE_INSTALL_PREFIX=<install_prefix> \
-      -DBUILD_SHARED_LIBS=ON
-   make -C build
-   make -C build install
-
-When cross-compiling, more options must be provided to CMake:
-
-.. code-block:: console
-
-   -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
-   -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \
-   -DCMAKE_FIND_ROOT_PATH=<install_prefix>
-
 libarchive
 ~~~~~~~~~~
 
diff --git a/drivers/ml/cnxk/cnxk_ml_io.h b/drivers/ml/cnxk/cnxk_ml_io.h
index 83329c237aa..17f5b4619f0 100644
--- a/drivers/ml/cnxk/cnxk_ml_io.h
+++ b/drivers/ml/cnxk/cnxk_ml_io.h
@@ -6,7 +6,7 @@
 #define _CNXK_ML_IO_H_
 
 #ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
-#include <tvmdp.h>
+#include <dlpack/dlpack.h>
 #endif
 
 #include <rte_mldev.h>
@@ -16,7 +16,7 @@
 
 /* Maximum number of layers per model */
 #ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
-#define ML_CNXK_MODEL_MAX_LAYERS TVMDP_MODEL_LAYERS_MAX
+#define ML_CNXK_MODEL_MAX_LAYERS 128
 #else
 #define ML_CNXK_MODEL_MAX_LAYERS 1
 #endif
@@ -41,7 +41,7 @@ struct cnxk_ml_io {
        /* Number of dimensions in shape */
        uint32_t nb_dims;
 
-       /* Shape of input */
+       /* Shape */
        uint32_t shape[ML_CNXK_MODEL_MAX_DIMS];
 
        /* Number of elements */
@@ -58,6 +58,20 @@ struct cnxk_ml_io {
 
        /* Zero point */
        int64_t zero_point;
+
+#ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
+       /* Shape - int64_t */
+       int64_t shape_i64[ML_CNXK_MODEL_MAX_DIMS];
+
+       /* Data type */
+       DLDataType datatype;
+
+       /* Model data type */
+       DLDataType model_datatype;
+
+       /* Device */
+       DLDevice device;
+#endif
 };
 
 /* Model / Layer IO structure */
diff --git a/drivers/ml/cnxk/cnxk_ml_ops.c b/drivers/ml/cnxk/cnxk_ml_ops.c
index 9958945670a..938982c7556 100644
--- a/drivers/ml/cnxk/cnxk_ml_ops.c
+++ b/drivers/ml/cnxk/cnxk_ml_ops.c
@@ -634,10 +634,6 @@ cnxk_ml_dev_configure(struct rte_ml_dev *dev, const struct 
rte_ml_dev_config *co
                }
        }
 
-       ret = mvtvm_ml_dev_configure(cnxk_mldev, conf);
-       if (ret != 0)
-               goto error;
-
        /* Set device capabilities */
        if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI)
                cnxk_mldev->max_nb_layers =
@@ -705,9 +701,6 @@ cnxk_ml_dev_close(struct rte_ml_dev *dev)
        /* Un-initialize xstats */
        cnxk_ml_xstats_uninit(cnxk_mldev);
 
-       if (mvtvm_ml_dev_close(cnxk_mldev) != 0)
-               plt_err("Failed to close MVTVM ML Device");
-
        if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI) {
                if (cn10k_ml_dev_close(cnxk_mldev) != 0)
                        plt_err("Failed to close CN10K ML Device");
@@ -1234,7 +1227,7 @@ cnxk_ml_model_load(struct rte_ml_dev *dev, struct 
rte_ml_model_params *params, u
                                            
model->layer[layer_id].glow.ocm_map.scratch_pages);
 #ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
        } else {
-               for (layer_id = 0; layer_id < 
model->mvtvm.metadata.model.nb_layers; layer_id++) {
+               for (layer_id = 0; layer_id < model->nb_layers; layer_id++) {
                        if (model->layer[layer_id].type == 
ML_CNXK_LAYER_TYPE_MRVL) {
                                total_wb_pages = total_wb_pages +
                                                 
model->layer[layer_id].glow.ocm_map.wb_pages;
@@ -1256,8 +1249,7 @@ cnxk_ml_model_load(struct rte_ml_dev *dev, struct 
rte_ml_model_params *params, u
                                   
model->layer[layer_id].glow.ocm_map.scratch_pages);
 #ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
                } else {
-                       for (layer_id = 0; layer_id < 
model->mvtvm.metadata.model.nb_layers;
-                            layer_id++) {
+                       for (layer_id = 0; layer_id < model->nb_layers; 
layer_id++) {
                                if (model->layer[layer_id].type == 
ML_CNXK_LAYER_TYPE_MRVL) {
                                        plt_ml_dbg(
                                                "layer_id = %u: wb_pages = %u, 
scratch_pages = %u",
diff --git a/drivers/ml/cnxk/meson.build b/drivers/ml/cnxk/meson.build
index ef7e21d7476..5f078bd4fd7 100644
--- a/drivers/ml/cnxk/meson.build
+++ b/drivers/ml/cnxk/meson.build
@@ -19,30 +19,24 @@ if not jansson_dep.found()
         enable_mvtvm = false
 endif
 
-dlpack_dep = dependency('dlpack', method: 'cmake', required: false, 
cmake_args: 'CONFIG')
+dlpack_dep = dependency('dlpack', method: 'cmake', required: false)
 if not dlpack_dep.found()
         message('drivers/ml/cnxk: dlpack not found')
         enable_mvtvm = false
 endif
 
-dmlc_dep = dependency('dmlc', method: 'cmake', required: false, cmake_args: 
'CONFIG')
+dmlc_dep = dependency('dmlc', method: 'cmake', required: false)
 if not dmlc_dep.found()
         message('drivers/ml/cnxk: dmlc not found')
         enable_mvtvm = false
 endif
 
-tvm_dep = dependency('tvm', method: 'cmake', required: false, cmake_args: 
'CONFIG', modules : ['tvm::tvm_runtime'])
+tvm_dep = dependency('tvm', method: 'cmake', required: false, modules : 
['tvm::tvm_runtime'])
 if not tvm_dep.found()
         message('drivers/ml/cnxk: tvm_runtime not found')
         enable_mvtvm = false
 endif
 
-tvmdp_dep = dependency('tvmdp', method: 'pkg-config', required: false)
-if not tvmdp_dep.found()
-        message('drivers/ml/cnxk: tvmdp not found')
-        enable_mvtvm = false
-endif
-
 sources = files(
         'cn10k_ml_dev.c',
         'cn10k_ml_ops.c',
@@ -68,10 +62,10 @@ sources += files(
 )
 
 ext_deps += jansson_dep
+ext_deps += libarchive
 ext_deps += dlpack_dep
 ext_deps += dmlc_dep
 ext_deps += tvm_dep
-ext_deps += tvmdp_dep
 stdcpp_dep = cc.find_library('stdc++', required: true)
 if not cc.links(min_c_code, dependencies: stdcpp_dep)
     error('broken dependency, "libstdc++"')
diff --git a/drivers/ml/cnxk/mvtvm_ml_dev.h b/drivers/ml/cnxk/mvtvm_ml_dev.h
index 6922c193372..05e30f094cd 100644
--- a/drivers/ml/cnxk/mvtvm_ml_dev.h
+++ b/drivers/ml/cnxk/mvtvm_ml_dev.h
@@ -19,9 +19,6 @@ extern struct rte_ml_dev_ops cnxk_ml_ops;
 /* Maximum number of descriptors per queue-pair */
 #define ML_MVTVM_MAX_DESC_PER_QP 1024
 
-/* Maximum number of inputs / outputs per model */
-#define ML_MVTVM_MAX_INPUT_OUTPUT 32
-
 /* Maximum number of segments for IO data */
 #define ML_MVTVM_MAX_SEGMENTS 1
 
diff --git a/drivers/ml/cnxk/mvtvm_ml_model.c b/drivers/ml/cnxk/mvtvm_ml_model.c
index 4c7aa906da0..e1946607629 100644
--- a/drivers/ml/cnxk/mvtvm_ml_model.c
+++ b/drivers/ml/cnxk/mvtvm_ml_model.c
@@ -2,6 +2,12 @@
  * Copyright (c) 2023 Marvell.
  */
 
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include <archive.h>
 #include <archive_entry.h>
 
@@ -23,6 +29,7 @@ enum cnxk_ml_model_type
 mvtvm_ml_model_type_get(struct rte_ml_model_params *params)
 {
        bool object_found[ML_MVTVM_MODEL_OBJECT_MAX] = {false, false, false};
+       enum cnxk_ml_model_type model_type;
        struct archive_entry *entry;
        struct archive *a;
        uint8_t i;
@@ -33,9 +40,10 @@ mvtvm_ml_model_type_get(struct rte_ml_model_params *params)
        archive_read_support_filter_all(a);
        archive_read_support_format_all(a);
 
+       model_type = ML_CNXK_MODEL_TYPE_UNKNOWN;
        ret = archive_read_open_memory(a, params->addr, params->size);
        if (ret != ARCHIVE_OK)
-               return ML_CNXK_MODEL_TYPE_UNKNOWN;
+               goto cleanup;
 
        /* Parse buffer for available objects */
        while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
@@ -51,11 +59,18 @@ mvtvm_ml_model_type_get(struct rte_ml_model_params *params)
        for (i = 0; i < ML_MVTVM_MODEL_OBJECT_MAX; i++) {
                if (!object_found[i]) {
                        plt_err("Object %s not found in archive!", 
mvtvm_object_list[i]);
-                       return ML_CNXK_MODEL_TYPE_INVALID;
+                       model_type = ML_CNXK_MODEL_TYPE_INVALID;
+                       goto cleanup;
                }
        }
 
-       return ML_CNXK_MODEL_TYPE_TVM;
+       model_type = ML_CNXK_MODEL_TYPE_TVM;
+
+cleanup:
+       archive_read_close(a);
+       archive_read_free(a);
+
+       return model_type;
 }
 
 int
@@ -67,14 +82,18 @@ mvtvm_ml_model_blob_parse(struct rte_ml_model_params 
*params, struct mvtvm_ml_mo
        uint8_t i;
        int ret;
 
+       memset(object, 0, ML_MVTVM_MODEL_OBJECT_MAX * sizeof(*object));
+
        /* Open archive */
        a = archive_read_new();
        archive_read_support_filter_all(a);
        archive_read_support_format_all(a);
 
        ret = archive_read_open_memory(a, params->addr, params->size);
-       if (ret != ARCHIVE_OK)
-               return archive_errno(a);
+       if (ret != ARCHIVE_OK) {
+               ret = archive_errno(a);
+               goto cleanup;
+       }
 
        /* Read archive */
        while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
@@ -84,11 +103,16 @@ mvtvm_ml_model_blob_parse(struct rte_ml_model_params 
*params, struct mvtvm_ml_mo
                                memcpy(object[i].name, mvtvm_object_list[i], 
RTE_ML_STR_MAX);
                                object[i].size = archive_entry_size(entry);
                                object[i].buffer = rte_malloc(NULL, 
object[i].size, 0);
+                               if (object[i].buffer == NULL) {
+                                       ret = -ENOMEM;
+                                       goto error;
+                               }
 
                                if (archive_read_data(a, object[i].buffer, 
object[i].size) !=
                                    object[i].size) {
                                        plt_err("Failed to read object from 
model archive: %s",
                                                object[i].name);
+                                       ret = -EINVAL;
                                        goto error;
                                }
                                object_found[i] = true;
@@ -101,17 +125,24 @@ mvtvm_ml_model_blob_parse(struct rte_ml_model_params 
*params, struct mvtvm_ml_mo
        for (i = 0; i < ML_MVTVM_MODEL_OBJECT_MAX; i++) {
                if (!object_found[i]) {
                        plt_err("Object %s not found in archive!", 
mvtvm_object_list[i]);
+                       ret = -EINVAL;
                        goto error;
                }
        }
-       return 0;
+       ret = 0;
+       goto cleanup;
 
 error:
        for (i = 0; i < ML_MVTVM_MODEL_OBJECT_MAX; i++) {
-               rte_free(object[i].buffer);
+               if (object[i].buffer != NULL)
+                       rte_free(object[i].buffer);
        }
 
-       return -EINVAL;
+cleanup:
+       archive_read_close(a);
+       archive_read_free(a);
+
+       return ret;
 }
 
 int
@@ -119,12 +150,12 @@ mvtvm_ml_model_get_layer_id(struct cnxk_ml_model *model, 
const char *layer_name,
 {
        uint16_t i;
 
-       for (i = 0; i < model->mvtvm.metadata.model.nb_layers; i++) {
+       for (i = 0; i < model->nb_layers; i++) {
                if (strcmp(model->layer[i].name, layer_name) == 0)
                        break;
        }
 
-       if (i == model->mvtvm.metadata.model.nb_layers) {
+       if (i == model->nb_layers) {
                plt_err("Invalid layer name: %s", layer_name);
                return -EINVAL;
        }
@@ -139,6 +170,506 @@ mvtvm_ml_model_get_layer_id(struct cnxk_ml_model *model, 
const char *layer_name,
        return 0;
 }
 
+static void
+mvtvm_ml_param_names_free(struct mvtvm_ml_param_names *param_names)
+{
+       size_t i;
+
+       for (i = 0; i < param_names->count; i++)
+               free(param_names->name[i]);
+
+       free(param_names->name);
+       param_names->name = NULL;
+       param_names->count = 0;
+}
+
+static int
+mvtvm_ml_blob_read_u64(const uint8_t *blob, size_t blob_size, size_t *offset, 
uint64_t *value)
+{
+       if (*offset + sizeof(*value) > blob_size)
+               return -EINVAL;
+
+       memcpy(value, blob + *offset, sizeof(*value));
+       *offset += sizeof(*value);
+
+       return 0;
+}
+
+static int
+mvtvm_ml_param_names_parse(const uint8_t *blob, size_t blob_size,
+                          struct mvtvm_ml_param_names *param_names)
+{
+       uint64_t magic = 0;
+       uint64_t reserved = 0;
+       uint64_t count = 0;
+       size_t offset = 0;
+       int ret;
+       size_t i;
+
+       memset(param_names, 0, sizeof(*param_names));
+
+       ret = mvtvm_ml_blob_read_u64(blob, blob_size, &offset, &magic);
+       if (ret != 0)
+               return ret;
+
+       if (magic != TVM_NDARRAY_LIST_MAGIC)
+               return -EINVAL;
+
+       ret = mvtvm_ml_blob_read_u64(blob, blob_size, &offset, &reserved);
+       if (ret != 0)
+               return ret;
+
+       ret = mvtvm_ml_blob_read_u64(blob, blob_size, &offset, &count);
+       if (ret != 0)
+               return ret;
+
+       if (count > SIZE_MAX / sizeof(*param_names->name))
+               return -EINVAL;
+
+       param_names->name = calloc(count, sizeof(*param_names->name));
+       if (count != 0 && param_names->name == NULL)
+               return -ENOMEM;
+
+       param_names->count = count;
+       for (i = 0; i < count; i++) {
+               uint64_t name_len = 0;
+
+               ret = mvtvm_ml_blob_read_u64(blob, blob_size, &offset, 
&name_len);
+               if (ret != 0)
+                       goto error;
+
+               if (name_len == SIZE_MAX) {
+                       ret = -EINVAL;
+                       goto error;
+               }
+
+               if (offset + name_len > blob_size) {
+                       ret = -EINVAL;
+                       goto error;
+               }
+
+               param_names->name[i] = calloc(name_len + 1, 1);
+               if (param_names->name[i] == NULL) {
+                       ret = -ENOMEM;
+                       goto error;
+               }
+
+               memcpy(param_names->name[i], blob + offset, name_len);
+               offset += name_len;
+       }
+
+       return 0;
+
+error:
+       mvtvm_ml_param_names_free(param_names);
+       return ret;
+}
+
+static int
+mvtvm_ml_dtype_parse(const char *dtype_str, DLDataType *dtype)
+{
+       const char *lanes_str;
+       char base[32] = {0};
+       long bits;
+       long lanes = 1;
+
+       if (dtype_str == NULL || dtype == NULL)
+               return -EINVAL;
+
+       lanes_str = strchr(dtype_str, 'x');
+       if (lanes_str != NULL) {
+               size_t base_len = lanes_str - dtype_str;
+
+               if (base_len >= sizeof(base))
+                       return -EINVAL;
+               memcpy(base, dtype_str, base_len);
+               lanes = strtol(lanes_str + 1, NULL, 10);
+               if (lanes <= 0 || lanes > UINT16_MAX)
+                       return -EINVAL;
+       } else {
+               snprintf(base, sizeof(base), "%s", dtype_str);
+       }
+
+       memset(dtype, 0, sizeof(*dtype));
+       dtype->lanes = (uint16_t)lanes;
+
+       if (strncmp(base, "int", 3) == 0) {
+               bits = strtol(base + 3, NULL, 10);
+               dtype->code = kDLInt;
+       } else if (strncmp(base, "uint", 4) == 0) {
+               bits = strtol(base + 4, NULL, 10);
+               dtype->code = kDLUInt;
+       } else if (strncmp(base, "float", 5) == 0) {
+               bits = strtol(base + 5, NULL, 10);
+               dtype->code = kDLFloat;
+       } else if (strncmp(base, "bfloat", 6) == 0) {
+               bits = strtol(base + 6, NULL, 10);
+               dtype->code = kDLBfloat;
+       } else if (strcmp(base, "bool") == 0) {
+               bits = 1;
+               dtype->code = kDLUInt;
+       } else {
+               return -EINVAL;
+       }
+
+       if (bits <= 0 || bits > UINT8_MAX)
+               return -EINVAL;
+
+       dtype->bits = (uint8_t)bits;
+
+       return 0;
+}
+
+static int
+mvtvm_ml_model_io_set(struct cnxk_ml_io *io, const char *name, json_t *shape, 
const char *dtype_str,
+                     DLDevice device)
+{
+       size_t i;
+       int ret;
+
+       memset(io, 0, sizeof(*io));
+       if (name != NULL)
+               snprintf(io->name, sizeof(io->name), "%s", name);
+
+       if (!json_is_array(shape))
+               return -EINVAL;
+
+       io->nb_dims = json_array_size(shape);
+       if (io->nb_dims > ML_CNXK_MODEL_MAX_DIMS)
+               return -ENOTSUP;
+
+       for (i = 0; i < (size_t)io->nb_dims; i++) {
+               json_t *dim = json_array_get(shape, i);
+
+               if (!json_is_integer(dim))
+                       return -EINVAL;
+               io->shape_i64[i] = json_integer_value(dim);
+       }
+
+       ret = mvtvm_ml_dtype_parse(dtype_str, &io->datatype);
+       if (ret != 0)
+               return ret;
+
+       io->model_datatype = io->datatype;
+       io->scale = 1.0f;
+       io->device = device;
+
+       return 0;
+}
+
+static int
+mvtvm_ml_json_graph_get_arrays(json_t *json_parsed, json_t **nodes, json_t 
**arg_nodes,
+                              json_t **heads, json_t **node_row_ptr, json_t 
**shape_values,
+                              json_t **dtype_values)
+{
+       json_t *attrs;
+       json_t *shape_attr;
+       json_t *dtype_attr;
+
+       *nodes = json_object_get(json_parsed, "nodes");
+       *arg_nodes = json_object_get(json_parsed, "arg_nodes");
+       *heads = json_object_get(json_parsed, "heads");
+       *node_row_ptr = json_object_get(json_parsed, "node_row_ptr");
+       attrs = json_object_get(json_parsed, "attrs");
+
+       if (!json_is_array(*nodes) || !json_is_array(*arg_nodes) || 
!json_is_array(*heads) ||
+           !json_is_array(*node_row_ptr) || !json_is_object(attrs))
+               return -EINVAL;
+
+       if (json_array_size(*node_row_ptr) != json_array_size(*nodes) + 1)
+               return -EINVAL;
+
+       shape_attr = json_object_get(attrs, "shape");
+       dtype_attr = json_object_get(attrs, "dltype");
+       if (!json_is_array(shape_attr) || json_array_size(shape_attr) < 2 ||
+           !json_is_array(dtype_attr) || json_array_size(dtype_attr) < 2)
+               return -EINVAL;
+
+       *shape_values = json_array_get(shape_attr, 1);
+       *dtype_values = json_array_get(dtype_attr, 1);
+
+       if (!json_is_array(*shape_values) || !json_is_array(*dtype_values))
+               return -EINVAL;
+
+       return 0;
+}
+
+int
+mvtvm_ml_model_json_parse(struct cnxk_ml_model *model)
+{
+       struct mvtvm_ml_param_names param_names;
+       json_error_t json_error;
+       json_t *json_parsed;
+       json_t *json_nodes;
+       json_t *json_arg_nodes;
+       json_t *json_heads;
+       json_t *json_node_row_ptr;
+       json_t *json_shape_values;
+       json_t *json_dtype_values;
+       uint16_t nb_mrvl_layers;
+       uint16_t nb_llvm_layers;
+       DLDevice device;
+       int ret;
+       size_t i;
+       size_t j;
+
+       /* Parse param names from params buffer */
+       ret = mvtvm_ml_param_names_parse(model->mvtvm.params.buffer, 
model->mvtvm.params.size,
+                                        &param_names);
+       if (ret != 0)
+               return ret;
+
+       /* Load JSON graph (single load for both stages) */
+       json_parsed = json_loadb((const char *)model->mvtvm.json.buffer, 
model->mvtvm.json.size, 0,
+                                &json_error);
+       if (json_parsed == NULL) {
+               mvtvm_ml_param_names_free(&param_names);
+               plt_err("TVM runtime: Failed to parse JSON graph, model_id = 
%u", model->model_id);
+               return -EINVAL;
+       }
+
+       /* Parse nodes to extract layer info */
+       json_nodes = json_object_get(json_parsed, "nodes");
+       if (!json_is_array(json_nodes)) {
+               ret = -EINVAL;
+               plt_err("TVM runtime: Failed to parse JSON nodes, model_id = 
%u, error = %d",
+                       model->model_id, ret);
+               goto error;
+       }
+
+       model->nb_layers = 0;
+       nb_mrvl_layers = 0;
+       nb_llvm_layers = 0;
+       for (i = 0; i < json_array_size(json_nodes); i++) {
+               json_t *node = json_array_get(json_nodes, i);
+               json_t *op = json_object_get(node, "op");
+               json_t *name;
+               json_t *attrs;
+               json_t *compiler;
+
+               if (!json_is_string(op) || strcmp(json_string_value(op), 
"tvm_op") != 0)
+                       continue;
+
+               if (model->nb_layers >= ML_CNXK_MODEL_MAX_LAYERS) {
+                       ret = -ENOTSUP;
+                       plt_err("TVM runtime: Number of layers exceeds maximum 
(%u), model_id = %u, error = %d",
+                               ML_CNXK_MODEL_MAX_LAYERS, model->model_id, ret);
+                       goto error;
+               }
+
+               name = json_object_get(node, "name");
+               if (!json_is_string(name)) {
+                       ret = -EINVAL;
+                       plt_err("TVM runtime: Failed to parse JSON node name, 
model_id = %u, error = %d",
+                               model->model_id, ret);
+                       goto error;
+               }
+
+               if (json_string_value(name) != NULL)
+                       snprintf(model->layer[model->nb_layers].name,
+                                sizeof(model->layer[model->nb_layers].name), 
"%s",
+                                json_string_value(name));
+               else
+                       snprintf(model->layer[model->nb_layers].name,
+                                sizeof(model->layer[model->nb_layers].name), 
"tvm_layer_%u",
+                                model->nb_layers);
+
+               attrs = json_object_get(node, "attrs");
+               compiler = json_is_object(attrs) ? json_object_get(attrs, 
"Compiler") : NULL;
+               if (json_is_string(compiler)) {
+                       if (strcmp(json_string_value(compiler), "mrvl") == 0 ||
+                           strcmp(json_string_value(compiler), "MRVL") == 0) {
+                               model->layer[model->nb_layers].type = 
ML_CNXK_LAYER_TYPE_MRVL;
+                               nb_mrvl_layers++;
+                       } else {
+                               model->layer[model->nb_layers].type = 
ML_CNXK_LAYER_TYPE_UNKNOWN;
+                       }
+               } else {
+                       model->layer[model->nb_layers].type = 
ML_CNXK_LAYER_TYPE_LLVM;
+                       nb_llvm_layers++;
+               }
+               model->nb_layers++;
+       }
+
+       /* Set model fields */
+       snprintf(model->name, sizeof(model->name), "tvm_model_%u", 
model->model_id);
+       model->batch_size = 1;
+
+       /* Validate layer counts */
+       if ((nb_llvm_layers == 0) && (nb_mrvl_layers == 0)) {
+               plt_err("Invalid model, nb_llvm_layers = %u, nb_mrvl_layers = 
%u", nb_llvm_layers,
+                       nb_mrvl_layers);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (nb_llvm_layers + nb_mrvl_layers != model->nb_layers) {
+               plt_err("Invalid model, nb_llvm_layers = %u, nb_mrvl_layers = 
%u, nb_layers = %u",
+                       nb_llvm_layers, nb_mrvl_layers, model->nb_layers);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* Set model subtype */
+       if ((nb_llvm_layers == 0) && (nb_mrvl_layers == 1))
+               model->subtype = ML_CNXK_MODEL_SUBTYPE_TVM_MRVL;
+       else if ((nb_llvm_layers > 0) && (nb_mrvl_layers == 0))
+               model->subtype = ML_CNXK_MODEL_SUBTYPE_TVM_LLVM;
+       else
+               model->subtype = ML_CNXK_MODEL_SUBTYPE_TVM_HYBRID;
+
+       /* Parse I/O info from the same JSON graph */
+       device.device_type = kDLCPU;
+       device.device_id = 0;
+
+       ret = mvtvm_ml_json_graph_get_arrays(json_parsed, &json_nodes, 
&json_arg_nodes, &json_heads,
+                                            &json_node_row_ptr, 
&json_shape_values,
+                                            &json_dtype_values);
+       if (ret == 0) {
+               model->mvtvm.info.nb_inputs = 0;
+               model->mvtvm.info.nb_outputs = 0;
+
+               for (i = 0; i < json_array_size(json_arg_nodes); i++) {
+                       json_t *arg_node_idx = json_array_get(json_arg_nodes, 
i);
+                       json_t *node;
+                       json_t *shape;
+                       json_t *dtype;
+                       json_t *name;
+                       json_int_t node_id;
+
+                       if (!json_is_integer(arg_node_idx)) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       node_id = json_integer_value(arg_node_idx);
+                       node = json_array_get(json_nodes, node_id);
+                       shape = json_array_get(json_shape_values, node_id);
+                       dtype = json_array_get(json_dtype_values, node_id);
+                       name = json_object_get(node, "name");
+                       if (!json_is_object(node) || !json_is_array(shape) ||
+                           !json_is_string(dtype) || !json_is_string(name)) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       for (j = 0; j < param_names.count; j++) {
+                               if (strcmp(param_names.name[j], 
json_string_value(name)) == 0)
+                                       break;
+                       }
+
+                       if (j < param_names.count)
+                               continue;
+
+                       if (model->mvtvm.info.nb_inputs >= 
ML_CNXK_MODEL_MAX_INPUT_OUTPUT) {
+                               ret = -ENOTSUP;
+                               break;
+                       }
+
+                       ret = mvtvm_ml_model_io_set(
+                               
&model->mvtvm.info.input[model->mvtvm.info.nb_inputs],
+                               json_string_value(name), shape, 
json_string_value(dtype), device);
+                       if (ret != 0)
+                               break;
+
+                       model->mvtvm.info.nb_inputs++;
+               }
+
+               for (i = 0; ret == 0 && i < json_array_size(json_heads); i++) {
+                       json_t *head = json_array_get(json_heads, i);
+                       json_t *node;
+                       json_t *shape;
+                       json_t *dtype;
+                       json_t *name;
+                       json_t *node_id_json;
+                       json_t *output_idx_json;
+                       json_t *entry_base_json;
+                       json_t *entry_limit_json;
+                       json_int_t node_id;
+                       json_int_t output_idx;
+                       json_int_t entry_base;
+                       json_int_t entry_limit;
+                       size_t entry_id;
+
+                       if (!json_is_array(head) || json_array_size(head) < 2) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       node_id_json = json_array_get(head, 0);
+                       output_idx_json = json_array_get(head, 1);
+                       if (!json_is_integer(node_id_json) || 
!json_is_integer(output_idx_json)) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       node_id = json_integer_value(node_id_json);
+                       output_idx = json_integer_value(output_idx_json);
+                       if (node_id < 0 || output_idx < 0) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       node = json_array_get(json_nodes, (size_t)node_id);
+                       entry_base_json = json_array_get(json_node_row_ptr, 
(size_t)node_id);
+                       entry_limit_json = json_array_get(json_node_row_ptr, 
(size_t)node_id + 1);
+                       if (!json_is_object(node) || 
!json_is_integer(entry_base_json) ||
+                           !json_is_integer(entry_limit_json)) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       entry_base = json_integer_value(entry_base_json);
+                       entry_limit = json_integer_value(entry_limit_json);
+                       if (entry_base < 0 || entry_limit < entry_base) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       if (output_idx >= (entry_limit - entry_base)) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       entry_id = (size_t)entry_base + (size_t)output_idx;
+                       shape = json_array_get(json_shape_values, entry_id);
+                       dtype = json_array_get(json_dtype_values, entry_id);
+                       name = json_object_get(node, "name");
+                       if (!json_is_array(shape) || !json_is_string(dtype) ||
+                           !json_is_string(name)) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       if (model->mvtvm.info.nb_outputs >= 
ML_CNXK_MODEL_MAX_INPUT_OUTPUT) {
+                               ret = -ENOTSUP;
+                               break;
+                       }
+
+                       ret = mvtvm_ml_model_io_set(
+                               
&model->mvtvm.info.output[model->mvtvm.info.nb_outputs],
+                               json_string_value(name), shape, 
json_string_value(dtype), device);
+                       if (ret != 0)
+                               break;
+
+                       model->mvtvm.info.nb_outputs++;
+               }
+       }
+
+       if (ret != 0)
+               plt_err("TVM runtime: Failed to get metadata, model_id = %u, 
error = %d",
+                       model->model_id, ret);
+
+       json_decref(json_parsed);
+       mvtvm_ml_param_names_free(&param_names);
+       return ret;
+
+error:
+       json_decref(json_parsed);
+       mvtvm_ml_param_names_free(&param_names);
+       return ret;
+}
+
 static enum rte_ml_io_type
 mvtvm_ml_io_type_map(DLDataType dltype)
 {
@@ -185,32 +716,27 @@ mvtvm_ml_io_type_map(DLDataType dltype)
 void
 mvtvm_ml_model_io_info_set(struct cnxk_ml_model *model)
 {
-       struct tvmdp_model_metadata *metadata;
        int32_t i;
-       int32_t j;
+       uint32_t j;
 
        if (model->subtype == ML_CNXK_MODEL_SUBTYPE_TVM_MRVL)
                goto tvm_mrvl_model;
 
-       metadata = &model->mvtvm.metadata;
-
        /* Inputs, set for layer_id = 0 */
-       model->mvtvm.info.nb_inputs = metadata->model.num_input;
        model->mvtvm.info.total_input_sz_d = 0;
        model->mvtvm.info.total_input_sz_q = 0;
-       for (i = 0; i < metadata->model.num_input; i++) {
-               rte_strscpy(model->mvtvm.info.input[i].name, 
metadata->input[i].name,
-                           TVMDP_NAME_STRLEN);
+       for (i = 0; i < model->mvtvm.info.nb_inputs; i++) {
                model->mvtvm.info.input[i].dtype =
-                       mvtvm_ml_io_type_map(metadata->input[i].datatype);
+                       
mvtvm_ml_io_type_map(model->mvtvm.info.input[i].datatype);
                model->mvtvm.info.input[i].qtype =
-                       mvtvm_ml_io_type_map(metadata->input[i].model_datatype);
-               model->mvtvm.info.input[i].nb_dims = metadata->input[i].ndim;
+                       
mvtvm_ml_io_type_map(model->mvtvm.info.input[i].model_datatype);
 
                model->mvtvm.info.input[i].nb_elements = 1;
-               for (j = 0; j < metadata->input[i].ndim; j++) {
-                       model->mvtvm.info.input[i].shape[j] = 
metadata->input[i].shape[j];
-                       model->mvtvm.info.input[i].nb_elements *= 
metadata->input[i].shape[j];
+               for (j = 0; j < model->mvtvm.info.input[i].nb_dims; j++) {
+                       model->mvtvm.info.input[i].shape[j] =
+                               
PLT_U32_CAST(model->mvtvm.info.input[i].shape_i64[j]);
+                       model->mvtvm.info.input[i].nb_elements *=
+                               model->mvtvm.info.input[i].shape[j];
                }
 
                model->mvtvm.info.input[i].sz_d =
@@ -219,15 +745,14 @@ mvtvm_ml_model_io_info_set(struct cnxk_ml_model *model)
                model->mvtvm.info.input[i].sz_q =
                        model->mvtvm.info.input[i].nb_elements *
                        
rte_ml_io_type_size_get(model->mvtvm.info.input[i].qtype);
-               model->mvtvm.info.input[i].scale = metadata->input[i].scale;
 
                model->mvtvm.info.total_input_sz_d += 
model->mvtvm.info.input[i].sz_d;
                model->mvtvm.info.total_input_sz_q += 
model->mvtvm.info.input[i].sz_q;
 
-               model->mvtvm.input_tensor[i].device = metadata->input[i].device;
-               model->mvtvm.input_tensor[i].ndim = metadata->input[i].ndim;
-               model->mvtvm.input_tensor[i].dtype = 
metadata->input[i].datatype;
-               model->mvtvm.input_tensor[i].shape = metadata->input[i].shape;
+               model->mvtvm.input_tensor[i].device = 
model->mvtvm.info.input[i].device;
+               model->mvtvm.input_tensor[i].ndim = 
model->mvtvm.info.input[i].nb_dims;
+               model->mvtvm.input_tensor[i].dtype = 
model->mvtvm.info.input[i].datatype;
+               model->mvtvm.input_tensor[i].shape = 
model->mvtvm.info.input[i].shape_i64;
                model->mvtvm.input_tensor[i].strides = NULL;
                model->mvtvm.input_tensor[i].byte_offset = 0;
 
@@ -236,22 +761,20 @@ mvtvm_ml_model_io_info_set(struct cnxk_ml_model *model)
        }
 
        /* Outputs, set for nb_layers - 1 */
-       model->mvtvm.info.nb_outputs = metadata->model.num_output;
        model->mvtvm.info.total_output_sz_d = 0;
        model->mvtvm.info.total_output_sz_q = 0;
-       for (i = 0; i < metadata->model.num_output; i++) {
-               rte_strscpy(model->mvtvm.info.output[i].name, 
metadata->output[i].name,
-                           TVMDP_NAME_STRLEN);
+       for (i = 0; i < model->mvtvm.info.nb_outputs; i++) {
                model->mvtvm.info.output[i].dtype =
-                       mvtvm_ml_io_type_map(metadata->output[i].datatype);
+                       
mvtvm_ml_io_type_map(model->mvtvm.info.output[i].datatype);
                model->mvtvm.info.output[i].qtype =
-                       
mvtvm_ml_io_type_map(metadata->output[i].model_datatype);
-               model->mvtvm.info.output[i].nb_dims = metadata->output[i].ndim;
+                       
mvtvm_ml_io_type_map(model->mvtvm.info.output[i].model_datatype);
 
                model->mvtvm.info.output[i].nb_elements = 1;
-               for (j = 0; j < metadata->output[i].ndim; j++) {
-                       model->mvtvm.info.output[i].shape[j] = 
metadata->output[i].shape[j];
-                       model->mvtvm.info.output[i].nb_elements *= 
metadata->output[i].shape[j];
+               for (j = 0; j < model->mvtvm.info.output[i].nb_dims; j++) {
+                       model->mvtvm.info.output[i].shape[j] =
+                               
PLT_U32_CAST(model->mvtvm.info.output[i].shape_i64[j]);
+                       model->mvtvm.info.output[i].nb_elements *=
+                               model->mvtvm.info.output[i].shape[j];
                }
 
                model->mvtvm.info.output[i].sz_d =
@@ -260,15 +783,14 @@ mvtvm_ml_model_io_info_set(struct cnxk_ml_model *model)
                model->mvtvm.info.output[i].sz_q =
                        model->mvtvm.info.output[i].nb_elements *
                        
rte_ml_io_type_size_get(model->mvtvm.info.output[i].qtype);
-               model->mvtvm.info.output[i].scale = metadata->output[i].scale;
 
                model->mvtvm.info.total_output_sz_d += 
model->mvtvm.info.output[i].sz_d;
                model->mvtvm.info.total_output_sz_q += 
model->mvtvm.info.output[i].sz_q;
 
-               model->mvtvm.output_tensor[i].device = 
metadata->output[i].device;
-               model->mvtvm.output_tensor[i].ndim = metadata->output[i].ndim;
-               model->mvtvm.output_tensor[i].dtype = 
metadata->output[i].datatype;
-               model->mvtvm.output_tensor[i].shape = metadata->output[i].shape;
+               model->mvtvm.output_tensor[i].device = 
model->mvtvm.info.output[i].device;
+               model->mvtvm.output_tensor[i].ndim = 
model->mvtvm.info.output[i].nb_dims;
+               model->mvtvm.output_tensor[i].dtype = 
model->mvtvm.info.output[i].datatype;
+               model->mvtvm.output_tensor[i].shape = 
model->mvtvm.info.output[i].shape_i64;
                model->mvtvm.output_tensor[i].strides = NULL;
                model->mvtvm.output_tensor[i].byte_offset = 0;
 
@@ -293,7 +815,6 @@ mvtvm_ml_model_io_info_get(struct cnxk_ml_model *model, 
uint16_t layer_id)
 void
 mvtvm_ml_model_info_set(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_model 
*model)
 {
-       struct tvmdp_model_metadata *metadata;
        struct rte_ml_model_info *info;
        struct rte_ml_io_info *output;
        struct rte_ml_io_info *input;
@@ -309,26 +830,23 @@ mvtvm_ml_model_info_set(struct cnxk_ml_dev *cnxk_mldev, 
struct cnxk_ml_model *mo
        if (model->subtype == ML_CNXK_MODEL_SUBTYPE_TVM_MRVL)
                goto tvm_mrvl_model;
 
-       metadata = &model->mvtvm.metadata;
-       rte_memcpy(info->name, metadata->model.name, TVMDP_NAME_STRLEN);
-       snprintf(info->version, RTE_ML_STR_MAX, "%u.%u.%u.%u", 
metadata->model.version[0],
-                metadata->model.version[1], metadata->model.version[2],
-                metadata->model.version[3]);
+       rte_memcpy(info->name, model->name, RTE_ML_STR_MAX);
+       snprintf(info->version, RTE_ML_STR_MAX, "%u.%u.%u.%u", 0, 0, 0, 0);
        info->model_id = model->model_id;
        info->device_id = cnxk_mldev->mldev->data->dev_id;
        info->io_layout = RTE_ML_IO_LAYOUT_SPLIT;
        info->min_batches = model->batch_size;
        info->max_batches = model->batch_size;
-       info->nb_inputs = metadata->model.num_input;
+       info->nb_inputs = model->mvtvm.info.nb_inputs;
        info->input_info = input;
-       info->nb_outputs = metadata->model.num_output;
+       info->nb_outputs = model->mvtvm.info.nb_outputs;
        info->output_info = output;
        info->wb_size = 0;
 
        /* Set input info */
        for (i = 0; i < info->nb_inputs; i++) {
-               rte_memcpy(input[i].name, metadata->input[i].name, 
MRVL_ML_INPUT_NAME_LEN);
-               input[i].nb_dims = metadata->input[i].ndim;
+               rte_memcpy(input[i].name, model->mvtvm.info.input[i].name, 
MRVL_ML_INPUT_NAME_LEN);
+               input[i].nb_dims = model->mvtvm.info.input[i].nb_dims;
                input[i].shape = &model->mvtvm.info.input[i].shape[0];
                input[i].type = model->mvtvm.info.input[i].qtype;
                input[i].nb_elements = model->mvtvm.info.input[i].nb_elements;
@@ -340,15 +858,16 @@ mvtvm_ml_model_info_set(struct cnxk_ml_dev *cnxk_mldev, 
struct cnxk_ml_model *mo
 
        /* Set output info */
        for (i = 0; i < info->nb_outputs; i++) {
-               rte_memcpy(output[i].name, metadata->output[i].name, 
MRVL_ML_OUTPUT_NAME_LEN);
-               output[i].nb_dims = metadata->output[i].ndim;
+               rte_memcpy(output[i].name, model->mvtvm.info.output[i].name,
+                          MRVL_ML_OUTPUT_NAME_LEN);
+               output[i].nb_dims = model->mvtvm.info.output[i].nb_dims;
                output[i].shape = &model->mvtvm.info.output[i].shape[0];
                output[i].type = model->mvtvm.info.output[i].qtype;
                output[i].nb_elements = model->mvtvm.info.output[i].nb_elements;
                output[i].size = model->mvtvm.info.output[i].nb_elements *
                                 
rte_ml_io_type_size_get(model->mvtvm.info.output[i].qtype);
-               input[i].scale = model->mvtvm.info.output[i].scale;
-               input[i].zero_point = 0;
+               output[i].scale = model->mvtvm.info.output[i].scale;
+               output[i].zero_point = 0;
        }
 
        return;
@@ -357,8 +876,7 @@ mvtvm_ml_model_info_set(struct cnxk_ml_dev *cnxk_mldev, 
struct cnxk_ml_model *mo
        cn10k_ml_model_info_set(cnxk_mldev, model, &model->mvtvm.info,
                                &model->layer[0].glow.metadata);
 
-       metadata = &model->mvtvm.metadata;
-       strlcpy(info->name, metadata->model.name, TVMDP_NAME_STRLEN);
+       strlcpy(info->name, model->name, RTE_ML_STR_MAX);
 
        info->io_layout = RTE_ML_IO_LAYOUT_PACKED;
 }
diff --git a/drivers/ml/cnxk/mvtvm_ml_model.h b/drivers/ml/cnxk/mvtvm_ml_model.h
index 7ffce380945..1151b0a39ed 100644
--- a/drivers/ml/cnxk/mvtvm_ml_model.h
+++ b/drivers/ml/cnxk/mvtvm_ml_model.h
@@ -5,7 +5,21 @@
 #ifndef _MVTVM_ML_MODEL_H_
 #define _MVTVM_ML_MODEL_H_
 
-#include <tvmdp.h>
+#include <dlpack/dlpack.h>
+#include <jansson.h>
+#include <rte_common.h>
+
+#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
+__rte_diagnostic_push
+RTE_PRAGMA(GCC diagnostic ignored "-Wstrict-prototypes")
+#include <tvm/runtime/c_runtime_api.h>
+__rte_diagnostic_pop
+#else
+#include <tvm/runtime/c_runtime_api.h>
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
 
 #include <rte_mldev.h>
 
@@ -18,19 +32,56 @@ struct cnxk_ml_layer;
 /* Maximum number of objects per model */
 #define ML_MVTVM_MODEL_OBJECT_MAX 3
 
-/* Objects list */
-extern char mvtvm_object_list[ML_MVTVM_MODEL_OBJECT_MAX][RTE_ML_STR_MAX];
+/* Magic number for TVM parameter blobs. */
+#define TVM_NDARRAY_LIST_MAGIC 0xF7E58D4F05049CB7ULL
 
-/* Model object structure */
+/* TVM parameter names structure */
+struct mvtvm_ml_param_names {
+       char **name;
+       size_t count;
+};
+
+/* TVM object / artifact info structure */
 struct mvtvm_ml_model_object {
        /* Name */
        char name[RTE_ML_STR_MAX];
 
-       /* Temporary buffer */
+       /* Buffer address */
        uint8_t *buffer;
 
        /* Buffer size */
        int64_t size;
+
+       /* Offset */
+       uint32_t offset;
+};
+
+/* Glow model callback functions */
+typedef int (*tvmrt_glow_layer_load_cb)(void *device, uint16_t model_id, const 
char *layer_name,
+                                       uint8_t *buffer, size_t size, uint16_t 
*index);
+typedef int (*tvmrt_glow_layer_unload_cb)(void *device, uint16_t model_id, 
const char *layer_name);
+typedef int (*tvmrt_io_alloc_cb)(void *device, uint16_t model_id, const char 
*layer_name,
+                                uint64_t **input_qbuffer, uint64_t 
**output_qbuffer);
+typedef int (*tvmrt_io_free_cb)(void *device, uint16_t model_id, const char 
*layer_name);
+typedef int (*tvmrt_malloc_cb)(const char *name, size_t size, uint32_t align, 
void **addr);
+typedef int (*tvmrt_free_cb)(const char *name);
+typedef int (*tvmrt_quantize_cb)(void *device, uint16_t model_id, const char 
*layer_name,
+                                const DLTensor **deq_tensor, void *qbuffer);
+typedef int (*tvmrt_dequantize_cb)(void *device, uint16_t model_id, const char 
*layer_name,
+                                  void *qbuffer, const DLTensor **deq_tensor);
+typedef int (*tvmrt_inference_cb)(void *device, uint16_t index, void *input, 
void *output,
+                                 uint16_t nb_batches);
+
+struct tvmrt_glow_callback {
+       tvmrt_glow_layer_load_cb tvmrt_glow_layer_load;
+       tvmrt_glow_layer_unload_cb tvmrt_glow_layer_unload;
+       tvmrt_io_alloc_cb tvmrt_io_alloc;
+       tvmrt_io_free_cb tvmrt_io_free;
+       tvmrt_malloc_cb tvmrt_malloc;
+       tvmrt_free_cb tvmrt_free;
+       tvmrt_quantize_cb tvmrt_quantize;
+       tvmrt_dequantize_cb tvmrt_dequantize;
+       tvmrt_inference_cb tvmrt_inference;
 };
 
 /* Model fast-path stats */
@@ -55,15 +106,26 @@ struct mvtvm_ml_model_xstats {
 };
 
 struct mvtvm_ml_model_data {
-       /* Model metadata */
-       struct tvmdp_model_metadata metadata;
-
        /* Model objects */
-       struct tvmdp_model_object object;
+       struct mvtvm_ml_model_object so;
+       struct mvtvm_ml_model_object json;
+       struct mvtvm_ml_model_object params;
 
        /* TVM runtime callbacks */
        struct tvmrt_glow_callback cb;
 
+       /* TVM Graph Module */
+       TVMModuleHandle graph_module;
+
+       /* Shared object memfd used to load the TVM module */
+       int fd;
+
+       /* TVM Function Handles */
+       TVMFunctionHandle load_params;
+       TVMFunctionHandle set_input_zero_copy;
+       TVMFunctionHandle set_output_zero_copy;
+       TVMFunctionHandle run;
+
        /* Model I/O info */
        struct cnxk_ml_io_info info;
 
@@ -86,5 +148,6 @@ void mvtvm_ml_model_io_info_set(struct cnxk_ml_model *model);
 struct cnxk_ml_io_info *mvtvm_ml_model_io_info_get(struct cnxk_ml_model 
*model, uint16_t layer_id);
 void mvtvm_ml_model_info_set(struct cnxk_ml_dev *cnxk_mldev, struct 
cnxk_ml_model *model);
 void mvtvm_ml_layer_print(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_layer 
*layer, FILE *fp);
+int mvtvm_ml_model_json_parse(struct cnxk_ml_model *model);
 
 #endif /* _MVTVM_ML_MODEL_H_ */
diff --git a/drivers/ml/cnxk/mvtvm_ml_ops.c b/drivers/ml/cnxk/mvtvm_ml_ops.c
index 80b22460db9..bc47a4bbd75 100644
--- a/drivers/ml/cnxk/mvtvm_ml_ops.c
+++ b/drivers/ml/cnxk/mvtvm_ml_ops.c
@@ -2,7 +2,17 @@
  * Copyright (c) 2023 Marvell.
  */
 
+#include <errno.h>
+#include <linux/limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
 #include <dlpack/dlpack.h>
+#include <jansson.h>
 
 #include <rte_common.h>
 #include <rte_cycles.h>
@@ -19,6 +29,76 @@
 /* ML model macros */
 #define MVTVM_ML_MODEL_MEMZONE_NAME "ml_mvtvm_model_mz"
 
+/* Shared memory file descriptor name */
+#define ML_MODEL_SHMFD_NAME "mvtvm_shmfd"
+
+/* Shared memory file descriptor path */
+#define ML_MODEL_SHMFD_PATH "/proc/%d/fd/%d"
+
+static int
+mvtvm_ml_tvm_func_get(struct cnxk_ml_model *model, TVMModuleHandle module, 
const char *name,
+                     TVMFunctionHandle *func)
+{
+       int ret;
+
+       ret = TVMModGetFunction(module, name, 0, func);
+       if (ret != 0) {
+               plt_err("Model load failed, model_id = %u, ret = %d, msg = %s", 
model->model_id,
+                       ret, TVMGetLastError());
+               return ret;
+       }
+
+       if (*func == NULL) {
+               ret = -ENOENT;
+               plt_err("Model load failed, model_id = %u, function '%s' not 
found",
+                       model->model_id, name);
+       }
+
+       return ret;
+}
+
+static int
+mvtvm_ml_tvm_func_call(struct cnxk_ml_model *model, TVMFunctionHandle func, 
const char *name,
+                      TVMValue *values, int *types, int num_args, TVMValue 
*ret_val, int *ret_type,
+                      int ret_type_code)
+{
+       int ret;
+
+       ret = TVMFuncCall(func, values, types, num_args, ret_val, ret_type);
+       if (ret != 0) {
+               plt_err("Error calling TVM function '%s', model_id = %u, ret = 
%d, msg = %s", name,
+                       model->model_id, ret, TVMGetLastError());
+               return ret;
+       }
+
+       if (*ret_type != ret_type_code) {
+               ret = -EINVAL;
+               plt_err("TVM function '%s' returned unexpected type, model_id = 
%u, expected = %d, "
+                       "actual = %d",
+                       name, model->model_id, ret_type_code, *ret_type);
+       }
+
+       return ret;
+}
+
+static void
+mvtvm_ml_tvm_func_free(TVMFunctionHandle *func)
+{
+       if ((func != NULL) && (*func != NULL)) {
+               TVMFuncFree(*func);
+               *func = NULL;
+       }
+}
+
+static void
+mvtvm_ml_tvm_mod_free(TVMModuleHandle *mod)
+{
+       if ((mod != NULL) && (*mod != NULL)) {
+               TVMModFree(*mod);
+               *mod = NULL;
+       }
+}
+
 __rte_hot static void
 mvtvm_ml_set_poll_addr(struct cnxk_ml_req *req)
 {
@@ -30,8 +110,8 @@ mvtvm_ml_model_xstat_name_set(struct cnxk_ml_dev 
*cnxk_mldev, struct cnxk_ml_mod
                              uint16_t stat_id, uint16_t entry, char *suffix)
 {
        snprintf(cnxk_mldev->xstats.entries[stat_id].map.name,
-                sizeof(cnxk_mldev->xstats.entries[stat_id].map.name), 
"%s-%s-%s",
-                model->mvtvm.metadata.model.name, model_xstats[entry].name, 
suffix);
+                sizeof(cnxk_mldev->xstats.entries[stat_id].map.name), 
"%s-%s-%s", model->name,
+                model_xstats[entry].name, suffix);
 }
 
 #define ML_AVG_FOREACH_QP_MVTVM(cnxk_mldev, model, qp_id, value, count)        
                    \
@@ -106,43 +186,13 @@ mvtvm_ml_dev_info_get(struct cnxk_ml_dev *cnxk_mldev, 
struct rte_ml_dev_info *de
 
        dev_info->max_queue_pairs = mvtvm_mldev->max_nb_qpairs;
        dev_info->max_desc = ML_MVTVM_MAX_DESC_PER_QP;
-       dev_info->max_io = ML_MVTVM_MAX_INPUT_OUTPUT;
+       dev_info->max_io = ML_CNXK_MODEL_MAX_INPUT_OUTPUT;
        dev_info->max_segments = ML_MVTVM_MAX_SEGMENTS;
        dev_info->align_size = RTE_CACHE_LINE_SIZE;
 
        return 0;
 }
 
-int
-mvtvm_ml_dev_configure(struct cnxk_ml_dev *cnxk_mldev, const struct 
rte_ml_dev_config *conf)
-{
-       int ret;
-
-       RTE_SET_USED(conf);
-
-       /* Configure TVMDP library */
-       ret = tvmdp_configure(cnxk_mldev->mldev->data->nb_models, 
rte_get_tsc_cycles);
-       if (ret != 0)
-               plt_err("TVMDP configuration failed, error = %d", ret);
-
-       return ret;
-}
-
-int
-mvtvm_ml_dev_close(struct cnxk_ml_dev *cnxk_mldev)
-{
-       int ret;
-
-       RTE_SET_USED(cnxk_mldev);
-
-       /* Close TVMDP library configuration */
-       ret = tvmdp_close();
-       if (ret != 0)
-               plt_err("TVMDP close failed, error = %d", ret);
-
-       return ret;
-}
-
 int
 mvtvm_ml_dev_dump(struct cnxk_ml_dev *cnxk_mldev, FILE *fp)
 {
@@ -159,16 +209,26 @@ mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, 
struct rte_ml_model_params *
        struct mvtvm_ml_model_object object[ML_MVTVM_MODEL_OBJECT_MAX];
        struct tvmrt_glow_callback *callback;
        char str[RTE_MEMZONE_NAMESIZE];
+       char path[PATH_MAX];
        const struct plt_memzone *mz;
        size_t model_object_size = 0;
        size_t model_xstats_size = 0;
-       uint16_t nb_mrvl_layers;
-       uint16_t nb_llvm_layers;
-       uint8_t layer_id = 0;
        uint64_t mz_size = 0;
+       TVMFunctionHandle create_fn = NULL;
+       TVMFunctionHandle register_cb_fn = NULL;
+       TVMModuleHandle module_so = NULL;
+       TVMByteArray tvm_params;
+       TVMValue ret_value = {0};
+       TVMValue arg_values[4] = {0};
+       TVMValue tvm_arg_values[1] = {0};
+       int ret_type = kTVMNullptr;
+       int arg_types[4] = {0};
+       int tvm_arg_types[1] = {0};
+       DLDevice device;
        int ret;
 
        RTE_SET_USED(cnxk_mldev);
+       model->mvtvm.fd = -1;
 
        ret = mvtvm_ml_model_blob_parse(params, object);
        if (ret != 0)
@@ -192,80 +252,39 @@ mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, 
struct rte_ml_model_params *
        }
 
        /* Copy mod.so */
-       model->mvtvm.object.so.addr = mz->addr;
-       model->mvtvm.object.so.size = object[0].size;
-       rte_memcpy(model->mvtvm.object.so.name, object[0].name, 
TVMDP_NAME_STRLEN);
-       rte_memcpy(model->mvtvm.object.so.addr, object[0].buffer, 
object[0].size);
+       model->mvtvm.so.buffer = mz->addr;
+       model->mvtvm.so.size = object[0].size;
+       rte_memcpy(model->mvtvm.so.name, object[0].name, RTE_ML_STR_MAX);
+       rte_memcpy(model->mvtvm.so.buffer, object[0].buffer, object[0].size);
        rte_free(object[0].buffer);
 
        /* Copy mod.json */
-       model->mvtvm.object.json.addr =
-               RTE_PTR_ADD(model->mvtvm.object.so.addr,
-                           RTE_ALIGN_CEIL(model->mvtvm.object.so.size, 
RTE_CACHE_LINE_MIN_SIZE));
-       model->mvtvm.object.json.size = object[1].size;
-       rte_memcpy(model->mvtvm.object.json.name, object[1].name, 
TVMDP_NAME_STRLEN);
-       rte_memcpy(model->mvtvm.object.json.addr, object[1].buffer, 
object[1].size);
+       model->mvtvm.json.buffer =
+               RTE_PTR_ADD(model->mvtvm.so.buffer,
+                           RTE_ALIGN_CEIL(model->mvtvm.so.size, 
RTE_CACHE_LINE_MIN_SIZE));
+       model->mvtvm.json.size = object[1].size;
+       rte_memcpy(model->mvtvm.json.name, object[1].name, RTE_ML_STR_MAX);
+       rte_memcpy(model->mvtvm.json.buffer, object[1].buffer, object[1].size);
        rte_free(object[1].buffer);
 
        /* Copy mod.params */
-       model->mvtvm.object.params.addr =
-               RTE_PTR_ADD(model->mvtvm.object.json.addr,
-                           RTE_ALIGN_CEIL(model->mvtvm.object.json.size, 
RTE_CACHE_LINE_MIN_SIZE));
-       model->mvtvm.object.params.size = object[2].size;
-       rte_memcpy(model->mvtvm.object.params.name, object[2].name, 
TVMDP_NAME_STRLEN);
-       rte_memcpy(model->mvtvm.object.params.addr, object[2].buffer, 
object[2].size);
+       model->mvtvm.params.buffer =
+               RTE_PTR_ADD(model->mvtvm.json.buffer,
+                           RTE_ALIGN_CEIL(model->mvtvm.json.size, 
RTE_CACHE_LINE_MIN_SIZE));
+       model->mvtvm.params.size = object[2].size;
+       rte_memcpy(model->mvtvm.params.name, object[2].name, RTE_ML_STR_MAX);
+       rte_memcpy(model->mvtvm.params.buffer, object[2].buffer, 
object[2].size);
        rte_free(object[2].buffer);
 
-       /* Get metadata - stage 1 */
-       ret = tvmdp_model_metadata_get_stage1(model->mvtvm.object.json.addr,
-                                             model->mvtvm.object.json.size,
-                                             &model->mvtvm.metadata);
-       if (ret != 0) {
-               plt_err("TVMDP: Failed to parse metadata - stage 1, model_id = 
%u, error = %d",
-                       model->model_id, ret);
-               goto error;
-       }
-
-       /* Set model fields */
-       plt_strlcpy(model->name, model->mvtvm.metadata.model.name, 
TVMDP_NAME_STRLEN);
-       model->batch_size = 1;
-       model->nb_layers = model->mvtvm.metadata.model.nb_layers;
-
-       /* Update layer info */
-       nb_mrvl_layers = 0;
-       nb_llvm_layers = 0;
-       for (layer_id = 0; layer_id < model->mvtvm.metadata.model.nb_layers; 
layer_id++) {
-               rte_strscpy(model->layer[layer_id].name,
-                           model->mvtvm.metadata.model.layer[layer_id].name, 
TVMDP_NAME_STRLEN);
-               if (strcmp(model->mvtvm.metadata.model.layer[layer_id].type, 
"mrvl") == 0 ||
-                   strcmp(model->mvtvm.metadata.model.layer[layer_id].type, 
"MRVL") == 0) {
-                       model->layer[layer_id].type = ML_CNXK_LAYER_TYPE_MRVL;
-                       nb_mrvl_layers++;
-               } else if 
(strcmp(model->mvtvm.metadata.model.layer[layer_id].type, "llvm") == 0 ||
-                          
strcmp(model->mvtvm.metadata.model.layer[layer_id].type, "LLVM") == 0) {
-                       model->layer[layer_id].type = ML_CNXK_LAYER_TYPE_LLVM;
-                       nb_llvm_layers++;
-               }
-       }
-
-       if ((nb_llvm_layers == 0) && (nb_mrvl_layers == 0)) {
-               plt_err("Invalid model, nb_llvm_layers = %u, nb_mrvl_layers = 
%u", nb_llvm_layers,
-                       nb_mrvl_layers);
+       ret = mvtvm_ml_model_json_parse(model);
+       if (ret != 0)
                goto error;
-       }
-
-       /* Set model subtype */
-       if ((nb_llvm_layers == 0) && (nb_mrvl_layers == 1))
-               model->subtype = ML_CNXK_MODEL_SUBTYPE_TVM_MRVL;
-       else if ((nb_llvm_layers > 0) && (nb_mrvl_layers == 0))
-               model->subtype = ML_CNXK_MODEL_SUBTYPE_TVM_LLVM;
-       else
-               model->subtype = ML_CNXK_MODEL_SUBTYPE_TVM_HYBRID;
 
        if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_VDEV &&
            model->subtype != ML_CNXK_MODEL_SUBTYPE_TVM_LLVM) {
                plt_err("Unsupported model sub-type");
-               return -ENOTSUP;
+               ret = -ENOTSUP;
+               goto error;
        }
 
        /* Set callback function array */
@@ -284,23 +303,120 @@ mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, 
struct rte_ml_model_params *
                callback = NULL;
        }
 
-       /* Initialize model in TVMDP */
-       ret = tvmdp_model_load(cnxk_mldev, model->model_id, (void 
*)(&model->mvtvm.object),
-                              callback);
+       /* Initialize model in TVM runtime */
+       if (model->mvtvm.graph_module != NULL) {
+               ret = -EBUSY;
+               plt_err("TVM runtime: Model load failed, model_id = %u, error = 
%d",
+                       model->model_id, ret);
+               goto error;
+       }
+
+       snprintf(path, sizeof(path), "%s_%d_%u", ML_MODEL_SHMFD_NAME, getpid(), 
model->model_id);
+       model->mvtvm.fd = memfd_create(path, 0);
+       if (model->mvtvm.fd < 0) {
+               ret = (errno == 0) ? -EIO : -errno;
+               plt_err("TVM runtime: Model load failed, model_id = %u, error = 
%d",
+                       model->model_id, ret);
+               goto error;
+       }
+
+       if (write(model->mvtvm.fd, model->mvtvm.so.buffer, 
model->mvtvm.so.size) !=
+           (ssize_t)model->mvtvm.so.size) {
+               ret = (errno == 0) ? -EIO : -errno;
+               plt_err("TVM runtime: Model load failed, model_id = %u, error = 
%d",
+                       model->model_id, ret);
+               goto error;
+       }
+
+       if (lseek(model->mvtvm.fd, 0, SEEK_SET) < 0) {
+               ret = (errno == 0) ? -EIO : -errno;
+               plt_err("TVM runtime: Model load failed, model_id = %u, error = 
%d",
+                       model->model_id, ret);
+               goto error;
+       }
+
+       snprintf(path, sizeof(path), ML_MODEL_SHMFD_PATH, getpid(), 
model->mvtvm.fd);
+       ret = TVMModLoadFromFile(path, "so", &module_so);
        if (ret != 0) {
-               plt_err("TVMDP: Model load failed, model_id = %u, error = %d", 
model->model_id,
-                       ret);
+               plt_err("TVM runtime: Model load failed, model_id = %u, ret = 
%d, msg = %s",
+                       model->model_id, ret, TVMGetLastError());
                goto error;
        }
 
-       /* Get model metadata - stage 2 */
-       ret = tvmdp_model_metadata_get_stage2(model->model_id, 
&model->mvtvm.metadata);
+       /* Set device info */
+       device.device_type = kDLCPU;
+       device.device_id = 0;
+
+       if (callback != NULL) {
+               ret = mvtvm_ml_tvm_func_get(model, module_so, "register_cb", 
&register_cb_fn);
+               if (ret != 0)
+                       goto error;
+
+               arg_values[0].v_handle = callback;
+               arg_types[0] = kTVMOpaqueHandle;
+               arg_values[1].v_handle = cnxk_mldev;
+               arg_types[1] = kTVMOpaqueHandle;
+               arg_values[2].v_int64 = model->model_id;
+               arg_types[2] = kDLInt;
+
+               ret = mvtvm_ml_tvm_func_call(model, register_cb_fn, 
"register_cb", arg_values,
+                                            arg_types, 3, &ret_value, 
&ret_type, kTVMNullptr);
+               if (ret != 0)
+                       goto error;
+       }
+
+       ret = TVMFuncGetGlobal("tvm.graph_executor.create", &create_fn);
        if (ret != 0) {
-               plt_err("TVMDP: Failed to get metadata, model_id = %u, error = 
%d",
-                       model->model_id, ret);
+               plt_err("TVM runtime: Model load failed, model_id = %u, ret = 
%d, msg = %s",
+                       model->model_id, ret, TVMGetLastError());
                goto error;
        }
 
+       arg_values[0].v_str = (const char *)model->mvtvm.json.buffer;
+       arg_types[0] = kTVMStr;
+       arg_values[1].v_handle = module_so;
+       arg_types[1] = kTVMModuleHandle;
+       arg_values[2].v_int64 = device.device_type;
+       arg_types[2] = kDLInt;
+       arg_values[3].v_int64 = device.device_id;
+       arg_types[3] = kDLInt;
+
+       ret = mvtvm_ml_tvm_func_call(model, create_fn, 
"tvm.graph_executor.create", arg_values,
+                                    arg_types, 4, &ret_value, &ret_type, 
kTVMModuleHandle);
+       if (ret != 0)
+               goto error;
+       model->mvtvm.graph_module = ret_value.v_handle;
+
+       ret = mvtvm_ml_tvm_func_get(model, model->mvtvm.graph_module, 
"load_params",
+                                   &model->mvtvm.load_params);
+       if (ret != 0)
+               goto error;
+       ret = mvtvm_ml_tvm_func_get(model, model->mvtvm.graph_module, 
"set_input_zero_copy",
+                                   &model->mvtvm.set_input_zero_copy);
+       if (ret != 0)
+               goto error;
+       ret = mvtvm_ml_tvm_func_get(model, model->mvtvm.graph_module, 
"set_output_zero_copy",
+                                   &model->mvtvm.set_output_zero_copy);
+       if (ret != 0)
+               goto error;
+       ret = mvtvm_ml_tvm_func_get(model, model->mvtvm.graph_module, "run", 
&model->mvtvm.run);
+       if (ret != 0)
+               goto error;
+
+       mvtvm_ml_tvm_func_free(&register_cb_fn);
+       mvtvm_ml_tvm_mod_free(&module_so);
+
+       /* Load model parameters into TVM runtime */
+       tvm_params.data = (const char *)model->mvtvm.params.buffer;
+       tvm_params.size = model->mvtvm.params.size;
+       tvm_arg_values[0].v_handle = &tvm_params;
+       tvm_arg_types[0] = kTVMBytes;
+
+       ret = mvtvm_ml_tvm_func_call(model, model->mvtvm.load_params, 
"load_params", tvm_arg_values,
+                                    tvm_arg_types, 1, &ret_value, &ret_type, 
kTVMNullptr);
+       if (ret != 0)
+               goto error;
+
        /* Update model I/O data */
        mvtvm_ml_model_io_info_set(model);
 
@@ -310,9 +426,9 @@ mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct 
rte_ml_model_params *
        /* Update model xstats name */
        cnxk_ml_xstats_model_name_update(cnxk_mldev, model->model_id);
 
-       model->mvtvm.burst_xstats = RTE_PTR_ADD(
-               model->mvtvm.object.params.addr,
-               RTE_ALIGN_CEIL(model->mvtvm.object.params.size, 
RTE_CACHE_LINE_MIN_SIZE));
+       model->mvtvm.burst_xstats =
+               RTE_PTR_ADD(model->mvtvm.params.buffer,
+                           RTE_ALIGN_CEIL(model->mvtvm.params.size, 
RTE_CACHE_LINE_MIN_SIZE));
 
        for (int qp_id = 0; qp_id < cnxk_mldev->mldev->data->nb_queue_pairs; 
qp_id++) {
                model->mvtvm.burst_xstats[qp_id].tvm_rt_latency_tot = 0;
@@ -341,7 +457,20 @@ mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct 
rte_ml_model_params *
        return 0;
 
 error:
-       rte_memzone_free(mz);
+       mvtvm_ml_tvm_func_free(&register_cb_fn);
+       if (model != NULL) {
+               mvtvm_ml_tvm_func_free(&model->mvtvm.load_params);
+               mvtvm_ml_tvm_func_free(&model->mvtvm.set_input_zero_copy);
+               mvtvm_ml_tvm_func_free(&model->mvtvm.set_output_zero_copy);
+               mvtvm_ml_tvm_func_free(&model->mvtvm.run);
+               mvtvm_ml_tvm_mod_free(&model->mvtvm.graph_module);
+               if (model->mvtvm.fd >= 0)
+                       close(model->mvtvm.fd);
+               memset(&model->mvtvm, 0, sizeof(model->mvtvm));
+               model->mvtvm.fd = -1;
+       }
+       mvtvm_ml_tvm_mod_free(&module_so);
+       plt_memzone_free(mz);
 
        return ret;
 }
@@ -351,20 +480,28 @@ mvtvm_ml_model_unload(struct cnxk_ml_dev *cnxk_mldev, 
struct cnxk_ml_model *mode
 {
        char str[RTE_MEMZONE_NAMESIZE];
        const struct plt_memzone *mz;
-       int ret;
 
        RTE_SET_USED(cnxk_mldev);
 
-       /* Initialize model in TVMDP */
-       ret = tvmdp_model_unload(model->model_id);
-       if (ret != 0) {
-               plt_err("TVMDP: Model unload failed, model_id = %u, error = 
%d", model->model_id,
-                       ret);
-               return ret;
-       }
+       /* Unload model from TVM runtime */
+       if (model->model_id >= cnxk_mldev->mldev->data->nb_models)
+               return -EINVAL;
+
+       if (model->mvtvm.graph_module == NULL)
+               return -EINVAL;
+
+       mvtvm_ml_tvm_func_free(&model->mvtvm.load_params);
+       mvtvm_ml_tvm_func_free(&model->mvtvm.set_input_zero_copy);
+       mvtvm_ml_tvm_func_free(&model->mvtvm.set_output_zero_copy);
+       mvtvm_ml_tvm_func_free(&model->mvtvm.run);
+       mvtvm_ml_tvm_mod_free(&model->mvtvm.graph_module);
+       if (model->mvtvm.fd >= 0)
+               close(model->mvtvm.fd);
+       memset(&model->mvtvm, 0, sizeof(model->mvtvm));
+       model->mvtvm.fd = -1;
 
        snprintf(str, RTE_MEMZONE_NAMESIZE, "%s_%u", 
MVTVM_ML_MODEL_MEMZONE_NAME, model->model_id);
-       mz = rte_memzone_lookup(str);
+       mz = plt_memzone_lookup(str);
        if (mz == NULL) {
                plt_err("Memzone lookup failed for TVM model: model_id = %u, mz 
= %s",
                        model->model_id, str);
@@ -455,13 +592,13 @@ mvtvm_ml_io_quantize(void *device, uint16_t model_id, 
const char *layer_name,
 #endif
 
        /* Get layer id */
-       for (layer_id = 0; layer_id < model->mvtvm.metadata.model.nb_layers; 
layer_id++) {
+       for (layer_id = 0; layer_id < model->nb_layers; layer_id++) {
                if (strcmp(model->layer[layer_id].name, layer_name) == 0)
                        break;
        }
 
 #ifdef CNXK_ML_DEV_DEBUG
-       if (layer_id == model->mvtvm.metadata.model.nb_layers) {
+       if (layer_id == model->nb_layers) {
                plt_err("Invalid layer name: %s", layer_name);
                return -EINVAL;
        }
@@ -516,13 +653,13 @@ mvtvm_ml_io_dequantize(void *device, uint16_t model_id, 
const char *layer_name,
        }
 #endif
 
-       for (layer_id = 0; layer_id < model->mvtvm.metadata.model.nb_layers; 
layer_id++) {
+       for (layer_id = 0; layer_id < model->nb_layers; layer_id++) {
                if (strcmp(model->layer[layer_id].name, layer_name) == 0)
                        break;
        }
 
 #ifdef CNXK_ML_DEV_DEBUG
-       if (layer_id == model->mvtvm.metadata.model.nb_layers) {
+       if (layer_id == model->nb_layers) {
                plt_err("Invalid layer name: %s", layer_name);
                return -EINVAL;
        }
@@ -553,28 +690,69 @@ static int
 mvtvm_ml_model_run(struct cnxk_ml_model *model, struct rte_ml_op *op, struct 
cnxk_ml_req *req)
 {
        uint8_t i;
+       struct mvtvm_ml_result *run_result;
+       TVMValue arg_values[2] = {0};
+       int arg_types[2] = {0};
+       TVMValue ret_value = {0};
+       int ret_type = kTVMNullptr;
+       int ret = 0;
 
        rte_memcpy(req->mvtvm_req.input_tensor, model->mvtvm.input_tensor,
-                  model->mvtvm.metadata.model.num_input * sizeof(DLTensor));
-       for (i = 0; i < model->mvtvm.metadata.model.num_input; i++) {
+                  model->mvtvm.info.nb_inputs * sizeof(DLTensor));
+       for (i = 0; i < model->mvtvm.info.nb_inputs; i++) {
                req->mvtvm_req.input_tensor[i].data = op->input[i]->addr;
                req->mvtvm_req.input_tensor[i].byte_offset = 0;
        }
 
        rte_memcpy(req->mvtvm_req.output_tensor, model->mvtvm.output_tensor,
-                  model->mvtvm.metadata.model.num_output * sizeof(DLTensor));
-       for (i = 0; i < model->mvtvm.metadata.model.num_output; i++) {
+                  model->mvtvm.info.nb_outputs * sizeof(DLTensor));
+       for (i = 0; i < model->mvtvm.info.nb_outputs; i++) {
                req->mvtvm_req.output_tensor[i].data = op->output[i]->addr;
                req->mvtvm_req.output_tensor[i].byte_offset = 0;
        }
 
-       tvmdp_model_run(model->model_id, model->mvtvm.metadata.model.num_input,
-                       req->mvtvm_req.input_tensor, 
model->mvtvm.metadata.model.num_output,
-                       req->mvtvm_req.output_tensor, &req->mvtvm_req.result,
-                       &req->mvtvm_req.status);
+       run_result = &req->mvtvm_req.result;
+       run_result->stats.start_ns = rte_get_tsc_cycles();
+       run_result->error_code = 0;
+
+       for (i = 0; i < model->mvtvm.info.nb_inputs; i++) {
+               arg_values[0].v_int64 = i;
+               arg_types[0] = kDLInt;
+               arg_values[1].v_handle = &req->mvtvm_req.input_tensor[i];
+               arg_types[1] = kTVMDLTensorHandle;
+               ret = mvtvm_ml_tvm_func_call(model, 
model->mvtvm.set_input_zero_copy,
+                                            "set_input_zero_copy", arg_values, 
arg_types, 2,
+                                            &ret_value, &ret_type, 
kTVMNullptr);
+               if (ret != 0)
+                       goto out;
+       }
+
+       for (i = 0; i < model->mvtvm.info.nb_outputs; i++) {
+               arg_values[0].v_int64 = i;
+               arg_types[0] = kDLInt;
+               arg_values[1].v_handle = &req->mvtvm_req.output_tensor[i];
+               arg_types[1] = kTVMDLTensorHandle;
+               ret = mvtvm_ml_tvm_func_call(model, 
model->mvtvm.set_output_zero_copy,
+                                            "set_output_zero_copy", 
arg_values, arg_types, 2,
+                                            &ret_value, &ret_type, 
kTVMNullptr);
+               if (ret != 0)
+                       goto out;
+       }
+
+       ret = mvtvm_ml_tvm_func_call(model, model->mvtvm.run, "run", NULL, 
NULL, 0, &ret_value,
+                                    &ret_type, kTVMNullptr);
+       if (ret != 0)
+               goto out;
+
+out:
+       run_result->stats.end_ns = rte_get_tsc_cycles();
+       req->mvtvm_req.status = 0x1;
 
        plt_write64(ML_CNXK_POLL_JOB_FINISH, req->status);
 
+       if (ret != 0)
+               run_result->error_code = -EIO;
+
        return 0;
 }
 
diff --git a/drivers/ml/cnxk/mvtvm_ml_ops.h b/drivers/ml/cnxk/mvtvm_ml_ops.h
index d8f2f361fb1..593f4585b3c 100644
--- a/drivers/ml/cnxk/mvtvm_ml_ops.h
+++ b/drivers/ml/cnxk/mvtvm_ml_ops.h
@@ -7,11 +7,10 @@
 
 #include <dlpack/dlpack.h>
 
-#include <tvmdp.h>
-
 #include <rte_mldev.h>
 
 #include "cnxk_ml_xstats.h"
+#include "mvtvm_ml_model.h"
 
 struct cnxk_ml_dev;
 struct cnxk_ml_model;
@@ -56,8 +55,6 @@ struct mvtvm_ml_req {
 };
 
 int mvtvm_ml_dev_info_get(struct cnxk_ml_dev *mldev, struct rte_ml_dev_info 
*dev_info);
-int mvtvm_ml_dev_configure(struct cnxk_ml_dev *cnxk_mldev, const struct 
rte_ml_dev_config *conf);
-int mvtvm_ml_dev_close(struct cnxk_ml_dev *cnxk_mldev);
 int mvtvm_ml_dev_dump(struct cnxk_ml_dev *cnxk_mldev, FILE *fp);
 int mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct 
rte_ml_model_params *params,
                        struct cnxk_ml_model *model);
diff --git a/drivers/ml/cnxk/mvtvm_ml_stubs.c b/drivers/ml/cnxk/mvtvm_ml_stubs.c
index 126a954c916..7c13fac42d6 100644
--- a/drivers/ml/cnxk/mvtvm_ml_stubs.c
+++ b/drivers/ml/cnxk/mvtvm_ml_stubs.c
@@ -76,23 +76,6 @@ mvtvm_ml_dev_info_get(struct cnxk_ml_dev *cnxk_mldev, struct 
rte_ml_dev_info *de
        return -ENOTSUP;
 }
 
-int
-mvtvm_ml_dev_configure(struct cnxk_ml_dev *cnxk_mldev, const struct 
rte_ml_dev_config *conf)
-{
-       RTE_SET_USED(cnxk_mldev);
-       RTE_SET_USED(conf);
-
-       return 0;
-}
-
-int
-mvtvm_ml_dev_close(struct cnxk_ml_dev *cnxk_mldev)
-{
-       RTE_SET_USED(cnxk_mldev);
-
-       return 0;
-}
-
 int
 mvtvm_ml_dev_dump(struct cnxk_ml_dev *cnxk_mldev, FILE *fp)
 {
diff --git a/drivers/ml/cnxk/mvtvm_ml_stubs.h b/drivers/ml/cnxk/mvtvm_ml_stubs.h
index 4220a963f2d..15985a75bf4 100644
--- a/drivers/ml/cnxk/mvtvm_ml_stubs.h
+++ b/drivers/ml/cnxk/mvtvm_ml_stubs.h
@@ -15,8 +15,6 @@ struct cnxk_ml_layer;
 
 enum cnxk_ml_model_type mvtvm_ml_model_type_get(struct rte_ml_model_params 
*params);
 int mvtvm_ml_dev_info_get(struct cnxk_ml_dev *cnxk_mldev, struct 
rte_ml_dev_info *dev_info);
-int mvtvm_ml_dev_configure(struct cnxk_ml_dev *cnxk_mldev, const struct 
rte_ml_dev_config *conf);
-int mvtvm_ml_dev_close(struct cnxk_ml_dev *cnxk_mldev);
 int mvtvm_ml_dev_dump(struct cnxk_ml_dev *cnxk_mldev, FILE *fp);
 int mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct 
rte_ml_model_params *params,
                        struct cnxk_ml_model *model);
-- 
2.34.1

Reply via email to