forked from pytorch/executorch
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall_executorch.py
More file actions
Latest commit
206 lines (175 loc) · 6.52 KB
/
Copy pathinstall_executorch.py
File metadata and controls
206 lines (175 loc) · 6.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# Copyright (c) Meta Platforms, Inc. and affiliates.
# Copyright 2024-25 Arm Limited and/or its affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
importargparse
importglob
importlogging
importos
importshutil
importsubprocess
importsys
fromcontextlibimportcontextmanager
frominstall_requirementsimport (
install_requirements,
python_is_compatible,
TORCH_NIGHTLY_URL,
)
# Set up logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s [ExecuTorch] %(levelname)s: %(message)s"
)
logger=logging.getLogger()
@contextmanager
defpushd(new_dir):
"""Change the current directory to new_dir and yield. When exiting the context, change back to the original directory."""
original_dir=os.getcwd()
os.chdir(new_dir)
try:
yield
finally:
os.chdir(original_dir)
defclean():
print("Cleaning build artifacts...")
print("Cleaning pip-out/...")
shutil.rmtree("pip-out/", ignore_errors=True)
dirs=glob.glob("cmake-out*/") +glob.glob("cmake-android-out/")
fordindirs:
print(f"Cleaning {d}...")
shutil.rmtree(d, ignore_errors=True)
print("Done cleaning build artifacts.")
################################################################################
# Git submodules
################################################################################
# The following submodules are required to be able to build ExecuTorch. If any of
# these folders are missing or missing CMakeLists.txt, we will run
# `git submodule update` to try to fix it. If the command fails, we will raise an
# error.
# An alternative to this would be to run `git submodule status` and run
# `git submodule update` if there's any local changes. However this is a bit
# too restrictive for users who modifies and tests the dependencies locally.
# keep sorted
REQUIRED_SUBMODULES= {
"ao": "LICENSE", # No CMakeLists.txt, choose a sort of stable file to check.
"cpuinfo": "CMakeLists.txt",
"eigen": "CMakeLists.txt",
"flatbuffers": "CMakeLists.txt",
"FP16": "CMakeLists.txt",
"FXdiv": "CMakeLists.txt",
"gflags": "CMakeLists.txt",
"prelude": "BUCK",
"pthreadpool": "CMakeLists.txt",
"pybind11": "CMakeLists.txt",
"shim": "BUCK",
"tokenizers": "CMakeLists.txt",
"XNNPACK": "CMakeLists.txt",
}
defget_required_submodule_paths():
gitmodules_path=os.path.join(os.getcwd(), ".gitmodules")
ifnotos.path.isfile(gitmodules_path):
logger.error(".gitmodules file not found.")
exit(1)
withopen(gitmodules_path, "r") asfile:
lines=file.readlines()
# Extract paths of required submodules
required_paths= {}
forlineinlines:
ifline.strip().startswith("path ="):
path=line.split("=")[1].strip()
forsubmodule, file_nameinREQUIRED_SUBMODULES.items():
ifsubmoduleinpath:
required_paths[path] =file_name
returnrequired_paths
defcheck_and_update_submodules():
defcheck_folder(folder: str, file: str) ->bool:
returnos.path.isdir(folder) andos.path.isfile(os.path.join(folder, file))
# Check if the directories exist for each required submodule
missing_submodules= {}
forpath, fileinget_required_submodule_paths().items():
ifnotcheck_folder(path, file):
missing_submodules[path] =file
# If any required submodule directories are missing, update them
ifmissing_submodules:
logger.warning("Some required submodules are missing. Updating submodules...")
try:
subprocess.check_call(["git", "submodule", "sync", "--recursive"])
subprocess.check_call(
["git", "submodule", "update", "--init", "--recursive"]
)
exceptsubprocess.CalledProcessErrorase:
logger.error(f"Error updating submodules: {e}")
exit(1)
# After updating submodules, check again
forpath, fileinmissing_submodules.items():
ifnotcheck_folder(path, file):
logger.error(f"{file} not found in {path}.")
logger.error(
"Submodule update failed. Please run `git submodule update --init --recursive` manually."
)
exit(1)
logger.info("All required submodules are present.")
def_parse_args() ->argparse.Namespace:
parser=argparse.ArgumentParser(
description="Install executorch in your Python environment."
)
parser.add_argument(
"--clean",
action="store_true",
help="clean build artifacts and pip-out instead of installing",
)
parser.add_argument(
"--use-pt-pinned-commit",
action="store_true",
help="build from the pinned PyTorch commit instead of nightly",
)
parser.add_argument(
"--editable",
"-e",
action="store_true",
help="build an editable pip wheel, changes to python code will be "
"picked up without rebuilding the wheel. Extension libraries will be "
"installed inside the source tree.",
)
returnparser.parse_args()
defmain(args):
ifnotpython_is_compatible():
sys.exit(1)
args=_parse_args()
ifargs.clean:
clean()
return
cmake_args= [os.getenv("CMAKE_ARGS", "")]
# Use ClangCL on Windows.
# ClangCL is an alias to Clang that configures it to work in an MSVC-compatible
# mode. Using it on Windows to avoid compiler compatibility issues for MSVC.
ifos.name=="nt":
cmake_args.append("-T ClangCL")
os.environ["CMAKE_ARGS"] =" ".join(cmake_args)
check_and_update_submodules()
# This option is used in CI to make sure that PyTorch build from the pinned commit
# is used instead of nightly. CI jobs wouldn't be able to catch regression from the
# latest PT commit otherwise
install_requirements(use_pytorch_nightly=notargs.use_pt_pinned_commit)
os.execvp(
sys.executable,
[
sys.executable,
"-m",
"pip",
"install",
]
+ (["--editable"] ifargs.editableelse [])
+ [
".",
"--no-build-isolation",
"-v",
"--extra-index-url",
TORCH_NIGHTLY_URL,
],
)
if__name__=="__main__":
# Before doing anything, cd to the directory containing this script.
os.chdir(os.path.dirname(os.path.abspath(__file__)))
main(sys.argv[1:])