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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
# Using Thrust with CMake
Thrust provides configuration files that simplify using Thrust
from other CMake projects. Requirements:
- Thrust >= 1.9.10
- CMake >= 3.15
See the [Fixing Legacy FindThrust.cmake](#fixing-legacy-findthrustcmake)
section for solutions that work on older Thrust versions.
## User Guide
#### Default Configuration (CUDA)
Thrust is configured using a `thrust_create_target` CMake function that
assembles a complete interface to the Thrust library:
```cmake
find_package(Thrust REQUIRED CONFIG)
thrust_create_target(Thrust)
target_link_libraries(MyProgram Thrust)
```
The first argument is the name of the interface target to create, and any
additional options will be used to configure the target. By default,
`thrust_create_target` will configure its result to use CUDA acceleration.
If desired, `thrust_create_target` may be called multiple times to build
several unique Thrust interface targets with different configurations, as
detailed below.
**Note:** If CMake is unable to locate Thrust, specify the path to Thrust's CMake
configuration directory (where this README file is located) as `Thrust_DIR`.
If cloning Thrust from github, this would be
```
$ cmake . -DThrust_DIR=<thrust git repo root>/thrust/cmake/
```
#### TBB / OpenMP
To explicitly specify host/device systems, `HOST` and `DEVICE` arguments can be
passed to `thrust_create_target`. If an explicit system is not specified, the
target will default to using CPP for host and/or CUDA for device.
```cmake
thrust_create_target(ThrustTBB DEVICE TBB)
thrust_create_target(ThrustOMP HOST CPP DEVICE OMP)
```
will create targets `ThrustTBB` and `ThrustOMP`. Both will use the serial `CPP`
host system, but will find and use TBB or OpenMP for the device system.
#### Configure Target from Cache Options
To allow a Thrust target to be configurable easily via `cmake-gui` or
`ccmake`, pass the `FROM_OPTIONS` flag to `thrust_create_target`. This will add
`THRUST_HOST_SYSTEM` and `THRUST_DEVICE_SYSTEM` options to the CMake cache that
allow selection from the systems supported by this version of Thrust.
```cmake
thrust_create_target(Thrust FROM_OPTIONS
[HOST_OPTION <option name>]
[DEVICE_OPTION <option name>]
[HOST_OPTION_DOC <doc string>]
[DEVICE_OPTION_DOC <doc string>]
[HOST <default host system name>]
[DEVICE <default device system name>]
[ADVANCED]
)
```
The optional arguments have sensible defaults, but may be configured per
`thrust_create_target` call:
| Argument | Default | Description |
|---------------------|-------------------------|---------------------------------|
| `HOST_OPTION` | `THRUST_HOST_SYSTEM` | Name of cache option for host |
| `DEVICE_OPTION` | `THRUST_DEVICE_SYSTEM` | Name of cache option for device |
| `HOST_OPTION_DOC` | Thrust's host system. | Docstring for host option |
| `DEVICE_OPTION_DOC` | Thrust's device system. | Docstring for device option |
| `HOST` | `CPP` | Default host system |
| `DEVICE` | `CUDA` | Default device system |
| `ADVANCED` | *N/A* | Mark cache options advanced |
### Specifying Thrust Version Requirements
A specific version of Thrust may be required in the `find_package` call:
```cmake
find_package(Thrust 1.9.10)
```
will only consider Thrust installations with version `1.9.10.X`. An exact match
down to the patch version can be forced by using `EXACT` matching:
```cmake
find_package(Thrust 1.9.10.1 EXACT)
```
would only match the 1.9.10.1 release.
#### Using an Explicit TBB or OpenMP CMake Target
When `thrust_create_target` is called, it will lazily load the requested
systems on-demand through internal `find_package` calls. If a project already
uses TBB or OpenMP, it may specify a CMake target for Thrust to share instead:
```cmake
thrust_set_TBB_target(MyTBBTarget)
thrust_set_OMP_target(MyOMPTarget)
```
These functions must be called **before** the corresponding system is loaded
through `thrust_create_target` or `find_package(Thrust COMPONENT [OMP|TBB])`.
#### Using an Explicit libcu++ CMake Target
In contrast to the optional TBB/OMP dependencies, there is no
`thrust_set_libcudacxx_target` function that specifies an explicit libcu++
target. This is because libcu++ is always required and must be found during the
initial `find_target(Thrust)` call that defines these functions.
To force Thrust to use a specific libcu++ target, ensure that either the
`Thrust::libcudacxx` or `libcudacxx::libcudacxx` targets are defined prior to
the first invocation of `find_package(Thrust)`. Thrust will automatically use
these, giving preference to the `Thrust::libcudacxx` target.
#### Testing for Systems
The following functions check if a system has been found, either by lazy loading
through `thrust_create_target` or as a `find_package` `COMPONENT` /
`OPTIONAL_COMPONENT`:
```cmake
# Set var_name to TRUE or FALSE if an individual system has been found:
thrust_is_cuda_system_found(<var_name>)
thrust_is_cpp_system_found(<var_name>)
thrust_is_tbb_system_found(<var_name>)
thrust_is_omp_system_found(<var_name>)
# Generic version that takes a component name from CUDA, CPP, TBB, OMP:
thrust_is_system_found(<component_name> <var_name>)
# Defines `THRUST_*_FOUND` variables in the current scope that reflect the
# state of all known systems. Can be used to refresh these flags after
# lazy system loading.
thrust_update_system_found_flags()
```
#### Debugging
Thrust will produce a detailed log describing its targets, cache options, and
interfaces when `--log-level=VERBOSE` is passed to CMake 3.15.7 or newer:
```
$ cmake . --log-level=VERBOSE
```
This can be handy for inspecting interface and dependency information.
## Fixing Legacy FindThrust.cmake
A community-created `FindThrust.cmake` module exists and is necessary to find
Thrust installations prior to Thrust 1.9.10. Its usage is discouraged whenever
possible and the config files in this directory should be strongly preferred.
However, projects that need to support old versions of Thrust may still need to
use the legacy `FindThrust.cmake` with pre-1.9.10 installations.
One popular flavor of this find module has a version parsing bug. Projects that
rely on `FindThrust.cmake` should check for this and patch their copies as
follows.
Replace:
```cmake
string( REGEX MATCH "^[0-9]" major ${version} )
string( REGEX REPLACE "^${major}00" "" version "${version}" )
string( REGEX MATCH "^[0-9]" minor ${version} )
string( REGEX REPLACE "^${minor}0" "" version "${version}" )
```
with:
```cmake
math(EXPR major "${version} / 100000")
math(EXPR minor "(${version} / 100) % 1000")
math(EXPR version "${version} % 100")
```
# Thrust Developer Documentation
This portion of the file contains descriptions of Thrust's internal CMake target
structure for Thrust developers. It should not be necessary for users
who just want to use Thrust from their projects.
## Internal Targets
By default, `find_package(Thrust)` will only create a single `Thrust::Thrust`
target that describes where the actual Thrust headers are located. It does not
locate or create configurations for any dependencies; these are lazily loaded
on-demand by calls to `create_thrust_target`, or when explicitly requested via
`find_package`'s component mechanism.
As mentioned, the basic Thrust interface is described by the `Thrust::Thrust`
target.
Each backend system (`CPP`, `CUDA`, `TBB`, `OMP`) is described by multiple
targets:
- `Thrust::${system}`
- Specifies an interface configured to build against all
dependencies for this backend (including `Thrust::Thrust`).
- For example, the `Thrust::CUDA` target is an interface
target that combines the interfaces of both Thrust and CUB.
- `Thrust::${system}::Host`
- Configures an interface for using a specific host system.
- Multiple `::Host` targets cannot be combined in the same library/executable.
Attempting to do so will produce a CMake configuration error.
- Only defined for systems that support being used as the host.
- `Thrust::${system}::Device`
- Configures an interface for using a specific device system.
- Multiple `::Device` targets cannot be combined in the same library/executable.
Attempting to do so will produce a CMake configuration error.
- Only defined for systems that support being used as the device.
|