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_valuesproperty and are the numeric character equivalent of the compute capability version (e.g., ‘10’ for version 1.0). Each provided value affects associatedCUDAdependencies 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_archvalue(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.