areusch commented on a change in pull request #9752:
URL: https://github.com/apache/tvm/pull/9752#discussion_r777739215
##########
File path: tests/scripts/ci.py
##########
@@ -110,17 +172,50 @@ def docs(
full -- Build all language docs, not just Python
precheck -- Run Sphinx precheck script
tutorial-pattern -- Regex for which tutorials to execute when building
docs (can also be set via TVM_TUTORIAL_EXEC_PATTERN)
- cpu -- Use CMake defaults for building TVM (useful for building docs on a
CPU machine.)
+ cpu -- Run with the ci-cpu image and use CMake defaults for building TVM
(if no GPUs are available)
"""
config = "./tests/scripts/task_config_build_gpu.sh"
if cpu and full:
clean_exit("--full cannot be used with --cpu")
+ extra_setup = []
+ image = "ci_gpu"
if cpu:
+ image = "ci_cpu"
# The docs import tvm.micro, so it has to be enabled in the build
- config = "cd build && cp ../cmake/config.cmake . && echo
set\(USE_MICRO ON\) >> config.cmake && cd .."
+ config = " && ".join(
Review comment:
nit: move the comment above the relevant line
##########
File path: tests/scripts/ci.py
##########
@@ -24,12 +24,15 @@
import getpass
import inspect
import argparse
+import json
+import shutil
import grp
import subprocess
from pathlib import Path
from typing import List, Dict, Any, Optional
REPO_ROOT = Path(__file__).resolve().parent.parent.parent
+SCRIPT_DIR = REPO_ROOT / ".cipy-scripts"
Review comment:
what happens if someone runs this command concurrently? should we name
like `.ci-py-scripts/<pid>`?
##########
File path: tests/scripts/ci.py
##########
@@ -221,6 +317,10 @@ def main():
add_subparser(func, subparsers)
args = parser.parse_args()
+ if args.command is None:
Review comment:
possible to use required=True?
##########
File path: tests/scripts/ci.py
##########
@@ -44,48 +47,107 @@ class col:
UNDERLINE = "\033[4m"
-def print_color(color: str, msg: str, **kwargs: Any) -> None:
+def print_color(color: str, msg: str, bold: bool, **kwargs: Any) -> None:
if hasattr(sys.stdout, "isatty") and sys.stdout.isatty():
- print(col.BOLD + color + msg + col.RESET, **kwargs)
+ bold_code = col.BOLD if bold else ""
+ print(bold_code + color + msg + col.RESET, **kwargs)
else:
print(msg, **kwargs)
+warnings = []
+
+
def clean_exit(msg: str) -> None:
- print_color(col.RED, msg, file=sys.stderr)
+ print_color(col.RED, msg, bold=True, file=sys.stderr)
+
+ for warning in warnings:
+ print_color(col.YELLOW, warning, bold=False, file=sys.stderr)
+
exit(1)
def cmd(commands: List[Any], **kwargs: Any):
commands = [str(s) for s in commands]
command_str = " ".join(commands)
- print_color(col.BLUE, command_str)
+ print_color(col.BLUE, command_str, bold=True)
proc = subprocess.run(commands, **kwargs)
if proc.returncode != 0:
raise RuntimeError(f"Command failed: '{command_str}'")
+ return proc
-def docker(name: str, image: str, scripts: List[str], env: Dict[str, str]):
- """
- Invoke a set of bash scripts through docker/bash.sh
- """
+def check_docker():
+ executable = shutil.which("docker")
+ if executable is None:
+ clean_exit("'docker' executable not found, install it first (e.g. 'apt
install docker.io')")
+
if sys.platform == "linux":
# Check that the user is in the docker group before running
try:
group = grp.getgrnam("docker")
if getpass.getuser() not in group.gr_mem:
- print_color(
- col.YELLOW, f"Note: User '{getpass.getuser()}' is not in
the 'docker' group"
+ warnings.append(
+ f"Note: User '{getpass.getuser()}' is not in the 'docker'
group, either:\n"
+ " * run with 'sudo'\n"
+ " * add user to 'docker': sudo usermod -aG docker
$(whoami), then log out and back in",
)
- except KeyError:
- print_color(col.YELLOW, f"Note: 'docker' group does not exist")
+ except KeyError as e:
+ warnings.append(f"Note: 'docker' group does not exist")
+
+
+def check_gpu():
+ if sys.platform == "linux" and shutil.which("lshw"):
+ # See if we can check if a GPU is present in case of later failures,
+ # but don't block on execution since this isn't critical
+ try:
+ proc = cmd(
+ ["lshw", "-json", "-C", "display"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ encoding="utf-8",
+ )
+ stdout = proc.stdout.strip().strip(",")
+ stdout = json.loads(stdout)
+ if isinstance(stdout, dict):
+ stdout = [stdout]
+ products = [s.get("product", "").lower() for s in stdout]
+ if not any("nvidia" in product for product in products):
+ warnings.append("nvidia GPU not found in 'lshw', maybe use
--cpu flag?")
+ except Exception as e:
Review comment:
want to catch something more specific, like `CalledProcessError`? this
is a good way for it to silently break
##########
File path: tests/scripts/ci.py
##########
@@ -44,48 +47,107 @@ class col:
UNDERLINE = "\033[4m"
-def print_color(color: str, msg: str, **kwargs: Any) -> None:
+def print_color(color: str, msg: str, bold: bool, **kwargs: Any) -> None:
if hasattr(sys.stdout, "isatty") and sys.stdout.isatty():
- print(col.BOLD + color + msg + col.RESET, **kwargs)
+ bold_code = col.BOLD if bold else ""
+ print(bold_code + color + msg + col.RESET, **kwargs)
else:
print(msg, **kwargs)
+warnings = []
+
+
def clean_exit(msg: str) -> None:
- print_color(col.RED, msg, file=sys.stderr)
+ print_color(col.RED, msg, bold=True, file=sys.stderr)
+
+ for warning in warnings:
+ print_color(col.YELLOW, warning, bold=False, file=sys.stderr)
+
exit(1)
def cmd(commands: List[Any], **kwargs: Any):
commands = [str(s) for s in commands]
command_str = " ".join(commands)
- print_color(col.BLUE, command_str)
+ print_color(col.BLUE, command_str, bold=True)
proc = subprocess.run(commands, **kwargs)
if proc.returncode != 0:
raise RuntimeError(f"Command failed: '{command_str}'")
+ return proc
-def docker(name: str, image: str, scripts: List[str], env: Dict[str, str]):
- """
- Invoke a set of bash scripts through docker/bash.sh
- """
+def check_docker():
+ executable = shutil.which("docker")
+ if executable is None:
+ clean_exit("'docker' executable not found, install it first (e.g. 'apt
install docker.io')")
+
if sys.platform == "linux":
# Check that the user is in the docker group before running
try:
group = grp.getgrnam("docker")
if getpass.getuser() not in group.gr_mem:
- print_color(
- col.YELLOW, f"Note: User '{getpass.getuser()}' is not in
the 'docker' group"
+ warnings.append(
+ f"Note: User '{getpass.getuser()}' is not in the 'docker'
group, either:\n"
+ " * run with 'sudo'\n"
+ " * add user to 'docker': sudo usermod -aG docker
$(whoami), then log out and back in",
)
- except KeyError:
- print_color(col.YELLOW, f"Note: 'docker' group does not exist")
+ except KeyError as e:
+ warnings.append(f"Note: 'docker' group does not exist")
+
+
+def check_gpu():
+ if sys.platform == "linux" and shutil.which("lshw"):
Review comment:
```suggestion
if not (sys.platform == "linux" and shutil.which("lshw")):
return
```
##########
File path: tests/scripts/ci.py
##########
@@ -24,12 +24,15 @@
import getpass
import inspect
import argparse
+import json
+import shutil
import grp
import subprocess
from pathlib import Path
from typing import List, Dict, Any, Optional
REPO_ROOT = Path(__file__).resolve().parent.parent.parent
+SCRIPT_DIR = REPO_ROOT / ".cipy-scripts"
Review comment:
should we call it `ci-py-scripts` or something, so that it doesn't look
like a `cpy` typo?
##########
File path: tests/scripts/ci.py
##########
@@ -44,48 +47,107 @@ class col:
UNDERLINE = "\033[4m"
-def print_color(color: str, msg: str, **kwargs: Any) -> None:
+def print_color(color: str, msg: str, bold: bool, **kwargs: Any) -> None:
if hasattr(sys.stdout, "isatty") and sys.stdout.isatty():
- print(col.BOLD + color + msg + col.RESET, **kwargs)
+ bold_code = col.BOLD if bold else ""
+ print(bold_code + color + msg + col.RESET, **kwargs)
else:
print(msg, **kwargs)
+warnings = []
+
+
def clean_exit(msg: str) -> None:
- print_color(col.RED, msg, file=sys.stderr)
+ print_color(col.RED, msg, bold=True, file=sys.stderr)
+
+ for warning in warnings:
+ print_color(col.YELLOW, warning, bold=False, file=sys.stderr)
+
exit(1)
def cmd(commands: List[Any], **kwargs: Any):
commands = [str(s) for s in commands]
command_str = " ".join(commands)
- print_color(col.BLUE, command_str)
+ print_color(col.BLUE, command_str, bold=True)
proc = subprocess.run(commands, **kwargs)
if proc.returncode != 0:
raise RuntimeError(f"Command failed: '{command_str}'")
+ return proc
-def docker(name: str, image: str, scripts: List[str], env: Dict[str, str]):
- """
- Invoke a set of bash scripts through docker/bash.sh
- """
+def check_docker():
+ executable = shutil.which("docker")
+ if executable is None:
+ clean_exit("'docker' executable not found, install it first (e.g. 'apt
install docker.io')")
+
if sys.platform == "linux":
# Check that the user is in the docker group before running
try:
group = grp.getgrnam("docker")
if getpass.getuser() not in group.gr_mem:
- print_color(
- col.YELLOW, f"Note: User '{getpass.getuser()}' is not in
the 'docker' group"
+ warnings.append(
+ f"Note: User '{getpass.getuser()}' is not in the 'docker'
group, either:\n"
+ " * run with 'sudo'\n"
+ " * add user to 'docker': sudo usermod -aG docker
$(whoami), then log out and back in",
)
- except KeyError:
- print_color(col.YELLOW, f"Note: 'docker' group does not exist")
+ except KeyError as e:
+ warnings.append(f"Note: 'docker' group does not exist")
+
+
+def check_gpu():
+ if sys.platform == "linux" and shutil.which("lshw"):
+ # See if we can check if a GPU is present in case of later failures,
+ # but don't block on execution since this isn't critical
+ try:
+ proc = cmd(
+ ["lshw", "-json", "-C", "display"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ encoding="utf-8",
+ )
+ stdout = proc.stdout.strip().strip(",")
+ stdout = json.loads(stdout)
+ if isinstance(stdout, dict):
Review comment:
how come you need this line?
##########
File path: tests/scripts/ci.py
##########
@@ -44,48 +47,107 @@ class col:
UNDERLINE = "\033[4m"
-def print_color(color: str, msg: str, **kwargs: Any) -> None:
+def print_color(color: str, msg: str, bold: bool, **kwargs: Any) -> None:
if hasattr(sys.stdout, "isatty") and sys.stdout.isatty():
- print(col.BOLD + color + msg + col.RESET, **kwargs)
+ bold_code = col.BOLD if bold else ""
+ print(bold_code + color + msg + col.RESET, **kwargs)
else:
print(msg, **kwargs)
+warnings = []
+
+
def clean_exit(msg: str) -> None:
- print_color(col.RED, msg, file=sys.stderr)
+ print_color(col.RED, msg, bold=True, file=sys.stderr)
+
+ for warning in warnings:
+ print_color(col.YELLOW, warning, bold=False, file=sys.stderr)
+
exit(1)
def cmd(commands: List[Any], **kwargs: Any):
commands = [str(s) for s in commands]
command_str = " ".join(commands)
- print_color(col.BLUE, command_str)
+ print_color(col.BLUE, command_str, bold=True)
proc = subprocess.run(commands, **kwargs)
if proc.returncode != 0:
raise RuntimeError(f"Command failed: '{command_str}'")
+ return proc
-def docker(name: str, image: str, scripts: List[str], env: Dict[str, str]):
- """
- Invoke a set of bash scripts through docker/bash.sh
- """
+def check_docker():
+ executable = shutil.which("docker")
+ if executable is None:
+ clean_exit("'docker' executable not found, install it first (e.g. 'apt
install docker.io')")
+
if sys.platform == "linux":
# Check that the user is in the docker group before running
try:
group = grp.getgrnam("docker")
if getpass.getuser() not in group.gr_mem:
- print_color(
- col.YELLOW, f"Note: User '{getpass.getuser()}' is not in
the 'docker' group"
+ warnings.append(
+ f"Note: User '{getpass.getuser()}' is not in the 'docker'
group, either:\n"
+ " * run with 'sudo'\n"
+ " * add user to 'docker': sudo usermod -aG docker
$(whoami), then log out and back in",
)
- except KeyError:
- print_color(col.YELLOW, f"Note: 'docker' group does not exist")
+ except KeyError as e:
+ warnings.append(f"Note: 'docker' group does not exist")
+
+
+def check_gpu():
+ if sys.platform == "linux" and shutil.which("lshw"):
+ # See if we can check if a GPU is present in case of later failures,
+ # but don't block on execution since this isn't critical
+ try:
+ proc = cmd(
+ ["lshw", "-json", "-C", "display"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ encoding="utf-8",
+ )
+ stdout = proc.stdout.strip().strip(",")
+ stdout = json.loads(stdout)
+ if isinstance(stdout, dict):
+ stdout = [stdout]
+ products = [s.get("product", "").lower() for s in stdout]
+ if not any("nvidia" in product for product in products):
+ warnings.append("nvidia GPU not found in 'lshw', maybe use
--cpu flag?")
+ except Exception as e:
+ # Do nothing if any step failed
+ pass
+
+
+def check_build():
+ if (REPO_ROOT / "build").exists():
+ warnings.append(
+ "Existing build dir found may be interfering with the Docker "
+ "build (you may need to remove it)"
+ )
+
+
+def docker(name: str, image: str, scripts: List[str], env: Dict[str, str]):
+ """
+ Invoke a set of bash scripts through docker/bash.sh
Review comment:
could you add param docstrings?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]