From ece371ceab45f01bcc3ed73f23ace9aeda37d481 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sat, 24 Oct 2026 03:45:32 +0900 Subject: [PATCH 01/11] feat: checkpoint ONNX Runtime modules, inference, and project template --- .../2026-10-24-implementation-checkpoints.md | 13 + .gitignore | 7 + .xlings.json | 1 + LICENSE | 21 + README.md | 61 +++ mcpp.toml | 26 ++ port/include/mwrap/onnxruntime/macros.hpp | 3 + src/exports.inc | 389 +++++++++++++++++ src/macros.cppm | 12 + src/onnxruntime.cppm | 7 + templates/inference/mcpp.toml.in | 10 + templates/inference/src/main.cpp.in | 21 + templates/inference/src/model.hpp | 2 + templates/inference/template.toml | 4 + tests/fixtures/identity.onnx | 11 + tests/fixtures/model.hpp | 2 + tests/headers_mix.cpp | 10 + tests/inference.cpp | 25 ++ tools/generate_exports.py | 73 ++++ tools/generate_model.py | 42 ++ tools/test_template.py | 54 +++ upstream/api-surface.json | 391 ++++++++++++++++++ upstream/sources.lock.toml | 18 + 23 files changed, 1203 insertions(+) create mode 100644 .agents/docs/2026-10-24-implementation-checkpoints.md create mode 100644 .gitignore create mode 100644 .xlings.json create mode 100644 LICENSE create mode 100644 README.md create mode 100644 mcpp.toml create mode 100644 port/include/mwrap/onnxruntime/macros.hpp create mode 100644 src/exports.inc create mode 100644 src/macros.cppm create mode 100644 src/onnxruntime.cppm create mode 100644 templates/inference/mcpp.toml.in create mode 100644 templates/inference/src/main.cpp.in create mode 100644 templates/inference/src/model.hpp create mode 100644 templates/inference/template.toml create mode 100644 tests/fixtures/identity.onnx create mode 100644 tests/fixtures/model.hpp create mode 100644 tests/headers_mix.cpp create mode 100644 tests/inference.cpp create mode 100644 tools/generate_exports.py create mode 100644 tools/generate_model.py create mode 100644 tools/test_template.py create mode 100644 upstream/api-surface.json create mode 100644 upstream/sources.lock.toml diff --git a/.agents/docs/2026-10-24-implementation-checkpoints.md b/.agents/docs/2026-10-24-implementation-checkpoints.md new file mode 100644 index 0000000..d20ed89 --- /dev/null +++ b/.agents/docs/2026-10-24-implementation-checkpoints.md @@ -0,0 +1,13 @@ +# ONNX Runtime mwrap implementation checkpoints + +## CPU interface checkpoint + +- Upstream official SDK: 1.25.1, hashes recorded in upstream/sources.lock.toml. +- Exports: 277 C declarations/enumerators and 107 public Ort declarations from Clang AST. +- LLVM 23.1.3: module inference and header coexistence, 2 passed. +- GCC 16.1.0: module inference and header coexistence, 2 passed. +- Actual mcpp new/list-templates followed by generated project build/run passed. +- Linux SDK runtime closure requires declared gcc-runtime; GCC consumers use toolchain-coupled C++ runtime. +- Provider candidate: mcpp-index-mwrap/pkgs/c/compat.onnxruntime.lua. +- Pending: C API/header inventory completion, isolated deployment, Windows/macOS CI, release/index consumption, remote PR. +- Remote organization creation currently refused for GitHub identity speak-agent (403); local implementation continues. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..04a7321 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +target/ +.mcpp/ +.xlings/ +mcpp.lock +compile_commands.json +__pycache__/ +*.pyc diff --git a/.xlings.json b/.xlings.json new file mode 100644 index 0000000..8475678 --- /dev/null +++ b/.xlings.json @@ -0,0 +1 @@ +{"workspace":{"xim:mcpp":"2026.10.21.1"}} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..48bc6bb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..dea89da --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# onnxruntime-m + +ONNX Runtime **1.25.1** C and C++ APIs through `mcpplibs.mwrap` modules. +Upstream names remain unchanged: `Ort::Env`, `Ort::Session`, `Ort::Value`, and +the C API retain their original namespaces and types. + +```toml +[dependencies."mcpplibs.mwrap"] +onnxruntime = "1.25.1" + +[target.x86_64-linux-gnu] +cxx_runtime = "toolchain-coupled" +``` + +```cpp +import mcpplibs.mwrap.onnxruntime; +Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example"); +``` + +The Linux official SDK itself loads libstdc++. GCC applications should use the +toolchain-coupled C++ runtime shown above to share one implementation. The SDK +provider supplies its declared runtime closure; no host library search is used. + +The package depends on `compat.onnxruntime`, which supplies the matching official +CPU SDK. Initial targets are Linux x86_64 with glibc, Windows x86_64 with the MSVC +ABI, and macOS arm64. GPU execution providers, musl and MinGW require separate +SDK builds and are not supplied by this version. + +## Quickstart template + +```sh +mcpp new inference --template mcpplibs.mwrap.onnxruntime@1.25.1 +cd inference +mcpp run +``` + +The template contains a reproducible ONNX Identity model and verifies real CPU +inference. It needs no external model download or device. + +`import mcpplibs.mwrap.onnxruntime.macros;` exposes the API version as +`mcpplibs::mwrap::onnxruntime::macros::ORT_API_VERSION`. Original preprocessing +macros, including `ORT_TSTR`, remain available through +`#include ` **before** imports. A preprocessing macro +still expands inside a qualified identifier; use the mapping and raw-macro forms +in separate contexts. + +## Development + +Use mcpp 2026.10.21.1 or newer. Tests exercise module-only inference, output shape +and values, and header/module coexistence. `tools/generate_model.py` regenerates +the checked-in model, and `tools/generate_exports.py ` +regenerates exports from Clang's declaration AST. SDK source pins and the public +declaration inventory live under `upstream/`. + +For an unpublished provider, use a local `compat` index during development, then +run `mcpp test --toolchain llvm@23.1.3` and `mcpp test --toolchain gcc@16.1.0`. +`python3 tools/test_template.py --index /path/to/mcpp-index` runs the actual mcpp +template renderer and builds/runs the generated project against the candidate. + +The wrapper is MIT licensed. The SDK is distributed separately with Microsoft's +MIT license and its `ThirdPartyNotices.txt`. diff --git a/mcpp.toml b/mcpp.toml new file mode 100644 index 0000000..1345ac1 --- /dev/null +++ b/mcpp.toml @@ -0,0 +1,26 @@ +[package] +namespace = "mcpplibs.mwrap" +name = "onnxruntime" +version = "1.25.1" +description = "ONNX Runtime 1.25.1 C/C++ APIs as C++ modules, with upstream names preserved" +license = "MIT" +repo = "https://github.com/mcpplibs/onnxruntime-m" + +[package.metadata.mwrap] +upstream-version = "1.25.1" +upstream-repo = "https://github.com/microsoft/onnxruntime" + +[build] +sources = ["src/onnxruntime.cppm", "src/macros.cppm"] +include_dirs = ["port/include"] + +[dependencies.compat] +onnxruntime = "1.25.1" + +[targets.onnxruntime] +kind = "lib" + +# The Linux SDK is a shared library that itself needs libstdc++. A GCC +# executable must share that runtime rather than embed a second copy. +[target.x86_64-linux-gnu] +cxx_runtime = "toolchain-coupled" diff --git a/port/include/mwrap/onnxruntime/macros.hpp b/port/include/mwrap/onnxruntime/macros.hpp new file mode 100644 index 0000000..37902ef --- /dev/null +++ b/port/include/mwrap/onnxruntime/macros.hpp @@ -0,0 +1,3 @@ +#pragma once +// Include before imports when preprocessing macros such as ORT_TSTR are needed. +#include diff --git a/src/exports.inc b/src/exports.inc new file mode 100644 index 0000000..e7c8a1d --- /dev/null +++ b/src/exports.inc @@ -0,0 +1,389 @@ +// Generated from the official 1.25.1 public API AST. +export { +using ::ExecutionMode; +using ::GraphOptimizationLevel; +using ::INPUT_OUTPUT_OPTIONAL; +using ::INPUT_OUTPUT_REQUIRED; +using ::INPUT_OUTPUT_VARIADIC; +using ::ONNXTensorElementDataType; +using ::ONNXType; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_BFLOAT16; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_BOOL; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX128; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX64; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_DOUBLE; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT4E2M1; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT8E4M3FN; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT8E4M3FNUZ; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT8E5M2; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT8E5M2FNUZ; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_INT2; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_INT4; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_STRING; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT2; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT4; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8; +using ::ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED; +using ::ONNX_TYPE_MAP; +using ::ONNX_TYPE_OPAQUE; +using ::ONNX_TYPE_OPTIONAL; +using ::ONNX_TYPE_SEQUENCE; +using ::ONNX_TYPE_SPARSETENSOR; +using ::ONNX_TYPE_TENSOR; +using ::ONNX_TYPE_UNKNOWN; +using ::ORT_DISABLE_ALL; +using ::ORT_ENABLE_ALL; +using ::ORT_ENABLE_BASIC; +using ::ORT_ENABLE_EXTENDED; +using ::ORT_ENABLE_LAYOUT; +using ::ORT_ENGINE_ERROR; +using ::ORT_EP_FAIL; +using ::ORT_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP; +using ::ORT_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE; +using ::ORT_EXTERNAL_SEMAPHORE_D3D12_FENCE; +using ::ORT_FAIL; +using ::ORT_GRAPHICS_API_D3D12; +using ::ORT_GRAPHICS_API_NONE; +using ::ORT_GRAPHICS_API_VULKAN; +using ::ORT_INVALID_ARGUMENT; +using ::ORT_INVALID_GRAPH; +using ::ORT_INVALID_PROTOBUF; +using ::ORT_LOGGING_LEVEL_ERROR; +using ::ORT_LOGGING_LEVEL_FATAL; +using ::ORT_LOGGING_LEVEL_INFO; +using ::ORT_LOGGING_LEVEL_VERBOSE; +using ::ORT_LOGGING_LEVEL_WARNING; +using ::ORT_MODEL_LOADED; +using ::ORT_MODEL_LOAD_CANCELED; +using ::ORT_MODEL_REQUIRES_COMPILATION; +using ::ORT_NOT_FOUND; +using ::ORT_NOT_IMPLEMENTED; +using ::ORT_NO_MODEL; +using ::ORT_NO_SUCHFILE; +using ::ORT_OK; +using ::ORT_OP_ATTR_FLOAT; +using ::ORT_OP_ATTR_FLOATS; +using ::ORT_OP_ATTR_GRAPH; +using ::ORT_OP_ATTR_INT; +using ::ORT_OP_ATTR_INTS; +using ::ORT_OP_ATTR_STRING; +using ::ORT_OP_ATTR_STRINGS; +using ::ORT_OP_ATTR_TENSOR; +using ::ORT_OP_ATTR_UNDEFINED; +using ::ORT_PARALLEL; +using ::ORT_PROJECTION_C; +using ::ORT_PROJECTION_CPLUSPLUS; +using ::ORT_PROJECTION_CSHARP; +using ::ORT_PROJECTION_JAVA; +using ::ORT_PROJECTION_NODEJS; +using ::ORT_PROJECTION_PYTHON; +using ::ORT_PROJECTION_WINML; +using ::ORT_RUNTIME_EXCEPTION; +using ::ORT_SEQUENTIAL; +using ::ORT_SPARSE_BLOCK_SPARSE; +using ::ORT_SPARSE_BLOCK_SPARSE_INDICES; +using ::ORT_SPARSE_COO; +using ::ORT_SPARSE_COO_INDICES; +using ::ORT_SPARSE_CSRC; +using ::ORT_SPARSE_CSR_INNER_INDICES; +using ::ORT_SPARSE_CSR_OUTER_INDICES; +using ::ORT_SPARSE_UNDEFINED; +using ::OrtAllocator; +using ::OrtAllocatorType; +using ::OrtApi; +using ::OrtApiBase; +using ::OrtArenaAllocator; +using ::OrtArenaCfg; +using ::OrtCANNProviderOptions; +using ::OrtCUDAProviderOptions; +using ::OrtCUDAProviderOptionsV2; +using ::OrtCompileApi; +using ::OrtCompileApiFlags; +using ::OrtCompileApiFlags_ERROR_IF_NO_NODES_COMPILED; +using ::OrtCompileApiFlags_ERROR_IF_OUTPUT_FILE_EXISTS; +using ::OrtCompileApiFlags_NONE; +using ::OrtCompiledModelCompatibility; +using ::OrtCompiledModelCompatibility_EP_NOT_APPLICABLE; +using ::OrtCompiledModelCompatibility_EP_SUPPORTED_OPTIMAL; +using ::OrtCompiledModelCompatibility_EP_SUPPORTED_PREFER_RECOMPILATION; +using ::OrtCompiledModelCompatibility_EP_UNSUPPORTED; +using ::OrtCudnnConvAlgoSearch; +using ::OrtCudnnConvAlgoSearchDefault; +using ::OrtCudnnConvAlgoSearchExhaustive; +using ::OrtCudnnConvAlgoSearchHeuristic; +using ::OrtCustomCreateThreadFn; +using ::OrtCustomHandleType; +using ::OrtCustomJoinThreadFn; +using ::OrtCustomOp; +using ::OrtCustomOpDomain; +using ::OrtCustomOpInputOutputCharacteristic; +using ::OrtCustomThreadHandle; +using ::OrtDataTransferImpl; +using ::OrtDataType; +using ::OrtDeviceAllocator; +using ::OrtDeviceEpIncompatibilityDetails; +using ::OrtDeviceEpIncompatibilityReason; +using ::OrtDeviceEpIncompatibility_DEVICE_INCOMPATIBLE; +using ::OrtDeviceEpIncompatibility_DRIVER_INCOMPATIBLE; +using ::OrtDeviceEpIncompatibility_MISSING_DEPENDENCY; +using ::OrtDeviceEpIncompatibility_NONE; +using ::OrtDeviceEpIncompatibility_UNKNOWN; +using ::OrtDeviceMemoryType; +using ::OrtDeviceMemoryType_DEFAULT; +using ::OrtDeviceMemoryType_HOST_ACCESSIBLE; +using ::OrtDnnlProviderOptions; +using ::OrtEnv; +using ::OrtEnvCreationOptions; +using ::OrtEp; +using ::OrtEpApi; +using ::OrtEpAssignedNode; +using ::OrtEpAssignedSubgraph; +using ::OrtEpDataLayout; +using ::OrtEpDataLayout_Default; +using ::OrtEpDataLayout_NCHW; +using ::OrtEpDataLayout_NHWC; +using ::OrtEpDevice; +using ::OrtEpFactory; +using ::OrtEpGraphSupportInfo; +using ::OrtEpProfilerImpl; +using ::OrtErrorCode; +using ::OrtExecutionProviderDevicePolicy; +using ::OrtExecutionProviderDevicePolicy_DEFAULT; +using ::OrtExecutionProviderDevicePolicy_MAX_EFFICIENCY; +using ::OrtExecutionProviderDevicePolicy_MAX_PERFORMANCE; +using ::OrtExecutionProviderDevicePolicy_MIN_OVERALL_POWER; +using ::OrtExecutionProviderDevicePolicy_PREFER_CPU; +using ::OrtExecutionProviderDevicePolicy_PREFER_GPU; +using ::OrtExecutionProviderDevicePolicy_PREFER_NPU; +using ::OrtExternalInitializerInfo; +using ::OrtExternalMemoryDescriptor; +using ::OrtExternalMemoryHandle; +using ::OrtExternalMemoryHandleType; +using ::OrtExternalResourceImporter; +using ::OrtExternalResourceImporterImpl; +using ::OrtExternalSemaphoreDescriptor; +using ::OrtExternalSemaphoreHandle; +using ::OrtExternalSemaphoreType; +using ::OrtExternalTensorDescriptor; +using ::OrtGetApiBase; +using ::OrtGetInitializerLocationFunc; +using ::OrtGraph; +using ::OrtGraphicsApi; +using ::OrtGraphicsInteropConfig; +using ::OrtHardwareDevice; +using ::OrtHardwareDeviceType; +using ::OrtHardwareDeviceType_CPU; +using ::OrtHardwareDeviceType_GPU; +using ::OrtHardwareDeviceType_NPU; +using ::OrtInteropApi; +using ::OrtInvalidAllocator; +using ::OrtIoBinding; +using ::OrtKernelContext; +using ::OrtKernelCreateFunc; +using ::OrtKernelDef; +using ::OrtKernelDefBuilder; +using ::OrtKernelImpl; +using ::OrtKernelInfo; +using ::OrtKernelRegistry; +using ::OrtKeyValuePairs; +using ::OrtLanguageProjection; +using ::OrtLogger; +using ::OrtLoggingFunction; +using ::OrtLoggingLevel; +using ::OrtLoopKernelHelper; +using ::OrtLoraAdapter; +using ::OrtMIGraphXProviderOptions; +using ::OrtMapTypeInfo; +using ::OrtMemType; +using ::OrtMemTypeCPU; +using ::OrtMemTypeCPUInput; +using ::OrtMemTypeCPUOutput; +using ::OrtMemTypeDefault; +using ::OrtMemoryDevice; +using ::OrtMemoryInfo; +using ::OrtMemoryInfoDeviceType; +using ::OrtMemoryInfoDeviceType_CPU; +using ::OrtMemoryInfoDeviceType_FPGA; +using ::OrtMemoryInfoDeviceType_GPU; +using ::OrtMemoryInfoDeviceType_NPU; +using ::OrtModel; +using ::OrtModelCompilationOptions; +using ::OrtModelEditorApi; +using ::OrtModelMetadata; +using ::OrtNode; +using ::OrtNodeComputeContext; +using ::OrtNodeComputeInfo; +using ::OrtNodeFusionOptions; +using ::OrtNvTensorRtRtxProviderOptions; +using ::OrtOp; +using ::OrtOpAttr; +using ::OrtOpAttrType; +using ::OrtOpSchema; +using ::OrtOpSchemaTypeConstraint; +using ::OrtOpenVINOProviderOptions; +using ::OrtOptionalTypeInfo; +using ::OrtPrepackedWeightsContainer; +using ::OrtProfilingEvent; +using ::OrtProfilingEventCategory; +using ::OrtProfilingEventCategory_API; +using ::OrtProfilingEventCategory_KERNEL; +using ::OrtProfilingEventCategory_NODE; +using ::OrtProfilingEventCategory_SESSION; +using ::OrtProfilingEventsContainer; +using ::OrtROCMProviderOptions; +using ::OrtReadOnlyAllocator; +using ::OrtRunOptions; +using ::OrtScanKernelHelper; +using ::OrtSequenceTypeInfo; +using ::OrtSession; +using ::OrtSessionOptions; +using ::OrtSessionOptionsAppendExecutionProvider_CUDA; +using ::OrtSessionOptionsAppendExecutionProvider_Dnnl; +using ::OrtSessionOptionsAppendExecutionProvider_MIGraphX; +using ::OrtSessionOptionsAppendExecutionProvider_ROCM; +using ::OrtSessionOptionsAppendExecutionProvider_Tensorrt; +using ::OrtShapeInferContext; +using ::OrtSharedPrePackedWeightCache; +using ::OrtSparseFormat; +using ::OrtSparseIndicesFormat; +using ::OrtStatus; +using ::OrtStatusPtr; +using ::OrtSyncNotificationImpl; +using ::OrtSyncStream; +using ::OrtSyncStreamImpl; +using ::OrtTensorRTProviderOptions; +using ::OrtTensorRTProviderOptionsV2; +using ::OrtTensorTypeAndShapeInfo; +using ::OrtThreadPoolCallbacksConfig; +using ::OrtThreadPoolParams; +using ::OrtThreadPoolWorkAbandonFn; +using ::OrtThreadPoolWorkEnqueueFn; +using ::OrtThreadPoolWorkStartFn; +using ::OrtThreadPoolWorkStopFn; +using ::OrtThreadWorkerFn; +using ::OrtThreadingOptions; +using ::OrtTrainingApi; +using ::OrtTypeInfo; +using ::OrtValue; +using ::OrtValueInfo; +using ::OrtWriteBufferFunc; +using ::RunAsyncCallbackFn; +} +export namespace Ort { +using ::Ort::AllocatedStringPtr; +using ::Ort::Allocator; +using ::Ort::AllocatorWithDefaultOptions; +using ::Ort::ArenaCfg; +using ::Ort::AttrNameSubgraph; +using ::Ort::BFloat16_t; +using ::Ort::CUDAProviderOptions; +using ::Ort::CompileModel; +using ::Ort::ConstEpAssignedNode; +using ::Ort::ConstEpAssignedSubgraph; +using ::Ort::ConstEpDevice; +using ::Ort::ConstExternalInitializerInfo; +using ::Ort::ConstGraph; +using ::Ort::ConstHardwareDevice; +using ::Ort::ConstIoBinding; +using ::Ort::ConstKernelDef; +using ::Ort::ConstKernelInfo; +using ::Ort::ConstKeyValuePairs; +using ::Ort::ConstMapTypeInfo; +using ::Ort::ConstMemoryInfo; +using ::Ort::ConstNode; +using ::Ort::ConstOpAttr; +using ::Ort::ConstOpSchemaTypeConstraint; +using ::Ort::ConstOptionalTypeInfo; +using ::Ort::ConstProfilingEvent; +using ::Ort::ConstSequenceTypeInfo; +using ::Ort::ConstSession; +using ::Ort::ConstSessionOptions; +using ::Ort::ConstTensorTypeAndShapeInfo; +using ::Ort::ConstTypeInfo; +using ::Ort::ConstValue; +using ::Ort::ConstValueInfo; +using ::Ort::CustomOpBase; +using ::Ort::CustomOpConfigs; +using ::Ort::CustomOpDomain; +using ::Ort::Env; +using ::Ort::EpDevice; +using ::Ort::Exception; +using ::Ort::ExternalInitializerInfo; +using ::Ort::FinalizeModelEditorSession; +using ::Ort::Float16_t; +using ::Ort::Float8E4M3FNUZ_t; +using ::Ort::Float8E4M3FN_t; +using ::Ort::Float8E5M2FNUZ_t; +using ::Ort::Float8E5M2_t; +using ::Ort::GetApi; +using ::Ort::GetAvailableProviders; +using ::Ort::GetBuildInfoString; +using ::Ort::GetCompatibilityInfoFromModelAllocated; +using ::Ort::GetCompatibilityInfoFromModelBytesAllocated; +using ::Ort::GetCompileApi; +using ::Ort::GetEnvConfigEntries; +using ::Ort::GetEpApi; +using ::Ort::GetInteropApi; +using ::Ort::GetModelCompatibilityForEpDevices; +using ::Ort::GetModelEditorApi; +using ::Ort::GetOpSchema; +using ::Ort::GetVersionString; +using ::Ort::Graph; +using ::Ort::IoBinding; +using ::Ort::KernelContext; +using ::Ort::KernelDef; +using ::Ort::KernelDefBuilder; +using ::Ort::KernelInfo; +using ::Ort::KernelRegistry; +using ::Ort::KeyValuePairs; +using ::Ort::Logger; +using ::Ort::LoraAdapter; +using ::Ort::MapTypeInfo; +using ::Ort::MemoryAllocation; +using ::Ort::MemoryInfo; +using ::Ort::Model; +using ::Ort::ModelCompilationOptions; +using ::Ort::ModelMetadata; +using ::Ort::Node; +using ::Ort::Op; +using ::Ort::OpAttr; +using ::Ort::OpSchema; +using ::Ort::OperatorSet; +using ::Ort::PrepackedWeightsContainer; +using ::Ort::ProfilingEvent; +using ::Ort::RunOptions; +using ::Ort::SequenceTypeInfo; +using ::Ort::Session; +using ::Ort::SessionOptions; +using ::Ort::ShapeInferContext; +using ::Ort::ShapeInferFn; +using ::Ort::Status; +using ::Ort::SyncStream; +using ::Ort::TensorRTProviderOptions; +using ::Ort::TensorTypeAndShapeInfo; +using ::Ort::ThreadingOptions; +using ::Ort::ThrowOnError; +using ::Ort::TypeInfo; +using ::Ort::TypeToTensorType; +using ::Ort::UnownedAllocator; +using ::Ort::UnownedIoBinding; +using ::Ort::UnownedModel; +using ::Ort::UnownedProfilingEventsContainer; +using ::Ort::UnownedSession; +using ::Ort::UnownedSessionOptions; +using ::Ort::UnownedSharedPrePackedWeightCache; +using ::Ort::UnownedSyncStream; +using ::Ort::UnownedValue; +using ::Ort::Value; +using ::Ort::ValueInfo; +using ::Ort::ValueInfoConsumerProducerInfo; +} diff --git a/src/macros.cppm b/src/macros.cppm new file mode 100644 index 0000000..3ff56e3 --- /dev/null +++ b/src/macros.cppm @@ -0,0 +1,12 @@ +module; +#include +namespace mwrap_onnxruntime_detail { +inline constexpr unsigned api_version = ORT_API_VERSION; +} +#undef ORT_API_VERSION + +export module mcpplibs.mwrap.onnxruntime.macros; + +export namespace mcpplibs::mwrap::onnxruntime::macros { +inline constexpr unsigned ORT_API_VERSION = mwrap_onnxruntime_detail::api_version; +} diff --git a/src/onnxruntime.cppm b/src/onnxruntime.cppm new file mode 100644 index 0000000..c50978f --- /dev/null +++ b/src/onnxruntime.cppm @@ -0,0 +1,7 @@ +module; +#include + +export module mcpplibs.mwrap.onnxruntime; + +export import mcpplibs.mwrap.onnxruntime.macros; +#include "exports.inc" diff --git a/templates/inference/mcpp.toml.in b/templates/inference/mcpp.toml.in new file mode 100644 index 0000000..bb78a54 --- /dev/null +++ b/templates/inference/mcpp.toml.in @@ -0,0 +1,10 @@ +[package] +name = "{{project.name}}" +version = "0.1.0" +description = "ONNX Runtime CPU inference with C++ modules" + +[dependencies] +"{{self.name}}" = "{{self.version}}" + +[target.x86_64-linux-gnu] +cxx_runtime = "toolchain-coupled" diff --git a/templates/inference/src/main.cpp.in b/templates/inference/src/main.cpp.in new file mode 100644 index 0000000..50a4c47 --- /dev/null +++ b/templates/inference/src/main.cpp.in @@ -0,0 +1,21 @@ +#include "model.hpp" +import std; +import mcpplibs.mwrap.onnxruntime; + +int main() { + Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "{{project.name}}"); + Ort::SessionOptions options; + options.SetIntraOpNumThreads(1); + Ort::Session session(env, identity_model, sizeof(identity_model), options); + std::array input{1.0f, 2.0f, 3.0f}; + std::array shape{3}; + auto memory = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); + auto tensor = Ort::Value::CreateTensor(memory, input.data(), input.size(), shape.data(), shape.size()); + const char* inputs[]{"x"}; + const char* outputs[]{"y"}; + auto result = session.Run(Ort::RunOptions{nullptr}, inputs, &tensor, 1, outputs, 1); + const auto* values = result.at(0).GetTensorData(); + for (std::size_t i = 0; i < input.size(); ++i) + if (values[i] != input[i]) return 1; + std::println("ONNX Runtime {}: Identity inference passed", Ort::GetVersionString()); +} diff --git a/templates/inference/src/model.hpp b/templates/inference/src/model.hpp new file mode 100644 index 0000000..e793294 --- /dev/null +++ b/templates/inference/src/model.hpp @@ -0,0 +1,2 @@ +#pragma once +inline constexpr unsigned char identity_model[] = {0x08, 0x08, 0x12, 0x0d, 0x6d, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x66, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3a, 0x44, 0x0a, 0x10, 0x0a, 0x01, 0x78, 0x12, 0x01, 0x79, 0x22, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x6d, 0x77, 0x72, 0x61, 0x70, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5a, 0x0f, 0x0a, 0x01, 0x78, 0x12, 0x0a, 0x0a, 0x08, 0x08, 0x01, 0x12, 0x04, 0x0a, 0x02, 0x08, 0x03, 0x62, 0x0f, 0x0a, 0x01, 0x79, 0x12, 0x0a, 0x0a, 0x08, 0x08, 0x01, 0x12, 0x04, 0x0a, 0x02, 0x08, 0x03, 0x42, 0x02, 0x10, 0x0d}; diff --git a/templates/inference/template.toml b/templates/inference/template.toml new file mode 100644 index 0000000..37d998b --- /dev/null +++ b/templates/inference/template.toml @@ -0,0 +1,4 @@ +[template] +description = "Run an embedded ONNX identity model with the upstream Ort C++ API" +default = true +post_message = "Run `mcpp run` to execute the embedded model on the CPU." diff --git a/tests/fixtures/identity.onnx b/tests/fixtures/identity.onnx new file mode 100644 index 0000000..1c845e4 --- /dev/null +++ b/tests/fixtures/identity.onnx @@ -0,0 +1,11 @@ + mwrap-fixture:D + +xy"Identitymwrap_identityZ +x + + +b +y + + +B \ No newline at end of file diff --git a/tests/fixtures/model.hpp b/tests/fixtures/model.hpp new file mode 100644 index 0000000..e793294 --- /dev/null +++ b/tests/fixtures/model.hpp @@ -0,0 +1,2 @@ +#pragma once +inline constexpr unsigned char identity_model[] = {0x08, 0x08, 0x12, 0x0d, 0x6d, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x66, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3a, 0x44, 0x0a, 0x10, 0x0a, 0x01, 0x78, 0x12, 0x01, 0x79, 0x22, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x6d, 0x77, 0x72, 0x61, 0x70, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5a, 0x0f, 0x0a, 0x01, 0x78, 0x12, 0x0a, 0x0a, 0x08, 0x08, 0x01, 0x12, 0x04, 0x0a, 0x02, 0x08, 0x03, 0x62, 0x0f, 0x0a, 0x01, 0x79, 0x12, 0x0a, 0x0a, 0x08, 0x08, 0x01, 0x12, 0x04, 0x0a, 0x02, 0x08, 0x03, 0x42, 0x02, 0x10, 0x0d}; diff --git a/tests/headers_mix.cpp b/tests/headers_mix.cpp new file mode 100644 index 0000000..e7f5689 --- /dev/null +++ b/tests/headers_mix.cpp @@ -0,0 +1,10 @@ +#include +import std; +import mcpplibs.mwrap.onnxruntime; + +static_assert(std::is_same_v); +static_assert(ORT_API_VERSION == 25); +int main() { + Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "header-module-mix"); + return OrtGetApiBase() && OrtGetApiBase()->GetApi(ORT_API_VERSION) ? 0 : 1; +} diff --git a/tests/inference.cpp b/tests/inference.cpp new file mode 100644 index 0000000..0764926 --- /dev/null +++ b/tests/inference.cpp @@ -0,0 +1,25 @@ +#include "fixtures/model.hpp" +import std; +import mcpplibs.mwrap.onnxruntime; + +int main() { + if (Ort::GetVersionString() != "1.25.1") return 1; + static_assert(mcpplibs::mwrap::onnxruntime::macros::ORT_API_VERSION == 25); + Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "mwrap-inference"); + Ort::SessionOptions options; + options.SetIntraOpNumThreads(1); + Ort::Session session(env, identity_model, sizeof(identity_model), options); + const char* names[]{"x"}; + const char* outputs[]{"y"}; + std::array input{0.5f, -4.0f, 8.0f}; + std::array shape{3}; + auto memory = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); + auto value = Ort::Value::CreateTensor(memory, input.data(), input.size(), shape.data(), shape.size()); + auto result = session.Run(Ort::RunOptions{nullptr}, names, &value, 1, outputs, 1); + if (result.size() != 1 || !result[0].IsTensor()) return 2; + auto dimensions = result[0].GetTensorTypeAndShapeInfo().GetShape(); + if (dimensions != std::vector{3}) return 3; + const float* actual = result[0].GetTensorData(); + for (std::size_t i = 0; i < input.size(); ++i) + if (actual[i] != input[i]) return 4; +} diff --git a/tools/generate_exports.py b/tools/generate_exports.py new file mode 100644 index 0000000..33c36c8 --- /dev/null +++ b/tools/generate_exports.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +"""Generate export-using declarations from Clang's public SDK declaration AST.""" +import argparse +import json +from pathlib import Path +import subprocess +import tempfile + + +def generate(ast): + declarations = ast.get("inner", []) + namespace_ids = {n["id"] for n in declarations + if n.get("kind") == "NamespaceDecl" and n.get("name") == "Ort"} + kinds = {"CXXRecordDecl", "RecordDecl", "ClassTemplateDecl", "FunctionTemplateDecl", + "FunctionDecl", "TypeAliasDecl", "TypeAliasTemplateDecl", "EnumDecl", "VarDecl"} + cpp, capi = set(), set() + for namespace in declarations: + if namespace.get("id") not in namespace_ids: + continue + for node in namespace.get("inner", []): + name = node.get("name", "") + if node.get("kind") not in kinds or not name.isidentifier() or node.get("isImplicit"): + continue + # Clang also places out-of-line qualified definitions here. Their + # semantic owner is a class/detail namespace, not the public Ort scope. + owner = node.get("parentDeclContextId") + if owner and owner not in namespace_ids: + continue + if node.get("kind") == "FunctionTemplateDecl" and any( + x.get("kind") == "CXXMethodDecl" for x in node.get("inner", [])): + continue + cpp.add(name) + + def collect_c(nodes): + for node in nodes: + if node.get("kind") == "LinkageSpecDecl": + collect_c(node.get("inner", [])) + continue + name = node.get("name", "") + public_name = name.startswith(("Ort", "ONNX")) or name in { + "GraphOptimizationLevel", "ExecutionMode", "ExecutionOrder", "RunAsyncCallbackFn"} + if public_name and node.get("kind") in kinds | {"TypedefDecl"}: + capi.add(name) + if node.get("kind") == "EnumDecl": + capi.update(x["name"] for x in node.get("inner", []) + if x.get("kind") == "EnumConstantDecl") + collect_c(declarations) + return sorted(capi), sorted(cpp) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("sdk_include", type=Path) + parser.add_argument("--clang", default="clang++") + args = parser.parse_args() + root = Path(__file__).resolve().parents[1] + with tempfile.TemporaryDirectory(prefix="mwrap-ort-exports-") as temporary: + directory = Path(temporary) + probe = directory / "probe.cpp" + probe.write_text("#include \n") + with (directory / "ast.json").open("w") as out: + subprocess.run([args.clang, "-std=c++23", "-I", str(args.sdk_include), + "-Xclang", "-ast-dump=json", "-fsyntax-only", str(probe)], + stdout=out, check=True) + with (directory / "ast.json").open() as source: + capi, cpp = generate(json.load(source)) + text = "// Generated from the official 1.25.1 public API AST.\nexport {\n" + text += "".join(f"using ::{name};\n" for name in capi) + "}\nexport namespace Ort {\n" + text += "".join(f"using ::Ort::{name};\n" for name in cpp) + "}\n" + (root / "src/exports.inc").write_text(text) + (root / "upstream/api-surface.json").write_text(json.dumps( + {"version": "1.25.1", "c": capi, "cpp": cpp}, indent=2) + "\n") + print(f"Exported {len(capi)} C declarations/enumerators and {len(cpp)} Ort declarations") diff --git a/tools/generate_model.py b/tools/generate_model.py new file mode 100644 index 0000000..45e001f --- /dev/null +++ b/tools/generate_model.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Write a small ONNX Identity model without requiring Python ONNX packages.""" +from pathlib import Path + + +def varint(value): + out = bytearray() + while value > 127: + out.append((value & 127) | 128) + value >>= 7 + out.append(value) + return bytes(out) + + +def field(number, value): + if isinstance(value, int): + return varint(number << 3) + varint(value) + if isinstance(value, str): + value = value.encode() + return varint((number << 3) | 2) + varint(len(value)) + value + + +def identity_model(): + shape = field(1, field(1, 3)) + tensor_type = field(1, 1) + field(2, shape) + def value_info(name): + return field(1, name) + field(2, field(1, tensor_type)) + node = field(1, "x") + field(2, "y") + field(4, "Identity") + graph = field(1, node) + field(2, "mwrap_identity") + graph += field(11, value_info("x")) + field(12, value_info("y")) + return field(1, 8) + field(2, "mwrap-fixture") + field(7, graph) + field(8, field(2, 13)) + + +if __name__ == "__main__": + root = Path(__file__).resolve().parents[1] + model = identity_model() + (root / "tests/fixtures/identity.onnx").write_bytes(model) + initializer = ", ".join(f"0x{x:02x}" for x in model) + (root / "templates/inference/src/model.hpp").write_text( + "#pragma once\ninline constexpr unsigned char identity_model[] = {" + initializer + "};\n") + (root / "tests/fixtures/model.hpp").write_text( + "#pragma once\ninline constexpr unsigned char identity_model[] = {" + initializer + "};\n") diff --git a/tools/test_template.py b/tools/test_template.py new file mode 100644 index 0000000..67b3a0c --- /dev/null +++ b/tools/test_template.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +"""Render the shipped default template with mcpp, then build and run it.""" +import argparse +import os +from pathlib import Path +import shutil +import subprocess +import tempfile +import tomllib + + +def run(command, cwd, env=None): + print("+", " ".join(map(str, command)), flush=True) + subprocess.run(command, cwd=cwd, env=env, check=True) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--index", type=Path, help="Candidate mcpp-index containing compat.onnxruntime") + parser.add_argument("--mcpp", default="mcpp") + parser.add_argument("--toolchain", default="llvm@23.1.3") + args = parser.parse_args() + root = Path(__file__).resolve().parents[1] + with tempfile.TemporaryDirectory(prefix="mwrap-ort-template-") as directory: + temporary = Path(directory) + home = temporary / "home" + package = home / "registry/data/xpkgs/mcpplibs.mwrap-x-onnxruntime/1.25.1/onnxruntime-1.25.1" + shutil.copytree(root, package, ignore=shutil.ignore_patterns(".git", "target", ".mcpp", "__pycache__")) + index = home / "indices/mcpplibs/pkgs/mwrap" + index.mkdir(parents=True) + (index / "mcpplibs.mwrap.onnxruntime.lua").write_text('''package = { +spec="1", namespace="mcpplibs.mwrap", name="onnxruntime", +description="Local installed-package template fixture", type="package", +xpm={linux={["1.25.1"]={url="https://example.invalid/ort.tar.gz",sha256="fixture"}}, +macosx={["1.25.1"]={url="https://example.invalid/ort.tar.gz",sha256="fixture"}}, +windows={["1.25.1"]={url="https://example.invalid/ort.zip",sha256="fixture"}}}, +mcpp="mcpp.toml"} +''') + env = dict(os.environ, MCPP_HOME=str(home)) + run([args.mcpp, "new", "--list-templates", "mcpplibs.mwrap.onnxruntime@1.25.1"], temporary, env) + run([args.mcpp, "new", "inference-app", "--template", "mcpplibs.mwrap.onnxruntime@1.25.1"], temporary, env) + project = temporary / "inference-app" + manifest = project / "mcpp.toml" + parsed = tomllib.loads(manifest.read_text()) + dependency = parsed["dependencies"]["mcpplibs.mwrap.onnxruntime"] + assert dependency == "1.25.1" or dependency.get("version") == "1.25.1", dependency + # Keep the rendered dependency's identity/version check above. For an + # unpublished candidate, build that exact staged source via a local edge. + text = manifest.read_text().replace('"mcpplibs.mwrap.onnxruntime" = "1.25.1"', + '"mcpplibs.mwrap.onnxruntime" = { path = "' + package.as_posix() + '" }') + if args.index: + text += '\n[indices]\ncompat = { path = "' + args.index.resolve().as_posix() + '" }\n' + manifest.write_text(text) + run([args.mcpp, "run", "--toolchain", args.toolchain], project) diff --git a/upstream/api-surface.json b/upstream/api-surface.json new file mode 100644 index 0000000..4355194 --- /dev/null +++ b/upstream/api-surface.json @@ -0,0 +1,391 @@ +{ + "version": "1.25.1", + "c": [ + "ExecutionMode", + "GraphOptimizationLevel", + "INPUT_OUTPUT_OPTIONAL", + "INPUT_OUTPUT_REQUIRED", + "INPUT_OUTPUT_VARIADIC", + "ONNXTensorElementDataType", + "ONNXType", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_BFLOAT16", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_BOOL", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX128", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX64", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_DOUBLE", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT4E2M1", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT8E4M3FN", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT8E4M3FNUZ", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT8E5M2", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT8E5M2FNUZ", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_INT2", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_INT4", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_STRING", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT2", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT4", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8", + "ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED", + "ONNX_TYPE_MAP", + "ONNX_TYPE_OPAQUE", + "ONNX_TYPE_OPTIONAL", + "ONNX_TYPE_SEQUENCE", + "ONNX_TYPE_SPARSETENSOR", + "ONNX_TYPE_TENSOR", + "ONNX_TYPE_UNKNOWN", + "ORT_DISABLE_ALL", + "ORT_ENABLE_ALL", + "ORT_ENABLE_BASIC", + "ORT_ENABLE_EXTENDED", + "ORT_ENABLE_LAYOUT", + "ORT_ENGINE_ERROR", + "ORT_EP_FAIL", + "ORT_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP", + "ORT_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE", + "ORT_EXTERNAL_SEMAPHORE_D3D12_FENCE", + "ORT_FAIL", + "ORT_GRAPHICS_API_D3D12", + "ORT_GRAPHICS_API_NONE", + "ORT_GRAPHICS_API_VULKAN", + "ORT_INVALID_ARGUMENT", + "ORT_INVALID_GRAPH", + "ORT_INVALID_PROTOBUF", + "ORT_LOGGING_LEVEL_ERROR", + "ORT_LOGGING_LEVEL_FATAL", + "ORT_LOGGING_LEVEL_INFO", + "ORT_LOGGING_LEVEL_VERBOSE", + "ORT_LOGGING_LEVEL_WARNING", + "ORT_MODEL_LOADED", + "ORT_MODEL_LOAD_CANCELED", + "ORT_MODEL_REQUIRES_COMPILATION", + "ORT_NOT_FOUND", + "ORT_NOT_IMPLEMENTED", + "ORT_NO_MODEL", + "ORT_NO_SUCHFILE", + "ORT_OK", + "ORT_OP_ATTR_FLOAT", + "ORT_OP_ATTR_FLOATS", + "ORT_OP_ATTR_GRAPH", + "ORT_OP_ATTR_INT", + "ORT_OP_ATTR_INTS", + "ORT_OP_ATTR_STRING", + "ORT_OP_ATTR_STRINGS", + "ORT_OP_ATTR_TENSOR", + "ORT_OP_ATTR_UNDEFINED", + "ORT_PARALLEL", + "ORT_PROJECTION_C", + "ORT_PROJECTION_CPLUSPLUS", + "ORT_PROJECTION_CSHARP", + "ORT_PROJECTION_JAVA", + "ORT_PROJECTION_NODEJS", + "ORT_PROJECTION_PYTHON", + "ORT_PROJECTION_WINML", + "ORT_RUNTIME_EXCEPTION", + "ORT_SEQUENTIAL", + "ORT_SPARSE_BLOCK_SPARSE", + "ORT_SPARSE_BLOCK_SPARSE_INDICES", + "ORT_SPARSE_COO", + "ORT_SPARSE_COO_INDICES", + "ORT_SPARSE_CSRC", + "ORT_SPARSE_CSR_INNER_INDICES", + "ORT_SPARSE_CSR_OUTER_INDICES", + "ORT_SPARSE_UNDEFINED", + "OrtAllocator", + "OrtAllocatorType", + "OrtApi", + "OrtApiBase", + "OrtArenaAllocator", + "OrtArenaCfg", + "OrtCANNProviderOptions", + "OrtCUDAProviderOptions", + "OrtCUDAProviderOptionsV2", + "OrtCompileApi", + "OrtCompileApiFlags", + "OrtCompileApiFlags_ERROR_IF_NO_NODES_COMPILED", + "OrtCompileApiFlags_ERROR_IF_OUTPUT_FILE_EXISTS", + "OrtCompileApiFlags_NONE", + "OrtCompiledModelCompatibility", + "OrtCompiledModelCompatibility_EP_NOT_APPLICABLE", + "OrtCompiledModelCompatibility_EP_SUPPORTED_OPTIMAL", + "OrtCompiledModelCompatibility_EP_SUPPORTED_PREFER_RECOMPILATION", + "OrtCompiledModelCompatibility_EP_UNSUPPORTED", + "OrtCudnnConvAlgoSearch", + "OrtCudnnConvAlgoSearchDefault", + "OrtCudnnConvAlgoSearchExhaustive", + "OrtCudnnConvAlgoSearchHeuristic", + "OrtCustomCreateThreadFn", + "OrtCustomHandleType", + "OrtCustomJoinThreadFn", + "OrtCustomOp", + "OrtCustomOpDomain", + "OrtCustomOpInputOutputCharacteristic", + "OrtCustomThreadHandle", + "OrtDataTransferImpl", + "OrtDataType", + "OrtDeviceAllocator", + "OrtDeviceEpIncompatibilityDetails", + "OrtDeviceEpIncompatibilityReason", + "OrtDeviceEpIncompatibility_DEVICE_INCOMPATIBLE", + "OrtDeviceEpIncompatibility_DRIVER_INCOMPATIBLE", + "OrtDeviceEpIncompatibility_MISSING_DEPENDENCY", + "OrtDeviceEpIncompatibility_NONE", + "OrtDeviceEpIncompatibility_UNKNOWN", + "OrtDeviceMemoryType", + "OrtDeviceMemoryType_DEFAULT", + "OrtDeviceMemoryType_HOST_ACCESSIBLE", + "OrtDnnlProviderOptions", + "OrtEnv", + "OrtEnvCreationOptions", + "OrtEp", + "OrtEpApi", + "OrtEpAssignedNode", + "OrtEpAssignedSubgraph", + "OrtEpDataLayout", + "OrtEpDataLayout_Default", + "OrtEpDataLayout_NCHW", + "OrtEpDataLayout_NHWC", + "OrtEpDevice", + "OrtEpFactory", + "OrtEpGraphSupportInfo", + "OrtEpProfilerImpl", + "OrtErrorCode", + "OrtExecutionProviderDevicePolicy", + "OrtExecutionProviderDevicePolicy_DEFAULT", + "OrtExecutionProviderDevicePolicy_MAX_EFFICIENCY", + "OrtExecutionProviderDevicePolicy_MAX_PERFORMANCE", + "OrtExecutionProviderDevicePolicy_MIN_OVERALL_POWER", + "OrtExecutionProviderDevicePolicy_PREFER_CPU", + "OrtExecutionProviderDevicePolicy_PREFER_GPU", + "OrtExecutionProviderDevicePolicy_PREFER_NPU", + "OrtExternalInitializerInfo", + "OrtExternalMemoryDescriptor", + "OrtExternalMemoryHandle", + "OrtExternalMemoryHandleType", + "OrtExternalResourceImporter", + "OrtExternalResourceImporterImpl", + "OrtExternalSemaphoreDescriptor", + "OrtExternalSemaphoreHandle", + "OrtExternalSemaphoreType", + "OrtExternalTensorDescriptor", + "OrtGetApiBase", + "OrtGetInitializerLocationFunc", + "OrtGraph", + "OrtGraphicsApi", + "OrtGraphicsInteropConfig", + "OrtHardwareDevice", + "OrtHardwareDeviceType", + "OrtHardwareDeviceType_CPU", + "OrtHardwareDeviceType_GPU", + "OrtHardwareDeviceType_NPU", + "OrtInteropApi", + "OrtInvalidAllocator", + "OrtIoBinding", + "OrtKernelContext", + "OrtKernelCreateFunc", + "OrtKernelDef", + "OrtKernelDefBuilder", + "OrtKernelImpl", + "OrtKernelInfo", + "OrtKernelRegistry", + "OrtKeyValuePairs", + "OrtLanguageProjection", + "OrtLogger", + "OrtLoggingFunction", + "OrtLoggingLevel", + "OrtLoopKernelHelper", + "OrtLoraAdapter", + "OrtMIGraphXProviderOptions", + "OrtMapTypeInfo", + "OrtMemType", + "OrtMemTypeCPU", + "OrtMemTypeCPUInput", + "OrtMemTypeCPUOutput", + "OrtMemTypeDefault", + "OrtMemoryDevice", + "OrtMemoryInfo", + "OrtMemoryInfoDeviceType", + "OrtMemoryInfoDeviceType_CPU", + "OrtMemoryInfoDeviceType_FPGA", + "OrtMemoryInfoDeviceType_GPU", + "OrtMemoryInfoDeviceType_NPU", + "OrtModel", + "OrtModelCompilationOptions", + "OrtModelEditorApi", + "OrtModelMetadata", + "OrtNode", + "OrtNodeComputeContext", + "OrtNodeComputeInfo", + "OrtNodeFusionOptions", + "OrtNvTensorRtRtxProviderOptions", + "OrtOp", + "OrtOpAttr", + "OrtOpAttrType", + "OrtOpSchema", + "OrtOpSchemaTypeConstraint", + "OrtOpenVINOProviderOptions", + "OrtOptionalTypeInfo", + "OrtPrepackedWeightsContainer", + "OrtProfilingEvent", + "OrtProfilingEventCategory", + "OrtProfilingEventCategory_API", + "OrtProfilingEventCategory_KERNEL", + "OrtProfilingEventCategory_NODE", + "OrtProfilingEventCategory_SESSION", + "OrtProfilingEventsContainer", + "OrtROCMProviderOptions", + "OrtReadOnlyAllocator", + "OrtRunOptions", + "OrtScanKernelHelper", + "OrtSequenceTypeInfo", + "OrtSession", + "OrtSessionOptions", + "OrtSessionOptionsAppendExecutionProvider_CUDA", + "OrtSessionOptionsAppendExecutionProvider_Dnnl", + "OrtSessionOptionsAppendExecutionProvider_MIGraphX", + "OrtSessionOptionsAppendExecutionProvider_ROCM", + "OrtSessionOptionsAppendExecutionProvider_Tensorrt", + "OrtShapeInferContext", + "OrtSharedPrePackedWeightCache", + "OrtSparseFormat", + "OrtSparseIndicesFormat", + "OrtStatus", + "OrtStatusPtr", + "OrtSyncNotificationImpl", + "OrtSyncStream", + "OrtSyncStreamImpl", + "OrtTensorRTProviderOptions", + "OrtTensorRTProviderOptionsV2", + "OrtTensorTypeAndShapeInfo", + "OrtThreadPoolCallbacksConfig", + "OrtThreadPoolParams", + "OrtThreadPoolWorkAbandonFn", + "OrtThreadPoolWorkEnqueueFn", + "OrtThreadPoolWorkStartFn", + "OrtThreadPoolWorkStopFn", + "OrtThreadWorkerFn", + "OrtThreadingOptions", + "OrtTrainingApi", + "OrtTypeInfo", + "OrtValue", + "OrtValueInfo", + "OrtWriteBufferFunc", + "RunAsyncCallbackFn" + ], + "cpp": [ + "AllocatedStringPtr", + "Allocator", + "AllocatorWithDefaultOptions", + "ArenaCfg", + "AttrNameSubgraph", + "BFloat16_t", + "CUDAProviderOptions", + "CompileModel", + "ConstEpAssignedNode", + "ConstEpAssignedSubgraph", + "ConstEpDevice", + "ConstExternalInitializerInfo", + "ConstGraph", + "ConstHardwareDevice", + "ConstIoBinding", + "ConstKernelDef", + "ConstKernelInfo", + "ConstKeyValuePairs", + "ConstMapTypeInfo", + "ConstMemoryInfo", + "ConstNode", + "ConstOpAttr", + "ConstOpSchemaTypeConstraint", + "ConstOptionalTypeInfo", + "ConstProfilingEvent", + "ConstSequenceTypeInfo", + "ConstSession", + "ConstSessionOptions", + "ConstTensorTypeAndShapeInfo", + "ConstTypeInfo", + "ConstValue", + "ConstValueInfo", + "CustomOpBase", + "CustomOpConfigs", + "CustomOpDomain", + "Env", + "EpDevice", + "Exception", + "ExternalInitializerInfo", + "FinalizeModelEditorSession", + "Float16_t", + "Float8E4M3FNUZ_t", + "Float8E4M3FN_t", + "Float8E5M2FNUZ_t", + "Float8E5M2_t", + "GetApi", + "GetAvailableProviders", + "GetBuildInfoString", + "GetCompatibilityInfoFromModelAllocated", + "GetCompatibilityInfoFromModelBytesAllocated", + "GetCompileApi", + "GetEnvConfigEntries", + "GetEpApi", + "GetInteropApi", + "GetModelCompatibilityForEpDevices", + "GetModelEditorApi", + "GetOpSchema", + "GetVersionString", + "Graph", + "IoBinding", + "KernelContext", + "KernelDef", + "KernelDefBuilder", + "KernelInfo", + "KernelRegistry", + "KeyValuePairs", + "Logger", + "LoraAdapter", + "MapTypeInfo", + "MemoryAllocation", + "MemoryInfo", + "Model", + "ModelCompilationOptions", + "ModelMetadata", + "Node", + "Op", + "OpAttr", + "OpSchema", + "OperatorSet", + "PrepackedWeightsContainer", + "ProfilingEvent", + "RunOptions", + "SequenceTypeInfo", + "Session", + "SessionOptions", + "ShapeInferContext", + "ShapeInferFn", + "Status", + "SyncStream", + "TensorRTProviderOptions", + "TensorTypeAndShapeInfo", + "ThreadingOptions", + "ThrowOnError", + "TypeInfo", + "TypeToTensorType", + "UnownedAllocator", + "UnownedIoBinding", + "UnownedModel", + "UnownedProfilingEventsContainer", + "UnownedSession", + "UnownedSessionOptions", + "UnownedSharedPrePackedWeightCache", + "UnownedSyncStream", + "UnownedValue", + "Value", + "ValueInfo", + "ValueInfoConsumerProducerInfo" + ] +} diff --git a/upstream/sources.lock.toml b/upstream/sources.lock.toml new file mode 100644 index 0000000..65e5bbd --- /dev/null +++ b/upstream/sources.lock.toml @@ -0,0 +1,18 @@ +[onnxruntime] +version = "1.25.1" +tag = "v1.25.1" +repo = "https://github.com/microsoft/onnxruntime" +provider = "compat.onnxruntime@1.25.1" +headers = "Official CPU SDK, same version as the linked runtime" + +[onnxruntime.linux-x86_64] +archive = "onnxruntime-linux-x64-1.25.1.tgz" +sha256 = "eb566a49cfc49ef0642f809b69340b5bb656c7c4905ba873526d226f2c005816" + +[onnxruntime.macos-arm64] +archive = "onnxruntime-osx-arm64-1.25.1.tgz" +sha256 = "18987ec3187b5f29ba798109750f6135060560ad4e0a52678fcc753ee8fb3091" + +[onnxruntime.windows-x86_64-msvc] +archive = "onnxruntime-win-x64-1.25.1.zip" +sha256 = "33f2e8a63774811f99a5fc224cac32f4eed8c27643d46c6cc685319fa8f18019" From 4a6c74efbeccfff5f7344f60f74e533a42889efd Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sat, 24 Oct 2026 05:31:24 +0900 Subject: [PATCH 02/11] test: verify ORT deployment and project templates on native CI --- .../2026-10-24-implementation-checkpoints.md | 10 ++- .github/workflows/ci.yml | 86 +++++++++++++++++++ tools/test_candidate.py | 65 ++++++++++++++ tools/test_template.py | 3 +- 4 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 tools/test_candidate.py diff --git a/.agents/docs/2026-10-24-implementation-checkpoints.md b/.agents/docs/2026-10-24-implementation-checkpoints.md index d20ed89..1fa917b 100644 --- a/.agents/docs/2026-10-24-implementation-checkpoints.md +++ b/.agents/docs/2026-10-24-implementation-checkpoints.md @@ -10,4 +10,12 @@ - Linux SDK runtime closure requires declared gcc-runtime; GCC consumers use toolchain-coupled C++ runtime. - Provider candidate: mcpp-index-mwrap/pkgs/c/compat.onnxruntime.lua. - Pending: C API/header inventory completion, isolated deployment, Windows/macOS CI, release/index consumption, remote PR. -- Remote organization creation currently refused for GitHub identity speak-agent (403); local implementation continues. +- Organization repository creation is resolved through the existing authorized GitHub account; the default local account is unchanged. + +## SDK deployment and native CI checkpoint + +- An isolated MCPP_HOME with no ORT SDK successfully downloaded and installed the current SDK provider, then passed LLVM inference and header/module coexistence tests. +- The SDK provider is pinned to mcpp-index commit 3067e52abc0165b453ea3acac4022895ebf7d9bc for reproducible candidate CI. +- Native CI covers Linux GCC/LLVM, macOS arm64 and Windows MSVC ABI, including actual mcpp template rendering, build and execution. +- tools/test_candidate.py stages the candidate source and index routing outside the checkout; local --cold-sdk additionally verifies installation into a fresh home. +- Pending CI results, API inventory completion and release/index archive consumption remain release gates. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..290f41d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,86 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +env: + MCPP_VERSION: "2026.10.21.1" + SDK_INDEX_COMMIT: "3067e52abc0165b453ea3acac4022895ebf7d9bc" + +jobs: + test: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + include: + - name: linux-llvm + os: ubuntu-latest + suffix: linux-x86_64 + ext: tar.gz + toolchain: llvm@23.1.3 + - name: linux-gcc + os: ubuntu-latest + suffix: linux-x86_64 + ext: tar.gz + toolchain: gcc@16.1.0 + - name: macos-arm64 + os: macos-15 + suffix: macosx-arm64 + ext: tar.gz + toolchain: llvm@23.1.3 + - name: windows-msvc-abi + os: windows-latest + suffix: windows-x86_64 + ext: zip + toolchain: llvm@23.1.3 + steps: + - uses: actions/checkout@v4 + + - name: Checkout the candidate SDK provider + uses: actions/checkout@v4 + with: + repository: mcpplibs/mcpp-index + ref: ${{ env.SDK_INDEX_COMMIT }} + path: candidate-index + + - name: Install pinned mcpp + shell: bash + env: + MCPP_ARCHIVE: mcpp-${{ env.MCPP_VERSION }}-${{ matrix.suffix }}.${{ matrix.ext }} + MCPP_ROOT: mcpp-${{ env.MCPP_VERSION }}-${{ matrix.suffix }} + run: | + mkdir -p "$RUNNER_TEMP/mwrap-mcpp" + cd "$RUNNER_TEMP/mwrap-mcpp" + curl -L -fsS -o "$MCPP_ARCHIVE" \ + "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/${MCPP_ARCHIVE}" + case "$MCPP_ARCHIVE" in + *.zip) powershell -NoProfile -Command "Expand-Archive -Force -Path '${MCPP_ARCHIVE}' -DestinationPath '.'" ;; + *) tar -xzf "$MCPP_ARCHIVE" ;; + esac + root="$PWD/$MCPP_ROOT" + mkdir -p "$HOME/.mcpp/registry" + cp -a "$root/registry/." "$HOME/.mcpp/registry/" + if [[ "$RUNNER_OS" == Windows ]]; then + echo "$(cygpath -m "$root/bin")" >> "$GITHUB_PATH" + else + echo "$root/bin" >> "$GITHUB_PATH" + fi + + - name: SDK installation, module consumers and actual project template + shell: bash + run: | + python3 tools/test_candidate.py --index "$PWD/candidate-index" \ + --toolchain '${{ matrix.toolchain }}' --template diff --git a/tools/test_candidate.py b/tools/test_candidate.py new file mode 100644 index 0000000..5d8f6a3 --- /dev/null +++ b/tools/test_candidate.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +"""Test this wrapper against a candidate SDK index without editing the checkout.""" +import argparse +import os +from pathlib import Path +import shutil +import subprocess +import tempfile + + +def borrow_tools(home): + """Reuse installed tool versions, but never reuse the SDK under test.""" + user_home = Path.home() + for store in (user_home / ".mcpp/registry/data/xpkgs", user_home / ".xlings/data/xpkgs"): + if not store.is_dir(): + continue + for package in store.glob("xim-x-*"): + if not package.is_dir(): + continue + dest = home / "registry/data/xpkgs" / package.name + dest.mkdir(parents=True, exist_ok=True) + for version in package.iterdir(): + target = dest / version.name + if not target.exists(): + target.symlink_to(version.resolve(), target_is_directory=version.is_dir()) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--index", required=True, type=Path) + parser.add_argument("--mcpp", default="mcpp") + parser.add_argument("--toolchain", default="llvm@23.1.3") + parser.add_argument("--cold-sdk", action="store_true", help="use a fresh MCPP_HOME with no installed ORT SDK") + parser.add_argument("--template", action="store_true", help="also render and run the default project template") + args = parser.parse_args() + root = Path(__file__).resolve().parents[1] + with tempfile.TemporaryDirectory(prefix="mwrap-ort-candidate-") as directory: + temporary = Path(directory) + source = temporary / "source" + shutil.copytree(root, source, ignore=shutil.ignore_patterns( + ".git", "target", ".mcpp", ".xlings", "__pycache__", "mcpp.lock", "compile_commands.json", + "candidate-index", "mcpp-2026.*")) + with (source / "mcpp.toml").open("a") as manifest: + manifest.write('\n[indices]\ncompat = { path = "' + args.index.resolve().as_posix() + '" }\n') + env = dict(os.environ) + if args.cold_sdk: + home = temporary / "home" + home.mkdir() + borrow_tools(home) + env["MCPP_HOME"] = str(home) + command = [args.mcpp, "test", "--strict", "--toolchain", args.toolchain] + print("+", " ".join(command), flush=True) + subprocess.run(command, cwd=source, env=env, check=True) + if args.cold_sdk: + installed = [path for path in home.rglob("*onnxruntime*") if path.is_dir()] + assert installed, "SDK did not install into the isolated home" + print("Verified: SDK installed in the isolated home", flush=True) + if args.template: + subprocess.run([os.sys.executable, str(source / "tools/test_template.py"), + "--index", str(args.index.resolve()), "--mcpp", args.mcpp, + "--toolchain", args.toolchain], cwd=source, env=env, check=True) + + +if __name__ == "__main__": + main() diff --git a/tools/test_template.py b/tools/test_template.py index 67b3a0c..0de3abb 100644 --- a/tools/test_template.py +++ b/tools/test_template.py @@ -25,7 +25,8 @@ def run(command, cwd, env=None): temporary = Path(directory) home = temporary / "home" package = home / "registry/data/xpkgs/mcpplibs.mwrap-x-onnxruntime/1.25.1/onnxruntime-1.25.1" - shutil.copytree(root, package, ignore=shutil.ignore_patterns(".git", "target", ".mcpp", "__pycache__")) + shutil.copytree(root, package, ignore=shutil.ignore_patterns( + ".git", "target", ".mcpp", ".xlings", "__pycache__", "mcpp.lock", "compile_commands.json", "candidate-index", "mcpp-2026.*")) index = home / "indices/mcpplibs/pkgs/mwrap" index.mkdir(parents=True) (index / "mcpplibs.mwrap.onnxruntime.lua").write_text('''package = { From cff23f8dd44d75641f2491530750f75004be3ce3 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sat, 24 Oct 2026 05:47:37 +0900 Subject: [PATCH 03/11] feat: expose the CPU SDK public helper and configuration interfaces --- .../2026-10-24-implementation-checkpoints.md | 7 ++ .github/workflows/ci.yml | 6 +- README.md | 19 +++ mcpp.toml | 2 +- src/config.cppm | 11 ++ src/config_exports.inc | 70 ++++++++++++ src/exports.inc | 31 +++++ src/onnxruntime.cppm | 5 + tests/headers_mix.cpp | 2 + tests/public_surface.cpp | 22 ++++ tools/generate_exports.py | 94 ++++++++++----- tools/test_candidate.py | 19 +++ upstream/api-coverage.md | 34 ++++++ upstream/api-surface.json | 108 +++++++++++++++++- 14 files changed, 397 insertions(+), 33 deletions(-) create mode 100644 src/config.cppm create mode 100644 src/config_exports.inc create mode 100644 tests/public_surface.cpp create mode 100644 upstream/api-coverage.md diff --git a/.agents/docs/2026-10-24-implementation-checkpoints.md b/.agents/docs/2026-10-24-implementation-checkpoints.md index 1fa917b..b6a6fb2 100644 --- a/.agents/docs/2026-10-24-implementation-checkpoints.md +++ b/.agents/docs/2026-10-24-implementation-checkpoints.md @@ -19,3 +19,10 @@ - Native CI covers Linux GCC/LLVM, macOS arm64 and Windows MSVC ABI, including actual mcpp template rendering, build and execution. - tools/test_candidate.py stages the candidate source and index routing outside the checkout; local --cold-sdk additionally verifies installation into a fresh home. - Pending CI results, API inventory completion and release/index archive consumption remain release gates. + +## Expanded public SDK surface checkpoint + +- First native CI run 40019919136 passed all four jobs, including actual template execution. +- Expanded exports cover the CPU provider factory, plugin EP callbacks, Ort::Custom helpers, provider option aliases and legacy custom-op resource types. +- Added the independent .config module for 69 enabled SDK configuration/metadata keys. GCC cannot directly export upstream internal-linkage variables; equivalent inline pointers preserve spelling/type, with explicit header-mixing limits documented in upstream/api-coverage.md. +- Expanded Linux GCC/LLVM consumer tests passed; AST regeneration --check passed with the exact resolved LLVM compiler and SDK include path. Native CI rerun remains required on this expanded head. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 290f41d..b9432b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,21 +31,25 @@ jobs: suffix: linux-x86_64 ext: tar.gz toolchain: llvm@23.1.3 + audit: --audit - name: linux-gcc os: ubuntu-latest suffix: linux-x86_64 ext: tar.gz toolchain: gcc@16.1.0 + audit: "" - name: macos-arm64 os: macos-15 suffix: macosx-arm64 ext: tar.gz toolchain: llvm@23.1.3 + audit: "" - name: windows-msvc-abi os: windows-latest suffix: windows-x86_64 ext: zip toolchain: llvm@23.1.3 + audit: "" steps: - uses: actions/checkout@v4 @@ -83,4 +87,4 @@ jobs: shell: bash run: | python3 tools/test_candidate.py --index "$PWD/candidate-index" \ - --toolchain '${{ matrix.toolchain }}' --template + --toolchain '${{ matrix.toolchain }}' --template ${{ matrix.audit }} diff --git a/README.md b/README.md index dea89da..49f812b 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,25 @@ macros, including `ORT_TSTR`, remain available through still expands inside a qualified identifier; use the mapping and raw-macro forms in separate contexts. +The root also exposes the CPU provider factory, plugin EP API declarations, +`Ort::Custom` lightweight custom-op types and `onnxruntime::ProviderOptions`. +API availability does not install an execution provider that is absent from the CPU SDK. + +Configuration keys follow the SDK's separate-header grouping: + +```cpp +import mcpplibs.mwrap.onnxruntime; +import mcpplibs.mwrap.onnxruntime.config; +Ort::SessionOptions options; +options.AddConfigEntry(kOrtSessionOptionsConfigDisablePrepacking, "1"); +``` + +The config module preserves global key names and pointer types. Upstream gives +these header variables internal linkage, which GCC cannot export directly, so +the module supplies equivalent inline constants. Use either this module or the +raw config headers in a translation unit; combining both creates duplicate key +names. Raw config headers can be mixed with the root module, as the tests verify. + ## Development Use mcpp 2026.10.21.1 or newer. Tests exercise module-only inference, output shape diff --git a/mcpp.toml b/mcpp.toml index 1345ac1..c5763d0 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -11,7 +11,7 @@ upstream-version = "1.25.1" upstream-repo = "https://github.com/microsoft/onnxruntime" [build] -sources = ["src/onnxruntime.cppm", "src/macros.cppm"] +sources = ["src/onnxruntime.cppm", "src/macros.cppm", "src/config.cppm"] include_dirs = ["port/include"] [dependencies.compat] diff --git a/src/config.cppm b/src/config.cppm new file mode 100644 index 0000000..59bd5a3 --- /dev/null +++ b/src/config.cppm @@ -0,0 +1,11 @@ +module; +namespace mwrap_onnxruntime_config_detail { +#include +#include +#include +#include +} + +export module mcpplibs.mwrap.onnxruntime.config; + +#include "config_exports.inc" diff --git a/src/config_exports.inc b/src/config_exports.inc new file mode 100644 index 0000000..cc7fde9 --- /dev/null +++ b/src/config_exports.inc @@ -0,0 +1,70 @@ +// Generated from the official SDK configuration key headers. +export inline const char* const kDebugLayoutTransformation = mwrap_onnxruntime_config_detail::kDebugLayoutTransformation; +export inline const char* const kNodePartitionConfigFile = mwrap_onnxruntime_config_detail::kNodePartitionConfigFile; +export inline const char* const kOrtEnvAllowVirtualDevices = mwrap_onnxruntime_config_detail::kOrtEnvAllowVirtualDevices; +export inline const char* const kOrtEpDevice_EpMetadataKey_LibraryPath = mwrap_onnxruntime_config_detail::kOrtEpDevice_EpMetadataKey_LibraryPath; +export inline const char* const kOrtEpDevice_EpMetadataKey_OSDriverVersion = mwrap_onnxruntime_config_detail::kOrtEpDevice_EpMetadataKey_OSDriverVersion; +export inline const char* const kOrtEpDevice_EpMetadataKey_Version = mwrap_onnxruntime_config_detail::kOrtEpDevice_EpMetadataKey_Version; +export inline const char* const kOrtEpDynamicOptionsQnnHtpPerformanceMode = mwrap_onnxruntime_config_detail::kOrtEpDynamicOptionsQnnHtpPerformanceMode; +export inline const char* const kOrtEpDynamicOptionsWorkloadType = mwrap_onnxruntime_config_detail::kOrtEpDynamicOptionsWorkloadType; +export inline const char* const kOrtHardwareDevice_MetadataKey_IsVirtual = mwrap_onnxruntime_config_detail::kOrtHardwareDevice_MetadataKey_IsVirtual; +export inline const char* const kOrtModelMetadata_EpCompatibilityInfoPrefix = mwrap_onnxruntime_config_detail::kOrtModelMetadata_EpCompatibilityInfoPrefix; +export inline const char* const kOrtRunOptionsConfigCudaGraphAnnotation = mwrap_onnxruntime_config_detail::kOrtRunOptionsConfigCudaGraphAnnotation; +export inline const char* const kOrtRunOptionsConfigDisableSynchronizeExecutionProviders = mwrap_onnxruntime_config_detail::kOrtRunOptionsConfigDisableSynchronizeExecutionProviders; +export inline const char* const kOrtRunOptionsConfigEnableMemoryArenaShrinkage = mwrap_onnxruntime_config_detail::kOrtRunOptionsConfigEnableMemoryArenaShrinkage; +export inline const char* const kOrtRunOptionsConfigQnnLoraConfig = mwrap_onnxruntime_config_detail::kOrtRunOptionsConfigQnnLoraConfig; +export inline const char* const kOrtRunOptionsConfigQnnPerfMode = mwrap_onnxruntime_config_detail::kOrtRunOptionsConfigQnnPerfMode; +export inline const char* const kOrtRunOptionsConfigQnnPerfModePostRun = mwrap_onnxruntime_config_detail::kOrtRunOptionsConfigQnnPerfModePostRun; +export inline const char* const kOrtRunOptionsConfigQnnRpcControlLatency = mwrap_onnxruntime_config_detail::kOrtRunOptionsConfigQnnRpcControlLatency; +export inline const char* const kOrtSessionOptionEpContextEmbedMode = mwrap_onnxruntime_config_detail::kOrtSessionOptionEpContextEmbedMode; +export inline const char* const kOrtSessionOptionEpContextEnable = mwrap_onnxruntime_config_detail::kOrtSessionOptionEpContextEnable; +export inline const char* const kOrtSessionOptionEpContextFilePath = mwrap_onnxruntime_config_detail::kOrtSessionOptionEpContextFilePath; +export inline const char* const kOrtSessionOptionEpContextNodeNamePrefix = mwrap_onnxruntime_config_detail::kOrtSessionOptionEpContextNodeNamePrefix; +export inline const char* const kOrtSessionOptionEpEnableWeightlessEpContextNodes = mwrap_onnxruntime_config_detail::kOrtSessionOptionEpEnableWeightlessEpContextNodes; +export inline const char* const kOrtSessionOptionShareEpContexts = mwrap_onnxruntime_config_detail::kOrtSessionOptionShareEpContexts; +export inline const char* const kOrtSessionOptionStopShareEpContexts = mwrap_onnxruntime_config_detail::kOrtSessionOptionStopShareEpContexts; +export inline const char* const kOrtSessionOptionsAvx2PrecisionMode = mwrap_onnxruntime_config_detail::kOrtSessionOptionsAvx2PrecisionMode; +export inline const char* const kOrtSessionOptionsCollectNodeMemoryStatsToFile = mwrap_onnxruntime_config_detail::kOrtSessionOptionsCollectNodeMemoryStatsToFile; +export inline const char* const kOrtSessionOptionsConfigAllowInterOpSpinning = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigAllowInterOpSpinning; +export inline const char* const kOrtSessionOptionsConfigAllowIntraOpSpinning = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigAllowIntraOpSpinning; +export inline const char* const kOrtSessionOptionsConfigDisablePrepacking = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigDisablePrepacking; +export inline const char* const kOrtSessionOptionsConfigDynamicBlockBase = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigDynamicBlockBase; +export inline const char* const kOrtSessionOptionsConfigForceSpinningStop = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigForceSpinningStop; +export inline const char* const kOrtSessionOptionsConfigIntraOpThreadAffinities = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigIntraOpThreadAffinities; +export inline const char* const kOrtSessionOptionsConfigLoadModelFormat = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigLoadModelFormat; +export inline const char* const kOrtSessionOptionsConfigMinimalBuildOptimizations = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigMinimalBuildOptimizations; +export inline const char* const kOrtSessionOptionsConfigNnapiEpPartitioningStopOps = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigNnapiEpPartitioningStopOps; +export inline const char* const kOrtSessionOptionsConfigSaveModelFormat = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigSaveModelFormat; +export inline const char* const kOrtSessionOptionsConfigSetDenormalAsZero = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigSetDenormalAsZero; +export inline const char* const kOrtSessionOptionsConfigStrictAllowReleasedOpsetsOnly = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigStrictAllowReleasedOpsetsOnly; +export inline const char* const kOrtSessionOptionsConfigStrictShapeTypeInference = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigStrictShapeTypeInference; +export inline const char* const kOrtSessionOptionsConfigUseEnvAllocators = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigUseEnvAllocators; +export inline const char* const kOrtSessionOptionsConfigUseORTModelBytesDirectly = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigUseORTModelBytesDirectly; +export inline const char* const kOrtSessionOptionsConfigUseORTModelBytesForInitializers = mwrap_onnxruntime_config_detail::kOrtSessionOptionsConfigUseORTModelBytesForInitializers; +export inline const char* const kOrtSessionOptionsDisableAheadOfTimeFunctionInlining = mwrap_onnxruntime_config_detail::kOrtSessionOptionsDisableAheadOfTimeFunctionInlining; +export inline const char* const kOrtSessionOptionsDisableCPUEPFallback = mwrap_onnxruntime_config_detail::kOrtSessionOptionsDisableCPUEPFallback; +export inline const char* const kOrtSessionOptionsDisableDoubleQDQRemover = mwrap_onnxruntime_config_detail::kOrtSessionOptionsDisableDoubleQDQRemover; +export inline const char* const kOrtSessionOptionsDisableModelCompile = mwrap_onnxruntime_config_detail::kOrtSessionOptionsDisableModelCompile; +export inline const char* const kOrtSessionOptionsDisableQuantQDQ = mwrap_onnxruntime_config_detail::kOrtSessionOptionsDisableQuantQDQ; +export inline const char* const kOrtSessionOptionsDisableSpecifiedOptimizers = mwrap_onnxruntime_config_detail::kOrtSessionOptionsDisableSpecifiedOptimizers; +export inline const char* const kOrtSessionOptionsEnableCastChainElimination = mwrap_onnxruntime_config_detail::kOrtSessionOptionsEnableCastChainElimination; +export inline const char* const kOrtSessionOptionsEnableDQMatMulNBitsFusion = mwrap_onnxruntime_config_detail::kOrtSessionOptionsEnableDQMatMulNBitsFusion; +export inline const char* const kOrtSessionOptionsEnableGeluApproximation = mwrap_onnxruntime_config_detail::kOrtSessionOptionsEnableGeluApproximation; +export inline const char* const kOrtSessionOptionsEnableQuantQDQCleanup = mwrap_onnxruntime_config_detail::kOrtSessionOptionsEnableQuantQDQCleanup; +export inline const char* const kOrtSessionOptionsEpContextModelExternalInitializersFileName = mwrap_onnxruntime_config_detail::kOrtSessionOptionsEpContextModelExternalInitializersFileName; +export inline const char* const kOrtSessionOptionsFailOnSuboptimalCompiledModel = mwrap_onnxruntime_config_detail::kOrtSessionOptionsFailOnSuboptimalCompiledModel; +export inline const char* const kOrtSessionOptionsGraphOptimizationsLoopLevel = mwrap_onnxruntime_config_detail::kOrtSessionOptionsGraphOptimizationsLoopLevel; +export inline const char* const kOrtSessionOptionsLayerAssignmentSettings = mwrap_onnxruntime_config_detail::kOrtSessionOptionsLayerAssignmentSettings; +export inline const char* const kOrtSessionOptionsMlasDisableKleidiAi = mwrap_onnxruntime_config_detail::kOrtSessionOptionsMlasDisableKleidiAi; +export inline const char* const kOrtSessionOptionsMlasGemmFastMathArm64Bfloat16 = mwrap_onnxruntime_config_detail::kOrtSessionOptionsMlasGemmFastMathArm64Bfloat16; +export inline const char* const kOrtSessionOptionsMlasLutGemm = mwrap_onnxruntime_config_detail::kOrtSessionOptionsMlasLutGemm; +export inline const char* const kOrtSessionOptionsModelExternalInitializersFileFolderPath = mwrap_onnxruntime_config_detail::kOrtSessionOptionsModelExternalInitializersFileFolderPath; +export inline const char* const kOrtSessionOptionsOptimizedModelExternalInitializersFileName = mwrap_onnxruntime_config_detail::kOrtSessionOptionsOptimizedModelExternalInitializersFileName; +export inline const char* const kOrtSessionOptionsOptimizedModelExternalInitializersMinSizeInBytes = mwrap_onnxruntime_config_detail::kOrtSessionOptionsOptimizedModelExternalInitializersMinSizeInBytes; +export inline const char* const kOrtSessionOptionsQDQIsInt8Allowed = mwrap_onnxruntime_config_detail::kOrtSessionOptionsQDQIsInt8Allowed; +export inline const char* const kOrtSessionOptionsQDQMatMulNBitsAccuracyLevel = mwrap_onnxruntime_config_detail::kOrtSessionOptionsQDQMatMulNBitsAccuracyLevel; +export inline const char* const kOrtSessionOptionsQDQMatMulNBitsBlockSize = mwrap_onnxruntime_config_detail::kOrtSessionOptionsQDQMatMulNBitsBlockSize; +export inline const char* const kOrtSessionOptionsRecordEpGraphAssignmentInfo = mwrap_onnxruntime_config_detail::kOrtSessionOptionsRecordEpGraphAssignmentInfo; +export inline const char* const kOrtSessionOptionsResourceCudaPartitioningSettings = mwrap_onnxruntime_config_detail::kOrtSessionOptionsResourceCudaPartitioningSettings; +export inline const char* const kOrtSessionOptionsSavePrePackedConstantInitializers = mwrap_onnxruntime_config_detail::kOrtSessionOptionsSavePrePackedConstantInitializers; +export inline const char* const kOrtSessionOptionsUseDeviceAllocatorForInitializers = mwrap_onnxruntime_config_detail::kOrtSessionOptionsUseDeviceAllocatorForInitializers; diff --git a/src/exports.inc b/src/exports.inc index e7c8a1d..d90bed6 100644 --- a/src/exports.inc +++ b/src/exports.inc @@ -1,5 +1,7 @@ // Generated from the official 1.25.1 public API AST. export { +using ::CreateEpApiFactoriesFn; +using ::CustomOpContext; using ::ExecutionMode; using ::GraphOptimizationLevel; using ::INPUT_OUTPUT_OPTIONAL; @@ -246,6 +248,7 @@ using ::OrtScanKernelHelper; using ::OrtSequenceTypeInfo; using ::OrtSession; using ::OrtSessionOptions; +using ::OrtSessionOptionsAppendExecutionProvider_CPU; using ::OrtSessionOptionsAppendExecutionProvider_CUDA; using ::OrtSessionOptionsAppendExecutionProvider_Dnnl; using ::OrtSessionOptionsAppendExecutionProvider_MIGraphX; @@ -276,7 +279,14 @@ using ::OrtTypeInfo; using ::OrtValue; using ::OrtValueInfo; using ::OrtWriteBufferFunc; +using ::ReleaseEpApiFactoryFn; +using ::ResourceOffset; using ::RunAsyncCallbackFn; +using ::cpu_resource_offset; +using ::cuda_resource_offset; +using ::custom_ep_resource_offset; +using ::dml_resource_offset; +using ::migraphx_resource_offset; } export namespace Ort { using ::Ort::AllocatedStringPtr; @@ -387,3 +397,24 @@ using ::Ort::Value; using ::Ort::ValueInfo; using ::Ort::ValueInfoConsumerProducerInfo; } +export namespace Ort::Custom { +using ::Ort::Custom::ArgBase; +using ::Ort::Custom::ArgPtr; +using ::Ort::Custom::ArgPtrs; +using ::Ort::Custom::CreateLiteCustomOp; +using ::Ort::Custom::OrtLiteCustomFunc; +using ::Ort::Custom::OrtLiteCustomOp; +using ::Ort::Custom::OrtLiteCustomStruct; +using ::Ort::Custom::Span; +using ::Ort::Custom::Tensor; +using ::Ort::Custom::TensorArray; +using ::Ort::Custom::TensorBase; +using ::Ort::Custom::TensorPtr; +using ::Ort::Custom::TensorPtrs; +using ::Ort::Custom::Variadic; +} +export namespace onnxruntime { +using ::onnxruntime::ProviderOptions; +using ::onnxruntime::ProviderOptionsMap; +using ::onnxruntime::ProviderOptionsVector; +} diff --git a/src/onnxruntime.cppm b/src/onnxruntime.cppm index c50978f..3e90d2b 100644 --- a/src/onnxruntime.cppm +++ b/src/onnxruntime.cppm @@ -1,5 +1,10 @@ module; #include +#include +#include +#include +#include +#include export module mcpplibs.mwrap.onnxruntime; diff --git a/tests/headers_mix.cpp b/tests/headers_mix.cpp index e7f5689..28d37fc 100644 --- a/tests/headers_mix.cpp +++ b/tests/headers_mix.cpp @@ -1,4 +1,5 @@ #include +#include import std; import mcpplibs.mwrap.onnxruntime; @@ -6,5 +7,6 @@ static_assert(std::is_same_vGetApi(ORT_API_VERSION) ? 0 : 1; } diff --git a/tests/public_surface.cpp b/tests/public_surface.cpp new file mode 100644 index 0000000..c6efd3b --- /dev/null +++ b/tests/public_surface.cpp @@ -0,0 +1,22 @@ +import std; +import mcpplibs.mwrap.onnxruntime; +import mcpplibs.mwrap.onnxruntime.config; + +int main() { + static_assert(sizeof(OrtEpApi) > 0); + static_assert(std::is_pointer_v); + static_assert(std::is_class_v>); + static_assert(std::is_same_v); + static_assert(cpu_resource_offset == 0); + CustomOpContext context; + onnxruntime::ProviderOptions provider_options{{"example", "value"}}; + if (provider_options.at("example") != "value") return 1; + Ort::SessionOptions options; + if (std::string_view(kOrtSessionOptionsConfigDisablePrepacking) != "session.disable_prepacking") return 3; + options.AddConfigEntry(kOrtSessionOptionsConfigDisablePrepacking, "1"); + OrtStatus* status = OrtSessionOptionsAppendExecutionProvider_CPU(options, 1); + if (status) { + Ort::GetApi().ReleaseStatus(status); + return 2; + } +} diff --git a/tools/generate_exports.py b/tools/generate_exports.py index 33c36c8..046f73b 100644 --- a/tools/generate_exports.py +++ b/tools/generate_exports.py @@ -9,27 +9,39 @@ def generate(ast): declarations = ast.get("inner", []) - namespace_ids = {n["id"] for n in declarations - if n.get("kind") == "NamespaceDecl" and n.get("name") == "Ort"} - kinds = {"CXXRecordDecl", "RecordDecl", "ClassTemplateDecl", "FunctionTemplateDecl", - "FunctionDecl", "TypeAliasDecl", "TypeAliasTemplateDecl", "EnumDecl", "VarDecl"} - cpp, capi = set(), set() - for namespace in declarations: - if namespace.get("id") not in namespace_ids: - continue - for node in namespace.get("inner", []): - name = node.get("name", "") - if node.get("kind") not in kinds or not name.isidentifier() or node.get("isImplicit"): - continue - # Clang also places out-of-line qualified definitions here. Their - # semantic owner is a class/detail namespace, not the public Ort scope. - owner = node.get("parentDeclContextId") - if owner and owner not in namespace_ids: - continue - if node.get("kind") == "FunctionTemplateDecl" and any( - x.get("kind") == "CXXMethodDecl" for x in node.get("inner", [])): + namespaces = {name: [] for name in ("Ort", "Ort::Custom", "onnxruntime", "mwrap_onnxruntime_config_detail")} + + def find_namespaces(nodes, prefix=""): + for node in nodes: + if node.get("kind") != "NamespaceDecl": continue - cpp.add(name) + name = "::".join(filter(None, (prefix, node.get("name", "")))) + if name in namespaces: + namespaces[name].append(node) + find_namespaces(node.get("inner", []), name) + + find_namespaces(declarations) + kinds = {"CXXRecordDecl", "RecordDecl", "ClassTemplateDecl", "FunctionTemplateDecl", + "FunctionDecl", "TypeAliasDecl", "TypeAliasTemplateDecl", "TypedefDecl", "EnumDecl", "VarDecl"} + cpp, capi = {}, set() + for path, extensions in namespaces.items(): + namespace_ids = {node["id"] for node in extensions} + names = set() + for namespace in extensions: + for node in namespace.get("inner", []): + name = node.get("name", "") + if node.get("kind") not in kinds or not name.isidentifier() or node.get("isImplicit"): + continue + # Ignore out-of-line definitions whose semantic owner is a + # class or an internal namespace rather than this public scope. + owner = node.get("parentDeclContextId") + if owner and owner not in namespace_ids: + continue + if node.get("kind") == "FunctionTemplateDecl" and any( + x.get("kind") == "CXXMethodDecl" for x in node.get("inner", [])): + continue + names.add(name) + cpp[path] = sorted(names) def collect_c(nodes): for node in nodes: @@ -38,36 +50,60 @@ def collect_c(nodes): continue name = node.get("name", "") public_name = name.startswith(("Ort", "ONNX")) or name in { - "GraphOptimizationLevel", "ExecutionMode", "ExecutionOrder", "RunAsyncCallbackFn"} + "GraphOptimizationLevel", "ExecutionMode", "ExecutionOrder", "RunAsyncCallbackFn", + "CreateEpApiFactoriesFn", "ReleaseEpApiFactoryFn", "CustomOpContext", "ResourceOffset"} if public_name and node.get("kind") in kinds | {"TypedefDecl"}: capi.add(name) if node.get("kind") == "EnumDecl": capi.update(x["name"] for x in node.get("inner", []) if x.get("kind") == "EnumConstantDecl") collect_c(declarations) - return sorted(capi), sorted(cpp) + return sorted(capi), cpp if __name__ == "__main__": parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("sdk_include", type=Path) parser.add_argument("--clang", default="clang++") + parser.add_argument("--check", action="store_true", help="fail if the committed inventory/exports differ") args = parser.parse_args() root = Path(__file__).resolve().parents[1] + config_headers = ("onnxruntime_env_config_keys.h", "onnxruntime_run_options_config_keys.h", + "onnxruntime_session_options_config_keys.h", "onnxruntime_ep_device_ep_metadata_keys.h") with tempfile.TemporaryDirectory(prefix="mwrap-ort-exports-") as temporary: directory = Path(temporary) probe = directory / "probe.cpp" - probe.write_text("#include \n") + probe.write_text("\n".join(f"#include <{header}>" for header in ( + "onnxruntime_cxx_api.h", "cpu_provider_factory.h", + "provider_options.h", "onnxruntime_lite_custom_op.h", + "core/providers/custom_op_context.h", "core/providers/resource.h")) + + "\nnamespace mwrap_onnxruntime_config_detail {\n" + + "\n".join(f"#include <{header}>" for header in config_headers) + "\n}\n") with (directory / "ast.json").open("w") as out: subprocess.run([args.clang, "-std=c++23", "-I", str(args.sdk_include), "-Xclang", "-ast-dump=json", "-fsyntax-only", str(probe)], stdout=out, check=True) with (directory / "ast.json").open() as source: capi, cpp = generate(json.load(source)) + config_keys = cpp.pop("mwrap_onnxruntime_config_detail") text = "// Generated from the official 1.25.1 public API AST.\nexport {\n" - text += "".join(f"using ::{name};\n" for name in capi) + "}\nexport namespace Ort {\n" - text += "".join(f"using ::Ort::{name};\n" for name in cpp) + "}\n" - (root / "src/exports.inc").write_text(text) - (root / "upstream/api-surface.json").write_text(json.dumps( - {"version": "1.25.1", "c": capi, "cpp": cpp}, indent=2) + "\n") - print(f"Exported {len(capi)} C declarations/enumerators and {len(cpp)} Ort declarations") + text += "".join(f"using ::{name};\n" for name in capi) + "}\n" + for namespace, names in cpp.items(): + text += f"export namespace {namespace} {{\n" + text += "".join(f"using ::{namespace}::{name};\n" for name in names) + "}\n" + config_text = "// Generated from the official SDK configuration key headers.\n" + config_text += "".join(f"export inline const char* const {name} = mwrap_onnxruntime_config_detail::{name};\n" + for name in sorted(config_keys)) + outputs = {root / "src/exports.inc": text, + root / "src/config_exports.inc": config_text, + root / "upstream/api-surface.json": json.dumps( + {"version": "1.25.1", "c": capi, "cpp": cpp["Ort"], + "config-keys": sorted(config_keys), + "cpp-namespaces": {name: names for name, names in cpp.items() if name != "Ort"}}, indent=2) + "\n"} + for path, content in outputs.items(): + if args.check: + if path.read_text() != content: + raise SystemExit(f"API surface differs: regenerate {path.relative_to(root)}") + else: + path.write_text(content) + print(f"Exported {len(capi)} C declarations/enumerators and {sum(map(len, cpp.values()))} C++ declarations") diff --git a/tools/test_candidate.py b/tools/test_candidate.py index 5d8f6a3..8b7f8aa 100644 --- a/tools/test_candidate.py +++ b/tools/test_candidate.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 """Test this wrapper against a candidate SDK index without editing the checkout.""" import argparse +import json import os from pathlib import Path import shutil @@ -32,6 +33,7 @@ def main(): parser.add_argument("--toolchain", default="llvm@23.1.3") parser.add_argument("--cold-sdk", action="store_true", help="use a fresh MCPP_HOME with no installed ORT SDK") parser.add_argument("--template", action="store_true", help="also render and run the default project template") + parser.add_argument("--audit", action="store_true", help="verify generated exports with the LLVM SDK consumer command") args = parser.parse_args() root = Path(__file__).resolve().parents[1] with tempfile.TemporaryDirectory(prefix="mwrap-ort-candidate-") as directory: @@ -51,6 +53,23 @@ def main(): command = [args.mcpp, "test", "--strict", "--toolchain", args.toolchain] print("+", " ".join(command), flush=True) subprocess.run(command, cwd=source, env=env, check=True) + if args.audit: + commands = json.loads((source / "compile_commands.json").read_text()) + found = None + for entry in commands: + arguments = entry["arguments"] + if "clang" not in Path(arguments[0]).name: + continue + for number, argument in enumerate(arguments): + include = arguments[number + 1] if argument == "-I" else argument[2:] if argument.startswith("-I") else "" + if include and (Path(include) / "onnxruntime_cxx_api.h").is_file(): + found = (arguments[0], include) + break + if found: + break + assert found, "Cannot locate the resolved SDK include path and LLVM compiler for the export audit" + subprocess.run([os.sys.executable, str(source / "tools/generate_exports.py"), + found[1], "--clang", found[0], "--check"], cwd=source, env=env, check=True) if args.cold_sdk: installed = [path for path in home.rglob("*onnxruntime*") if path.is_dir()] assert installed, "SDK did not install into the isolated home" diff --git a/upstream/api-coverage.md b/upstream/api-coverage.md new file mode 100644 index 0000000..d2d9cde --- /dev/null +++ b/upstream/api-coverage.md @@ -0,0 +1,34 @@ +# Official CPU SDK header coverage + +The source of truth is the official 1.25.1 CPU SDK pinned in sources.lock.toml. +tools/generate_exports.py records enabled declarations from Clang's semantic +AST. Its --check mode verifies committed exports and inventory without pruning +compiler failures. Methods and overloads remain members of the original exported +classes; the inventory counts top-level names, not every member function. + +| SDK surface | Module surface | +|---|---| +| onnxruntime_c_api.h, including its unguarded onnxruntime_ep_c_api.h continuation | Root: C types, enumerators, API tables and callback typedefs | +| onnxruntime_cxx_api.h and onnxruntime_cxx_inline.h | Root: original public Ort declarations and their methods | +| cpu_provider_factory.h | Root: original CPU registration function, tested against the actual SDK | +| onnxruntime_lite_custom_op.h | Root: original Ort::Custom types and factories | +| provider_options.h | Root: original onnxruntime::ProviderOptions aliases | +| core/providers/custom_op_context.h and resource.h | Root: original custom-op context and resource offsets | +| env/run/session config keys and EP metadata keys | Separate .config module, preserving global names and pointer types | +| onnxruntime_float16.h | Original public Ort float16 types through the C++ API; their implementation namespace remains an implementation dependency | + +The SDK's configuration keys have internal linkage. GCC rejects exporting those +variables directly. The .config module supplies equivalent inline constant +pointers; combining it with the same raw config headers would introduce two +entities with the same names. As upstream's C++ API header itself does not +include those separate key headers, the root does not re-export .config. Both +module-only config use and raw-config-header/root-module coexistence are tested. + +Function-like/preprocessing-control macros require the compatibility header +before import. ORT_API_VERSION additionally has a typed mapping in .macros. +The default module uses the SDK's normal API initialization mode, not a caller's +later preprocessing changes. Internal detail namespaces and implementation-only +float16 helpers are not promoted to public module APIs. + +The SDK is CPU-only. EP API declarations and resource offsets do not supply GPU +provider binaries. No claim is made that a CPU SDK can execute those providers. diff --git a/upstream/api-surface.json b/upstream/api-surface.json index 4355194..fbfcf1a 100644 --- a/upstream/api-surface.json +++ b/upstream/api-surface.json @@ -1,6 +1,8 @@ { "version": "1.25.1", "c": [ + "CreateEpApiFactoriesFn", + "CustomOpContext", "ExecutionMode", "GraphOptimizationLevel", "INPUT_OUTPUT_OPTIONAL", @@ -247,6 +249,7 @@ "OrtSequenceTypeInfo", "OrtSession", "OrtSessionOptions", + "OrtSessionOptionsAppendExecutionProvider_CPU", "OrtSessionOptionsAppendExecutionProvider_CUDA", "OrtSessionOptionsAppendExecutionProvider_Dnnl", "OrtSessionOptionsAppendExecutionProvider_MIGraphX", @@ -277,7 +280,14 @@ "OrtValue", "OrtValueInfo", "OrtWriteBufferFunc", - "RunAsyncCallbackFn" + "ReleaseEpApiFactoryFn", + "ResourceOffset", + "RunAsyncCallbackFn", + "cpu_resource_offset", + "cuda_resource_offset", + "custom_ep_resource_offset", + "dml_resource_offset", + "migraphx_resource_offset" ], "cpp": [ "AllocatedStringPtr", @@ -387,5 +397,99 @@ "Value", "ValueInfo", "ValueInfoConsumerProducerInfo" - ] + ], + "config-keys": [ + "kDebugLayoutTransformation", + "kNodePartitionConfigFile", + "kOrtEnvAllowVirtualDevices", + "kOrtEpDevice_EpMetadataKey_LibraryPath", + "kOrtEpDevice_EpMetadataKey_OSDriverVersion", + "kOrtEpDevice_EpMetadataKey_Version", + "kOrtEpDynamicOptionsQnnHtpPerformanceMode", + "kOrtEpDynamicOptionsWorkloadType", + "kOrtHardwareDevice_MetadataKey_IsVirtual", + "kOrtModelMetadata_EpCompatibilityInfoPrefix", + "kOrtRunOptionsConfigCudaGraphAnnotation", + "kOrtRunOptionsConfigDisableSynchronizeExecutionProviders", + "kOrtRunOptionsConfigEnableMemoryArenaShrinkage", + "kOrtRunOptionsConfigQnnLoraConfig", + "kOrtRunOptionsConfigQnnPerfMode", + "kOrtRunOptionsConfigQnnPerfModePostRun", + "kOrtRunOptionsConfigQnnRpcControlLatency", + "kOrtSessionOptionEpContextEmbedMode", + "kOrtSessionOptionEpContextEnable", + "kOrtSessionOptionEpContextFilePath", + "kOrtSessionOptionEpContextNodeNamePrefix", + "kOrtSessionOptionEpEnableWeightlessEpContextNodes", + "kOrtSessionOptionShareEpContexts", + "kOrtSessionOptionStopShareEpContexts", + "kOrtSessionOptionsAvx2PrecisionMode", + "kOrtSessionOptionsCollectNodeMemoryStatsToFile", + "kOrtSessionOptionsConfigAllowInterOpSpinning", + "kOrtSessionOptionsConfigAllowIntraOpSpinning", + "kOrtSessionOptionsConfigDisablePrepacking", + "kOrtSessionOptionsConfigDynamicBlockBase", + "kOrtSessionOptionsConfigForceSpinningStop", + "kOrtSessionOptionsConfigIntraOpThreadAffinities", + "kOrtSessionOptionsConfigLoadModelFormat", + "kOrtSessionOptionsConfigMinimalBuildOptimizations", + "kOrtSessionOptionsConfigNnapiEpPartitioningStopOps", + "kOrtSessionOptionsConfigSaveModelFormat", + "kOrtSessionOptionsConfigSetDenormalAsZero", + "kOrtSessionOptionsConfigStrictAllowReleasedOpsetsOnly", + "kOrtSessionOptionsConfigStrictShapeTypeInference", + "kOrtSessionOptionsConfigUseEnvAllocators", + "kOrtSessionOptionsConfigUseORTModelBytesDirectly", + "kOrtSessionOptionsConfigUseORTModelBytesForInitializers", + "kOrtSessionOptionsDisableAheadOfTimeFunctionInlining", + "kOrtSessionOptionsDisableCPUEPFallback", + "kOrtSessionOptionsDisableDoubleQDQRemover", + "kOrtSessionOptionsDisableModelCompile", + "kOrtSessionOptionsDisableQuantQDQ", + "kOrtSessionOptionsDisableSpecifiedOptimizers", + "kOrtSessionOptionsEnableCastChainElimination", + "kOrtSessionOptionsEnableDQMatMulNBitsFusion", + "kOrtSessionOptionsEnableGeluApproximation", + "kOrtSessionOptionsEnableQuantQDQCleanup", + "kOrtSessionOptionsEpContextModelExternalInitializersFileName", + "kOrtSessionOptionsFailOnSuboptimalCompiledModel", + "kOrtSessionOptionsGraphOptimizationsLoopLevel", + "kOrtSessionOptionsLayerAssignmentSettings", + "kOrtSessionOptionsMlasDisableKleidiAi", + "kOrtSessionOptionsMlasGemmFastMathArm64Bfloat16", + "kOrtSessionOptionsMlasLutGemm", + "kOrtSessionOptionsModelExternalInitializersFileFolderPath", + "kOrtSessionOptionsOptimizedModelExternalInitializersFileName", + "kOrtSessionOptionsOptimizedModelExternalInitializersMinSizeInBytes", + "kOrtSessionOptionsQDQIsInt8Allowed", + "kOrtSessionOptionsQDQMatMulNBitsAccuracyLevel", + "kOrtSessionOptionsQDQMatMulNBitsBlockSize", + "kOrtSessionOptionsRecordEpGraphAssignmentInfo", + "kOrtSessionOptionsResourceCudaPartitioningSettings", + "kOrtSessionOptionsSavePrePackedConstantInitializers", + "kOrtSessionOptionsUseDeviceAllocatorForInitializers" + ], + "cpp-namespaces": { + "Ort::Custom": [ + "ArgBase", + "ArgPtr", + "ArgPtrs", + "CreateLiteCustomOp", + "OrtLiteCustomFunc", + "OrtLiteCustomOp", + "OrtLiteCustomStruct", + "Span", + "Tensor", + "TensorArray", + "TensorBase", + "TensorPtr", + "TensorPtrs", + "Variadic" + ], + "onnxruntime": [ + "ProviderOptions", + "ProviderOptionsMap", + "ProviderOptionsVector" + ] + } } From de3a0a9da143f4ae52eb5e1a0302ba3fdf623b6d Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sat, 24 Oct 2026 05:53:38 +0900 Subject: [PATCH 04/11] fix: supply pinned upstream helper headers omitted from the Windows SDK --- .../docs/2026-10-24-implementation-checkpoints.md | 6 ++++++ mcpp.toml | 2 +- tools/generate_exports.py | 9 ++++++++- upstream/api-coverage.md | 6 ++++++ .../include/core/providers/custom_op_context.h | 10 ++++++++++ upstream/include/core/providers/resource.h | 14 ++++++++++++++ upstream/sources.lock.toml | 10 ++++++++++ 7 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 upstream/include/core/providers/custom_op_context.h create mode 100644 upstream/include/core/providers/resource.h diff --git a/.agents/docs/2026-10-24-implementation-checkpoints.md b/.agents/docs/2026-10-24-implementation-checkpoints.md index b6a6fb2..4dd8850 100644 --- a/.agents/docs/2026-10-24-implementation-checkpoints.md +++ b/.agents/docs/2026-10-24-implementation-checkpoints.md @@ -26,3 +26,9 @@ - Expanded exports cover the CPU provider factory, plugin EP callbacks, Ort::Custom helpers, provider option aliases and legacy custom-op resource types. - Added the independent .config module for 69 enabled SDK configuration/metadata keys. GCC cannot directly export upstream internal-linkage variables; equivalent inline pointers preserve spelling/type, with explicit header-mixing limits documented in upstream/api-coverage.md. - Expanded Linux GCC/LLVM consumer tests passed; AST regeneration --check passed with the exact resolved LLVM compiler and SDK include path. Native CI rerun remains required on this expanded head. + +## Windows SDK header parity correction + +- Expanded native CI passed on Linux GCC/LLVM and macOS; Windows revealed that its official SDK omits core/providers/custom_op_context.h and resource.h. +- Added exact official v1.25.1 source copies under upstream/include, verified byte-for-byte against both the official raw source and Linux SDK; individual hashes and source URLs are recorded and checked by the API auditor. +- This preserves the helper API on Windows without inventing declarations, linking another runtime or removing those interfaces from other platforms. diff --git a/mcpp.toml b/mcpp.toml index c5763d0..302bc28 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -12,7 +12,7 @@ upstream-repo = "https://github.com/microsoft/onnxruntime" [build] sources = ["src/onnxruntime.cppm", "src/macros.cppm", "src/config.cppm"] -include_dirs = ["port/include"] +include_dirs = ["port/include", "upstream/include"] [dependencies.compat] onnxruntime = "1.25.1" diff --git a/tools/generate_exports.py b/tools/generate_exports.py index 046f73b..612bb94 100644 --- a/tools/generate_exports.py +++ b/tools/generate_exports.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 """Generate export-using declarations from Clang's public SDK declaration AST.""" import argparse +import hashlib import json from pathlib import Path import subprocess import tempfile +import tomllib def generate(ast): @@ -68,6 +70,11 @@ def collect_c(nodes): parser.add_argument("--check", action="store_true", help="fail if the committed inventory/exports differ") args = parser.parse_args() root = Path(__file__).resolve().parents[1] + lock = tomllib.loads((root / "upstream/sources.lock.toml").read_text()) + for header in lock["onnxruntime"]["supplemental-headers"].values(): + digest = hashlib.sha256((root / header["path"]).read_bytes()).hexdigest() + if digest != header["sha256"]: + raise SystemExit(f"Supplemental upstream header differs: {header['path']}") config_headers = ("onnxruntime_env_config_keys.h", "onnxruntime_run_options_config_keys.h", "onnxruntime_session_options_config_keys.h", "onnxruntime_ep_device_ep_metadata_keys.h") with tempfile.TemporaryDirectory(prefix="mwrap-ort-exports-") as temporary: @@ -80,7 +87,7 @@ def collect_c(nodes): "\nnamespace mwrap_onnxruntime_config_detail {\n" + "\n".join(f"#include <{header}>" for header in config_headers) + "\n}\n") with (directory / "ast.json").open("w") as out: - subprocess.run([args.clang, "-std=c++23", "-I", str(args.sdk_include), + subprocess.run([args.clang, "-std=c++23", "-I", str(args.sdk_include), "-I", str(root / "upstream/include"), "-Xclang", "-ast-dump=json", "-fsyntax-only", str(probe)], stdout=out, check=True) with (directory / "ast.json").open() as source: diff --git a/upstream/api-coverage.md b/upstream/api-coverage.md index d2d9cde..ecbe245 100644 --- a/upstream/api-coverage.md +++ b/upstream/api-coverage.md @@ -17,6 +17,12 @@ classes; the inventory counts top-level names, not every member function. | env/run/session config keys and EP metadata keys | Separate .config module, preserving global names and pointer types | | onnxruntime_float16.h | Original public Ort float16 types through the C++ API; their implementation namespace remains an implementation dependency | +The Windows SDK omits the two core/providers helper headers. The wrapper carries +verbatim copies under upstream/include from the official v1.25.1 source. Their +bytes were checked against both the official source and Linux SDK, and their +individual SHA256 values are pinned in sources.lock.toml. They contain only +interface declarations/resource offsets and add no second runtime binary. + The SDK's configuration keys have internal linkage. GCC rejects exporting those variables directly. The .config module supplies equivalent inline constant pointers; combining it with the same raw config headers would introduce two diff --git a/upstream/include/core/providers/custom_op_context.h b/upstream/include/core/providers/custom_op_context.h new file mode 100644 index 0000000..b10126d --- /dev/null +++ b/upstream/include/core/providers/custom_op_context.h @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +// CustomOpContext defines an interface allowing a custom op to access ep-specific resources. +struct CustomOpContext { + CustomOpContext() = default; + virtual ~CustomOpContext() {}; +}; \ No newline at end of file diff --git a/upstream/include/core/providers/resource.h b/upstream/include/core/providers/resource.h new file mode 100644 index 0000000..8f9451a --- /dev/null +++ b/upstream/include/core/providers/resource.h @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +enum ResourceOffset { + cpu_resource_offset = 0, + cuda_resource_offset = 10000, + dml_resource_offset = 20000, + migraphx_resource_offset = 30000, + // offsets for other ort eps + custom_ep_resource_offset = 10000000, + // offsets for customized eps +}; diff --git a/upstream/sources.lock.toml b/upstream/sources.lock.toml index 65e5bbd..102a5d0 100644 --- a/upstream/sources.lock.toml +++ b/upstream/sources.lock.toml @@ -16,3 +16,13 @@ sha256 = "18987ec3187b5f29ba798109750f6135060560ad4e0a52678fcc753ee8fb3091" [onnxruntime.windows-x86_64-msvc] archive = "onnxruntime-win-x64-1.25.1.zip" sha256 = "33f2e8a63774811f99a5fc224cac32f4eed8c27643d46c6cc685319fa8f18019" + +[onnxruntime.supplemental-headers.custom-op-context] +path = "upstream/include/core/providers/custom_op_context.h" +url = "https://raw.githubusercontent.com/microsoft/onnxruntime/v1.25.1/include/onnxruntime/core/providers/custom_op_context.h" +sha256 = "c1f2a96c0de1978b0f2fbf60bf1b2d50c6412d487c1f5d68ac5ffa8e01b46ee4" + +[onnxruntime.supplemental-headers.resource] +path = "upstream/include/core/providers/resource.h" +url = "https://raw.githubusercontent.com/microsoft/onnxruntime/v1.25.1/include/onnxruntime/core/providers/resource.h" +sha256 = "65480b7886a180f09f40999aaead120e41cb872b2efa187938d610bfe1977473" From 2c3495fb2f6a108404871aaee996b1b104635e0a Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sat, 24 Oct 2026 07:27:17 +0900 Subject: [PATCH 05/11] build: validate the CPU wrapper with mcpp 2026.10.24.1 --- .github/workflows/ci.yml | 2 +- .xlings.json | 2 +- README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9432b9..ada6a72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ concurrency: cancel-in-progress: true env: - MCPP_VERSION: "2026.10.21.1" + MCPP_VERSION: "2026.10.24.1" SDK_INDEX_COMMIT: "3067e52abc0165b453ea3acac4022895ebf7d9bc" jobs: diff --git a/.xlings.json b/.xlings.json index 8475678..b914806 100644 --- a/.xlings.json +++ b/.xlings.json @@ -1 +1 @@ -{"workspace":{"xim:mcpp":"2026.10.21.1"}} +{"workspace":{"xim:mcpp":"2026.10.24.1"}} diff --git a/README.md b/README.md index 49f812b..678e312 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ names. Raw config headers can be mixed with the root module, as the tests verify ## Development -Use mcpp 2026.10.21.1 or newer. Tests exercise module-only inference, output shape +Use mcpp 2026.10.24.1 or newer. Tests exercise module-only inference, output shape and values, and header/module coexistence. `tools/generate_model.py` regenerates the checked-in model, and `tools/generate_exports.py ` regenerates exports from Clang's declaration AST. SDK source pins and the public From 576c780bfcbd792c7f4194942c90324f183a48aa Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sat, 24 Oct 2026 10:09:05 +0900 Subject: [PATCH 06/11] docs: unify the concise package README and move details into docs --- README.md | 84 +++++++++++++++++---------------------------------- docs/usage.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 57 deletions(-) create mode 100644 docs/usage.md diff --git a/README.md b/README.md index 678e312..33d6837 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,10 @@ # onnxruntime-m -ONNX Runtime **1.25.1** C and C++ APIs through `mcpplibs.mwrap` modules. -Upstream names remain unchanged: `Ort::Env`, `Ort::Session`, `Ort::Value`, and -the C API retain their original namespaces and types. +ONNX Runtime **1.25.1** C/C++ APIs through C++23 modules, preserving `Ort::` and C API names. -```toml -[dependencies."mcpplibs.mwrap"] -onnxruntime = "1.25.1" - -[target.x86_64-linux-gnu] -cxx_runtime = "toolchain-coupled" -``` - -```cpp -import mcpplibs.mwrap.onnxruntime; -Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example"); -``` +## Quick start -The Linux official SDK itself loads libstdc++. GCC applications should use the -toolchain-coupled C++ runtime shown above to share one implementation. The SDK -provider supplies its declared runtime closure; no host library search is used. - -The package depends on `compat.onnxruntime`, which supplies the matching official -CPU SDK. Initial targets are Linux x86_64 with glibc, Windows x86_64 with the MSVC -ABI, and macOS arm64. GPU execution providers, musl and MinGW require separate -SDK builds and are not supplied by this version. - -## Quickstart template +Use mcpp **2026.10.24.1**. This candidate becomes available after index publication. ```sh mcpp new inference --template mcpplibs.mwrap.onnxruntime@1.25.1 @@ -34,47 +12,39 @@ cd inference mcpp run ``` -The template contains a reproducible ONNX Identity model and verifies real CPU -inference. It needs no external model download or device. +The default template runs an embedded ONNX Identity model on the CPU and checks its output. -`import mcpplibs.mwrap.onnxruntime.macros;` exposes the API version as -`mcpplibs::mwrap::onnxruntime::macros::ORT_API_VERSION`. Original preprocessing -macros, including `ORT_TSTR`, remain available through -`#include ` **before** imports. A preprocessing macro -still expands inside a qualified identifier; use the mapping and raw-macro forms -in separate contexts. +## Existing projects -The root also exposes the CPU provider factory, plugin EP API declarations, -`Ort::Custom` lightweight custom-op types and `onnxruntime::ProviderOptions`. -API availability does not install an execution provider that is absent from the CPU SDK. +```toml +[dependencies] +"mcpplibs.mwrap.onnxruntime" = "1.25.1" -Configuration keys follow the SDK's separate-header grouping: +[target.x86_64-linux-gnu] +cxx_runtime = "toolchain-coupled" +``` ```cpp import mcpplibs.mwrap.onnxruntime; -import mcpplibs.mwrap.onnxruntime.config; -Ort::SessionOptions options; -options.AddConfigEntry(kOrtSessionOptionsConfigDisablePrepacking, "1"); +int main() { + Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example"); + return 0; +} ``` -The config module preserves global key names and pointer types. Upstream gives -these header variables internal linkage, which GCC cannot export directly, so -the module supplies equivalent inline constants. Use either this module or the -raw config headers in a translation unit; combining both creates duplicate key -names. Raw config headers can be mixed with the root module, as the tests verify. +The Linux SDK loads libstdc++; GCC consumers use the runtime setting above to share one implementation. + +## Scope + +The official CPU SDK supports Linux x86_64 glibc, Windows x86_64 MSVC ABI and macOS arm64. +GPU providers, musl and MinGW need separate SDK builds. Provider API declarations do not install providers. -## Development +The `.config` submodule exposes configuration keys; `.macros` maps the API-version constant. +Raw macros use `` before imports. Mixing limits are documented below. -Use mcpp 2026.10.24.1 or newer. Tests exercise module-only inference, output shape -and values, and header/module coexistence. `tools/generate_model.py` regenerates -the checked-in model, and `tools/generate_exports.py ` -regenerates exports from Clang's declaration AST. SDK source pins and the public -declaration inventory live under `upstream/`. +## Documentation -For an unpublished provider, use a local `compat` index during development, then -run `mcpp test --toolchain llvm@23.1.3` and `mcpp test --toolchain gcc@16.1.0`. -`python3 tools/test_template.py --index /path/to/mcpp-index` runs the actual mcpp -template renderer and builds/runs the generated project against the candidate. +[Usage, macros and configuration](docs/usage.md) · [SDK provenance](upstream) · +[Tests](tests) · [MIT](LICENSE) -The wrapper is MIT licensed. The SDK is distributed separately with Microsoft's -MIT license and its `ThirdPartyNotices.txt`. +The SDK carries its own MIT license and `ThirdPartyNotices.txt`. diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..4c47eb2 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,82 @@ +Detailed usage and background. See the [README](../README.md) for the current candidate quickstart and support boundary. + +# onnxruntime-m + +ONNX Runtime **1.25.1** C and C++ APIs through `mcpplibs.mwrap` modules. +Upstream names remain unchanged: `Ort::Env`, `Ort::Session`, `Ort::Value`, and +the C API retain their original namespaces and types. + +```toml +[dependencies."mcpplibs.mwrap"] +onnxruntime = "1.25.1" + +[target.x86_64-linux-gnu] +cxx_runtime = "toolchain-coupled" +``` + +```cpp +import mcpplibs.mwrap.onnxruntime; +Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example"); +``` + +The Linux official SDK itself loads libstdc++. GCC applications should use the +toolchain-coupled C++ runtime shown above to share one implementation. The SDK +provider supplies its declared runtime closure; no host library search is used. + +The package depends on `compat.onnxruntime`, which supplies the matching official +CPU SDK. Initial targets are Linux x86_64 with glibc, Windows x86_64 with the MSVC +ABI, and macOS arm64. GPU execution providers, musl and MinGW require separate +SDK builds and are not supplied by this version. + +## Quickstart template + +```sh +mcpp new inference --template mcpplibs.mwrap.onnxruntime@1.25.1 +cd inference +mcpp run +``` + +The template contains a reproducible ONNX Identity model and verifies real CPU +inference. It needs no external model download or device. + +`import mcpplibs.mwrap.onnxruntime.macros;` exposes the API version as +`mcpplibs::mwrap::onnxruntime::macros::ORT_API_VERSION`. Original preprocessing +macros, including `ORT_TSTR`, remain available through +`#include ` **before** imports. A preprocessing macro +still expands inside a qualified identifier; use the mapping and raw-macro forms +in separate contexts. + +The root also exposes the CPU provider factory, plugin EP API declarations, +`Ort::Custom` lightweight custom-op types and `onnxruntime::ProviderOptions`. +API availability does not install an execution provider that is absent from the CPU SDK. + +Configuration keys follow the SDK's separate-header grouping: + +```cpp +import mcpplibs.mwrap.onnxruntime; +import mcpplibs.mwrap.onnxruntime.config; +Ort::SessionOptions options; +options.AddConfigEntry(kOrtSessionOptionsConfigDisablePrepacking, "1"); +``` + +The config module preserves global key names and pointer types. Upstream gives +these header variables internal linkage, which GCC cannot export directly, so +the module supplies equivalent inline constants. Use either this module or the +raw config headers in a translation unit; combining both creates duplicate key +names. Raw config headers can be mixed with the root module, as the tests verify. + +## Development + +Use mcpp 2026.10.24.1 or newer. Tests exercise module-only inference, output shape +and values, and header/module coexistence. `tools/generate_model.py` regenerates +the checked-in model, and `tools/generate_exports.py ` +regenerates exports from Clang's declaration AST. SDK source pins and the public +declaration inventory live under `upstream/`. + +For an unpublished provider, use a local `compat` index during development, then +run `mcpp test --toolchain llvm@23.1.3` and `mcpp test --toolchain gcc@16.1.0`. +`python3 tools/test_template.py --index /path/to/mcpp-index` runs the actual mcpp +template renderer and builds/runs the generated project against the candidate. + +The wrapper is MIT licensed. The SDK is distributed separately with Microsoft's +MIT license and its `ThirdPartyNotices.txt`. From 15dbfdf6798781899709fbbe02b84b66a04b401c Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 25 Oct 2026 07:09:43 +0900 Subject: [PATCH 07/11] feat: unify mwrap identity and upstream-aligned first release --- .../2026-10-25-unified-mwrap-checkpoint.md | 8 +++ .github/workflows/ci.yml | 3 ++ .github/workflows/release.yml | 49 +++++++++++++++++++ README.md | 40 ++++++--------- README.zh.md | 40 +++++++++++++++ mcpp.toml | 1 + tools/check_mwrap_release.py | 33 +++++++++++++ 7 files changed, 149 insertions(+), 25 deletions(-) create mode 100644 .agents/docs/2026-10-25-unified-mwrap-checkpoint.md create mode 100644 .github/workflows/release.yml create mode 100644 README.zh.md create mode 100644 tools/check_mwrap_release.py diff --git a/.agents/docs/2026-10-25-unified-mwrap-checkpoint.md b/.agents/docs/2026-10-25-unified-mwrap-checkpoint.md new file mode 100644 index 0000000..030f98b --- /dev/null +++ b/.agents/docs/2026-10-25-unified-mwrap-checkpoint.md @@ -0,0 +1,8 @@ +# Unified mwrap first release + +Package/module: `mcpplibs.mwrap.onnxruntime`; upstream version: `1.25.1`. + +This checkpoint migrates wrapper identity while retaining upstream API names and SDK sources. +Default README is English with a mandatory Chinese counterpart; original section order is preserved. +Validation and release evidence are recorded in the PR and the index ecosystem ledger. +No old release tag or source resource is rewritten. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ada6a72..9344096 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Mwrap identity and bilingual README contract + run: python3 tools/check_mwrap_release.py + - name: Checkout the candidate SDK provider uses: actions/checkout@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f0c6447 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,49 @@ +name: Release +on: + push: + tags: ["mwrap-*"] +permissions: + contents: read +jobs: + publish: + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: write + actions: read + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Check tag, upstream version and bilingual entry pages + run: python3 tools/check_mwrap_release.py --tag "$GITHUB_REF_NAME" + - name: Require successful source CI at this exact commit + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + result=$(gh run list --repo "$GITHUB_REPOSITORY" --workflow ci.yml --commit "$GITHUB_SHA" --limit 1 --json status,conclusion --jq '.[0] | .status == "completed" and .conclusion == "success"') + test "$result" = true || { echo 'No successful source CI at the tag commit'; exit 1; } + - name: Build immutable source asset and publish + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + version="${GITHUB_REF_NAME#mwrap-}" + repo="${GITHUB_REPOSITORY#*/}" + asset="${repo}-${version}.tar.gz" + git archive --format=tar.gz --prefix="${repo}-${version}/" "$GITHUB_SHA" > "$RUNNER_TEMP/$asset" + (cd "$RUNNER_TEMP" && sha256sum "$asset" > "$asset.sha256") + if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then + echo 'Release already exists; refusing to change immutable assets'; exit 1 + fi + extra=() + if [[ "$version" == *-rc* ]]; then extra+=(--prerelease); fi + gh release create "$GITHUB_REF_NAME" "$RUNNER_TEMP/$asset" "$RUNNER_TEMP/$asset.sha256" \ + --repo "$GITHUB_REPOSITORY" --verify-tag --title "$repo $version" \ + --notes "Module wrapper for upstream $version. New mwrap package identities become installable after mcpp-index publication; see the bilingual README for the tested support scope." "${extra[@]}" diff --git a/README.md b/README.md index 33d6837..9a4ca2c 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # onnxruntime-m -ONNX Runtime **1.25.1** C/C++ APIs through C++23 modules, preserving `Ort::` and C API names. +> ONNX Runtime 1.25.1 C/C++ APIs as C++23 modules; Ort:: names are preserved. -## Quick start +**English** · [简体中文](README.zh.md) + +Use mcpp **2026.10.24.1**. The new mwrap identity becomes installable after index publication. -Use mcpp **2026.10.24.1**. This candidate becomes available after index publication. +## Quick start ```sh mcpp new inference --template mcpplibs.mwrap.onnxruntime@1.25.1 @@ -12,39 +14,27 @@ cd inference mcpp run ``` -The default template runs an embedded ONNX Identity model on the CPU and checks its output. - -## Existing projects - ```toml [dependencies] -"mcpplibs.mwrap.onnxruntime" = "1.25.1" - -[target.x86_64-linux-gnu] -cxx_runtime = "toolchain-coupled" +mcpplibs.mwrap.onnxruntime = "1.25.1" ``` +## Existing projects + ```cpp import mcpplibs.mwrap.onnxruntime; -int main() { - Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example"); - return 0; -} +int main() { Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example"); } ``` -The Linux SDK loads libstdc++; GCC consumers use the runtime setting above to share one implementation. +Linux GCC consumers set `cxx_runtime = "toolchain-coupled"` in `[target.x86_64-linux-gnu]` for the SDK exception runtime. ## Scope -The official CPU SDK supports Linux x86_64 glibc, Windows x86_64 MSVC ABI and macOS arm64. -GPU providers, musl and MinGW need separate SDK builds. Provider API declarations do not install providers. - -The `.config` submodule exposes configuration keys; `.macros` maps the API-version constant. -Raw macros use `` before imports. Mixing limits are documented below. +Official CPU SDK: Linux x86_64 glibc, Windows x86_64 MSVC ABI, macOS ARM64. +GPU, musl and MinGW need separate SDKs. The template executes an embedded Identity model. +`.config` exposes configuration keys; `.macros` maps API version. Text macros use `` before imports. ## Documentation -[Usage, macros and configuration](docs/usage.md) · [SDK provenance](upstream) · -[Tests](tests) · [MIT](LICENSE) - -The SDK carries its own MIT license and `ThirdPartyNotices.txt`. +[Usage and mixing limits](docs/usage.md) · [SDK provenance](upstream) · [Tests](tests) · [MIT](LICENSE) +The SDK retains its MIT license and ThirdPartyNotices.txt. diff --git a/README.zh.md b/README.zh.md new file mode 100644 index 0000000..0b5205b --- /dev/null +++ b/README.zh.md @@ -0,0 +1,40 @@ +# onnxruntime-m + +> ONNX Runtime 1.25.1 C/C++ API 的 C++23 模块封装,保留 Ort:: 名称。 + +[English](README.md) · **简体中文** + +使用 mcpp **2026.10.24.1**。新 mwrap 身份在索引发布后可直接安装。 + +## 快速开始 + +```sh +mcpp new inference --template mcpplibs.mwrap.onnxruntime@1.25.1 +cd inference +mcpp run +``` + +```toml +[dependencies] +mcpplibs.mwrap.onnxruntime = "1.25.1" +``` + +## 已有项目 + +```cpp +import mcpplibs.mwrap.onnxruntime; +int main() { Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example"); } +``` + +Linux GCC 消费者在 `[target.x86_64-linux-gnu]` 设置 `cxx_runtime = "toolchain-coupled"`,共享 SDK 异常运行时。 + +## 支持范围 + +官方 CPU SDK:Linux x86_64 glibc、Windows x86_64 MSVC ABI、macOS ARM64。 +GPU、musl、MinGW 需要独立 SDK;模板实际执行内嵌 Identity 模型。 +`.config` 导出配置键,`.macros` 映射 API 版本;文本宏在 import 前包含 ``。 + +## 文档 + +[使用与混用限制](docs/usage.md) · [SDK 来源](upstream) · [测试](tests) · [MIT](LICENSE) +SDK 保留 MIT 许可证与 ThirdPartyNotices.txt。 diff --git a/mcpp.toml b/mcpp.toml index 302bc28..4ecfad4 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,3 +1,4 @@ +# Module wrapper; upstream API preserved. Policy: mcpp-index/docs/mwrap.md. [package] namespace = "mcpplibs.mwrap" name = "onnxruntime" diff --git a/tools/check_mwrap_release.py b/tools/check_mwrap_release.py new file mode 100644 index 0000000..4dde1a9 --- /dev/null +++ b/tools/check_mwrap_release.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +"""Check the immutable mwrap release coordinate and bilingual entry pages.""" +import argparse +from pathlib import Path +import re +import tomllib + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--tag', help='release tag; omitted during PR checks') + args = parser.parse_args() + root = Path(__file__).resolve().parents[1] + package = tomllib.loads((root / 'mcpp.toml').read_text())['package'] + assert package['namespace'] == 'mcpplibs.mwrap', package + assert re.fullmatch(r'[A-Za-z_][A-Za-z_0-9]*', package['name']), package['name'] + upstream = package['metadata']['mwrap']['upstream-version'] + version = package['version'] + assert version == upstream or re.fullmatch(re.escape(upstream) + r'\.[1-9][0-9]*', version), (version, upstream) + if args.tag: + assert args.tag == 'mwrap-' + version, (args.tag, version) + identity = package['namespace'] + '.' + package['name'] + for name, other in [('README.md', 'README.zh.md'), ('README.zh.md', 'README.md')]: + text = (root / name).read_text() + assert len(text.splitlines()) <= 100, name + assert '](' + other + ')' in '\n'.join(text.splitlines()[:12]), name + assert identity in text and version in text, name + assert text.count('```') % 2 == 0, name + print(identity + '@' + version) + + +if __name__ == '__main__': + main() From a20def5e72c167a604045218c0f688e04f36611b Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 25 Oct 2026 07:13:18 +0900 Subject: [PATCH 08/11] fix(ci): read bilingual metadata explicitly as UTF-8 --- tools/check_mwrap_release.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/check_mwrap_release.py b/tools/check_mwrap_release.py index 4dde1a9..9222469 100644 --- a/tools/check_mwrap_release.py +++ b/tools/check_mwrap_release.py @@ -11,7 +11,7 @@ def main(): parser.add_argument('--tag', help='release tag; omitted during PR checks') args = parser.parse_args() root = Path(__file__).resolve().parents[1] - package = tomllib.loads((root / 'mcpp.toml').read_text())['package'] + package = tomllib.loads((root / 'mcpp.toml').read_text(encoding="utf-8"))['package'] assert package['namespace'] == 'mcpplibs.mwrap', package assert re.fullmatch(r'[A-Za-z_][A-Za-z_0-9]*', package['name']), package['name'] upstream = package['metadata']['mwrap']['upstream-version'] @@ -21,7 +21,7 @@ def main(): assert args.tag == 'mwrap-' + version, (args.tag, version) identity = package['namespace'] + '.' + package['name'] for name, other in [('README.md', 'README.zh.md'), ('README.zh.md', 'README.md')]: - text = (root / name).read_text() + text = (root / name).read_text(encoding="utf-8") assert len(text.splitlines()) <= 100, name assert '](' + other + ')' in '\n'.join(text.splitlines()[:12]), name assert identity in text and version in text, name From bcb8dddc23e3804596aba3547ef69947fddbb7c4 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 25 Oct 2026 07:31:36 +0900 Subject: [PATCH 09/11] docs: apply concise bilingual mwrap README layout --- README.md | 2 +- README.zh.md | 2 +- tools/check_mwrap_release.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9a4ca2c..7a1c66d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ **English** · [简体中文](README.zh.md) -Use mcpp **2026.10.24.1**. The new mwrap identity becomes installable after index publication. +Upstream: [microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) ## Quick start diff --git a/README.zh.md b/README.zh.md index 0b5205b..4c723c2 100644 --- a/README.zh.md +++ b/README.zh.md @@ -4,7 +4,7 @@ [English](README.md) · **简体中文** -使用 mcpp **2026.10.24.1**。新 mwrap 身份在索引发布后可直接安装。 +上游仓库:[microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) ## 快速开始 diff --git a/tools/check_mwrap_release.py b/tools/check_mwrap_release.py index 9222469..227fd8d 100644 --- a/tools/check_mwrap_release.py +++ b/tools/check_mwrap_release.py @@ -22,7 +22,7 @@ def main(): identity = package['namespace'] + '.' + package['name'] for name, other in [('README.md', 'README.zh.md'), ('README.zh.md', 'README.md')]: text = (root / name).read_text(encoding="utf-8") - assert len(text.splitlines()) <= 100, name + assert len(text.splitlines()) <= 150, name assert '](' + other + ')' in '\n'.join(text.splitlines()[:12]), name assert identity in text and version in text, name assert text.count('```') % 2 == 0, name From 2fdd686f73945a54379525025ddcc0ef8e06281f Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 25 Oct 2026 07:36:16 +0900 Subject: [PATCH 10/11] docs: standardize navigation and introductory layout --- README.md | 6 ++++-- README.zh.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7a1c66d..7a03f23 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,11 @@ > ONNX Runtime 1.25.1 C/C++ APIs as C++23 modules; Ort:: names are preserved. -**English** · [简体中文](README.zh.md) +**English** · [简体中文](README.zh.md) · Upstream: [microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) · [Releases](https://github.com/mcpplibs/onnxruntime-m/releases) · [mcpp](https://github.com/mcpp-community/mcpp) · [Index](https://github.com/mcpplibs/mcpp-index) -Upstream: [microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) +[![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![CI](https://github.com/mcpplibs/onnxruntime-m/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mcpplibs/onnxruntime-m/actions/workflows/ci.yml) ## Quick start diff --git a/README.zh.md b/README.zh.md index 4c723c2..5772f7d 100644 --- a/README.zh.md +++ b/README.zh.md @@ -2,9 +2,11 @@ > ONNX Runtime 1.25.1 C/C++ API 的 C++23 模块封装,保留 Ort:: 名称。 -[English](README.md) · **简体中文** +[English](README.md) · **简体中文** · 上游:[microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) · [Releases](https://github.com/mcpplibs/onnxruntime-m/releases) · [mcpp](https://github.com/mcpp-community/mcpp) · [Index](https://github.com/mcpplibs/mcpp-index) -上游仓库:[microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) +[![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![CI](https://github.com/mcpplibs/onnxruntime-m/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mcpplibs/onnxruntime-m/actions/workflows/ci.yml) ## 快速开始 From 45073fc979c8091f9d94988ea973e634fa5728ff Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 25 Oct 2026 07:42:55 +0900 Subject: [PATCH 11/11] docs: lead quickstarts with core module imports and uniform upstream links --- README.md | 10 +++++++++- README.zh.md | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a03f23..27e9798 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,20 @@ > ONNX Runtime 1.25.1 C/C++ APIs as C++23 modules; Ort:: names are preserved. -**English** · [简体中文](README.zh.md) · Upstream: [microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) · [Releases](https://github.com/mcpplibs/onnxruntime-m/releases) · [mcpp](https://github.com/mcpp-community/mcpp) · [Index](https://github.com/mcpplibs/mcpp-index) +**English** · [简体中文](README.zh.md) · [Upstream](https://github.com/microsoft/onnxruntime) · [Releases](https://github.com/mcpplibs/onnxruntime-m/releases) · [mcpp](https://github.com/mcpp-community/mcpp) · [Index](https://github.com/mcpplibs/mcpp-index) [![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![CI](https://github.com/mcpplibs/onnxruntime-m/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mcpplibs/onnxruntime-m/actions/workflows/ci.yml) +## Modules + +- `import mcpplibs.mwrap.onnxruntime;`: Ort:: and C inference APIs +- `import mcpplibs.mwrap.onnxruntime.config;`: Session and runtime configuration keys +- `import mcpplibs.mwrap.onnxruntime.macros;`: API-version macro mappings + +> More Modules API -> [Usage and API](docs/usage.md) + ## Quick start ```sh diff --git a/README.zh.md b/README.zh.md index 5772f7d..f1823cb 100644 --- a/README.zh.md +++ b/README.zh.md @@ -2,12 +2,20 @@ > ONNX Runtime 1.25.1 C/C++ API 的 C++23 模块封装,保留 Ort:: 名称。 -[English](README.md) · **简体中文** · 上游:[microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) · [Releases](https://github.com/mcpplibs/onnxruntime-m/releases) · [mcpp](https://github.com/mcpp-community/mcpp) · [Index](https://github.com/mcpplibs/mcpp-index) +[English](README.md) · **简体中文** · [Upstream](https://github.com/microsoft/onnxruntime) · [Releases](https://github.com/mcpplibs/onnxruntime-m/releases) · [mcpp](https://github.com/mcpp-community/mcpp) · [Index](https://github.com/mcpplibs/mcpp-index) [![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![CI](https://github.com/mcpplibs/onnxruntime-m/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mcpplibs/onnxruntime-m/actions/workflows/ci.yml) +## 模块 + +- `import mcpplibs.mwrap.onnxruntime;`: Ort:: 与 C 推理 API +- `import mcpplibs.mwrap.onnxruntime.config;`: 会话与运行时配置键 +- `import mcpplibs.mwrap.onnxruntime.macros;`: API 版本宏映射 + +> More Modules API -> [模块与 API](docs/usage.md) + ## 快速开始 ```sh