Skip to content

Commit f66d687

Browse files
huydhnfacebook-github-bot
authored andcommitted
Add cmake Linux build and test job (#52)
Summary: This adds a build and test workflow using CMake on Linux. Here are some of my findings: * The build only works if `executorch` is checked out into a directory called `executorch`. Otherwise, including `<executorch/...>` would fail (pytorch/test-infra#4465) * Linking with GNU ld fails with the following error `/usr/bin/ld: -f may not be used without -shared`, which I'm not sure what it means atm, so I switch to LLD by adding `add_link_options("-fuse-ld=lld")` for clang * I still couldn't make this work on Mac yet because `libprogram_schema.a` is empty and Mac `ar` refuses to link the library. So that's an issue for another day. ``` /Library/Developer/CommandLineTools/usr/bin/ar qc libprogram_schema.a ar: no archive members specified ``` Pull Request resolved: #52 Reviewed By: dbort Differential Revision: D48216923 Pulled By: huydhn fbshipit-source-id: 0ba751e3e849ec6779b19338253dd73b7ef0f3c8
1 parent 30a4b36 commit f66d687

File tree

9 files changed

+99
-48
lines changed

9 files changed

+99
-48
lines changed

.ci/docker/conda-env-ci.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# TODO: We might need to update this to install flatbuffers from the pinned commit
22
# in fbcode/executorch/third-party/flatbuffers.submodule.txt
33
flatbuffers=2.0.0
4+
cmake=3.22.1

.ci/docker/requirements-ci.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ numpy==1.25.2
33
PyYAML==6.0.1
44
ruamel.yaml==0.17.32
55
sympy==1.12
6+
tomli==2.0.1
67
zstd==1.5.5.1

.ci/scripts/test-cmake.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/bin/bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
set -exu
9+
10+
# shellcheck source=/dev/null
11+
source "$(dirname "${BASH_SOURCE[0]}")/utils.sh"
12+
13+
test_model() {
14+
MODEL_NAME=$1
15+
python -m examples.export.export_example --model_name="${MODEL_NAME}"
16+
17+
# Run test model
18+
./"${CMAKE_OUTPUT_DIR}"/executor_runner --model_path "./${MODEL_NAME}.pte"
19+
}
20+
21+
build_and_test_executorch() {
22+
CMAKE_OUTPUT_DIR=cmake-out
23+
# Build executorch runtime using cmake
24+
rm -rf "${CMAKE_OUTPUT_DIR}" && mkdir "${CMAKE_OUTPUT_DIR}"
25+
26+
pushd "${CMAKE_OUTPUT_DIR}"
27+
cmake -DBUCK2=buck2 ..
28+
popd
29+
30+
if [ "$(uname)" == "Darwin" ]; then
31+
CMAKE_JOBS=$(( $(sysctl -n hw.ncpu) - 1 ))
32+
else
33+
CMAKE_JOBS=$(( $(nproc) - 1 ))
34+
fi
35+
cmake --build "${CMAKE_OUTPUT_DIR}" -j "${CMAKE_JOBS}"
36+
37+
which python
38+
# Test the example linear model
39+
test_model "linear"
40+
}
41+
42+
install_executorch
43+
build_and_test_executorch

.ci/scripts/test.sh

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,24 @@
77

88
set -exu
99

10-
install_executorch() {
11-
which pip
12-
# Install executorch, this assumes that Executorch is checked out in the
13-
# current directory
14-
pip install .
15-
# Just print out the list of packages for debugging
16-
pip list
10+
# shellcheck source=/dev/null
11+
source "$(dirname "${BASH_SOURCE[0]}")/utils.sh"
12+
13+
test_model() {
14+
MODEL_NAME=$1
15+
python -m examples.export.export_example --model_name="${MODEL_NAME}"
16+
17+
# Run test model
18+
buck2 run //examples/executor_runner:executor_runner -- --model_path "./${MODEL_NAME}.pte"
1719
}
1820

1921
build_and_test_executorch() {
2022
# Build executorch runtime
2123
buck2 build //examples/executor_runner:executor_runner
2224

2325
which python
24-
# Export a test model
25-
python -m examples.export.export_example --model_name="linear"
26-
# Run test model
27-
buck2 run //examples/executor_runner:executor_runner -- --model_path ./linear.pte
26+
# Test the example linear model
27+
test_model "linear"
2828
}
2929

3030
install_executorch

.ci/scripts/utils.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
install_executorch() {
9+
which pip
10+
# Install executorch, this assumes that Executorch is checked out in the
11+
# current directory
12+
pip install .
13+
# Just print out the list of packages for debugging
14+
pip list
15+
}

.github/workflows/pull.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ jobs:
3030
# Build and test Executorch
3131
bash .ci/scripts/test.sh
3232
33+
# Test custom ops
34+
bash examples/custom_ops/test_custom_ops.sh
35+
3336
buck-build-test-macos:
3437
name: buck-build-test-macos
3538
uses: pytorch/test-infra/.github/workflows/macos_job.yml@main
@@ -47,3 +50,21 @@ jobs:
4750
# Build and test Executorch
4851
bash .ci/scripts/test.sh
4952
popd
53+
54+
cmake-build-test-linux:
55+
name: cmake-build-test-linux
56+
uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
57+
with:
58+
runner: linux.2xlarge
59+
docker-image: executorch-ubuntu-22.04-clang12
60+
fetch-depth: 0
61+
submodules: 'true'
62+
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
63+
script: |
64+
PYTHON_VERSION=3.10
65+
# TODO: Figure out why /opt/conda/envs/py_$PYTHON_VERSION/bin is not in the path
66+
# here, as it's there in the container
67+
export PATH="/opt/conda/envs/py_${PYTHON_VERSION}/bin:${PATH}"
68+
69+
# Build and test Executorch
70+
bash .ci/scripts/test-cmake.sh

CMakeLists.txt

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -259,19 +259,7 @@ target_link_libraries(portable_kernels_bindings INTERFACE portable_kernels)
259259

260260
# Ensure that the load-time constructor functions run. By default, the linker
261261
# would remove them since there are no other references to them.
262-
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL
263-
"AppleClang")
264-
if(CMAKE_TOOLCHAIN_FILE MATCHES ".*android\.toolchain\.cmake$")
265-
# For Android tool chain
266-
gcc_kernel_link_options(portable_kernels_bindings)
267-
else()
268-
# For host tool chain
269-
clang_kernel_link_options(portable_kernels_bindings)
270-
endif()
271-
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
272-
# Using gcc
273-
gcc_kernel_link_options(portable_kernels_bindings)
274-
endif()
262+
kernel_link_options(portable_kernels_bindings)
275263

276264
#
277265
# executor_runner: A simple commandline tool that loads and runs a program file.

build/Utils.cmake

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,8 @@ function(executorch_print_configuration_summary)
2222
message(STATUS " REGISTER_EXAMPLE_CUSTOM_OPS : ${REGISTER_EXAMPLE_CUSTOM_OPS}")
2323
endfunction()
2424

25-
# This is the funtion to use -Wl to link static library, used for clang
26-
function(clang_kernel_link_options target_name)
27-
target_link_options(${target_name}
28-
INTERFACE
29-
# TODO(dbort): This will cause the .a to show up on the link line twice
30-
# for targets that depend on this library; once because CMake will add
31-
# it, and once because it's in this list of args. See if there's a way
32-
# to avoid that.
33-
-Wl,-force_load,$<TARGET_FILE:${target_name}>
34-
)
35-
endfunction()
36-
37-
# This is the funtion to use -Wl, --whole-archive to link static library, used for gcc
38-
function(gcc_kernel_link_options target_name)
25+
# This is the funtion to use -Wl, --whole-archive to link static library
26+
function(kernel_link_options target_name)
3927
target_link_options(${target_name}
4028
INTERFACE
4129
# TODO(dbort): This will cause the .a to show up on the link line twice

examples/custom_ops/CMakeLists.txt

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ endif()
3131
if(NOT TORCH_ROOT)
3232
set(TORCH_ROOT ${EXECUTORCH_ROOT}/third-party/pytorch)
3333
endif()
34+
35+
include(${EXECUTORCH_ROOT}/build/Utils.cmake)
36+
3437
# Command to generate selected_operators.yaml from custom_ops.yaml.
3538
set(_oplist_yaml ${CMAKE_CURRENT_BINARY_DIR}/selected_operators.yaml)
3639
file(GLOB_RECURSE _codegen_tools_srcs "${EXECUTORCH_ROOT}/codegen/tools/*.py")
@@ -107,16 +110,7 @@ if(REGISTER_EXAMPLE_CUSTOM_OP_2)
107110

108111
# Ensure that the load-time constructor functions run. By default, the linker
109112
# would remove them since there are no other references to them.
110-
if((CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
111-
OR (APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
112-
target_link_options(custom_ops_aot_lib INTERFACE
113-
"-Wl,-force_load,$<TARGET_FILE:custom_ops_aot_lib>")
114-
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
115-
target_link_options(
116-
custom_ops_aot_lib INTERFACE
117-
"-Wl,--whole-archive,$<TARGET_FILE:custom_ops_aot_lib>,--no-whole-archive"
118-
)
119-
endif()
113+
kernel_link_options("custom_ops_aot_lib")
120114
endif()
121115

122116
# 1. C++ library to register custom ops into Executorch runtime.

0 commit comments

Comments
 (0)