#include "onnxruntime_wrapper.h" static const OrtApi *ort_api = NULL; static const char *ORT_VERSION = NULL; static AppendCoreMLProviderFn append_coreml_provider_fn = NULL; // The dml_provider_factory.h header for using DirectML is annoying to include // here for a couple reasons: // - It contains C++ // - It includes d3d12.h and DirectML.h, both of which may be hard to set up // under mingw // Fortunately, the basic AppendExecutionProvider_DML function from the // OrtDmlApi struct does not rely on any of these things, but we still need the // struct definition itself. Obviously, copying it here is not perfect, and // we'll need to keep an eye on it to make sure it doesn't change between // updates. Most importantly, we need to make sure that the one function we // care about remains at the same place in the struct. Since it's first, // hopefully it's unlikely to change. typedef OrtStatus* (*AppendDirectMLProviderFn)(OrtSessionOptions*, int); typedef struct { AppendDirectMLProviderFn SessionOptionsAppendExecutionProvider_DML; // All of these functions pointers should be irrelevant (and they depend on // other definitions from dml_provider_factory.h), but I'll copy them here // regardless as plain void*s. GetExecutionProviderApi shouldn't write to // this struct anyway, as it only provides a const pointer to it. void *SessionOptionsAppendExecutionProvider_DML1; void *CreateGPUAllocationFromD3DResource; void *FreeGPUAllocation; void *GetD3D12ResourceFromAllocation; void *SessionOptionsAppendExecutionProvider_DML2; void *GetDMLDevice; void *GetDMLCommandQueue; } DummyOrtDMLAPI; int SetAPIFromBase(OrtApiBase *api_base) { if (!api_base) return 1; ort_api = api_base->GetApi(ORT_API_VERSION); ORT_VERSION = api_base->GetVersionString(); if (!ort_api) return 2; return 0; } const char *GetVersion() { return ORT_VERSION; } void SetCoreMLProviderFunctionPointer(void *ptr) { append_coreml_provider_fn = (AppendCoreMLProviderFn) ptr; } void ReleaseOrtStatus(OrtStatus *status) { ort_api->ReleaseStatus(status); } OrtStatus *CreateOrtEnv(char *name, OrtEnv **env) { return ort_api->CreateEnv(ORT_LOGGING_LEVEL_ERROR, name, env); } OrtStatus *UpdateEnvWithCustomLogLevel(OrtEnv *ort_env, OrtLoggingLevel log_severity_level) { return ort_api->UpdateEnvWithCustomLogLevel(ort_env, log_severity_level); } OrtStatus *DisableTelemetry(OrtEnv *env) { return ort_api->DisableTelemetryEvents(env); } OrtStatus *EnableTelemetry(OrtEnv *env) { return ort_api->EnableTelemetryEvents(env); } void ReleaseOrtEnv(OrtEnv *env) { ort_api->ReleaseEnv(env); } OrtStatus *CreateOrtMemoryInfo(OrtMemoryInfo **mem_info) { return ort_api->CreateCpuMemoryInfo(OrtArenaAllocator, OrtMemTypeDefault, mem_info); } void ReleaseOrtMemoryInfo(OrtMemoryInfo *info) { ort_api->ReleaseMemoryInfo(info); } const char *GetErrorMessage(OrtStatus *status) { if (!status) return "No error (NULL status)"; return ort_api->GetErrorMessage(status); } OrtStatus *CreateSessionOptions(OrtSessionOptions **o) { return ort_api->CreateSessionOptions(o); } void ReleaseSessionOptions(OrtSessionOptions *o) { ort_api->ReleaseSessionOptions(o); } OrtStatus *SetSessionExecutionMode(OrtSessionOptions *o, int new_mode) { return ort_api->SetSessionExecutionMode(o, new_mode); } OrtStatus *SetSessionGraphOptimizationLevel(OrtSessionOptions *o, int level) { return ort_api->SetSessionGraphOptimizationLevel(o, level); } OrtStatus *SetSessionLogSeverityLevel(OrtSessionOptions *o, int level) { return ort_api->SetSessionLogSeverityLevel(o, level); } OrtStatus *AddSessionConfigEntry(OrtSessionOptions *o, char *key, char *value) { return ort_api->AddSessionConfigEntry(o, key, value); } OrtStatus *HasSessionConfigEntry(OrtSessionOptions *o, char *key, int *result) { return ort_api->HasSessionConfigEntry(o, key, result); } // Wraps ort_api->GetSessionConfigEntry OrtStatus *GetSessionConfigEntry(OrtSessionOptions *o, char *key, char *result, size_t *required_size) { return ort_api->GetSessionConfigEntry(o, key, result, required_size); } OrtStatus *SetIntraOpNumThreads(OrtSessionOptions *o, int n) { return ort_api->SetIntraOpNumThreads(o, n); } OrtStatus *SetInterOpNumThreads(OrtSessionOptions *o, int n) { return ort_api->SetInterOpNumThreads(o, n); } OrtStatus *SetCpuMemArena(OrtSessionOptions *o, int use_arena){ if (use_arena) return ort_api->EnableCpuMemArena(o); return ort_api->DisableCpuMemArena(o); } OrtStatus *SetMemPattern(OrtSessionOptions *o, int use_mem_pattern){ if (use_mem_pattern) return ort_api->EnableMemPattern(o); return ort_api->DisableMemPattern(o); } OrtStatus *AppendExecutionProviderCUDAV2(OrtSessionOptions *o, OrtCUDAProviderOptionsV2 *cuda_options) { return ort_api->SessionOptionsAppendExecutionProvider_CUDA_V2(o, cuda_options); } OrtStatus *CreateCUDAProviderOptions(OrtCUDAProviderOptionsV2 **o) { return ort_api->CreateCUDAProviderOptions(o); } void ReleaseCUDAProviderOptions(OrtCUDAProviderOptionsV2 *o) { ort_api->ReleaseCUDAProviderOptions(o); } OrtStatus *UpdateCUDAProviderOptions(OrtCUDAProviderOptionsV2 *o, const char **keys, const char **values, int num_keys) { return ort_api->UpdateCUDAProviderOptions(o, keys, values, num_keys); } OrtStatus *CreateTensorRTProviderOptions(OrtTensorRTProviderOptionsV2 **o) { return ort_api->CreateTensorRTProviderOptions(o); } void ReleaseTensorRTProviderOptions(OrtTensorRTProviderOptionsV2 *o) { ort_api->ReleaseTensorRTProviderOptions(o); } OrtStatus *UpdateTensorRTProviderOptions(OrtTensorRTProviderOptionsV2 *o, const char **keys, const char **values, int num_keys) { return ort_api->UpdateTensorRTProviderOptions(o, keys, values, num_keys); } OrtStatus *AppendExecutionProviderTensorRTV2(OrtSessionOptions *o, OrtTensorRTProviderOptionsV2 *tensor_rt_options) { return ort_api->SessionOptionsAppendExecutionProvider_TensorRT_V2(o, tensor_rt_options); } OrtStatus *AppendExecutionProviderCoreML(OrtSessionOptions *o, uint32_t flags) { if (!append_coreml_provider_fn) { return ort_api->CreateStatus(ORT_NOT_IMPLEMENTED, "Your platform or " "onnxruntime library does not support CoreML"); } return append_coreml_provider_fn(o, flags); } OrtStatus *AppendExecutionProviderCoreMLV2(OrtSessionOptions *o, const char **keys, const char **values, size_t num_options) { if (!append_coreml_provider_fn) { return ort_api->CreateStatus(ORT_NOT_IMPLEMENTED, "Your platform or " "onnxruntime library does not support CoreML"); } return ort_api->SessionOptionsAppendExecutionProvider(o, "CoreML", keys, values, num_options); } OrtStatus *AppendExecutionProviderDirectML(OrtSessionOptions *o, int device_id) { DummyOrtDMLAPI *dml_api = NULL; OrtStatus *status = NULL; status = ort_api->GetExecutionProviderApi("DML", ORT_API_VERSION, (const void **) (&dml_api)); if (status) return status; status = dml_api->SessionOptionsAppendExecutionProvider_DML(o, device_id); return status; } OrtStatus *AppendExecutionProviderOpenVINOV2(OrtSessionOptions *o, const char **keys, const char **values, int num_keys) { return ort_api->SessionOptionsAppendExecutionProvider_OpenVINO_V2(o, keys, values, num_keys); } OrtStatus *AppendExecutionProvider(OrtSessionOptions *o, const char *provider_name, const char **keys, const char **values, int num_keys) { return ort_api->SessionOptionsAppendExecutionProvider(o, provider_name, keys, values, num_keys); } OrtStatus *SetOptimizedModelFilePath(OrtSessionOptions *o, char *path) { return ort_api->SetOptimizedModelFilePath(o, (const ORTCHAR_T*) path); } OrtStatus *EnableProfiling(OrtSessionOptions *o, char *path) { return ort_api->EnableProfiling(o, (const ORTCHAR_T*) path); } OrtStatus *DisableProfiling(OrtSessionOptions *o) { return ort_api->DisableProfiling(o); } OrtStatus *RegisterExecutionProviderLibrary(OrtEnv *env, const char *registration_name, char *path) { return ort_api->RegisterExecutionProviderLibrary(env, registration_name, (const ORTCHAR_T *) path); } OrtStatus *UnregisterExecutionProviderLibrary(OrtEnv *env, const char *registration_name) { return ort_api->UnregisterExecutionProviderLibrary(env, registration_name); } OrtStatus *RegisterCustomOpsLibraryV2( OrtSessionOptions *o, const char *library_path) { return ort_api->RegisterCustomOpsLibrary_V2(o, library_path); } OrtStatus *GetEpDevices(OrtEnv *env, const OrtEpDevice * const **out_devices, size_t *out_count) { return ort_api->GetEpDevices(env, out_devices, out_count); } const char *EpDeviceEpName(const OrtEpDevice *device) { return ort_api->EpDevice_EpName(device); } const char *EpDeviceEpVendor(const OrtEpDevice *device) { return ort_api->EpDevice_EpVendor(device); } OrtStatus *AppendExecutionProviderV2(OrtSessionOptions *o, OrtEnv *env, const OrtEpDevice * const *ep_devices, size_t num_ep_devices, const char **keys, const char **values, size_t num_keys) { return ort_api->SessionOptionsAppendExecutionProvider_V2(o, env, ep_devices, num_ep_devices, keys, values, num_keys); } OrtStatus *CreateArenaCfg(size_t max_mem, int arena_extend_strategy, int initial_chunk_size_bytes, int max_dead_bytes_per_chunk, OrtArenaCfg **out) { return ort_api->CreateArenaCfg(max_mem, arena_extend_strategy, initial_chunk_size_bytes, max_dead_bytes_per_chunk, out); } OrtStatus *CreateArenaCfgV2(const char *const *arena_config_keys, const size_t *arena_config_values, size_t num_keys, OrtArenaCfg **out) { return ort_api->CreateArenaCfgV2(arena_config_keys, arena_config_values, num_keys, out); } void ReleaseArenaCfg(OrtArenaCfg *ptr) { ort_api->ReleaseArenaCfg(ptr); } OrtStatus *CreateAndRegisterAllocator(OrtEnv *env, const OrtMemoryInfo *mem_info, const OrtArenaCfg *arena_cfg) { return ort_api->CreateAndRegisterAllocator(env, mem_info, arena_cfg); } OrtStatus *CreateAndRegisterAllocatorV2(OrtEnv *env, const char *provider_type, const OrtMemoryInfo *mem_info, const OrtArenaCfg *arena_cfg, const char *const *provider_options_keys, const char *const *provider_options_values, size_t num_keys) { return ort_api->CreateAndRegisterAllocatorV2(env, provider_type, mem_info, arena_cfg, provider_options_keys, provider_options_values, num_keys); } OrtStatus *RegisterAllocator(OrtEnv *env, OrtAllocator *allocator) { return ort_api->RegisterAllocator(env, allocator); } OrtStatus *UnregisterAllocator(OrtEnv *env, const OrtMemoryInfo *mem_info) { return ort_api->UnregisterAllocator(env, mem_info); } OrtStatus *CreateSession(void *model_data, size_t model_data_length, OrtEnv *env, OrtSession **out, OrtSessionOptions *options) { OrtStatus *status = NULL; int default_options = 0; if (!options) { default_options = 1; status = ort_api->CreateSessionOptions(&options); if (status) return status; } status = ort_api->CreateSessionFromArray(env, model_data, model_data_length, options, out); if (default_options) { // If we created a default, empty, options struct, we don't need to keep it // after creating the session. ort_api->ReleaseSessionOptions(options); } return status; } OrtStatus *CreateSessionFromFile(char *model_path, OrtEnv *env, OrtSession **out, OrtSessionOptions *options) { // Nearly identical to CreateSession, except invokes ort_api->CreateSession // rather than ort_api->CreateSessionFromArray. OrtStatus *status = NULL; int default_options = 0; if (!options) { default_options = 1; status = ort_api->CreateSessionOptions(&options); if (status) return status; } status = ort_api->CreateSession(env, (const ORTCHAR_T*) model_path, options, out); if (default_options) ort_api->ReleaseSessionOptions(options); return status; } OrtStatus *RunOrtSession(OrtSession *session, OrtValue **inputs, char **input_names, int input_count, OrtValue **outputs, char **output_names, int output_count) { OrtStatus *status = NULL; status = ort_api->Run(session, NULL, (const char* const*) input_names, (const OrtValue* const*) inputs, input_count, (const char* const*) output_names, output_count, outputs); return status; } OrtStatus *RunOrtSessionWithOptions(OrtSession *session, OrtValue **inputs, char **input_names, int input_count, OrtValue **outputs, char **output_names, int output_count, OrtRunOptions *run_options) { OrtStatus *status = NULL; status = ort_api->Run(session, run_options, (const char* const*) input_names, (const OrtValue* const*) inputs, input_count, (const char* const*) output_names, output_count, outputs); return status; } OrtStatus *CreateRunOptions(OrtRunOptions **o) { return ort_api->CreateRunOptions(o); } void ReleaseRunOptions(OrtRunOptions *o) { ort_api->ReleaseRunOptions(o); } OrtStatus *RunOptionsSetTerminate(OrtRunOptions *o) { return ort_api->RunOptionsSetTerminate(o); } OrtStatus *RunOptionsUnsetTerminate(OrtRunOptions *o) { return ort_api->RunOptionsUnsetTerminate(o); } OrtStatus *RunSessionWithBinding(OrtSession *session, OrtIoBinding *b) { return ort_api->RunWithBinding(session, NULL, b); } void ReleaseOrtSession(OrtSession *session) { ort_api->ReleaseSession(session); } OrtStatus *CreateIoBinding(OrtSession *session, OrtIoBinding **out) { return ort_api->CreateIoBinding(session, out); } void ReleaseIoBinding(OrtIoBinding *b) { ort_api->ReleaseIoBinding(b); } OrtStatus *BindInput(OrtIoBinding *b, char *name, OrtValue *value) { return ort_api->BindInput(b, name, value); } OrtStatus *BindOutput(OrtIoBinding *b, char *name, OrtValue *value) { return ort_api->BindOutput(b, name, value); } OrtStatus *GetBoundOutputNames(OrtIoBinding *b, char **buffer, size_t **lengths, size_t *count) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->GetBoundOutputNames(b, allocator, buffer, lengths, count); } OrtStatus *SessionGetInputCount(OrtSession *session, size_t *result) { return ort_api->SessionGetInputCount(session, result); } OrtStatus *GetBoundOutputValues(OrtIoBinding *b, OrtValue ***buffer, size_t *count) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->GetBoundOutputValues(b, allocator, buffer, count); } void ClearBoundInputs(OrtIoBinding *b) { ort_api->ClearBoundInputs(b); } void ClearBoundOutputs(OrtIoBinding *b) { ort_api->ClearBoundOutputs(b); } OrtStatus *SessionGetOutputCount(OrtSession *session, size_t *result) { return ort_api->SessionGetOutputCount(session, result); } void ReleaseOrtValue(OrtValue *value) { ort_api->ReleaseValue(value); } OrtStatus *CreateOrtTensorWithShape(void *data, size_t data_size, int64_t *shape, int64_t shape_size, OrtMemoryInfo *mem_info, ONNXTensorElementDataType dtype, OrtValue **out) { OrtStatus *status = NULL; status = ort_api->CreateTensorWithDataAsOrtValue(mem_info, data, data_size, shape, shape_size, dtype, out); return status; } OrtStatus *CreateTensorAsOrtValue(int64_t *shape, int64_t shape_size, ONNXTensorElementDataType dtype, OrtValue **out) { OrtStatus *status = NULL; OrtAllocator *allocator = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; status = ort_api->CreateTensorAsOrtValue(allocator, shape, shape_size, dtype, out); return status; } OrtStatus *GetTensorTypeAndShape(const OrtValue *value, OrtTensorTypeAndShapeInfo **out) { return ort_api->GetTensorTypeAndShape(value, out); } OrtStatus *GetDimensionsCount(const OrtTensorTypeAndShapeInfo *info, size_t *out) { return ort_api->GetDimensionsCount(info, out); } OrtStatus *GetDimensions(const OrtTensorTypeAndShapeInfo *info, int64_t *dim_values, size_t dim_values_length) { return ort_api->GetDimensions(info, dim_values, dim_values_length); } OrtStatus *GetTensorElementType(const OrtTensorTypeAndShapeInfo *info, enum ONNXTensorElementDataType *out) { return ort_api->GetTensorElementType(info, out); } void ReleaseTensorTypeAndShapeInfo(OrtTensorTypeAndShapeInfo *input) { ort_api->ReleaseTensorTypeAndShapeInfo(input); } OrtStatus *GetTensorMutableData(OrtValue *value, void **out) { return ort_api->GetTensorMutableData(value, out); } OrtStatus *SessionGetInputName(OrtSession *session, size_t i, char **name) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->SessionGetInputName(session, i, allocator, name); } OrtStatus *SessionGetOutputName(OrtSession *session, size_t i, char **name) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->SessionGetOutputName(session, i, allocator, name); } OrtStatus *FreeWithDefaultORTAllocator(void *to_free) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->AllocatorFree(allocator, to_free); } OrtStatus *SessionGetInputTypeInfo(OrtSession *session, size_t i, OrtTypeInfo **out) { return ort_api->SessionGetInputTypeInfo(session, i, out); } OrtStatus *SessionGetOutputTypeInfo(OrtSession *session, size_t i, OrtTypeInfo **out) { return ort_api->SessionGetOutputTypeInfo(session, i, out); } void ReleaseTypeInfo(OrtTypeInfo *o) { ort_api->ReleaseTypeInfo(o); } OrtStatus *GetONNXTypeFromTypeInfo(OrtTypeInfo *info, enum ONNXType *out) { return ort_api->GetOnnxTypeFromTypeInfo(info, out); } OrtStatus *CastTypeInfoToTensorInfo(OrtTypeInfo *type_info, OrtTensorTypeAndShapeInfo **out) { return ort_api->CastTypeInfoToTensorInfo(type_info, (const OrtTensorTypeAndShapeInfo **) out); } OrtStatus *SessionGetModelMetadata(OrtSession *s, OrtModelMetadata **m) { return ort_api->SessionGetModelMetadata(s, m); } void ReleaseModelMetadata(OrtModelMetadata *m) { return ort_api->ReleaseModelMetadata(m); } OrtStatus *ModelMetadataGetProducerName(OrtModelMetadata *m, char **name) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->ModelMetadataGetProducerName(m, allocator, name); } OrtStatus *ModelMetadataGetGraphName(OrtModelMetadata *m, char **name) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->ModelMetadataGetGraphName(m, allocator, name); } OrtStatus *ModelMetadataGetDomain(OrtModelMetadata *m, char **domain) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->ModelMetadataGetDomain(m, allocator, domain); } OrtStatus *ModelMetadataGetDescription(OrtModelMetadata *m, char **desc) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->ModelMetadataGetDescription(m, allocator, desc); } OrtStatus *ModelMetadataLookupCustomMetadataMap(OrtModelMetadata *m, char *key, char **value) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->ModelMetadataLookupCustomMetadataMap(m, allocator, key, value); } OrtStatus *ModelMetadataGetCustomMetadataMapKeys(OrtModelMetadata *m, char ***keys, int64_t *num_keys) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->ModelMetadataGetCustomMetadataMapKeys(m, allocator, keys, num_keys); } OrtStatus *ModelMetadataGetVersion(OrtModelMetadata *m, int64_t *version) { return ort_api->ModelMetadataGetVersion(m, version); } OrtStatus *GetValue(OrtValue *container, int index, OrtValue **dst) { OrtAllocator *allocator = NULL; OrtStatus *status = NULL; status = ort_api->GetAllocatorWithDefaultOptions(&allocator); if (status) return status; return ort_api->GetValue(container, index, allocator, dst); } OrtStatus *GetValueType(OrtValue *v, enum ONNXType *out) { return ort_api->GetValueType(v, out); } OrtStatus *GetValueCount(OrtValue *v, size_t *out) { return ort_api->GetValueCount(v, out); } OrtStatus *CreateOrtValue(OrtValue **in, size_t num_values, enum ONNXType value_type, OrtValue **out) { return ort_api->CreateValue((const OrtValue* const*) in, num_values, value_type, out); } OrtStatus *FillStringTensor(OrtValue *v, char **strings, size_t num_strings) { return ort_api->FillStringTensor(v, (const char* const*) strings, num_strings); } OrtStatus *GetStringTensorDataLength(OrtValue *v, size_t *length) { return ort_api->GetStringTensorDataLength(v, length); } OrtStatus *GetStringTensorContent(OrtValue *v, void *data_buffer, size_t data_size, size_t *offsets_buffer, size_t offsets_length) { return ort_api->GetStringTensorContent(v, data_buffer, data_size, offsets_buffer, offsets_length); } OrtStatus *FillStringTensorElement(OrtValue *v, char *s, size_t index) { return ort_api->FillStringTensorElement(v, s, index); } OrtStatus *GetStringTensorElementLength(OrtValue *v, size_t index, size_t *result) { return ort_api->GetStringTensorElementLength(v, index, result); } OrtStatus *GetStringTensorElement(OrtValue *v, size_t buffer_length, size_t index, void *buffer) { return ort_api->GetStringTensorElement(v, buffer_length, index, buffer); }