|
25 | 25 | class CudaDependency(SystemDependency):
|
26 | 26 |
|
27 | 27 | supported_languages = ['cpp', 'c', 'cuda'] # see also _default_language
|
| 28 | + targets_dir = 'targets' # Directory containing CUDA targets. |
28 | 29 |
|
29 | 30 | def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
|
30 | 31 | for_machine = self.get_for_machine_from_kwargs(kwargs)
|
@@ -54,11 +55,7 @@ def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> No
|
54 | 55 | raise DependencyException(f'CUDA Toolkit path must be absolute, got \'{self.cuda_path}\'.')
|
55 | 56 |
|
56 | 57 | # Cuda target directory relative to cuda path.
|
57 |
| - if machine.is_linux(): |
58 |
| - # E.g. targets/x86_64-linux |
59 |
| - self.target_path = os.path.join('targets', f'{machine.cpu_family}-{machine.system}') |
60 |
| - else: |
61 |
| - self.target_path = '.' |
| 58 | + self.target_path = self._detect_target_path(machine) |
62 | 59 |
|
63 | 60 | # nvcc already knows where to find the CUDA Toolkit, but if we're compiling
|
64 | 61 | # a mixed C/C++/CUDA project, we still need to make the include dir searchable
|
@@ -141,6 +138,32 @@ def _find_matching_toolkit(self, paths: T.List[TV_ResultTuple], version_reqs: T.
|
141 | 138 | mlog.warning(nvcc_warning)
|
142 | 139 | return (None, None, False)
|
143 | 140 |
|
| 141 | + def _detect_target_path(self, machine) -> str: |
| 142 | + # Non-Linux hosts: nothing to detect. |
| 143 | + if not machine.is_linux(): |
| 144 | + return "." |
| 145 | + |
| 146 | + # Canonical target: "<arch>-<system>", e.g. "x86_64-linux". |
| 147 | + canonical_target = f"{machine.cpu_family}-{machine.system}" |
| 148 | + rel_path = os.path.join(self.targets_dir, canonical_target) |
| 149 | + abs_path = os.path.join(self.cuda_path, rel_path) |
| 150 | + |
| 151 | + # AArch64 may need the SBSA fallback. |
| 152 | + if machine.cpu_family == "aarch64" and not os.path.exists(abs_path): |
| 153 | + rel_path = os.path.join(self.targets_dir, f"sbsa-{machine.system}") |
| 154 | + abs_path = os.path.join(self.cuda_path, rel_path) |
| 155 | + mlog.debug( |
| 156 | + f'Canonical CUDA target "{self.targets_dir}/{canonical_target}" missing; ' |
| 157 | + f'falling back to "{rel_path}".' |
| 158 | + ) |
| 159 | + |
| 160 | + mlog.debug(f'CUDA target resolved to "{rel_path}".') |
| 161 | + |
| 162 | + if not os.path.exists(abs_path): |
| 163 | + mlog.error(f'CUDA target "{rel_path}" does not exist.') |
| 164 | + |
| 165 | + return rel_path |
| 166 | + |
144 | 167 | def _default_path_env_var(self) -> T.Optional[str]:
|
145 | 168 | env_vars = ['CUDA_PATH'] if self._is_windows() else ['CUDA_PATH', 'CUDA_HOME', 'CUDA_ROOT']
|
146 | 169 | env_vars = [var for var in env_vars if var in os.environ]
|
|
0 commit comments