diff --git a/sources/onnxruntime/quick_start.rst b/sources/onnxruntime/quick_start.rst index 60cf448..39a83ca 100644 --- a/sources/onnxruntime/quick_start.rst +++ b/sources/onnxruntime/quick_start.rst @@ -35,6 +35,8 @@ ONNX Runtime 推理需要 ONNX 格式模型作为输入,目前有以下几种 模型推理 ----------- +python推理示例 +~~~~~~~~~~~~~~~~~~~~ .. code-block:: python :linenos: @@ -95,3 +97,148 @@ ONNX Runtime 推理需要 ONNX 格式模型作为输入,目前有以下几种 img = preprocess(image_path) result = inference(model_path, img) display(classes_path, result) + +C++推理示例 +~~~~~~~~~~~~~~~~~ +.. code-block:: c++ + :linenos: + + #include + #include + + #include "onnxruntime_cxx_api.h" + + // path of model, Change to user's own model path + const char* model_path = "./onnx/resnet50_Opset16.onnx"; + + /** + * @brief Input data preparation provided by user. + * + * @param num_input_nodes The number of model input nodes. + * @return A collection of input data. + */ + std::vector> input_prepare(size_t num_input_nodes) { + std::vector> input_datas; + input_datas.reserve(num_input_nodes); + + constexpr size_t input_data_size = 3 * 224 * 224; + std::vector input_data(input_data_size); + // initialize input data with values in [0.0, 1.0] + for (unsigned int i = 0; i < input_data_size; i++) + input_data[i] = (float)i / (input_data_size + 1); + input_datas.push_back(input_data); + + return input_datas; + } + + /** + * @brief Model output data processing logic(For User updates). + * + * @param output_tensors The results of the model output. + */ + void output_postprocess(std::vector& output_tensors) { + auto floatarr = output_tensors.front().GetTensorMutableData(); + + for (int i = 0; i < 5; i++) { + std::cout << "Score for class [" << i << "] = " << floatarr[i] << '\n'; + } + + std::cout << "Done!" << std::endl; + } + + /** + * @brief The main functions for model inference. + * + * The complete model inference process, which generally does not need to be + * changed here + */ + void inference() { + const auto& api = Ort::GetApi(); + Ort::Env env(ORT_LOGGING_LEVEL_WARNING); + + // Enable cann graph in cann provider option. + OrtCANNProviderOptions* cann_options = nullptr; + api.CreateCANNProviderOptions(&cann_options); + + // Configurations of EP + std::vector keys{ + "device_id", + "npu_mem_limit", + "arena_extend_strategy", + "enable_cann_graph"}; + std::vector values{"0", "4294967296", "kNextPowerOfTwo", "1"}; + api.UpdateCANNProviderOptions( + cann_options, keys.data(), values.data(), keys.size()); + + // Convert to general session options + Ort::SessionOptions session_options; + api.SessionOptionsAppendExecutionProvider_CANN( + static_cast(session_options), cann_options); + + Ort::Session session(env, model_path, session_options); + + Ort::AllocatorWithDefaultOptions allocator; + + // Input Process + const size_t num_input_nodes = session.GetInputCount(); + std::vector input_node_names; + std::vector input_names_ptr; + input_node_names.reserve(num_input_nodes); + input_names_ptr.reserve(num_input_nodes); + std::vector> input_node_shapes; + std::cout << num_input_nodes << std::endl; + for (size_t i = 0; i < num_input_nodes; i++) { + auto input_name = session.GetInputNameAllocated(i, allocator); + input_node_names.push_back(input_name.get()); + input_names_ptr.push_back(std::move(input_name)); + auto type_info = session.GetInputTypeInfo(i); + auto tensor_info = type_info.GetTensorTypeAndShapeInfo(); + input_node_shapes.push_back(tensor_info.GetShape()); + } + + // Output Process + const size_t num_output_nodes = session.GetOutputCount(); + std::vector output_node_names; + std::vector output_names_ptr; + output_names_ptr.reserve(num_input_nodes); + output_node_names.reserve(num_output_nodes); + for (size_t i = 0; i < num_output_nodes; i++) { + auto output_name = session.GetOutputNameAllocated(i, allocator); + output_node_names.push_back(output_name.get()); + output_names_ptr.push_back(std::move(output_name)); + } + + // User need to generate input date according to real situation. + std::vector> input_datas = input_prepare(num_input_nodes); + + auto memory_info = Ort::MemoryInfo::CreateCpu( + OrtAllocatorType::OrtArenaAllocator, OrtMemTypeDefault); + + std::vector input_tensors; + input_tensors.reserve(num_input_nodes); + for (size_t i = 0; i < input_node_shapes.size(); i++) { + auto input_tensor = Ort::Value::CreateTensor( + memory_info, + input_datas[i].data(), + input_datas[i].size(), + input_node_shapes[i].data(), + input_node_shapes[i].size()); + input_tensors.push_back(std::move(input_tensor)); + } + + auto output_tensors = session.Run( + Ort::RunOptions{nullptr}, + input_node_names.data(), + input_tensors.data(), + num_input_nodes, + output_node_names.data(), + output_node_names.size()); + + // Processing of out_tensor + output_postprocess(output_tensors); + } + + int main(int argc, char* argv[]) { + inference(); + return 0; + } \ No newline at end of file