Skip to content

Commit 4a98c89

Browse files
huydhnpytorchmergebot
authored andcommitted
Refactor ios-build-test workflow to support binary release (pytorch#108322)
This refactors the logic from CircleCI iOS [build](https://github.com/pytorch/pytorch/blob/main/.circleci/config.yml#L1323-L1344) and [upload](https://github.com/pytorch/pytorch/blob/main/.circleci/config.yml#L1369-L1377) jobs to GHA. * Nightly artifacts will be available again on `ossci-ios-build` S3 bucket, for example `libtorch_lite_ios_nightly_2.1.0.20230517.zip`. The last one there was s3://ossci-ios-build/libtorch_lite_ios_nightly_2.1.0.20230517.zip from May 17th * [LibTorch-Lite-Nightly](https://github.com/CocoaPods/Specs/blob/master/Specs/c/3/1/LibTorch-Lite-Nightly/1.14.0.20221109/LibTorch-Lite-Nightly.podspec.json) on cocoapods * Release artifacts will be on `ossci-ios` S3 bucket, for example `s3://ossci-ios/libtorch_lite_ios_1.13.0.zip` from Nov 3rd 2022 * [LibTorch-Lite](https://github.com/CocoaPods/Specs/blob/master/Specs/c/c/3/LibTorch-Lite/1.13.0.1/LibTorch-Lite.podspec.json) on cocoapods * [LibTorch](https://github.com/CocoaPods/Specs/blob/master/Specs/1/3/c/LibTorch/1.13.0.1/LibTorch.podspec.json) on cocoapods I will clean up Circle CI code in another PR. ### Testing Generate new release artifacts for testing from main branch. Simulator testing have all passed. * With lite interpreter https://github.com/pytorch/pytorch/actions/runs/6093860118 * https://ossci-ios.s3.amazonaws.com/libtorch_lite_ios_2.1.0.zip * https://ossci-ios.s3.amazonaws.com/LibTorch-Lite-2.1.0.podspec * LibTorch binary can be built without lite interpreter https://github.com/pytorch/pytorch/actions/runs/6103616035 and uses TorchScript, but it has been long dead from my understanding. The binary can still be built and tested though. * https://ossci-ios.s3.amazonaws.com/libtorch_ios_2.1.0.zip * https://ossci-ios.s3.amazonaws.com/LibTorch-2.1.0.podspec ### Next step for release * Once the PR is committed. I plan to use the workflow dispatch to build the binaries manually on `release/2.1` branch. Once they looks good, we can publish them on cocoapods. Pull Request resolved: pytorch#108322 Approved by: https://github.com/atalman
1 parent 63ae105 commit 4a98c89

File tree

8 files changed

+431
-79
lines changed

8 files changed

+431
-79
lines changed

.github/workflows/_ios-build-test.yml

+320-47
Large diffs are not rendered by default.
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Build iOS binaries
2+
3+
on:
4+
push:
5+
branches:
6+
- nightly
7+
tags:
8+
# NOTE: Binary build pipelines should only get triggered on release candidate builds
9+
# Release candidate tags look like: v1.11.0-rc1
10+
- v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+
11+
paths:
12+
- .github/workflows/build-ios-binaries.yml
13+
- .github/workflows/_ios-build-test.yml
14+
pull_request:
15+
paths:
16+
- .github/workflows/build-ios-binaries.yml
17+
- .github/workflows/_ios-build-test.yml
18+
# NB: We can use this workflow dispatch to test and build iOS binaries manually
19+
workflow_dispatch:
20+
inputs:
21+
use_lite_interpreter:
22+
description: "Use PyTorch lite interpreter?"
23+
type: string
24+
default: 1
25+
use_coreml:
26+
description: "Use Apple Core ML?"
27+
type: string
28+
default: 1
29+
use_custom_op_list:
30+
description: "Specify the custom ops list to include in the binaries"
31+
type: string
32+
default: ""
33+
34+
concurrency:
35+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.event_name == 'workflow_dispatch' }}
36+
cancel-in-progress: true
37+
38+
jobs:
39+
# TODO: Figure out how to migrate this job to M1 runner
40+
ios-build-test:
41+
name: ios-build-test
42+
uses: ./.github/workflows/_ios-build-test.yml
43+
with:
44+
build-environment: ios-build-test
45+
sync-tag: ios-build-test
46+
test-matrix: |
47+
{ include: [
48+
{ config: "default",
49+
shard: 1,
50+
num_shards: 1,
51+
runner: "macos-12",
52+
ios_platform: "SIMULATOR",
53+
ios_arch: "x86_64",
54+
use_lite_interpreter: ${{ inputs.use_lite_interpreter || 1 }},
55+
use_metal: 0,
56+
use_coreml: ${{ inputs.use_coreml || 1 }},
57+
use_custom_op_list: ${{ inputs.use_custom_op_list || '' }}
58+
},
59+
{ config: "default",
60+
shard: 1,
61+
num_shards: 1,
62+
runner: "macos-12",
63+
ios_platform: "OS",
64+
ios_arch: "arm64",
65+
use_lite_interpreter: ${{ inputs.use_lite_interpreter || 1 }},
66+
use_metal: 1,
67+
use_coreml: ${{ inputs.use_coreml || 1 }},
68+
use_custom_op_list: ${{ inputs.use_custom_op_list || '' }}
69+
}
70+
]}

.github/workflows/periodic.yml

+27-19
Original file line numberDiff line numberDiff line change
@@ -112,30 +112,38 @@ jobs:
112112
cuda-version: "11.8"
113113
test-matrix: ${{ needs.win-vs2019-cuda11_8-py3-build.outputs.test-matrix }}
114114

115-
ios-12-5-1-x86-64-coreml:
116-
name: ios-12-5-1-x86-64-coreml
115+
# TODO: Figure out how to migrate this job to M1 runner
116+
ios-build-test:
117+
name: ios-build-test
117118
if: github.event_name != 'schedule' || github.event.schedule == '45 0,8,16 * * 1-5' || github.event.schedule == '45 4 * * 0,6'
118119
uses: ./.github/workflows/_ios-build-test.yml
119120
with:
120-
build-environment: ios-12-5-1-x86-64-coreml
121-
ios-platform: SIMULATOR
122-
ios-arch: x86_64
121+
build-environment: ios-build-test
122+
sync-tag: ios-build-test
123123
test-matrix: |
124124
{ include: [
125-
{ config: "default", shard: 1, num_shards: 1, runner: "macos-12" },
126-
]}
127-
128-
ios-12-5-1-arm64-custom-ops:
129-
name: ios-12-5-1-arm64-custom-ops
130-
if: github.event_name != 'schedule' || github.event.schedule == '45 0,8,16 * * 1-5' || github.event.schedule == '45 4 * * 0,6'
131-
uses: ./.github/workflows/_ios-build-test.yml
132-
with:
133-
build-environment: ios-12-5-1-arm64-custom-ops
134-
ios-platform: OS
135-
ios-arch: arm64
136-
test-matrix: |
137-
{ include: [
138-
{ config: "default", shard: 1, num_shards: 1, runner: "macos-12" },
125+
{ config: "default",
126+
shard: 1,
127+
num_shards: 1,
128+
runner: "macos-12",
129+
ios_platform: "SIMULATOR",
130+
ios_arch: "x86_64",
131+
use_lite_interpreter: 1,
132+
use_metal: 0,
133+
use_coreml: 1,
134+
use_custom_op_list: ""
135+
},
136+
{ config: "default",
137+
shard: 1,
138+
num_shards: 1,
139+
runner: "macos-12",
140+
ios_platform: "OS",
141+
ios_arch: "arm64",
142+
use_lite_interpreter: 1,
143+
use_metal: 1,
144+
use_coreml: 1,
145+
use_custom_op_list: "mobilenetv2.yaml"
146+
}
139147
]}
140148
141149
buck-build-test:

cmake/iOS.cmake

+8-8
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ set(CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE)
5353
set(PKG_CONFIG_EXECUTABLE pkg-config CACHE FILEPATH "" FORCE)
5454

5555
# Setup iOS platform unless specified manually with IOS_PLATFORM
56-
if(NOT DEFINED IOS_PLATFORM)
56+
if(NOT IOS_PLATFORM)
5757
set(IOS_PLATFORM "OS")
58-
endif(NOT DEFINED IOS_PLATFORM)
58+
endif(NOT IOS_PLATFORM)
5959
set(IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS Platform")
6060

6161
# Check the platform selection and setup for developer root
@@ -118,9 +118,9 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
118118
# (where install_name_tool was hardcoded) and where CMAKE_INSTALL_NAME_TOOL isn't in the cache
119119
# and still cmake didn't fail in CMakeFindBinUtils.cmake (because it isn't rerun)
120120
# hardcode CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did before, Alex
121-
if(NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
121+
if(NOT CMAKE_INSTALL_NAME_TOOL)
122122
find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool)
123-
endif(NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
123+
endif(NOT CMAKE_INSTALL_NAME_TOOL)
124124

125125
# Setup iOS deployment target
126126
set(IOS_DEPLOYMENT_TARGET ${IOS_DEPLOYMENT_TARGET} CACHE STRING "Minimum iOS version")
@@ -130,17 +130,17 @@ set(IOS_DEPLOYMENT_TARGET ${IOS_DEPLOYMENT_TARGET} CACHE STRING "Minimum iOS ver
130130
exec_program(/usr/bin/xcode-select ARGS -print-path OUTPUT_VARIABLE CMAKE_XCODE_DEVELOPER_DIR)
131131
set(XCODE_POST_43_ROOT "${CMAKE_XCODE_DEVELOPER_DIR}/Platforms/${IOS_PLATFORM_LOCATION}/Developer")
132132
set(XCODE_PRE_43_ROOT "/Developer/Platforms/${IOS_PLATFORM_LOCATION}/Developer")
133-
if(NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT)
133+
if(NOT CMAKE_IOS_DEVELOPER_ROOT)
134134
if(EXISTS ${XCODE_POST_43_ROOT})
135135
set(CMAKE_IOS_DEVELOPER_ROOT ${XCODE_POST_43_ROOT})
136136
elseif(EXISTS ${XCODE_PRE_43_ROOT})
137137
set(CMAKE_IOS_DEVELOPER_ROOT ${XCODE_PRE_43_ROOT})
138138
endif(EXISTS ${XCODE_POST_43_ROOT})
139-
endif(NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT)
139+
endif(NOT CMAKE_IOS_DEVELOPER_ROOT)
140140
set(CMAKE_IOS_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT} CACHE PATH "Location of iOS Platform")
141141

142142
# Find and use the most recent iOS sdk unless specified manually with CMAKE_IOS_SDK_ROOT
143-
if(NOT DEFINED CMAKE_IOS_SDK_ROOT)
143+
if(NOT CMAKE_IOS_SDK_ROOT)
144144
file(GLOB _CMAKE_IOS_SDKS "${CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*")
145145
if(_CMAKE_IOS_SDKS)
146146
list(SORT _CMAKE_IOS_SDKS)
@@ -150,7 +150,7 @@ if(NOT DEFINED CMAKE_IOS_SDK_ROOT)
150150
message(FATAL_ERROR "No iOS SDK's found in default search path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.")
151151
endif(_CMAKE_IOS_SDKS)
152152
message(STATUS "Toolchain using default iOS SDK: ${CMAKE_IOS_SDK_ROOT}")
153-
endif(NOT DEFINED CMAKE_IOS_SDK_ROOT)
153+
endif(NOT CMAKE_IOS_SDK_ROOT)
154154
set(CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK")
155155

156156
# Set the sysroot default to the most recent SDK

ios/LibTorch-Lite.podspec renamed to ios/LibTorch-Lite.podspec.template

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'LibTorch-Lite'
3-
s.version = '1.13.0'
3+
s.version = 'IOS_BUILD_VERSION'
44
s.authors = 'PyTorch Team'
55
s.license = { :type => 'BSD' }
66
s.homepage = 'https://github.com/pytorch/pytorch'
@@ -33,5 +33,5 @@ Pod::Spec.new do |s|
3333
'VALID_ARCHS' => 'x86_64 arm64'
3434
}
3535
s.library = ['c++', 'stdc++']
36-
s.frameworks = 'Accelerate'
36+
s.frameworks = 'Accelerate', 'MetalPerformanceShaders', 'CoreML'
3737
end

ios/LibTorch.podspec renamed to ios/LibTorch.podspec.template

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'LibTorch'
3-
s.version = '1.13.0'
3+
s.version = 'IOS_BUILD_VERSION'
44
s.authors = 'PyTorch Team'
55
s.license = { :type => 'BSD' }
66
s.homepage = 'https://github.com/pytorch/pytorch'
@@ -33,5 +33,5 @@ Pod::Spec.new do |s|
3333
'VALID_ARCHS' => 'x86_64 arm64'
3434
}
3535
s.library = ['c++', 'stdc++']
36-
s.frameworks = 'Accelerate'
36+
s.frameworks = 'Accelerate', 'MetalPerformanceShaders', 'CoreML'
3737
end

ios/TestApp/benchmark/coreml_backend.py

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def main():
3232
mlmodel = torch._C._jit_to_backend("coreml", model, compile_spec)
3333
print(mlmodel._c._get_method("forward").graph)
3434
mlmodel._save_for_lite_interpreter("../models/model_coreml.ptl")
35+
torch.jit.save(mlmodel, "../models/model_coreml.pt")
3536

3637

3738
if __name__ == "__main__":

ios/TestApp/benchmark/trace_model.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
optimized_scripted_module = optimize_for_mobile(traced_script_module)
1010
torch.jit.save(optimized_scripted_module, "../models/model.pt")
1111
exported_optimized_scripted_module = (
12-
optimized_scripted_module._save_for_lite_interpreter("../models/model_lite.ptl")
12+
optimized_scripted_module._save_for_lite_interpreter("../models/model.ptl")
1313
)

0 commit comments

Comments
 (0)