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-packages/blob/develop/repos/spack_repo/builtin/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 more 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.