summaryrefslogtreecommitdiff
path: root/lib/spack/docs/build_systems/cudapackage.rst
blob: 79c98dd52c94f1b3aff883f3925b20f951ec528b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
.. Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
   Spack Project Developers. See the top-level COPYRIGHT file for details.

   SPDX-License-Identifier: (Apache-2.0 OR MIT)

.. _cudapackage:

----
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 <https://en.wikipedia.org/wiki/Mixin>`_.

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 (or ``False``).

* **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 associated
  ``CUDA`` 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:

.. code-block:: python

    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:

.. code-block:: python

    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
:ref:`CMakePackage <cmakepackage>`-based package as follows:

.. code-block:: python
   :emphasize-lines: 1,7-16

    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.