Skip to content

Commit

Permalink
BUILD(cfg): Add build toolchain for CUDA variant
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeSWang committed Sep 10, 2024
1 parent c00b62f commit c504c77
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 43 deletions.
140 changes: 113 additions & 27 deletions .github/workflows/cd_cuda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ on:
type: boolean
default: false
required: false
run_build_bdist_cuda_xplat:
description: 'Run job build_bdist_cuda'
type: boolean
default: false
required: false
run_build_conda_cuda:
description: 'Run job build_conda_cuda'
type: boolean
Expand All @@ -39,7 +44,7 @@ concurrency:

jobs:
build_bdist_cuda:
name: Build bdist wheel
name: Build bdist wheel (CUDA)

strategy:
fail-fast: false
Expand Down Expand Up @@ -76,12 +81,6 @@ jobs:
package-dir: .
output-dir: dist/
config-file: pyproject.toml
env:
CIBW_ENVIRONMENT: >-
PY_CXX=nvcc
PY_OMP=1
PY_CUDA=1
PY_BUILD_PARALLEL='-j'

- name: Verify built distribution
run: python -m twine check --strict dist/*
Expand All @@ -98,8 +97,106 @@ jobs:
name: pypi_dist_${{ runner.os }}_${{ runner.arch }}_${{ github.ref_name }}_cuda
path: dist/*.whl

build_bdist_cuda_xplat:
name: Build bdist wheel (CUDA, cross-platform)

strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]

runs-on: ${{ matrix.os }}

timeout-minutes: 100

# Allow manual trigger from inputs.
if: >
github.event_name != 'workflow_dispatch' ||
github.event.inputs.run_build_bdist_cuda_xplat == 'true'
steps:
- name: Extract platform architecture
run: |
if [[ $(uname -m) == 'aarch64' ]]; then
echo "TARGET_ARCH=x86_64" >> "${GITHUB_ENV}"
elif [[ $(uname -m) == 'x86_64' ]]; then
echo "TARGET_ARCH=aarch64" >> "${GITHUB_ENV}"
fi
- name: Checkout (automatic trigger)
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Checkout (manual trigger)
if: >
github.event.inputs.run_build_bdist_cuda == 'true' &&
github.event.inputs.version_tag == ''
uses: actions/checkout@v4
with:
fetch-tags: true

- name: Checkout (manual trigger with tag)
if: >
github.event.inputs.run_build_bdist_cuda == 'true' &&
github.event.inputs.version_tag != ''
uses: actions/checkout@v4
with:
ref: refs/tags/${{ github.event.inputs.version_tag }}

# Use QEMU for non-native Linux runner.
- name: Set up QEMU (Linux)
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v3
with:
# Specify target architecture.
platforms: linux/${{ env.TARGET_ARCH }}

- name: Set up Python 3
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Install packaging requirements
run: python -m pip install --upgrade twine

- name: Copy Python project configuration file
run: cp .pyproject_cuda.toml pyproject.toml

- name: Build built distribution
uses: pypa/cibuildwheel@v2.20.0
with:
package-dir: .
output-dir: dist/
config-file: pyproject.toml
env:
# Specify target architecture, which is actually fixed to aarch64.
CIBW_ARCHS_LINUX: ${{ env.TARGET_ARCH }}
CIBW_MANYLINUX_AARCH64_IMAGE: quay.io/pypa/manylinux_2_24_aarch64
CIBW_BEFORE_ALL_LINUX: >
apt-get -y install libgsl-devel &&
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/cross-linux-aarch64/cuda-keyring_1.1-1_all.deb &&
dpkg -i cuda-keyring_1.1-1_all.deb &&
apt-get -y install cuda-cross-aarch64
- name: Verify built distribution
run: python -m twine check --strict dist/*

- name: Save wheel to bdist
uses: actions/upload-artifact@v4
with:
name: bdist_whl_${{ matrix.os }}_${{ env.TARGET_ARCH }}_${{ github.ref_name }}_cuda
path: dist/*.whl

- name: Save wheel to pypi_dist
uses: actions/upload-artifact@v4
with:
name: pypi_dist_${{ runner.os }}_${{ env.TARGET_ARCH }}_${{ github.ref_name }}_cuda
path: dist/*.whl

build_conda_cuda:
name: Build Conda package
name: Build Conda package (CUDA)

strategy:
fail-fast: false
Expand All @@ -112,7 +209,7 @@ jobs:

if: >
github.event_name != 'workflow_dispatch' ||
github.event.inputs.run_build_conda == 'true'
github.event.inputs.run_build_conda_cuda == 'true'
defaults:
run:
Expand All @@ -124,20 +221,13 @@ jobs:
with:
fetch-depth: 0

- uses: Jimver/cuda-toolkit@master
id: cuda-toolkit
with:
log-file-suffix: '${{matrix.os}}_cudatoolkit_log.txt'
method: 'network'
sub-packages: '["nvcc"]'
non-cuda-sub-packages: '["libcufft"]'

- name: Set up (Mini)conda
uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: conda_bld
channels: conda-forge
channels: conda-forge,nvidia
channel-priority: strict
architecture: ${{ env.TARGET_ARCH }}

- name: Install packaging requirements
run: |
Expand All @@ -149,17 +239,13 @@ jobs:
- name: Override version
if: github.event_name == 'workflow_dispatch'
uses: knicknic/os-specific-run@v1.0.4
env:
recipe_file: deploy/pkg/conda_recipe_cuda/meta.yaml
with:
linux: |
vers_tag=${{ github.event.inputs.version_tag }}
cuda_vers=${{ steps.cuda-toolkit.outputs.cuda }}
if [[ ! -z ${vers_tag} ]]; then
sed -i "s/# git_rev:.*/git_rev: ${vers_tag}/g" ${recipe_file}
sed -i "s/'CUDA_VERSION', ''/'CUDA_VERSION', '${cuda_vers}'/g" ${recipe_file}
fi
run: |
vers_tag=${{ github.event.inputs.version_tag }}
if [[ ! -z ${vers_tag} ]]; then
sed -i "s/# git_rev:.*/git_rev: ${vers_tag}/g" ${recipe_file}
fi
- name: Build Conda package
env:
Expand Down
10 changes: 9 additions & 1 deletion .pyproject_cuda.toml
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,16 @@ manylinux-aarch64-image = 'manylinux_2_28'

[tool.cibuildwheel.linux]
before-all = [
"yum install -y gsl-devel cuda-toolkit",
"yum install -y gsl-devel",
# Install CUDA Toolkit inside Docker container using package manager,
# matching repository with image OS, and optionally matching CUDA version
# for Pip/Conda consistency.
"yum install -y yum-utils",
"yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel9/x86_64/cuda-rhel9.repo",
"yum install -y cuda-toolkit",
# "yum install -y cuda-toolkit-12-6",
]
environment = { PY_CXX="/usr/local/cuda/bin/nvcc", PY_CXXFLAGS="-I/usr/local/cuda/include", PY_LDFLAGS="-L/usr/local/cuda/lib64", PY_OMP='1', PY_CUDA='1', PY_BUILD_PARALLEL='-j' }

[tool.autopep8]
in-place = true
Expand Down
3 changes: 3 additions & 0 deletions deploy/pkg/conda_recipe_cuda/conda_build_config.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
target_platform:
- linux-64 # [linux]
- linux-aarch64 # [linux]

cuda_version:
- 12.0
30 changes: 19 additions & 11 deletions deploy/pkg/conda_recipe_cuda/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{% set name = 'Triumvirate-CUDA' %}
{% set version = environ.get('GIT_DESCRIBE_TAG', 'v0.5.0') %}
{% set cuda_vers = environ.get('CUDA_VERSION', '') %}
# {% set cuda_vers = environ.get('CUDA_VERSION', '12.0') %}
# {% set cuda_vers_parts = cuda_vers.split('.') %}
# {% set cuda_vers_major_minor = cuda_vers_parts[0] ~ cuda_vers_parts[1] %}
# {% set cuda_vers_int = cuda_vers_major_minor|int %}
# {% set cuda_path = environ.get('CUDA_PATH', '/usr/local/cuda') %}

package:
name: "{{ name|lower }}"
Expand All @@ -13,22 +17,23 @@ source:

build:
number: 0
string: cuda{{ cuda_vers }}_py{{ CONDA_PY }}h{{ PKG_HASH }}_{{ PKG_BUILDNUM }}
string: cuda{{ cuda_version|replace(".", "") }}py{{ CONDA_PY }}h{{ PKG_HASH }}_{{ PKG_BUILDNUM }}
script:
# Use Conda-provided compiler.
- export PY_CXX=$CXX
- export PY_CXXFLAGS="${PY_CXXFLAGS} -D_LIBCPP_DISABLE_AVAILABILITY"
# Enforce OpenMP support.
- export PY_OMP=1
- export PY_CUDA=1
- cp .pyproject_cuda.toml pyproject.toml
- {{ PYTHON }} -m pip install . -vvv
script_env:
- PY_BUILD_PARALLEL="-j"
# Enforce OpenMP and CUDA support.
- PY_OMP=1
- PY_CUDA=1
- PY_BUILD_PARALLEL='-j'

requirements:
build:
- {{ compiler('cuda') }}
# Use Nvidia channel libraries.
- cuda-nvcc
- libcufft-dev
# Use conda-forge channel libraries.
- cuda-version {{ cuda_version }}
- python # [build_platform != target_platform]
- cross-python_{{ target_platform }} # [build_platform != target_platform]
- numpy >=2.0 # [build_platform != target_platform]
Expand All @@ -38,15 +43,18 @@ requirements:
host:
- python
- pip >=22.0
# Use Conda-provided libraries.
# Use conda-forge channel libraries.
- cuda-version {{ cuda_version }}
- gsl >=2.7
- libcufft
- libgomp # [linux]
- setuptools >=61.0
- setuptools_scm >=6.4
- cython >=3.0
- extension-helpers >=1.1
- numpy >=2.0
run:
- {{ pin_compatible('cuda-version', min_pin='x', max_pin='x.x') }}
- python >=3.10
- numpy >=1.23
- scipy >=1.13
Expand Down
19 changes: 15 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,21 @@ def get_pkg_version_scheme(default_ver_scheme='no-guess-dev',
# Build
# ========================================================================

NA_OPTS = ('-Wstrict-prototypes', '-Wl,-pie',) # noqa: E231
CUDA_XCOMPILER_OPTS = ('-f', '-O', '-W',) # noqa: E231
CUDA_XCOMPILER_OPTS_EXACT = ['-pthread', '-B',] # noqa: E231
CUDA_XCOMPILER_OPTS_PARTIAL = ['compiler_compat',] # noqa: E231
NA_OPTS = (
'-Wstrict-prototypes',
'-Wl,-pie',
)
CUDA_XCOMPILER_OPTS = (
'-f', '-O', '-W',
'-march', '-mtune', '-pipe',
)
CUDA_XCOMPILER_OPTS_EXACT = [
'-pthread',
'-B',
]
CUDA_XCOMPILER_OPTS_PARTIAL = [
'compiler_compat',
]


class BuildExt(build_ext):
Expand Down

0 comments on commit c504c77

Please sign in to comment.