Cuda
Different from other packages, CudaPackage
does not represent a build system.
Instead its goal is to simplify and unify usage of CUDA
in other packages by providing a mixin-class.
You can find source for the package at https://github.com/spack/spack/blob/develop/lib/spack/spack/build_systems/cuda.py.
Variants
This package provides the following variants:
cuda
This variant is used to enable/disable building with
CUDA
. The default is disabled (orFalse
).cuda_arch
This variant supports the optional specification of one or multiple architectures. Valid values are maintained in the
cuda_arch_values
property and are the numeric character equivalent of the compute capability version (e.g., ‘10’ for version 1.0). Each provided value affects associatedCUDA
dependencies and compiler conflicts.The variant builds both PTX code for the _virtual_ architecture (e.g.
compute_10
) and binary code for the _real_ architecture (e.g.sm_10
).GPUs and their compute capability versions are listed at https://developer.nvidia.com/cuda-gpus .
Conflicts
Conflicts are used to prevent builds with known bugs or issues. While
base CUDA
conflicts have been included with this package, you may
want to add more for your software.
For example, if your package requires cuda_arch
to be specified when
cuda
is enabled, you can add the following conflict to your package
to terminate such build attempts with a suitable message:
conflicts("cuda_arch=none", when="+cuda",
msg="CUDA architecture is required")
Similarly, if your software does not support all versions of the property,
you could add conflicts
to your package for those versions. For example,
suppose your software does not work with CUDA compute capability versions
prior to SM 5.0 (50
). You can add the following code to display a
custom message should a user attempt such a build:
unsupported_cuda_archs = [
"10", "11", "12", "13",
"20", "21",
"30", "32", "35", "37"
]
for value in unsupported_cuda_archs:
conflicts(f"cuda_arch={value}", when="+cuda",
msg=f"CUDA architecture {value} is not supported")
Methods
This package provides one custom helper method, which is used to build standard CUDA compiler flags.
cuda_flags
This built-in static method returns a list of command line flags for the chosen
cuda_arch
value(s). The flags are intended to be passed to the CUDA compiler driver (i.e.,nvcc
).This method must be explicitly called when you are creating the arguments for your build in order to use the values.
Usage
This helper package can be added to your package by adding it as a base class of your package. For example, you can add it to your CMakePackage-based package as follows:
class MyCudaPackage(CMakePackage, CudaPackage):
...
def cmake_args(self):
spec = self.spec
args = []
...
if spec.satisfies("+cuda"):
# Set up the cuda macros needed by the build
args.append("-DWITH_CUDA=ON")
cuda_arch_list = spec.variants["cuda_arch"].value
cuda_arch = cuda_arch_list[0]
if cuda_arch != "none":
args.append(f"-DCUDA_FLAGS=-arch=sm_{cuda_arch}")
else:
# Ensure build with cuda is disabled
args.append("-DWITH_CUDA=OFF")
...
return args
assuming only the WITH_CUDA
and CUDA_FLAGS
flags are required.
You will need to customize options as needed for your build.
This example also illustrates how to check for the cuda
variant using
self.spec
and how to retrieve the cuda_arch
variant’s value, which
is a list, using self.spec.variants["cuda_arch"].value
.
With over 70 packages using CudaPackage
as of January 2021 there are
lots of examples to choose from to get more ideas for using this package.