Skip to content

Commit

Permalink
Add install_requirements.{sh,py} that only install requirements (#7715)
Browse files Browse the repository at this point in the history
Now that the previous PR renamed install_requirements to install_executorch, we can use those names for scripts that actually just install requirements.
  • Loading branch information
swolchok authored Jan 17, 2025
1 parent ee1d7c3 commit cd0e584
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 137 deletions.
131 changes: 10 additions & 121 deletions install_executorch.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,59 +10,15 @@
import glob
import itertools
import os
import platform
import re
import shutil
import subprocess
import sys

# Before doing anything, cd to the directory containing this script.
os.chdir(os.path.dirname(os.path.abspath(__file__)))


def python_is_compatible():
# Scrape the version range from pyproject.toml, which should be in the current directory.
version_specifier = None
with open("pyproject.toml", "r") as file:
for line in file:
if line.startswith("requires-python"):
match = re.search(r'"([^"]*)"', line)
if match:
version_specifier = match.group(1)
break

if not version_specifier:
print(
"WARNING: Skipping python version check: version range not found",
file=sys.stderr,
)
return False

# Install the packaging module if necessary.
try:
import packaging
except ImportError:
subprocess.run(
[sys.executable, "-m", "pip", "install", "packaging"], check=True
)
# Compare the current python version to the range in version_specifier. Exits
# with status 1 if the version is not compatible, or with status 0 if the
# version is compatible or the logic itself fails.
try:
import packaging.specifiers
import packaging.version

python_version = packaging.version.parse(platform.python_version())
version_range = packaging.specifiers.SpecifierSet(version_specifier)
if python_version not in version_range:
print(
f'ERROR: ExecuTorch does not support python version {python_version}: must satisfy "{version_specifier}"',
file=sys.stderr,
)
return False
except Exception as e:
print(f"WARNING: Skipping python version check: {e}", file=sys.stderr)
return True
from install_requirements import (
install_requirements,
python_is_compatible,
TORCH_NIGHTLY_URL,
)


def clean():
Expand All @@ -79,78 +35,6 @@ def clean():
VALID_PYBINDS = ["coreml", "mps", "xnnpack"]


# The pip repository that hosts nightly torch packages.
TORCH_NIGHTLY_URL = "https://download.pytorch.org/whl/nightly/cpu"


# Since ExecuTorch often uses main-branch features of pytorch, only the nightly
# pip versions will have the required features.
#
# NOTE: If a newly-fetched version of the executorch repo changes the value of
# NIGHTLY_VERSION, you should re-run this script to install the necessary
# package versions.
NIGHTLY_VERSION = "dev20250104"


def install_requirements(use_pytorch_nightly):
# pip packages needed by exir.
EXIR_REQUIREMENTS = [
# Setting use_pytorch_nightly to false to test the pinned PyTorch commit. Note
# that we don't need to set any version number there because they have already
# been installed on CI before this step, so pip won't reinstall them
f"torch==2.6.0.{NIGHTLY_VERSION}" if use_pytorch_nightly else "torch",
(
f"torchvision==0.22.0.{NIGHTLY_VERSION}"
if use_pytorch_nightly
else "torchvision"
), # For testing.
]

EXAMPLES_REQUIREMENTS = [
f"torchaudio==2.6.0.{NIGHTLY_VERSION}" if use_pytorch_nightly else "torchaudio",
]

# Assemble the list of requirements to actually install.
# TODO: Add options for reducing the number of requirements.
REQUIREMENTS_TO_INSTALL = EXIR_REQUIREMENTS + EXAMPLES_REQUIREMENTS

# Install the requirements. `--extra-index-url` tells pip to look for package
# versions on the provided URL if they aren't available on the default URL.
subprocess.run(
[
sys.executable,
"-m",
"pip",
"install",
"-r",
"requirements-examples.txt",
*REQUIREMENTS_TO_INSTALL,
"--extra-index-url",
TORCH_NIGHTLY_URL,
],
check=True,
)

LOCAL_REQUIREMENTS = [
"third-party/ao", # We need the latest kernels for fast iteration, so not relying on pypi.
]

# Install packages directly from local copy instead of pypi.
# This is usually not recommended.
subprocess.run(
[
sys.executable,
"-m",
"pip",
"install",
# Without --no-build-isolation, setup.py can't find the torch module.
"--no-build-isolation",
*LOCAL_REQUIREMENTS,
],
check=True,
)


def main(args):
if not python_is_compatible():
sys.exit(1)
Expand Down Expand Up @@ -252,4 +136,9 @@ def main(args):


if __name__ == "__main__":
# Before doing anything, cd to the directory containing this script.
os.chdir(os.path.dirname(os.path.abspath(__file__)))
if not python_is_compatible():
sys.exit(1)

main(sys.argv[1:])
17 changes: 1 addition & 16 deletions install_executorch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,4 @@

# Before doing anything, cd to the directory containing this script.
cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null || /bin/true

# Find the names of the python tools to use.
if [[ -z $PYTHON_EXECUTABLE ]];
then
if [[ -z $CONDA_DEFAULT_ENV ]] || [[ $CONDA_DEFAULT_ENV == "base" ]] || [[ ! -x "$(command -v python)" ]];
then
PYTHON_EXECUTABLE=python3
else
PYTHON_EXECUTABLE=python
fi
fi

$PYTHON_EXECUTABLE ./install_executorch.py "$@"

# Exit with the same status as the python script.
exit $?
./run_python_script.sh ./install_executorch.py "$@"
150 changes: 150 additions & 0 deletions install_requirements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# 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.

import argparse
import platform
import re
import subprocess
import sys


def python_is_compatible():
# Scrape the version range from pyproject.toml, which should be in the current directory.
version_specifier = None
with open("pyproject.toml", "r") as file:
for line in file:
if line.startswith("requires-python"):
match = re.search(r'"([^"]*)"', line)
if match:
version_specifier = match.group(1)
break

if not version_specifier:
print(
"WARNING: Skipping python version check: version range not found",
file=sys.stderr,
)
return False

# Install the packaging module if necessary.
try:
import packaging
except ImportError:
subprocess.run(
[sys.executable, "-m", "pip", "install", "packaging"], check=True
)
# Compare the current python version to the range in version_specifier. Exits
# with status 1 if the version is not compatible, or with status 0 if the
# version is compatible or the logic itself fails.
try:
import packaging.specifiers
import packaging.version

python_version = packaging.version.parse(platform.python_version())
version_range = packaging.specifiers.SpecifierSet(version_specifier)
if python_version not in version_range:
print(
f'ERROR: ExecuTorch does not support python version {python_version}: must satisfy "{version_specifier}"',
file=sys.stderr,
)
return False
except Exception as e:
print(f"WARNING: Skipping python version check: {e}", file=sys.stderr)
return True


# The pip repository that hosts nightly torch packages.
TORCH_NIGHTLY_URL = "https://download.pytorch.org/whl/nightly/cpu"


# Since ExecuTorch often uses main-branch features of pytorch, only the nightly
# pip versions will have the required features.
#
# NOTE: If a newly-fetched version of the executorch repo changes the value of
# NIGHTLY_VERSION, you should re-run this script to install the necessary
# package versions.
NIGHTLY_VERSION = "dev20250104"


def install_requirements(use_pytorch_nightly):
# pip packages needed by exir.
EXIR_REQUIREMENTS = [
# Setting use_pytorch_nightly to false to test the pinned PyTorch commit. Note
# that we don't need to set any version number there because they have already
# been installed on CI before this step, so pip won't reinstall them
f"torch==2.6.0.{NIGHTLY_VERSION}" if use_pytorch_nightly else "torch",
(
f"torchvision==0.22.0.{NIGHTLY_VERSION}"
if use_pytorch_nightly
else "torchvision"
), # For testing.
]

EXAMPLES_REQUIREMENTS = [
f"torchaudio==2.6.0.{NIGHTLY_VERSION}" if use_pytorch_nightly else "torchaudio",
]

# Assemble the list of requirements to actually install.
# TODO: Add options for reducing the number of requirements.
REQUIREMENTS_TO_INSTALL = EXIR_REQUIREMENTS + EXAMPLES_REQUIREMENTS

# Install the requirements. `--extra-index-url` tells pip to look for package
# versions on the provided URL if they aren't available on the default URL.
subprocess.run(
[
sys.executable,
"-m",
"pip",
"install",
"-r",
"requirements-examples.txt",
*REQUIREMENTS_TO_INSTALL,
"--extra-index-url",
TORCH_NIGHTLY_URL,
],
check=True,
)

LOCAL_REQUIREMENTS = [
"third-party/ao", # We need the latest kernels for fast iteration, so not relying on pypi.
]

# Install packages directly from local copy instead of pypi.
# This is usually not recommended.
subprocess.run(
[
sys.executable,
"-m",
"pip",
"install",
# Without --no-build-isolation, setup.py can't find the torch module.
"--no-build-isolation",
*LOCAL_REQUIREMENTS,
],
check=True,
)


def main(args):
parser = argparse.ArgumentParser()
parser.add_argument(
"--use-pt-pinned-commit",
action="store_true",
help="build from the pinned PyTorch commit instead of nightly",
)
args = parser.parse_args(args)
install_requirements(use_pytorch_nightly=not bool(args.use_pt_pinned_commit))


if __name__ == "__main__":
import os

# Before doing anything, cd to the directory containing this script.
os.chdir(os.path.dirname(os.path.abspath(__file__)))
if not python_is_compatible():
sys.exit(1)
main(sys.argv[1:])
10 changes: 10 additions & 0 deletions install_requirements.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and 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.

# Before doing anything, cd to the directory containing this script.
cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null || /bin/true
./run_python_script.sh ./install_requirements.py "$@"
26 changes: 26 additions & 0 deletions run_python_script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and 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.

# Before doing anything, cd to the directory containing this script.
cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null || /bin/true

# Find the names of the python tools to use.
if [[ -z $PYTHON_EXECUTABLE ]];
then
if [[ -z $CONDA_DEFAULT_ENV ]] || [[ $CONDA_DEFAULT_ENV == "base" ]] || [[ ! -x "$(command -v python)" ]];
then
PYTHON_EXECUTABLE=python3
else
PYTHON_EXECUTABLE=python
fi
fi

SCRIPT="$1"; shift
$PYTHON_EXECUTABLE $SCRIPT "$@"

# Exit with the same status as the python script.
exit $?

0 comments on commit cd0e584

Please sign in to comment.