|
| 1 | +/* |
| 2 | + * SPDX-License-Identifier: Apache-2.0 |
| 3 | + */ |
| 4 | + |
| 5 | +//===------- OnnxMlirRuntime.h - ONNX-MLIR Runtime API Declarations -------===// |
| 6 | +// |
| 7 | +// Copyright 2019-2023 The IBM Research Authors. |
| 8 | +// |
| 9 | +// ============================================================================= |
| 10 | +// |
| 11 | +// This file contains declaration of external OMTensor data structures and |
| 12 | +// helper functions. |
| 13 | +// |
| 14 | +//===----------------------------------------------------------------------===// |
| 15 | +#ifndef ONNX_MLIR_ONNXMLIRRUNTIME_H |
| 16 | +#define ONNX_MLIR_ONNXMLIRRUNTIME_H |
| 17 | + |
| 18 | +#ifdef __cplusplus |
| 19 | +#include <cstdint> |
| 20 | +#else |
| 21 | +#include <stdbool.h> |
| 22 | +#include <stdint.h> |
| 23 | +#endif |
| 24 | + |
| 25 | +#include <onnx-mlir/Runtime/OMEntryPoint.h> |
| 26 | +#include <onnx-mlir/Runtime/OMInstrument.h> |
| 27 | +#include <onnx-mlir/Runtime/OMSignature.h> |
| 28 | +#include <onnx-mlir/Runtime/OMTensor.h> |
| 29 | +#include <onnx-mlir/Runtime/OMTensorList.h> |
| 30 | + |
| 31 | +/*! \mainpage ONNX-MLIR Runtime API documentation |
| 32 | + * |
| 33 | + * \section intro_sec Introduction |
| 34 | + * |
| 35 | + * ONNX-MLIR project comes with an executable `onnx-mlir` capable |
| 36 | + * of compiling onnx models to a shared library. In this documentation, we |
| 37 | + * demonstrate how to interact programmatically with the compiled |
| 38 | + * shared library using ONNX-MLIR's Runtime API. |
| 39 | + * |
| 40 | + * \section c-runtime-api C Runtime API |
| 41 | + * |
| 42 | + * \subsection data-structures Data Structures |
| 43 | + * |
| 44 | + * `OMTensor` is the data structure used to describe the runtime information |
| 45 | + * (rank, shape, data type, etc) associated with a tensor input or output. |
| 46 | + * |
| 47 | + * `OMTensorList` is the data structure used to hold a list of pointers to |
| 48 | + * OMTensor so that they can be passed into and out of the compiled model as |
| 49 | + * inputs and outputs. |
| 50 | + * |
| 51 | + * `OMEntryPoint` is the data structure used to return all entry point names |
| 52 | + * in a model. These entry point names are the symbols of the inference functions |
| 53 | + * in the model. |
| 54 | + * |
| 55 | + * `OMSignature` is the data structure used to return the output signature of |
| 56 | + * the given entry point as a JSON string. |
| 57 | + * |
| 58 | + * \subsection model-entry-point-signature Model Entry Point Signature |
| 59 | + * |
| 60 | + * All compiled models will have the same exact C function signature equivalent |
| 61 | + * to: |
| 62 | + * |
| 63 | + * ```c |
| 64 | + * OMTensorList* run_main_graph(OMTensorList*); |
| 65 | + * ``` |
| 66 | + * |
| 67 | + * Intuitively, the model takes a list of tensors as input and returns a list of |
| 68 | + * tensors as output. |
| 69 | + * |
| 70 | + * \subsection invoke-models-using-c-runtime-api Invoke Models Using C Runtime |
| 71 | + * API |
| 72 | + * |
| 73 | + * We demonstrate using the API functions to run a simple ONNX model consisting |
| 74 | + * of an add operation. To create such an onnx model, use this |
| 75 | + * <a href="gen_add_onnx.py" target="_blank"><b>python script</b></a> |
| 76 | + * |
| 77 | + * To compile the above model, run `onnx-mlir add.onnx` and a binary library |
| 78 | + * "add.so" should appear. We can use the following C code to call into the |
| 79 | + * compiled function computing the sum of two inputs: |
| 80 | + * |
| 81 | + * ```c |
| 82 | + * #include <OnnxMlirRuntime.h> |
| 83 | + * #include <stdio.h> |
| 84 | + * |
| 85 | + * OMTensorList *run_main_graph(OMTensorList *); |
| 86 | + * |
| 87 | + * OMTensorList *create_input_list() { |
| 88 | + * // Shared shape & rank. |
| 89 | + * int64_t shape[] = {3, 2}; |
| 90 | + * int64_t num_elements = shape[0] * shape[1]; |
| 91 | + * int64_t rank = 2; |
| 92 | + * |
| 93 | + * // Construct float arrays filled with 1s or 2s. |
| 94 | + * float *x1Data = (float *)malloc(sizeof(float) * num_elements); |
| 95 | + * for (int i = 0; i < num_elements; i++) |
| 96 | + * x1Data[i] = 1.0; |
| 97 | + * float *x2Data = (float *)malloc(sizeof(float) * num_elements); |
| 98 | + * for (int i = 0; i < num_elements; i++) |
| 99 | + * x2Data[i] = 2.0; |
| 100 | + * |
| 101 | + * // Use omTensorCreateWithOwnership "true" so float arrays are automatically |
| 102 | + * // freed when the Tensors are destroyed. |
| 103 | + * OMTensor *x1 = omTensorCreateWithOwnership(x1Data, shape, rank, ONNX_TYPE_FLOAT, true); |
| 104 | + * OMTensor *x2 = omTensorCreateWithOwnership(x2Data, shape, rank, ONNX_TYPE_FLOAT, true); |
| 105 | + * |
| 106 | + * // Construct a TensorList using the Tensors |
| 107 | + * OMTensor *list[2] = {x1, x2}; |
| 108 | + * return omTensorListCreate(list, 2); |
| 109 | + * } |
| 110 | + * |
| 111 | + * int main() { |
| 112 | + * // Generate input TensorList |
| 113 | + * OMTensorList *input_list = create_input_list(); |
| 114 | + * |
| 115 | + * // Call the compiled onnx model function. |
| 116 | + * OMTensorList *output_list = run_main_graph(input_list); |
| 117 | + * if (!output_list) { |
| 118 | + * // May inspect errno to get info about the error. |
| 119 | + * return 1; |
| 120 | + * } |
| 121 | + * |
| 122 | + * // Get the first tensor from output list. |
| 123 | + * OMTensor *y = omTensorListGetOmtByIndex(output_list, 0); |
| 124 | + * float *outputPtr = (float *) omTensorGetDataPtr(y); |
| 125 | + * |
| 126 | + * // Print its content, should be all 3. |
| 127 | + * for (int i = 0; i < 6; i++) |
| 128 | + * printf("%f ", outputPtr[i]); |
| 129 | + * printf("\n"); |
| 130 | + * |
| 131 | + * // Destory the list and the tensors inside of it. |
| 132 | + * // Use omTensorListDestroyShallow if only want to destroy the list themselves. |
| 133 | + * omTensorListDestroy(input_list); |
| 134 | + * omTensorListDestroy(output_list); |
| 135 | + * return 0; |
| 136 | + * } |
| 137 | + * ``` |
| 138 | + * |
| 139 | + * Compile with `gcc main.c add.so -o add`, you should see an executable `add` |
| 140 | + * appearing. Run it, and the output should be: |
| 141 | + * |
| 142 | + * ``` |
| 143 | + * 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 |
| 144 | + * ``` |
| 145 | + * Exactly as it should be. |
| 146 | + * |
| 147 | + * \subsection freeing-tensor-memory Freeing Tensor Memory |
| 148 | + * |
| 149 | + * In general, if a caller creates a tensor object (omTensorCreate), they are |
| 150 | + * responsible for deallocating the data buffer separately after the tensor is |
| 151 | + * destroyed. If onnx-mlir creates the tensor (run_main_graph), then the |
| 152 | + * tensor object owns the data buffer and it is freed automatically when the |
| 153 | + * tensor is destroyed. |
| 154 | + * |
| 155 | + * This default behavior can be changed. When creating a tensor, a user may use |
| 156 | + * omTensorCreateWithOwnership to explicitly set data buffer ownership. Additionally, |
| 157 | + * after a tenor is created, omTensorSetOwning can be used to change |
| 158 | + * the ownership setting. |
| 159 | + * |
| 160 | + * When omTensorDestroy is called, if the ownership flag is set to "true", |
| 161 | + * then the destruction of the tensor will also free any associated data buffer |
| 162 | + * memory. If the ownership flag is set to "false", then the user is responsible |
| 163 | + * for freeing the data buffer memory after destroying the tensor. |
| 164 | + * |
| 165 | + * For tensor list objects, when omTensorListDestory is called, omTensorDestory |
| 166 | + * is called on all tensors the list contained. The data buffer of each tensor |
| 167 | + * is freed based on each tensor's ownership setting. |
| 168 | + * |
| 169 | + * To destroy a TensorList without automatically destorying the tensors it |
| 170 | + * contained, use omTensorListDestroyShallow. |
| 171 | + * |
| 172 | + * \subsection reference Reference |
| 173 | + * |
| 174 | + * For full reference to available C Runtime API, refer to |
| 175 | + * `include/onnx-mlir/Runtime/OMTensor.h` and |
| 176 | + * `include/onnx-mlir/Runtime/OMTensorList.h`. |
| 177 | + * |
| 178 | + */ |
| 179 | + |
| 180 | +#endif // ONNX_MLIR_ONNXMLIRRUNTIME_H |
0 commit comments