From 58ba1d58df0ecd10a69ac0f880873639ef86ba44 Mon Sep 17 00:00:00 2001 From: Hank Donnay Date: Thu, 29 May 2025 11:31:02 -0500 Subject: [PATCH] magika: add ml-based content type detection Signed-off-by: Hank Donnay --- detector/magika/_cmd/ortgen/go.mod | 14 + detector/magika/_cmd/ortgen/go.sum | 22 ++ detector/magika/_cmd/ortgen/ortgen.go | 246 ++++++++++++ detector/magika/magika.go | 281 ++++++++++++++ detector/magika/magika_test.go | 171 +++++++++ detector/magika/ort.go | 299 +++++++++++++++ detector/magika/ort_types.go | 529 ++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 + 9 files changed, 1565 insertions(+) create mode 100644 detector/magika/_cmd/ortgen/go.mod create mode 100644 detector/magika/_cmd/ortgen/go.sum create mode 100644 detector/magika/_cmd/ortgen/ortgen.go create mode 100644 detector/magika/magika.go create mode 100644 detector/magika/magika_test.go create mode 100644 detector/magika/ort.go create mode 100644 detector/magika/ort_types.go diff --git a/detector/magika/_cmd/ortgen/go.mod b/detector/magika/_cmd/ortgen/go.mod new file mode 100644 index 000000000..ba980b95f --- /dev/null +++ b/detector/magika/_cmd/ortgen/go.mod @@ -0,0 +1,14 @@ +module ortgen + +go 1.24.3 + +require modernc.org/cc/v4 v4.27.1 + +require ( + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/opt v0.1.4 // indirect + modernc.org/sortutil v1.2.1 // indirect + modernc.org/strutil v1.2.1 // indirect + modernc.org/token v1.1.0 // indirect +) diff --git a/detector/magika/_cmd/ortgen/go.sum b/detector/magika/_cmd/ortgen/go.sum new file mode 100644 index 000000000..4f05d01cb --- /dev/null +++ b/detector/magika/_cmd/ortgen/go.sum @@ -0,0 +1,22 @@ +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis= +modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccorpus2 v1.5.2 h1:Ui+4tc58mf/W+2arcYCJR903y3zl3ecsI7Fpaaqozyw= +modernc.org/ccorpus2 v1.5.2/go.mod h1:Wifvo4Q/qS/h1aRoC2TffcHsnxwTikmi1AuLANuucJQ= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= +modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/detector/magika/_cmd/ortgen/ortgen.go b/detector/magika/_cmd/ortgen/ortgen.go new file mode 100644 index 000000000..6cdc21d23 --- /dev/null +++ b/detector/magika/_cmd/ortgen/ortgen.go @@ -0,0 +1,246 @@ +// Ortgen is a helper program to generate type information from the ONNX Runtime +// release tarball. +package main + +import ( + "archive/tar" + "bufio" + "bytes" + "compress/gzip" + "context" + "flag" + "fmt" + "io" + "io/fs" + "log/slog" + "net/http" + "os" + "path/filepath" + "strconv" + "strings" + "text/template" + + "modernc.org/cc/v4" +) + +const urlTmpl = "https://github.com/microsoft/onnxruntime/releases/download/v{{.}}/onnxruntime-linux-x64-{{.}}.tgz" + +func main() { + var code int + defer func() { + if code != 0 { + os.Exit(code) + } + }() + var out *os.File + tmpl := template.Must(template.New(`url`).Parse(urlTmpl)) + var loglevel slog.LevelVar + loglevel.Set(slog.LevelError) + slog.SetDefault(slog.New(slog.NewTextHandler( + os.Stderr, + &slog.HandlerOptions{ + Level: &loglevel, + }))) + ctx := context.Background() + + vers := flag.String("version", `1.15.1`, "use `version` as the argument to the URL template") + flag.Func("url", "fetch ONNX Runtime release tarball from templated `URL`", func(text string) error { + if _, err := tmpl.Parse(text); err != nil { + return err + } + return nil + }) + pkg := flag.String("package", "magika", "generated package `name`") + flag.Func("o", "output to `file`", func(p string) error { + if out != nil { + if err := out.Close(); err != nil { + return err + } + } + f, err := os.Create(p) + if err != nil { + return err + } + out = f + return nil + }) + flag.BoolFunc("D", "debug log output", func(v string) error { + if ok, err := strconv.ParseBool(v); err == nil && ok { + loglevel.Set(slog.LevelDebug) + } + return nil + }) + flag.Parse() + + var sb strings.Builder + if err := tmpl.Execute(&sb, *vers); err != nil { + slog.ErrorContext(ctx, "unexpected template error", "reason", err) + code = 1 + return + } + slog.InfoContext(ctx, "templated URL", "url", &sb) + + if out == nil { + out = os.Stdout + } + defer out.Close() + + if err := Main(ctx, out, sb.String(), *pkg); err != nil { + slog.ErrorContext(ctx, "unexpected error", "reason", err) + code = 1 + } +} + +const genHeader = `// Code generated by ortgen. DO NOT EDIT.` + +func Main(ctx context.Context, out io.Writer, in, pkg string) error { + const header = `onnxruntime_c_api.h` + dir, err := fetchTarball(ctx, in) + if err != nil { + return fmt.Errorf("fetching: %w", err) + } + defer os.RemoveAll(dir.Name()) + defer dir.Close() + + cfg, err := cc.NewConfig("linux", "amd64") + if err != nil { + return fmt.Errorf("unable to create config: %w", err) + } + ms, _ := fs.Glob(dir.FS(), `*/include/`+header) + f, err := dir.Open(ms[0]) + if err != nil { + return fmt.Errorf("unable to open header: %q: %w", ms[0], err) + } + src := []cc.Source{ + {Name: "", Value: cfg.Predefined}, + {Name: "", Value: cc.Builtin}, + {Name: "", Value: "#define bool _Bool\n"}, + {Name: header, Value: f}, + } + ast, err := cc.Translate(cfg, src) + if err != nil { + return fmt.Errorf("parse error: %w", err) + } + + fmt.Fprintf(out, "%s\n\npackage %s\n\nimport \"structs\"\n", genHeader, pkg) + // Walk the list, looking for the bits we want: + var buf bytes.Buffer + for cur := ast.TranslationUnit; cur != nil; cur = cur.TranslationUnit { + buf.Reset() + if cur.ExternalDeclaration.Case != cc.ExternalDeclarationDecl { + continue + } + decl := cur.ExternalDeclaration.Declaration + if decl.Position().Filename != header { + continue + } + spec := decl.DeclarationSpecifiers + if spec == nil || spec.Case != cc.DeclarationSpecifiersTypeSpec { + continue + } + ty := spec.TypeSpecifier + if ty == nil || ty.Case != cc.TypeSpecifierStructOrUnion { + continue + } + structSpec := ty.StructOrUnionSpecifier + if structSpec == nil || + structSpec.Case != cc.StructOrUnionSpecifierDef || + structSpec.StructOrUnion.Case != cc.StructOrUnionStruct { + continue + } + + n := structSpec.Token.SrcStr() + switch n { + case "OrtApi": + case "OrtApiBase": + default: + continue + } + fmt.Fprintf(&buf, "\ntype %s struct {\n\t_ structs.HostLayout\n\n", strings.Replace(n, "O", "o", 1)) + + for cur := structSpec.StructDeclarationList; cur != nil; cur = cur.StructDeclarationList { + buf.WriteString("\t// ") + buf.WriteString(cc.NodeSource(cur.StructDeclaration)) + buf.WriteByte('\n') + + // pull out the function pointer ident: + decl := cur.StructDeclaration.StructDeclaratorList.StructDeclarator.Declarator.DirectDeclarator.DirectDeclarator.Declarator.DirectDeclarator + buf.WriteByte('\t') + buf.Write(decl.Token.Src()) + buf.WriteString(" uintptr\n") + } + + buf.WriteString("}\n") + if _, err := io.Copy(out, &buf); err != nil { + return err + } + } + + return nil +} + +func fetchTarball(ctx context.Context, in string) (*os.Root, error) { + slog.DebugContext(ctx, "fetching tarball", "url", in) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, in, nil) + if err != nil { + return nil, err + } + res, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status: %v", res.Status) + } + defer res.Body.Close() + z, err := gzip.NewReader(res.Body) + if err != nil { + return nil, err + } + + d, err := os.MkdirTemp("", "ortgen.") + if err != nil { + return nil, err + } + slog.DebugContext(ctx, "untarring to disk", "path", d) + root, err := os.OpenRoot(d) + if err != nil { + return nil, err + } + + ok := false + defer func() { + if !ok { + os.RemoveAll(d) + root.Close() + } + }() + + rd := tar.NewReader(bufio.NewReader(z)) + h, err := rd.Next() + for ; err == nil; h, err = rd.Next() { + err := func() error { + p := filepath.Join(".", h.Name) + fi := h.FileInfo() + if fi.IsDir() { + return root.Mkdir(p, 0o755) + } + f, err := root.Create(p) + if err != nil { + return err + } + defer f.Close() + + if _, err := io.Copy(f, rd); err != nil { + return err + } + return nil + }() + if err != nil { + return nil, err + } + } + + ok = true + return root, nil +} diff --git a/detector/magika/magika.go b/detector/magika/magika.go new file mode 100644 index 000000000..dd21371ab --- /dev/null +++ b/detector/magika/magika.go @@ -0,0 +1,281 @@ +// Package magika implements bindings for the [magika] file type detector. +// +// The model runs on the [ONNX Runtime]; the ONNX Runtime libraries are required +// and will be dynamically loaded as needed. +// +// [magika]: https://github.com/google/magika/ +// [ONNX Runtime]: https://onnxruntime.ai/ +package magika + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/fs" + "path" +) + +// LoadModel loads the named model from the provided [fs.FS]. +// +// The FS is assumed to be structured like the upstream repository's "assets" +// folder. +func LoadModel(sys fs.FS, name string) (*Model, error) { + ct, err := LoadContentTypes(sys) + if err != nil { + return nil, err + } + + config, err := LoadConfig(sys, name) + if err != nil { + return nil, err + } + + p := path.Join(`models`, name, `model.onnx`) + model, err := fs.ReadFile(sys, p) + if err != nil { + return nil, err + } + + api, err := getAPI() + if err != nil { + return nil, err + } + session, err := api.CreateSession(model) + if err != nil { + return nil, err + } + + m := Model{ + ct: ct, + config: config, + model: model, + session: session, + } + return &m, nil +} + +// Model is a loaded magika model. +// +// This type should provide the same concurrency guarantees as the underlying +// [OrtSession] type. +// +// [OrtSession]: https://onnxruntime.ai/docs/api/c/group___global.html#ga5220ca3b3f0a31a01a3f15057c35cac6 +type Model struct { + ct map[string]*ContentType + config *Config + // I don't think the C-side session object copies the model data, so keep + // the slice around. + model []byte + session *session +} + +// Scan extracts features from the provided [io.ReaderAt] and runs the model, +// reporting the highest confidence result. +func (m *Model) Scan(r io.ReaderAt, size int64) (*ContentType, error) { + if size == 0 { + return m.ct[contentTypeLabelEmpty], nil + } + + features, err := m.config.Features(r, size) + if err != nil { + return nil, err + } + scores, err := m.session.Run(features, len(m.config.TargetLabelsSpace)) + if err != nil { + return nil, err + } + best := 0 + for i, v := range scores { + if v > scores[best] { + best = i + } + } + score := scores[best] + l := m.config.TargetLabelsSpace[best] + ct, ok := m.ct[l] + if !ok { + return nil, fmt.Errorf("no content type found for %q", l) + } + th := m.config.MediumConfidenceThreshold + if t, ok := m.config.Thresholds[l]; ok { + th = t + } + + // Return the inferred content type if the threshold is met, otherwise + // falls back to a relevant default. + switch { + case score >= th: + return ct, nil + case ct.IsText: + return m.ct[contentTypeLabelText], nil + default: + return m.ct[contentTypeLabelUnknown], nil + } +} + +// LoadConfig loads the configuration of the named model from the provided +// [fs.FS]. +// +// The FS is assumed to be structured like the upstream repository's "assets" +// folder. +func LoadConfig(sys fs.FS, name string) (*Config, error) { + p := path.Join(`models`, name, `config.min.json`) + f, err := sys.Open(p) + if err != nil { + return nil, err + } + defer f.Close() + + var cfg Config + if err := json.NewDecoder(f).Decode(&cfg); err != nil { + return nil, err + } + return &cfg, nil +} + +// Config is the model configuration. +type Config struct { + BegSize int `json:"beg_size"` + MidSize int `json:"mid_size"` + EndSize int `json:"end_size"` + UseInputsAtOffsets bool `json:"use_inputs_at_offsets"` + MediumConfidenceThreshold float32 `json:"medium_confidence_threshold"` + MinFileSizeForDl int64 `json:"min_file_size_for_dl"` + PaddingToken int32 `json:"padding_token"` + BlockSize int `json:"block_size"` + TargetLabelsSpace []string `json:"target_labels_space"` + Thresholds map[string]float32 `json:"thresholds"` +} + +// PaddedInt32 places "b" into "out" starting at index "prefix", setting any +// bytes before and after to the [Config.PaddingToken]. +// +// This function assumes the "out" slice is zeroed. +func (cfg *Config) paddedInt32(out []int32, b []byte, prefix int) { + pre, n, post := out[:prefix], out[prefix:][:len(b)], out[prefix+len(b):] + + if cfg.PaddingToken != 0 { + for i := range pre { + pre[i] = cfg.PaddingToken + } + } + for i, b := range b { + n[i] = int32(b) + } + if cfg.PaddingToken != 0 { + for i := range post { + post[i] = cfg.PaddingToken + } + } +} + +// Features extracts the configured features from the provided [io.ReaderAt]. +func (cfg *Config) Features(r io.ReaderAt, size int64) ([]int32, error) { + const spaces = " \f\n\r\t\v" + out := make([]int32, cfg.BegSize+cfg.MidSize+cfg.EndSize) + beg := out[:cfg.BegSize] + mid := out[cfg.BegSize:][:cfg.MidSize] + end := out[cfg.BegSize+cfg.MidSize:] + var v []byte + b := make([]byte, cfg.BlockSize) + + n, err := r.ReadAt(b, 0) + switch { + case err == nil: + case err == io.EOF: + default: + return nil, err + } + v = b[:n] + v = bytes.TrimLeft(v, spaces) + v = v[:min(len(v), cfg.BegSize)] + cfg.paddedInt32(beg, v, 0) + + n, err = r.ReadAt(b[:cfg.MidSize], (size-int64(cfg.MidSize))/2) + switch { + case err == nil: + case err == io.EOF: + default: + return nil, err + } + v = b[:n] + v = v[:min(len(v), cfg.EndSize)] + cfg.paddedInt32(mid, v, (cfg.MidSize-len(v))/2) + + n, err = r.ReadAt(b, max(size-int64(cfg.BlockSize), 0)) + switch { + case err == nil: + case err == io.EOF: + default: + return nil, err + } + v = b[:n] + v = bytes.TrimRight(v, spaces) + v = v[:min(len(v), cfg.EndSize)] + cfg.paddedInt32(end, v, cfg.EndSize-len(v)) + + return out, nil +} + +const ( + contentTypeLabelEmpty = "empty" + contentTypeLabelText = "txt" + contentTypeLabelUnknown = "unknown" +) + +// ContentType holds the definition of a content type. +type ContentType struct { + Label string // As keyed in the content types KB. + MimeType string `json:"mime_type"` + Group string `json:"group"` + Description string `json:"description"` + Extensions []string `json:"extensions"` + IsText bool `json:"is_text"` +} + +// String implements [fmt.Stringer]. +func (ct *ContentType) String() string { + return ct.MimeType +} + +// LoadContentTypes loads known [ContentType]s from the provided [fs.FS]. +// +// The FS is assumed to be structured like the upstream repository's "assets" +// folder. +func LoadContentTypes(sys fs.FS) (map[string]*ContentType, error) { + f, err := sys.Open(`content_types_kb.min.json`) + if err != nil { + return nil, err + } + defer f.Close() + kb := make(map[string]*ContentType) + + dec := json.NewDecoder(f) + if tok, err := dec.Token(); tok != json.Delim('{') || err != nil { + return nil, fmt.Errorf("unexpected content_types formatting: %v / %w", tok, err) + } + for dec.More() { + tok, err := dec.Token() + if err == io.EOF { + break + } + if err != nil { + return nil, fmt.Errorf("unexpected content_types formatting: %v / %w", tok, err) + } + key, ok := tok.(string) + if !ok { + return nil, fmt.Errorf("unexpected content_types formatting: got: %T, want: string", tok) + } + + var ct ContentType + if err := dec.Decode(&ct); err != nil { + return nil, fmt.Errorf("unexpected content_types formatting: %w", err) + } + ct.Label = key + kb[key] = &ct + + } + + return kb, nil +} diff --git a/detector/magika/magika_test.go b/detector/magika/magika_test.go new file mode 100644 index 000000000..8fbb06e69 --- /dev/null +++ b/detector/magika/magika_test.go @@ -0,0 +1,171 @@ +package magika + +import ( + "archive/zip" + "io" + "net/http" + "os" + "path" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/quay/claircore/test" + "github.com/quay/claircore/test/integration" +) + +func loadRuntime(t testing.TB) { + t.Helper() + _, err := getRuntimeHandle() + if err == nil { + return + } + t.Skipf("unable to load ONNX runtime: %v", err) +} + +func TestLoadRuntime(t *testing.T) { + loadRuntime(t) + t.Logf("runtime loaded") +} + +func TestApiBase(t *testing.T) { + loadRuntime(t) + base, err := getAPIBase() + if err != nil { + t.Error(err) + } + if base == nil { + t.Error("unexpected nil pointer return") + } + t.Logf("got version: %q", base.GetVersionString()) +} + +func TestGetApi(t *testing.T) { + loadRuntime(t) + api, err := getAPI() + if err != nil { + t.Error(err) + } + if api == nil { + t.Error("unexpected nil pointer return") + } +} + +func TestMagika(t *testing.T) { + loadRuntime(t) + modelZip := test.GenerateFixture(t, "magika_model.zip", time.Time{}, GenerateModelZip) + if t.Failed() { + return + } + + f, fi := openStat(t, modelZip) + z, err := zip.NewReader(f, fi.Size()) + if err != nil { + t.Fatal(err) + } + + m, err := LoadModel(z, `standard_v3_3`) + if err != nil { + t.Fatal(err) + } + + for _, tc := range []struct { + Name string + Want string + }{ + {Name: "magika.go", Want: "text/x-golang"}, + {Name: modelZip, Want: "application/zip"}, + } { + n := filepath.Base(tc.Name) + t.Run(n, func(t *testing.T) { + t.Logf("checking file %q", tc.Name) + f, fi = openStat(t, tc.Name) + ct, err := m.Scan(f, fi.Size()) + if err != nil { + t.Error(err) + } + got, want := ct.MimeType, tc.Want + t.Logf("got: %q, want: %q", got, want) + if got != want { + t.Fail() + } + }) + } +} + +// Open and stats the named file, returning both. +// +// Fails and exits the test on error. +// Arranges for the file to be closed in a [testing.TB.Cleanup] function. +func openStat(t testing.TB, name string) (*os.File, os.FileInfo) { + t.Helper() + f, err := os.Open(name) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + if err := f.Close(); err != nil { + t.Errorf("closing file %q: %v", f.Name(), err) + } + }) + fi, err := f.Stat() + if err != nil { + t.Fatal(err) + } + return f, fi +} + +func GenerateModelZip(t testing.TB, f *os.File) { + integration.Skip(t) + const arURL = `https://github.com/google/magika/archive/refs/heads/main.zip` + + zf, err := os.Create(filepath.Join(t.TempDir(), `main.zip`)) + if err != nil { + t.Fatal(err) + } + defer zf.Close() + + res, err := http.Get(arURL) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + t.Fatalf("unexpected response: %v", res.Status) + } + sz, err := io.Copy(zf, res.Body) + if err != nil { + t.Fatal(err) + } + + zr, err := zip.NewReader(zf, sz) + if err != nil { + t.Fatal(err) + } + zw := zip.NewWriter(f) + defer zw.Close() + + for _, f := range zr.File { + const prefix = `magika-main/assets/` + if !strings.HasPrefix(f.Name, prefix) { + continue + } + switch ext := path.Ext(f.Name); { + case strings.HasSuffix(f.Name, "/"): + case ext == ".onnx": + case ext == ".json": + default: + continue + } + f.Name = strings.TrimPrefix(f.Name, prefix) + if f.Name == "" { + continue + } + t.Log(f.Name) + + if err := zw.Copy(f); err != nil { + t.Fatal(err) + } + } +} diff --git a/detector/magika/ort.go b/detector/magika/ort.go new file mode 100644 index 000000000..6826a65b0 --- /dev/null +++ b/detector/magika/ort.go @@ -0,0 +1,299 @@ +package magika + +import ( + "errors" + "runtime" + "sync" + "unique" + "unsafe" + + "github.com/ebitengine/purego" +) + +//go:generate env -C _cmd/ortgen go run . -version 1.15.1 -o ../../ort_types.go + +// The version requested here needs to match the value defined as +// ORT_API_VERSION in the C header used to generate "ort_types.go". +// +// This seems to always be the minor version. It should be fine to lag the +// version of the library used at runtime. +const apiVersion = 15 + +// GetRuntimeHandle attempts to load "libonnxruntime.so.1", reporting +// [errors.ErrUnsupported] if not found. +var getRuntimeHandle = sync.OnceValues(func() (uintptr, error) { + handle, err := purego.Dlopen("libonnxruntime.so.1", purego.RTLD_NOW|purego.RTLD_GLOBAL) + if err != nil { + return 0, errors.Join(errors.ErrUnsupported, err) + } + + return handle, nil +}) + +// GetAPIBase returns the [apiBase], loading the runtime if needed. +var getAPIBase = sync.OnceValues(func() (*apiBase, error) { + handle, err := getRuntimeHandle() + if err != nil { + return nil, err + } + + var fn func() *ortApiBase + cfn, err := purego.Dlsym(handle, "OrtGetApiBase") + if err != nil { + return nil, errors.Join(errors.ErrUnsupported, err) + } + purego.RegisterFunc(&fn, cfn) + + return newAPIBase(fn()), nil +}) + +// GetAPI returns the [api], loading the runtime if needed. +var getAPI = sync.OnceValues(func() (*api, error) { + base, err := getAPIBase() + if err != nil { + return nil, errors.Join(errors.ErrUnsupported, err) + } + + return base.GetAPI() +}) + +type apiBase struct { + getAPI func(uint32) *ortApi + getVersionString func() string +} + +func newAPIBase(ort *ortApiBase) *apiBase { + var r apiBase + purego.RegisterFunc(&r.getAPI, ort.GetApi) + purego.RegisterFunc(&r.getVersionString, ort.GetVersionString) + return &r +} + +func (a *apiBase) GetAPI() (*api, error) { + ort := a.getAPI(apiVersion) + if ort == nil { + return nil, errors.New("unable to load ONNX Runtime") + } + return newAPI(ort), nil +} + +func (a *apiBase) GetVersionString() string { + // intern and return + return unique.Make(a.getVersionString()).Value() +} + +// See ort_types.go for the C function declarations to determine what the +// pointers are. +// +// The ONNX runtime returns most of its objects as typed but opaque pointers, +// which are written here as aliases to [unsafe.Pointer]. +type api struct { + getErrorMessage func(ortStatus) string + getErrorCode func(ortStatus) int + + createEnv func(int, string, *ortEnv) ortStatus + disableTelemetryEvents func(ortEnv) ortStatus + + createSessionOptions func(*ortSessionOptions) ortStatus + enableCPUMemArena func(ortSessionOptions) ortStatus + + createSessionFromArray func(ortEnv, unsafe.Pointer, int, ortSessionOptions, *ortSession) ortStatus + + createCPUMemoryInfo func(int, int, *ortMemoryInfo) ortStatus + + createTensorWithDataAsOrtValue func(ortMemoryInfo, unsafe.Pointer, int, *int64, int, int, *ortValue) ortStatus + getTensorMutableData func(ortValue, *unsafe.Pointer) ortStatus + + run func(ortSession, unsafe.Pointer, *string, *ortValue, int, *string, int, *ortValue) ortStatus + + releaseEnv func(ortEnv) + releaseMemoryInfo func(ortMemoryInfo) + releaseSession func(ortSession) + releaseSessionOptions func(ortSessionOptions) + releaseStatus func(ortStatus) + releaseValue func(ortValue) +} + +func newAPI(ort *ortApi) *api { + var r api + + purego.RegisterFunc(&r.getErrorMessage, ort.GetErrorMessage) + purego.RegisterFunc(&r.getErrorCode, ort.GetErrorCode) + + purego.RegisterFunc(&r.createEnv, ort.CreateEnv) + purego.RegisterFunc(&r.disableTelemetryEvents, ort.DisableTelemetryEvents) + + purego.RegisterFunc(&r.createSessionOptions, ort.CreateSessionOptions) + purego.RegisterFunc(&r.enableCPUMemArena, ort.EnableCpuMemArena) + + purego.RegisterFunc(&r.createSessionFromArray, ort.CreateSessionFromArray) + + purego.RegisterFunc(&r.createCPUMemoryInfo, ort.CreateCpuMemoryInfo) + + purego.RegisterFunc(&r.createTensorWithDataAsOrtValue, ort.CreateTensorWithDataAsOrtValue) + purego.RegisterFunc(&r.getTensorMutableData, ort.GetTensorMutableData) + + purego.RegisterFunc(&r.run, ort.Run) + + purego.RegisterFunc(&r.releaseEnv, ort.ReleaseEnv) + purego.RegisterFunc(&r.releaseMemoryInfo, ort.ReleaseMemoryInfo) + purego.RegisterFunc(&r.releaseSessionOptions, ort.ReleaseSessionOptions) + purego.RegisterFunc(&r.releaseSession, ort.ReleaseSession) + purego.RegisterFunc(&r.releaseStatus, ort.ReleaseStatus) + purego.RegisterFunc(&r.releaseValue, ort.ReleaseValue) + + return &r +} + +const onnxLogName = "magika\x00" + +const ( + ortInvalidAllocator = iota - 1 + ortDeviceAllocator + ortArenaAllocator +) + +const ( + ortMemTypeCPUInput = iota - 2 ///< Any CPU memory used by non-CPU execution provider + ortMemTypeCPUOutput ///< CPU accessible memory outputted by non-CPU execution provider, i.e. CUDA_PINNED + ortMemTypeDefault ///< The default allocator for execution provider + ortMemTypeCPU = ortMemTypeCPUOutput ///< Temporary CPU accessible memory allocated by non-CPU execution provider, i.e. CUDA_PINNED +) + +func (a *api) checkStatus(s ortStatus) error { + if s != nil { + err := errors.New(a.getErrorMessage(s)) + a.releaseStatus(s) + return err + } + return nil +} + +func (a *api) CreateSession(model []byte) (*session, error) { + const logLevelWarning = 2 + var env ortEnv + if err := a.checkStatus(a.createEnv(logLevelWarning, onnxLogName, &env)); err != nil { + return nil, err + } + if err := a.checkStatus(a.disableTelemetryEvents(env)); err != nil { + return nil, err + } + + var options ortSessionOptions + if err := a.checkStatus(a.createSessionOptions(&options)); err != nil { + return nil, err + } + if err := a.checkStatus(a.enableCPUMemArena(options)); err != nil { + return nil, err + } + + var mem ortMemoryInfo + if err := a.checkStatus(a.createCPUMemoryInfo(ortArenaAllocator, ortMemTypeDefault, &mem)); err != nil { + return nil, err + } + + var session ortSession + if err := a.checkStatus(a.createSessionFromArray(env, unsafe.Pointer(unsafe.SliceData(model)), len(model), options, &session)); err != nil { + return nil, err + } + + return newSession(env, options, mem, session), nil +} + +type session struct { + api *api + env ortEnv + options ortSessionOptions + mem ortMemoryInfo + session ortSession +} + +func newSession(env ortEnv, options ortSessionOptions, mem ortMemoryInfo, p ortSession) *session { + api, _ := getAPI() + r := &session{ + api: api, + env: env, + options: options, + mem: mem, + session: p, + } + runtime.AddCleanup(r, api.releaseEnv, env) + runtime.AddCleanup(r, api.releaseSessionOptions, options) + runtime.AddCleanup(r, api.releaseMemoryInfo, mem) + runtime.AddCleanup(r, api.releaseSession, p) + return r +} + +var ( + inputNames = []string{"bytes\x00"} + outputNames = []string{"target_label\x00"} +) + +func (s *session) Run(features []int32, labelSpace int) ([]float32, error) { + shape := []int64{1, int64(len(features))} + + var input, output ortValue + status := s.api.createTensorWithDataAsOrtValue(s.mem, + unsafe.Pointer(unsafe.SliceData(features)), len(features)*int(unsafe.Sizeof(int32(0))), + unsafe.SliceData(shape), 2, + tensorElementInt32, &input) + if err := s.api.checkStatus(status); err != nil { + return nil, err + } + defer s.api.releaseValue(input) + + status = s.api.run(s.session, nil, + unsafe.SliceData(inputNames), &input, 1, + unsafe.SliceData(outputNames), 1, + &output, + ) + if err := s.api.checkStatus(status); err != nil { + return nil, err + } + defer s.api.releaseValue(output) + + // Returned data is owned by the Value, so copy it out. + var out unsafe.Pointer + status = s.api.getTensorMutableData(output, &out) + if err := s.api.checkStatus(status); err != nil { + return nil, err + } + ret := make([]float32, labelSpace) + copy(ret, unsafe.Slice((*float32)(out), labelSpace)) + + return ret, nil +} + +type ( + ortEnv unsafe.Pointer + ortSessionOptions unsafe.Pointer + ortMemoryInfo unsafe.Pointer + ortValue unsafe.Pointer + ortSession unsafe.Pointer + ortStatus unsafe.Pointer +) + +const ( + tensorElementUndefined = iota + tensorElementFloat // maps to c type float + tensorElementUint8 // maps to c type uint8_t + tensorElementInt8 // maps to c type int8_t + tensorElementUint16 // maps to c type uint16_t + tensorElementInt16 // maps to c type int16_t + tensorElementInt32 // maps to c type int32_t + tensorElementInt64 // maps to c type int64_t + tensorElementString // maps to c++ type std::string + tensorElementBool + tensorElementFloat16 + tensorElementDouble // maps to c type double + tensorElementUint32 // maps to c type uint32_t + tensorElementUint64 // maps to c type uint64_t + tensorElementComplex64 // complex with float32 real and imaginary components + tensorElementComplex128 // complex with float64 real and imaginary components + tensorElementBFloat16 // Non-IEEE floating-point format based on IEEE754 single-precision + // float 8 types were introduced in onnx 1.14 see https://onnx.ai/onnx/technical/float8.html + tensorElementFloat8E4M3FN // Non-IEEE floating-point format based on IEEE754 single-precision + tensorElementFloat8E4M3FNUZ // Non-IEEE floating-point format based on IEEE754 single-precision + tensorElementFloat8E5M2 // Non-IEEE floating-point format based on IEEE754 single-precision + tensorElementFloat8E5M2FNUZ // Non-IEEE floating-point format based on IEEE754 single-precision +) diff --git a/detector/magika/ort_types.go b/detector/magika/ort_types.go new file mode 100644 index 000000000..5a242a8ce --- /dev/null +++ b/detector/magika/ort_types.go @@ -0,0 +1,529 @@ +// Code generated by ortgen. DO NOT EDIT. + +package magika + +import "structs" + +type ortApiBase struct { + _ structs.HostLayout + + // const OrtApi*(* GetApi)(uint32_t version); + GetApi uintptr + // const char*(* GetVersionString)(void); + GetVersionString uintptr +} + +type ortApi struct { + _ structs.HostLayout + + // OrtStatus*(* CreateStatus)(OrtErrorCode code, const char* msg) __attribute__((nonnull)); + CreateStatus uintptr + // OrtErrorCode(* GetErrorCode)( const OrtStatus* status) __attribute__((nonnull)); + GetErrorCode uintptr + // const char*(* GetErrorMessage)( const OrtStatus* status) __attribute__((nonnull)); + GetErrorMessage uintptr + // OrtStatusPtr(*CreateEnv)( OrtLoggingLevel log_severity_level, const char* logid, OrtEnv** out) __attribute__((warn_unused_result)); + CreateEnv uintptr + // OrtStatusPtr(*CreateEnvWithCustomLogger)( OrtLoggingFunction logging_function, void* logger_param, OrtLoggingLevel log_severity_level, const char* logid, OrtEnv** out) __attribute__((warn_unused_result)); + CreateEnvWithCustomLogger uintptr + // OrtStatusPtr(*EnableTelemetryEvents)( const OrtEnv* env) __attribute__((warn_unused_result)); + EnableTelemetryEvents uintptr + // OrtStatusPtr(*DisableTelemetryEvents)( const OrtEnv* env) __attribute__((warn_unused_result)); + DisableTelemetryEvents uintptr + // OrtStatusPtr(*CreateSession)( const OrtEnv* env, const char* model_path, const OrtSessionOptions* options, OrtSession** out) __attribute__((warn_unused_result)); + CreateSession uintptr + // OrtStatusPtr(*CreateSessionFromArray)( const OrtEnv* env, const void* model_data, size_t model_data_length, const OrtSessionOptions* options, OrtSession** out) __attribute__((warn_unused_result)); + CreateSessionFromArray uintptr + // OrtStatusPtr(*Run)( OrtSession* session, const OrtRunOptions* run_options, const char* const* input_names, const OrtValue* const* inputs, size_t input_len, const char* const* output_names, size_t output_names_len, OrtValue** outputs) __attribute__((warn_unused_result)); + Run uintptr + // OrtStatusPtr(*CreateSessionOptions)( OrtSessionOptions** options) __attribute__((warn_unused_result)); + CreateSessionOptions uintptr + // OrtStatusPtr(*SetOptimizedModelFilePath)( OrtSessionOptions* options, const char* optimized_model_filepath) __attribute__((warn_unused_result)); + SetOptimizedModelFilePath uintptr + // OrtStatusPtr(*CloneSessionOptions)( const OrtSessionOptions* in_options, OrtSessionOptions** out_options) __attribute__((warn_unused_result)); + CloneSessionOptions uintptr + // OrtStatusPtr(*SetSessionExecutionMode)( OrtSessionOptions* options, ExecutionMode execution_mode) __attribute__((warn_unused_result)); + SetSessionExecutionMode uintptr + // OrtStatusPtr(*EnableProfiling)( OrtSessionOptions* options, const char* profile_file_prefix) __attribute__((warn_unused_result)); + EnableProfiling uintptr + // OrtStatusPtr(*DisableProfiling)( OrtSessionOptions* options) __attribute__((warn_unused_result)); + DisableProfiling uintptr + // OrtStatusPtr(*EnableMemPattern)( OrtSessionOptions* options) __attribute__((warn_unused_result)); + EnableMemPattern uintptr + // OrtStatusPtr(*DisableMemPattern)( OrtSessionOptions* options) __attribute__((warn_unused_result)); + DisableMemPattern uintptr + // OrtStatusPtr(*EnableCpuMemArena)( OrtSessionOptions* options) __attribute__((warn_unused_result)); + EnableCpuMemArena uintptr + // OrtStatusPtr(*DisableCpuMemArena)( OrtSessionOptions* options) __attribute__((warn_unused_result)); + DisableCpuMemArena uintptr + // OrtStatusPtr(*SetSessionLogId)( OrtSessionOptions* options, const char* logid) __attribute__((warn_unused_result)); + SetSessionLogId uintptr + // OrtStatusPtr(*SetSessionLogVerbosityLevel)( OrtSessionOptions* options, int session_log_verbosity_level) __attribute__((warn_unused_result)); + SetSessionLogVerbosityLevel uintptr + // OrtStatusPtr(*SetSessionLogSeverityLevel)( OrtSessionOptions* options, int session_log_severity_level) __attribute__((warn_unused_result)); + SetSessionLogSeverityLevel uintptr + // OrtStatusPtr(*SetSessionGraphOptimizationLevel)( OrtSessionOptions* options, GraphOptimizationLevel graph_optimization_level) __attribute__((warn_unused_result)); + SetSessionGraphOptimizationLevel uintptr + // OrtStatusPtr(*SetIntraOpNumThreads)( OrtSessionOptions* options, int intra_op_num_threads) __attribute__((warn_unused_result)); + SetIntraOpNumThreads uintptr + // OrtStatusPtr(*SetInterOpNumThreads)( OrtSessionOptions* options, int inter_op_num_threads) __attribute__((warn_unused_result)); + SetInterOpNumThreads uintptr + // OrtStatusPtr(*CreateCustomOpDomain)( const char* domain, OrtCustomOpDomain** out) __attribute__((warn_unused_result)); + CreateCustomOpDomain uintptr + // OrtStatusPtr(*CustomOpDomain_Add)( OrtCustomOpDomain* custom_op_domain, const OrtCustomOp* op) __attribute__((warn_unused_result)); + CustomOpDomain_Add uintptr + // OrtStatusPtr(*AddCustomOpDomain)( OrtSessionOptions* options, OrtCustomOpDomain* custom_op_domain) __attribute__((warn_unused_result)); + AddCustomOpDomain uintptr + // OrtStatusPtr(*RegisterCustomOpsLibrary)( OrtSessionOptions* options, const char* library_path, void** library_handle) __attribute__((warn_unused_result)); + RegisterCustomOpsLibrary uintptr + // OrtStatusPtr(*SessionGetInputCount)( const OrtSession* session, size_t* out) __attribute__((warn_unused_result)); + SessionGetInputCount uintptr + // OrtStatusPtr(*SessionGetOutputCount)( const OrtSession* session, size_t* out) __attribute__((warn_unused_result)); + SessionGetOutputCount uintptr + // OrtStatusPtr(*SessionGetOverridableInitializerCount)( const OrtSession* session, size_t* out) __attribute__((warn_unused_result)); + SessionGetOverridableInitializerCount uintptr + // OrtStatusPtr(*SessionGetInputTypeInfo)( const OrtSession* session, size_t index, OrtTypeInfo** type_info) __attribute__((warn_unused_result)); + SessionGetInputTypeInfo uintptr + // OrtStatusPtr(*SessionGetOutputTypeInfo)( const OrtSession* session, size_t index, OrtTypeInfo** type_info) __attribute__((warn_unused_result)); + SessionGetOutputTypeInfo uintptr + // OrtStatusPtr(*SessionGetOverridableInitializerTypeInfo)( const OrtSession* session, size_t index, OrtTypeInfo** type_info) __attribute__((warn_unused_result)); + SessionGetOverridableInitializerTypeInfo uintptr + // OrtStatusPtr(*SessionGetInputName)( const OrtSession* session, size_t index, OrtAllocator* allocator, char** value) __attribute__((warn_unused_result)); + SessionGetInputName uintptr + // OrtStatusPtr(*SessionGetOutputName)( const OrtSession* session, size_t index, OrtAllocator* allocator, char** value) __attribute__((warn_unused_result)); + SessionGetOutputName uintptr + // OrtStatusPtr(*SessionGetOverridableInitializerName)( const OrtSession* session, size_t index, OrtAllocator* allocator, char** value) __attribute__((warn_unused_result)); + SessionGetOverridableInitializerName uintptr + // OrtStatusPtr(*CreateRunOptions)( OrtRunOptions** out) __attribute__((warn_unused_result)); + CreateRunOptions uintptr + // OrtStatusPtr(*RunOptionsSetRunLogVerbosityLevel)( OrtRunOptions* options, int log_verbosity_level) __attribute__((warn_unused_result)); + RunOptionsSetRunLogVerbosityLevel uintptr + // OrtStatusPtr(*RunOptionsSetRunLogSeverityLevel)( OrtRunOptions* options, int log_severity_level) __attribute__((warn_unused_result)); + RunOptionsSetRunLogSeverityLevel uintptr + // OrtStatusPtr(*RunOptionsSetRunTag)( OrtRunOptions* options, const char* run_tag) __attribute__((warn_unused_result)); + RunOptionsSetRunTag uintptr + // OrtStatusPtr(*RunOptionsGetRunLogVerbosityLevel)( const OrtRunOptions* options, int* log_verbosity_level) __attribute__((warn_unused_result)); + RunOptionsGetRunLogVerbosityLevel uintptr + // OrtStatusPtr(*RunOptionsGetRunLogSeverityLevel)( const OrtRunOptions* options, int* log_severity_level) __attribute__((warn_unused_result)); + RunOptionsGetRunLogSeverityLevel uintptr + // OrtStatusPtr(*RunOptionsGetRunTag)( const OrtRunOptions* options, const char** run_tag) __attribute__((warn_unused_result)); + RunOptionsGetRunTag uintptr + // OrtStatusPtr(*RunOptionsSetTerminate)( OrtRunOptions* options) __attribute__((warn_unused_result)); + RunOptionsSetTerminate uintptr + // OrtStatusPtr(*RunOptionsUnsetTerminate)( OrtRunOptions* options) __attribute__((warn_unused_result)); + RunOptionsUnsetTerminate uintptr + // OrtStatusPtr(*CreateTensorAsOrtValue)( OrtAllocator* allocator, const int64_t* shape, size_t shape_len, ONNXTensorElementDataType type, OrtValue** out) __attribute__((warn_unused_result)); + CreateTensorAsOrtValue uintptr + // OrtStatusPtr(*CreateTensorWithDataAsOrtValue)( const OrtMemoryInfo* info, void* p_data, size_t p_data_len, const int64_t* shape, size_t shape_len, ONNXTensorElementDataType type, OrtValue** out) __attribute__((warn_unused_result)); + CreateTensorWithDataAsOrtValue uintptr + // OrtStatusPtr(*IsTensor)( const OrtValue* value, int* out) __attribute__((warn_unused_result)); + IsTensor uintptr + // OrtStatusPtr(*GetTensorMutableData)( OrtValue* value, void** out) __attribute__((warn_unused_result)); + GetTensorMutableData uintptr + // OrtStatusPtr(*FillStringTensor)( OrtValue* value, const char* const* s, size_t s_len) __attribute__((warn_unused_result)); + FillStringTensor uintptr + // OrtStatusPtr(*GetStringTensorDataLength)( const OrtValue* value, size_t* len) __attribute__((warn_unused_result)); + GetStringTensorDataLength uintptr + // OrtStatusPtr(*GetStringTensorContent)( const OrtValue* value, void* s, size_t s_len, size_t* offsets, size_t offsets_len) __attribute__((warn_unused_result)); + GetStringTensorContent uintptr + // OrtStatusPtr(*CastTypeInfoToTensorInfo)( const OrtTypeInfo* type_info, const OrtTensorTypeAndShapeInfo** out) __attribute__((warn_unused_result)); + CastTypeInfoToTensorInfo uintptr + // OrtStatusPtr(*GetOnnxTypeFromTypeInfo)( const OrtTypeInfo* type_info, enum ONNXType* out) __attribute__((warn_unused_result)); + GetOnnxTypeFromTypeInfo uintptr + // OrtStatusPtr(*CreateTensorTypeAndShapeInfo)( OrtTensorTypeAndShapeInfo** out) __attribute__((warn_unused_result)); + CreateTensorTypeAndShapeInfo uintptr + // OrtStatusPtr(*SetTensorElementType)( OrtTensorTypeAndShapeInfo* info, enum ONNXTensorElementDataType type) __attribute__((warn_unused_result)); + SetTensorElementType uintptr + // OrtStatusPtr(*SetDimensions)( OrtTensorTypeAndShapeInfo* info, const int64_t* dim_values, size_t dim_count) __attribute__((warn_unused_result)); + SetDimensions uintptr + // OrtStatusPtr(*GetTensorElementType)( const OrtTensorTypeAndShapeInfo* info, enum ONNXTensorElementDataType* out) __attribute__((warn_unused_result)); + GetTensorElementType uintptr + // OrtStatusPtr(*GetDimensionsCount)( const OrtTensorTypeAndShapeInfo* info, size_t* out) __attribute__((warn_unused_result)); + GetDimensionsCount uintptr + // OrtStatusPtr(*GetDimensions)( const OrtTensorTypeAndShapeInfo* info, int64_t* dim_values, size_t dim_values_length) __attribute__((warn_unused_result)); + GetDimensions uintptr + // OrtStatusPtr(*GetSymbolicDimensions)( const OrtTensorTypeAndShapeInfo* info, const char* dim_params[], size_t dim_params_length) __attribute__((warn_unused_result)); + GetSymbolicDimensions uintptr + // OrtStatusPtr(*GetTensorShapeElementCount)( const OrtTensorTypeAndShapeInfo* info, size_t* out) __attribute__((warn_unused_result)); + GetTensorShapeElementCount uintptr + // OrtStatusPtr(*GetTensorTypeAndShape)( const OrtValue* value, OrtTensorTypeAndShapeInfo** out) __attribute__((warn_unused_result)); + GetTensorTypeAndShape uintptr + // OrtStatusPtr(*GetTypeInfo)( const OrtValue* value, OrtTypeInfo** out) __attribute__((warn_unused_result)); + GetTypeInfo uintptr + // OrtStatusPtr(*GetValueType)( const OrtValue* value, enum ONNXType* out) __attribute__((warn_unused_result)); + GetValueType uintptr + // OrtStatusPtr(*CreateMemoryInfo)( const char* name, enum OrtAllocatorType type, int id, enum OrtMemType mem_type, OrtMemoryInfo** out) __attribute__((warn_unused_result)); + CreateMemoryInfo uintptr + // OrtStatusPtr(*CreateCpuMemoryInfo)( enum OrtAllocatorType type, enum OrtMemType mem_type, OrtMemoryInfo** out) __attribute__((warn_unused_result)); + CreateCpuMemoryInfo uintptr + // OrtStatusPtr(*CompareMemoryInfo)( const OrtMemoryInfo* info1, const OrtMemoryInfo* info2, int* out) __attribute__((warn_unused_result)); + CompareMemoryInfo uintptr + // OrtStatusPtr(*MemoryInfoGetName)( const OrtMemoryInfo* ptr, const char** out) __attribute__((warn_unused_result)); + MemoryInfoGetName uintptr + // OrtStatusPtr(*MemoryInfoGetId)( const OrtMemoryInfo* ptr, int* out) __attribute__((warn_unused_result)); + MemoryInfoGetId uintptr + // OrtStatusPtr(*MemoryInfoGetMemType)( const OrtMemoryInfo* ptr, OrtMemType* out) __attribute__((warn_unused_result)); + MemoryInfoGetMemType uintptr + // OrtStatusPtr(*MemoryInfoGetType)( const OrtMemoryInfo* ptr, OrtAllocatorType* out) __attribute__((warn_unused_result)); + MemoryInfoGetType uintptr + // OrtStatusPtr(*AllocatorAlloc)( OrtAllocator* ort_allocator, size_t size, void** out) __attribute__((warn_unused_result)); + AllocatorAlloc uintptr + // OrtStatusPtr(*AllocatorFree)( OrtAllocator* ort_allocator, void* p) __attribute__((warn_unused_result)); + AllocatorFree uintptr + // OrtStatusPtr(*AllocatorGetInfo)( const OrtAllocator* ort_allocator, const struct OrtMemoryInfo** out) __attribute__((warn_unused_result)); + AllocatorGetInfo uintptr + // OrtStatusPtr(*GetAllocatorWithDefaultOptions)( OrtAllocator** out) __attribute__((warn_unused_result)); + GetAllocatorWithDefaultOptions uintptr + // OrtStatusPtr(*AddFreeDimensionOverride)( OrtSessionOptions* options, const char* dim_denotation, int64_t dim_value) __attribute__((warn_unused_result)); + AddFreeDimensionOverride uintptr + // OrtStatusPtr(*GetValue)( const OrtValue* value, int index, OrtAllocator* allocator, OrtValue** out) __attribute__((warn_unused_result)); + GetValue uintptr + // OrtStatusPtr(*GetValueCount)( const OrtValue* value, size_t* out) __attribute__((warn_unused_result)); + GetValueCount uintptr + // OrtStatusPtr(*CreateValue)( const OrtValue* const* in, size_t num_values, enum ONNXType value_type, OrtValue** out) __attribute__((warn_unused_result)); + CreateValue uintptr + // OrtStatusPtr(*CreateOpaqueValue)( const char* domain_name, const char* type_name, const void* data_container, size_t data_container_size, OrtValue** out) __attribute__((warn_unused_result)); + CreateOpaqueValue uintptr + // OrtStatusPtr(*GetOpaqueValue)( const char* domain_name, const char* type_name, const OrtValue* in, void* data_container, size_t data_container_size) __attribute__((warn_unused_result)); + GetOpaqueValue uintptr + // OrtStatusPtr(*KernelInfoGetAttribute_float)( const OrtKernelInfo* info, const char* name, float* out) __attribute__((warn_unused_result)); + KernelInfoGetAttribute_float uintptr + // OrtStatusPtr(*KernelInfoGetAttribute_int64)( const OrtKernelInfo* info, const char* name, int64_t* out) __attribute__((warn_unused_result)); + KernelInfoGetAttribute_int64 uintptr + // OrtStatusPtr(*KernelInfoGetAttribute_string)( const OrtKernelInfo* info, const char* name, char* out, size_t* size) __attribute__((warn_unused_result)); + KernelInfoGetAttribute_string uintptr + // OrtStatusPtr(*KernelContext_GetInputCount)( const OrtKernelContext* context, size_t* out) __attribute__((warn_unused_result)); + KernelContext_GetInputCount uintptr + // OrtStatusPtr(*KernelContext_GetOutputCount)( const OrtKernelContext* context, size_t* out) __attribute__((warn_unused_result)); + KernelContext_GetOutputCount uintptr + // OrtStatusPtr(*KernelContext_GetInput)( const OrtKernelContext* context, size_t index, const OrtValue** out) __attribute__((warn_unused_result)); + KernelContext_GetInput uintptr + // OrtStatusPtr(*KernelContext_GetOutput)( OrtKernelContext* context, size_t index, const int64_t* dim_values, size_t dim_count, OrtValue** out) __attribute__((warn_unused_result)); + KernelContext_GetOutput uintptr + // void( *ReleaseEnv)(OrtEnv * input); + ReleaseEnv uintptr + // void( *ReleaseStatus)(OrtStatus * input); + ReleaseStatus uintptr + // void( *ReleaseMemoryInfo)(OrtMemoryInfo * input); + ReleaseMemoryInfo uintptr + // void( *ReleaseSession)(OrtSession * input); + ReleaseSession uintptr + // void( *ReleaseValue)(OrtValue * input); + ReleaseValue uintptr + // void( *ReleaseRunOptions)(OrtRunOptions * input); + ReleaseRunOptions uintptr + // void( *ReleaseTypeInfo)(OrtTypeInfo * input); + ReleaseTypeInfo uintptr + // void( *ReleaseTensorTypeAndShapeInfo)(OrtTensorTypeAndShapeInfo * input); + ReleaseTensorTypeAndShapeInfo uintptr + // void( *ReleaseSessionOptions)(OrtSessionOptions * input); + ReleaseSessionOptions uintptr + // void( *ReleaseCustomOpDomain)(OrtCustomOpDomain * input); + ReleaseCustomOpDomain uintptr + // OrtStatusPtr(*GetDenotationFromTypeInfo)( const OrtTypeInfo* type_info, const char** const denotation, size_t* len) __attribute__((warn_unused_result)); + GetDenotationFromTypeInfo uintptr + // OrtStatusPtr(*CastTypeInfoToMapTypeInfo)( const OrtTypeInfo* type_info, const OrtMapTypeInfo** out) __attribute__((warn_unused_result)); + CastTypeInfoToMapTypeInfo uintptr + // OrtStatusPtr(*CastTypeInfoToSequenceTypeInfo)( const OrtTypeInfo* type_info, const OrtSequenceTypeInfo** out) __attribute__((warn_unused_result)); + CastTypeInfoToSequenceTypeInfo uintptr + // OrtStatusPtr(*GetMapKeyType)( const OrtMapTypeInfo* map_type_info, enum ONNXTensorElementDataType* out) __attribute__((warn_unused_result)); + GetMapKeyType uintptr + // OrtStatusPtr(*GetMapValueType)( const OrtMapTypeInfo* map_type_info, OrtTypeInfo** type_info) __attribute__((warn_unused_result)); + GetMapValueType uintptr + // OrtStatusPtr(*GetSequenceElementType)( const OrtSequenceTypeInfo* sequence_type_info, OrtTypeInfo** type_info) __attribute__((warn_unused_result)); + GetSequenceElementType uintptr + // void( *ReleaseMapTypeInfo)(OrtMapTypeInfo * input); + ReleaseMapTypeInfo uintptr + // void( *ReleaseSequenceTypeInfo)(OrtSequenceTypeInfo * input); + ReleaseSequenceTypeInfo uintptr + // OrtStatusPtr(*SessionEndProfiling)( OrtSession* session, OrtAllocator* allocator, char** out) __attribute__((warn_unused_result)); + SessionEndProfiling uintptr + // OrtStatusPtr(*SessionGetModelMetadata)( const OrtSession* session, OrtModelMetadata** out) __attribute__((warn_unused_result)); + SessionGetModelMetadata uintptr + // OrtStatusPtr(*ModelMetadataGetProducerName)( const OrtModelMetadata* model_metadata, OrtAllocator* allocator, char** value) __attribute__((warn_unused_result)); + ModelMetadataGetProducerName uintptr + // OrtStatusPtr(*ModelMetadataGetGraphName)( const OrtModelMetadata* model_metadata, OrtAllocator* allocator, char** value) __attribute__((warn_unused_result)); + ModelMetadataGetGraphName uintptr + // OrtStatusPtr(*ModelMetadataGetDomain)( const OrtModelMetadata* model_metadata, OrtAllocator* allocator, char** value) __attribute__((warn_unused_result)); + ModelMetadataGetDomain uintptr + // OrtStatusPtr(*ModelMetadataGetDescription)( const OrtModelMetadata* model_metadata, OrtAllocator* allocator, char** value) __attribute__((warn_unused_result)); + ModelMetadataGetDescription uintptr + // OrtStatusPtr(*ModelMetadataLookupCustomMetadataMap)( const OrtModelMetadata* model_metadata, OrtAllocator* allocator, const char* key, char** value) __attribute__((warn_unused_result)); + ModelMetadataLookupCustomMetadataMap uintptr + // OrtStatusPtr(*ModelMetadataGetVersion)( const OrtModelMetadata* model_metadata, int64_t* value) __attribute__((warn_unused_result)); + ModelMetadataGetVersion uintptr + // void( *ReleaseModelMetadata)(OrtModelMetadata * input); + ReleaseModelMetadata uintptr + // OrtStatusPtr(*CreateEnvWithGlobalThreadPools)( OrtLoggingLevel log_severity_level, const char* logid, const OrtThreadingOptions* tp_options, OrtEnv** out) __attribute__((warn_unused_result)); + CreateEnvWithGlobalThreadPools uintptr + // OrtStatusPtr(*DisablePerSessionThreads)( OrtSessionOptions* options) __attribute__((warn_unused_result)); + DisablePerSessionThreads uintptr + // OrtStatusPtr(*CreateThreadingOptions)( OrtThreadingOptions** out) __attribute__((warn_unused_result)); + CreateThreadingOptions uintptr + // void( *ReleaseThreadingOptions)(OrtThreadingOptions * input); + ReleaseThreadingOptions uintptr + // OrtStatusPtr(*ModelMetadataGetCustomMetadataMapKeys)( const OrtModelMetadata* model_metadata, OrtAllocator* allocator, char*** keys, int64_t* num_keys) __attribute__((warn_unused_result)); + ModelMetadataGetCustomMetadataMapKeys uintptr + // OrtStatusPtr(*AddFreeDimensionOverrideByName)( OrtSessionOptions* options, const char* dim_name, int64_t dim_value) __attribute__((warn_unused_result)); + AddFreeDimensionOverrideByName uintptr + // OrtStatusPtr(*GetAvailableProviders)( char*** out_ptr, int* provider_length) __attribute__((warn_unused_result)); + GetAvailableProviders uintptr + // OrtStatusPtr(*ReleaseAvailableProviders)( char** ptr, int providers_length) __attribute__((warn_unused_result)); + ReleaseAvailableProviders uintptr + // OrtStatusPtr(*GetStringTensorElementLength)( const OrtValue* value, size_t index, size_t* out) __attribute__((warn_unused_result)); + GetStringTensorElementLength uintptr + // OrtStatusPtr(*GetStringTensorElement)( const OrtValue* value, size_t s_len, size_t index, void* s) __attribute__((warn_unused_result)); + GetStringTensorElement uintptr + // OrtStatusPtr(*FillStringTensorElement)( OrtValue* value, const char* s, size_t index) __attribute__((warn_unused_result)); + FillStringTensorElement uintptr + // OrtStatusPtr(*AddSessionConfigEntry)( OrtSessionOptions* options, const char* config_key, const char* config_value) __attribute__((warn_unused_result)); + AddSessionConfigEntry uintptr + // OrtStatusPtr(*CreateAllocator)( const OrtSession* session, const OrtMemoryInfo* mem_info, OrtAllocator** out) __attribute__((warn_unused_result)); + CreateAllocator uintptr + // void( *ReleaseAllocator)(OrtAllocator * input); + ReleaseAllocator uintptr + // OrtStatusPtr(*RunWithBinding)( OrtSession* session, const OrtRunOptions* run_options, const OrtIoBinding* binding_ptr) __attribute__((warn_unused_result)); + RunWithBinding uintptr + // OrtStatusPtr(*CreateIoBinding)( OrtSession* session, OrtIoBinding** out) __attribute__((warn_unused_result)); + CreateIoBinding uintptr + // void( *ReleaseIoBinding)(OrtIoBinding * input); + ReleaseIoBinding uintptr + // OrtStatusPtr(*BindInput)( OrtIoBinding* binding_ptr, const char* name, const OrtValue* val_ptr) __attribute__((warn_unused_result)); + BindInput uintptr + // OrtStatusPtr(*BindOutput)( OrtIoBinding* binding_ptr, const char* name, const OrtValue* val_ptr) __attribute__((warn_unused_result)); + BindOutput uintptr + // OrtStatusPtr(*BindOutputToDevice)( OrtIoBinding* binding_ptr, const char* name, const OrtMemoryInfo* mem_info_ptr) __attribute__((warn_unused_result)); + BindOutputToDevice uintptr + // OrtStatusPtr(*GetBoundOutputNames)( const OrtIoBinding* binding_ptr, OrtAllocator* allocator, char** buffer, size_t** lengths, size_t* count) __attribute__((warn_unused_result)); + GetBoundOutputNames uintptr + // OrtStatusPtr(*GetBoundOutputValues)( const OrtIoBinding* binding_ptr, OrtAllocator* allocator, OrtValue*** output, size_t* output_count) __attribute__((warn_unused_result)); + GetBoundOutputValues uintptr + // void(* ClearBoundInputs)( OrtIoBinding* binding_ptr) __attribute__((nonnull)); + ClearBoundInputs uintptr + // void(* ClearBoundOutputs)( OrtIoBinding* binding_ptr) __attribute__((nonnull)); + ClearBoundOutputs uintptr + // OrtStatusPtr(*TensorAt)( OrtValue* value, const int64_t* location_values, size_t location_values_count, void** out) __attribute__((warn_unused_result)); + TensorAt uintptr + // OrtStatusPtr(*CreateAndRegisterAllocator)( OrtEnv* env, const OrtMemoryInfo* mem_info, const OrtArenaCfg* arena_cfg) __attribute__((warn_unused_result)); + CreateAndRegisterAllocator uintptr + // OrtStatusPtr(*SetLanguageProjection)( const OrtEnv* ort_env, OrtLanguageProjection projection) __attribute__((warn_unused_result)); + SetLanguageProjection uintptr + // OrtStatusPtr(*SessionGetProfilingStartTimeNs)( const OrtSession* session, uint64_t* out) __attribute__((warn_unused_result)); + SessionGetProfilingStartTimeNs uintptr + // OrtStatusPtr(*SetGlobalIntraOpNumThreads)( OrtThreadingOptions* tp_options, int intra_op_num_threads) __attribute__((warn_unused_result)); + SetGlobalIntraOpNumThreads uintptr + // OrtStatusPtr(*SetGlobalInterOpNumThreads)( OrtThreadingOptions* tp_options, int inter_op_num_threads) __attribute__((warn_unused_result)); + SetGlobalInterOpNumThreads uintptr + // OrtStatusPtr(*SetGlobalSpinControl)( OrtThreadingOptions* tp_options, int allow_spinning) __attribute__((warn_unused_result)); + SetGlobalSpinControl uintptr + // OrtStatusPtr(*AddInitializer)( OrtSessionOptions* options, const char* name, const OrtValue* val) __attribute__((warn_unused_result)); + AddInitializer uintptr + // OrtStatusPtr(*CreateEnvWithCustomLoggerAndGlobalThreadPools)( OrtLoggingFunction logging_function, void* logger_param, OrtLoggingLevel log_severity_level, const char* logid, const struct OrtThreadingOptions* tp_options, OrtEnv** out) __attribute__((warn_unused_result)); + CreateEnvWithCustomLoggerAndGlobalThreadPools uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_CUDA)( OrtSessionOptions* options, const OrtCUDAProviderOptions* cuda_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_CUDA uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_ROCM)( OrtSessionOptions* options, const OrtROCMProviderOptions* rocm_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_ROCM uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_OpenVINO)( OrtSessionOptions* options, const OrtOpenVINOProviderOptions* provider_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_OpenVINO uintptr + // OrtStatusPtr(*SetGlobalDenormalAsZero)( OrtThreadingOptions* tp_options) __attribute__((warn_unused_result)); + SetGlobalDenormalAsZero uintptr + // OrtStatusPtr(*CreateArenaCfg)( size_t max_mem, int arena_extend_strategy, int initial_chunk_size_bytes, int max_dead_bytes_per_chunk, OrtArenaCfg** out) __attribute__((warn_unused_result)); + CreateArenaCfg uintptr + // void( *ReleaseArenaCfg)(OrtArenaCfg * input); + ReleaseArenaCfg uintptr + // OrtStatusPtr(*ModelMetadataGetGraphDescription)( const OrtModelMetadata* model_metadata, OrtAllocator* allocator, char** value) __attribute__((warn_unused_result)); + ModelMetadataGetGraphDescription uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_TensorRT)( OrtSessionOptions* options, const OrtTensorRTProviderOptions* tensorrt_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_TensorRT uintptr + // OrtStatusPtr(*SetCurrentGpuDeviceId)( int device_id) __attribute__((warn_unused_result)); + SetCurrentGpuDeviceId uintptr + // OrtStatusPtr(*GetCurrentGpuDeviceId)( int* device_id) __attribute__((warn_unused_result)); + GetCurrentGpuDeviceId uintptr + // OrtStatusPtr(*KernelInfoGetAttributeArray_float)( const OrtKernelInfo* info, const char* name, float* out, size_t* size) __attribute__((warn_unused_result)); + KernelInfoGetAttributeArray_float uintptr + // OrtStatusPtr(*KernelInfoGetAttributeArray_int64)( const OrtKernelInfo* info, const char* name, int64_t* out, size_t* size) __attribute__((warn_unused_result)); + KernelInfoGetAttributeArray_int64 uintptr + // OrtStatusPtr(*CreateArenaCfgV2)( const char* const* arena_config_keys, const size_t* arena_config_values, size_t num_keys, OrtArenaCfg** out) __attribute__((warn_unused_result)); + CreateArenaCfgV2 uintptr + // OrtStatusPtr(*AddRunConfigEntry)( OrtRunOptions* options, const char* config_key, const char* config_value) __attribute__((warn_unused_result)); + AddRunConfigEntry uintptr + // OrtStatusPtr(*CreatePrepackedWeightsContainer)( OrtPrepackedWeightsContainer** out) __attribute__((warn_unused_result)); + CreatePrepackedWeightsContainer uintptr + // void( *ReleasePrepackedWeightsContainer)(OrtPrepackedWeightsContainer * input); + ReleasePrepackedWeightsContainer uintptr + // OrtStatusPtr(*CreateSessionWithPrepackedWeightsContainer)( const OrtEnv* env, const char* model_path, const OrtSessionOptions* options, OrtPrepackedWeightsContainer* prepacked_weights_container, OrtSession** out) __attribute__((warn_unused_result)); + CreateSessionWithPrepackedWeightsContainer uintptr + // OrtStatusPtr(*CreateSessionFromArrayWithPrepackedWeightsContainer)( const OrtEnv* env, const void* model_data, size_t model_data_length, const OrtSessionOptions* options, OrtPrepackedWeightsContainer* prepacked_weights_container, OrtSession** out) __attribute__((warn_unused_result)); + CreateSessionFromArrayWithPrepackedWeightsContainer uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_TensorRT_V2)( OrtSessionOptions* options, const OrtTensorRTProviderOptionsV2* tensorrt_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_TensorRT_V2 uintptr + // OrtStatusPtr(*CreateTensorRTProviderOptions)( OrtTensorRTProviderOptionsV2** out) __attribute__((warn_unused_result)); + CreateTensorRTProviderOptions uintptr + // OrtStatusPtr(*UpdateTensorRTProviderOptions)( OrtTensorRTProviderOptionsV2* tensorrt_options, const char* const* provider_options_keys, const char* const* provider_options_values, size_t num_keys) __attribute__((warn_unused_result)); + UpdateTensorRTProviderOptions uintptr + // OrtStatusPtr(*GetTensorRTProviderOptionsAsString)( const OrtTensorRTProviderOptionsV2* tensorrt_options, OrtAllocator* allocator, char** ptr) __attribute__((warn_unused_result)); + GetTensorRTProviderOptionsAsString uintptr + // void(* ReleaseTensorRTProviderOptions)( OrtTensorRTProviderOptionsV2* input); + ReleaseTensorRTProviderOptions uintptr + // OrtStatusPtr(*EnableOrtCustomOps)( OrtSessionOptions* options) __attribute__((warn_unused_result)); + EnableOrtCustomOps uintptr + // OrtStatusPtr(*RegisterAllocator)( OrtEnv* env, OrtAllocator* allocator) __attribute__((warn_unused_result)); + RegisterAllocator uintptr + // OrtStatusPtr(*UnregisterAllocator)( OrtEnv* env, const OrtMemoryInfo* mem_info) __attribute__((warn_unused_result)); + UnregisterAllocator uintptr + // OrtStatusPtr(*IsSparseTensor)( const OrtValue* value, int* out) __attribute__((warn_unused_result)); + IsSparseTensor uintptr + // OrtStatusPtr(*CreateSparseTensorAsOrtValue)( OrtAllocator* allocator, const int64_t* dense_shape, size_t dense_shape_len, ONNXTensorElementDataType type, OrtValue** out) __attribute__((warn_unused_result)); + CreateSparseTensorAsOrtValue uintptr + // OrtStatusPtr(*FillSparseTensorCoo)( OrtValue* ort_value, const OrtMemoryInfo* data_mem_info, const int64_t* values_shape, size_t values_shape_len, const void* values, const int64_t* indices_data, size_t indices_num) __attribute__((warn_unused_result)); + FillSparseTensorCoo uintptr + // OrtStatusPtr(*FillSparseTensorCsr)( OrtValue* ort_value, const OrtMemoryInfo* data_mem_info, const int64_t* values_shape, size_t values_shape_len, const void* values, const int64_t* inner_indices_data, size_t inner_indices_num, const int64_t* outer_indices_data, size_t outer_indices_num) __attribute__((warn_unused_result)); + FillSparseTensorCsr uintptr + // OrtStatusPtr(*FillSparseTensorBlockSparse)( OrtValue* ort_value, const OrtMemoryInfo* data_mem_info, const int64_t* values_shape, size_t values_shape_len, const void* values, const int64_t* indices_shape_data, size_t indices_shape_len, const int32_t* indices_data) __attribute__((warn_unused_result)); + FillSparseTensorBlockSparse uintptr + // OrtStatusPtr(*CreateSparseTensorWithValuesAsOrtValue)( const OrtMemoryInfo* info, void* p_data, const int64_t* dense_shape, size_t dense_shape_len, const int64_t* values_shape, size_t values_shape_len, ONNXTensorElementDataType type, OrtValue** out) __attribute__((warn_unused_result)); + CreateSparseTensorWithValuesAsOrtValue uintptr + // OrtStatusPtr(*UseCooIndices)( OrtValue* ort_value, int64_t* indices_data, size_t indices_num) __attribute__((warn_unused_result)); + UseCooIndices uintptr + // OrtStatusPtr(*UseCsrIndices)( OrtValue* ort_value, int64_t* inner_data, size_t inner_num, int64_t* outer_data, size_t outer_num) __attribute__((warn_unused_result)); + UseCsrIndices uintptr + // OrtStatusPtr(*UseBlockSparseIndices)( OrtValue* ort_value, const int64_t* indices_shape, size_t indices_shape_len, int32_t* indices_data) __attribute__((warn_unused_result)); + UseBlockSparseIndices uintptr + // OrtStatusPtr(*GetSparseTensorFormat)( const OrtValue* ort_value, enum OrtSparseFormat* out) __attribute__((warn_unused_result)); + GetSparseTensorFormat uintptr + // OrtStatusPtr(*GetSparseTensorValuesTypeAndShape)( const OrtValue* ort_value, OrtTensorTypeAndShapeInfo** out) __attribute__((warn_unused_result)); + GetSparseTensorValuesTypeAndShape uintptr + // OrtStatusPtr(*GetSparseTensorValues)( const OrtValue* ort_value, const void** out) __attribute__((warn_unused_result)); + GetSparseTensorValues uintptr + // OrtStatusPtr(*GetSparseTensorIndicesTypeShape)( const OrtValue* ort_value, enum OrtSparseIndicesFormat indices_format, OrtTensorTypeAndShapeInfo** out) __attribute__((warn_unused_result)); + GetSparseTensorIndicesTypeShape uintptr + // OrtStatusPtr(*GetSparseTensorIndices)( const OrtValue* ort_value, enum OrtSparseIndicesFormat indices_format, size_t* num_indices, const void** indices) __attribute__((warn_unused_result)); + GetSparseTensorIndices uintptr + // OrtStatusPtr(*HasValue)( const OrtValue* value, int* out) __attribute__((warn_unused_result)); + HasValue uintptr + // OrtStatusPtr(*KernelContext_GetGPUComputeStream)( const OrtKernelContext* context, void** out) __attribute__((warn_unused_result)); + KernelContext_GetGPUComputeStream uintptr + // OrtStatusPtr(*GetTensorMemoryInfo)( const OrtValue* value, const OrtMemoryInfo** mem_info) __attribute__((warn_unused_result)); + GetTensorMemoryInfo uintptr + // OrtStatusPtr(*GetExecutionProviderApi)( const char* provider_name, uint32_t version, const void** provider_api) __attribute__((warn_unused_result)); + GetExecutionProviderApi uintptr + // OrtStatusPtr(*SessionOptionsSetCustomCreateThreadFn)( OrtSessionOptions* options, OrtCustomCreateThreadFn ort_custom_create_thread_fn) __attribute__((warn_unused_result)); + SessionOptionsSetCustomCreateThreadFn uintptr + // OrtStatusPtr(*SessionOptionsSetCustomThreadCreationOptions)( OrtSessionOptions* options, void* ort_custom_thread_creation_options) __attribute__((warn_unused_result)); + SessionOptionsSetCustomThreadCreationOptions uintptr + // OrtStatusPtr(*SessionOptionsSetCustomJoinThreadFn)( OrtSessionOptions* options, OrtCustomJoinThreadFn ort_custom_join_thread_fn) __attribute__((warn_unused_result)); + SessionOptionsSetCustomJoinThreadFn uintptr + // OrtStatusPtr(*SetGlobalCustomCreateThreadFn)( OrtThreadingOptions* tp_options, OrtCustomCreateThreadFn ort_custom_create_thread_fn) __attribute__((warn_unused_result)); + SetGlobalCustomCreateThreadFn uintptr + // OrtStatusPtr(*SetGlobalCustomThreadCreationOptions)( OrtThreadingOptions* tp_options, void* ort_custom_thread_creation_options) __attribute__((warn_unused_result)); + SetGlobalCustomThreadCreationOptions uintptr + // OrtStatusPtr(*SetGlobalCustomJoinThreadFn)( OrtThreadingOptions* tp_options, OrtCustomJoinThreadFn ort_custom_join_thread_fn) __attribute__((warn_unused_result)); + SetGlobalCustomJoinThreadFn uintptr + // OrtStatusPtr(*SynchronizeBoundInputs)( OrtIoBinding* binding_ptr) __attribute__((warn_unused_result)); + SynchronizeBoundInputs uintptr + // OrtStatusPtr(*SynchronizeBoundOutputs)( OrtIoBinding* binding_ptr) __attribute__((warn_unused_result)); + SynchronizeBoundOutputs uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_CUDA_V2)( OrtSessionOptions* options, const OrtCUDAProviderOptionsV2* cuda_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_CUDA_V2 uintptr + // OrtStatusPtr(*CreateCUDAProviderOptions)( OrtCUDAProviderOptionsV2** out) __attribute__((warn_unused_result)); + CreateCUDAProviderOptions uintptr + // OrtStatusPtr(*UpdateCUDAProviderOptions)( OrtCUDAProviderOptionsV2* cuda_options, const char* const* provider_options_keys, const char* const* provider_options_values, size_t num_keys) __attribute__((warn_unused_result)); + UpdateCUDAProviderOptions uintptr + // OrtStatusPtr(*GetCUDAProviderOptionsAsString)( const OrtCUDAProviderOptionsV2* cuda_options, OrtAllocator* allocator, char** ptr) __attribute__((warn_unused_result)); + GetCUDAProviderOptionsAsString uintptr + // void(* ReleaseCUDAProviderOptions)( OrtCUDAProviderOptionsV2* input); + ReleaseCUDAProviderOptions uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_MIGraphX)( OrtSessionOptions* options, const OrtMIGraphXProviderOptions* migraphx_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_MIGraphX uintptr + // OrtStatusPtr(*AddExternalInitializers)( OrtSessionOptions* options, const char* const* initializer_names, const OrtValue* const* initializers, size_t initializers_num) __attribute__((warn_unused_result)); + AddExternalInitializers uintptr + // OrtStatusPtr(*CreateOpAttr)( const char* name, const void* data, int len, OrtOpAttrType type, OrtOpAttr** op_attr) __attribute__((warn_unused_result)); + CreateOpAttr uintptr + // void( *ReleaseOpAttr)(OrtOpAttr * input); + ReleaseOpAttr uintptr + // OrtStatusPtr(*CreateOp)( const OrtKernelInfo* info, const char* op_name, const char* domain, int version, const char** type_constraint_names, const ONNXTensorElementDataType* type_constraint_values, int type_constraint_count, const OrtOpAttr* const* attr_values, int attr_count, int input_count, int output_count, OrtOp** ort_op) __attribute__((warn_unused_result)); + CreateOp uintptr + // OrtStatusPtr(*InvokeOp)( const OrtKernelContext* context, const OrtOp* ort_op, const OrtValue* const* input_values, int input_count, OrtValue* const* output_values, int output_count) __attribute__((warn_unused_result)); + InvokeOp uintptr + // void( *ReleaseOp)(OrtOp * input); + ReleaseOp uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider)( OrtSessionOptions* options, const char* provider_name, const char* const* provider_options_keys, const char* const* provider_options_values, size_t num_keys) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider uintptr + // OrtStatusPtr(*CopyKernelInfo)( const OrtKernelInfo* info, OrtKernelInfo** info_copy) __attribute__((warn_unused_result)); + CopyKernelInfo uintptr + // void( *ReleaseKernelInfo)(OrtKernelInfo * input); + ReleaseKernelInfo uintptr + // const OrtTrainingApi*(* GetTrainingApi)(uint32_t version); + GetTrainingApi uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_CANN)( OrtSessionOptions* options, const OrtCANNProviderOptions* cann_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_CANN uintptr + // OrtStatusPtr(*CreateCANNProviderOptions)( OrtCANNProviderOptions** out) __attribute__((warn_unused_result)); + CreateCANNProviderOptions uintptr + // OrtStatusPtr(*UpdateCANNProviderOptions)( OrtCANNProviderOptions* cann_options, const char* const* provider_options_keys, const char* const* provider_options_values, size_t num_keys) __attribute__((warn_unused_result)); + UpdateCANNProviderOptions uintptr + // OrtStatusPtr(*GetCANNProviderOptionsAsString)( const OrtCANNProviderOptions* cann_options, OrtAllocator* allocator, char** ptr) __attribute__((warn_unused_result)); + GetCANNProviderOptionsAsString uintptr + // void(* ReleaseCANNProviderOptions)( OrtCANNProviderOptions* input); + ReleaseCANNProviderOptions uintptr + // void(* MemoryInfoGetDeviceType)( const OrtMemoryInfo* ptr, OrtMemoryInfoDeviceType* out); + MemoryInfoGetDeviceType uintptr + // OrtStatusPtr(*UpdateEnvWithCustomLogLevel)( OrtEnv* ort_env, OrtLoggingLevel log_severity_level) __attribute__((warn_unused_result)); + UpdateEnvWithCustomLogLevel uintptr + // OrtStatusPtr(*SetGlobalIntraOpThreadAffinity)( OrtThreadingOptions* tp_options, const char* affinity_string) __attribute__((warn_unused_result)); + SetGlobalIntraOpThreadAffinity uintptr + // OrtStatusPtr(*RegisterCustomOpsLibrary_V2)( OrtSessionOptions* options, const char* library_name) __attribute__((warn_unused_result)); + RegisterCustomOpsLibrary_V2 uintptr + // OrtStatusPtr(*RegisterCustomOpsUsingFunction)( OrtSessionOptions* options, const char* registration_func_name) __attribute__((warn_unused_result)); + RegisterCustomOpsUsingFunction uintptr + // OrtStatusPtr(*KernelInfo_GetInputCount)( const OrtKernelInfo* info, size_t* out) __attribute__((warn_unused_result)); + KernelInfo_GetInputCount uintptr + // OrtStatusPtr(*KernelInfo_GetOutputCount)( const OrtKernelInfo* info, size_t* out) __attribute__((warn_unused_result)); + KernelInfo_GetOutputCount uintptr + // OrtStatusPtr(*KernelInfo_GetInputName)( const OrtKernelInfo* info, size_t index, char* out, size_t* size) __attribute__((warn_unused_result)); + KernelInfo_GetInputName uintptr + // OrtStatusPtr(*KernelInfo_GetOutputName)( const OrtKernelInfo* info, size_t index, char* out, size_t* size) __attribute__((warn_unused_result)); + KernelInfo_GetOutputName uintptr + // OrtStatusPtr(*KernelInfo_GetInputTypeInfo)( const OrtKernelInfo* info, size_t index, OrtTypeInfo** type_info) __attribute__((warn_unused_result)); + KernelInfo_GetInputTypeInfo uintptr + // OrtStatusPtr(*KernelInfo_GetOutputTypeInfo)( const OrtKernelInfo* info, size_t index, OrtTypeInfo** type_info) __attribute__((warn_unused_result)); + KernelInfo_GetOutputTypeInfo uintptr + // OrtStatusPtr(*KernelInfoGetAttribute_tensor)( const OrtKernelInfo* info, const char* name, OrtAllocator* allocator, OrtValue** out) __attribute__((warn_unused_result)); + KernelInfoGetAttribute_tensor uintptr + // OrtStatusPtr(*HasSessionConfigEntry)( const OrtSessionOptions* options, const char* config_key, int* out) __attribute__((warn_unused_result)); + HasSessionConfigEntry uintptr + // OrtStatusPtr(*GetSessionConfigEntry)( const OrtSessionOptions* options, const char* config_key, char* config_value, size_t* size) __attribute__((warn_unused_result)); + GetSessionConfigEntry uintptr + // OrtStatusPtr(*SessionOptionsAppendExecutionProvider_Dnnl)( OrtSessionOptions* options, const OrtDnnlProviderOptions* dnnl_options) __attribute__((warn_unused_result)); + SessionOptionsAppendExecutionProvider_Dnnl uintptr + // OrtStatusPtr(*CreateDnnlProviderOptions)( OrtDnnlProviderOptions** out) __attribute__((warn_unused_result)); + CreateDnnlProviderOptions uintptr + // OrtStatusPtr(*UpdateDnnlProviderOptions)( OrtDnnlProviderOptions* dnnl_options, const char* const* provider_options_keys, const char* const* provider_options_values, size_t num_keys) __attribute__((warn_unused_result)); + UpdateDnnlProviderOptions uintptr + // OrtStatusPtr(*GetDnnlProviderOptionsAsString)( const OrtDnnlProviderOptions* dnnl_options, OrtAllocator* allocator, char** ptr) __attribute__((warn_unused_result)); + GetDnnlProviderOptionsAsString uintptr + // void(* ReleaseDnnlProviderOptions)( OrtDnnlProviderOptions* input); + ReleaseDnnlProviderOptions uintptr + // OrtStatusPtr(*KernelInfo_GetNodeName)( const OrtKernelInfo* info, char* out, size_t* size) __attribute__((warn_unused_result)); + KernelInfo_GetNodeName uintptr + // OrtStatusPtr(*KernelInfo_GetLogger)( const OrtKernelInfo* info, const OrtLogger** logger) __attribute__((warn_unused_result)); + KernelInfo_GetLogger uintptr + // OrtStatusPtr(*KernelContext_GetLogger)( const OrtKernelContext* context, const OrtLogger** logger) __attribute__((warn_unused_result)); + KernelContext_GetLogger uintptr + // OrtStatusPtr(*Logger_LogMessage)( const OrtLogger* logger, OrtLoggingLevel log_severity_level, const char* message, const char* file_path, int line_number, const char* func_name) __attribute__((warn_unused_result)); + Logger_LogMessage uintptr + // OrtStatusPtr(*Logger_GetLoggingSeverityLevel)( const OrtLogger* logger, OrtLoggingLevel* out) __attribute__((warn_unused_result)); + Logger_GetLoggingSeverityLevel uintptr + // OrtStatusPtr(*KernelInfoGetConstantInput_tensor)( const OrtKernelInfo* info, size_t index, int* is_constant, const OrtValue** out) __attribute__((warn_unused_result)); + KernelInfoGetConstantInput_tensor uintptr + // OrtStatusPtr(*CastTypeInfoToOptionalTypeInfo)( const OrtTypeInfo* type_info, const OrtOptionalTypeInfo** out) __attribute__((warn_unused_result)); + CastTypeInfoToOptionalTypeInfo uintptr + // OrtStatusPtr(*GetOptionalContainedTypeInfo)( const OrtOptionalTypeInfo* optional_type_info, OrtTypeInfo** out) __attribute__((warn_unused_result)); + GetOptionalContainedTypeInfo uintptr + // OrtStatusPtr(*GetResizedStringTensorElementBuffer)( OrtValue* value, size_t index, size_t length_in_bytes, char** buffer) __attribute__((warn_unused_result)); + GetResizedStringTensorElementBuffer uintptr + // OrtStatusPtr(*KernelContext_GetAllocator)( const OrtKernelContext* context, const OrtMemoryInfo* mem_info, OrtAllocator** out) __attribute__((warn_unused_result)); + KernelContext_GetAllocator uintptr + // const char*(* GetBuildInfoString)(void); + GetBuildInfoString uintptr +} diff --git a/go.mod b/go.mod index bc0694946..90a1ca488 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ toolchain go1.24.3 require ( github.com/Masterminds/semver v1.5.0 github.com/doug-martin/goqu/v8 v8.6.0 + github.com/ebitengine/purego v0.8.4 github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 github.com/jackc/pgconn v1.14.3 diff --git a/go.sum b/go.sum index 982985b65..28036ec5f 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/doug-martin/goqu/v8 v8.6.0 h1:KWuDGL135poBgY+SceArvOtIIEpieNKgIZCvger github.com/doug-martin/goqu/v8 v8.6.0/go.mod h1:wiiYWkiguNXK5d4kGIkYmOxBScEL37d9Cfv9tXhPsTk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= +github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=