{"id":13435783,"url":"https://github.com/kraiskil/onnx2c","last_synced_at":"2025-10-25T01:29:37.075Z","repository":{"id":37791022,"uuid":"284266752","full_name":"kraiskil/onnx2c","owner":"kraiskil","description":"Open Neural Network Exchange to C compiler.","archived":false,"fork":false,"pushed_at":"2024-10-15T17:00:23.000Z","size":30934,"stargazers_count":213,"open_issues_count":17,"forks_count":35,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-16T22:38:50.480Z","etag":null,"topics":["edge-computing","machine-learning","microcontroller","neural-network","onnx"],"latest_commit_sha":null,"homepage":"","language":"C","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/kraiskil.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2020-08-01T13:37:19.000Z","updated_at":"2024-10-16T11:24:39.000Z","dependencies_parsed_at":"2024-08-15T12:10:46.919Z","dependency_job_id":"814e8f0c-5b65-4b3b-af84-2a865058d0bf","html_url":"https://github.com/kraiskil/onnx2c","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kraiskil%2Fonnx2c","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kraiskil%2Fonnx2c/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kraiskil%2Fonnx2c/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kraiskil%2Fonnx2c/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kraiskil","download_url":"https://codeload.github.com/kraiskil/onnx2c/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244211175,"owners_count":20416591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["edge-computing","machine-learning","microcontroller","neural-network","onnx"],"created_at":"2024-07-31T03:00:39.155Z","updated_at":"2025-10-25T01:29:37.070Z","avatar_url":"https://github.com/kraiskil.png","language":"C","funding_links":[],"categories":["C","Lighter and Deployment Frameworks","Uncategorized","Data \u0026 Science"],"sub_categories":["Uncategorized","Machine Learning Framework"],"readme":"onnx2c\n======\n\nOnnx2c is a [ONNX](https://onnx.ai) to C compiler. It will read an ONNX file,\nand generate C code to be included in your project.\n\nOnnx2c's target is \"Tiny ML\", meaning running the inference on microcontrollers. To make this\neasier, the generated code:\n\n- Does not `#include \u003cstdio.h\u003e` (i.e. no `printf()`s)\n- Compile-time allocates buffers. Does not use dynamic memory allocation or (much) stack memory\n- Has no library requirements except standard C maths library. (Floating point hardware recommended!)\n- Should be compiler-friendly allowing the C compiler optimize the output as well as it can\n- Is contained in one single C file for easier project management\n\nThe idea behind onnx2c is to be an easy-to-use tool with no learning curve. If you can export your trained\nneural network to an ONNX file (e.g. PyTorch and Tensorflow both can) and you have a working microcontroller\nproject, then joining the two with onnx2c should be easy.\n\nTo make all of the above easier to achieve, there are some non-goals for onnx2c:\n\n - ONNX specification coverage. (For now, 91 out of 166 ONNX Operands are at least partially implemented).\n - accelerators\n - backpropagation (i.e. training)\n\n\nBuilding\n--------\n\nMake sure you have ProtocolBuffers libraries installed, e.g.: \n\n - Ubuntu: `apt install libprotobuf-dev protobuf-compiler`\n - MacOS: `brew install protobuf`\n\nGet the sources:\n\n```\ngit clone https://github.com/kraiskil/onnx2c.git\ncd onnx2c\ngit submodule update --init\n```\n\nthen run a standard CMake build\n\n```\nmkdir build\ncd build\ncmake -DCMAKE_BUILD_TYPE=Release ..\nmake onnx2c\n```\n\n### FAQ\n\n#### Getting `error: ‘class onnx::ModelProto’ has no member named ‘ParseFromIstream’;` ?\n\nIf you have ProtoBuf 3.6 or earlier, you need the following modification to `onnx/onnx/onnx.proto`\n\n- remove the last lines (i.e. option `optimize_for = LITE_RUNTIME;`)\n\nWith ProtoBuf 3.12 (e.g. Ubuntu 20.10 onwards) this modification is not needed.\n\nVersions between 3.6 and 3.12 are uninvestigated.\n\n#### Seeing build error  `void* __builtin_memset ... is out of the bounds ...` ?\n\nOn (at least) protobuf 3.6, which ships as default on Ubuntu 20.04, the build fails when onnx2c is build in `Release` mode.\n\nChange the buildstep above to `cmake -DCMAKE_BUILD_TYPE=Debug ..`\nOr update your protobuf.\nSee kraiskil/onnx2c#39 and onnx/onnx#4756.\n\nUsage\n-----\n\nThe build creates `onnx2c` binary. \nRun \n\n`./onnx2c [your ONNX model file] \u003e model.c`\n\nAt the end of the `model.c` there is a function called 'void entry(...)'.\nCall that from your main program to run inference. Function parameters are named as in your ONNX model.\n\nUsing the compiler `-ffast-math` (or equivalent) when compiling onnx2c-generated code increases computation speed.\nSee the [GCC wiki on floating point maths](https://gcc.gnu.org/wiki/FloatingPointMath) for details.\n\nOnnx2c has a few optimization passes that modify the generated output:\n - Tensor unionization to wrap intermediate tensors in unions to help the compiler re-use the heap memory.\n - Removing `Cast` nodes, by modifying their predecessor node's output tensor.\n - Optimization for AVR processors to put constants into instruction memory.\n - An [experimental quantization option](quantization.md) to convert floating point calculation to integers.\n\n`./onnx2c -h` prints out all available command line options.\n\nonnx2c prints a log on stdout. Log level can be given with the `-l N` command line option.\nLogging levels are\n - 0 Fatal errors only\n - 1 Warnings where onnx2c might not be correctly implemented\n - 2 Generic info (default level in the Release build)\n - 3 Debug: high level trace of what onnx2c does useful debugging the model\n - 4 Trace: detailed info useful for debugging onnx2c\n\nThere is a [helper script](scripts/) to initially run any `.onnx` on a MCU development board. This is intended\nas a tool when designing the network to see if it will fit the target, before starting training the network.\nSee the script sources and [the onnx2c development documentation](development.md) for instructions.\n\n\nDevelopment\n-----------\n\nTips for development of onnx2c, including testing is described in [a separate file](development.md).\n\n\nOn-target performance\n---------------------\n\nor, how to extrapolate from incomplete data.\n\nAt the time of writing this, a single ONNX neural net has been benchmarked with\nonnx2c - the [\"Hello World\"-sine generating example from TensorFlow Lite micro](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/hello_world/train/train_hello_world_model.ipynb) and compiled to ONNX with keras2onnx.\n\nThat ONNX file was compiled with  STM32CubeAI and onnx2c to a STM32F411\nrunning STM32Cube HAL with a clock speed of 84 or 96MHz. With same project and\noptimization settings (gcc -O4), measuring inference time by toggling GPIO pins,\nthe STMCubeAI-generated version ran at 490us, while the onnx2c one took 20us.\n\nSee Notes below for a description of the RAM optmimized version.\n\nMemory consumption was about similar:\n| platform               |text      |  data  |  bss | runtime |\n|:-----------------------|---------:|-------:|-----:|--------:|\n|STM HAL + onnx2c @96MHz |     8276 |   1300 |  3060| 20us    |\n|STM HAL + CubeAI @96MHz |     14372|   1696 |  2808| 490us   |\n|OpenCM3 + onnx2c @84MHz |     8236 |   1296 |   388| 25us    |\n|--\"-- (onnx2c RAM opt)  |     8236 |     12 |   388| 29us    |\n\n\n### Comparison \n\nThe same NN model was measured\n[on a youtube video by Shawn Hymel](https://www.youtube.com/watch?v=crJcDqIUbP4),\nrun both via TFL and STM32CubeAI. The device used was a STM32L4 at 80MHz.\nThere the TFL version took 104us, while the STM32CubeAI one took 74us.\n\nThe STM32L4 used by Hymel is a low-power version of the STM32F4, so the L4 \ncertainly should not be faster than the F4. Same versions of CubeAI were used.\nThe only difference was that Hymel fed the TFL model to CubeAI, not the ONNX model\nas in the above measurement. I am not sure if this is relevant, but so far\nit is the only think I can think of that could explain the difference.\nAlso the measured ONNX model was not converted from the TFL model that Hymel used,\nbut re-trained using the tutorial. But this most likely is not the cause for the\nexecution speed difference.\n\nMore datapoints are definitely needed...\n\n### Notes\n\nThe above values are made with an older version of onnx2c. Later versions\nhave added a \"mark constant tensors as 'const'\" optimisation, that significantly\nreduces RAM usage, but has a small performance penalty (4us in the above case).\n\nThis is because when marked const, GCC generates code that reads the 'const' vectors\nfrom flash (as opposed to copying them to RAM). Reading flash is, of course,\nslower than RAM.\n\nDisabling of this optimisation should be added as a command-line option to onnx2c.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkraiskil%2Fonnx2c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkraiskil%2Fonnx2c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkraiskil%2Fonnx2c/lists"}