Skip to content

cuda: use target-specific paths under CUDA Toolkit on Linux #14612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions .github/workflows/images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ jobs:
fail-fast: false
matrix:
cfg:
- { name: Arch Linux, id: arch }
- { name: CUDA (on Arch), id: cuda }
- { name: Fedora, id: fedora }
- { name: Gentoo, id: gentoo }
- { name: OpenSUSE, id: opensuse }
- { name: Ubuntu Bionic, id: bionic }
- { name: Ubuntu Rolling, id: ubuntu-rolling }
- { name: Arch Linux, id: arch }
- { name: CUDA (on Arch), id: cuda }
- { name: CUDA Cross (on Ubuntu Jammy), id: cuda-cross }
- { name: Fedora, id: fedora }
- { name: Gentoo, id: gentoo }
- { name: OpenSUSE, id: opensuse }
- { name: Ubuntu Bionic, id: bionic }
- { name: Ubuntu Rolling, id: ubuntu-rolling }
steps:
# Need v3 because of bionic
- uses: actions/checkout@v3
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/nonnative.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,12 @@ jobs:
name: "Ubuntu nonnative"
fail_ci_if_error: false
verbose: true

cross-cuda:
runs-on: ubuntu-latest
container: mesonbuild/cuda-cross:latest
env:
MESON_CI_JOBNAME: cuda-cross-${{ github.job }}
steps:
- name: Run tests
run: bash -c 'source /ci/env_vars.sh; cd $GITHUB_WORKSPACE; ./run_tests.py $CI_ARGS --cross cuda-cross.json --cross-only'
8 changes: 8 additions & 0 deletions ci/ciimage/cuda-cross/image.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"base_image": "ubuntu:22.04",
"args": ["--only", "cuda", "--cross", "cuda-cross.json"],
"env": {
"CI": "1",
"MESON_CI_JOBNAME": "linux-cuda-cross"
}
}
38 changes: 38 additions & 0 deletions ci/ciimage/cuda-cross/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash

set -e

source /ci/common.sh

export DEBIAN_FRONTEND=noninteractive
export LANG='C.UTF-8'

apt-get -y update
apt-get -y upgrade
apt-get -y install wget

# Cuda repo + keyring.
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
apt-get -y install ./cuda-keyring_1.1-1_all.deb

# Cuda cross repo.
echo "deb [signed-by=/usr/share/keyrings/cuda-archive-keyring.gpg] https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/cross-linux-aarch64/ /" \
> /etc/apt/sources.list.d/cuda-ubuntu2204-cross-linux-aarch64.list
apt-get -y update

pkgs=(
clang cmake crossbuild-essential-arm64 cuda-cross-aarch64
cuda-nvcc-12-9 git libglib2.0-dev ninja-build pkg-config python3-pip
)

apt-get -y install "${pkgs[@]}"

install_minimal_python_packages

# Tests need nvcc in PATH in order to run cuda tests.
echo "export PATH=\$PATH:/usr/local/cuda/bin" >> /ci/env_vars.sh

# cleanup
apt-get -y clean
apt-get -y autoclean
rm cuda-keyring_1.1-1_all.deb
5 changes: 5 additions & 0 deletions cross/cuda-cross.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"file": "cuda-cross.txt",
"tests": ["cuda"],
"env": {}
}
17 changes: 17 additions & 0 deletions cross/cuda-cross.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[binaries]
c = ['/usr/bin/aarch64-linux-gnu-gcc']
cpp = ['/usr/bin/aarch64-linux-gnu-g++']
cuda = ['/usr/local/cuda/bin/nvcc']
ar = '/usr/bin/aarch64-linux-gnu-ar'
strip = '/usr/bin/aarch64-linux-gnu-strip'
ld = '/usr/bin/aarch64-linux-gnu-ld'

[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'

[built-in options]
cuda_link_args = ['-lstdc++']
cuda_ccbindir = '/usr/bin/aarch64-linux-gnu-gcc'
24 changes: 15 additions & 9 deletions mesonbuild/dependencies/cuda.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

from .. import mesonlib
from .. import mlog
from ..environment import detect_cpu_family
from .base import DependencyException, SystemDependency
from .detect import packages
from ..mesonlib import LibType
Expand All @@ -28,8 +27,11 @@ class CudaDependency(SystemDependency):
supported_languages = ['cpp', 'c', 'cuda'] # see also _default_language

def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
compilers = environment.coredata.compilers[self.get_for_machine_from_kwargs(kwargs)]
for_machine = self.get_for_machine_from_kwargs(kwargs)
compilers = environment.coredata.compilers[for_machine]
machine = environment.machines[for_machine]
language = self._detect_language(compilers)

if language not in self.supported_languages:
raise DependencyException(f'Language \'{language}\' is not supported by the CUDA Toolkit. Supported languages are {self.supported_languages}.')

Expand All @@ -51,14 +53,21 @@ def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> No
if not os.path.isabs(self.cuda_path):
raise DependencyException(f'CUDA Toolkit path must be absolute, got \'{self.cuda_path}\'.')

# Cuda target directory relative to cuda path.
if machine.is_linux():
# E.g. targets/x86_64-linux
self.target_path = os.path.join('targets', f'{machine.cpu_family}-{machine.system}')
else:
self.target_path = '.'

# nvcc already knows where to find the CUDA Toolkit, but if we're compiling
# a mixed C/C++/CUDA project, we still need to make the include dir searchable
if self.language != 'cuda' or len(compilers) > 1:
self.incdir = os.path.join(self.cuda_path, 'include')
self.incdir = os.path.join(self.cuda_path, self.target_path, 'include')
self.compile_args += [f'-I{self.incdir}']

arch_libdir = self._detect_arch_libdir()
self.libdir = os.path.join(self.cuda_path, arch_libdir)
self.libdir = os.path.join(self.cuda_path, self.target_path, arch_libdir)
mlog.debug('CUDA library directory is', mlog.bold(self.libdir))

if 'static' not in kwargs:
Expand Down Expand Up @@ -215,19 +224,16 @@ def _strip_patch_version(cls, version: str) -> str:
return '.'.join(version.split('.')[:2])

def _detect_arch_libdir(self) -> str:
arch = detect_cpu_family(self.env.coredata.compilers.host)
machine = self.env.machines[self.for_machine]
arch = machine.cpu_family
msg = '{} architecture is not supported in {} version of the CUDA Toolkit.'
if machine.is_windows():
libdirs = {'x86': 'Win32', 'x86_64': 'x64'}
if arch not in libdirs:
raise DependencyException(msg.format(arch, 'Windows'))
return os.path.join('lib', libdirs[arch])
elif machine.is_linux():
libdirs = {'x86_64': 'lib64', 'ppc64': 'lib', 'aarch64': 'lib64', 'loongarch64': 'lib64'}
if arch not in libdirs:
raise DependencyException(msg.format(arch, 'Linux'))
return libdirs[arch]
return 'lib'
elif machine.is_darwin():
libdirs = {'x86_64': 'lib64'}
if arch not in libdirs:
Expand Down
Loading