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
|
||||
*.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
|
||||
> make sure to update the content to build a great experience for community-building.
|
||||
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.
|
||||
|
||||
As the maintainer of this project, please make a few updates:
|
||||
|
||||
- Improving this README.MD file to provide a great experience
|
||||
- Updating SUPPORT.MD with content about this project's support experience
|
||||
- Understanding the security reporting process in SECURITY.MD
|
||||
- Remove this section from the README
|
||||
SPM is the alternative to CocoaPods when desired platform to consume is mobile iOS.
|
||||
|
||||
## Note
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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