The ONNX-LRE library provides a machine learning runtime environment for executing ONNX (Open Neural Network Exchange) models.
ONNX-LRE C++ APIs offer an easy-to-use interface to onboard and execute ONNX models from LEIP Optimize.
Inference Options
ONNX-LRE supports three different input formats for inference:
Each approach offers different tradeoffs between ease of use, performance, and integration complexity. See the examples below for practical usage patterns.
These examples demonstrate usage of the ONNX-LRE.
Examples
Example 1: DLPack Tensors with Smart Pointers
#include "onnx_lre.hpp"
#include <memory>
#include <functional>
#include <iostream>
struct DLTensorDeleter {
void operator()(DLManagedTensor* tensor) const {
if (tensor && tensor->deleter) {
tensor->deleter(tensor);
}
}
};
using DLTensorPtr = std::unique_ptr<DLManagedTensor, DLTensorDeleter>;
int main() {
try {
std::vector<DLTensorPtr> outputTensors;
for (auto* tensor : engine.getOutput()) {
outputTensors.emplace_back(tensor);
}
for (const auto& tensor : outputTensors) {
if (!tensor) continue;
const auto& dl_tensor = tensor->dl_tensor;
std::cout << "Shape: [";
for (int j = 0; j < dl_tensor.ndim; j++) {
std::cout << dl_tensor.shape[j] << " ";
}
std::cout << "]" << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
Example 2: Using ONNX Runtime Tensors with RAII
This approach uses ONNX Runtime's tensor types with automatic memory management:
#include "onnx_lre.hpp"
#include <memory>
#include <iostream>
int main() {
try {
const auto& inputShapes = engine.getInputShapes();
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example");
Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(
OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault);
std::vector<Ort::Value> inputTensors;
for (size_t i = 0; i < engine.getNumberOfInputs(); i++) {
size_t totalElements = 1;
for (auto dim : inputShapes[i]) {
totalElements *= (dim > 0) ? dim : 1;
}
std::vector<float> data(totalElements, 0.5f);
inputTensors.push_back(Ort::Value::CreateTensor<float>(
memInfo, data.data(), data.size() * sizeof(float),
inputShapes[i].data(), inputShapes[i].size()));
}
engine.infer(inputTensors);
auto outputTensors = engine.getOutputOrt();
for (size_t i = 0; i < outputTensors.size(); i++) {
auto info = outputTensors[i].GetTensorTypeAndShapeInfo();
std::cout << "Output " << i << " shape: [";
for (auto dim : info.GetShape()) {
std::cout << dim << " ";
}
std::cout << "]" << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}