Skip to content

Commit c76787f

Browse files
YUNQIUGUOrachguorachguo
authored
Enable SPM support for Ext and configure pipelines for extensions target testing (#3)
* initial ext files * add a workable version of spm for extensions * update * update pipeline * update pipelines * fix dev/release pipelines for extensions pod * fix dev pipelines for extensions pod * fix release pipelines for extensions pod * fix dev pipelines for extensions pod * adding empty include folder for configuring extensions target path * test * test * test * revert pipeline changes * revert gitignore changes * add ext pod binary target for release pipeline * add pipeline for extensions * update * update package.swift * update latest from branch * update * fix * fix * update * try dummy empty file * test * update package.swift to use fatalerror * syntax * try gitignore revert * update gitignore * add -list * onnxruntime-Package * update using onnxruntime-Package * update dev pipeline * fix dev pipelines * syntax * pull extensions/ * update pipelines again * syntax * variables * fix * fix -r * update Package.swift * update Package.swift * minor update * address pr comments * minor updates * fix * refine messages * syntax * syntax again * address pr comments partial * address pr comments * add .h header file and notes * minor updates * syncing objc source files and add code to register custom ops using function pointer * format * move to the header for function doc --------- Co-authored-by: rachguo <rachguo@rachguos-Mini.attlocal.net> Co-authored-by: rachguo <rachguo@rachguos-Mac-mini.local>
1 parent 7acc38c commit c76787f

33 files changed

+1422
-60
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,4 +400,5 @@ FodyWeavers.xsd
400400
.DS_Store
401401
*.DS_Store
402402

403-
.build/
403+
.build/
404+
.swiftpm

.pipelines/mac-ios-spm-dev-validation-pipeline.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,5 @@
6868
displayName: "Print ORT iOS Pod checksum and Test Package.swift usage"
6969
7070
- template: templates/component-governance-component-detection-steps.yml
71-
parameters :
72-
condition : 'succeeded'
71+
parameters:
72+
condition: 'succeeded'
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
jobs:
2+
- job: j
3+
displayName: "Test with ORT Extensions native pod"
4+
5+
pool:
6+
vmImage: "macOS-13"
7+
8+
variables:
9+
xcodeVersion: "14.3"
10+
artifactsName: "ios_packaging_artifacts_full"
11+
artifactsNameForExt: "ios_packaging_artifacts"
12+
13+
timeoutInMinutes: 60
14+
15+
steps:
16+
- template: templates/use-xcode-version.yml
17+
parameters:
18+
xcodeVersion: ${{ variables.xcodeVersion }}
19+
20+
- script: |
21+
mkdir tmp
22+
cd tmp
23+
git clone -n --depth=1 --filter=tree:0 https://github.com/microsoft/onnxruntime.git
24+
cd onnxruntime
25+
git sparse-checkout set --no-cone objectivec
26+
git checkout
27+
workingDirectory: "$(Build.SourcesDirectory)"
28+
displayName: "Sparse checkout objectivec/ folders from latest ORT main repository"
29+
30+
- script: |
31+
ls -R "$(Build.SourcesDirectory)/tmp/onnxruntime"
32+
workingDirectory: "$(Build.SourcesDirectory)/tmp"
33+
displayName: "List sparse checkout repo contents"
34+
35+
# Download artifacts for ORT C pod from iOS packaging pipeline
36+
- task: DownloadPipelineArtifact@2
37+
inputs:
38+
buildType: 'specific'
39+
project: 'Lotus'
40+
definition: 995 #'definitionid' is obtained from `System.DefinitionId` of ORT CI: onnxruntime-ios-packaging-pipeline
41+
buildVersionToDownload: 'latest'
42+
branchName: 'main'
43+
targetPath: '$(Build.ArtifactStagingDirectory)'
44+
45+
- script: |
46+
set -e -x
47+
ls
48+
workingDirectory: '$(Build.ArtifactStagingDirectory)/$(artifactsName)'
49+
displayName: "List staged artifacts for ORT C Pod"
50+
51+
# Download artifacts for ORT Ext C pod from extensions iOS packaging pipeline
52+
- task: DownloadPipelineArtifact@2
53+
inputs:
54+
buildType: 'specific'
55+
project: 'Lotus'
56+
definition: 1206 #'definitionid' is obtained from `System.DefinitionId` of extensions CI: extensions.ios_packaging
57+
buildVersionToDownload: 'latest'
58+
branchName: 'main'
59+
targetPath: '$(Build.ArtifactStagingDirectory)'
60+
61+
- script: |
62+
set -e -x
63+
ls
64+
workingDirectory: '$(Build.ArtifactStagingDirectory)/$(artifactsNameForExt)'
65+
displayName: "List staged artifacts for ORT Ext C Pod"
66+
67+
# Note: Running xcodebuild test on `onnxruntime-Package` scheme will perform swift unit tests for both OnnxRuntimeBindings
68+
# and OnnxRuntimeExtensions targets.
69+
- script: |
70+
set -e -x
71+
cd "$(Build.ArtifactStagingDirectory)/$(artifactsName)"
72+
POD_ARCHIVE=$(find . -name "pod-archive-onnxruntime-c-*.zip")
73+
74+
echo "Printing the checksum here to make it easier when updating for actual release pod archive file in Package.swift"
75+
shasum -a 256 "$(Build.ArtifactStagingDirectory)/$(artifactsName)/${POD_ARCHIVE}"
76+
77+
cd "$(Build.ArtifactStagingDirectory)/$(artifactsNameForExt)"
78+
POD_ARCHIVE_EXT=$(find . -name "pod-archive-onnxruntime-extensions-c-*.zip")
79+
80+
echo "Printing the checksum here to make it easier when updating for actual release extensions pod archive file in Package.swift"
81+
shasum -a 256 "$(Build.ArtifactStagingDirectory)/$(artifactsNameForExt)/${POD_ARCHIVE_EXT}"
82+
83+
cd "$(Build.SourcesDirectory)/tmp/onnxruntime"
84+
cp -r "$(Build.SourcesDirectory)/swift" .
85+
cp "$(Build.SourcesDirectory)/Package.swift" .
86+
cp -r "$(Build.SourcesDirectory)/extensions" .
87+
88+
cp "$(Build.ArtifactStagingDirectory)/$(artifactsName)/${POD_ARCHIVE}" swift/
89+
export ORT_IOS_POD_LOCAL_PATH="swift/${POD_ARCHIVE}"
90+
cp "$(Build.ArtifactStagingDirectory)/$(artifactsNameForExt)/${POD_ARCHIVE_EXT}" swift/
91+
export ORT_EXTENSIONS_IOS_POD_LOCAL_PATH="swift/${POD_ARCHIVE_EXT}"
92+
93+
xcodebuild test -scheme onnxruntime-Package -destination 'platform=iOS Simulator,name=iPhone 14'
94+
95+
rm swift/pod-archive-onnxruntime-c-*.zip
96+
rm swift/pod-archive-onnxruntime-extensions-c-*.zip
97+
workingDirectory: "$(Build.SourcesDirectory)/tmp"
98+
displayName: "Test Package.swift usage for ORT and ORT Extensions"
99+
100+
- template: templates/component-governance-component-detection-steps.yml
101+
parameters:
102+
condition: 'succeeded'

.pipelines/mac-ios-spm-release-validation-pipeline.yml

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,40 @@
1414
- template: templates/use-xcode-version.yml
1515
parameters:
1616
xcodeVersion: ${{ variables.xcodeVersion }}
17+
18+
# Note: Currently it requires a dev version extensions c pod for testing
19+
- task: DownloadPipelineArtifact@2
20+
inputs:
21+
buildType: 'specific'
22+
project: 'Lotus'
23+
definition: 1206 #'definitionid' is obtained from `System.DefinitionId` of extensions CI: extensions.ios_packaging
24+
buildVersionToDownload: 'latest'
25+
branchName: 'main'
26+
targetPath: '$(Build.ArtifactStagingDirectory)'
1727

1828
- script: |
1929
set -e -x
20-
xcodebuild test -scheme onnxruntime -destination 'platform=iOS Simulator,name=iPhone 14'
30+
ls
31+
workingDirectory: "$(Build.ArtifactStagingDirectory)/ios_packaging_artifacts"
32+
displayName: "List staged artifacts for ORT Ext C Pod"
33+
34+
# Note: Running xcodebuild test on `onnxruntime-Package` scheme will perform swift tests for both OnnxRuntimeBindings
35+
# and OnnxRuntimeExtensions targets.
36+
- script: |
37+
set -e -x
38+
39+
cd "$(Build.ArtifactStagingDirectory)/ios_packaging_artifacts"
40+
POD_ARCHIVE=$(find . -name "pod-archive-onnxruntime-extensions-c-*.zip")
41+
42+
cd "$(Build.SourcesDirectory)"
43+
cp "$(Build.ArtifactStagingDirectory)/ios_packaging_artifacts/${POD_ARCHIVE}" swift/
44+
export ORT_EXTENSIONS_IOS_POD_LOCAL_PATH="swift/${POD_ARCHIVE}"
45+
46+
xcodebuild test -scheme onnxruntime-Package -destination 'platform=iOS Simulator,name=iPhone 14'
47+
rm swift/pod-archive-onnxruntime-extensions-c-*.zip
2148
workingDirectory: "$(Build.SourcesDirectory)"
2249
displayName: "Test Package.swift usage"
2350
2451
- template: templates/component-governance-component-detection-steps.yml
25-
parameters :
26-
condition : 'succeeded'
52+
parameters:
53+
condition: 'succeeded'

Package.swift

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,23 @@ let package = Package(
2424
.library(name: "onnxruntime",
2525
type: .static,
2626
targets: ["OnnxRuntimeBindings"]),
27+
.library(name: "onnxruntime_extensions",
28+
type: .static,
29+
targets: ["OnnxRuntimeExtensions"]),
2730
],
2831
dependencies: [],
2932
targets: [
3033
.target(name: "OnnxRuntimeBindings",
3134
dependencies: ["onnxruntime"],
3235
path: "objectivec",
33-
exclude: ["ReadMe.md", "format_objc.sh"],
36+
exclude: ["ReadMe.md", "format_objc.sh", "test",
37+
"ort_checkpoint.mm",
38+
"ort_checkpoint_internal.h",
39+
"ort_training_session_internal.h",
40+
"ort_training_session.mm",
41+
"include/ort_checkpoint.h",
42+
"include/ort_training_session.h",
43+
"include/onnxruntime_training.h"],
3444
cxxSettings: [
3545
.define("SPM_BUILD"),
3646
.unsafeFlags(["-std=c++17",
@@ -45,6 +55,23 @@ let package = Package(
4555
resources: [
4656
.copy("Resources/single_add.basic.ort")
4757
]),
58+
.target(name: "OnnxRuntimeExtensions",
59+
dependencies: ["onnxruntime_extensions", "onnxruntime"],
60+
path: "extensions",
61+
cxxSettings: [
62+
.define("ORT_SWIFT_PACKAGE_MANAGER_BUILD"),
63+
.unsafeFlags(["-std=c++17",
64+
"-fobjc-arc-exceptions"
65+
]),
66+
], linkerSettings: [
67+
.unsafeFlags(["-ObjC"]),
68+
]),
69+
.testTarget(name: "OnnxRuntimeExtensionsTests",
70+
dependencies: ["OnnxRuntimeExtensions", "OnnxRuntimeBindings"],
71+
path: "swift/OnnxRuntimeExtensionsTests",
72+
resources: [
73+
.copy("Resources/decode_image.onnx")
74+
]),
4875
]
4976
)
5077

@@ -83,3 +110,18 @@ if let pod_archive_path = ProcessInfo.processInfo.environment["ORT_IOS_POD_LOCAL
83110
checksum: "9b41412329a73d7d298b1d94ab40ae9adb65cb84f132054073bc82515b4f5f82")
84111
)
85112
}
113+
114+
if let ext_pod_archive_path = ProcessInfo.processInfo.environment["ORT_EXTENSIONS_IOS_POD_LOCAL_PATH"] {
115+
package.targets.append(Target.binaryTarget(name: "onnxruntime_extensions", path: ext_pod_archive_path))
116+
}
117+
// Note: ORT Extensions 0.8.0 release version pod (Currently not working - it gives a header path not found error.)
118+
else {
119+
// package.targets.append(
120+
// Target.binaryTarget(name: "onnxruntime_extensions",
121+
// url: "https://onnxruntimepackages.z14.web.core.windows.net/pod-archive-onnxruntime-extensions-c-0.8.0.zip",
122+
// checksum: "1d003770c9a6d0ead92c04ed40d5083e8f4f55ea985750c3efab91489be15512")
123+
// )
124+
fatalError("It is not valid to use a release version extensions c pod for now.\n" +
125+
"Please set ORT_EXTENSIONS_IOS_POD_LOCAL_PATH environment variable to specify a location for local dev version pod.\n" +
126+
"See Package.swift for more information on using a local pod archive.")
127+
}

extensions/OrtExt.mm

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#import "OrtExt.h"
5+
6+
#include "onnxruntime_extensions/onnxruntime_extensions.h"
7+
8+
@implementation OrtExt
9+
10+
+ (nonnull ORTCAPIRegisterCustomOpsFnPtr)getRegisterCustomOpsFunctionPointer {
11+
return RegisterCustomOps;
12+
}
13+
14+
@end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This is the umbrella header
2+
3+
#include "OrtExt.h"

extensions/include/OrtExt.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#import <Foundation/Foundation.h>
5+
6+
@interface OrtExt : NSObject
7+
8+
typedef struct OrtStatus* (*ORTCAPIRegisterCustomOpsFnPtr)(struct OrtSessionOptions* /*options*/,
9+
const struct OrtApiBase* /*api*/);
10+
11+
// Note: This returns the address of `RegisterCustomOps` function. At swift
12+
// level, user can call this function to get the RegisterCustomOpsFnPtr
13+
// and use the function pointer to register custom ops. See
14+
// SwiftOnnxRuntimeExtensionsTests.swift for an example usage.
15+
+ (nonnull ORTCAPIRegisterCustomOpsFnPtr)getRegisterCustomOpsFunctionPointer;
16+
17+
@end

objectivec/cxx_api.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,28 @@
1111
#endif // defined(__clang__)
1212

1313
// paths are different when building the Swift Package Manager package as the headers come from the iOS pod archive
14+
// clang-format off
15+
#define STRINGIFY(x) #x
1416
#ifdef SPM_BUILD
15-
#include "onnxruntime/onnxruntime_c_api.h"
16-
#include "onnxruntime/onnxruntime_cxx_api.h"
17-
18-
#if __has_include("onnxruntime/coreml_provider_factory.h")
19-
#define ORT_OBJC_API_COREML_EP_AVAILABLE 1
20-
#include "onnxruntime/coreml_provider_factory.h"
17+
#define ORT_C_CXX_HEADER_FILE_PATH(x) STRINGIFY(onnxruntime/x)
2118
#else
22-
#define ORT_OBJC_API_COREML_EP_AVAILABLE 0
19+
#define ORT_C_CXX_HEADER_FILE_PATH(x) STRINGIFY(x)
2320
#endif
21+
// clang-format on
2422

23+
#if __has_include(ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_training_c_api.h))
24+
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_training_c_api.h)
25+
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_training_cxx_api.h)
2526
#else
26-
#include "onnxruntime_c_api.h"
27-
#include "onnxruntime_cxx_api.h"
27+
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_c_api.h)
28+
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_cxx_api.h)
29+
#endif
2830

29-
#if __has_include("coreml_provider_factory.h")
31+
#if __has_include(ORT_C_CXX_HEADER_FILE_PATH(coreml_provider_factory.h))
3032
#define ORT_OBJC_API_COREML_EP_AVAILABLE 1
31-
#include "coreml_provider_factory.h"
33+
#include ORT_C_CXX_HEADER_FILE_PATH(coreml_provider_factory.h)
3234
#else
3335
#define ORT_OBJC_API_COREML_EP_AVAILABLE 0
34-
35-
#endif
36-
3736
#endif
3837

3938
#if defined(__clang__)

objectivec/cxx_utils.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#import <Foundation/Foundation.h>
5+
6+
#include <optional>
7+
#include <string>
8+
#include <variant>
9+
10+
#import "cxx_api.h"
11+
12+
NS_ASSUME_NONNULL_BEGIN
13+
@class ORTValue;
14+
15+
namespace utils {
16+
17+
NSString* toNSString(const std::string& str);
18+
NSString* _Nullable toNullableNSString(const std::optional<std::string>& str);
19+
20+
std::string toStdString(NSString* str);
21+
std::optional<std::string> toStdOptionalString(NSString* _Nullable str);
22+
23+
std::vector<std::string> toStdStringVector(NSArray<NSString*>* strs);
24+
NSArray<NSString*>* toNSStringNSArray(const std::vector<std::string>& strs);
25+
26+
NSArray<ORTValue*>* _Nullable wrapUnownedCAPIOrtValues(const std::vector<OrtValue*>& values, NSError** error);
27+
28+
std::vector<const OrtValue*> getWrappedCAPIOrtValues(NSArray<ORTValue*>* values);
29+
30+
} // namespace utils
31+
32+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)