Skip to content

Commit

Permalink
[ci] arm64 wheels (ray-project#41056)
Browse files Browse the repository at this point in the history
Build arm64 wheels in civ2

Signed-off-by: can <can@anyscale.com>
  • Loading branch information
can-anyscale authored and ujjawal-khare committed Nov 29, 2023
1 parent 89f0640 commit ff16a00
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 38 deletions.
8 changes: 8 additions & 0 deletions .buildkite/_forge.rayci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@ steps:
- name: forge
wanda: ci/docker/forge.wanda.yaml

- name: forge-aarch64
wanda: ci/docker/forge.aarch64.wanda.yaml
instance_type: builder-arm64

- name: manylinux
wanda: ci/docker/manylinux.wanda.yaml

- name: manylinux-aarch64
wanda: ci/docker/manylinux.aarch64.wanda.yaml
instance_type: builder-arm64

- name: raycudabase
label: "wanda: ray.py{{matrix.python}}.cu{{matrix.cuda}}.base"
tags:
Expand Down
21 changes: 19 additions & 2 deletions .buildkite/build.rayci.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
group: build
steps:
- label: ":tapioca: build: wheel {{matrix}}"
- label: ":tapioca: build: wheel {{matrix}} (x86_64)"
tags:
- linux_wheels
- oss
instance_type: medium
commands:
- bazel run //ci/ray_ci:build_in_docker -- wheel --python-version {{matrix}}
- bazel run //ci/ray_ci:build_in_docker -- wheel --python-version {{matrix}} --architecture x86_64
matrix:
- "3.8"
- "3.9"
Expand All @@ -17,6 +17,23 @@ steps:
- forge
job_env: forge

- label: ":tapioca: build: wheel {{matrix}} (aarch64)"
tags:
- linux_wheels
- oss
instance_type: medium-arm64
commands:
- bazel run //ci/ray_ci:build_in_docker -- wheel --python-version {{matrix}} --architecture aarch64
matrix:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
depends_on:
- manylinux-aarch64
- forge-aarch64
job_env: forge-aarch64

- label: ":tapioca: build: debug wheel"
tags:
- linux_wheels
Expand Down
16 changes: 0 additions & 16 deletions .buildkite/pipeline.arm64.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
#ci:group=:mechanical_arm: :ferris_wheel: ARM64 wheels and containers

- label: ":mechanical_arm: :ferris_wheel: ARM64 Linux wheels"
conditions: ["RAY_CI_LINUX_WHEELS_AFFECTED"]
instance_size: arm64-medium
commands:
# Build the wheels
- UPLOAD_WHEELS_AS_ARTIFACTS=1 LINUX_WHEELS=1 ./ci/ci.sh build
# Upload the wheels
# We don't want to push on PRs, in fact, the copy_files will fail because unauthenticated.
- if [ "$BUILDKITE_PULL_REQUEST" != "false" ]; then exit 0; fi
- pip install -q docker aws_requests_auth boto3
- ./ci/env/env_info.sh
# Upload to branch directory.
- python .buildkite/copy_files.py --destination branch_wheels --path ./.whl
# Upload to latest directory.
- if [ "$BUILDKITE_BRANCH" == "master" ]; then python .buildkite/copy_files.py --destination wheels --path ./.whl; fi

- label: ":mechanical_arm: :ferris_wheel: ARM64 Post-wheels tests"
conditions: ["RAY_CI_LINUX_WHEELS_AFFECTED"]
instance_size: arm64-medium
Expand Down
6 changes: 6 additions & 0 deletions ci/docker/forge.aarch64.wanda.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: "forge-aarch64"
froms:
- ubuntu:20.04
build_args:
- BUILDKITE_BAZEL_CACHE_URL
dockerfile: ci/docker/forge.Dockerfile
3 changes: 2 additions & 1 deletion ci/docker/manylinux.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# syntax=docker/dockerfile:1.3-labs

FROM quay.io/pypa/manylinux2014_x86_64:2022-12-20-b4884d9
ARG HOSTTYPE
FROM quay.io/pypa/manylinux2014_${HOSTTYPE}:2022-12-20-b4884d9

ARG BUILDKITE_BAZEL_CACHE_URL

Expand Down
9 changes: 9 additions & 0 deletions ci/docker/manylinux.aarch64.wanda.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: "manylinux-aarch64"
froms:
- quay.io/pypa/manylinux2014_aarch64:2022-12-20-b4884d9
srcs:
- ci/build/build-manylinux-forge.sh
build_args:
- BUILDKITE_BAZEL_CACHE_URL
- HOSTTYPE=aarch64
dockerfile: ci/docker/manylinux.Dockerfile
1 change: 1 addition & 0 deletions ci/docker/manylinux.wanda.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ srcs:
- ci/build/build-manylinux-forge.sh
build_args:
- BUILDKITE_BAZEL_CACHE_URL
- HOSTTYPE=x86_64
dockerfile: ci/docker/manylinux.Dockerfile
8 changes: 7 additions & 1 deletion ci/pipeline/determine_tests_to_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ def get_commit_range():
break
elif (
changed_file == ".buildkite/core.rayci.yml"
or changed_file == ".buildkite/_forge.rayci.yml"
or changed_file == "ci/docker/min.build.Dockerfile"
or changed_file == "ci/docker/min.build.wanda.yaml"
or changed_file == ".buildkite/serverless.rayci.yml"
Expand Down Expand Up @@ -310,6 +309,9 @@ def get_commit_range():
elif (
changed_file.startswith("ci/pipeline")
or changed_file.startswith("ci/ray_ci")
or changed_file == ".buildkite/_forge.rayci.yml"
or changed_file == "ci/docker/forge.wanda.yaml"
or changed_file == "ci/docker/forge.aarch64.wanda.yaml"
or changed_file == ".buildkite/pipeline.build.yml"
or changed_file == ".buildkite/pipeline.ml.yml"
):
Expand All @@ -318,6 +320,10 @@ def get_commit_range():
elif (
changed_file.endswith("build-docker-images.py")
or changed_file == ".buildkite/build.rayci.yml"
or changed_file == ".buildkite/pipeline.arm64.yml"
or changed_file == "ci/docker/manylinux.Dockerfile"
or changed_file == "ci/docker/manylinux.wanda.yaml"
or changed_file == "ci/docker/manylinux.aarch64.wanda.yaml"
):
RAY_CI_DOCKER_AFFECTED = 1
RAY_CI_LINUX_WHEELS_AFFECTED = 1
Expand Down
42 changes: 31 additions & 11 deletions ci/ray_ci/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

import click

from ci.ray_ci.builder_container import PYTHON_VERSIONS, BUILD_TYPES, BuilderContainer
from ci.ray_ci.builder_container import (
PYTHON_VERSIONS,
BUILD_TYPES,
ARCHITECTURE,
BuilderContainer,
)
from ci.ray_ci.doc_builder_container import DocBuilderContainer
from ci.ray_ci.forge_container import ForgeContainer
from ci.ray_ci.docker_container import PLATFORM
Expand Down Expand Up @@ -40,32 +45,39 @@
type=click.Choice(list(PLATFORM)),
help=("Platform to build the docker with"),
)
@click.option(
"--architecture",
default="x86_64",
type=click.Choice(list(ARCHITECTURE)),
help=("Platform to build the docker with"),
)
def main(
artifact_type: str,
image_type: str,
build_type: str,
python_version: str,
platform: List[str],
architecture: str,
) -> None:
"""
Build a wheel or jar artifact
"""
docker_login(_DOCKER_ECR_REPO.split("/")[0])
if artifact_type == "wheel":
logger.info(f"Building wheel for {python_version}")
build_wheel(python_version, build_type)
build_wheel(python_version, build_type, architecture)
return

if artifact_type == "docker":
logger.info(f"Building {image_type} docker for {python_version} on {platform}")
build_docker(image_type, python_version, build_type, platform)
build_docker(image_type, python_version, build_type, platform, architecture)
return

if artifact_type == "anyscale":
logger.info(
f"Building {image_type} anyscale for {python_version} on {platform}"
)
build_anyscale(image_type, python_version, build_type, platform)
build_anyscale(image_type, python_version, build_type, platform, architecture)
return

if artifact_type == "doc":
Expand All @@ -76,32 +88,40 @@ def main(
raise ValueError(f"Invalid artifact type {artifact_type}")


def build_wheel(python_version: str, build_type: str) -> None:
def build_wheel(python_version: str, build_type: str, architecture: str) -> None:
"""
Build a wheel artifact.
"""
BuilderContainer(python_version, build_type).run()
ForgeContainer().upload_wheel()
BuilderContainer(python_version, build_type, architecture).run()
ForgeContainer(architecture).upload_wheel()


def build_docker(
image_type: str, python_version: str, build_type: str, platform: List[str]
image_type: str,
python_version: str,
build_type: str,
platform: List[str],
architecture: str,
) -> None:
"""
Build a container artifact.
"""
BuilderContainer(python_version, build_type).run()
BuilderContainer(python_version, build_type, architecture).run()
for p in platform:
RayDockerContainer(python_version, p, image_type).run()


def build_anyscale(
image_type: str, python_version: str, build_type: str, platform: List[str]
image_type: str,
python_version: str,
build_type: str,
platform: List[str],
architecture: str,
) -> None:
"""
Build an anyscale container artifact.
"""
BuilderContainer(python_version, build_type).run()
BuilderContainer(python_version, build_type, architecture).run()
for p in platform:
RayDockerContainer(python_version, p, image_type).run()
AnyscaleDockerContainer(python_version, p, image_type).run()
Expand Down
9 changes: 7 additions & 2 deletions ci/ray_ci/builder_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class PythonVersionInfo(TypedDict):
"optimized",
"debug",
]
ARCHITECTURE = [
"x86_64",
"aarch64",
]
PYTHON_VERSIONS = {
"3.8": PythonVersionInfo(bin_path="cp38-cp38", numpy_version="1.19.3"),
"3.9": PythonVersionInfo(bin_path="cp39-cp39", numpy_version="1.19.3"),
Expand All @@ -21,12 +25,13 @@ class PythonVersionInfo(TypedDict):
}
DEFAULT_PYTHON_VERSION = "3.8"
DEFAULT_BUILD_TYPE = "optimized"
DEFAULT_ARCHITECTURE = "x86_64"


class BuilderContainer(Container):
def __init__(self, python_version: str, build_type: str) -> None:
def __init__(self, python_version: str, build_type: str, architecture: str) -> None:
super().__init__(
"manylinux",
"manylinux" if architecture == "x86_64" else f"manylinux-{architecture}",
volumes=[f"{os.environ.get('RAYCI_CHECKOUT_DIR')}:/rayci"],
)
python_version_info = PYTHON_VERSIONS.get(python_version)
Expand Down
4 changes: 2 additions & 2 deletions ci/ray_ci/forge_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@


class ForgeContainer(Container):
def __init__(self) -> None:
def __init__(self, architecture: str) -> None:
super().__init__(
"forge",
"forge" if architecture == "x86_64" else "forge-aarch64",
volumes=[f"{os.environ.get('RAYCI_CHECKOUT_DIR')}:/rayci"],
)

Expand Down
11 changes: 9 additions & 2 deletions ci/ray_ci/test_builder_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
from ci.ray_ci.builder_container import BuilderContainer


def test_init() -> None:
builder = BuilderContainer("3.10", "optimized", "aarch64")
assert builder.docker_tag == "manylinux-aarch64"
builder = BuilderContainer("3.10", "optimized", "x86_64")
assert builder.docker_tag == "manylinux"


def test_run() -> None:
cmds = []

Expand All @@ -17,15 +24,15 @@ def _mock_run_script(input: List[str]) -> None:
side_effect=_mock_run_script,
):
# test optimized build
BuilderContainer("3.10", "optimized").run()
BuilderContainer("3.10", "optimized", "x86_64").run()
assert cmds[-1] == [
"./ci/build/build-manylinux-ray.sh",
"./ci/build/build-manylinux-wheel.sh cp310-cp310 1.22.0",
"chown -R 2000:100 /artifact-mount",
]

# test debug build
BuilderContainer("3.9", "debug").run()
BuilderContainer("3.9", "debug", "x86_64").run()
assert cmds[-1] == [
"export RAY_DEBUG_BUILD=debug",
"./ci/build/build-manylinux-ray.sh",
Expand Down
5 changes: 4 additions & 1 deletion ci/ray_ci/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
BuilderContainer,
DEFAULT_BUILD_TYPE,
DEFAULT_PYTHON_VERSION,
DEFAULT_ARCHITECTURE,
)
from ci.ray_ci.tester_container import TesterContainer
from ci.ray_ci.utils import docker_login
Expand Down Expand Up @@ -156,7 +157,9 @@ def main(

if build_type == "wheel":
# for wheel testing, we first build the wheel and then use it for running tests
BuilderContainer(DEFAULT_PYTHON_VERSION, DEFAULT_BUILD_TYPE).run()
BuilderContainer(
DEFAULT_PYTHON_VERSION, DEFAULT_BUILD_TYPE, DEFAULT_ARCHITECTURE
).run()
container = _get_container(
team,
workers,
Expand Down

0 comments on commit ff16a00

Please sign in to comment.