feat(ecosystem): compliant Praxis/Hexis integration + vendored build
Bring the Nexus/Praxis/Hexis integration in line with MAVEN_ECOSYSTEM_ARCHITECTURE.md: - Praxis over HTTP: drop the in-process praxis.db open (praxisstore/ praxistools) and call praxisd's /api/v1/tools/* API via a new praxisClient. Honors the "no component reads another's DB" invariant (AC#12). PraxisConfig.DBPath -> URL. - Hexis confirmation gate: mutating capabilities (ReadOnly=false) now park a bound pendingHexis confirmation and require a spoken "да" before executing; read-only run immediately (AC#7, no auto attention->action). - Capability safety: >1 verb match is ambiguous -> ask instead of firing the first; ambiguous Nexus resolution asks for clarification (AC#2). - Correlation IDs on Hexis execute, recorded in the cross-service trace. - Bug: importance arrives as JSON float64 over HTTP, not int. - Tests: confirm-gate, decline, read-only, and ambiguity paths. Build: vendor/ bakes in the hexis client (replace-directed at a sibling repo outside the Docker context); Dockerfile builds from vendor and no longer `go mod download`s the unreachable replace paths. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+219
@@ -0,0 +1,219 @@
|
||||
Cross-Platform `onnxruntime` Wrapper for Go
|
||||
===========================================
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
This library seeks to provide an interface for loading and executing neural
|
||||
networks from Go(lang) code, while remaining as simple to use as possible.
|
||||
|
||||
A few example applications using this library can be found in the
|
||||
[`onnxruntime_go_examples` repository](https://github.com/yalue/onnxruntime_go_examples).
|
||||
|
||||
The [onnxruntime](https://github.com/microsoft/onnxruntime) library provides a
|
||||
way to load and execute ONNX-format neural networks, though the library
|
||||
primarily supports C and C++ APIs. Several efforts exist to have written
|
||||
Go(lang) wrappers for the `onnxruntime` library, but as far as I can tell, none
|
||||
of these existing Go wrappers support Windows. This is due to the fact that
|
||||
Microsoft's `onnxruntime` library assumes the user will be using the MSVC
|
||||
compiler on Windows systems, while CGo on Windows requires using Mingw.
|
||||
|
||||
This wrapper works around the issues by manually loading the `onnxruntime`
|
||||
shared library, removing any dependency on the `onnxruntime` source code beyond
|
||||
the header files. Naturally, this approach works equally well on non-Windows
|
||||
systems.
|
||||
|
||||
Additionally, this library uses Go's recent addition of generics to support
|
||||
multiple Tensor data types; see the `NewTensor` or `NewEmptyTensor` functions.
|
||||
|
||||
Several accelerated execution providers (including TensorRT, CUDA and CoreML)
|
||||
are tested and confirmed to work with `onnxruntime_go`. The "Requirements"
|
||||
portion of this README (below) has a few more details.
|
||||
|
||||
|
||||
Note on onnxruntime Library Versions
|
||||
------------------------------------
|
||||
|
||||
At the time of writing, this library uses version 1.26.0 of the onnxruntime
|
||||
C API headers. So, it will probably only work with version 1.26.0 of the
|
||||
onnxruntime shared libraries, as well. If you need to use a different version,
|
||||
or if I get behind on updating this repository, updating or changing the
|
||||
onnxruntime version should be fairly easy:
|
||||
|
||||
1. Replace the `onnxruntime_c_api.h` and `onnxruntime_ep_c_api.h` files with
|
||||
the versions corresponding to the onnxruntime version you wish to use.
|
||||
|
||||
2. Replace the `test_data/onnxruntime.dll` (or `test_data/onnxruntime*.so`,
|
||||
`test_data/onnxruntime*.dylib`) file with the version corresponding to the
|
||||
onnxruntime version you wish to use.
|
||||
|
||||
3. (If you care about DirectML support) Verify that the entries in the
|
||||
`DummyOrtDMLAPI` struct in `onnxruntime_wrapper.c` match the order in which
|
||||
they appear in the `OrtDmlApi` struct from the `dml_provider_factory.h`
|
||||
header in the official repo. See the comment on this struct in
|
||||
`onnxruntime_wrapper.c` for more information.
|
||||
|
||||
Note that both the C API headers and the shared library files are available to
|
||||
download from the releases page in the
|
||||
[official repo](https://github.com/microsoft/onnxruntime). Download the archive
|
||||
for the release you want to use, and extract it. The header files are located
|
||||
in the "include" subdirectory, and the shared library will be located in the
|
||||
"lib" subdirectory. (On Linux systems, you'll need the version of the .so with
|
||||
the appended version numbers, e.g., `libonnxruntime.so.1.26.0`, and _not_ the
|
||||
`libonnxruntime.so`, which is just a symbolic link.) The archive will contain
|
||||
several other files containing C++ headers, debug symbols, and so on, but you
|
||||
shouldn't need anything other than the single onnxruntime shared library and
|
||||
the two `_c_api.h` header files. (The exception is if you're wanting to enable
|
||||
GPU support, where you may need other shared-library files, such as
|
||||
`execution_providers_cuda.dll` and `execution_providers_shared.dll` (or their
|
||||
equivalents for Linux or OSX).
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
To use this library, you'll need a version of Go with cgo support. You'll also
|
||||
need a copy of the correct version of the onnxruntime shared library or DLL for
|
||||
your operating system and architecture. Prior to initializing
|
||||
`onnxruntime_go`, you need to provide a path to this shared library. See the
|
||||
first couple lines (i.e., `ort.SetSharedLibraryPath(...)`) of the following
|
||||
example.
|
||||
|
||||
If you want to use CUDA, you'll need to be using a version of the onnxruntime
|
||||
shared library with CUDA support, as well as be using a CUDA version supported
|
||||
by the underlying version of your onnxruntime library. For example, version
|
||||
1.23.2 of the onnxruntime library only supports CUDA versions 12.x. See
|
||||
[the onnxruntime CUDA support documentation](https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html)
|
||||
for more specifics.
|
||||
|
||||
Similarly to CUDA, other execution providers have their own separate
|
||||
requirements. All of these requirements are too numerous to document in this
|
||||
README. Please ensure that you are successfully able to use your execution
|
||||
provider of choice in a python script before raising issues about it here.
|
||||
|
||||
|
||||
Example Usage
|
||||
-------------
|
||||
|
||||
The full documentation can be found at [pkg.go.dev](https://pkg.go.dev/github.com/yalue/onnxruntime_go).
|
||||
|
||||
Additionally, several example command-line applications complete with necessary
|
||||
networks and data can be found in the
|
||||
[`onnxruntime_go_examples` repository](https://github.com/yalue/onnxruntime_go_examples).
|
||||
|
||||
The following example illustrates how this library can be used to load and run
|
||||
an ONNX network taking a single input tensor and producing a single output
|
||||
tensor, both of which contain 32-bit floating point values. Note that error
|
||||
handling is omitted; each of the functions returns an err value, which will be
|
||||
non-nil in the case of failure.
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
ort "github.com/yalue/onnxruntime_go"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// This line _may_ be optional; by default the library will try to load
|
||||
// "onnxruntime.dll" on Windows, and "onnxruntime.so" on any other system.
|
||||
// For stability, programs should always set this explicitly.
|
||||
ort.SetSharedLibraryPath("path/to/onnxruntime.so")
|
||||
|
||||
err := ort.InitializeEnvironment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer ort.DestroyEnvironment()
|
||||
|
||||
// For a slight performance boost and convenience when re-using existing
|
||||
// tensors, this library expects the user to create all input and output
|
||||
// tensors prior to creating the session. If this isn't ideal for your use
|
||||
// case, see the DynamicAdvancedSession type in the documnentation, which
|
||||
// allows input and output tensors to be specified when calling Run()
|
||||
// rather than when initializing a session.
|
||||
inputData := []float32{0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}
|
||||
inputShape := ort.NewShape(2, 5)
|
||||
inputTensor, err := ort.NewTensor(inputShape, inputData)
|
||||
defer inputTensor.Destroy()
|
||||
// This hypothetical network maps a 2x5 input -> 2x3x4 output.
|
||||
outputShape := ort.NewShape(2, 3, 4)
|
||||
outputTensor, err := ort.NewEmptyTensor[float32](outputShape)
|
||||
defer outputTensor.Destroy()
|
||||
|
||||
session, err := ort.NewAdvancedSession("path/to/network.onnx",
|
||||
[]string{"Input 1 Name"}, []string{"Output 1 Name"},
|
||||
[]ort.Value{inputTensor}, []ort.Value{outputTensor}, nil)
|
||||
defer session.Destroy()
|
||||
|
||||
// Calling Run() will run the network, reading the current contents of the
|
||||
// input tensors and modifying the contents of the output tensors.
|
||||
err = session.Run()
|
||||
|
||||
// Get a slice view of the output tensor's data.
|
||||
outputData := outputTensor.GetData()
|
||||
|
||||
// If you want to run the network on a different input, all you need to do
|
||||
// is modify the input tensor data (available via inputTensor.GetData())
|
||||
// and call Run() again.
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Deprecated APIs
|
||||
---------------
|
||||
|
||||
**Typed `Session[t]`:** Older versions of this library used a typed
|
||||
`Session[T]` struct to keep track of sessions. In retrospect, associating type
|
||||
parameters with Sessions was unnecessary, and the `AdvancedSession` type, along
|
||||
with its associated APIs, was added to rectify this mistake. For backwards
|
||||
compatibility, the old typed `Session[T]` and `DynamicSession[T]` types are
|
||||
still included and unlikely to be removed. However, they now delegate their
|
||||
functionality to `AdvancedSession` internally. New code should always favor
|
||||
using `AdvancedSession` directly.
|
||||
|
||||
**Onnxruntime's training API:** The training API has been deprecated as of
|
||||
onnxruntime version 1.20. Rather than continuing to maintain wrappers for a
|
||||
deprecated API, `onnxruntime_go` has replaced the wrapper functions for the
|
||||
training API with stubs that return an error. Users who need to continue to
|
||||
use the training API will need to use an older version. For example the
|
||||
following versions should be compatible with training:
|
||||
|
||||
- Version `v1.12.1` of `onnxruntime_go`, and
|
||||
- Version 1.19.2 of `onnxruntime`.
|
||||
|
||||
|
||||
Running Tests and System Compatibility for Testing
|
||||
--------------------------------------------------
|
||||
|
||||
Navigate to this directory and run `go test -v`, or optionally
|
||||
`go test -v -bench=.`. All tests should pass; tests relating to CUDA or other
|
||||
accelerator support will be skipped on systems or onnxruntime builds that don't
|
||||
support them.
|
||||
|
||||
Currently, this repository includes a copy of the onnxruntime shared libraries
|
||||
for a few systems, including AMD64 windows, ARM64 Linux, and ARM64 darwin.
|
||||
These should allow tests to pass on those systems without users needing to copy
|
||||
additional libraries beyond cloning this repository. In the future, however,
|
||||
this may change if support for more systems are added or removed.
|
||||
|
||||
You may want to use a different version of the `onnxruntime` shared library for
|
||||
a couple reasons. In particular:
|
||||
|
||||
1. The included shared library copies do not include support for CUDA or other
|
||||
accelerated execution providers, so CUDA-related tests will always be
|
||||
skipped if you use the default libraries in this repo.
|
||||
|
||||
2. Many systems, including AMD64 and i386 Linux, and x86 osx, do not currently
|
||||
have shared libraries included in `test_data/` in the first place. (I would
|
||||
like to keep this directory, and the overall repo, smaller by keeping the
|
||||
number of shared libraries small.)
|
||||
|
||||
If these or other reasons apply to you, the test code will check the
|
||||
`ONNXRUNTIME_SHARED_LIBRARY_PATH` environment variable before attempting to
|
||||
load a library from `test_data/`. So, if you are using one of these systems or
|
||||
want accelerator-related tests to run, you should set the environment variable
|
||||
to the path to the onnxruntime shared library. Afterwards, `go test -v` should
|
||||
run and pass.
|
||||
Reference in New Issue
Block a user