{"id":30157451,"url":"https://github.com/jgalego/runnx","last_synced_at":"2026-01-20T17:00:58.238Z","repository":{"id":305741406,"uuid":"1023751935","full_name":"JGalego/RunNX","owner":"JGalego","description":"Fast, fearless, and fully verifiable ONNX runtime in Rust 🚀⚡🦀 ","archived":false,"fork":false,"pushed_at":"2025-12-30T11:31:31.000Z","size":3258,"stargazers_count":16,"open_issues_count":6,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-03T01:45:29.597Z","etag":null,"topics":["onnx","onnxruntime","rust","vibe-coded"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/runnx","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JGalego.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-21T16:30:05.000Z","updated_at":"2025-12-31T10:13:50.000Z","dependencies_parsed_at":"2025-09-01T15:15:33.441Z","dependency_job_id":"7fb36460-a4d4-4e8a-87b8-ad8575bea675","html_url":"https://github.com/JGalego/RunNX","commit_stats":null,"previous_names":["jgalego/runnx"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/JGalego/RunNX","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JGalego%2FRunNX","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JGalego%2FRunNX/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JGalego%2FRunNX/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JGalego%2FRunNX/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JGalego","download_url":"https://codeload.github.com/JGalego/RunNX/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JGalego%2FRunNX/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28607624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T16:10:39.856Z","status":"ssl_error","status_checked_at":"2026-01-20T16:10:39.493Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["onnx","onnxruntime","rust","vibe-coded"],"created_at":"2025-08-11T13:39:01.941Z","updated_at":"2026-01-20T17:00:58.191Z","avatar_url":"https://github.com/JGalego.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RunNX\n\nA minimal, **mathematically verifiable** ONNX runtime implementation in Rust.\n\n[![Crates.io](https://img.shields.io/crates/v/runnx.svg)](https://crates.io/crates/runnx)\n[![Documentation](https://docs.rs/runnx/badge.svg)](https://docs.rs/runnx)\n[![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE)\n[![CI](https://github.com/jgalego/runnx/actions/workflows/ci.yml/badge.svg)](https://github.com/jgalego/runnx/actions/workflows/ci.yml)\n[![Formal Verification](https://github.com/jgalego/runnx/actions/workflows/formal-verification.yml/badge.svg)](https://github.com/jgalego/runnx/actions/workflows/formal-verification.yml)\n[![codecov](https://codecov.io/gh/jgalego/runnx/branch/main/graph/badge.svg)](https://codecov.io/gh/jgalego/runnx)\n\n![RunNX](assets/runnx.jpg)\n\n## Overview\n\n\u003e Fast, fearless, and **formally verified** ONNX in Rust.\n\nThis project provides a minimal, educational ONNX runtime implementation focused on:\n- **Simplicity**: Easy to understand and modify\n- **Verifiability**: **Formal mathematical verification** using Why3 and property-based testing\n- **Performance**: Efficient operations using ndarray\n- **Safety**: Memory-safe Rust implementation with mathematical guarantees\n\n## Features\n\n- ✅ **Dual Format Support**: JSON and binary ONNX protobuf formats with automatic detection\n- ✅ **Graph Visualization**: Beautiful terminal ASCII art and professional Graphviz export\n  - Terminal visualization with dynamic layout and rich formatting\n  - DOT format export for publication-quality diagrams (PNG, SVG, PDF)\n  - CLI integration with `--graph` and `--dot` options\n  - Topological sorting and cycle detection\n- ✅ **Comprehensive Operator Support**: Wide range of ONNX operators for various model types\n  - **Core Operations**: `Add`, `Mul`, `MatMul`, `Conv`, `Relu`, `Sigmoid`, `Reshape`, `Transpose`\n  - **Advanced Operations**: `Concat`, `Slice`, `Upsample`, `MaxPool`, `Softmax`, `NonMaxSuppression`\n  - **Computer Vision**: Support for CNN architectures and object detection models\n  - **Tested Compatibility**: Validated with real-world models including YOLOv8\n- ✅ **Formal Verification**: Mathematical specifications with Why3 and property-based testing\n- ✅ **Production Ready Features**:\n  - Model loading and validation with comprehensive error handling\n  - Async support for high-throughput inference\n  - Benchmarking and performance monitoring\n  - Command-line tools for model testing and visualization\n  - Comprehensive examples and documentation\n\n## Quick Start\n\n### Prerequisites\n\nRunNX requires the Protocol Buffers compiler (`protoc`) to build:\n\n```bash\n# Ubuntu/Debian\nsudo apt-get install protobuf-compiler\n\n# macOS  \nbrew install protobuf\n\n# Windows\nchoco install protoc\n```\n\n### Installation\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nrunnx = \"0.2.0\"\n```\n\n### Basic Usage\n\n```rust\nuse runnx::{Model, Tensor};\n\n// Load a model (supports both JSON and ONNX binary formats)  \nlet model = Model::from_file(\"model.onnx\")?;  // Auto-detects format\n// Or explicitly:\n// let model = Model::from_onnx_file(\"model.onnx\")?;  // Binary ONNX\n// let model = Model::from_json_file(\"model.json\")?;  // JSON format\n\n// Create input tensor\nlet input = Tensor::from_array(ndarray::array![[1.0, 2.0, 3.0]]);\n\n// Run inference\nlet outputs = model.run(\u0026[(\"input\", input)])?;\n\n// Get results\nlet result = outputs.get(\"output\").unwrap();\nprintln!(\"Result: {:?}\", result.data());\n```\n\n### Computer Vision Example\n\nRunNX supports various computer vision models. Here's an example with object detection:\n\n```rust\nuse runnx::Model;\n\n// Load any compatible ONNX model (e.g., classification, detection, segmentation)\nlet model = Model::from_file(\"vision_model.onnx\")?;\n\n// For object detection models like YOLOv8, RCNN, etc.\n// The runtime handles various operator types automatically\ncargo run --example yolov8_detect_and_draw  // YOLOv8 detection example\n```\n\n### Saving Models\n\n```rust\nuse runnx::Model;\n\nlet model = /* ... create or load model ... */;\n\n// Save in different formats\nmodel.to_file(\"output.onnx\")?;    // Auto-detects format from extension  \nmodel.to_onnx_file(\"binary.onnx\")?;  // Explicit binary ONNX format\nmodel.to_json_file(\"readable.json\")?;  // Explicit JSON format\n```\n\n### Command Line Usage\n\n```bash\n# Run inference on a model (supports both .onnx and .json files)\ncargo run --bin runnx-runner -- --model model.onnx --input input.json\ncargo run --bin runnx-runner -- --model model.json --input input.json\n\n# Show model summary and graph visualization\ncargo run --bin runnx-runner -- --model model.onnx --summary --graph\n\n# Generate Graphviz DOT file for professional diagrams\ncargo run --bin runnx-runner -- --model model.onnx --dot graph.dot\n\n# Run specialized examples (computer vision, object detection, etc.)\ncargo run --example yolov8_detect_and_draw  # Object detection example\n\n# Run async inference (requires --features async)\ncargo run --features async --bin runnx-runner -- --model model.onnx --input input.json\n```\n\n## Graph Visualization\n\nRunNX provides comprehensive graph visualization capabilities to help you understand and debug ONNX model structures. You can visualize models both in the terminal and as publication-quality graphics.\n\n### Terminal Visualization\n\nDisplay beautiful ASCII art representations of your model directly in the terminal:\n\n```bash\n# Show visual graph representation\n./target/debug/runnx-runner --model model.onnx --graph\n\n# Show both model summary and graph\n./target/debug/runnx-runner --model model.onnx --summary --graph\n```\n\n#### Example Output\n\nHere's what the terminal visualization looks like for a complex neural network:\n\n```\n┌────────────────────────────────────────┐\n│       GRAPH: neural_network_demo       │\n└────────────────────────────────────────┘\n\n📥 INPUTS:\n   ┌─ image_input [1 × 3 × 224 × 224] (float32)\n   ┌─ mask_input [1 × 1 × 224 × 224] (float32)\n\n⚙️  INITIALIZERS:\n   ┌─ conv1_weight [64 × 3 × 7 × 7]\n   ┌─ conv1_bias [64]\n   ┌─ fc_weight [1000 × 512]\n   ┌─ fc_bias [1000]\n\n🔄 COMPUTATION FLOW:\n   │\n   ├─ Step 1: conv1\n   │  ┌─ Operation: Conv\n   │  ├─ Inputs:\n   │  │  └─ image_input\n   │  │  └─ conv1_weight\n   │  │  └─ conv1_bias\n   │  ├─ Outputs:\n   │  │  └─ conv1_output\n   │  └─ Attributes:\n   │     └─ kernel_shape: [7, 7]\n   │     └─ strides: [2, 2]\n   │     └─ pads: [3, 3, 3, 3]\n   │\n   ├─ Step 2: relu1\n   │  ┌─ Operation: Relu\n   │  ├─ Inputs:\n   │  │  └─ conv1_output\n   │  ├─ Outputs:\n   │  │  └─ relu1_output\n   │  └─ (no attributes)\n   \n   [... more steps ...]\n\n📤 OUTPUTS:\n   └─ classification [1 × 1000] (float32)\n   └─ segmentation [1 × 21 × 224 × 224] (float32)\n\n📊 STATISTICS:\n   ├─ Total nodes: 10\n   ├─ Input tensors: 2\n   ├─ Output tensors: 2\n   └─ Initializers: 4\n\n🎯 OPERATION SUMMARY:\n   ├─ Add: 1\n   ├─ Conv: 2\n   ├─ Flatten: 1\n   ├─ GlobalAveragePool: 1\n   ├─ MatMul: 1\n   ├─ MaxPool: 1\n   ├─ Mul: 1\n   ├─ Relu: 1\n   └─ Upsample: 1\n```\n\n### Graphviz Export\n\nGenerate professional diagrams using DOT format for Graphviz:\n\n```bash\n# Generate DOT file for Graphviz\n./target/debug/runnx-runner --model model.onnx --dot graph.dot\n\n# Convert to PNG (requires Graphviz installation)\ndot -Tpng graph.dot -o graph.png\n\n# Convert to SVG for vector graphics\ndot -Tsvg graph.dot -o graph.svg\n\n# Convert to PDF for documents\ndot -Tpdf graph.dot -o graph.pdf\n```\n\n#### Example Graph Output\n\nThe DOT format generates clean, professional diagrams with:\n- **Green ellipses** for input tensors\n- **Blue diamonds** for initializers (weights/biases)  \n- **Rectangular boxes** for operations\n- **Red ellipses** for output tensors\n- **Directed arrows** showing data flow\n\n![Complex Neural Network Graph](assets/complex_graph.png)\n\n*Example: Multi-task neural network with classification and segmentation branches*\n\n#### DOT Format Output\n\nThe generated DOT file contains structured graph data that Graphviz uses to create the visualizations. Here's an excerpt of the DOT format:\n\n```dot\ndigraph G {\n  rankdir=TB;\n  node [shape=box, style=rounded];\n\n  \"image_input\" [shape=ellipse, color=green, label=\"image_input\"];\n  \"mask_input\" [shape=ellipse, color=green, label=\"mask_input\"];\n  \"conv1_weight\" [shape=diamond, color=blue, label=\"conv1_weight\"];\n  \"conv1_bias\" [shape=diamond, color=blue, label=\"conv1_bias\"];\n  \"conv1\" [label=\"conv1\\n(Conv)\"];\n  \"relu1\" [label=\"relu1\\n(Relu)\"];\n  \"classification\" [shape=ellipse, color=red, label=\"classification\"];\n  \"segmentation\" [shape=ellipse, color=red, label=\"segmentation\"];\n\n  \"image_input\" -\u003e \"conv1\";\n  \"conv1_weight\" -\u003e \"conv1\";\n  \"conv1_bias\" -\u003e \"conv1\";\n  \"conv1\" -\u003e \"relu1\";\n  \"relu1\" -\u003e \"classification\";\n  // ... additional connections\n}\n```\n\nThe DOT format uses:\n- **Nodes**: Define graph elements with shapes, colors, and labels\n- **Edges**: Define connections with `-\u003e` arrows\n- **Attributes**: Control visual appearance and layout\n- **rankdir=TB**: Top-to-bottom layout direction\n\nFor the complete DOT file example, see [`assets/complex_graph.dot`](assets/complex_graph.dot).\n\n### Programmatic Usage\n\nYou can also generate visualizations programmatically:\n\n```rust\nuse runnx::Model;\n\nlet model = Model::from_file(\"model.onnx\")?;\n\n// Print graph to terminal\nmodel.print_graph();\n\n// Generate DOT format\nlet dot_content = model.to_dot();\nstd::fs::write(\"graph.dot\", dot_content)?;\n\n// The graph name box automatically adjusts to any length\n// Works with short names like \"CNN\" or very long names like\n// \"SuperLongComplexNeuralNetworkGraphName\"\n```\n\n### Features\n\n- **Dynamic Layout**: Graph title box automatically adjusts to accommodate any name length\n- **Topological Sorting**: Shows correct execution order with dependency resolution\n- **Cycle Detection**: Gracefully handles graphs with cycles  \n- **Rich Information**: Displays shapes, data types, attributes, and statistics\n- **Color Coding**: Visual distinction between different node types in DOT format\n- **Multiple Formats**: Terminal ASCII art and Graphviz-compatible DOT export\n- **Professional Quality**: Publication-ready graphics for papers and presentations\n\n## Architecture\n\nThe runtime is organized into several key components:\n\n### Core Components\n\n- **Model**: ONNX model representation and loading\n- **Graph**: Computational graph with nodes and edges\n- **Tensor**: N-dimensional array wrapper with type safety\n- **Operators**: Implementation of ONNX operations\n- **Runtime**: Execution engine with optimizations\n\n### File Format Support\n\nRunNX supports both JSON and binary ONNX protobuf formats:\n\n#### 📄 JSON Format\n- **Human-readable**: Easy to inspect and debug\n- **Text-based**: Can be viewed and edited in any text editor\n- **Larger file size**: More verbose due to text representation\n- **Extension**: `.json`\n\n#### 🔧 Binary ONNX Format  \n- **Standard format**: Official ONNX protobuf serialization\n- **Compact**: Smaller file sizes due to binary encoding\n- **Interoperable**: Compatible with other ONNX runtime implementations\n- **Extension**: `.onnx`\n\n#### 🎯 Auto-Detection\nThe `Model::from_file()` method automatically detects the format based on file extension:\n- `.onnx` files → Binary ONNX protobuf format\n- `.json` files → JSON format  \n- Other extensions → Attempts JSON parsing as fallback\n\nFor explicit control, use:\n- `Model::from_onnx_file()` for binary ONNX files\n- `Model::from_json_file()` for JSON files\n\n### Supported Operators\n\n#### Core Operators\n| Operator      | Status   | Notes                       |\n| ------------- | -------- | --------------------------- |\n| `Add`         | ✅      | Element-wise addition        |\n| `Mul`         | ✅      | Element-wise multiplication  |\n| `MatMul`      | ✅      | Matrix multiplication        |\n| `Conv`        | ✅      | 2D Convolution               |\n| `Relu`        | ✅      | Rectified Linear Unit        |\n| `Sigmoid`     | ✅      | Sigmoid activation           |\n| `Reshape`     | ✅      | Tensor reshaping             |\n| `Transpose`   | ✅      | Tensor transposition         |\n\n#### Advanced Operators\n| Operator             | Status   | Notes                                |\n| -------------------- | -------- | ------------------------------------ |\n| `Concat`             | ✅      | Tensor concatenation                 |\n| `Slice`              | ✅      | Tensor slicing operations            |\n| `Upsample`           | ✅      | Feature map upsampling               |\n| `MaxPool`            | ✅      | Max pooling operations               |\n| `Softmax`            | ✅      | Softmax normalization                |\n| `NonMaxSuppression`  | ✅      | Non-maximum suppression              |\n\n*Legend: ✅ = Fully implemented, 🚧 = In development, ❌ = Not implemented*\n\n**Model Compatibility**: These operators enable support for various model architectures including:\n- **Computer Vision**: CNNs, ResNet, EfficientNet, Vision Transformers\n- **Object Detection**: YOLO family (YOLOv8, YOLOv5), R-CNN variants, SSD\n- **Classification**: Image classifiers and feature extractors\n- **Custom Models**: Any ONNX model using the supported operator set\n\n## Examples\n\n### Model Loading and Basic Inference\n\n```rust\nuse runnx::{Model, Tensor};\nuse std::collections::HashMap;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    // Load model from file\n    let model = Model::from_file(\"path/to/model.onnx\")?;\n    \n    // Print model information\n    println!(\"Model: {}\", model.name());\n    println!(\"Inputs: {:?}\", model.input_names());\n    println!(\"Outputs: {:?}\", model.output_names());\n    \n    // Prepare inputs\n    let mut inputs = HashMap::new();\n    inputs.insert(\"input\", Tensor::zeros(\u0026[1, 3, 224, 224]));\n    \n    // Run inference\n    let outputs = model.run(\u0026inputs)?;\n    \n    // Process outputs\n    for (name, tensor) in outputs {\n        println!(\"Output '{}': shape {:?}\", name, tensor.shape());\n    }\n    \n    Ok(())\n}\n```\n\n### Computer Vision Applications\n\nRunNX supports various computer vision models including object detection:\n\n```bash\n# Object detection example (YOLOv8)\ncargo run --example yolov8_detect_and_draw\n\n# Expected workflow:\n# 1. Model loading and validation\n# 2. Image preprocessing (resize, normalize)\n# 3. Inference execution\n# 4. Post-processing (NMS, confidence filtering)\n# 5. Visualization (bounding boxes, labels)\n```\n\n### Format Compatibility Demo\n\n```rust\nuse runnx::*;\n\nfn main() -\u003e runnx::Result\u003c()\u003e {\n    // Create a simple model\n    let mut graph = graph::Graph::new(\"demo_graph\".to_string());\n    \n    // Add input/output specifications\n    let input_spec = graph::TensorSpec::new(\"input\".to_string(), vec![Some(1), Some(4)]);\n    let output_spec = graph::TensorSpec::new(\"output\".to_string(), vec![Some(1), Some(4)]);\n    graph.add_input(input_spec);\n    graph.add_output(output_spec);\n    \n    // Add a ReLU node\n    let relu_node = graph::Node::new(\n        \"relu_1\".to_string(),\n        \"Relu\".to_string(), \n        vec![\"input\".to_string()],\n        vec![\"output\".to_string()],\n    );\n    graph.add_node(relu_node);\n    \n    let model = model::Model::with_metadata(\n        model::ModelMetadata {\n            name: \"demo_model\".to_string(),\n            version: \"1.0\".to_string(),\n            description: \"A simple ReLU demo model\".to_string(),\n            producer: \"RunNX Demo\".to_string(),\n            onnx_version: \"1.9.0\".to_string(),\n            domain: \"\".to_string(),\n        },\n        graph,\n    );\n\n    // Save in both formats\n    model.to_json_file(\"demo_model.json\")?;\n    model.to_onnx_file(\"demo_model.onnx\")?;\n    \n    // Load from both formats\n    let json_model = model::Model::from_json_file(\"demo_model.json\")?;\n    let onnx_model = model::Model::from_onnx_file(\"demo_model.onnx\")?;\n    \n    // Auto-detection also works\n    let auto_json = model::Model::from_file(\"demo_model.json\")?;\n    let auto_onnx = model::Model::from_file(\"demo_model.onnx\")?;\n    \n    println!(\"✅ All formats loaded successfully!\");\n    println!(\"Original: {}\", model.name());\n    println!(\"JSON: {}\", json_model.name());\n    println!(\"ONNX: {}\", onnx_model.name());\n    \n    Ok(())\n}\n```\n\n### Simple Linear Model\n\n```rust\nuse runnx::{Model, Tensor};\nuse ndarray::Array2;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    // Initialize logging\n    env_logger::init();\n\n    // Create a simple linear transformation: y = x * w + b\n    let weights = Array2::from_shape_vec((3, 2), vec![0.5, 0.3, 0.2, 0.4, 0.1, 0.6])?;\n    let bias = Array2::from_shape_vec((1, 2), vec![0.1, 0.2])?;\n    \n    let input = Tensor::from_array(Array2::from_shape_vec((1, 3), vec![1.0, 2.0, 3.0])?);\n    let w_tensor = Tensor::from_array(weights);\n    let b_tensor = Tensor::from_array(bias);\n    \n    // Manual computation for verification\n    let result1 = input.matmul(\u0026w_tensor)?;\n    let result2 = result1.add(\u0026b_tensor)?;\n    \n    println!(\"Linear transformation result: {:?}\", result2.data());\n    Ok(())\n}\n```\n\n### Available Examples\n\n```bash\n# Basic model operations and format compatibility\ncargo run --example onnx_demo\ncargo run --example simple_model\ncargo run --example format_conversion\n\n# Computer vision applications\ncargo run --example yolov8_detect_and_draw      # Object detection example\ncargo run --example yolov8_object_detection     # Detection with post-processing\ncargo run --example yolov8n_compat_demo         # Model compatibility testing\n\n# Core functionality\ncargo run --example tensor_ops                  # Tensor operations\ncargo run --example formal_verification         # Mathematical verification\ncargo run --example test_onnx_support          # Operator support testing\n```\n\n### Custom Model Creation\n\n```rust\nuse runnx::*;\n\nfn create_simple_model() -\u003e runnx::Result\u003c()\u003e {\n    // Create a simple neural network model\n    let mut graph = graph::Graph::new(\"custom_model\".to_string());\n    \n    // Define inputs and outputs\n    let input_spec = graph::TensorSpec::new(\"input\".to_string(), vec![Some(1), Some(4)]);\n    let output_spec = graph::TensorSpec::new(\"output\".to_string(), vec![Some(1), Some(4)]);\n    graph.add_input(input_spec);\n    graph.add_output(output_spec);\n    \n    // Add operations\n    let relu_node = graph::Node::new(\n        \"activation\".to_string(),\n        \"Relu\".to_string(), \n        vec![\"input\".to_string()],\n        vec![\"output\".to_string()],\n    );\n    graph.add_node(relu_node);\n    \n    // Create model with metadata\n    let model = model::Model::with_metadata(\n        model::ModelMetadata {\n            name: \"custom_neural_network\".to_string(),\n            version: \"1.0\".to_string(),\n            description: \"Custom model example\".to_string(),\n            producer: \"RunNX\".to_string(),\n            onnx_version: \"1.9.0\".to_string(),\n            domain: \"\".to_string(),\n        },\n        graph,\n    );\n\n    // Save in multiple formats\n    model.to_json_file(\"custom_model.json\")?;\n    model.to_onnx_file(\"custom_model.onnx\")?;\n    \n    println!(\"✅ Custom model created and saved!\");\n    Ok(())\n}\n```\n    graph.add_node(silu_sigmoid);\n    graph.add_node(silu_mul);\n    \n    // Multi-scale feature processing\n    let upsample = graph::Node::new(\n        \"upsample\".to_string(),\n        \"Upsample\".to_string(),\n        vec![\"silu_out\".to_string()],\n        vec![\"upsampled\".to_string()],\n    );\n    let concat = graph::Node::new(\n        \"concat\".to_string(),\n        \"Concat\".to_string(),\n        vec![\"upsampled\".to_string(), \"silu_out\".to_string()],\n        vec![\"concat_out\".to_string()],\n    );\n    graph.add_node(upsample);\n    graph.add_node(concat);\n    \n    // Detection head with Softmax\n    let head_conv = graph::Node::new(\n        \"head_conv\".to_string(),\n        \"Conv\".to_string(),\n        vec![\"concat_out\".to_string()],\n        vec![\"raw_detections\".to_string()],\n    );\n    let softmax = graph::Node::new(\n        \"softmax\".to_string(),\n        \"Softmax\".to_string(),\n        vec![\"raw_detections\".to_string()],\n        vec![\"detections\".to_string()],\n    );\n    graph.add_node(head_conv);\n    graph.add_node(softmax);\n    \n    let model = model::Model::with_metadata(\n        model::ModelMetadata {\n            name: \"yolo_demo_v1\".to_string(),\n            version: \"1.0\".to_string(),\n            description: \"YOLO-like object detection model\".to_string(),\n            producer: \"RunNX YOLO Demo\".to_string(),\n            onnx_version: \"1.9.0\".to_string(),\n            domain: \"\".to_string(),\n        },\n        graph,\n    );\n    \n    println!(\"🎯 YOLO Model Created!\");\n    println!(\"   Inputs: {} ({})\", model.graph.inputs.len(), model.graph.inputs[0].name);\n    println!(\"   Outputs: {} ({})\", model.graph.outputs.len(), model.graph.outputs[0].name);\n    println!(\"   Nodes: {} (Conv, SiLU, Upsample, Concat, Softmax)\", model.graph.nodes.len());\n    \n    Ok(())\n}\n```\n\n### Basic Model Loading\n\n```rust\nuse runnx::{Model, Tensor};\nuse std::collections::HashMap;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    // Load model from file\n    let model = Model::from_file(\"path/to/model.onnx\")?;\n    \n    // Print model information\n    println!(\"Model: {}\", model.name());\n    println!(\"Inputs: {:?}\", model.input_names());\n    println!(\"Outputs: {:?}\", model.output_names());\n    \n    // Prepare inputs\n    let mut inputs = HashMap::new();\n    inputs.insert(\"input\", Tensor::zeros(\u0026[1, 3, 224, 224]));\n    \n    // Run inference\n    let outputs = model.run(\u0026inputs)?;\n    \n    // Process outputs\n    for (name, tensor) in outputs {\n        println!(\"Output '{}': shape {:?}\", name, tensor.shape());\n    }\n    \n    Ok(())\n}\n```\n\n## Performance\n\nThe runtime includes benchmarking capabilities:\n\n```bash\n# Run benchmarks\ncargo bench\n\n# Generate HTML reports\ncargo bench -- --output-format html\n```\n\nExample benchmark results:\n- Basic operations: ~10-50 µs\n- Small model inference: ~100-500 µs\n- Medium model inference: ~1-10 ms\n\n## Formal Verification\n\nRunNX includes comprehensive formal verification capabilities to ensure mathematical correctness:\n\n### 🔬 Mathematical Specifications\n\nThe runtime includes formal specifications for all tensor operations using Why3:\n\n```why3\n(** Addition operation specification *)\nfunction add_spec (a b: tensor) : tensor\n  requires { valid_tensor a /\\ valid_tensor b }\n  requires { a.shape = b.shape }\n  ensures  { valid_tensor result }\n  ensures  { result.shape = a.shape }\n  ensures  { forall i. 0 \u003c= i \u003c length result.data -\u003e\n             result.data[i] = a.data[i] + b.data[i] }\n```\n\n### 🧪 Property-Based Testing\n\nAutomatic verification of mathematical properties:\n\n```rust\nuse runnx::formal::contracts::{AdditionContracts, ActivationContracts, YoloOperatorContracts};\n\n// Test addition commutativity: a + b = b + a\nlet result1 = tensor_a.add_with_contracts(\u0026tensor_b)?;\nlet result2 = tensor_b.add_with_contracts(\u0026tensor_a)?;\nassert_eq!(result1.data(), result2.data());\n\n// Test ReLU idempotency: ReLU(ReLU(x)) = ReLU(x)  \nlet relu_once = tensor.relu_with_contracts()?;\nlet relu_twice = relu_once.relu_with_contracts()?;\nassert_eq!(relu_once.data(), relu_twice.data());\n\n// Test Softmax probability distribution: sum = 1.0\nlet softmax_result = tensor.softmax_with_contracts()?;\nlet sum: f32 = softmax_result.data().iter().sum();\nassert!((sum - 1.0).abs() \u003c 1e-6);\n```\n\n### 🔍 Runtime Verification\n\nDynamic checking of invariants during execution:\n\n```rust\nuse runnx::formal::runtime_verification::InvariantMonitor;\n\nlet monitor = InvariantMonitor::new();\nlet result = tensor.add(\u0026other)?;\n\n// Verify numerical stability and bounds\nassert!(monitor.verify_operation(\u0026[\u0026tensor, \u0026other], \u0026[\u0026result]));\n```\n\n### 🎯 Verified Properties\n\nThe formal verification system proves:\n\n- **Addition**: Commutativity, associativity, identity\n- **Matrix Multiplication**: Associativity, distributivity  \n- **ReLU**: Idempotency, monotonicity, non-negativity\n- **Sigmoid**: Boundedness (0, 1), monotonicity, symmetry\n- **Numerical Stability**: Overflow/underflow prevention\n\n### 📊 Running Formal Verification\n\n```bash\n# Install Why3 (optional, for complete formal proofs)\nmake -C formal install-why3\n\n# Run all verification (tests + proofs)\nmake -C formal all\n\n# Run only property-based tests (no Why3 required)\ncargo test formal --lib\n\n# Run verification example\ncargo run --example formal_verification\n\n# Generate verification report  \nmake -C formal report\n```\n\n## Development\n\n### Quick Development with Justfile\n\nRunNX includes a [Justfile](justfile) with convenient shortcuts for common development tasks:\n\n```bash\n# Install just command runner (one time setup)\ncargo install just\n\n# Show all available commands\njust --list\n\n# Quick development cycle\njust dev          # Format, lint, and test\njust test         # Run all tests\njust build        # Build the project\njust examples     # Run all examples\n\n# Code quality\njust format       # Format code\njust lint         # Run clippy\njust quality      # Run quality check script\n\n# Documentation  \njust docs-open    # Build and open docs\n\n# Benchmarks\njust bench        # Run benchmarks\n\n# Formal verification\njust formal-test  # Test formal verification setup\n\n# CI simulation\njust ci          # Simulate CI checks locally\n```\n\n**Alternatively**, if you don't have `just` installed, use the included shell script:\n\n```bash\n# Show all available commands\n./dev.sh help\n\n# Quick development cycle\n./dev.sh dev      # Format, lint, and test\n./dev.sh test     # Run all tests  \n./dev.sh examples # Run all examples\n```\n\n### Running Tests\n\n```bash\n# Run all tests\ncargo test\n# or with just\njust test\n\n# Run tests with logging\nRUST_LOG=debug cargo test\n\n# Run specific test\ncargo test test_tensor_operations\n```\n\n### Building Documentation\n\n```bash\n# Build and open documentation\ncargo doc --open\n# or with just  \njust docs-open\n\n# Build with private items\ncargo doc --document-private-items\n```\n\n### Contributing\n\nWe welcome contributions! Please follow our development quality standards:\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes following our [Development QA Guidelines](docs/DEVELOPMENT_QA.md)\n4. Add tests and documentation\n5. Run quality checks: `./scripts/quality-check.sh`\n6. Commit your changes (pre-commit hooks will run automatically)\n7. Submit a pull request\n\n#### Development Quality Assurance\n\nRunNX uses automated quality assurance tools to maintain code quality:\n\n- **Pre-commit hooks**: Automatically run formatting, linting, and tests before each commit\n- **Code formatting**: Consistent style enforced by `rustfmt`\n- **Linting**: Comprehensive checks with `clippy` (warnings treated as errors)\n- **Comprehensive testing**: Unit tests, integration tests, property-based tests, and doc tests\n- **Build verification**: Ensures all code compiles successfully\n\nFor detailed information, see [Development QA Guidelines](docs/DEVELOPMENT_QA.md).\n\nTo run quality checks manually:\n```bash\n# Run all quality checks with auto-fixes\n./scripts/quality-check.sh\n\n# Or run individual checks\ncargo fmt           # Format code\ncargo clippy        # Run linting\ncargo test          # Run all tests\n```\n\n## License\n\nThis project is licensed under\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\n\n## Acknowledgments\n\n- [ONNX](https://onnx.ai/) - Open Neural Network Exchange format\n- [ndarray](https://github.com/rust-ndarray/ndarray) - Rust's `ndarray` library\n- [Candle](https://github.com/huggingface/candle) - Inspiration for some design patterns\n\n## Roadmap\n\n### ✅ Completed\n- [x] **Dual Format Support**: Both JSON and binary ONNX protobuf formats\n- [x] **Auto-detection**: Automatic format detection based on file extension  \n- [x] **Graph Visualization**: Terminal ASCII art and professional Graphviz export\n- [x] **Core Operators**: Add, Mul, MatMul, Conv, ReLU, Sigmoid, Reshape, Transpose\n- [x] **YOLO Operators**: Concat, Slice, Upsample, MaxPool, Softmax, NonMaxSuppression\n- [x] **Formal Verification**: Mathematical specifications with Why3\n- [x] **CLI Tool**: Command-line runner with visualization capabilities\n\n### 🚧 In Progress\n- [ ] **Performance Optimizations**: GPU acceleration and SIMD vectorization\n- [ ] **Extended ONNX Support**: Additional operators (BatchNorm, LayerNorm, etc.)\n- [ ] **Quantization**: INT8 and FP16 model support\n- [ ] **Model Optimization**: Graph optimization passes and operator fusion\n\n### 🚀 Planned\n- [ ] **Deployment Targets**: WASM compilation and embedded systems support\n- [ ] **Language Bindings**: Python and JavaScript bindings\n- [ ] **Enterprise Features**: Model serving and distributed inference\n- [ ] **Advanced Visualization**: Interactive model exploration tools\n\n## Documentation\n\n### 📚 Additional Resources\n\n- **[Release Notes](RELEASE_NOTES_0.2.0.md)** - What's new in the latest version\n- **[Complete Changelog](CHANGELOG.md)** - Full history of changes\n- **[Release History](docs/releases/)** - All previous release notes\n- **[Contributing Guide](CONTRIBUTING.md)** - How to contribute to RunNX\n- **[Development QA](docs/DEVELOPMENT_QA.md)** - Quality assurance guidelines\n- **[Formal Verification](FORMAL_VERIFICATION.md)** - Mathematical verification details\n\n### 🔗 External Links\n\n- **[API Documentation](https://docs.rs/runnx)** - Complete API reference\n- **[Crates.io](https://crates.io/crates/runnx)** - Package information\n- **[GitHub Repository](https://github.com/JGalego/runnx)** - Source code and issues\n- **[CI/CD Status](https://github.com/JGalego/runnx/actions)** - Build and test results\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgalego%2Frunnx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjgalego%2Frunnx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgalego%2Frunnx/lists"}