mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-05-14 20:48:00 +00:00
Enable iOS packaging for training (#16525)
### Description Enable support for building iOS packages/CocoaPods with training API - Add `Training` Package variant and config files in current iOS packaging utilities to enable creation of training packages ### Motivation and Context This PR introduces new `Training` variant in `build_and_assemble_ios_pods.py` script which allows creating pods for iOS with training API enabled. The sample script to build training pods: ``` python3 tools/ci_build/github/apple/build_and_assemble_ios_pods.py --variant Training \ --build-settings-file tools/ci_build/github/apple/default_full_ios_training_framework_build_settings.json \ -b=-- path_to_protoc_exe=<path/to/protoc> ``` Note: build settings file should have `--enable_training` as a build parameter. Simply adding training packaging increases the duration of the Azure pipeline for packaging by 70 minutes. To address this issue, we need to parallelize pod creation. In order not to further strain the pipeline, the changes for training packaging will be added in another PR, which optimizes the packaging pipeline. --------- Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com>
This commit is contained in:
parent
ba91457183
commit
fd8ad9b950
17 changed files with 136 additions and 57 deletions
|
|
@ -32,7 +32,14 @@ let package = Package(
|
|||
.target(name: "OnnxRuntimeBindings",
|
||||
dependencies: ["onnxruntime"],
|
||||
path: "objectivec",
|
||||
exclude: ["test", "docs", "ReadMe.md", "format_objc.sh"],
|
||||
exclude: ["test", "docs", "ReadMe.md", "format_objc.sh",
|
||||
"ort_checkpoint.mm",
|
||||
"ort_checkpoint_internal.h",
|
||||
"ort_training_session_internal.h",
|
||||
"ort_training_session.mm",
|
||||
"include/ort_checkpoint.h",
|
||||
"include/ort_training_session.h",
|
||||
"include/onnxruntime_training.h"],
|
||||
cxxSettings: [
|
||||
.define("SPM_BUILD"),
|
||||
.unsafeFlags(["-std=c++17",
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@
|
|||
#endif
|
||||
// clang-format on
|
||||
|
||||
#ifndef ENABLE_TRAINING_APIS
|
||||
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_c_api.h)
|
||||
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_cxx_api.h)
|
||||
#else
|
||||
#if __has_include(ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_training_c_api.h))
|
||||
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_training_c_api.h)
|
||||
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_training_cxx_api.h)
|
||||
#else
|
||||
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_c_api.h)
|
||||
#include ORT_C_CXX_HEADER_FILE_PATH(onnxruntime_cxx_api.h)
|
||||
#endif
|
||||
|
||||
#if __has_include(ORT_C_CXX_HEADER_FILE_PATH(coreml_provider_factory.h))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -121,5 +120,3 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -257,5 +256,3 @@ void ORTSetSeed(int64_t seed);
|
|||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import "ort_checkpoint_internal.h"
|
||||
|
||||
#include <optional>
|
||||
|
|
@ -110,4 +109,3 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import "ort_checkpoint.h"
|
||||
|
||||
#import "cxx_api.h"
|
||||
|
|
@ -15,4 +14,3 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import "ort_training_session_internal.h"
|
||||
|
||||
#import <vector>
|
||||
|
|
@ -223,5 +222,3 @@ void ORTSetSeed(int64_t seed) {
|
|||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import "ort_training_session.h"
|
||||
|
||||
#import "cxx_api.h"
|
||||
|
|
@ -15,5 +14,3 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "ort_checkpoint.h"
|
||||
|
|
@ -116,5 +115,3 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "ort_checkpoint.h"
|
||||
|
|
@ -358,5 +357,3 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef ENABLE_TRAINING_APIS
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "ort_training_session.h"
|
||||
|
||||
|
|
@ -25,5 +24,3 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // ENABLE_TRAINING_APIS
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ def get_pod_config_file(package_variant: PackageVariant):
|
|||
return _script_dir / "onnxruntime-mobile-c.config.json"
|
||||
elif package_variant == PackageVariant.Test:
|
||||
return _script_dir / "onnxruntime-test-c.config.json"
|
||||
elif package_variant == PackageVariant.Training:
|
||||
return _script_dir / "onnxruntime-training-c.config.json"
|
||||
else:
|
||||
raise ValueError(f"Unhandled package variant: {package_variant}")
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "onnxruntime-training-c",
|
||||
"summary": "ONNX Runtime Training C/C++ Pod",
|
||||
"description": "A pod for the ONNX Runtime C/C++ library. This pod supports additional training features."
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"build_osx_archs": {
|
||||
"iphoneos": [
|
||||
"arm64"
|
||||
],
|
||||
"iphonesimulator": [
|
||||
"arm64",
|
||||
"x86_64"
|
||||
]
|
||||
},
|
||||
"build_params": [
|
||||
"--ios",
|
||||
"--parallel",
|
||||
"--use_xcode",
|
||||
"--enable_training_apis",
|
||||
"--build_apple_framework",
|
||||
"--skip_tests",
|
||||
"--cmake_extra_defines=onnxruntime_BUILD_UNIT_TESTS=OFF",
|
||||
"--apple_deploy_target=12.0"
|
||||
]
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ from c.assemble_c_pod_package import get_pod_config_file as get_c_pod_config_fil
|
|||
from package_assembly_utils import ( # noqa: E402
|
||||
PackageVariant,
|
||||
copy_repo_relative_to_dir,
|
||||
filter_files,
|
||||
gen_file_from_template,
|
||||
load_json_config,
|
||||
)
|
||||
|
|
@ -29,31 +30,65 @@ include_dirs = [
|
|||
"objectivec",
|
||||
]
|
||||
|
||||
# pod source files
|
||||
source_files = [
|
||||
"objectivec/include/*.h",
|
||||
"objectivec/*.h",
|
||||
"objectivec/*.m",
|
||||
"objectivec/*.mm",
|
||||
]
|
||||
all_objc_files = {
|
||||
"source_files": [
|
||||
"objectivec/include/*.h",
|
||||
"objectivec/*.h",
|
||||
"objectivec/*.m",
|
||||
"objectivec/*.mm",
|
||||
],
|
||||
"public_header_files": [
|
||||
"objectivec/include/*.h",
|
||||
],
|
||||
"test_source_files": [
|
||||
"objectivec/test/*.h",
|
||||
"objectivec/test/*.m",
|
||||
"objectivec/test/*.mm",
|
||||
],
|
||||
"test_resource_files": [
|
||||
"objectivec/test/testdata/*.ort",
|
||||
"onnxruntime/test/testdata/training_api/*",
|
||||
],
|
||||
}
|
||||
|
||||
# pod public header files
|
||||
# note: these are a subset of source_files
|
||||
public_header_files = [
|
||||
"objectivec/include/*.h",
|
||||
]
|
||||
training_only_objc_files = {
|
||||
"source_files": [
|
||||
"objectivec/include/onnxruntime_training.h",
|
||||
"objectivec/include/ort_checkpoint.h",
|
||||
"objectivec/include/ort_training_session.h",
|
||||
"objectivec/ort_checkpoint.mm",
|
||||
"objectivec/ort_checkpoint_internal.h",
|
||||
"objectivec/ort_training_session_internal.h",
|
||||
"objectivec/ort_training_session.mm",
|
||||
],
|
||||
"public_header_files": [
|
||||
"objectivec/include/ort_checkpoint.h",
|
||||
"objectivec/include/ort_training_session.h",
|
||||
"objectivec/include/onnxruntime_training.h",
|
||||
],
|
||||
"test_source_files": [
|
||||
"objectivec/test/ort_training_session_test.mm",
|
||||
"objectivec/test/ort_checkpoint_test.mm",
|
||||
"objectivec/test/ort_training_utils_test.mm",
|
||||
],
|
||||
"test_resource_files": [
|
||||
"onnxruntime/test/testdata/training_api/*",
|
||||
],
|
||||
}
|
||||
|
||||
# pod test source files
|
||||
test_source_files = [
|
||||
"objectivec/test/*.h",
|
||||
"objectivec/test/*.m",
|
||||
"objectivec/test/*.mm",
|
||||
]
|
||||
|
||||
# pod test resource files
|
||||
test_resource_files = [
|
||||
"objectivec/test/testdata/*.ort",
|
||||
]
|
||||
def get_pod_files(package_variant: PackageVariant):
|
||||
"""
|
||||
Gets the source and header files for the given package variant.
|
||||
"""
|
||||
if package_variant == PackageVariant.Training:
|
||||
return all_objc_files
|
||||
else:
|
||||
# return files that are in pod_files but not in training_only_objc_files
|
||||
filtered_pod_files = {}
|
||||
for key in all_objc_files:
|
||||
filtered_pod_files[key] = filter_files(all_objc_files[key], training_only_objc_files[key])
|
||||
return filtered_pod_files
|
||||
|
||||
|
||||
def get_pod_config_file(package_variant: PackageVariant):
|
||||
|
|
@ -64,6 +99,8 @@ def get_pod_config_file(package_variant: PackageVariant):
|
|||
return _script_dir / "onnxruntime-objc.config.json"
|
||||
elif package_variant == PackageVariant.Mobile:
|
||||
return _script_dir / "onnxruntime-mobile-objc.config.json"
|
||||
elif package_variant == PackageVariant.Training:
|
||||
return _script_dir / "onnxruntime-training-objc.config.json"
|
||||
else:
|
||||
raise ValueError(f"Unhandled package variant: {package_variant}")
|
||||
|
||||
|
|
@ -93,8 +130,13 @@ def assemble_objc_pod_package(
|
|||
if staging_dir.exists():
|
||||
print("Warning: staging directory already exists", file=sys.stderr)
|
||||
|
||||
pod_files = get_pod_files(package_variant)
|
||||
|
||||
# copy the necessary files to the staging directory
|
||||
copy_repo_relative_to_dir([license_file, *source_files, *test_source_files, *test_resource_files], staging_dir)
|
||||
copy_repo_relative_to_dir(
|
||||
[license_file, *pod_files["source_files"], *pod_files["test_source_files"], *pod_files["test_resource_files"]],
|
||||
staging_dir,
|
||||
)
|
||||
|
||||
# generate the podspec file from the template
|
||||
|
||||
|
|
@ -108,11 +150,11 @@ def assemble_objc_pod_package(
|
|||
"IOS_DEPLOYMENT_TARGET": framework_info["IOS_DEPLOYMENT_TARGET"],
|
||||
"LICENSE_FILE": license_file,
|
||||
"NAME": pod_name,
|
||||
"PUBLIC_HEADER_FILE_LIST": path_patterns_as_variable_value(public_header_files),
|
||||
"SOURCE_FILE_LIST": path_patterns_as_variable_value(source_files),
|
||||
"PUBLIC_HEADER_FILE_LIST": path_patterns_as_variable_value(pod_files["public_header_files"]),
|
||||
"SOURCE_FILE_LIST": path_patterns_as_variable_value(pod_files["source_files"]),
|
||||
"SUMMARY": pod_config["summary"],
|
||||
"TEST_RESOURCE_FILE_LIST": path_patterns_as_variable_value(test_resource_files),
|
||||
"TEST_SOURCE_FILE_LIST": path_patterns_as_variable_value(test_source_files),
|
||||
"TEST_RESOURCE_FILE_LIST": path_patterns_as_variable_value(pod_files["test_resource_files"]),
|
||||
"TEST_SOURCE_FILE_LIST": path_patterns_as_variable_value(pod_files["test_source_files"]),
|
||||
"VERSION": pod_version,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "onnxruntime-training-objc",
|
||||
"summary": "ONNX Runtime Objective-C Pod",
|
||||
"description": "A pod for the ONNX Runtime Objective-C training API."
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ repo_root = _script_dir.parents[3]
|
|||
class PackageVariant(enum.Enum):
|
||||
Full = 0 # full ORT build with all opsets, ops, and types
|
||||
Mobile = 1 # minimal ORT build with reduced ops
|
||||
Training = 2 # full ORT build with all opsets, ops, and types, plus training APIs
|
||||
Test = -1 # for testing purposes only
|
||||
|
||||
@classmethod
|
||||
|
|
@ -70,6 +71,27 @@ def gen_file_from_template(
|
|||
output.write(content)
|
||||
|
||||
|
||||
def filter_files(all_file_patterns: List[str], excluded_file_patterns: List[str]):
|
||||
"""
|
||||
Filters file paths based on inclusion and exclusion patterns
|
||||
|
||||
:param all_file_patterns The list of file paths to filter.
|
||||
:param excluded_file_patterns The list of exclusion patterns.
|
||||
|
||||
:return The filtered list of file paths
|
||||
"""
|
||||
# get all files matching the patterns in all_file_patterns
|
||||
all_files = [str(path.relative_to(repo_root)) for pattern in all_file_patterns for path in repo_root.glob(pattern)]
|
||||
|
||||
# get all files matching the patterns in excluded_file_patterns
|
||||
exclude_files = [
|
||||
str(path.relative_to(repo_root)) for pattern in excluded_file_patterns for path in repo_root.glob(pattern)
|
||||
]
|
||||
|
||||
# return the difference
|
||||
return list(set(all_files) - set(exclude_files))
|
||||
|
||||
|
||||
def copy_repo_relative_to_dir(patterns: List[str], dest_dir: pathlib.Path):
|
||||
"""
|
||||
Copies file paths relative to the repo root to a directory.
|
||||
|
|
|
|||
Loading…
Reference in a new issue