Standalone C++ example: validate an ONNX model with onnx_light checker#
This page documents examples/check_onnx_light_model
(view on GitHub),
a self-contained
CMake project that demonstrates linking with onnx-light and running
onnx::checker::check_model() from C++. The same program also
demonstrates calling onnx_optim::shapes::InferShapesModel() —
the onnx_optim shape-inference entry point — on the loaded model.
Step 1 – Install the C++ library#
From the onnx-light repository root, build and install the static library and its public headers. The Python extension is not required:
cmake -S . -B build-install \
-DCMAKE_BUILD_TYPE=Release \
-DONNX_LIGHT_BUILD_PYTHON=OFF \
-DONNX_LIGHT_BUILD_KERNELS=OFF \
-DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build build-install
cmake --install build-install
-DONNX_LIGHT_BUILD_KERNELS=OFF skips building lib_onnx_kernels and
lib_onnx_backend_test (the operator-kernel runtime and the backend-test
case registry). They are not needed by this example, which only links the
checker / shape-inference layer exposed by onnx_light::onnx_light.
Step 2 – Build the example#
Point CMAKE_PREFIX_PATH at the install prefix chosen above:
cmake -S examples/check_onnx_light_model -B build-check-onnx-light-model \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=/usr/local
cmake --build build-check-onnx-light-model
Step 3 – Run the example#
./build-check-onnx-light-model/check_onnx_light_model path/to/model.onnx 1 1
The optional full_check argument accepts 0 (default) or 1.
When full_check=1, checker runs additional shape-inference validation.
The optional infer_shapes() argument accepts 0 (default) or 1.
When infer_shapes=1, the example loads the model into a ModelProto
and calls onnx_optim::shapes::InferShapesModel() to populate
graph.value_info and refine graph.output shapes in place, then
reports how many entries each list contains.
Example output:
Model is valid: path/to/model.onnx
full_check: true
shape inference: ok
graph.value_info entries: 12
graph.output entries: 1
CMakeLists.txt#
The example uses find_package and links against the exported
onnx_light::onnx_light target. onnx_light::lib_onnx_optim is also
linked so the program can call onnx_optim shape inference:
cmake_minimum_required(VERSION 3.15)
project(check_onnx_light_model LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(onnx_light REQUIRED)
add_executable(check_onnx_light_model main.cc)
target_link_libraries(check_onnx_light_model
PRIVATE onnx_light::onnx_light onnx_light::lib_onnx_optim)
main.cc#
The program calls the path-based checker API and handles validation failures
using onnx::checker::ValidationError. When infer_shapes=1 it
also loads the model with LoadProtoFromPath() and runs
onnx_optim::shapes::InferShapesModel() on the resulting
ModelProto.
/**
* main.cc — Standalone example: validate an ONNX model with the onnx_light
* checker API and optionally run onnx_optim shape inference on it.
*
* Usage:
* ./check_onnx_light_model <model.onnx> [full_check] [infer_shapes]
*
* When ``infer_shapes`` is set to 1, the model is loaded into a ``ModelProto``
* and passed to :cpp:func:`onnx_optim::shapes::InferShapesModel`, which
* mutates the graph in place so that its outputs and value_info entries carry
* the inferred shapes. The example then prints how many value_info entries
* the inferred graph contains.
*
* See CMakeLists.txt for build instructions.
*/
#include "onnx_lib/checker.h"
#include "onnx_lib/common/file_utils.h"
#include "onnx_optim/shapes/shape_inference.h"
#include "onnx_proto/onnx.h"
#include <charconv>
#include <iostream>
#include <string_view>
namespace {
bool ParseZeroOrOne(const char *text, bool &value) {
const std::string_view arg(text);
if (arg.empty()) {
return false;
}
int parsed = 0;
const char *begin = arg.data();
const char *end = begin + arg.size();
const auto result = std::from_chars(begin, end, parsed);
if (result.ec != std::errc() || result.ptr != end || (parsed != 0 && parsed != 1)) {
return false;
}
value = (parsed == 1);
return true;
}
} // namespace
int main(int argc, char *argv[]) {
if (argc < 2 || argc > 4) {
std::cerr << "Usage: " << argv[0] << " <model.onnx> [full_check] [infer_shapes]\n";
std::cerr << " full_check: 0 (default) or 1\n";
std::cerr << " infer_shapes: 0 (default) or 1 — runs onnx_optim shape inference\n";
return 1;
}
bool full_check = false;
if (argc >= 3 && !ParseZeroOrOne(argv[2], full_check)) {
std::cerr << "Invalid full_check value: " << argv[2] << " (expected 0 or 1)\n";
return 1;
}
bool infer_shapes = false;
if (argc == 4 && !ParseZeroOrOne(argv[3], infer_shapes)) {
std::cerr << "Invalid infer_shapes value: " << argv[3] << " (expected 0 or 1)\n";
return 1;
}
try {
ONNX_LIGHT_NAMESPACE::checker::check_model(argv[1], full_check);
std::cout << "Model is valid: " << argv[1] << "\n";
std::cout << " full_check: " << (full_check ? "true" : "false") << "\n";
if (infer_shapes) {
ONNX_LIGHT_NAMESPACE::ModelProto model;
ONNX_LIGHT_NAMESPACE::LoadProtoFromPath(argv[1], model);
ONNX_LIGHT_NAMESPACE::onnx_optim::shapes::InferShapesModel(model);
std::cout << " shape inference: ok\n";
std::cout << " graph.value_info entries: " << model.graph().value_info_size() << "\n";
std::cout << " graph.output entries: " << model.graph().output_size() << "\n";
}
} catch (const ONNX_LIGHT_NAMESPACE::checker::ValidationError &e) {
std::cerr << "Validation error in '" << argv[1] << "':\n" << e.what() << "\n";
return 2;
} catch (const std::exception &e) {
std::cerr << "Error while processing '" << argv[1] << "': " << e.what() << "\n";
return 1;
}
return 0;
}
See also#
Standalone C++ example: load an ONNX file with onnx_light – standalone example that loads a model and reports timing statistics.
checker.h – checker API reference.