1# Table of Contents
2
31. [Contributing to CUB](#contributing-to-cub)
41. [CMake Options](#cmake-options)
51. [Development Model](#development-model)
6
7# Contributing to CUB
8
9CUB uses Github to manage all open-source development, including bug tracking,
10pull requests, and design discussions. This document details how to get
11started as a CUB contributor.
12
13An overview of this process is:
14
151. [Clone the CUB repository](#clone-the-cub-repository)
161. [Setup a fork of CUB](#setup-a-fork-of-cub)
171. [Setup your environment](#setup-your-environment)
181. [Create a development branch](#create-a-development-branch)
191. [Local development loop](#local-development-loop)
201. [Push development branch to your fork](#push-development-branch-to-your-fork)
211. [Create pull request](#create-pull-request)
221. [Address feedback and update pull request](#address-feedback-and-update-pull-request)
231. [When your PR is approved...](#when-your-pr-is-approved)
24
25## Clone the CUB Repository
26
27To get started, clone the main repository to your local computer:
28
29```
30git clone https://github.com/NVIDIA/cub.git
31cd cub
32```
33
34## Setup a Fork of CUB
35
36You'll need a fork of CUB on Github to create a pull request. To setup your
37fork:
38
391. Create a Github account (if needed)
402. Go to [the CUB Github page](https://github.com/NVIDIA/cub)
413. Click "Fork" and follow any prompts that appear.
42
43Once your fork is created, setup a new remote repo in your local CUB clone:
44
45```
46git remote add github-fork git@github.com:<GITHUB_USERNAME>/cub.git
47```
48
49## Setup Your Environment
50
51### Git Environment
52
53If you haven't already, this is a good time to tell git who you are. This
54information is used to fill out authorship information on your git commits.
55
56```
57git config --global user.name "John Doe"
58git config --global user.email johndoe@example.com
59```
60
61### Configure CMake builds
62
63CUB uses [CMake](https://www.cmake.org) for its developer build system. To
64configure, build, and test your checkout of CUB with default settings:
65
66```
67# Create build directory:
68mkdir build
69cd build
70
71# Configure -- use one of the following:
72cmake ..   # Command line interface.
73ccmake ..  # ncurses GUI (Linux only)
74cmake-gui  # Graphical UI, set source/build directories in the app
75
76# Build:
77cmake --build . -j <num jobs>   # invokes make (or ninja, etc)
78
79# Run tests and examples:
80ctest
81```
82
83See [CMake Options](#cmake-options) for details on customizing the build.
84
85## Create a Development Branch
86
87All work should be done in a development branch (also called a "topic branch")
88and not directly in the `main` branch. This makes it easier to manage multiple
89in-progress patches at once, and provides a descriptive label for your patch
90as it passes through the review system.
91
92To create a new branch based on the current `main`:
93
94```
95# Checkout local main branch:
96cd /path/to/cub/sources
97git checkout main
98
99# Sync local main branch with github:
100git pull
101
102# Create a new branch named `my_descriptive_branch_name` based on main:
103git checkout -b my_descriptive_branch_name
104
105# Verify that the branch has been created and is currently checked out:
106git branch
107```
108
109CUB branch names should follow a particular pattern:
110
111- For new features, name the branch `feature/<name>`
112- For bugfixes associated with a github issue, use `bug/github/<bug-description>-<bug-id>`
113  - Internal nvidia and gitlab bugs should use `nvidia` or `gitlab` in place of
114    `github`.
115
116## Local Development Loop
117
118### Edit, Build, Test, Repeat
119
120Once the topic branch is created, you're all set to start working on CUB
121code. Make some changes, then build and test them:
122
123```
124# Implement changes:
125cd /path/to/cub/sources
126emacs cub/some_file.cuh # or whatever editor you prefer
127
128# Create / update a unit test for your changes:
129emacs tests/some_test.cu
130
131# Check that everything builds and tests pass:
132cd /path/to/cub/build/directory
133cmake --build . -j <num_jobs> # or make, ninja, etc
134ctest
135```
136
137### Creating a Commit
138
139Once you're satisfied with your patch, commit your changes:
140
141```
142# Manually add changed files and create a commit:
143cd /path/to/cub
144git add cub/some_file.cuh
145git add tests/some_test.cu
146git commit
147
148# Or, if possible, use git-gui to review your changes while building your patch:
149git gui
150```
151
152#### Writing a Commit Message
153
154Your commit message will communicate the purpose and rationale behind your
155patch to other developers, and will be used to populate the initial description
156of your Github pull request.
157
158When writing a commit message, the following standard format should be used,
159since tools in the git ecosystem are designed to parse this correctly:
160
161```
162First line of commit message is a short summary (<80 char)
163<Second line left blank>
164Detailed description of change begins on third line. This portion can
165span multiple lines, try to manually wrap them at something reasonable.
166
167Blank lines can be used to separate multiple paragraphs in the description.
168
169If your patch is associated with another pull request or issue in the main
170CUB repository, you should reference it with a `#` symbol, e.g.
171#1023 for issue 1023.
172
173For issues / pull requests in a different github repo, reference them using
174the full syntax, e.g. NVIDIA/thrust#4 for issue 4 in the NVIDIA/thrust repo.
175
176Markdown is recommended for formatting more detailed messages, as these will
177be nicely rendered on Github, etc.
178```
179
180## Push Development Branch to your Fork
181
182Once you've committed your changes to a local development branch, it's time to
183push them to your fork:
184
185```
186cd /path/to/cub/checkout
187git checkout my_descriptive_branch_name # if not already checked out
188git push --set-upstream github-fork my_descriptive_branch_name
189```
190
191`--set-upstream github-fork` tells git that future pushes/pulls on this branch
192should target your `github-fork` remote by default.
193
194## Create Pull Request
195
196To create a pull request for your freshly pushed branch, open your github fork
197in a browser by going to `https://www.github.com/<GITHUB_USERNAME>/cub`. A
198prompt may automatically appear asking you to create a pull request if you've
199recently pushed a branch.
200
201If there's no prompt, go to "Code" > "Branches" and click the appropriate
202"New pull request" button for your branch.
203
204If you would like a specific developer to review your patch, feel free to
205request them as a reviewer at this time.
206
207The CUB team will review your patch, test it on NVIDIA's internal CI, and
208provide feedback.
209
210## Address Feedback and Update Pull Request
211
212If the reviewers request changes to your patch, use the following process to
213update the pull request:
214
215```
216# Make changes:
217cd /path/to/cub/sources
218git checkout my_descriptive_branch_name
219emacs cub/some_file.cuh
220emacs tests/some_test.cu
221
222# Build + test
223cd /path/to/thrust/build/directory
224cmake --build . -j <num jobs>
225ctest
226
227# Amend commit:
228cd /path/to/cub/sources
229git add cub/some_file.cuh
230git add tests/some_test.cu
231git commit --amend
232# Or
233git gui # Check the "Amend Last Commit" box
234
235# Update the branch on your fork:
236git push -f
237```
238
239At this point, the pull request should show your recent changes.
240
241## When Your PR is Approved
242
243Once your pull request is approved by the CUB team, no further action is
244needed from you. We will handle integrating it since we must coordinate changes
245to `main` with NVIDIA's internal perforce repository.
246
247# CMake Options
248
249A CUB build is configured using CMake options. These may be passed to CMake
250using
251
252```
253cmake -D<option_name>=<value> /path/to/cub/sources
254```
255
256or configured interactively with the `ccmake` or `cmake-gui` interfaces.
257
258The configuration options for CUB are:
259
260- `CMAKE_BUILD_TYPE={Release, Debug, RelWithDebInfo, MinSizeRel}`
261  - Standard CMake build option. Default: `RelWithDebInfo`
262- `CUB_ENABLE_HEADER_TESTING={ON, OFF}`
263  - Whether to test compile public headers. Default is `ON`.
264- `CUB_ENABLE_TESTING={ON, OFF}`
265  - Whether to build unit tests. Default is `ON`.
266- `CUB_ENABLE_EXAMPLES={ON, OFF}`
267  - Whether to build examples. Default is `ON`.
268- `CUB_ENABLE_DIALECT_CPPXX={ON, OFF}`
269  - Toggle whether a specific C++ dialect will be targeted.
270  - Multiple dialects may be targeted in a single build.
271  - Possible values of `XX` are `{11, 14, 17}`.
272  - By default, only C++14 is enabled.
273- `CUB_ENABLE_COMPUTE_XX={ON, OFF}`
274  - Controls the targeted CUDA architecture(s)
275  - Multiple options may be selected when using NVCC as the CUDA compiler.
276  - Valid values of `XX` are:
277    `{35, 37, 50, 52, 53, 60, 61, 62, 70, 72, 75, 80}`
278  - Default value depends on `CUB_DISABLE_ARCH_BY_DEFAULT`:
279- `CUB_ENABLE_COMPUTE_FUTURE={ON, OFF}`
280  - If enabled, CUDA objects will target the most recent virtual architecture
281    in addition to the real architectures specified by the
282    `CUB_ENABLE_COMPUTE_XX` options.
283  - Default value depends on `CUB_DISABLE_ARCH_BY_DEFAULT`:
284- `CUB_DISABLE_ARCH_BY_DEFAULT={ON, OFF}`
285  - When `ON`, all `CUB_ENABLE_COMPUTE_*` options are initially `OFF`.
286  - Default: `OFF` (meaning all architectures are enabled by default)
287- `CUB_ENABLE_TESTS_WITH_RDC={ON, OFF}`
288  - Whether to enable Relocatable Device Code when building tests.
289    Default is `OFF`.
290- `CUB_ENABLE_EXAMPLES_WITH_RDC={ON, OFF}`
291  - Whether to enable Relocatable Device Code when building examples.
292    Default is `OFF`.
293- `CUB_ENABLE_INSTALL_RULES={ON, OFF}`
294  - If true, installation rules will be generated for CUB. Default is `ON` when
295    building CUB alone, and `OFF` when CUB is a subproject added via CMake's
296    `add_subdirectory`.
297
298# Development Model
299
300The following is a description of the basic development process that CUB follows. This is a living
301document that will evolve as our process evolves.
302
303CUB is distributed in three ways:
304
305   * On GitHub.
306   * In the NVIDIA HPC SDK.
307   * In the CUDA Toolkit.
308
309## Trunk Based Development
310
311CUB uses [trunk based development](https://trunkbaseddevelopment.com). There is a single long-lived
312branch called `main`. Engineers may create branches for feature development. Such branches always
313merge into `main`. There are no release branches. Releases are produced by taking a snapshot of
314`main` ("snapping"). After a release has been snapped from `main`, it will never be changed.
315
316## Repositories
317
318As CUB is developed both on GitHub and internally at NVIDIA, there are three main places where code lives:
319
320   * The Source of Truth, the [public CUB repository](https://github.com/NVIDIA/cub), referred to as
321     `github` later in this document.
322   * An internal GitLab repository, referred to as `gitlab` later in this document.
323   * An internal Perforce repository, referred to as `perforce` later in this document.
324
325## Versioning
326
327CUB has its own versioning system for releases, independent of the versioning scheme of the NVIDIA
328HPC SDK or the CUDA Toolkit.
329
330Today, CUB version numbers have a specific [semantic meaning](https://semver.org/).
331Releases prior to 1.10.0 largely, but not strictly, followed these semantic meanings.
332
333The version number for a CUB release uses the following format: `MMM.mmm.ss-ppp`, where:
334
335   * `CUB_VERSION_MAJOR`/`MMM`: Major version, up to 3 decimal digits. It is incremented
336     when the fundamental nature of the library evolves, leading to widespread changes across the
337     entire library interface with no guarantee of API, ABI, or semantic compatibility with former
338     versions.
339   * `CUB_VERSION_MINOR`/`mmm`: Minor version, up to 3 decimal digits. It is incremented when
340     breaking API, ABI, or semantic changes are made.
341   * `CUB_VERSION_SUBMINOR`/`ss`: Subminor version, up to 2 decimal digits. It is incremented
342     when notable new features or bug fixes or features that are API, ABI, and semantic backwards
343     compatible are added.
344   * `CUB_PATCH_NUMBER`/`ppp`: Patch number, up to 3 decimal digits. It is incremented if any
345     change in the repo whatsoever is made and no other version component has been incremented.
346
347The `<cub/version.h>` header defines `CUB_*` macros for all of the version components mentioned
348above. Additionally, a `CUB_VERSION` macro is defined, which is an integer literal containing all
349of the version components except for `CUB_PATCH_NUMBER`.
350
351## Branches and Tags
352
353The following tag names are used in the CUB project:
354
355  * `github/nvhpc-X.Y`: the tag that directly corresponds to what has been shipped in the NVIDIA HPC SDK release X.Y.
356  * `github/cuda-X.Y`: the tag that directly corresponds to what has been shipped in the CUDA Toolkit release X.Y.
357  * `github/A.B.C`: the tag that directly corresponds to CUB version A.B.C.
358  * `github/A.B.C-rcN`: the tag that directly corresponds to CUB version A.B.C release candidate N.
359
360The following branch names are used in the CUB project:
361
362  * `github/main`: the Source of Truth development branch of CUB.
363  * `github/old-master`: the old Source of Truth branch, before unification of public and internal repositories.
364  * `github/feature/<name>`: feature branch for a feature under development.
365  * `github/bug/<bug-system>/<bug-description>-<bug-id>`: bug fix branch, where `bug-system` is `github` or `nvidia`.
366  * `gitlab/main`: mirror of `github/main`.
367  * `perforce/private`: mirrored `github/main`, plus files necessary for internal NVIDIA testing systems.
368
369On the rare occasion that we cannot do work in the open, for example when developing a change specific to an
370unreleased product, these branches may exist on `gitlab` instead of `github`. By default, everything should be
371in the open on `github` unless there is a strong motivation for it to not be open.
372