Merge pull request #1 from microsoft/yguo/add-initial-files
Create initial contents for new onnxruntime-swift-package-manager repo
This commit is contained in:
@@ -396,3 +396,8 @@ FodyWeavers.xsd
|
|||||||
|
|
||||||
# JetBrains Rider
|
# JetBrains Rider
|
||||||
*.sln.iml
|
*.sln.iml
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
*.DS_Store
|
||||||
|
|
||||||
|
.build/
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
jobs:
|
||||||
|
- job: j
|
||||||
|
displayName: "Test with latest local ORT native pod"
|
||||||
|
|
||||||
|
pool:
|
||||||
|
vmImage: "macOS-13"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
xcodeVersion: "14.3"
|
||||||
|
artifactsName: "ios_packaging_artifacts_full"
|
||||||
|
|
||||||
|
timeoutInMinutes: 60
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- template: templates/use-xcode-version.yml
|
||||||
|
parameters:
|
||||||
|
xcodeVersion: ${{ variables.xcodeVersion }}
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
mkdir tmp
|
||||||
|
cd tmp
|
||||||
|
git clone -n --depth=1 --filter=tree:0 https://github.com/microsoft/onnxruntime.git
|
||||||
|
cd onnxruntime
|
||||||
|
git sparse-checkout set --no-cone objectivec swift Package.swift
|
||||||
|
git checkout
|
||||||
|
workingDirectory: "$(Build.SourcesDirectory)"
|
||||||
|
displayName: "Sparse checkout objectivec/ swift/ folders from latest ORT main repository"
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
ls -R "$(Build.SourcesDirectory)/tmp/onnxruntime"
|
||||||
|
workingDirectory: "$(Build.SourcesDirectory)/tmp"
|
||||||
|
displayName: "List sparse checkout repo contents"
|
||||||
|
|
||||||
|
# Download artifacts from a specific pipeline
|
||||||
|
# For now, it consumes rel-1.15.0 version ORT iOS Pod which matches the current source code
|
||||||
|
# TODO: Update branch to latest main of ORT github repo when syncing changes to ORT SPM repo here.
|
||||||
|
- task: DownloadPipelineArtifact@2
|
||||||
|
inputs:
|
||||||
|
buildType: 'specific'
|
||||||
|
project: 'Lotus'
|
||||||
|
definition: 995 #'definitionid' is obtained from `System.DefinitionId` of ORT CI: onnxruntime-ios-packaging-pipeline
|
||||||
|
buildVersionToDownload: 'latest'
|
||||||
|
branchName: 'main'
|
||||||
|
targetPath: '$(Build.ArtifactStagingDirectory)'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
set -e -x
|
||||||
|
ls
|
||||||
|
workingDirectory: '$(Build.ArtifactStagingDirectory)/$(artifactsName)'
|
||||||
|
displayName: "List staged artifacts"
|
||||||
|
|
||||||
|
# copy the pod archive to a path relative to Package.swift and set the env var required by Package.swift to use that.
|
||||||
|
# xcodebuild will implicitly use Package.swift and build/run the .testTarget (tests in swift/onnxTests).
|
||||||
|
# once that's done cleanup the copy of the pod zip file
|
||||||
|
- script: |
|
||||||
|
set -e -x
|
||||||
|
cd "$(Build.ArtifactStagingDirectory)/$(artifactsName)"
|
||||||
|
POD_ARCHIVE=$(find . -name "pod-archive-onnxruntime-c*.zip")
|
||||||
|
|
||||||
|
shasum -a 256 "$(Build.ArtifactStagingDirectory)/$(artifactsName)/${POD_ARCHIVE}"
|
||||||
|
|
||||||
|
cd "$(Build.SourcesDirectory)/tmp/onnxruntime"
|
||||||
|
cp "$(Build.ArtifactStagingDirectory)/$(artifactsName)/${POD_ARCHIVE}" swift/
|
||||||
|
export ORT_IOS_POD_LOCAL_PATH="swift/${POD_ARCHIVE}"
|
||||||
|
xcodebuild test -scheme onnxruntime -destination 'platform=iOS Simulator,name=iPhone 14'
|
||||||
|
rm swift/pod-archive-onnxruntime-c-*.zip
|
||||||
|
workingDirectory: "$(Build.SourcesDirectory)/tmp"
|
||||||
|
displayName: "Print ORT iOS Pod checksum and Test Package.swift usage"
|
||||||
|
|
||||||
|
- template: templates/component-governance-component-detection-steps.yml
|
||||||
|
parameters :
|
||||||
|
condition : 'succeeded'
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
jobs:
|
||||||
|
- job: j
|
||||||
|
displayName: "Test with released ORT native pod"
|
||||||
|
|
||||||
|
pool:
|
||||||
|
vmImage: "macOS-13"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
xcodeVersion: "14.3"
|
||||||
|
|
||||||
|
timeoutInMinutes: 60
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- template: templates/use-xcode-version.yml
|
||||||
|
parameters:
|
||||||
|
xcodeVersion: ${{ variables.xcodeVersion }}
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
set -e -x
|
||||||
|
xcodebuild test -scheme onnxruntime -destination 'platform=iOS Simulator,name=iPhone 14'
|
||||||
|
workingDirectory: "$(Build.SourcesDirectory)"
|
||||||
|
displayName: "Test Package.swift usage"
|
||||||
|
|
||||||
|
- template: templates/component-governance-component-detection-steps.yml
|
||||||
|
parameters :
|
||||||
|
condition : 'succeeded'
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# component detection for component governance checks
|
||||||
|
parameters:
|
||||||
|
- name: condition
|
||||||
|
type: string
|
||||||
|
default: 'succeeded' # could be 'ci_only', 'always', 'succeeded'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- ${{ if eq(variables['System.TeamProject'], 'Lotus') }}:
|
||||||
|
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||||
|
displayName: 'Component Detection'
|
||||||
|
condition:
|
||||||
|
or(or(and(eq('${{parameters.condition}}', 'ci_only'), and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'Scheduled'))),
|
||||||
|
and(eq('${{parameters.condition}}', 'always'), always())),
|
||||||
|
and(eq('${{parameters.condition}}', 'succeeded'), succeeded()))
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Specify use of a specific Xcode version.
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
- name: xcodeVersion
|
||||||
|
type: string
|
||||||
|
default: "14.3"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- bash: |
|
||||||
|
set -e -x
|
||||||
|
XCODE_DEVELOPER_DIR="/Applications/Xcode_${{ parameters.xcodeVersion }}.app/Contents/Developer"
|
||||||
|
sudo xcode-select --switch "${XCODE_DEVELOPER_DIR}"
|
||||||
|
|
||||||
|
displayName: Use Xcode ${{ parameters.xcodeVersion }}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
// swift-tools-version: 5.6
|
||||||
|
// The swift-tools-version declares the minimum version of Swift required to build this package and MUST be the first
|
||||||
|
// line of this file. 5.6 is required to support zip files for the pod archive binaryTarget.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
// A user of the Swift Package Manager (SPM) package will consume this file directly from the ORT github repository.
|
||||||
|
// For context, the end user's config will look something like:
|
||||||
|
//
|
||||||
|
// dependencies: [
|
||||||
|
// #TODO: update to use release 'version' and the new repo url here when available
|
||||||
|
// .package(url: "https://github.com/microsoft/onnxruntime", branch: "rel-1.15.0"),
|
||||||
|
// ...
|
||||||
|
// ],
|
||||||
|
//
|
||||||
|
|
||||||
|
import PackageDescription
|
||||||
|
import class Foundation.ProcessInfo
|
||||||
|
|
||||||
|
let package = Package(
|
||||||
|
name: "onnxruntime",
|
||||||
|
platforms: [.iOS(.v11)],
|
||||||
|
products: [
|
||||||
|
.library(name: "onnxruntime",
|
||||||
|
type: .static,
|
||||||
|
targets: ["OnnxRuntimeBindings"]),
|
||||||
|
],
|
||||||
|
dependencies: [],
|
||||||
|
targets: [
|
||||||
|
.target(name: "OnnxRuntimeBindings",
|
||||||
|
dependencies: ["onnxruntime"],
|
||||||
|
path: "objectivec",
|
||||||
|
exclude: ["ReadMe.md", "format_objc.sh"],
|
||||||
|
cxxSettings: [
|
||||||
|
.define("SPM_BUILD"),
|
||||||
|
.unsafeFlags(["-std=c++17",
|
||||||
|
"-fobjc-arc-exceptions"
|
||||||
|
]),
|
||||||
|
], linkerSettings: [
|
||||||
|
.unsafeFlags(["-ObjC"]),
|
||||||
|
]),
|
||||||
|
.testTarget(name: "OnnxRuntimeBindingsTests",
|
||||||
|
dependencies: ["OnnxRuntimeBindings"],
|
||||||
|
path: "swift/OnnxRuntimeBindingsTests",
|
||||||
|
resources: [
|
||||||
|
.copy("Resources/single_add.basic.ort")
|
||||||
|
]),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
// Add the ORT iOS Pod archive as a binary target.
|
||||||
|
//
|
||||||
|
// There are 2 scenarios:
|
||||||
|
//
|
||||||
|
// Release version of ORT SPM github repo:
|
||||||
|
// Target will be set to the latest released ORT iOS pod archive and its checksum.
|
||||||
|
//
|
||||||
|
// Current main of ORT SPM github repo:
|
||||||
|
// Target will be set to the pod archive built in sync with the current main objective-c source code.
|
||||||
|
|
||||||
|
// CI or local testing where you have built/obtained the iOS Pod archive matching the current source code.
|
||||||
|
// Requires the ORT_IOS_POD_LOCAL_PATH environment variable to be set to specify the location of the pod.
|
||||||
|
if let pod_archive_path = ProcessInfo.processInfo.environment["ORT_IOS_POD_LOCAL_PATH"] {
|
||||||
|
// ORT_IOS_POD_LOCAL_PATH MUST be a path that is relative to Package.swift.
|
||||||
|
//
|
||||||
|
// To build locally, tools/ci_build/github/apple/build_and_assemble_ios_pods.py can be used
|
||||||
|
// See https://onnxruntime.ai/docs/build/custom.html#ios
|
||||||
|
// Example command:
|
||||||
|
// python3 tools/ci_build/github/apple/build_and_assemble_ios_pods.py \
|
||||||
|
// --variant Full \
|
||||||
|
// --build-settings-file tools/ci_build/github/apple/default_full_ios_framework_build_settings.json
|
||||||
|
//
|
||||||
|
// This should produce the pod archive in build/ios_pod_staging, and ORT_IOS_POD_LOCAL_PATH can be set to
|
||||||
|
// "build/ios_pod_staging/pod-archive-onnxruntime-c-???.zip" where '???' is replaced by the version info in the
|
||||||
|
// actual filename.
|
||||||
|
package.targets.append(Target.binaryTarget(name: "onnxruntime", path: pod_archive_path))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// ORT 1.15.0 release
|
||||||
|
package.targets.append(
|
||||||
|
Target.binaryTarget(name: "onnxruntime",
|
||||||
|
url: "https://onnxruntimepackages.z14.web.core.windows.net/pod-archive-onnxruntime-c-1.15.0.zip",
|
||||||
|
checksum: "9b41412329a73d7d298b1d94ab40ae9adb65cb84f132054073bc82515b4f5f82")
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
# Project
|
# Swift Package Manager for ONNX Runtime
|
||||||
|
|
||||||
> This repo has been populated by an initial template to help get you started. Please
|
A light-weight repository for providing [Swift Package Manager (SPM)](https://www.swift.org/package-manager/) support for [ONNXRuntime](https://github.com/microsoft/onnxruntime). The ONNX Runtime native package is included as a binary dependency of the SPM package.
|
||||||
> make sure to update the content to build a great experience for community-building.
|
|
||||||
|
|
||||||
As the maintainer of this project, please make a few updates:
|
|
||||||
|
|
||||||
- Improving this README.MD file to provide a great experience
|
SPM is the alternative to CocoaPods when desired platform to consume is mobile iOS.
|
||||||
- Updating SUPPORT.MD with content about this project's support experience
|
|
||||||
- Understanding the security reporting process in SECURITY.MD
|
## Note
|
||||||
- Remove this section from the README
|
|
||||||
|
The `objectivec/` and `swift/` directories are copied from ORT repo and it's expected to match. It will be updated periodically/before release to merge the newly checked-in changes for objective-c/swift on ORT main repo.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
NOTE: Flat directory structure to work with both the Objective-C build and the Swift Package Manager build which is done
|
||||||
|
via ../Package.swift
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
static_assert(__has_feature(objc_arc), "Objective-C ARC must be enabled.");
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// wrapper for ORT C/C++ API headers
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
// ignore clang documentation-related warnings
|
||||||
|
// instead, we will rely on Doxygen warnings for the C/C++ API headers
|
||||||
|
#pragma clang diagnostic ignored "-Wdocumentation"
|
||||||
|
#endif // defined(__clang__)
|
||||||
|
|
||||||
|
// paths are different when building the Swift Package Manager package as the headers come from the iOS pod archive
|
||||||
|
#ifdef SPM_BUILD
|
||||||
|
#include "onnxruntime/onnxruntime_c_api.h"
|
||||||
|
#include "onnxruntime/onnxruntime_cxx_api.h"
|
||||||
|
|
||||||
|
#if __has_include("onnxruntime/coreml_provider_factory.h")
|
||||||
|
#define ORT_OBJC_API_COREML_EP_AVAILABLE 1
|
||||||
|
#include "onnxruntime/coreml_provider_factory.h"
|
||||||
|
#else
|
||||||
|
#define ORT_OBJC_API_COREML_EP_AVAILABLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include "onnxruntime_c_api.h"
|
||||||
|
#include "onnxruntime_cxx_api.h"
|
||||||
|
|
||||||
|
#if __has_include("coreml_provider_factory.h")
|
||||||
|
#define ORT_OBJC_API_COREML_EP_AVAILABLE 1
|
||||||
|
#include "coreml_provider_factory.h"
|
||||||
|
#else
|
||||||
|
#define ORT_OBJC_API_COREML_EP_AVAILABLE 0
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif // defined(__clang__)
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
void ORTSaveCodeAndDescriptionToError(int code, const char* description, NSError** error);
|
||||||
|
void ORTSaveOrtExceptionToError(const Ort::Exception& e, NSError** error);
|
||||||
|
void ORTSaveExceptionToError(const std::exception& e, NSError** error);
|
||||||
|
|
||||||
|
// helper macros to catch and handle C++ exceptions
|
||||||
|
#define ORT_OBJC_API_IMPL_CATCH(error, failure_return_value) \
|
||||||
|
catch (const Ort::Exception& e) { \
|
||||||
|
ORTSaveOrtExceptionToError(e, (error)); \
|
||||||
|
return (failure_return_value); \
|
||||||
|
} \
|
||||||
|
catch (const std::exception& e) { \
|
||||||
|
ORTSaveExceptionToError(e, (error)); \
|
||||||
|
return (failure_return_value); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error) \
|
||||||
|
ORT_OBJC_API_IMPL_CATCH(error, NO)
|
||||||
|
|
||||||
|
#define ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) \
|
||||||
|
ORT_OBJC_API_IMPL_CATCH(error, nil)
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "error_utils.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
static NSString* const kOrtErrorDomain = @"onnxruntime";
|
||||||
|
|
||||||
|
void ORTSaveCodeAndDescriptionToError(int code, const char* descriptionCstr, NSError** error) {
|
||||||
|
if (!error) return;
|
||||||
|
|
||||||
|
NSString* description = [NSString stringWithCString:descriptionCstr
|
||||||
|
encoding:NSASCIIStringEncoding];
|
||||||
|
|
||||||
|
*error = [NSError errorWithDomain:kOrtErrorDomain
|
||||||
|
code:code
|
||||||
|
userInfo:@{NSLocalizedDescriptionKey : description}];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ORTSaveOrtExceptionToError(const Ort::Exception& e, NSError** error) {
|
||||||
|
ORTSaveCodeAndDescriptionToError(e.GetOrtErrorCode(), e.what(), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ORTSaveExceptionToError(const std::exception& e, NSError** error) {
|
||||||
|
ORTSaveCodeAndDescriptionToError(ORT_RUNTIME_EXCEPTION, e.what(), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# formats Objective-C/C++ code
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
clang-format -i $(find ${SCRIPT_DIR} -name "*.h" -o -name "*.m" -o -name "*.mm")
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// this header contains the entire ONNX Runtime Objective-C API
|
||||||
|
// the headers below can also be imported individually
|
||||||
|
|
||||||
|
#import "ort_coreml_execution_provider.h"
|
||||||
|
#import "ort_xnnpack_execution_provider.h"
|
||||||
|
#import "ort_enums.h"
|
||||||
|
#import "ort_env.h"
|
||||||
|
#import "ort_session.h"
|
||||||
|
#import "ort_value.h"
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "ort_session.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the CoreML execution provider is available.
|
||||||
|
*/
|
||||||
|
BOOL ORTIsCoreMLExecutionProviderAvailable(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for configuring the CoreML execution provider.
|
||||||
|
*/
|
||||||
|
@interface ORTCoreMLExecutionProviderOptions : NSObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the CoreML execution provider should run on CPU only.
|
||||||
|
*/
|
||||||
|
@property BOOL useCPUOnly;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the CoreML execution provider is enabled on subgraphs.
|
||||||
|
*/
|
||||||
|
@property BOOL enableOnSubgraphs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the CoreML execution provider is only enabled for devices with Apple
|
||||||
|
* Neural Engine (ANE).
|
||||||
|
*/
|
||||||
|
@property BOOL onlyEnableForDevicesWithANE;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ORTSessionOptions (ORTSessionOptionsCoreMLEP)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the CoreML execution provider in the session configuration options.
|
||||||
|
* It is appended to the execution provider list which is ordered by
|
||||||
|
* decreasing priority.
|
||||||
|
*
|
||||||
|
* @param options The CoreML execution provider configuration options.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the provider was enabled successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)appendCoreMLExecutionProviderWithOptions:(ORTCoreMLExecutionProviderOptions*)options
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ORT logging verbosity levels.
|
||||||
|
*/
|
||||||
|
typedef NS_ENUM(int32_t, ORTLoggingLevel) {
|
||||||
|
ORTLoggingLevelVerbose,
|
||||||
|
ORTLoggingLevelInfo,
|
||||||
|
ORTLoggingLevelWarning,
|
||||||
|
ORTLoggingLevelError,
|
||||||
|
ORTLoggingLevelFatal,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ORT value types.
|
||||||
|
* Currently, a subset of all types is supported.
|
||||||
|
*/
|
||||||
|
typedef NS_ENUM(int32_t, ORTValueType) {
|
||||||
|
ORTValueTypeUnknown,
|
||||||
|
ORTValueTypeTensor,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ORT tensor element data types.
|
||||||
|
* Currently, a subset of all types is supported.
|
||||||
|
*/
|
||||||
|
typedef NS_ENUM(int32_t, ORTTensorElementDataType) {
|
||||||
|
ORTTensorElementDataTypeUndefined,
|
||||||
|
ORTTensorElementDataTypeFloat,
|
||||||
|
ORTTensorElementDataTypeInt8,
|
||||||
|
ORTTensorElementDataTypeUInt8,
|
||||||
|
ORTTensorElementDataTypeInt32,
|
||||||
|
ORTTensorElementDataTypeUInt32,
|
||||||
|
ORTTensorElementDataTypeInt64,
|
||||||
|
ORTTensorElementDataTypeUInt64,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ORT graph optimization levels.
|
||||||
|
* See here for more details:
|
||||||
|
* https://onnxruntime.ai/docs/performance/graph-optimizations.html
|
||||||
|
*/
|
||||||
|
typedef NS_ENUM(int32_t, ORTGraphOptimizationLevel) {
|
||||||
|
ORTGraphOptimizationLevelNone,
|
||||||
|
ORTGraphOptimizationLevelBasic,
|
||||||
|
ORTGraphOptimizationLevelExtended,
|
||||||
|
ORTGraphOptimizationLevelAll,
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "ort_enums.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ORT version string in format major.minor.patch.
|
||||||
|
*
|
||||||
|
* Available since 1.15.
|
||||||
|
*/
|
||||||
|
NSString* ORTVersion(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ORT environment.
|
||||||
|
*/
|
||||||
|
@interface ORTEnv : NSObject
|
||||||
|
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an ORT Environment.
|
||||||
|
*
|
||||||
|
* @param loggingLevel The environment logging level.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return The instance, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable instancetype)initWithLoggingLevel:(ORTLoggingLevel)loggingLevel
|
||||||
|
error:(NSError**)error NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "ort_enums.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class ORTEnv;
|
||||||
|
@class ORTRunOptions;
|
||||||
|
@class ORTSessionOptions;
|
||||||
|
@class ORTValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ORT session loads and runs a model.
|
||||||
|
*/
|
||||||
|
@interface ORTSession : NSObject
|
||||||
|
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a session.
|
||||||
|
*
|
||||||
|
* @param env The ORT Environment instance.
|
||||||
|
* @param path The path to the ONNX model.
|
||||||
|
* @param sessionOptions Optional session configuration options.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return The instance, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable instancetype)initWithEnv:(ORTEnv*)env
|
||||||
|
modelPath:(NSString*)path
|
||||||
|
sessionOptions:(nullable ORTSessionOptions*)sessionOptions
|
||||||
|
error:(NSError**)error NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the model.
|
||||||
|
* The inputs and outputs are pre-allocated.
|
||||||
|
*
|
||||||
|
* @param inputs Dictionary of input names to input ORT values.
|
||||||
|
* @param outputs Dictionary of output names to output ORT values.
|
||||||
|
* @param runOptions Optional run configuration options.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the model was run successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
|
||||||
|
outputs:(NSDictionary<NSString*, ORTValue*>*)outputs
|
||||||
|
runOptions:(nullable ORTRunOptions*)runOptions
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the model.
|
||||||
|
* The inputs are pre-allocated and the outputs are allocated by ORT.
|
||||||
|
*
|
||||||
|
* @param inputs Dictionary of input names to input ORT values.
|
||||||
|
* @param outputNames Set of output names.
|
||||||
|
* @param runOptions Optional run configuration options.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return A dictionary of output names to output ORT values with the outputs
|
||||||
|
* requested in `outputNames`, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable NSDictionary<NSString*, ORTValue*>*)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
|
||||||
|
outputNames:(NSSet<NSString*>*)outputNames
|
||||||
|
runOptions:(nullable ORTRunOptions*)runOptions
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's input names.
|
||||||
|
*
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return An array of input names, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable NSArray<NSString*>*)inputNamesWithError:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's overridable initializer names.
|
||||||
|
*
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return An array of overridable initializer names, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable NSArray<NSString*>*)overridableInitializerNamesWithError:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's output names.
|
||||||
|
*
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return An array of output names, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable NSArray<NSString*>*)outputNamesWithError:(NSError**)error;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for configuring a session.
|
||||||
|
*/
|
||||||
|
@interface ORTSessionOptions : NSObject
|
||||||
|
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates session configuration options.
|
||||||
|
*
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return The instance, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable instancetype)initWithError:(NSError**)error NS_SWIFT_NAME(init());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends an execution provider to the session options to enable the execution provider to be used when running
|
||||||
|
* the model.
|
||||||
|
*
|
||||||
|
* Available since 1.14.
|
||||||
|
*
|
||||||
|
* The execution provider list is ordered by decreasing priority.
|
||||||
|
* i.e. the first provider registered has the highest priority.
|
||||||
|
*
|
||||||
|
* @param providerName Provider name. For example, "xnnpack".
|
||||||
|
* @param providerOptions Provider-specific options. For example, for provider "xnnpack", {"intra_op_num_threads": "2"}.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the execution provider was appended successfully
|
||||||
|
*/
|
||||||
|
- (BOOL)appendExecutionProvider:(NSString*)providerName
|
||||||
|
providerOptions:(NSDictionary<NSString*, NSString*>*)providerOptions
|
||||||
|
error:(NSError**)error;
|
||||||
|
/**
|
||||||
|
* Sets the number of threads used to parallelize the execution within nodes.
|
||||||
|
* A value of 0 means ORT will pick a default value.
|
||||||
|
*
|
||||||
|
* @param intraOpNumThreads The number of threads.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)setIntraOpNumThreads:(int)intraOpNumThreads
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the graph optimization level.
|
||||||
|
*
|
||||||
|
* @param graphOptimizationLevel The graph optimization level.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)setGraphOptimizationLevel:(ORTGraphOptimizationLevel)graphOptimizationLevel
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the path to which the optimized model file will be saved.
|
||||||
|
*
|
||||||
|
* @param optimizedModelFilePath The optimized model file path.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)setOptimizedModelFilePath:(NSString*)optimizedModelFilePath
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the session log ID.
|
||||||
|
*
|
||||||
|
* @param logID The log ID.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)setLogID:(NSString*)logID
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the session log severity level.
|
||||||
|
*
|
||||||
|
* @param loggingLevel The log severity level.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)setLogSeverityLevel:(ORTLoggingLevel)loggingLevel
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a session configuration key-value pair.
|
||||||
|
* Any value for a previously set key will be overwritten.
|
||||||
|
* The session configuration keys and values are documented here:
|
||||||
|
* https://github.com/microsoft/onnxruntime/blob/main/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param value The value.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)addConfigEntryWithKey:(NSString*)key
|
||||||
|
value:(NSString*)value
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers custom ops for use with `ORTSession`s using this SessionOptions by calling the specified
|
||||||
|
* native function name. The custom ops library must either be linked against, or have previously been loaded
|
||||||
|
* by the user.
|
||||||
|
*
|
||||||
|
* Available since 1.14.
|
||||||
|
*
|
||||||
|
* The registration function must have the signature:
|
||||||
|
* OrtStatus* (*fn)(OrtSessionOptions* options, const OrtApiBase* api);
|
||||||
|
*
|
||||||
|
* See https://onnxruntime.ai/docs/reference/operators/add-custom-op.html for more information on custom ops.
|
||||||
|
* See https://github.com/microsoft/onnxruntime/blob/342a5bf2b756d1a1fc6fdc582cfeac15182632fe/onnxruntime/test/testdata/custom_op_library/custom_op_library.cc#L115
|
||||||
|
* for an example of a custom op library registration function.
|
||||||
|
*
|
||||||
|
* @param registrationFuncName The name of the registration function to call.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the registration function was successfully called.
|
||||||
|
*/
|
||||||
|
- (BOOL)registerCustomOpsUsingFunction:(NSString*)registrationFuncName
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for configuring a run.
|
||||||
|
*/
|
||||||
|
@interface ORTRunOptions : NSObject
|
||||||
|
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates run configuration options.
|
||||||
|
*
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return The instance, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable instancetype)initWithError:(NSError**)error NS_SWIFT_NAME(init());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the run log tag.
|
||||||
|
*
|
||||||
|
* @param logTag The log tag.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)setLogTag:(NSString*)logTag
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the run log severity level.
|
||||||
|
*
|
||||||
|
* @param loggingLevel The log severity level.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)setLogSeverityLevel:(ORTLoggingLevel)loggingLevel
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a run configuration key-value pair.
|
||||||
|
* Any value for a previously set key will be overwritten.
|
||||||
|
* The run configuration keys and values are documented here:
|
||||||
|
* https://github.com/microsoft/onnxruntime/blob/main/include/onnxruntime/core/session/onnxruntime_run_options_config_keys.h
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param value The value.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the option was set successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)addConfigEntryWithKey:(NSString*)key
|
||||||
|
value:(NSString*)value
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "ort_enums.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class ORTValueTypeInfo;
|
||||||
|
@class ORTTensorTypeAndShapeInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ORT value encapsulates data used as an input or output to a model at runtime.
|
||||||
|
*/
|
||||||
|
@interface ORTValue : NSObject
|
||||||
|
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a value that is a tensor.
|
||||||
|
* The tensor data is allocated by the caller.
|
||||||
|
*
|
||||||
|
* @param tensorData The tensor data.
|
||||||
|
* @param elementType The tensor element data type.
|
||||||
|
* @param shape The tensor shape.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return The instance, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable instancetype)initWithTensorData:(NSMutableData*)tensorData
|
||||||
|
elementType:(ORTTensorElementDataType)elementType
|
||||||
|
shape:(NSArray<NSNumber*>*)shape
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type information.
|
||||||
|
*
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return The type information, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable ORTValueTypeInfo*)typeInfoWithError:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the tensor type and shape information.
|
||||||
|
* This assumes that the value is a tensor.
|
||||||
|
*
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return The tensor type and shape information, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable ORTTensorTypeAndShapeInfo*)tensorTypeAndShapeInfoWithError:(NSError**)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the tensor data.
|
||||||
|
* This assumes that the value is a tensor.
|
||||||
|
*
|
||||||
|
* This returns the value's underlying data directly, not a copy of it.
|
||||||
|
* The memory's lifetime may be tied to this value, i.e., if it was allocated
|
||||||
|
* by ORT. On the other hand, the memory's lifetime is independent of the value
|
||||||
|
* if the value was created with user-provided data.
|
||||||
|
*
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return The tensor data, or nil if an error occurs.
|
||||||
|
*/
|
||||||
|
- (nullable NSMutableData*)tensorDataWithError:(NSError**)error;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value's type information.
|
||||||
|
*/
|
||||||
|
@interface ORTValueTypeInfo : NSObject
|
||||||
|
|
||||||
|
/** The value type. */
|
||||||
|
@property(nonatomic) ORTValueType type;
|
||||||
|
|
||||||
|
/** The tensor type and shape information, if the value is a tensor. */
|
||||||
|
@property(nonatomic, nullable) ORTTensorTypeAndShapeInfo* tensorTypeAndShapeInfo;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tensor's type and shape information.
|
||||||
|
*/
|
||||||
|
@interface ORTTensorTypeAndShapeInfo : NSObject
|
||||||
|
|
||||||
|
/** The tensor element data type. */
|
||||||
|
@property(nonatomic) ORTTensorElementDataType elementType;
|
||||||
|
|
||||||
|
/** The tensor shape. */
|
||||||
|
@property(nonatomic) NSArray<NSNumber*>* shape;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "ort_session.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for configuring the Xnnpack execution provider.
|
||||||
|
*/
|
||||||
|
@interface ORTXnnpackExecutionProviderOptions : NSObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many threads used for the Xnnpack execution provider.
|
||||||
|
*/
|
||||||
|
@property int intra_op_num_threads;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ORTSessionOptions (ORTSessionOptionsXnnpackEP)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available since 1.14.
|
||||||
|
* Enables the Xnnpack execution provider in the session configuration options.
|
||||||
|
* It is appended to the execution provider list which is ordered by
|
||||||
|
* decreasing priority.
|
||||||
|
*
|
||||||
|
* @param options The Xnnpack execution provider configuration options.
|
||||||
|
* @param error Optional error information set if an error occurs.
|
||||||
|
* @return Whether the provider was enabled successfully.
|
||||||
|
*/
|
||||||
|
- (BOOL)appendXnnpackExecutionProviderWithOptions:(ORTXnnpackExecutionProviderOptions*)options
|
||||||
|
error:(NSError**)error;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_coreml_execution_provider.h"
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
#import "error_utils.h"
|
||||||
|
#import "ort_session_internal.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
BOOL ORTIsCoreMLExecutionProviderAvailable() {
|
||||||
|
return ORT_OBJC_API_COREML_EP_AVAILABLE ? YES : NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation ORTCoreMLExecutionProviderOptions
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ORTSessionOptions (ORTSessionOptionsCoreMLEP)
|
||||||
|
|
||||||
|
- (BOOL)appendCoreMLExecutionProviderWithOptions:(ORTCoreMLExecutionProviderOptions*)options
|
||||||
|
error:(NSError**)error {
|
||||||
|
#if ORT_OBJC_API_COREML_EP_AVAILABLE
|
||||||
|
try {
|
||||||
|
const uint32_t flags =
|
||||||
|
(options.useCPUOnly ? COREML_FLAG_USE_CPU_ONLY : 0) |
|
||||||
|
(options.enableOnSubgraphs ? COREML_FLAG_ENABLE_ON_SUBGRAPH : 0) |
|
||||||
|
(options.onlyEnableForDevicesWithANE ? COREML_FLAG_ONLY_ENABLE_DEVICE_WITH_ANE : 0);
|
||||||
|
Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_CoreML(
|
||||||
|
[self CXXAPIOrtSessionOptions], flags));
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error);
|
||||||
|
#else // !ORT_OBJC_API_COREML_EP_AVAILABLE
|
||||||
|
static_cast<void>(options);
|
||||||
|
ORTSaveCodeAndDescriptionToError(ORT_FAIL, "CoreML execution provider is not enabled.", error);
|
||||||
|
return NO;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_enums_internal.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct LoggingLevelInfo {
|
||||||
|
ORTLoggingLevel logging_level;
|
||||||
|
OrtLoggingLevel capi_logging_level;
|
||||||
|
};
|
||||||
|
|
||||||
|
// supported ORT logging levels
|
||||||
|
// define the mapping from ORTLoggingLevel to C API OrtLoggingLevel here
|
||||||
|
constexpr LoggingLevelInfo kLoggingLevelInfos[]{
|
||||||
|
{ORTLoggingLevelVerbose, ORT_LOGGING_LEVEL_VERBOSE},
|
||||||
|
{ORTLoggingLevelInfo, ORT_LOGGING_LEVEL_INFO},
|
||||||
|
{ORTLoggingLevelWarning, ORT_LOGGING_LEVEL_WARNING},
|
||||||
|
{ORTLoggingLevelError, ORT_LOGGING_LEVEL_ERROR},
|
||||||
|
{ORTLoggingLevelFatal, ORT_LOGGING_LEVEL_FATAL},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ValueTypeInfo {
|
||||||
|
ORTValueType type;
|
||||||
|
ONNXType capi_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// supported ORT value types
|
||||||
|
// define the mapping from ORTValueType to C API ONNXType here
|
||||||
|
constexpr ValueTypeInfo kValueTypeInfos[]{
|
||||||
|
{ORTValueTypeUnknown, ONNX_TYPE_UNKNOWN},
|
||||||
|
{ORTValueTypeTensor, ONNX_TYPE_TENSOR},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TensorElementTypeInfo {
|
||||||
|
ORTTensorElementDataType type;
|
||||||
|
ONNXTensorElementDataType capi_type;
|
||||||
|
size_t element_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
// supported ORT tensor element data types
|
||||||
|
// define the mapping from ORTTensorElementDataType to C API ONNXTensorElementDataType here
|
||||||
|
constexpr TensorElementTypeInfo kElementTypeInfos[]{
|
||||||
|
{ORTTensorElementDataTypeUndefined, ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED, 0},
|
||||||
|
{ORTTensorElementDataTypeFloat, ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT, sizeof(float)},
|
||||||
|
{ORTTensorElementDataTypeInt8, ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8, sizeof(int8_t)},
|
||||||
|
{ORTTensorElementDataTypeUInt8, ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8, sizeof(uint8_t)},
|
||||||
|
{ORTTensorElementDataTypeInt32, ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32, sizeof(int32_t)},
|
||||||
|
{ORTTensorElementDataTypeUInt32, ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32, sizeof(uint32_t)},
|
||||||
|
{ORTTensorElementDataTypeInt64, ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64, sizeof(int64_t)},
|
||||||
|
{ORTTensorElementDataTypeUInt64, ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64, sizeof(uint64_t)},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GraphOptimizationLevelInfo {
|
||||||
|
ORTGraphOptimizationLevel opt_level;
|
||||||
|
GraphOptimizationLevel capi_opt_level;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ORT graph optimization levels
|
||||||
|
// define the mapping from ORTGraphOptimizationLevel to C API GraphOptimizationLevel here
|
||||||
|
constexpr GraphOptimizationLevelInfo kGraphOptimizationLevelInfos[]{
|
||||||
|
{ORTGraphOptimizationLevelNone, ORT_DISABLE_ALL},
|
||||||
|
{ORTGraphOptimizationLevelBasic, ORT_ENABLE_BASIC},
|
||||||
|
{ORTGraphOptimizationLevelExtended, ORT_ENABLE_EXTENDED},
|
||||||
|
{ORTGraphOptimizationLevelAll, ORT_ENABLE_ALL},
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Container, typename SelectFn, typename TransformFn>
|
||||||
|
auto SelectAndTransform(
|
||||||
|
const Container& container, SelectFn select_fn, TransformFn transform_fn,
|
||||||
|
const char* not_found_msg)
|
||||||
|
-> decltype(transform_fn(*std::begin(container))) {
|
||||||
|
const auto it = std::find_if(
|
||||||
|
std::begin(container), std::end(container), select_fn);
|
||||||
|
if (it == std::end(container)) {
|
||||||
|
ORT_CXX_API_THROW(not_found_msg, ORT_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
return transform_fn(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
OrtLoggingLevel PublicToCAPILoggingLevel(ORTLoggingLevel logging_level) {
|
||||||
|
return SelectAndTransform(
|
||||||
|
kLoggingLevelInfos,
|
||||||
|
[logging_level](const auto& logging_level_info) { return logging_level_info.logging_level == logging_level; },
|
||||||
|
[](const auto& logging_level_info) { return logging_level_info.capi_logging_level; },
|
||||||
|
"unsupported logging level");
|
||||||
|
}
|
||||||
|
|
||||||
|
ORTValueType CAPIToPublicValueType(ONNXType capi_type) {
|
||||||
|
return SelectAndTransform(
|
||||||
|
kValueTypeInfos,
|
||||||
|
[capi_type](const auto& type_info) { return type_info.capi_type == capi_type; },
|
||||||
|
[](const auto& type_info) { return type_info.type; },
|
||||||
|
"unsupported value type");
|
||||||
|
}
|
||||||
|
|
||||||
|
ONNXTensorElementDataType PublicToCAPITensorElementType(ORTTensorElementDataType type) {
|
||||||
|
return SelectAndTransform(
|
||||||
|
kElementTypeInfos,
|
||||||
|
[type](const auto& type_info) { return type_info.type == type; },
|
||||||
|
[](const auto& type_info) { return type_info.capi_type; },
|
||||||
|
"unsupported tensor element type");
|
||||||
|
}
|
||||||
|
|
||||||
|
ORTTensorElementDataType CAPIToPublicTensorElementType(ONNXTensorElementDataType capi_type) {
|
||||||
|
return SelectAndTransform(
|
||||||
|
kElementTypeInfos,
|
||||||
|
[capi_type](const auto& type_info) { return type_info.capi_type == capi_type; },
|
||||||
|
[](const auto& type_info) { return type_info.type; },
|
||||||
|
"unsupported tensor element type");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SizeOfCAPITensorElementType(ONNXTensorElementDataType capi_type) {
|
||||||
|
return SelectAndTransform(
|
||||||
|
kElementTypeInfos,
|
||||||
|
[capi_type](const auto& type_info) { return type_info.capi_type == capi_type; },
|
||||||
|
[](const auto& type_info) { return type_info.element_size; },
|
||||||
|
"unsupported tensor element type");
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphOptimizationLevel PublicToCAPIGraphOptimizationLevel(ORTGraphOptimizationLevel opt_level) {
|
||||||
|
return SelectAndTransform(
|
||||||
|
kGraphOptimizationLevelInfos,
|
||||||
|
[opt_level](const auto& opt_level_info) { return opt_level_info.opt_level == opt_level; },
|
||||||
|
[](const auto& opt_level_info) { return opt_level_info.capi_opt_level; },
|
||||||
|
"unsupported graph optimization level");
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_enums.h"
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
|
||||||
|
OrtLoggingLevel PublicToCAPILoggingLevel(ORTLoggingLevel logging_level);
|
||||||
|
|
||||||
|
ORTValueType CAPIToPublicValueType(ONNXType capi_type);
|
||||||
|
|
||||||
|
ONNXTensorElementDataType PublicToCAPITensorElementType(ORTTensorElementDataType type);
|
||||||
|
ORTTensorElementDataType CAPIToPublicTensorElementType(ONNXTensorElementDataType capi_type);
|
||||||
|
|
||||||
|
size_t SizeOfCAPITensorElementType(ONNXTensorElementDataType capi_type);
|
||||||
|
|
||||||
|
GraphOptimizationLevel PublicToCAPIGraphOptimizationLevel(ORTGraphOptimizationLevel opt_level);
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_env_internal.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
|
||||||
|
#import "error_utils.h"
|
||||||
|
#import "ort_enums_internal.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
NSString* ORTVersion(void) {
|
||||||
|
std::string result = OrtGetApiBase()->GetVersionString();
|
||||||
|
return [NSString stringWithUTF8String:result.c_str()];
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation ORTEnv {
|
||||||
|
std::optional<Ort::Env> _env;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable instancetype)initWithLoggingLevel:(ORTLoggingLevel)loggingLevel
|
||||||
|
error:(NSError**)error {
|
||||||
|
if ((self = [super init]) == nil) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const auto CAPILoggingLevel = PublicToCAPILoggingLevel(loggingLevel);
|
||||||
|
_env = Ort::Env{CAPILoggingLevel};
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (Ort::Env&)CXXAPIOrtEnv {
|
||||||
|
return *_env;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_env.h"
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface ORTEnv ()
|
||||||
|
|
||||||
|
- (Ort::Env&)CXXAPIOrtEnv;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,361 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_session_internal.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
#import "error_utils.h"
|
||||||
|
#import "ort_enums_internal.h"
|
||||||
|
#import "ort_env_internal.h"
|
||||||
|
#import "ort_value_internal.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
enum class NamedValueType {
|
||||||
|
Input,
|
||||||
|
OverridableInitializer,
|
||||||
|
Output,
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@implementation ORTSession {
|
||||||
|
std::optional<Ort::Session> _session;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Public
|
||||||
|
|
||||||
|
- (nullable instancetype)initWithEnv:(ORTEnv*)env
|
||||||
|
modelPath:(NSString*)path
|
||||||
|
sessionOptions:(nullable ORTSessionOptions*)sessionOptions
|
||||||
|
error:(NSError**)error {
|
||||||
|
if ((self = [super init]) == nil) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!sessionOptions) {
|
||||||
|
sessionOptions = [[ORTSessionOptions alloc] initWithError:error];
|
||||||
|
if (!sessionOptions) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_session = Ort::Session{[env CXXAPIOrtEnv],
|
||||||
|
path.UTF8String,
|
||||||
|
[sessionOptions CXXAPIOrtSessionOptions]};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
|
||||||
|
outputs:(NSDictionary<NSString*, ORTValue*>*)outputs
|
||||||
|
runOptions:(nullable ORTRunOptions*)runOptions
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
if (!runOptions) {
|
||||||
|
runOptions = [[ORTRunOptions alloc] initWithError:error];
|
||||||
|
if (!runOptions) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const char*> inputNames, outputNames;
|
||||||
|
std::vector<const OrtValue*> inputValues;
|
||||||
|
std::vector<OrtValue*> outputValues;
|
||||||
|
|
||||||
|
for (NSString* inputName in inputs) {
|
||||||
|
inputNames.push_back(inputName.UTF8String);
|
||||||
|
inputValues.push_back(static_cast<const OrtValue*>([inputs[inputName] CXXAPIOrtValue]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NSString* outputName in outputs) {
|
||||||
|
outputNames.push_back(outputName.UTF8String);
|
||||||
|
outputValues.push_back(static_cast<OrtValue*>([outputs[outputName] CXXAPIOrtValue]));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ort::ThrowOnError(Ort::GetApi().Run(*_session, [runOptions CXXAPIOrtRunOptions],
|
||||||
|
inputNames.data(), inputValues.data(), inputNames.size(),
|
||||||
|
outputNames.data(), outputNames.size(), outputValues.data()));
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable NSDictionary<NSString*, ORTValue*>*)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
|
||||||
|
outputNames:(NSSet<NSString*>*)outputNameSet
|
||||||
|
runOptions:(nullable ORTRunOptions*)runOptions
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
if (!runOptions) {
|
||||||
|
runOptions = [[ORTRunOptions alloc] initWithError:error];
|
||||||
|
if (!runOptions) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray<NSString*>* outputNameArray = outputNameSet.allObjects;
|
||||||
|
|
||||||
|
std::vector<const char*> inputNames, outputNames;
|
||||||
|
std::vector<const OrtValue*> inputValues;
|
||||||
|
std::vector<OrtValue*> outputValues;
|
||||||
|
|
||||||
|
for (NSString* inputName in inputs) {
|
||||||
|
inputNames.push_back(inputName.UTF8String);
|
||||||
|
inputValues.push_back(static_cast<const OrtValue*>([inputs[inputName] CXXAPIOrtValue]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NSString* outputName in outputNameArray) {
|
||||||
|
outputNames.push_back(outputName.UTF8String);
|
||||||
|
outputValues.push_back(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ort::ThrowOnError(Ort::GetApi().Run(*_session, [runOptions CXXAPIOrtRunOptions],
|
||||||
|
inputNames.data(), inputValues.data(), inputNames.size(),
|
||||||
|
outputNames.data(), outputNames.size(), outputValues.data()));
|
||||||
|
|
||||||
|
NSMutableDictionary<NSString*, ORTValue*>* outputs = [[NSMutableDictionary alloc] init];
|
||||||
|
for (NSUInteger i = 0; i < outputNameArray.count; ++i) {
|
||||||
|
ORTValue* outputValue = [[ORTValue alloc] initWithCAPIOrtValue:outputValues[i] externalTensorData:nil error:error];
|
||||||
|
if (!outputValue) {
|
||||||
|
// clean up remaining C API OrtValues which haven't been wrapped by an ORTValue yet
|
||||||
|
for (NSUInteger j = i; j < outputNameArray.count; ++j) {
|
||||||
|
Ort::GetApi().ReleaseValue(outputValues[j]);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputs[outputNameArray[i]] = outputValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable NSArray<NSString*>*)inputNamesWithError:(NSError**)error {
|
||||||
|
return [self namesWithType:NamedValueType::Input error:error];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable NSArray<NSString*>*)overridableInitializerNamesWithError:(NSError**)error {
|
||||||
|
return [self namesWithType:NamedValueType::OverridableInitializer error:error];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable NSArray<NSString*>*)outputNamesWithError:(NSError**)error {
|
||||||
|
return [self namesWithType:NamedValueType::Output error:error];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Private
|
||||||
|
|
||||||
|
- (nullable NSArray<NSString*>*)namesWithType:(NamedValueType)namedValueType
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
auto getCount = [&session = *_session, namedValueType]() {
|
||||||
|
if (namedValueType == NamedValueType::Input) {
|
||||||
|
return session.GetInputCount();
|
||||||
|
} else if (namedValueType == NamedValueType::OverridableInitializer) {
|
||||||
|
return session.GetOverridableInitializerCount();
|
||||||
|
} else {
|
||||||
|
return session.GetOutputCount();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getName = [&session = *_session, namedValueType](size_t i, OrtAllocator* allocator) {
|
||||||
|
if (namedValueType == NamedValueType::Input) {
|
||||||
|
return session.GetInputNameAllocated(i, allocator);
|
||||||
|
} else if (namedValueType == NamedValueType::OverridableInitializer) {
|
||||||
|
return session.GetOverridableInitializerNameAllocated(i, allocator);
|
||||||
|
} else {
|
||||||
|
return session.GetOutputNameAllocated(i, allocator);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t nameCount = getCount();
|
||||||
|
|
||||||
|
Ort::AllocatorWithDefaultOptions allocator;
|
||||||
|
NSMutableArray<NSString*>* result = [NSMutableArray arrayWithCapacity:nameCount];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nameCount; ++i) {
|
||||||
|
auto name = getName(i, allocator);
|
||||||
|
NSString* nameNsstr = [NSString stringWithUTF8String:name.get()];
|
||||||
|
NSAssert(nameNsstr != nil, @"nameNsstr must not be nil");
|
||||||
|
[result addObject:nameNsstr];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ORTSessionOptions {
|
||||||
|
std::optional<Ort::SessionOptions> _sessionOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Public
|
||||||
|
|
||||||
|
- (nullable instancetype)initWithError:(NSError**)error {
|
||||||
|
if ((self = [super init]) == nil) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_sessionOptions = Ort::SessionOptions{};
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)appendExecutionProvider:(NSString*)providerName
|
||||||
|
providerOptions:(NSDictionary<NSString*, NSString*>*)providerOptions
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
std::unordered_map<std::string, std::string> options;
|
||||||
|
NSArray* keys = [providerOptions allKeys];
|
||||||
|
|
||||||
|
for (NSString* key in keys) {
|
||||||
|
NSString* value = [providerOptions objectForKey:key];
|
||||||
|
options.emplace(key.UTF8String, value.UTF8String);
|
||||||
|
}
|
||||||
|
|
||||||
|
_sessionOptions->AppendExecutionProvider(providerName.UTF8String, options);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)setIntraOpNumThreads:(int)intraOpNumThreads
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_sessionOptions->SetIntraOpNumThreads(intraOpNumThreads);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)setGraphOptimizationLevel:(ORTGraphOptimizationLevel)graphOptimizationLevel
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_sessionOptions->SetGraphOptimizationLevel(
|
||||||
|
PublicToCAPIGraphOptimizationLevel(graphOptimizationLevel));
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)setOptimizedModelFilePath:(NSString*)optimizedModelFilePath
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_sessionOptions->SetOptimizedModelFilePath(optimizedModelFilePath.UTF8String);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)setLogID:(NSString*)logID
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_sessionOptions->SetLogId(logID.UTF8String);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)setLogSeverityLevel:(ORTLoggingLevel)loggingLevel
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_sessionOptions->SetLogSeverityLevel(PublicToCAPILoggingLevel(loggingLevel));
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)addConfigEntryWithKey:(NSString*)key
|
||||||
|
value:(NSString*)value
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_sessionOptions->AddConfigEntry(key.UTF8String, value.UTF8String);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)registerCustomOpsUsingFunction:(NSString*)registrationFuncName
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_sessionOptions->RegisterCustomOpsUsingFunction(registrationFuncName.UTF8String);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Internal
|
||||||
|
|
||||||
|
- (Ort::SessionOptions&)CXXAPIOrtSessionOptions {
|
||||||
|
return *_sessionOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ORTRunOptions {
|
||||||
|
std::optional<Ort::RunOptions> _runOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Public
|
||||||
|
|
||||||
|
- (nullable instancetype)initWithError:(NSError**)error {
|
||||||
|
if ((self = [super init]) == nil) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_runOptions = Ort::RunOptions{};
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)setLogTag:(NSString*)logTag
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_runOptions->SetRunTag(logTag.UTF8String);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)setLogSeverityLevel:(ORTLoggingLevel)loggingLevel
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_runOptions->SetRunLogSeverityLevel(PublicToCAPILoggingLevel(loggingLevel));
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)addConfigEntryWithKey:(NSString*)key
|
||||||
|
value:(NSString*)value
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
_runOptions->AddConfigEntry(key.UTF8String, value.UTF8String);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Internal
|
||||||
|
|
||||||
|
- (Ort::RunOptions&)CXXAPIOrtRunOptions {
|
||||||
|
return *_runOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_session.h"
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface ORTSessionOptions ()
|
||||||
|
|
||||||
|
- (Ort::SessionOptions&)CXXAPIOrtSessionOptions;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ORTRunOptions ()
|
||||||
|
|
||||||
|
- (Ort::RunOptions&)CXXAPIOrtRunOptions;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_value_internal.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
#import "error_utils.h"
|
||||||
|
#import "ort_enums_internal.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
ORTTensorTypeAndShapeInfo* CXXAPIToPublicTensorTypeAndShapeInfo(
|
||||||
|
const Ort::ConstTensorTypeAndShapeInfo& CXXAPITensorTypeAndShapeInfo) {
|
||||||
|
auto* result = [[ORTTensorTypeAndShapeInfo alloc] init];
|
||||||
|
const auto elementType = CXXAPITensorTypeAndShapeInfo.GetElementType();
|
||||||
|
const std::vector<int64_t> shape = CXXAPITensorTypeAndShapeInfo.GetShape();
|
||||||
|
|
||||||
|
result.elementType = CAPIToPublicTensorElementType(elementType);
|
||||||
|
auto* shapeArray = [[NSMutableArray alloc] initWithCapacity:shape.size()];
|
||||||
|
for (size_t i = 0; i < shape.size(); ++i) {
|
||||||
|
shapeArray[i] = @(shape[i]);
|
||||||
|
}
|
||||||
|
result.shape = shapeArray;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ORTValueTypeInfo* CXXAPIToPublicValueTypeInfo(
|
||||||
|
const Ort::TypeInfo& CXXAPITypeInfo) {
|
||||||
|
auto* result = [[ORTValueTypeInfo alloc] init];
|
||||||
|
const auto valueType = CXXAPITypeInfo.GetONNXType();
|
||||||
|
|
||||||
|
result.type = CAPIToPublicValueType(valueType);
|
||||||
|
|
||||||
|
if (valueType == ONNX_TYPE_TENSOR) {
|
||||||
|
const auto tensorTypeAndShapeInfo = CXXAPITypeInfo.GetTensorTypeAndShapeInfo();
|
||||||
|
result.tensorTypeAndShapeInfo = CXXAPIToPublicTensorTypeAndShapeInfo(tensorTypeAndShapeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// out = a * b
|
||||||
|
// returns true iff the result does not overflow
|
||||||
|
bool SafeMultiply(size_t a, size_t b, size_t& out) {
|
||||||
|
return !__builtin_mul_overflow(a, b, &out);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
@interface ORTValue ()
|
||||||
|
|
||||||
|
// pointer to any external tensor data to keep alive for the lifetime of the ORTValue
|
||||||
|
@property(nonatomic, nullable) NSMutableData* externalTensorData;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ORTValue {
|
||||||
|
std::optional<Ort::Value> _value;
|
||||||
|
std::optional<Ort::TypeInfo> _typeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Public
|
||||||
|
|
||||||
|
- (nullable instancetype)initWithTensorData:(NSMutableData*)tensorData
|
||||||
|
elementType:(ORTTensorElementDataType)elementType
|
||||||
|
shape:(NSArray<NSNumber*>*)shape
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
const auto memoryInfo = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
|
||||||
|
const auto ONNXElementType = PublicToCAPITensorElementType(elementType);
|
||||||
|
const auto shapeVector = [shape]() {
|
||||||
|
std::vector<int64_t> result{};
|
||||||
|
result.reserve(shape.count);
|
||||||
|
for (NSNumber* dim in shape) {
|
||||||
|
result.push_back(dim.longLongValue);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}();
|
||||||
|
Ort::Value ortValue = Ort::Value::CreateTensor(
|
||||||
|
memoryInfo, tensorData.mutableBytes, tensorData.length,
|
||||||
|
shapeVector.data(), shapeVector.size(), ONNXElementType);
|
||||||
|
|
||||||
|
return [self initWithCAPIOrtValue:ortValue.release()
|
||||||
|
externalTensorData:tensorData
|
||||||
|
error:error];
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable ORTValueTypeInfo*)typeInfoWithError:(NSError**)error {
|
||||||
|
try {
|
||||||
|
return CXXAPIToPublicValueTypeInfo(*_typeInfo);
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable ORTTensorTypeAndShapeInfo*)tensorTypeAndShapeInfoWithError:(NSError**)error {
|
||||||
|
try {
|
||||||
|
const auto tensorTypeAndShapeInfo = _typeInfo->GetTensorTypeAndShapeInfo();
|
||||||
|
return CXXAPIToPublicTensorTypeAndShapeInfo(tensorTypeAndShapeInfo);
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable NSMutableData*)tensorDataWithError:(NSError**)error {
|
||||||
|
try {
|
||||||
|
const auto tensorTypeAndShapeInfo = _typeInfo->GetTensorTypeAndShapeInfo();
|
||||||
|
const size_t elementCount = tensorTypeAndShapeInfo.GetElementCount();
|
||||||
|
const size_t elementSize = SizeOfCAPITensorElementType(tensorTypeAndShapeInfo.GetElementType());
|
||||||
|
size_t rawDataLength;
|
||||||
|
if (!SafeMultiply(elementCount, elementSize, rawDataLength)) {
|
||||||
|
ORT_CXX_API_THROW("failed to compute tensor data length", ORT_RUNTIME_EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* rawData;
|
||||||
|
Ort::ThrowOnError(Ort::GetApi().GetTensorMutableData(*_value, &rawData));
|
||||||
|
|
||||||
|
return [NSMutableData dataWithBytesNoCopy:rawData
|
||||||
|
length:rawDataLength
|
||||||
|
freeWhenDone:NO];
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Internal
|
||||||
|
|
||||||
|
- (nullable instancetype)initWithCAPIOrtValue:(OrtValue*)CAPIOrtValue
|
||||||
|
externalTensorData:(nullable NSMutableData*)externalTensorData
|
||||||
|
error:(NSError**)error {
|
||||||
|
if ((self = [super init]) == nil) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_value = Ort::Value{CAPIOrtValue};
|
||||||
|
_typeInfo = _value->GetTypeInfo();
|
||||||
|
_externalTensorData = externalTensorData;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (Ort::Value&)CXXAPIOrtValue {
|
||||||
|
return *_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ORTValueTypeInfo
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ORTTensorTypeAndShapeInfo
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_value.h"
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface ORTValue ()
|
||||||
|
|
||||||
|
- (nullable instancetype)initWithCAPIOrtValue:(OrtValue*)CAPIOrtValue
|
||||||
|
externalTensorData:(nullable NSMutableData*)externalTensorData
|
||||||
|
error:(NSError**)error NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
|
- (Ort::Value&)CXXAPIOrtValue;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#import "ort_xnnpack_execution_provider.h"
|
||||||
|
|
||||||
|
#import "cxx_api.h"
|
||||||
|
#import "error_utils.h"
|
||||||
|
#import "ort_session_internal.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@implementation ORTXnnpackExecutionProviderOptions
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ORTSessionOptions (ORTSessionOptionsXnnpackEP)
|
||||||
|
|
||||||
|
- (BOOL)appendXnnpackExecutionProviderWithOptions:(ORTXnnpackExecutionProviderOptions*)options
|
||||||
|
error:(NSError**)error {
|
||||||
|
try {
|
||||||
|
NSDictionary* provider_options = @{
|
||||||
|
@"intra_op_num_threads" : [NSString stringWithFormat:@"%d", options.intra_op_num_threads]
|
||||||
|
};
|
||||||
|
return [self appendExecutionProvider:@"XNNPACK" providerOptions:provider_options error:error];
|
||||||
|
}
|
||||||
|
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
Binary file not shown.
@@ -0,0 +1,62 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
import Foundation
|
||||||
|
@testable import OnnxRuntimeBindings
|
||||||
|
|
||||||
|
final class SwiftOnnxRuntimeBindingsTests: XCTestCase {
|
||||||
|
let modelPath: String = Bundle.module.url(forResource: "single_add.basic", withExtension: "ort")!.path
|
||||||
|
|
||||||
|
func testGetVersionString() throws {
|
||||||
|
do {
|
||||||
|
let version = ORTVersion()
|
||||||
|
XCTAssertNotNil(version)
|
||||||
|
} catch let error {
|
||||||
|
XCTFail(error.localizedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCreateSession() throws {
|
||||||
|
do {
|
||||||
|
let env = try ORTEnv(loggingLevel: ORTLoggingLevel.verbose)
|
||||||
|
let options = try ORTSessionOptions()
|
||||||
|
try options.setLogSeverityLevel(ORTLoggingLevel.verbose)
|
||||||
|
try options.setIntraOpNumThreads(1)
|
||||||
|
// Create the ORTSession
|
||||||
|
_ = try ORTSession(env: env, modelPath: modelPath, sessionOptions: options)
|
||||||
|
} catch let error {
|
||||||
|
XCTFail(error.localizedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAppendCoreMLEP() throws {
|
||||||
|
do {
|
||||||
|
let env = try ORTEnv(loggingLevel: ORTLoggingLevel.verbose)
|
||||||
|
let sessionOptions: ORTSessionOptions = try ORTSessionOptions()
|
||||||
|
let coreMLOptions: ORTCoreMLExecutionProviderOptions = ORTCoreMLExecutionProviderOptions()
|
||||||
|
coreMLOptions.enableOnSubgraphs = true
|
||||||
|
try sessionOptions.appendCoreMLExecutionProvider(with: coreMLOptions)
|
||||||
|
|
||||||
|
XCTAssertTrue(ORTIsCoreMLExecutionProviderAvailable())
|
||||||
|
_ = try ORTSession(env: env, modelPath: modelPath, sessionOptions: sessionOptions)
|
||||||
|
} catch let error {
|
||||||
|
XCTFail(error.localizedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAppendXnnpackEP() throws {
|
||||||
|
do {
|
||||||
|
let env = try ORTEnv(loggingLevel: ORTLoggingLevel.verbose)
|
||||||
|
let sessionOptions: ORTSessionOptions = try ORTSessionOptions()
|
||||||
|
let XnnpackOptions: ORTXnnpackExecutionProviderOptions = ORTXnnpackExecutionProviderOptions()
|
||||||
|
XnnpackOptions.intra_op_num_threads = 2
|
||||||
|
try sessionOptions.appendXnnpackExecutionProvider(with: XnnpackOptions)
|
||||||
|
|
||||||
|
XCTAssertTrue(ORTIsCoreMLExecutionProviderAvailable())
|
||||||
|
_ = try ORTSession(env: env, modelPath: modelPath, sessionOptions: sessionOptions)
|
||||||
|
} catch let error {
|
||||||
|
XCTFail(error.localizedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user