diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..2b00788b1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,90 @@ +BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignEscapedNewlines: Right +AlignOperands: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma +ColumnLimit: 100 +CompactNamespaces: false +ContinuationIndentWidth: 2 +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^$' + Priority: 4 + - Regex: '^ in binary search algorithms - #418 avoid various warnings - #443 including version.h no longer configures default systems - #578 nvcc produces warnings when sequential algorithms are used with cpu systems - -Known Issues - When invoked with primitive data types, thrust::sort, thrust::sort_by_key, thrust::stable_sort, & thrust::stable_sort_by_key may - fail to link in some cases with nvcc -rdc=true. - - The CUDA implementation of thrust::reduce_by_key incorrectly outputs the last element in a segment of equivalent keys instead of the first. - -Acknowledgments - Thanks to Sean Baxter for contributing faster CUDA reduce, merge, and scan implementations. - Thanks to Duane Merrill for contributing a faster CUDA radix sort implementation. - Thanks to Filipe Maia for contributing the implementation of thrust::complex. - -####################################### -# Thrust v1.7.2 # -####################################### - -Summary - Small bug fixes - -Bug Fixes - Avoid use of std::min in generic find implementation - -####################################### -# Thrust v1.7.1 # -####################################### - -Summary - Small bug fixes - -Bug Fixes - Eliminate identifiers in set_operations.cu example with leading underscore - Eliminate unused variable warning in CUDA reduce_by_key implemention - Avoid deriving function objects from std::unary_function and std::binary_function - -####################################### -# Thrust v1.7.0 # -####################################### - -Summary - Thrust 1.7.0 introduces a new interface for controlling algorithm execution as - well as several new algorithms and performance improvements. With this new - interface, users may directly control how algorithms execute as well as details - such as the allocation of temporary storage. Key/value versions of thrust::merge - and the set operation algorithms have been added, as well stencil versions of - partitioning algorithms. thrust::tabulate has been introduced to tabulate the - values of functions taking integers. For 32b types, new CUDA merge and set - operations provide 2-15x faster performance while a new CUDA comparison sort - provides 1.3-4x faster performance. Finally, a new TBB reduce_by_key implementation - provides 80% faster performance. - -Breaking API Changes - Dispatch - Custom user backend systems' tag types must now inherit from the corresponding system's execution_policy template (e.g. thrust::cuda::execution_policy) instead - of the tag struct (e.g. thrust::cuda::tag). Otherwise, algorithm specializations will silently go unfound during dispatch. - See examples/minimal_custom_backend.cu and examples/cuda/fallback_allocator.cu for usage examples. - - thrust::advance and thrust::distance are no longer dispatched based on iterator system type and thus may no longer be customized. - - Iterators - iterator_facade and iterator_adaptor's Pointer template parameters have been eliminated. - iterator_adaptor has been moved into the thrust namespace (previously thrust::experimental::iterator_adaptor). - iterator_facade has been moved into the thrust namespace (previously thrust::experimental::iterator_facade). - iterator_core_access has been moved into the thrust namespace (previously thrust::experimental::iterator_core_access). - All iterators' nested pointer typedef (the type of the result of operator->) is now void instead of a pointer type to indicate that such expressions are currently impossible. - Floating point counting_iterators' nested difference_type typedef is now a signed integral type instead of a floating point type. - - Other - normal_distribution has been moved into the thrust::random namespace (previously thrust::random::experimental::normal_distribution). - Placeholder expressions may no longer include the comma operator. - -New Features - Execution Policies - Users may directly control the dispatch of algorithm invocations with optional execution policy arguments. - For example, instead of wrapping raw pointers allocated by cudaMalloc with thrust::device_ptr, the thrust::device execution_policy may be passed as an argument to an algorithm invocation to enable CUDA execution. - The following execution policies are supported in this version: - - thrust::host - thrust::device - thrust::cpp::par - thrust::cuda::par - thrust::omp::par - thrust::tbb::par - - Algorithms - free - get_temporary_buffer - malloc - merge_by_key - partition with stencil - partition_copy with stencil - return_temporary_buffer - set_difference_by_key - set_intersection_by_key - set_symmetric_difference_by_key - set_union_by_key - stable_partition with stencil - stable_partition_copy with stencil - tabulate - -New Examples - uninitialized_vector demonstrates how to use a custom allocator to avoid the automatic initialization of elements in thrust::device_vector. - -Other Enhancements - Authors of custom backend systems may manipulate arbitrary state during algorithm dispatch by incorporating it into their execution_policy parameter. - Users may control the allocation of temporary storage during algorithm execution by passing standard allocators as parameters via execution policies such as thrust::device. - THRUST_DEVICE_SYSTEM_CPP has been added as a compile-time target for the device backend. - CUDA merge performance is 2-15x faster. - CUDA comparison sort performance is 1.3-4x faster. - CUDA set operation performance is 1.5-15x faster. - TBB reduce_by_key performance is 80% faster. - Several algorithms have been parallelized with TBB. - Support for user allocators in vectors has been improved. - The sparse_vector example is now implemented with merge_by_key instead of sort_by_key. - Warnings have been eliminated in various contexts. - Warnings about __host__ or __device__-only functions called from __host__ __device__ functions have been eliminated in various contexts. - Documentation about algorithm requirements have been improved. - Simplified the minimal_custom_backend example. - Simplified the cuda/custom_temporary_allocation example. - Simplified the cuda/fallback_allocator example. - -Bug Fixes - #248 fix broken counting_iterator behavior with OpenMP - #231, #209 fix set operation failures with CUDA - #187 fix incorrect occupancy calculation with CUDA - #153 fix broken multigpu behavior with CUDA - #142 eliminate warning produced by thrust::random::taus88 and MSVC 2010 - #208 correctly initialize elements in temporary storage when necessary - #16 fix compilation error when sorting bool with CUDA - #10 fix ambiguous overloads of reinterpret_tag - -Known Issues - g++ versions 4.3 and lower may fail to dispatch thrust::get_temporary_buffer correctly causing infinite recursion in examples such as cuda/custom_temporary_allocation. - -Acknowledgments - Thanks to Sean Baxter, Bryan Catanzaro, and Manjunath Kudlur for contributing a faster merge implementation for CUDA. - Thanks to Sean Baxter for contributing a faster set operation implementation for CUDA. - Thanks to Cliff Woolley for contributing a correct occupancy calculation algorithm. - -####################################### -# Thrust v1.6.0 # -####################################### - -Summary - Thrust v1.6.0 provides an interface for customization and extension and a new - backend system based on the Threading Building Blocks library. With this - new interface, programmers may customize the behavior of specific algorithms - as well as control the allocation of temporary storage or invent entirely new - backends. These enhancements also allow multiple different backend systems - such as CUDA and OpenMP to coexist within a single program. Support for TBB - allows Thrust programs to integrate more naturally into applications which - may already employ the TBB task scheduler. - -Breaking API Changes - The header has been moved to - thrust::experimental::cuda::pinned_allocator has been moved to thrust::cuda::experimental::pinned_allocator - The macro THRUST_DEVICE_BACKEND has been renamed THRUST_DEVICE_SYSTEM - The macro THRUST_DEVICE_BACKEND_CUDA has been renamed THRUST_DEVICE_SYSTEM_CUDA - The macro THRUST_DEVICE_BACKEND_OMP has been renamed THRUST_DEVICE_SYSTEM_OMP - thrust::host_space_tag has been renamed thrust::host_system_tag - thrust::device_space_tag has been renamed thrust::device_system_tag - thrust::any_space_tag has been renamed thrust::any_system_tag - thrust::iterator_space has been renamed thrust::iterator_system - - -New Features - Backend Systems - Threading Building Blocks (TBB) is now supported - Functions - for_each_n - raw_reference_cast - Types - pointer - reference - -New Examples - cuda/custom_temporary_allocation - cuda/fallback_allocator - device_ptr - expand - minimal_custom_backend - raw_reference_cast - set_operations - -Other Enhancements - thrust::for_each now returns the end of the input range similar to most other algorithms - thrust::pair and thrust::tuple have swap functionality - all CUDA algorithms now support large data types - iterators may be dereferenced in user __device__ or __global__ functions - the safe use of different backend systems is now possible within a single binary - -Bug Fixes - #469 min_element and max_element algorithms no longer require a const comparison operator - -Known Issues - cudafe++.exe may crash when parsing TBB headers on Windows. - -####################################### -# Thrust v1.5.3 # -####################################### - -Summary - Small bug fixes - -Bug Fixes - Avoid warnings about potential race due to __shared__ non-POD variable - -####################################### -# Thrust v1.5.2 # -####################################### - -Summary - Small bug fixes - -Bug Fixes - Fixed warning about C-style initialization of structures - -####################################### -# Thrust v1.5.1 # -####################################### - -Summary - Small bug fixes - -Bug Fixes - Sorting data referenced by permutation_iterators on CUDA produces invalid results - -####################################### -# Thrust v1.5.0 # -####################################### - -Summary - Thrust v1.5.0 provides introduces new programmer productivity and performance - enhancements. New functionality for creating anonymous "lambda" functions has - been added. A faster host sort provides 2-10x faster performance for sorting - arithmetic types on (single-threaded) CPUs. A new OpenMP sort provides - 2.5x-3.0x speedup over the host sort using a quad-core CPU. When sorting - arithmetic types with the OpenMP backend the combined performance improvement - is 5.9x for 32-bit integers and ranges from 3.0x (64-bit types) to 14.2x - (8-bit types). A new CUDA reduce_by_key implementation provides 2-3x faster - performance. - -Breaking API Changes - device_ptr no longer unsafely converts to device_ptr without an - explicit cast. Use the expression - device_pointer_cast(static_cast(void_ptr.get())) - to convert, for example, device_ptr to device_ptr. - -New Features - Functions - stencil-less transform_if - - Types - lambda placeholders - -New Examples - lambda - -Other Enhancements - host sort is 2-10x faster for arithmetic types - OMP sort provides speedup over host sort - reduce_by_key is 2-3x faster - reduce_by_key no longer requires O(N) temporary storage - CUDA scan algorithms are 10-40% faster - host_vector and device_vector are now documented - out-of-memory exceptions now provide detailed information from CUDART - improved histogram example - device_reference now has a specialized swap - reduce_by_key and scan algorithms are compatible with discard_iterator - -Removed Functionality - -Bug Fixes - #44 allow host_vector to compile when value_type uses __align__ - #198 allow adjacent_difference to permit safe in-situ operation - #303 make thrust thread-safe - #313 avoid race conditions in device_vector::insert - #314 avoid unintended adl invocation when dispatching copy - #365 fix merge and set operation failures - -Known Issues - None - -Acknowledgments - Thanks to Manjunath Kudlur for contributing his Carbon library, from which the lambda functionality is derived. - Thanks to Jean-Francois Bastien for suggesting a fix for issue 303. - -####################################### -# Thrust v1.4.0 # -####################################### - -Summary - Thrust v1.4.0 provides support for CUDA 4.0 in addition to many feature - and performance improvements. New set theoretic algorithms operating on - sorted sequences have been added. Additionally, a new fancy iterator - allows discarding redundant or otherwise unnecessary output from - algorithms, conserving memory storage and bandwidth. - -Breaking API Changes - Eliminations - thrust/is_sorted.h - thrust/utility.h - thrust/set_intersection.h - thrust/experimental/cuda/ogl_interop_allocator.h and the functionality therein - thrust::deprecated::copy_when - thrust::deprecated::absolute_value - -New Features - Functions - copy_n - merge - set_difference - set_symmetric_difference - set_union - - Types - discard_iterator - - Device support - Compute Capability 2.1 GPUs - -New Examples - run_length_decoding - -Other Enhancements - Compilation warnings are substantially reduced in various contexts. - The compilation time of thrust::sort, thrust::stable_sort, thrust::sort_by_key, - and thrust::stable_sort_by_key are substantially reduced. - A fast sort implementation is used when sorting primitive types with thrust::greater. - The performance of thrust::set_intersection is improved. - The performance of thrust::fill is improved on SM 1.x devices. - A code example is now provided in each algorithm's documentation. - thrust::reverse now operates in-place - -Removed Functionality - thrust::deprecated::copy_when - thrust::deprecated::absolute_value - thrust::experimental::cuda::ogl_interop_allocator - thrust::gather and thrust::scatter from host to device and vice versa are no longer supported. - Operations which modify the elements of a thrust::device_vector are no longer - available from source code compiled without nvcc when the device backend is CUDA. - Instead, use the idiom from the cpp_interop example. - -Bug Fixes - #212 set_intersection works correctly for large input sizes. - #275 counting_iterator and constant_iterator work correctly with OpenMP as the - backend when compiling with optimization - #256 min and max correctly return their first argument as a tie-breaker - #248 NDEBUG is interpreted correctly - -Known Issues - nvcc may generate code containing warnings when compiling some Thrust algorithms. - When compiling with -arch=sm_1x, some Thrust algorithms may cause nvcc to issue - benign pointer advisories. - When compiling with -arch=sm_1x and -G, some Thrust algorithms may fail to execute correctly. - thrust::inclusive_scan, thrust::exclusive_scan, thrust::inclusive_scan_by_key, - and thrust::exclusive_scan_by_key are currently incompatible with thrust::discard_iterator. - -Acknowledgments - Thanks to David Tarjan for improving the performance of set_intersection. - Thanks to Duane Merrill for continued help with sort. - Thanks to Nathan Whitehead for help with CUDA Toolkit integration. - -####################################### -# Thrust v1.3.0 # -####################################### - -Summary - Thrust v1.3.0 provides support for CUDA 3.2 in addition to many feature - and performance enhancements. - - Performance of the sort and sort_by_key algorithms is improved by as much - as 3x in certain situations. The performance of stream compaction algorithms, - such as copy_if, is improved by as much as 2x. Reduction performance is - also improved, particularly for small input sizes. - - CUDA errors are now converted to runtime exceptions using the system_error - interface. Combined with a debug mode, also new in v1.3, runtime errors - can be located with greater precision. - - Lastly, a few header files have been consolidated or renamed for clarity. - See the deprecations section below for additional details. - - -Breaking API Changes - Promotions - thrust::experimental::inclusive_segmented_scan has been renamed thrust::inclusive_scan_by_key and exposes a different interface - thrust::experimental::exclusive_segmented_scan has been renamed thrust::exclusive_scan_by_key and exposes a different interface - thrust::experimental::partition_copy has been renamed thrust::partition_copy and exposes a different interface - thrust::next::gather has been renamed thrust::gather - thrust::next::gather_if has been renamed thrust::gather_if - thrust::unique_copy_by_key has been renamed thrust::unique_by_key_copy - Deprecations - thrust::copy_when has been renamed thrust::deprecated::copy_when - thrust::absolute_value has been renamed thrust::deprecated::absolute_value - The header thrust/set_intersection.h is now deprecated; use thrust/set_operations.h instead - The header thrust/utility.h is now deprecated; use thrust/swap.h instead - The header thrust/swap_ranges.h is now deprecated; use thrust/swap.h instead - Eliminations - thrust::deprecated::gather - thrust::deprecated::gather_if - thrust/experimental/arch.h and the functions therein - thrust/sorting/merge_sort.h - thrust/sorting/radix_sort.h - -New Features - Functions - exclusive_scan_by_key - find - find_if - find_if_not - inclusive_scan_by_key - is_partitioned - is_sorted_until - mismatch - partition_point - reverse - reverse_copy - stable_partition_copy - - Types - system_error and related types - experimental::cuda::ogl_interop_allocator - bit_and, bit_or, and bit_xor - - Device support - gf104-based GPUs - -New Examples - opengl_interop.cu - repeated_range.cu - simple_moving_average.cu - sparse_vector.cu - strided_range.cu - -Other Enhancements - Performance of thrust::sort and thrust::sort_by_key is substantially improved for primitive key types - Performance of thrust::copy_if is substantially improved - Performance of thrust::reduce and related reductions is improved - THRUST_DEBUG mode added - Callers of Thrust functions may detect error conditions by catching thrust::system_error, which derives from std::runtime_error - The number of compiler warnings generated by Thrust has been substantially reduced - Comparison sort now works correctly for input sizes > 32M - min & max usage no longer collides with definitions - Compiling against the OpenMP backend no longer requires nvcc - Performance of device_vector initialized in .cpp files is substantially improved in common cases - Performance of thrust::sort_by_key on the host is substantially improved - -Removed Functionality - nvcc 2.3 is no longer supported - -Bug Fixes - Debug device code now compiles correctly - thrust::uninitialized_copy and thrust::unintialized_fill now dispatch constructors on the device rather than the host - -Known Issues - #212 set_intersection is known to fail for large input sizes - partition_point is known to fail for 64b types with nvcc 3.2 - -Acknowledgments - Thanks to Duane Merrill for contributing a fast CUDA radix sort implementation - Thanks to Erich Elsen for contributing an implementation of find_if - Thanks to Andrew Corrigan for contributing changes which allow the OpenMP backend to compile in the absence of nvcc - Thanks to Andrew Corrigan, Cliff Wooley, David Coeurjolly, Janick Martinez Esturo, John Bowers, Maxim Naumov, Michael Garland, and Ryuta Suzuki for bug reports - Thanks to Cliff Woolley for help with testing - -####################################### -# Thrust v1.2.1 # -####################################### - -Summary - Small fixes for compatibility with CUDA 3.1 - -Known Issues - inclusive_scan & exclusive_scan may fail with very large types - the Microsoft compiler may fail to compile code using both sort and binary search algorithms - uninitialized_fill & uninitialized_copy dispatch constructors on the host rather than the device - # 109 some algorithms may exhibit poor performance with the OpenMP backend with large numbers (>= 6) of CPU threads - default_random_engine::discard is not accelerated with nvcc 2.3 - nvcc 3.1 may fail to compile code using types derived from thrust::subtract_with_carry_engine, such as thrust::ranlux24 & thrust::ranlux48. - -####################################### -# Thrust v1.2.0 # -####################################### - -Summary - Thrust v1.2 introduces support for compilation to multicore CPUs - and the Ocelot virtual machine, and several new facilities for - pseudo-random number generation. New algorithms such as set - intersection and segmented reduction have also been added. Lastly, - improvements to the robustness of the CUDA backend ensure - correctness across a broad set of (uncommon) use cases. - -Breaking API Changes - thrust::gather's interface was incorrect and has been removed. - The old interface is deprecated but will be preserved for Thrust - version 1.2 at thrust::deprecated::gather & - thrust::deprecated::gather_if. The new interface is provided at - thrust::next::gather & thrust::next::gather_if. The new interface - will be promoted to thrust:: in Thrust version 1.3. For more details, - please refer to this thread: - http://groups.google.com/group/thrust-users/browse_thread/thread/f5f0583cb97b51fd - - The thrust::sorting namespace has been deprecated in favor of the - top-level sorting functions, such as thrust::sort() and - thrust::sort_by_key(). - -New Features - Functions - reduce_by_key - set_intersection - tie - unique_copy - unique_by_key - unique_copy_by_key - - Types - Random Number Generation - discard_block_engine - default_random_engine - linear_congruential_engine - linear_feedback_shift_engine - minstd_rand - minstd_rand0 - normal_distribution (experimental) - ranlux24 - ranlux48 - ranlux24_base - ranlux48_base - subtract_with_carry_engine - taus88 - uniform_int_distribution - uniform_real_distribution - xor_combine_engine - Functionals - project1st - project2nd - - Fancy Iterators - permutation_iterator - reverse_iterator - - Device support - Add support for multicore CPUs via OpenMP - Add support for Fermi-class GPUs - Add support for Ocelot virtual machine - -New Examples - cpp_integration - histogram - mode - monte_carlo - monte_carlo_disjoint_sequences - padded_grid_reduction - permutation_iterator - row_sum - run_length_encoding - segmented_scan - stream_compaction - summary_statistics - transform_iterator - word_count - -Other Enhancements - vector functions operator!=, rbegin, crbegin, rend, crend, data, & shrink_to_fit - integer sorting performance is improved when max is large but (max - min) is small and when min is negative - performance of inclusive_scan() and exclusive_scan() is improved by 20-25% for primitive types - support for nvcc 3.0 - -Removed Functionality - removed support for equal between host & device sequences - removed support for gather() and scatter() between host & device sequences - -Bug Fixes - # 8 cause a compiler error if the required compiler is not found rather than a mysterious error at link time - # 42 device_ptr & device_reference are classes rather than structs, eliminating warnings on certain platforms - # 46 gather & scatter handle any space iterators correctly - # 51 thrust::experimental::arch functions gracefully handle unrecognized GPUs - # 52 avoid collisions with common user macros such as BLOCK_SIZE - # 62 provide better documentation for device_reference - # 68 allow built-in CUDA vector types to work with device_vector in pure C++ mode - # 102 eliminated a race condition in device_vector::erase - various compilation warnings eliminated - -Known Issues - inclusive_scan & exclusive_scan may fail with very large types - the Microsoft compiler may fail to compile code using both sort and binary search algorithms - uninitialized_fill & uninitialized_copy dispatch constructors on the host rather than the device - # 109 some algorithms may exhibit poor performance with the OpenMP backend with large numbers (>= 6) of CPU threads - default_random_engine::discard is not accelerated with nvcc 2.3 - -Acknowledgments - Thanks to Gregory Diamos for contributing a CUDA implementation of set_intersection - Thanks to Ryuta Suzuki & Gregory Diamos for rigorously testing Thrust's unit tests and examples against Ocelot - Thanks to Tom Bradley for contributing an implementation of normal_distribution - Thanks to Joseph Rhoads for contributing the example summary_statistics - -####################################### -# Thrust v1.1.1 # -####################################### - -Summary - Small fixes for compatibility with CUDA 2.3a and Mac OSX Snow Leopard. - -####################################### -# Thrust v1.1.0 # -####################################### - -Summary - Thrust v1.1 introduces fancy iterators, binary search functions, and - several specialized reduction functions. Experimental support for - segmented scan has also been added. - -Breaking API Changes - counting_iterator has been moved into the thrust namespace (previously thrust::experimental) - -New Features - Functions - copy_if - lower_bound - upper_bound - vectorized lower_bound - vectorized upper_bound - equal_range - binary_search - vectorized binary_search - all_of - any_of - none_of - minmax_element - advance - inclusive_segmented_scan (experimental) - exclusive_segmented_scan (experimental) - - Types - pair - tuple - device_malloc_allocator - - Fancy Iterators - constant_iterator - counting_iterator - transform_iterator - zip_iterator - -New Examples - computing the maximum absolute difference between vectors - computing the bounding box of a two-dimensional point set - sorting multiple arrays together (lexicographical sorting) - constructing a summed area table - using zip_iterator to mimic an array of structs - using constant_iterator to increment array values - -Other Enhancements - added pinned memory allocator (experimental) - added more methods to host_vector & device_vector (issue #4) - added variant of remove_if with a stencil argument (issue #29) - scan and reduce use cudaFuncGetAttributes to determine grid size - exceptions are reported when temporary device arrays cannot be allocated - -Bug Fixes - #5 make vector work for larger data types - #9 stable_partition_copy doesn't respect OutputIterator concept semantics - #10 scans should return OutputIterator - #16 make algorithms work for larger data types - #27 dispatch radix_sort even when comp=less is explicitly provided - -Known Issues - Using functors with Thrust entry points may not compile on Mac OSX with gcc-4.0.1 - uninitialized_copy & uninitialized_fill dispatch constructors on the host rather than the device. - inclusive_scan, inclusive_scan_by_key, exclusive_scan, and exclusive_scan_by_key may fail when used with large types with the CUDA 3.1 driver - - -####################################### -# Thrust v1.0.0 # -####################################### - -Breaking API changes - Rename top level namespace komrade to thrust. - Move partition_copy() & stable_partition_copy() into thrust::experimental namespace until we can easily provide the standard interface. - Rename range() to sequence() to avoid collision with Boost.Range. - Rename copy_if() to copy_when() due to semantic differences with C++0x copy_if(). - -New Features - Add C++0x style cbegin() & cend() methods to host_vector & device_vector. - Add transform_if function. - Add stencil versions of replace_if() & replace_copy_if(). - Allow counting_iterator to work with for_each(). - Allow types with constructors in comparison sort & reduce. - -Other Enhancements - merge_sort and stable_merge_sort are now 2 to 5x faster when executed on the parallel device. - -Bug fixes - Workaround an issue where an incremented iterator causes nvcc to crash. (Komrade issue #6) - Fix an issue where const_iterators could not be passed to transform. (Komrade issue #7) - diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..57eff4212 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2315 @@ +# Changelog + +## Thrust 2.1.0 + +### New Features + +- NVIDIA/thrust#1805: Add default constructors to `transform_output_iterator` + and `transform_input_output_iterator`. Thanks to Mark Harris (@harrism) for this contribution. +- NVIDIA/thrust#1836: Enable constructions of vectors from `std::initializer_list`. + +### Bug Fixes + +- NVIDIA/thrust#1768: Fix type conversion warning in the `thrust::complex` utilities. Thanks to + Zishi Wu (@zishiwu123) for this contribution. +- NVIDIA/thrust#1809: Fix some warnings about usage of `__host__` functions in `__device__` code. +- NVIDIA/thrust#1825: Fix Thrust's CMake install rules. Thanks to Robert Maynard (@robertmaynard) + for this contribution. +- NVIDIA/thrust#1827: Fix `thrust::reduce_by_key` when using non-default-initializable iterators. +- NVIDIA/thrust#1832: Fix bug in device-side CDP `thrust::reduce` when using a large number of + inputs. + +### Other Enhancements + +- NVIDIA/thrust#1815: Update Thrust's libcu++ git submodule to version 1.8.1. +- NVIDIA/thrust#1841: Fix invalid code in execution policy documentation example. Thanks to Raphaël + Frantz (@Eren121) for this contribution. +- NVIDIA/thrust#1848: Improve error messages when attempting to launch a kernel on a device that is + not supported by compiled PTX versions. Thanks to Zahra Khatami (@zkhatami) for this contribution. +- NVIDIA/thrust#1855: Remove usage of deprecated CUDA error codes. + +## Thrust 2.0.1 + +### Other Enhancements + +- Disable CDP parallelization of device-side invocations of Thrust algorithms on SM90+. The removal + of device-side synchronization support in recent architectures makes Thrust's fork-join model + unimplementable on device, so a serial implementation will be used instead. Host-side invocations + of Thrust algorithms are not affected. + +## Thrust 2.0.0 + +### Summary + +The Thrust 2.0.0 major release adds a dependency on libcu++ and contains several +breaking changes. These include new diagnostics when inspecting device-only +lambdas from the host, removal of the `cub` symlink in the Thrust repository +root, and removal of the deprecated `THRUST_*_BACKEND` macros. It also includes +several minor bugfixes and cleanups. + +### Breaking Changes + +- NVIDIA/thrust#1605: Add libcu++ dependency. + - A suitable version of libcu++ is provided through + the `${THRUST_ROOT}/dependencies/libcudacxx/` submodule. + - Non-cmake users may need to add the libcu++ include path to their + builds (`-I ${THRUST_ROOT}/dependencies/libcudacxx/include/`). + - The Thrust CMake packages have been updated to add this include path. +- NVIDIA/thrust#1605: The following macros are no longer defined by default. + They can be re-enabled by defining `THRUST_PROVIDE_LEGACY_ARCH_MACROS`. These + will be removed completely in a future release. + - `THRUST_IS_HOST_CODE`: Replace with `NV_IF_TARGET`. + - `THRUST_IS_DEVICE_CODE`: Replace with `NV_IF_TARGET`. + - `THRUST_INCLUDE_HOST_CODE`: Replace with `NV_IF_TARGET`. + - `THRUST_INCLUDE_DEVICE_CODE`: Replace with `NV_IF_TARGET`. + - `THRUST_DEVICE_CODE`: Replace with `NV_IF_TARGET`. +- NVIDIA/thrust#1661: Thrust's CUDA Runtime support macros have been updated to + support `NV_IF_TARGET`. They are now defined consistently across all + host/device compilation passes. This should not affect most usages of these + macros, but may require changes for some edge cases. + - `THRUST_RUNTIME_FUNCTION`: Execution space annotations for functions that + invoke CUDA Runtime APIs. + - Old behavior: + - RDC enabled: Defined to `__host__ __device__` + - RDC not enabled: + - NVCC host pass: Defined to `__host__ __device__` + - NVCC device pass: Defined to `__host__` + - New behavior: + - RDC enabled: Defined to `__host__ __device__` + - RDC not enabled: Defined to `__host__` + - `__THRUST_HAS_CUDART__`: No change in behavior, but no longer used in + Thrust. Provided for legacy support only. Legacy behavior: + - RDC enabled: Defined to 1. + - RDC not enabled: + - NVCC host pass: Defined to 1. + - NVCC device pass: Defined to 0. + - `THRUST_RDC_ENABLED`: New macro, may be combined with `NV_IF_TARGET` to + replace most usages of `__THRUST_HAS_CUDART__`. Behavior: + - RDC enabled: Macro is defined. + - RDC not enabled: Macro is not defined. +- NVIDIA/thrust#1701: Remove the `cub` symlink from the root of the Thrust + repository. + - This symlink caused issues in certain build environments (e.g. + NVIDIA/thrust#1328). + - Builds that relied on this symlink will need to add the full CUB include + path (`-I ${THRUST_ROOT}/dependencies/cub`). + - CMake builds that use the Thrust packages via CPM, `add_subdirectory`, + or `find_package` are not affected. +- NVIDIA/thrust#1760: A compile-time error is now emitted when a `__device__` + -only lambda's return type is queried from host code (requires libcu++ ≥ + 1.9.0). + - Due to limitations in the CUDA programming model, the result of this query + is unreliable, and will silently return an incorrect result. This leads to + difficult to debug errors. + - When using libcu++ 1.9.0, an error will be emitted with information about + work-arounds: + - Use a named function object with a `__device__`-only implementation + of `operator()`. + - Use a `__host__ __device__` lambda. + - Use `cuda::proclaim_return_type` (Added in libcu++ 1.9.0) +- NVIDIA/thrust#1761: Removed support for deprecated `THRUST_DEVICE_BACKEND` + and `THRUST_HOST_BACKEND` macros. The `THRUST_DEVICE_SYSTEM` + and `THRUST_HOST_SYSTEM` macros should be used instead. + +### Bug Fixes + +- NVIDIA/thrust#1605: Fix some execution space warnings in the allocator + library. +- NVIDIA/thrust#1683: Fix bug in `iterator_category_to_traversal` metafunctions. +- NVIDIA/thrust#1715: Add missing `__thrust_exec_check_disable__` annotation + to `thrust::make_zip_function`. Thanks to @mfbalin for this contribution. +- NVIDIA/thrust#1722: Remove CUDA-specific error handler from code that may be + executed on non-CUDA backends. Thanks to @dkolsen-pgi for this contribution. +- NVIDIA/thrust#1756: Fix `copy_if` for output iterators that don't support copy + assignment. Thanks for @mfbalin for this contribution. + +### Other Enhancements + +- NVIDIA/thrust#1605: Removed special case code for unsupported CUDA + architectures. +- NVIDIA/thrust#1605: Replace several usages of `__CUDA_ARCH__` + with `` to handle host/device code divergence. +- NVIDIA/thrust#1752: Remove a leftover merge conflict from a documentation + file. Thanks to @tabedzki for this contribution. + +## Thrust 1.17.2 + +### Summary + +Thrust 1.17.2 is a minor bugfix release that provides an updated version of CUB. + +## Thrust 1.17.1 + +### Summary + +Thrust 1.17.1 is a minor bugfix release that provides an updated version of CUB. + +## Thrust 1.17.0 + +### Summary + +Thrust 1.17.0 is the final minor release of the 1.X series. This release +provides GDB pretty-printers for device vectors/references, a new `unique_count` +algorithm, and an easier way to create tagged Thrust iterators. Several +documentation fixes are included, which can be found on the new Thrust +documentation site at https://nvidia.github.io/thrust. We'll be migrating +existing documentation sources to this new location over the next few months. + +### New Features + +- NVIDIA/thrust#1586: Add new `thrust::make_tagged_iterator` convenience + function. Thanks to @karthikeyann for this contribution. +- NVIDIA/thrust#1619: Add `unique_count` algorithm. Thanks to @upsj for this + contribution. +- NVIDIA/thrust#1631: Add GDB pretty-printers for device vectors/references + to `scripts/gdb-pretty-printers.py`. Thanks to @upsj for this contribution. + +### Bug Fixes + +- NVIDIA/thrust#1671: Fixed `reduce_by_key` when called with 2^31 elements. + +### Other Enhancements + +- NVIDIA/thrust#1512: Use CUB to implement `adjacent_difference`. +- NVIDIA/thrust#1555: Use CUB to implement `scan_by_key`. +- NVIDIA/thrust#1611: Add new doxybook-based Thrust documentation + at https://nvidia.github.io/thrust. +- NVIDIA/thrust#1639: Fixed broken link in documentation. Thanks to @jrhemstad + for this contribution. +- NVIDIA/thrust#1644: Increase contrast of search input text in new doc site. + Thanks to @bdice for this contribution. +- NVIDIA/thrust#1647: Add `__forceinline__` annotations to a functor wrapper. + Thanks to @mkuron for this contribution. +- NVIDIA/thrust#1660: Fixed typo in documentation example for + `permutation_iterator`. +- NVIDIA/thrust#1669: Add a new `explicit_cuda_stream.cu` example that shows how + to use explicit CUDA streams and `par`/`par_nosync` execution policies. + +## Thrust 1.16.0 + +### Summary + +Thrust 1.16.0 provides a new “nosync” hint for the CUDA backend, as well as +numerous bugfixes and stability improvements. + +#### New `thrust::cuda::par_nosync` Execution Policy + +Most of Thrust's parallel algorithms are fully synchronous and will block the +calling CPU thread until all work is completed. This design avoids many pitfalls +associated with asynchronous GPU programming, resulting in simpler and +less-error prone usage for new CUDA developers. Unfortunately, this improvement +in user experience comes at a performance cost that often frustrates more +experienced CUDA programmers. + +Prior to this release, the only synchronous-to-asynchronous migration path for +existing Thrust codebases involved significant refactoring, replacing calls +to `thrust` algorithms with a limited set of `future`-based `thrust::async` +algorithms or lower-level CUB kernels. The new `thrust::cuda::par_nosync` +execution policy provides a new, less-invasive entry point for asynchronous +computation. + +`par_nosync` is a hint to the Thrust execution engine that any non-essential +internal synchronizations should be skipped and that an explicit synchronization +will be performed by the caller before accessing results. + +While some Thrust algorithms require internal synchronization to safely compute +their results, many do not. For example, multiple `thrust::for_each` invocations +can be launched without waiting for earlier calls to complete: + +```cpp +// Queue three `for_each` kernels: +thrust::for_each(thrust::cuda::par_nosync, vec1.begin(), vec1.end(), Op{}); +thrust::for_each(thrust::cuda::par_nosync, vec2.begin(), vec2.end(), Op{}); +thrust::for_each(thrust::cuda::par_nosync, vec3.begin(), vec3.end(), Op{}); + +// Do other work while kernels execute: +do_something(); + +// Must explictly synchronize before accessing `for_each` results: +cudaDeviceSynchronize(); +``` + +Thanks to @fkallen for this contribution. + +### Deprecation Notices + +#### CUDA Dynamic Parallelism Support + +**A future version of Thrust will remove support for CUDA Dynamic Parallelism +(CDP).** + +This will only affect calls to Thrust algorithms made from CUDA device-side code +that currently launches a kernel; such calls will instead execute sequentially +on the calling GPU thread instead of launching a device-wide kernel. + +### Breaking Changes + +- Thrust 1.14.0 included a change that aliased the `cub` namespace + to `thrust::cub`. This has caused issues with ambiguous namespaces for + projects that declare `using namespace thrust;` from the global namespace. We + recommend against this practice. +- NVIDIA/thrust#1572: Removed several unnecessary header includes. Downstream + projects may need to update their includes if they were relying on this + behavior. + +### New Features + +- NVIDIA/thrust#1568: Add `thrust::cuda::par_nosync` policy. Thanks to @fkallen + for this contribution. + +### Enhancements + +- NVIDIA/thrust#1511: Use CUB's new `DeviceMergeSort` API and remove Thrust's + internal implementation. +- NVIDIA/thrust#1566: Improved performance of `thrust::shuffle`. Thanks to + @djns99 for this contribution. +- NVIDIA/thrust#1584: Support user-defined `CMAKE_INSTALL_INCLUDEDIR` values in + Thrust's CMake install rules. Thanks to @robertmaynard for this contribution. + +### Bug Fixes + +- NVIDIA/thrust#1496: Fix some issues affecting `icc` builds. +- NVIDIA/thrust#1552: Fix some collisions with the `min`/`max` macros defined + in `windows.h`. +- NVIDIA/thrust#1582: Fix issue with function type alias on 32-bit MSVC builds. +- NVIDIA/thrust#1591: Workaround issue affecting compilation with `nvc++`. +- NVIDIA/thrust#1597: Fix some collisions with the `small` macro defined + in `windows.h`. +- NVIDIA/thrust#1599, NVIDIA/thrust#1603: Fix some issues with version handling + in Thrust's CMake packages. +- NVIDIA/thrust#1614: Clarify that scan algorithm results are non-deterministic + for pseudo-associative operators (e.g. floating-point addition). + +## Thrust 1.15.0 + +### Summary + +Thrust 1.15.0 provides numerous bugfixes, including non-numeric +`thrust::sequence` support, several MSVC-related compilation fixes, fewer +conversion warnings, `counting_iterator` initialization, and documentation +updates. + +### Deprecation Notices + +**A future version of Thrust will remove support for CUDA Dynamic Parallelism +(CDP).** + +This will only affect calls to Thrust algorithms made from CUDA device-side code +that currently launches a kernel; such calls will instead execute sequentially +on the calling GPU thread instead of launching a device-wide kernel. + +### Bug Fixes + +- NVIDIA/thrust#1507: Allow `thrust::sequence` to work with non-numeric types. + Thanks to Ben Jude (@bjude) for this contribution. +- NVIDIA/thrust#1509: Avoid macro collision when calling `max()` on MSVC. Thanks + to Thomas (@tomintheshell) for this contribution. +- NVIDIA/thrust#1514: Initialize all members in `counting_iterator`'s default + constructor. +- NVIDIA/thrust#1518: Fix `std::allocator_traits` on MSVC + C++17. +- NVIDIA/thrust#1530: Fix several `-Wconversion` warnings. Thanks to Matt + Stack (@matt-stack) for this contribution. +- NVIDIA/thrust#1539: Fixed typo in `thrust::for_each` documentation. Thanks to + Salman (@untamedImpala) for this contribution. +- NVIDIA/thrust#1548: Avoid name collision with `B0` macro in termios.h system + header. Thanks to Philip Deegan (@PhilipDeegan) for this contribution. + +## Thrust 1.14.0 (NVIDIA HPC SDK 21.9) + +Thrust 1.14.0 is a major release accompanying the NVIDIA HPC SDK 21.9. + +This release adds the ability to wrap the `thrust::` namespace in an external +namespace, providing a workaround for a variety of shared library linking +issues. Thrust also learned to detect when CUB's symbols are in a wrapped +namespace and properly import them. To enable this feature, use +`#define THRUST_CUB_WRAPPED_NAMESPACE foo` to wrap both Thrust and CUB in the +`foo::` namespace. See `thrust/detail/config/namespace.h` for details and more +namespace options. + +Several bugfixes are also included: The `tuple_size` and `tuple_element` helpers +now support cv-qualified types. `scan_by_key` uses less memory. +`thrust::iterator_traits` is better integrated with `std::iterator_traits`. +See below for more details and references. + +### Breaking Changes + +- Thrust 1.14.0 included a change that aliased the `cub` namespace + to `thrust::cub`. This has caused issues with ambiguous namespaces for + projects that declare `using namespace thrust;` from the global namespace. We + recommend against this practice. + +### New Features + +- NVIDIA/thrust#1464: Add preprocessor hooks that allow `thrust::` to be wrapped + in an external namespace, and support cases when CUB is wrapped in an external + namespace. + +### Bug Fixes + +- NVIDIA/thrust#1457: Support cv-qualified types in `thrust::tuple_size` and + `thrust::tuple_element`. Thanks to Jake Hemstad for this contribution. +- NVIDIA/thrust#1471: Fixed excessive memory allocation in `scan_by_key`. Thanks + to Lilo Huang for this contribution. +- NVIDIA/thrust#1476: Removed dead code from the `expand` example. Thanks to + Lilo Huang for this contribution. +- NVIDIA/thrust#1488: Fixed the path to the installed CUB headers in the CMake + `find_package` configuration files. +- NVIDIA/thrust#1491: Fallback to `std::iterator_traits` when no + `thrust::iterator_traits` specialization exists for an iterator type. Thanks + to Divye Gala for this contribution. + +## Thrust 1.13.1 (CUDA Toolkit 11.5) + +Thrust 1.13.1 is a minor release accompanying the CUDA Toolkit 11.5. + +This release provides a new hook for embedding the `thrust::` namespace inside a +custom namespace. This is intended to work around various issues related to +linking multiple shared libraries that use Thrust. The existing `CUB_NS_PREFIX` +and `CUB_NS_POSTFIX` macros already provided this capability for CUB; this +update provides a simpler mechanism that is extended to and integrated with +Thrust. Simply define `THRUST_CUB_WRAPPED_NAMESPACE` to a namespace name, and +both `thrust::` and `cub::` will be placed inside the new namespace. Using +different wrapped namespaces for each shared library will prevent issues like +those reported in NVIDIA/thrust#1401. + +### New Features + +- NVIDIA/thrust#1464: Add `THRUST_CUB_WRAPPED_NAMESPACE` hooks. + +### Bug Fixes + +- NVIDIA/thrust#1488: Fix path to installed CUB in Thrust's CMake config files. + +## Thrust 1.13.0 (NVIDIA HPC SDK 21.7) + +Thrust 1.13.0 is the major release accompanying the NVIDIA HPC SDK 21.7 release. +Notable changes include `bfloat16` radix sort support (via `thrust::sort`) and + memory handling fixes in the `reserve` method of Thrust's vectors. +The `CONTRIBUTING.md` file has been expanded to include instructions for + building CUB as a component of Thrust, and API documentation now refers to + [cppreference](https://cppreference.com) instead of SGI's old STL reference. + +### Breaking Changes + +- NVIDIA/thrust#1459: Remove deprecated aliases `thrust::host_space_tag` and + `thrust::device_space_tag`. Use the equivalent `thrust::host_system_tag` and + `thrust::device_system_tag` instead. + +### New Features + +- NVIDIA/cub#306: Add radix-sort support for `bfloat16` in `thrust::sort`. + Thanks to Xiang Gao (@zasdfgbnm) for this contribution. +- NVIDIA/thrust#1423: `thrust::transform_iterator` now supports non-copyable + types. Thanks to Jake Hemstad (@jrhemstad) for this contribution. +- NVIDIA/thrust#1459: Introduce a new `THRUST_IGNORE_DEPRECATED_API` macro that + disables deprecation warnings on Thrust and CUB APIs. + +### Bug Fixes + +- NVIDIA/cub#277: Fixed sanitizer warnings when `thrust::sort` calls + into `cub::DeviceRadixSort`. Thanks to Andy Adinets (@canonizer) for this + contribution. +- NVIDIA/thrust#1442: Reduce extraneous comparisons in `thrust::sort`'s merge + sort implementation. +- NVIDIA/thrust#1447: Fix memory leak and avoid overallocation when + calling `reserve` on Thrust's vector containers. Thanks to Kai Germaschewski + (@germasch) for this contribution. + +### Other Enhancements + +- NVIDIA/thrust#1405: Update links to standard C++ documentations from sgi to + cppreference. Thanks to Muhammad Adeel Hussain (@AdeilH) for this + contribution. +- NVIDIA/thrust#1432: Updated build instructions in `CONTRIBUTING.md` to include + details on building CUB's test suite as part of Thrust. + +## Thrust 1.12.1 (CUDA Toolkit 11.4) + +Thrust 1.12.1 is a trivial patch release that slightly changes the phrasing of +a deprecation message. + +## Thrust 1.12.0 (NVIDIA HPC SDK 21.3) + +Thrust 1.12.0 is the major release accompanying the NVIDIA HPC SDK 21.3 + and the CUDA Toolkit 11.4. +It includes a new `thrust::universal_vector`, which holds data that is + accessible from both host and device. This allows users to easily leverage + CUDA's unified memory with Thrust. +New asynchronous `thrust::async:exclusive_scan` and `inclusive_scan` algorithms + have been added, and the synchronous versions of these have been updated to + use `cub::DeviceScan` directly. +CUB radix sort for floating point types is now stable when both +0.0 and -0.0 + are present in the input. This affects some usages of `thrust::sort` and + `thrust::stable_sort`. +Many compilation warnings and subtle overflow bugs were fixed in the device + algorithms, including a long-standing bug that returned invalid temporary + storage requirements when `num_items` was close to (but not + exceeding) `INT32_MAX`. +This release deprecates support for Clang < 7.0 and MSVC < 2019 (aka + 19.20/16.0/14.20). + +### Breaking Changes + +- NVIDIA/thrust#1372: Deprecate Clang < 7 and MSVC < 2019. +- NVIDIA/thrust#1376: Standardize `thrust::scan_by_key` functors / accumulator + types. + This may change the results from `scan_by_key` when input, output, and + initial value types are not the same type. + +### New Features + +- NVIDIA/thrust#1251: Add two new `thrust::async::` algorithms: `inclusive_scan` + and `exclusive_scan`. +- NVIDIA/thrust#1334: Add `thrust::universal_vector`, `universal_ptr`, + and `universal_allocator`. + +### Bug Fixes + +- NVIDIA/thrust#1347: Qualify calls to `make_reverse_iterator`. +- NVIDIA/thrust#1359: Enable stricter warning flags. This fixes several + outstanding issues: + - NVIDIA/cub#221: Overflow in `temp_storage_bytes` when `num_items` close to + (but not over) `INT32_MAX`. + - NVIDIA/cub#228: CUB uses non-standard C++ extensions that break strict + compilers. + - NVIDIA/cub#257: Warning when compiling `GridEvenShare` with unsigned + offsets. + - NVIDIA/thrust#974: Conversion warnings in `thrust::transform_reduce`. + - NVIDIA/thrust#1091: Conversion warnings in `thrust::counting_iterator`. +- NVIDIA/thrust#1373: Fix compilation error when a standard library type is + wrapped in `thrust::optional`. + Thanks to Vukasin Milovanovic for this contribution. +- NVIDIA/thrust#1388: Fix `signbit(double)` implementation on MSVC. +- NVIDIA/thrust#1389: Support building Thrust tests without CUDA enabled. + +### Other Enhancements + +- NVIDIA/thrust#1304: Use `cub::DeviceScan` to implement + `thrust::exclusive_scan` and `thrust::inclusive_scan`. +- NVIDIA/thrust#1362, NVIDIA/thrust#1370: Update smoke test naming. +- NVIDIA/thrust#1380: Fix typos in `set_operation` documentation. + Thanks to Hongyu Cai for this contribution. +- NVIDIA/thrust#1383: Include FreeBSD license in LICENSE.md for + `thrust::complex` implementation. +- NVIDIA/thrust#1384: Add missing precondition to `thrust::gather` + documentation. + +## Thrust 1.11.0 (CUDA Toolkit 11.3) + +Thrust 1.11.0 is a major release providing bugfixes and performance + enhancements. +It includes a new sort algorithm that provides up to 2x more performance + from `thrust::sort` when used with certain key types and hardware. +The new `thrust::shuffle` algorithm has been tweaked to improve the randomness + of the output. +Our CMake package and build system continue to see improvements with + better `add_subdirectory` support, installation rules, status messages, and + other features that make Thrust easier to use from CMake projects. +The release includes several other bugfixes and modernizations, and received + updates from 12 contributors. + +### New Features + +- NVIDIA/cub#204: New implementation for `thrust::sort` on CUDA when using + 32/64-bit numeric keys on Pascal and up (SM60+). + This improved radix sort algorithm provides up to 2x more performance. + Thanks for Andy Adinets for this contribution. +- NVIDIA/thrust#1310, NVIDIA/thrust#1312: Various tuple-related APIs have been + updated to use variadic templates. + Thanks for Andrew Corrigan for these contributions. +- NVIDIA/thrust#1297: Optionally add install rules when included with + CMake's `add_subdirectory`. + Thanks to Kai Germaschewski for this contribution. + +### Bug Fixes + +- NVIDIA/thrust#1309: Fix `thrust::shuffle` to produce better quality random + distributions. + Thanks to Rory Mitchell and Daniel Stokes for this contribution. +- NVIDIA/thrust#1337: Fix compile-time regression in `transform_inclusive_scan` + and `transform_exclusive_scan`. +- NVIDIA/thrust#1306: Fix binary search `middle` calculation to avoid overflows. + Thanks to Richard Barnes for this contribution. +- NVIDIA/thrust#1314: Use `size_t` for the index type parameter + in `thrust::tuple_element`. + Thanks to Andrew Corrigan for this contribution. +- NVIDIA/thrust#1329: Fix runtime error when copying an empty + `thrust::device_vector` in MSVC Debug builds. + Thanks to Ben Jude for this contribution. +- NVIDIA/thrust#1323: Fix and add test for cmake package install rules. + Thanks for Keith Kraus and Kai Germaschewski for testing and discussion. +- NVIDIA/thrust#1338: Fix GCC version checks in `thrust::detail::is_pod` + implementation. + Thanks to Anatoliy Tomilov for this contribution. +- NVIDIA/thrust#1289: Partial fixes for Clang 10 as host compiler. + Filed an NVCC bug that will be fixed in a future version of the CUDA Toolkit + (NVBug 3136307). +- NVIDIA/thrust#1272: Fix ambiguous `iter_swap` call when + using `thrust::partition` with STL containers. + Thanks to Isaac Deutsch for this contribution. +- NVIDIA/thrust#1281: Update our bundled `FindTBB.cmake` module to support + latest MSVC. +- NVIDIA/thrust#1298: Use semantic versioning rules for our CMake package's + compatibility checks. + Thanks to Kai Germaschewski for this contribution. +- NVIDIA/thrust#1300: Use `FindPackageHandleStandardArgs` to print standard + status messages when our CMake package is found. + Thanks to Kai Germaschewski for this contribution. +- NVIDIA/thrust#1320: Use feature-testing instead of a language dialect check + for `thrust::remove_cvref`. + Thanks to Andrew Corrigan for this contribution. +- NVIDIA/thrust#1319: Suppress GPU deprecation warnings. + +### Other Enhancements + +- NVIDIA/cub#213: Removed some tuning policies for unsupported hardware (` + specialization. + - The `thrust::intermediate_type_from_function_and_iterators` helper is no + longer needed and has been removed. +- NVIDIA/thrust#1255: Always use `cudaStreamSynchronize` instead of + `cudaDeviceSynchronize` if the execution policy has a stream attached to it. + Thanks to Rong Ou for this contribution. +- NVIDIA/thrust#1201: Tests for correct handling of legacy and per-thread + default streams. + Thanks to Rong Ou for this contribution. + +### Bug Fixes + +- NVIDIA/thrust#1260: Fix `thrust::transform_inclusive_scan` with heterogeneous + types. + Thanks to Rong Ou for this contribution. +- NVIDIA/thrust#1258, NVC++ FS #28463: Ensure the CUDA radix sort backend + synchronizes before returning; otherwise, copies from temporary storage will + race with destruction of said temporary storage. +- NVIDIA/thrust#1264: Evaluate `CUDA_CUB_RET_IF_FAIL` macro argument only once. + Thanks to Jason Lowe for this contribution. +- NVIDIA/thrust#1262: Add missing `` header. +- NVIDIA/thrust#1250: Restore some `THRUST_DECLTYPE_RETURNS` macros in async + test implementations. +- NVIDIA/thrust#1249: Use `std::iota` in `CUDATestDriver::target_devices`. + Thanks to Michael Francis for this contribution. +- NVIDIA/thrust#1244: Check for macro collisions with system headers during + header testing. +- NVIDIA/thrust#1224: Remove unnecessary SFINAE contexts from asynchronous + algorithms. +- NVIDIA/thrust#1190: Make `out_of_memory_recovery` test trigger faster. +- NVIDIA/thrust#1187: Elminate superfluous iterators specific to the CUDA + backend. +- NVIDIA/thrust#1181: Various fixes for GoUDA. + Thanks to Andrei Tchouprakov for this contribution. +- NVIDIA/thrust#1178, NVIDIA/thrust#1229: Use transparent functionals in + placeholder expressions, fixing issues with `thrust::device_reference` and + placeholder expressions and `thrust::find` with asymmetric equality + operators. +- NVIDIA/thrust#1153: Switch to placement new instead of assignment to + construct items in uninitialized memory. + Thanks to Hugh Winkler for this contribution. +- NVIDIA/thrust#1050: Fix compilation of asynchronous algorithms when RDC is + enabled. +- NVIDIA/thrust#1042: Correct return type of + `thrust::detail::predicate_to_integral` from `bool` to `IntegralType`. + Thanks to Andreas Hehn for this contribution. +- NVIDIA/thrust#1009: Avoid returning uninitialized allocators. + Thanks to Zhihao Yuan for this contribution. +- NVIDIA/thrust#990: Add missing `` include to + ``. + Thanks to Robert Maynard for this contribution. +- NVIDIA/thrust#966: Fix spurious MSVC conversion with loss of data warning in + sort algorithms. + Thanks to Zhihao Yuan for this contribution. +- Add more metadata to mock specializations for testing iterator in + `testing/copy.cu`. +- Add missing include to shuffle unit test. +- Specialize `thrust::wrapped_function` for `void` return types because MSVC is + not a fan of the pattern `return static_cast(expr);`. +- Replace deprecated `tbb/tbb_thread.h` with ``. +- Fix overcounting of initial value in TBB scans. +- Use `thrust::advance` instead of `+=` for generic iterators. +- Wrap the OMP flags in `-Xcompiler` for NVCC +- Extend `ASSERT_STATIC_ASSERT` skip for the OMP backend. +- Add missing header caught by `tbb.cuda` configs. +- Fix "unsafe API" warnings in examples on MSVC: `s/fopen/fstream/` +- Various C++17 fixes. + +## Thrust 1.9.10-1 (NVIDIA HPC SDK 20.7, CUDA Toolkit 11.1) + +Thrust 1.9.10-1 is the minor release accompanying the NVIDIA HPC SDK 20.7 release + and the CUDA Toolkit 11.1 release. + +### Bug Fixes + +- #1214, NVBug 200619442: Stop using `std::allocator` APIs deprecated in C++17. +- #1216, NVBug 200540293: Make `thrust::optional` work with Clang when used + with older libstdc++. +- #1207, NVBug 200618218: Don't force C++14 with older compilers that don't + support it. +- #1218: Wrap includes of `` and `` to avoid circular + inclusion with NVC++. + +## Thrust 1.9.10 (NVIDIA HPC SDK 20.5) + +Thrust 1.9.10 is the release accompanying the NVIDIA HPC SDK 20.5 release. +It adds CMake support for compilation with NVC++ and a number of minor bug fixes + for NVC++. +It also adds CMake `find_package` support, which replaces the broken 3rd-party + legacy `FindThrust.cmake` script. +C++03, C++11, GCC < 5, Clang < 6, and MSVC < 2017 are now deprecated. +Starting with the upcoming 1.10.0 release, C++03 support will be dropped + entirely. + +### Breaking Changes + +- #1082: Thrust now checks that it is compatible with the version of CUB found + in your include path, generating an error if it is not. + If you are using your own version of CUB, it may be too old. + It is recommended to simply delete your own version of CUB and use the + version of CUB that comes with Thrust. +- #1089: C++03 and C++11 are deprecated. + Using these dialects will generate a compile-time warning. + These warnings can be suppressed by defining + `THRUST_IGNORE_DEPRECATED_CPP_DIALECT` (to suppress C++03 and C++11 + deprecation warnings) or `THRUST_IGNORE_DEPRECATED_CPP11` (to suppress C++11 + deprecation warnings). + Suppression is only a short term solution. + We will be dropping support for C++03 in the 1.10.0 release and C++11 in the + near future. +- #1089: GCC < 5, Clang < 6, and MSVC < 2017 are deprecated. + Using these compilers will generate a compile-time warning. + These warnings can be suppressed by defining + `THRUST_IGNORE_DEPRECATED_COMPILER`. + Suppression is only a short term solution. + We will be dropping support for these compilers in the near future. + +### New Features + +- #1130: CMake `find_package` support. + This is significant because there is a legacy `FindThrust.cmake` script + authored by a third party in widespread use in the community which has a + bug in how it parses Thrust version numbers which will cause it to + incorrectly parse 1.9.10. + This script only handles the first digit of each part of the Thrust version + number correctly: for example, Thrust 17.17.17 would be interpreted as + Thrust 1.1.1701717. + You can find directions for using the new CMake `find_package` support and + migrating away from the legacy `FindThrust.cmake` [here](https://github.com/NVIDIA/thrust/blob/main/thrust/cmake/README.md) +- #1129: Added `thrust::detail::single_device_tls_caching_allocator`, a + convenient way to get an MR caching allocator for device memory, which is + used by NVC++. + +### Other Enhancements + +- #1129: Refactored RDC handling in CMake to be a global option and not create + two targets for each example and test. + +### Bug Fixes + +- #1129: Fix the legacy `thrust::return_temporary_buffer` API to support + passing a size. + This was necessary to enable usage of Thrust caching MR allocators with + synchronous Thrust algorithms. + This change has allowed NVC++'s C++17 Parallel Algorithms implementation to + switch to use Thrust caching MR allocators for device temporary storage, + which gives a 2x speedup on large multi-GPU systems such as V100 and A100 + DGX where `cudaMalloc` is very slow. +- #1128: Respect `CUDA_API_PER_THREAD_DEFAULT_STREAM`. + Thanks to Rong Ou for this contribution. +- #1131: Fix the one-policy overload of `thrust::async::copy` to not copy the + policy, resolving use-afer-move issues. +- #1145: When cleaning up type names in `unittest::base_class_name`, only call + `std::string::replace` if we found the substring we are looking to replace. +- #1139: Don't use `cxx::__demangle` in NVC++. +- #1102: Don't use `thrust::detail::normal_distribution_nvcc` for Feta because + it uses `erfcinv`, a non-standard function that Feta doesn't have. + +## Thrust 1.9.9 (CUDA Toolkit 11.0) + +Thrust 1.9.9 adds support for NVC++, which uses Thrust to implement + GPU-accelerated C++17 Parallel Algorithms. +`thrust::zip_function` and `thrust::shuffle` were also added. +C++03, C++11, GCC < 5, Clang < 6, and MSVC < 2017 are now deprecated. +Starting with the upcoming 1.10.0 release, C++03 support will be dropped + entirely. +All other deprecated platforms will be dropped in the near future. + +### Breaking Changes + +- #1082: Thrust now checks that it is compatible with the version of CUB found + in your include path, generating an error if it is not. + If you are using your own version of CUB, it may be too old. + It is recommended to simply delete your own version of CUB and use the + version of CUB that comes with Thrust. +- #1089: C++03 and C++11 are deprecated. + Using these dialects will generate a compile-time warning. + These warnings can be suppressed by defining + `THRUST_IGNORE_DEPRECATED_CPP_DIALECT` (to suppress C++03 and C++11 + deprecation warnings) or `THRUST_IGNORE_DEPRECATED_CPP_11` (to suppress C++11 + deprecation warnings). + Suppression is only a short term solution. + We will be dropping support for C++03 in the 1.10.0 release and C++11 in the + near future. +- #1089: GCC < 5, Clang < 6, and MSVC < 2017 are deprecated. + Using these compilers will generate a compile-time warning. + These warnings can be suppressed by defining + `THRUST_IGNORE_DEPRECATED_COMPILER`. + Suppression is only a short term solution. + We will be dropping support for these compilers in the near future. + +### New Features + +- #1086: Support for NVC++ aka "Feta". + The most significant change is in how we use `__CUDA_ARCH__`. + Now, there are four macros that must be used: + - `THRUST_IS_DEVICE_CODE`, which should be used in an `if` statement around + device-only code. + - `THRUST_INCLUDE_DEVICE_CODE`, which should be used in an `#if` preprocessor + directive inside of the `if` statement mentioned in the prior bullet. + - `THRUST_IS_HOST_CODE`, which should be used in an `if` statement around + host-only code. + - `THRUST_INCLUDE_HOST_CODE`, which should be used in an `#if` preprocessor + directive inside of the `if` statement mentioned in the prior bullet. +- #1085: `thrust::shuffle`. + Thanks to Rory Mitchell for this contribution. +- #1029: `thrust::zip_function`, a facility for zipping functions that take N + parameters instead of a tuple of N parameters as `thrust::zip_iterator` + does. + Thanks to Ben Jude for this contribution. +- #1068: `thrust::system::cuda::managed_memory_pointer`, a universal memory + strongly typed pointer compatible with the ISO C++ Standard Library. + +### Other Enhancements + +- #1029: Thrust is now built and tested with NVCC warnings treated as errors. +- #1029: MSVC C++11 support. +- #1029: `THRUST_DEPRECATED` abstraction for generating compile-time + deprecation warning messages. +- #1029: `thrust::pointer::pointer_to(reference)`. +- #1070: Unit test for `thrust::inclusive_scan` with a user defined types. + Thanks to Conor Hoekstra for this contribution. + +### Bug Fixes + +- #1088: Allow `thrust::replace` to take functions that have non-`const` + `operator()`. +- #1094: Add missing `constexpr` to `par_t` constructors. + Thanks to Patrick Stotko for this contribution. +- #1077: Remove `__device__` from CUDA MR-based device allocators to fix + obscure "host function called from host device function" warning that occurs + when you use the new Thrust MR-based allocators. +- #1029: Remove inconsistently-used `THRUST_BEGIN`/`END_NS` macros. +- #1029: Fix C++ dialect detection on newer MSVC. +- #1029 Use `_Pragma`/`__pragma` instead of `#pragma` in macros. +- #1029: Replace raw `__cplusplus` checks with the appropriate Thrust macros. +- #1105: Add a missing `` include. +- #1103: Fix regression of `thrust::detail::temporary_allocator` with non-CUDA + back ends. +- #1111: Use Thrust's random number engine instead of `std::`s in device code. +- #1108: Get rid of a GCC 9 warning about deprecated generation of copy ctors. + +## Thrust 1.9.8-1 (NVIDIA HPC SDK 20.3) + +Thrust 1.9.8-1 is a variant of 1.9.8 accompanying the NVIDIA HPC SDK 20.3 + release. +It contains modifications necessary to serve as the implementation of NVC++'s + GPU-accelerated C++17 Parallel Algorithms when using the CUDA Toolkit 11.0 + release. + +## Thrust 1.9.8 (CUDA Toolkit 11.0 Early Access) + +Thrust 1.9.8, which is included in the CUDA Toolkit 11.0 release, removes + Thrust's internal derivative of CUB, upstreams all relevant changes too CUB, + and adds CUB as a Git submodule. +It will now be necessary to do `git clone --recursive` when checking out + Thrust, and to update the CUB submodule when pulling in new Thrust changes. +Additionally, CUB is now included as a first class citizen in the CUDA toolkit. +Thrust 1.9.8 also fixes bugs preventing most Thrust algorithms from working + with more than `2^31-1` elements. +Now, `thrust::reduce`, `thrust::*_scan`, and related algorithms (aka most of + Thrust) work with large element counts. + +### Breaking Changes + +- Thrust will now use the version of CUB in your include path instead of its own + internal copy. + If you are using your own version of CUB, it may be older and incompatible + with Thrust. + It is recommended to simply delete your own version of CUB and use the + version of CUB that comes with Thrust. + +### Other Enhancements + +- Refactor Thrust and CUB to support 64-bit indices in most algorithms. + In most cases, Thrust now selects between kernels that use 32-bit indices and + 64-bit indices at runtime depending on the size of the input. + This means large element counts work, but small element counts do not have to + pay for the register usage of 64-bit indices if they are not needed. + Now, `thrust::reduce`, `thrust::*_scan`, and related algorithms (aka most of + Thrust) work with more than `2^31-1` elements. + Notably, `thrust::sort` is still limited to less than `2^31-1` elements. +- CUB is now a submodule and the internal copy of CUB has been removed. +- #1051: Stop specifying the `__launch_bounds__` minimum blocks parameter + because it messes up register allocation and increases register pressure, + and we don't actually know at compile time how many blocks we will use + (aside from single tile kernels). + +### Bug Fixes + +- #1020: After making a CUDA API call, always clear the global CUDA error state + by calling `cudaGetLastError`. +- #1021: Avoid calling destroy in the destructor of a Thrust vector if the + vector is empty. +- #1046: Actually throw `thrust::bad_alloc` when `thrust::system::cuda::malloc` + fails instead of just constructing a temporary and doing nothing with it. +- Add missing copy constructor or copy assignment operator to all classes that + GCC 9's `-Wdeprecated-copy` complains about +- Add missing move operations to `thrust::system::cuda::vector`. +- #1015: Check that the backend is CUDA before using CUDA-specifics in + `thrust::detail::temporary_allocator`. + Thanks to Hugh Winkler for this contribution. +- #1055: More correctly detect the presence of aligned/sized `new`/`delete`. +- #1043: Fix ill-formed specialization of `thrust::system::is_error_code_enum` + for `thrust::event_errc`. + Thanks to Toru Niina for this contribution. +- #1027: Add tests for `thrust::tuple_for_each` and `thrust::tuple_subset`. + Thanks to Ben Jude for this contribution. +- #1027: Use correct macro in `thrust::tuple_for_each`. + Thanks to Ben Jude for this contribution. +- #1026: Use correct MSVC version formatting in CMake. + Thanks to Ben Jude for this contribution. +- Workaround an NVCC issue with type aliases with template template arguments + containing a parameter pack. +- Remove unused functions from the CUDA backend which call slow CUDA attribute + query APIs. +- Replace `CUB_RUNTIME_FUNCTION` with `THRUST_RUNTIME_FUNCTION`. +- Correct typo in `thrust::transform` documentation. + Thanks to Eden Yefet for this contribution. + +### Known Issues + +- `thrust::sort` remains limited to `2^31-1` elements for now. + +## Thrust 1.9.7-1 (CUDA Toolkit 10.2 for Tegra) + +Thrust 1.9.7-1 is a minor release accompanying the CUDA Toolkit 10.2 release + for Tegra. +It is nearly identical to 1.9.7. + +### Bug Fixes + +- Remove support for GCC's broken nodiscard-like attribute. + +## Thrust 1.9.7 (CUDA Toolkit 10.2) + +Thrust 1.9.7 is a minor release accompanying the CUDA Toolkit 10.2 release. +Unfortunately, although the version and patch numbers are identical, one bug + fix present in Thrust 1.9.7 (NVBug 2646034: Fix incorrect dependency handling + for stream acquisition in `thrust::future`) was not included in the CUDA + Toolkit 10.2 preview release for AArch64 SBSA. +The tag `cuda-10.2aarch64sbsa` contains the exact version of Thrust present + in the CUDA Toolkit 10.2 preview release for AArch64 SBSA. + +### Bug Fixes + +- #967, NVBug 2448170: Fix the CUDA backend `thrust::for_each` so that it + supports large input sizes with 64-bit indices. +- NVBug 2646034: Fix incorrect dependency handling for stream acquisition in + `thrust::future`. + - Not present in the CUDA Toolkit 10.2 preview release for AArch64 SBSA. +- #968, NVBug 2612102: Fix the `thrust::mr::polymorphic_adaptor` to actually + use its template parameter. + +## Thrust 1.9.6-1 (NVIDIA HPC SDK 20.3) + +Thrust 1.9.6-1 is a variant of 1.9.6 accompanying the NVIDIA HPC SDK 20.3 + release. +It contains modifications necessary to serve as the implementation of NVC++'s + GPU-accelerated C++17 Parallel Algorithms when using the CUDA Toolkit 10.1 + Update 2 release. + +## Thrust 1.9.6 (CUDA Toolkit 10.1 Update 2) + +Thrust 1.9.6 is a minor release accompanying the CUDA Toolkit 10.1 Update 2 + release. + +### Bug Fixes + +- NVBug 2509847: Inconsistent alignment of `thrust::complex` +- NVBug 2586774: Compilation failure with Clang + older libstdc++ that doesn't + have `std::is_trivially_copyable` +- NVBug 200488234: CUDA header files contain Unicode characters which leads + compiling errors on Windows +- #949, #973, NVBug 2422333, NVBug 2522259, NVBug 2528822: + `thrust::detail::aligned_reinterpret_cast` must be annotated with + `__host__ __device__`. +- NVBug 2599629: Missing include in the OpenMP sort implementation +- NVBug 200513211: Truncation warning in test code under VC142 + +## Thrust 1.9.5 (CUDA Toolkit 10.1 Update 1) + +Thrust 1.9.5 is a minor release accompanying the CUDA Toolkit 10.1 Update 1 + release. + +### Bug Fixes + +- NVBug 2502854: Fixed assignment of + `thrust::device_vector>` between host and device. + +## Thrust 1.9.4 (CUDA Toolkit 10.1) + +Thrust 1.9.4 adds asynchronous interfaces for parallel algorithms, a new + allocator system including caching allocators and unified memory support, as + well as a variety of other enhancements, mostly related to + C++11/C++14/C++17/C++20 support. +The new asynchronous algorithms in the `thrust::async` namespace return + `thrust::event` or `thrust::future` objects, which can be waited upon to + synchronize with the completion of the parallel operation. + +### Breaking Changes + +Synchronous Thrust algorithms now block until all of their operations have + completed. +Use the new asynchronous Thrust algorithms for non-blocking behavior. + +### New Features + +- `thrust::event` and `thrust::future`, uniquely-owned asynchronous handles + consisting of a state (ready or not ready), content (some value; for + `thrust::future` only), and an optional set of objects that should be + destroyed only when the future's value is ready and has been consumed. + - The design is loosely based on C++11's `std::future`. + - They can be `.wait`'d on, and the value of a future can be waited on and + retrieved with `.get` or `.extract`. + - Multiple `thrust::event`s and `thrust::future`s can be combined with + `thrust::when_all`. + - `thrust::future`s can be converted to `thrust::event`s. + - Currently, these primitives are only implemented for the CUDA backend and + are C++11 only. +- New asynchronous algorithms that return `thrust::event`/`thrust::future`s, + implemented as C++20 range style customization points: + - `thrust::async::reduce`. + - `thrust::async::reduce_into`, which takes a target location to store the + reduction result into. + - `thrust::async::copy`, including a two-policy overload that allows + explicit cross system copies which execution policy properties can be + attached to. + - `thrust::async::transform`. + - `thrust::async::for_each`. + - `thrust::async::stable_sort`. + - `thrust::async::sort`. + - By default the asynchronous algorithms use the new caching allocators. + Deallocation of temporary storage is deferred until the destruction of + the returned `thrust::future`. The content of `thrust::future`s is + stored in either device or universal memory and transferred to the host + only upon request to prevent unnecessary data migration. + - Asynchronous algorithms are currently only implemented for the CUDA + system and are C++11 only. +- `exec.after(f, g, ...)`, a new execution policy method that takes a set of + `thrust::event`/`thrust::future`s and returns an execution policy that + operations on that execution policy should depend upon. +- New logic and mindset for the type requirements for cross-system sequence + copies (currently only used by `thrust::async::copy`), based on: + - `thrust::is_contiguous_iterator` and `THRUST_PROCLAIM_CONTIGUOUS_ITERATOR` + for detecting/indicating that an iterator points to contiguous storage. + - `thrust::is_trivially_relocatable` and + `THRUST_PROCLAIM_TRIVIALLY_RELOCATABLE` for detecting/indicating that a + type is `memcpy`able (based on principles from + [P1144](https://wg21.link/P1144)). + - The new approach reduces buffering, increases performance, and increases + correctness. + - The fast path is now enabled when copying CUDA `__half` and vector types with + `thrust::async::copy`. +- All Thrust synchronous algorithms for the CUDA backend now actually + synchronize. Previously, any algorithm that did not allocate temporary + storage (counterexample: `thrust::sort`) and did not have a + computation-dependent result (counterexample: `thrust::reduce`) would + actually be launched asynchronously. Additionally, synchronous algorithms + that allocated temporary storage would become asynchronous if a custom + allocator was supplied that did not synchronize on allocation/deallocation, + unlike `cudaMalloc`/`cudaFree`. So, now `thrust::for_each`, + `thrust::transform`, `thrust::sort`, etc are truly synchronous. In some + cases this may be a performance regression; if you need asynchrony, use the + new asynchronous algorithms. +- Thrust's allocator framework has been rewritten. It now uses a memory + resource system, similar to C++17's `std::pmr` but supporting static + polymorphism. Memory resources are objects that allocate untyped storage and + allocators are cheap handles to memory resources in this new model. The new + facilities live in ``. + - `thrust::mr::memory_resource`, the memory resource base class, + which takes a (possibly tagged) pointer to `void` type as a parameter. + - `thrust::mr::allocator`, an allocator backed by a memory + resource object. + - `thrust::mr::polymorphic_adaptor_resource`, a type-erased memory + resource adaptor. + - `thrust::mr::polymorphic_allocator`, a C++17-style polymorphic allocator + backed by a type-erased memory resource object. + - New tunable C++17-style caching memory resources, + `thrust::mr::(disjoint_)?(un)?synchronized_pool_resource`, designed to + cache both small object allocations and large repetitive temporary + allocations. The disjoint variants use separate storage for management of + the pool, which is necessary if the memory being allocated cannot be + accessed on the host (e.g. device memory). + - System-specific allocators were rewritten to use the new memory resource + framework. + - New `thrust::device_memory_resource` for allocating device memory. + - New `thrust::universal_memory_resource` for allocating memory that can be + accessed from both the host and device (e.g. `cudaMallocManaged`). + - New `thrust::universal_host_pinned_memory_resource` for allocating memory + that can be accessed from the host and the device but always resides in + host memory (e.g. `cudaMallocHost`). + - `thrust::get_per_device_resource` and `thrust::per_device_allocator`, which + lazily create and retrieve a per-device singleton memory resource. + - Rebinding mechanisms (`rebind_traits` and `rebind_alloc`) for + `thrust::allocator_traits`. + - `thrust::device_make_unique`, a factory function for creating a + `std::unique_ptr` to a newly allocated object in device memory. + - ``, a C++11 implementation of the C++17 + uninitialized memory algorithms. + - `thrust::allocate_unique` and friends, based on the proposed C++23 + [`std::allocate_unique`](https://wg21.link/P0211). +- New type traits and metaprogramming facilities. Type traits are slowly being + migrated out of `thrust::detail::` and ``; their new home + will be `thrust::` and ``. + - `thrust::is_execution_policy`. + - `thrust::is_operator_less_or_greater_function_object`, which detects + `thrust::less`, `thrust::greater`, `std::less`, and `std::greater`. + - `thrust::is_operator_plus_function_object``, which detects `thrust::plus` + and `std::plus`. + - `thrust::remove_cvref(_t)?`, a C++11 implementation of C++20's + `thrust::remove_cvref(_t)?`. + - `thrust::void_t`, and various other new type traits. + - `thrust::integer_sequence` and friends, a C++11 implementation of C++20's + `std::integer_sequence` + - `thrust::conjunction`, `thrust::disjunction`, and `thrust::disjunction`, a + C++11 implementation of C++17's logical metafunctions. + - Some Thrust type traits (such as `thrust::is_constructible`) have been + redefined in terms of C++11's type traits when they are available. +- ``, new `std::tuple` algorithms: + - `thrust::tuple_transform`. + - `thrust::tuple_for_each`. + - `thrust::tuple_subset`. +- Miscellaneous new `std::`-like facilities: + - `thrust::optional`, a C++11 implementation of C++17's `std::optional`. + - `thrust::addressof`, an implementation of C++11's `std::addressof`. + - `thrust::next` and `thrust::prev`, an implementation of C++11's `std::next` + and `std::prev`. + - `thrust::square`, a `` style unary function object that + multiplies its argument by itself. + - `` and `thrust::numeric_limits`, a customized version of + `` and `std::numeric_limits`. +- ``, new general purpose preprocessor facilities: + - `THRUST_PP_CAT[2-5]`, concatenates two to five tokens. + - `THRUST_PP_EXPAND(_ARGS)?`, performs double expansion. + - `THRUST_PP_ARITY` and `THRUST_PP_DISPATCH`, tools for macro overloading. + - `THRUST_PP_BOOL`, boolean conversion. + - `THRUST_PP_INC` and `THRUST_PP_DEC`, increment/decrement. + - `THRUST_PP_HEAD`, a variadic macro that expands to the first argument. + - `THRUST_PP_TAIL`, a variadic macro that expands to all its arguments after + the first. + - `THRUST_PP_IIF`, bitwise conditional. + - `THRUST_PP_COMMA_IF`, and `THRUST_PP_HAS_COMMA`, facilities for adding and + detecting comma tokens. + - `THRUST_PP_IS_VARIADIC_NULLARY`, returns true if called with a nullary + `__VA_ARGS__`. + - `THRUST_CURRENT_FUNCTION`, expands to the name of the current function. +- New C++11 compatibility macros: + - `THRUST_NODISCARD`, expands to `[[nodiscard]]` when available and the best + equivalent otherwise. + - `THRUST_CONSTEXPR`, expands to `constexpr` when available and the best + equivalent otherwise. + - `THRUST_OVERRIDE`, expands to `override` when available and the best + equivalent otherwise. + - `THRUST_DEFAULT`, expands to `= default;` when available and the best + equivalent otherwise. + - `THRUST_NOEXCEPT`, expands to `noexcept` when available and the best + equivalent otherwise. + - `THRUST_FINAL`, expands to `final` when available and the best equivalent + otherwise. + - `THRUST_INLINE_CONSTANT`, expands to `inline constexpr` when available and + the best equivalent otherwise. +- ``, new C++11-only type deduction helpers: + - `THRUST_DECLTYPE_RETURNS*`, expand to function definitions with suitable + conditional `noexcept` qualifiers and trailing return types. + - `THRUST_FWD(x)`, expands to `::std::forward(x)`. + - `THRUST_MVCAP`, expands to a lambda move capture. + - `THRUST_RETOF`, expands to a decltype computing the return type of an + invocable. +- New CMake build system. + +### New Examples + +- `mr_basic` demonstrates how to use the new memory resource allocator system. + +### Other Enhancements + +- Tagged pointer enhancements: + - New `thrust::pointer_traits` specialization for `void const*`. + - `nullptr` support to Thrust tagged pointers. + - New `explicit operator bool` for Thrust tagged pointers when using C++11 + for `std::unique_ptr` interoperability. + - Added `thrust::reinterpret_pointer_cast` and `thrust::static_pointer_cast` + for casting Thrust tagged pointers. +- Iterator enhancements: + - `thrust::iterator_system` is now SFINAE friendly. + - Removed cv qualifiers from iterator types when using + `thrust::iterator_system`. +- Static assert enhancements: + - New `THRUST_STATIC_ASSERT_MSG`, takes an optional string constant to be + used as the error message when possible. + - Update `THRUST_STATIC_ASSERT(_MSG)` to use C++11's `static_assert` when + it's available. + - Introduce a way to test for static assertions. +- Testing enhancements: + - Additional scalar and sequence types, including non-builtin types and + vectors with unified memory allocators, have been added to the list of + types used by generic unit tests. + - The generation of random input data has been improved to increase the range + of values used and catch more corner cases. + - New `unittest::truncate_to_max_representable` utility for avoiding the + generation of ranges that cannot be represented by the underlying element + type in generic unit test code. + - The test driver now synchronizes with CUDA devices and check for errors + after each test, when switching devices, and after each raw kernel launch. + - The `warningtester` uber header is now compiled with NVCC to avoid needing + to disable CUDA-specific code with the preprocessor. + - Fixed the unit test framework's `ASSERT_*` to print `char`s as `int`s. + - New `DECLARE_INTEGRAL_VARIABLE_UNITTEST` test declaration macro. + - New `DECLARE_VARIABLE_UNITTEST_WITH_TYPES_AND_NAME` test declaration macro. + - `thrust::system_error` in the CUDA backend now print out its `cudaError_t` + enumerator in addition to the diagnostic message. + - Stopped using conditionally signed types like `char`. + +### Bug Fixes + +- #897, NVBug 2062242: Fix compilation error when using `__device__` lambdas + with `thrust::reduce` on MSVC. +- #908, NVBug 2089386: Static assert that `thrust::generate`/`thrust::fill` + isn't operating on const iterators. +- #919 Fix compilation failure with `thrust::zip_iterator` and + `thrust::complex`. +- #924, NVBug 2096679, NVBug 2315990: Fix dispatch for the CUDA backend's + `thrust::reduce` to use two functions (one with the pragma for disabling + exec checks, one with `THRUST_RUNTIME_FUNCTION`) instead of one. This fixes + a regression with device compilation that started in CUDA Toolkit 9.2. +- #928, NVBug 2341455: Add missing `__host__ __device__` annotations to a + `thrust::complex::operator=` to satisfy GoUDA. +- NVBug 2094642: Make `thrust::vector_base::clear` not depend on the element + type being default constructible. +- NVBug 2289115: Remove flaky `simple_cuda_streams` example. +- NVBug 2328572: Add missing `thrust::device_vector` constructor that takes an + allocator parameter. +- NVBug 2455740: Update the `range_view` example to not use device-side launch. +- NVBug 2455943: Ensure that sized unit tests that use + `thrust::counting_iterator` perform proper truncation. +- NVBug 2455952: Refactor questionable `thrust::copy_if` unit tests. + +## Thrust 1.9.3 (CUDA Toolkit 10.0) + +Thrust 1.9.3 unifies and integrates CUDA Thrust and GitHub Thrust. + +### Bug Fixes + +- #725, #850, #855, #859, #860: Unify the `thrust::iter_swap` interface and fix + `thrust::device_reference` swapping. +- NVBug 2004663: Add a `data` method to `thrust::detail::temporary_array` and + refactor temporary memory allocation in the CUDA backend to be exception + and leak safe. +- #886, #894, #914: Various documentation typo fixes. +- #724: Provide `NVVMIR_LIBRARY_DIR` environment variable to NVCC. +- #878: Optimize `thrust::min/max_element` to only use + `thrust::detail::get_iterator_value` for non-numeric types. +- #899: Make `thrust::cuda::experimental::pinned_allocator`'s comparison + operators `const`. +- NVBug 2092152: Remove all includes of ``. +- #911: Fix default comparator element type for `thrust::merge_by_key`. + +### Acknowledgments + +- Thanks to Andrew Corrigan for contributing fixes for swapping interfaces. +- Thanks to Francisco Facioni for contributing optimizations for + `thrust::min/max_element`. + +## Thrust 1.9.2 (CUDA Toolkit 9.2) + +Thrust 1.9.2 brings a variety of performance enhancements, bug fixes and test + improvements. +CUB 1.7.5 was integrated, enhancing the performance of `thrust::sort` on + small data types and `thrust::reduce`. +Changes were applied to `complex` to optimize memory access. +Thrust now compiles with compiler warnings enabled and treated as errors. +Additionally, the unit test suite and framework was enhanced to increase + coverage. + +### Breaking Changes + +- The `fallback_allocator` example was removed, as it was buggy and difficult + to support. + +### New Features + +- ``, utilities for memory alignment: + - `thrust::aligned_reinterpret_cast`. + - `thrust::aligned_storage_size`, which computes the amount of storage needed + for an object of a particular size and alignment. + - `thrust::alignment_of`, a C++03 implementation of C++11's + `std::alignment_of`. + - `thrust::aligned_storage`, a C++03 implementation of C++11's + `std::aligned_storage`. + - `thrust::max_align_t`, a C++03 implementation of C++11's + `std::max_align_t`. + +### Bug Fixes + +- NVBug 200385527, NVBug 200385119, NVBug 200385113, NVBug 200349350, NVBug + 2058778: Various compiler warning issues. +- NVBug 200355591: `thrust::reduce` performance issues. +- NVBug 2053727: Fixed an ADL bug that caused user-supplied `allocate` to be + overlooked but `deallocate` to be called with GCC <= 4.3. +- NVBug 1777043: Fixed `thrust::complex` to work with `thrust::sequence`. + +## Thrust 1.9.1-2 (CUDA Toolkit 9.1) + +Thrust 1.9.1-2 integrates version 1.7.4 of CUB and introduces a new CUDA backend + for `thrust::reduce` based on CUB. + +### Bug Fixes + +- NVBug 1965743: Remove unnecessary static qualifiers. +- NVBug 1940974: Fix regression causing a compilation error when using + `thrust::merge_by_key` with `thrust::constant_iterator`s. +- NVBug 1904217: Allow callables that take non-const refs to be used with + `thrust::reduce` and `thrust::*_scan`. + +## Thrust 1.9.0-5 (CUDA Toolkit 9.0) + +Thrust 1.9.0-5 replaces the original CUDA backend (bulk) with a new one + written using CUB, a high performance CUDA collectives library. +This brings a substantial performance improvement to the CUDA backend across + the board. + +### Breaking Changes + +- Any code depending on CUDA backend implementation details will likely be + broken. + +### New Features + +- New CUDA backend based on CUB which delivers substantially higher performance. +- `thrust::transform_output_iterator`, a fancy iterator that applies a function + to the output before storing the result. + +### New Examples + +- `transform_output_iterator` demonstrates use of the new fancy iterator + `thrust::transform_output_iterator`. + +### Other Enhancements + +- When C++11 is enabled, functors do not have to inherit from + `thrust::(unary|binary)_function` anymore to be used with + `thrust::transform_iterator`. +- Added C++11 only move constructors and move assignment operators for + `thrust::detail::vector_base`-based classes, e.g. `thrust::host_vector`, + `thrust::device_vector`, and friends. + +### Bug Fixes + +- `sin(thrust::complex)` no longer has precision loss to float. + +### Acknowledgments + +- Thanks to Manuel Schiller for contributing a C++11 based enhancement + regarding the deduction of functor return types, improving the performance + of `thrust::unique` and implementing `thrust::transform_output_iterator`. +- Thanks to Thibault Notargiacomo for the implementation of move semantics for + the `thrust::vector_base`-based classes. +- Thanks to Duane Merrill for developing CUB and helping to integrate it into + Thrust's backend. + +## Thrust 1.8.3 (CUDA Toolkit 8.0) + +Thrust 1.8.3 is a small bug fix release. + +### New Examples + +- `range_view` demonstrates the use of a view (a non-owning wrapper for an + iterator range with a container-like interface). + +### Bug Fixes + +- `thrust::(min|max|minmax)_element` can now accept raw device pointers when + an explicit device execution policy is used. +- `thrust::clear` operations on vector types no longer requires the element + type to have a default constructor. + +## Thrust 1.8.2 (CUDA Toolkit 7.5) + +Thrust 1.8.2 is a small bug fix release. + +### Bug Fixes + +- Avoid warnings and errors concerning user functions called from + `__host__ __device__` functions. +- #632: Fix an error in `thrust::set_intersection_by_key` with the CUDA backend. +- #651: `thrust::copy` between host and device now accepts execution policies + with streams attached, i.e. `thrust::::cuda::par.on(stream)`. +- #664: `thrust::for_each` and algorithms based on it no longer ignore streams + attached to execution policys. + +### Known Issues + +- #628: `thrust::reduce_by_key` for the CUDA backend fails for Compute + Capability 5.0 devices. + +## Thrust 1.8.1 (CUDA Toolkit 7.0) + +Thrust 1.8.1 is a small bug fix release. + +### Bug Fixes + +- #615, #620: Fixed `thrust::for_each` and `thrust::reduce` to no longer fail on + large inputs. + +### Known Issues + +- #628: `thrust::reduce_by_key` for the CUDA backend fails for Compute + Capability 5.0 devices. + +## Thrust 1.8.0 + +Thrust 1.8.0 introduces support for algorithm invocation from CUDA device + code, support for CUDA streams, and algorithm performance improvements. +Users may now invoke Thrust algorithms from CUDA device code, providing a + parallel algorithms library to CUDA programmers authoring custom kernels, as + well as allowing Thrust programmers to nest their algorithm calls within + functors. +The `thrust::seq` execution policy allows users to require sequential algorithm + execution in the calling thread and makes a sequential algorithms library + available to individual CUDA threads. +The `.on(stream)` syntax allows users to request a CUDA stream for kernels + launched during algorithm execution. +Finally, new CUDA algorithm implementations provide substantial performance + improvements. + +### New Features + +- Algorithms in CUDA Device Code: + - Thrust algorithms may now be invoked from CUDA `__device__` and + `__host__` __device__ functions. + Algorithms invoked in this manner must be invoked with an execution + policy as the first parameter. + The following execution policies are supported in CUDA __device__ code: + - `thrust::seq` + - `thrust::cuda::par` + - `thrust::device`, when THRUST_DEVICE_SYSTEM == THRUST_DEVICE_SYSTEM_CUDA. + - Device-side algorithm execution may not be parallelized unless CUDA Dynamic + Parallelism is available. +- Execution Policies: + - CUDA Streams + - The `thrust::cuda::par.on(stream)` syntax allows users to request that + CUDA kernels launched during algorithm execution should occur on a given + stream. + - Algorithms executed with a CUDA stream in this manner may still + synchronize with other streams when allocating temporary storage or + returning results to the CPU. + - `thrust::seq`, which allows users to require that an algorithm execute + sequentially in the calling thread. +- `thrust::complex`, a complex number data type. + +### New Examples + +- simple_cuda_streams demonstrates how to request a CUDA stream during + algorithm execution. +- async_reduce demonstrates ways to achieve algorithm invocations which are + asynchronous with the calling thread. + +### Other Enhancements + +- CUDA sort performance for user-defined types is 300% faster on Tesla K20c for + large problem sizes. +- CUDA merge performance is 200% faster on Tesla K20c for large problem sizes. +- CUDA sort performance for primitive types is 50% faster on Tesla K20c for + large problem sizes. +- CUDA reduce_by_key performance is 25% faster on Tesla K20c for large problem + sizes. +- CUDA scan performance is 15% faster on Tesla K20c for large problem sizes. +- fallback_allocator example is simpler. + +### Bug Fixes + +- #364: Iterators with unrelated system tags may be used with algorithms invoked + with an execution policy +- #371: Do not redefine `__CUDA_ARCH__`. +- #379: Fix crash when dereferencing transform_iterator on the host. +- #391: Avoid use of uppercase variable names. +- #392: Fix `thrust::copy` between `cusp::complex` and `std::complex`. +- #396: Program compiled with gcc < 4.3 hangs during comparison sort. +- #406: `fallback_allocator.cu` example checks device for unified addressing support. +- #417: Avoid using `std::less` in binary search algorithms. +- #418: Avoid various warnings. +- #443: Including version.h no longer configures default systems. +- #578: NVCC produces warnings when sequential algorithms are used with CPU systems. + +### Known Issues + +- When invoked with primitive data types, thrust::sort, thrust::sort_by_key, + thrust::stable_sort, & thrust::stable_sort_by_key may +- Sometimes linking fails when compiling with `-rdc=true` with NVCC. +- The CUDA implementation of thrust::reduce_by_key incorrectly outputs the last + element in a segment of equivalent keys instead of the first. + +### Acknowledgments + +- Thanks to Sean Baxter for contributing faster CUDA reduce, merge, and scan + implementations. +- Thanks to Duane Merrill for contributing a faster CUDA radix sort implementation. +- Thanks to Filipe Maia for contributing the implementation of thrust::complex. + +## Thrust 1.7.2 (CUDA Toolkit 6.5) + +Thrust 1.7.2 is a minor bug fix release. + +### Bug Fixes + +- Avoid use of `std::min` in generic find implementation. + +## Thrust 1.7.1 (CUDA Toolkit 6.0) + +Thrust 1.7.1 is a minor bug fix release. + +### Bug Fixes + +- Eliminate identifiers in `set_operations.cu` example with leading underscore. +- Eliminate unused variable warning in CUDA `reduce_by_key` implementation. +- Avoid deriving function objects from `std::unary_function` and + `std::binary_function`. + +## Thrust 1.7.0 (CUDA Toolkit 5.5) + +Thrust 1.7.0 introduces a new interface for controlling algorithm execution as + well as several new algorithms and performance improvements. +With this new interface, users may directly control how algorithms execute as + well as details such as the allocation of temporary storage. +Key/value versions of thrust::merge and the set operation algorithms have been + added, as well stencil versions of partitioning algorithms. +thrust::tabulate has been introduced to tabulate the values of functions taking + integers. +For 32b types, new CUDA merge and set operations provide 2-15x faster + performance while a new CUDA comparison sort provides 1.3-4x faster + performance. +Finally, a new TBB reduce_by_key implementation provides 80% faster + performance. + +### Breaking Changes + +- Dispatch: + - Custom user backend systems' tag types must now inherit from the + corresponding system's execution_policy template (e.g. + thrust::cuda::execution_policy) instead of the tag struct (e.g. + thrust::cuda::tag). Otherwise, algorithm specializations will silently go + unfound during dispatch. See examples/minimal_custom_backend.cu and + examples/cuda/fallback_allocator.cu for usage examples. + - thrust::advance and thrust::distance are no longer dispatched based on + iterator system type and thus may no longer be customized. +- Iterators: + - iterator_facade and iterator_adaptor's Pointer template parameters have + been eliminated. + - iterator_adaptor has been moved into the thrust namespace (previously + thrust::experimental::iterator_adaptor). + - iterator_facade has been moved into the thrust namespace (previously + thrust::experimental::iterator_facade). + - iterator_core_access has been moved into the thrust namespace (previously + thrust::experimental::iterator_core_access). + - All iterators' nested pointer typedef (the type of the result of + operator->) is now void instead of a pointer type to indicate that such + expressions are currently impossible. + - Floating point counting_iterators' nested difference_type typedef is now a + signed integral type instead of a floating point type. +- Other: + - normal_distribution has been moved into the thrust::random namespace + (previously thrust::random::experimental::normal_distribution). + - Placeholder expressions may no longer include the comma operator. + +### New Features +- Execution Policies: + - Users may directly control the dispatch of algorithm invocations with + optional execution policy arguments. + For example, instead of wrapping raw pointers allocated by cudaMalloc with + thrust::device_ptr, the thrust::device execution_policy may be passed as + an argument to an algorithm invocation to enable CUDA execution. + - The following execution policies are supported in this version: + - `thrust::host` + - `thrust::device` + - `thrust::cpp::par` + - `thrust::cuda::par` + - `thrust::omp::par` + - `thrust::tbb::par` +- Algorithms: + - `thrust::merge_by_key` + - `thrust::partition` with stencil + - `thrust::partition_copy` with stencil + - `thrust::set_difference_by_key` + - `thrust::set_intersection_by_key` + - `thrust::set_symmetric_difference_by_key` + - `thrust::set_union_by_key` + - `thrust::stable_partition with stencil` + - `thrust::stable_partition_copy with stencil` + - `thrust::tabulate` +- Memory Allocation: + - `thrust::malloc` + - `thrust::free` + - `thrust::get_temporary_buffer` + - `thrust::return_temporary_buffer` + +### New Examples + +- uninitialized_vector demonstrates how to use a custom allocator to avoid the + automatic initialization of elements in thrust::device_vector. + +### Other Enhancements + +- Authors of custom backend systems may manipulate arbitrary state during + algorithm dispatch by incorporating it into their execution_policy parameter. +- Users may control the allocation of temporary storage during algorithm + execution by passing standard allocators as parameters via execution policies + such as thrust::device. +- THRUST_DEVICE_SYSTEM_CPP has been added as a compile-time target for the + device backend. +- CUDA merge performance is 2-15x faster. +- CUDA comparison sort performance is 1.3-4x faster. +- CUDA set operation performance is 1.5-15x faster. +- TBB reduce_by_key performance is 80% faster. +- Several algorithms have been parallelized with TBB. +- Support for user allocators in vectors has been improved. +- The sparse_vector example is now implemented with merge_by_key instead of + sort_by_key. +- Warnings have been eliminated in various contexts. +- Warnings about __host__ or __device__-only functions called from __host__ + __device__ functions have been eliminated in various contexts. +- Documentation about algorithm requirements have been improved. +- Simplified the minimal_custom_backend example. +- Simplified the cuda/custom_temporary_allocation example. +- Simplified the cuda/fallback_allocator example. + +### Bug Fixes + +- #248: Fix broken `thrust::counting_iterator` behavior with OpenMP. +- #231, #209: Fix set operation failures with CUDA. +- #187: Fix incorrect occupancy calculation with CUDA. +- #153: Fix broken multi GPU behavior with CUDA. +- #142: Eliminate warning produced by `thrust::random::taus88` and MSVC 2010. +- #208: Correctly initialize elements in temporary storage when necessary. +- #16: Fix compilation error when sorting bool with CUDA. +- #10: Fix ambiguous overloads of `thrust::reinterpret_tag`. + +### Known Issues + +- GCC 4.3 and lower may fail to dispatch thrust::get_temporary_buffer correctly + causing infinite recursion in examples such as + cuda/custom_temporary_allocation. + +### Acknowledgments + +- Thanks to Sean Baxter, Bryan Catanzaro, and Manjunath Kudlur for contributing + a faster merge implementation for CUDA. +- Thanks to Sean Baxter for contributing a faster set operation implementation + for CUDA. +- Thanks to Cliff Woolley for contributing a correct occupancy calculation + algorithm. + +## Thrust 1.6.0 + +Thrust 1.6.0 provides an interface for customization and extension and a new + backend system based on the Threading Building Blocks library. +With this new interface, programmers may customize the behavior of specific + algorithms as well as control the allocation of temporary storage or invent + entirely new backends. +These enhancements also allow multiple different backend systems + such as CUDA and OpenMP to coexist within a single program. +Support for TBB allows Thrust programs to integrate more naturally into + applications which may already employ the TBB task scheduler. + +### Breaking Changes + +- The header has been moved to + +- thrust::experimental::cuda::pinned_allocator has been moved to + thrust::cuda::experimental::pinned_allocator +- The macro THRUST_DEVICE_BACKEND has been renamed THRUST_DEVICE_SYSTEM +- The macro THRUST_DEVICE_BACKEND_CUDA has been renamed THRUST_DEVICE_SYSTEM_CUDA +- The macro THRUST_DEVICE_BACKEND_OMP has been renamed THRUST_DEVICE_SYSTEM_OMP +- thrust::host_space_tag has been renamed thrust::host_system_tag +- thrust::device_space_tag has been renamed thrust::device_system_tag +- thrust::any_space_tag has been renamed thrust::any_system_tag +- thrust::iterator_space has been renamed thrust::iterator_system + +### New Features + +- Backend Systems + - Threading Building Blocks (TBB) is now supported +- Algorithms + - `thrust::for_each_n` + - `thrust::raw_reference_cast` +- Types + - `thrust::pointer` + - `thrust::reference` + +### New Examples + +- `cuda/custom_temporary_allocation` +- `cuda/fallback_allocator` +- `device_ptr` +- `expand` +- `minimal_custom_backend` +- `raw_reference_cast` +- `set_operations` + +### Other Enhancements + +- `thrust::for_each` now returns the end of the input range similar to most + other algorithms. +- `thrust::pair` and `thrust::tuple` have swap functionality. +- All CUDA algorithms now support large data types. +- Iterators may be dereferenced in user `__device__` or `__global__` functions. +- The safe use of different backend systems is now possible within a single + binary + +### Bug Fixes + +- #469 `min_element` and `max_element` algorithms no longer require a const comparison operator + +### Known Issues + +- NVCC may crash when parsing TBB headers on Windows. + +## Thrust 1.5.3 (CUDA Toolkit 5.0) + +Thrust 1.5.3 is a minor bug fix release. + +### Bug Fixes + +- Avoid warnings about potential race due to `__shared__` non-POD variable + +## Thrust 1.5.2 (CUDA Toolkit 4.2) + +Thrust 1.5.2 is a minor bug fix release. + +### Bug Fixes + +- Fixed warning about C-style initialization of structures + +## Thrust 1.5.1 (CUDA Toolkit 4.1) + +Thrust 1.5.1 is a minor bug fix release. + +### Bug Fixes + +- Sorting data referenced by permutation_iterators on CUDA produces invalid results + +## Thrust 1.5.0 + +Thrust 1.5.0 provides introduces new programmer productivity and performance + enhancements. +New functionality for creating anonymous "lambda" functions has been added. +A faster host sort provides 2-10x faster performance for sorting arithmetic + types on (single-threaded) CPUs. +A new OpenMP sort provides 2.5x-3.0x speedup over the host sort using a + quad-core CPU. +When sorting arithmetic types with the OpenMP backend the combined performance + improvement is 5.9x for 32-bit integers and ranges from 3.0x (64-bit types) to + 14.2x (8-bit types). +A new CUDA `reduce_by_key` implementation provides 2-3x faster + performance. + +### Breaking Changes +- device_ptr no longer unsafely converts to device_ptr without an + explicit cast. + Use the expression device_pointer_cast(static_cast(void_ptr.get())) to + convert, for example, device_ptr to device_ptr. + +### New Features + +- Algorithms: + - Stencil-less `thrust::transform_if`. +- Lambda placeholders + +### New Examples +- lambda + +### Other Enhancements + +- Host sort is 2-10x faster for arithmetic types +- OMP sort provides speedup over host sort +- `reduce_by_key` is 2-3x faster +- `reduce_by_key` no longer requires O(N) temporary storage +- CUDA scan algorithms are 10-40% faster +- `host_vector` and `device_vector` are now documented +- out-of-memory exceptions now provide detailed information from CUDART +- improved histogram example +- `device_reference` now has a specialized swap +- `reduce_by_key` and scan algorithms are compatible with `discard_iterator` + +### Bug Fixes + +- #44: Allow `thrust::host_vector` to compile when `value_type` uses + `__align__`. +- #198: Allow `thrust::adjacent_difference` to permit safe in-situ operation. +- #303: Make thrust thread-safe. +- #313: Avoid race conditions in `thrust::device_vector::insert`. +- #314: Avoid unintended ADL invocation when dispatching copy. +- #365: Fix merge and set operation failures. + +### Known Issues + +- None + +### Acknowledgments + +- Thanks to Manjunath Kudlur for contributing his Carbon library, from which + the lambda functionality is derived. +- Thanks to Jean-Francois Bastien for suggesting a fix for #303. + +## Thrust 1.4.0 (CUDA Toolkit 4.0) + +Thrust 1.4.0 is the first release of Thrust to be included in the CUDA Toolkit. +Additionally, it brings many feature and performance improvements. +New set theoretic algorithms operating on sorted sequences have been added. +Additionally, a new fancy iterator allows discarding redundant or otherwise + unnecessary output from algorithms, conserving memory storage and bandwidth. + +### Breaking Changes + +- Eliminations + - `thrust/is_sorted.h` + - `thrust/utility.h` + - `thrust/set_intersection.h` + - `thrust/experimental/cuda/ogl_interop_allocator.h` and the functionality + therein + - `thrust::deprecated::copy_when` + - `thrust::deprecated::absolute_value` + - `thrust::deprecated::copy_when` + - `thrust::deprecated::absolute_value` + - `thrust::deprecated::copy_when` + - `thrust::deprecated::absolute_value` + - `thrust::gather` and `thrust::scatter` from host to device and vice versa + are no longer supported. + - Operations which modify the elements of a thrust::device_vector are no longer + available from source code compiled without nvcc when the device backend + is CUDA. + Instead, use the idiom from the cpp_interop example. + +### New Features + +- Algorithms: + - `thrust::copy_n` + - `thrust::merge` + - `thrust::set_difference` + - `thrust::set_symmetric_difference` + - `thrust::set_union` + +- Types + - `thrust::discard_iterator` + +- Device Support: + - Compute Capability 2.1 GPUs. + +### New Examples + +- run_length_decoding + +### Other Enhancements + +- Compilation warnings are substantially reduced in various contexts. +- The compilation time of thrust::sort, thrust::stable_sort, + thrust::sort_by_key, and thrust::stable_sort_by_key are substantially + reduced. +- A fast sort implementation is used when sorting primitive types with + thrust::greater. +- The performance of thrust::set_intersection is improved. +- The performance of thrust::fill is improved on SM 1.x devices. +- A code example is now provided in each algorithm's documentation. +- thrust::reverse now operates in-place + +### Bug Fixes + +- #212: `thrust::set_intersection` works correctly for large input sizes. +- #275: `thrust::counting_iterator` and `thrust::constant_iterator` work + correctly with OpenMP as the backend when compiling with optimization. +- #256: `min` and `max` correctly return their first argument as a tie-breaker +- #248: `NDEBUG` is interpreted incorrectly + +### Known Issues + +- NVCC may generate code containing warnings when compiling some Thrust + algorithms. +- When compiling with `-arch=sm_1x`, some Thrust algorithms may cause NVCC to + issue benign pointer advisories. +- When compiling with `-arch=sm_1x` and -G, some Thrust algorithms may fail to + execute correctly. +- `thrust::inclusive_scan`, `thrust::exclusive_scan`, + `thrust::inclusive_scan_by_key`, and `thrust::exclusive_scan_by_key` are + currently incompatible with `thrust::discard_iterator`. + +### Acknowledgments + +- Thanks to David Tarjan for improving the performance of set_intersection. +- Thanks to Duane Merrill for continued help with sort. +- Thanks to Nathan Whitehead for help with CUDA Toolkit integration. + +## Thrust 1.3.0 + +Thrust 1.3.0 provides support for CUDA Toolkit 3.2 in addition to many feature + and performance enhancements. +Performance of the sort and sort_by_key algorithms is improved by as much as 3x + in certain situations. +The performance of stream compaction algorithms, such as copy_if, is improved + by as much as 2x. +CUDA errors are now converted to runtime exceptions using the system_error + interface. +Combined with a debug mode, also new in 1.3, runtime errors can be located with + greater precision. +Lastly, a few header files have been consolidated or renamed for clarity. +See the deprecations section below for additional details. + +### Breaking Changes + +- Promotions + - thrust::experimental::inclusive_segmented_scan has been renamed + thrust::inclusive_scan_by_key and exposes a different interface + - thrust::experimental::exclusive_segmented_scan has been renamed + thrust::exclusive_scan_by_key and exposes a different interface + - thrust::experimental::partition_copy has been renamed + thrust::partition_copy and exposes a different interface + - thrust::next::gather has been renamed thrust::gather + - thrust::next::gather_if has been renamed thrust::gather_if + - thrust::unique_copy_by_key has been renamed thrust::unique_by_key_copy +- Deprecations + - thrust::copy_when has been renamed thrust::deprecated::copy_when + - thrust::absolute_value has been renamed thrust::deprecated::absolute_value + - The header thrust/set_intersection.h is now deprecated; use + thrust/set_operations.h instead + - The header thrust/utility.h is now deprecated; use thrust/swap.h instead + - The header thrust/swap_ranges.h is now deprecated; use thrust/swap.h instead +- Eliminations + - thrust::deprecated::gather + - thrust::deprecated::gather_if + - thrust/experimental/arch.h and the functions therein + - thrust/sorting/merge_sort.h + - thrust/sorting/radix_sort.h +- NVCC 2.3 is no longer supported + +### New Features + +- Algorithms: + - `thrust::exclusive_scan_by_key` + - `thrust::find` + - `thrust::find_if` + - `thrust::find_if_not` + - `thrust::inclusive_scan_by_key` + - `thrust::is_partitioned` + - `thrust::is_sorted_until` + - `thrust::mismatch` + - `thrust::partition_point` + - `thrust::reverse` + - `thrust::reverse_copy` + - `thrust::stable_partition_copy` + +- Types: + - `thrust::system_error` and related types. + - `thrust::experimental::cuda::ogl_interop_allocator`. + - `thrust::bit_and`, `thrust::bit_or`, and `thrust::bit_xor`. + +- Device Support: + - GF104-based GPUs. + +### New Examples + +- opengl_interop.cu +- repeated_range.cu +- simple_moving_average.cu +- sparse_vector.cu +- strided_range.cu + +### Other Enhancements + +- Performance of thrust::sort and thrust::sort_by_key is substantially improved + for primitive key types +- Performance of thrust::copy_if is substantially improved +- Performance of thrust::reduce and related reductions is improved +- THRUST_DEBUG mode added +- Callers of Thrust functions may detect error conditions by catching + thrust::system_error, which derives from std::runtime_error +- The number of compiler warnings generated by Thrust has been substantially + reduced +- Comparison sort now works correctly for input sizes > 32M +- min & max usage no longer collides with definitions +- Compiling against the OpenMP backend no longer requires nvcc +- Performance of device_vector initialized in .cpp files is substantially + improved in common cases +- Performance of thrust::sort_by_key on the host is substantially improved + +### Bug Fixes + +- Debug device code now compiles correctly +- thrust::uninitialized_copy and thrust::uninitialized_fill now dispatch + constructors on the device rather than the host + +### Known Issues + +- #212 set_intersection is known to fail for large input sizes +- partition_point is known to fail for 64b types with nvcc 3.2 + +Acknowledgments +- Thanks to Duane Merrill for contributing a fast CUDA radix sort implementation +- Thanks to Erich Elsen for contributing an implementation of find_if +- Thanks to Andrew Corrigan for contributing changes which allow the OpenMP + backend to compile in the absence of nvcc +- Thanks to Andrew Corrigan, Cliff Wooley, David Coeurjolly, Janick Martinez + Esturo, John Bowers, Maxim Naumov, Michael Garland, and Ryuta Suzuki for + bug reports +- Thanks to Cliff Woolley for help with testing + +## Thrust 1.2.1 + +Thrust 1.2.1 is a small bug fix release that is compatible with the CUDA + Toolkit 3.1 release. + +### Known Issues + +- `thrust::inclusive_scan` and `thrust::exclusive_scan` may fail with very + large types. +- MSVC may fail to compile code using both sort and binary search algorithms. +- `thrust::uninitialized_fill` and `thrust::uninitialized_copy` dispatch + constructors on the host rather than the device. +- #109: Some algorithms may exhibit poor performance with the OpenMP backend + with large numbers (>= 6) of CPU threads. +- `thrust::default_random_engine::discard` is not accelerated with NVCC 2.3 +- NVCC 3.1 may fail to compile code using types derived from + `thrust::subtract_with_carry_engine`, such as `thrust::ranlux24` and + `thrust::ranlux48`. + +## Thrust 1.2.0 + +Thrust 1.2.0 introduces support for compilation to multicore CPUs and the Ocelot + virtual machine, and several new facilities for pseudo-random number + generation. +New algorithms such as set intersection and segmented reduction have also been + added. +Lastly, improvements to the robustness of the CUDA backend ensure correctness + across a broad set of (uncommon) use cases. + +### Breaking Changes + +- `thrust::gather`'s interface was incorrect and has been removed. + The old interface is deprecated but will be preserved for Thrust version 1.2 + at `thrust::deprecated::gather` and `thrust::deprecated::gather_if`. + The new interface is provided at `thrust::next::gather` and + `thrust::next::gather_if`. + The new interface will be promoted to `thrust::` in Thrust version 1.3. + For more details, please refer to [this thread](http://groups.google.com/group/thrust-users/browse_thread/thread/f5f0583cb97b51fd). +- The `thrust::sorting` namespace has been deprecated in favor of the top-level + sorting functions, such as `thrust::sort` and `thrust::sort_by_key`. +- Removed support for `thrust::equal` between host & device sequences. +- Removed support for `thrust::scatter` between host & device sequences. + +### New Features + +- Algorithms: + - `thrust::reduce_by_key` + - `thrust::set_intersection` + - `thrust::unique_copy` + - `thrust::unique_by_key` + - `thrust::unique_copy_by_key` +- Types +- Random Number Generation: + - `thrust::discard_block_engine` + - `thrust::default_random_engine` + - `thrust::linear_congruential_engine` + - `thrust::linear_feedback_shift_engine` + - `thrust::subtract_with_carry_engine` + - `thrust::xor_combine_engine` + - `thrust::minstd_rand` + - `thrust::minstd_rand0` + - `thrust::ranlux24` + - `thrust::ranlux48` + - `thrust::ranlux24_base` + - `thrust::ranlux48_base` + - `thrust::taus88` + - `thrust::uniform_int_distribution` + - `thrust::uniform_real_distribution` + - `thrust::normal_distribution` (experimental) +- Function Objects: + - `thrust::project1st` + - `thrust::project2nd` +- `thrust::tie` +- Fancy Iterators: + - `thrust::permutation_iterator` + - `thrust::reverse_iterator` +- Vector Functions: + - `operator!=` + - `rbegin` + - `crbegin` + - `rend` + - `crend` + - `data` + - `shrink_to_fit` +- Device Support: + - Multicore CPUs via OpenMP. + - Fermi-class GPUs. + - Ocelot virtual machines. +- Support for NVCC 3.0. + +### New Examples + +- `cpp_integration` +- `histogram` +- `mode` +- `monte_carlo` +- `monte_carlo_disjoint_sequences` +- `padded_grid_reduction` +- `permutation_iterator` +- `row_sum` +- `run_length_encoding` +- `segmented_scan` +- `stream_compaction` +- `summary_statistics` +- `transform_iterator` +- `word_count` + +### Other Enhancements + +- Integer sorting performance is improved when max is large but (max - min) is + small and when min is negative +- Performance of `thrust::inclusive_scan` and `thrust::exclusive_scan` is + improved by 20-25% for primitive types. + +### Bug Fixes + +- #8 cause a compiler error if the required compiler is not found rather than a + mysterious error at link time +- #42 device_ptr & device_reference are classes rather than structs, + eliminating warnings on certain platforms +- #46 gather & scatter handle any space iterators correctly +- #51 thrust::experimental::arch functions gracefully handle unrecognized GPUs +- #52 avoid collisions with common user macros such as BLOCK_SIZE +- #62 provide better documentation for device_reference +- #68 allow built-in CUDA vector types to work with device_vector in pure C++ + mode +- #102 eliminated a race condition in device_vector::erase +- various compilation warnings eliminated + +### Known Issues + +- inclusive_scan & exclusive_scan may fail with very large types +- MSVC may fail to compile code using both sort and binary search algorithms +- uninitialized_fill & uninitialized_copy dispatch constructors on the host + rather than the device +- #109 some algorithms may exhibit poor performance with the OpenMP backend + with large numbers (>= 6) of CPU threads +- default_random_engine::discard is not accelerated with nvcc 2.3 + +### Acknowledgments + +- Thanks to Gregory Diamos for contributing a CUDA implementation of + set_intersection +- Thanks to Ryuta Suzuki & Gregory Diamos for rigorously testing Thrust's unit + tests and examples against Ocelot +- Thanks to Tom Bradley for contributing an implementation of normal_distribution +- Thanks to Joseph Rhoads for contributing the example summary_statistics + +## Thrust 1.1.1 + +Thrust 1.1.1 is a small bug fix release that is compatible with the CUDA + Toolkit 2.3a release and Mac OSX Snow Leopard. + +## Thrust 1.1.0 + +Thrust 1.1.0 introduces fancy iterators, binary search functions, and several + specialized reduction functions. +Experimental support for segmented scans has also been added. + +### Breaking Changes + +- `thrust::counting_iterator` has been moved into the `thrust` namespace + (previously `thrust::experimental`). + +### New Features + +- Algorithms: + - `thrust::copy_if` + - `thrust::lower_bound` + - `thrust::upper_bound` + - `thrust::vectorized lower_bound` + - `thrust::vectorized upper_bound` + - `thrust::equal_range` + - `thrust::binary_search` + - `thrust::vectorized binary_search` + - `thrust::all_of` + - `thrust::any_of` + - `thrust::none_of` + - `thrust::minmax_element` + - `thrust::advance` + - `thrust::inclusive_segmented_scan` (experimental) + - `thrust::exclusive_segmented_scan` (experimental) +- Types: + - `thrust::pair` + - `thrust::tuple` + - `thrust::device_malloc_allocator` +- Fancy Iterators: + - `thrust::constant_iterator` + - `thrust::counting_iterator` + - `thrust::transform_iterator` + - `thrust::zip_iterator` + +### New Examples + +- Computing the maximum absolute difference between vectors. +- Computing the bounding box of a two-dimensional point set. +- Sorting multiple arrays together (lexicographical sorting). +- Constructing a summed area table. +- Using `thrust::zip_iterator` to mimic an array of structs. +- Using `thrust::constant_iterator` to increment array values. + +### Other Enhancements + +- Added pinned memory allocator (experimental). +- Added more methods to host_vector & device_vector (issue #4). +- Added variant of remove_if with a stencil argument (issue #29). +- Scan and reduce use cudaFuncGetAttributes to determine grid size. +- Exceptions are reported when temporary device arrays cannot be allocated. + +### Bug Fixes + +- #5: Make vector work for larger data types +- #9: stable_partition_copy doesn't respect OutputIterator concept semantics +- #10: scans should return OutputIterator +- #16: make algorithms work for larger data types +- #27: Dispatch radix_sort even when comp=less is explicitly provided + +### Known Issues + +- Using functors with Thrust entry points may not compile on Mac OSX with gcc + 4.0.1. +- `thrust::uninitialized_copy` and `thrust::uninitialized_fill` dispatch + constructors on the host rather than the device. +- `thrust::inclusive_scan`, `thrust::inclusive_scan_by_key`, + `thrust::exclusive_scan`, and `thrust::exclusive_scan_by_key` may fail when + used with large types with the CUDA Toolkit 3.1. + +## Thrust 1.0.0 + +First production release of Thrust. + +### Breaking Changes + +- Rename top level namespace `komrade` to `thrust`. +- Move `thrust::partition_copy` & `thrust::stable_partition_copy` into + `thrust::experimental` namespace until we can easily provide the standard + interface. +- Rename `thrust::range` to `thrust::sequence` to avoid collision with + Boost.Range. +- Rename `thrust::copy_if` to `thrust::copy_when` due to semantic differences + with C++0x `std::copy_if`. + +### New Features + +- Add C++0x style `cbegin` & `cend` methods to `thrust::host_vector` and + `thrust::device_vector`. +- Add `thrust::transform_if` function. +- Add stencil versions of `thrust::replace_if` & `thrust::replace_copy_if`. +- Allow `counting_iterator` to work with `thrust::for_each`. +- Allow types with constructors in comparison `thrust::sort` and + `thrust::reduce`. + +### Other Enhancements + +- `thrust::merge_sort` and `thrust::stable_merge_sort` are now 2x to 5x faster + when executed on the parallel device. + +### Bug Fixes + +- Komrade 6: Workaround an issue where an incremented iterator causes NVCC to + crash. +- Komrade 7: Fix an issue where `const_iterator`s could not be passed to + `thrust::transform`. + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..967ebf53a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,155 @@ +# 3.15 is the minimum for including the project with add_subdirectory. +# 3.17 for building the project's standalone tests/examples/etc. +# 3.18.3 for C++17 + CUDA +cmake_minimum_required(VERSION 3.15) + +# Remove this when we use the new CUDA_ARCHITECTURES properties with both +# nvcc and nvc++. +if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) + cmake_policy(SET CMP0104 OLD) +endif() + +project(Thrust NONE) + +# Determine whether Thrust is the top-level project or included into +# another project via add_subdirectory() +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_LIST_DIR}") + set(THRUST_TOPLEVEL_PROJECT ON) +else() + set(THRUST_TOPLEVEL_PROJECT OFF) +endif() + +## thrust_fix_clang_nvcc_build_for +# +# Modifies the given target to include a fix for the clang host compiler case. +# The fix consists of force-including a header into each compilation unit. +# +function(thrust_fix_clang_nvcc_build_for target) + if (UNIX) + # Path to the header containing the fix for clang + nvcc < 11.6. For more info, + # check the content of this header. + set(clang_fix_header_path "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/testing/fix_clang_nvcc_11.5.h") + + # Only affects host compiler + target_compile_options(${target} PRIVATE + "$<$:-include${clang_fix_header_path}>") + endif() +endfunction() + +# This must be done before any languages are enabled: +if (THRUST_TOPLEVEL_PROJECT) + include(cmake/ThrustCompilerHacks.cmake) +endif() + +# This must appear after our Compiler Hacks or else CMake will delete the cache +# and reconfigure from scratch. +# This must also appear before the installation rules, as it is required by the +# GNUInstallDirs CMake module. +enable_language(CXX) + +# Optionally include installation rules for non-top-level builds: +option(THRUST_ENABLE_INSTALL_RULES "Enable installation of Thrust" ${THRUST_TOPLEVEL_PROJECT}) +if (THRUST_ENABLE_INSTALL_RULES) + include(cmake/ThrustInstallRules.cmake) +endif() + +# Support adding Thrust to a parent project via add_subdirectory. +# See examples/cmake/add_subdir/CMakeLists.txt for details. +if (NOT THRUST_TOPLEVEL_PROJECT) + include(cmake/ThrustAddSubdir.cmake) + return() +endif() + +# We use 3.17 features when building our tests, etc. +cmake_minimum_required(VERSION 3.17) + +option(THRUST_ENABLE_HEADER_TESTING "Test that all public headers compile." "ON") +option(THRUST_ENABLE_TESTING "Build Thrust testing suite." "ON") +option(THRUST_ENABLE_EXAMPLES "Build Thrust examples." "ON") +option(THRUST_ENABLE_BENCHMARKS "Build Thrust runtime benchmarks." "OFF") +option(THRUST_INCLUDE_CUB_CMAKE "Build CUB tests and examples. (Requires CUDA)." "OFF") + +# Mark this option as advanced for now. We'll revisit this later once the new +# benchmarks are ready. For now, we just need to expose a way to compile +# bench.cu from CMake for NVIDIA's internal builds. +mark_as_advanced(THRUST_ENABLE_BENCHMARKS) + +# Check if we're actually building anything before continuing. If not, no need +# to search for deps, etc. This is a common approach for packagers that just +# need the install rules. See GH issue NVIDIA/thrust#1211. +if (NOT (THRUST_ENABLE_HEADER_TESTING OR + THRUST_ENABLE_TESTING OR + THRUST_ENABLE_EXAMPLES OR + THRUST_ENABLE_BENCHMARKS OR + THRUST_INCLUDE_CUB_CMAKE)) + return() +endif() + +include(cmake/AppendOptionIfAvailable.cmake) +include(cmake/ThrustBuildCompilerTargets.cmake) +include(cmake/ThrustBuildTargetList.cmake) +include(cmake/ThrustFindThrust.cmake) +include(cmake/ThrustMultiConfig.cmake) +include(cmake/ThrustUtilities.cmake) + +# Add cache string options for CMAKE_BUILD_TYPE and default to RelWithDebInfo. +if ("" STREQUAL "${CMAKE_BUILD_TYPE}") + set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build." FORCE) + + set_property( + CACHE CMAKE_BUILD_TYPE + PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel + ) +endif () + +# Disable compiler extensions: +set(CMAKE_CXX_EXTENSIONS OFF) + +# Where to put build outputs. Use CMAKE_BINARY_DIR so they'll show up in the +# top-level project's dir when building Thrust via add_subdirectory. +set(THRUST_LIBRARY_OUTPUT_DIR "${CMAKE_BINARY_DIR}/lib") +set(THRUST_EXECUTABLE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/bin") + +thrust_configure_multiconfig() +thrust_find_thrust() +thrust_build_compiler_targets() +thrust_update_system_found_flags() +if (THRUST_CUDA_FOUND) + include(cmake/ThrustCudaConfig.cmake) +endif() +thrust_build_target_list() + +message(STATUS "CPP system found? ${THRUST_CPP_FOUND}") +message(STATUS "CUDA system found? ${THRUST_CUDA_FOUND}") +message(STATUS "TBB system found? ${THRUST_TBB_FOUND}") +message(STATUS "OMP system found? ${THRUST_OMP_FOUND}") + +if (THRUST_ENABLE_HEADER_TESTING) + include(cmake/ThrustHeaderTesting.cmake) +endif() + +# Both testing and examples use ctest +if (THRUST_ENABLE_TESTING OR THRUST_ENABLE_EXAMPLES) + include(CTest) + enable_testing() +endif() + +if (THRUST_ENABLE_TESTING) + add_subdirectory(testing) +endif() + +if (THRUST_ENABLE_EXAMPLES) + add_subdirectory(examples) +endif() + +if (THRUST_ENABLE_BENCHMARKS) + add_subdirectory(internal/benchmark) +endif() + +if (THRUST_INCLUDE_CUB_CMAKE AND THRUST_CUDA_FOUND) + set(CUB_IN_THRUST ON) + # CUB's path is specified generically to support both GitHub and Perforce + # source tree layouts. The include directory used by cub-config.cmake + # for source layouts is the same as the project root. + add_subdirectory("${_CUB_INCLUDE_DIR}" dependencies/cub) +endif() diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..8c56af363 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,96 @@ +# Code of Conduct + +## Overview + +This document defines the Code of Conduct followed and enforced for NVIDIA C++ + Core Compute Libraries. + +### Intended Audience + +* Community +* Developers +* Project Leads + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as + contributors and maintainers pledge to making participation in our project and + our community a harassment-free experience for everyone, regardless of age, + body size, disability, ethnicity, sex characteristics, gender identity and + expression, level of experience, education, socio-economic status, nationality, + personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language. +- Being respectful of differing viewpoints and experiences. +- Gracefully accepting constructive criticism. +- Focusing on what is best for the community. +- Showing empathy towards other community members. + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances. +- Trolling, insulting/derogatory comments, and personal or political attacks. +- Public or private harassment. +- Publishing others’ private information, such as a physical or electronic + address, without explicit permission. +- Other conduct which could reasonably be considered inappropriate. + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable + behavior and are expected to take appropriate and fair corrective action in + response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or + reject comments, commits, code, wiki edits, issues, and other contributions + that are not aligned to this Code of Conduct, or to ban temporarily or + permanently any contributor for other behaviors that they deem inappropriate, + threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces + when an individual is representing the project or its community. +Examples of representing a project or community include using an official + project email address, posting via an official social media account, or acting + as an appointed representative at an online or offline event. +Representation of a project may be further defined and clarified by project + maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be + reported by contacting [cpp-conduct@nvidia.com](mailto:cpp-conduct@nvidia.com). +All complaints will be reviewed and investigated and will result in a response + that is deemed necessary and appropriate to the circumstances. +The project team is obligated to maintain confidentiality with regard to the + reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good + faith may face temporary or permanent repercussions as determined by other + members of the project’s leadership. + +## Attribution + +This Code of Conduct was taken from the [NVIDIA RAPIDS] project, which was + adapted from the [Contributor Covenant version 1.4]. + +Please see this [FAQ] for answers to common questions about this Code of Conduct. + +## Contact + +Please email [cpp-conduct@nvidia.com] for any Code of Conduct related matters. + + +[cpp-conduct@nvidia.com]: mailto:cpp-conduct@nvidia.com + +[FAQ]: https://www.contributor-covenant.org/faq + +[NVIDIA RAPIDS]: https://docs.rapids.ai/resources/conduct/ +[Contributor Covenant version 1.4]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html diff --git a/LICENSE b/LICENSE index e454a5258..c22c22563 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,7 @@ +Unless otherwise noted, Thrust's source code is released under the Apache +License, Version 2.0: + +================================================================================ Apache License Version 2.0, January 2004 @@ -174,5 +178,72 @@ incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS - +================================================================================ + +Some portions of Thrust may be licensed under other compatible open-source +licenses. Any divergence from the Apache 2 license will be noted in the source +code where applicable. + +Portions under other terms include, but are not limited to: + +================================================================================ + +Various C++ utility classes in Thrust are based on the Boost Iterator, Tuple, +System, and Random Number libraries, which are provided under the Boost Software +License: + + Boost Software License - Version 1.0 - August 17th, 2003 + + Permission is hereby granted, free of charge, to any person or organization + obtaining a copy of the software and accompanying documentation covered by + this license (the "Software") to use, reproduce, display, distribute, + execute, and transmit the Software, and to prepare derivative works of the + Software, and to permit third-parties to whom the Software is furnished to + do so, all subject to the following: + + The copyright notices in the Software and this entire statement, including + the above license grant, this restriction and the following disclaimer, + must be included in all copies of the Software, in whole or in part, and + all derivative works of the Software, unless such copies or derivative + works are solely in the form of machine-executable object code generated by + a source language processor. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + +================================================================================ + +Portions of the thrust::complex implementation are derived from FreeBSD with the +following terms: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice[1] unmodified, this list of conditions, and the following + disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[1] Individual copyright notices from the original authors are included in + the relevant source files. + +================================================================================ diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..4b5a4a423 --- /dev/null +++ b/Makefile @@ -0,0 +1,161 @@ +# Copyright 2010-2020 NVIDIA Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Makefile for building Thrust unit test driver + +# Force C++11 mode. NVCC will ignore it if the host compiler doesn't support it. +export CXX_STD := c++11 + +export CCCL_ENABLE_DEPRECATIONS := 1 + +export VERBOSE := 1 + +ifndef PROFILE + ifdef VULCAN_TOOLKIT_BASE + include $(VULCAN_TOOLKIT_BASE)/build/getprofile.mk + include $(VULCAN_TOOLKIT_BASE)/build/config/$(PROFILE).mk + else + include ../build/getprofile.mk + include ../build/config/$(PROFILE).mk + endif +endif + +SOLNDIR := . + +ifdef VULCAN_TOOLKIT_BASE + include $(VULCAN_TOOLKIT_BASE)/build/config/DetectOS.mk +else + include ../build/config/DetectOS.mk +endif + +TMP_DIR := built +TMP_PREFIX := $(ROOTDIR) +TMP_ARCH := $(ARCH)_$(PROFILE)_agnostic +THRUST_MKDIR := $(TMP_PREFIX)/$(TMP_DIR)/$(TMP_ARCH)/thrust/mk +THRUST_DIR := $(ROOTDIR)/thrust + +res:=$(shell $(PYTHON) ./generate_mk.py $(THRUST_MKDIR) $(THRUST_DIR)) + +# Use these environment variables to control what gets built: +# +# TEST_ALL +# TEST_UNITTESTS +# TEST_EXAMPLES +# TEST_BENCH +# TEST_OTHER + +ifneq ($(TEST_ALL),) + override TEST_UNITTESTS := 1 + override TEST_EXAMPLES := 1 + override TEST_BENCH := 1 + override TEST_OTHER := 1 +endif + +ifeq ($(TEST_UNITTESTS)$(TEST_EXAMPLES)$(TEST_BENCH)$(TEST_OTHER),) + override TEST_UNITTESTS := 1 + override TEST_EXAMPLES := 1 + override TEST_BENCH := 1 + override TEST_OTHER := 1 +endif + +ifneq ($(TEST_OTHER),) + PROJECTS += internal/build/warningstester +endif + +ifneq ($(TEST_BENCH),) + PROJECTS += internal/benchmark/bench +endif + +ifneq ($(TEST_UNITTESTS),) + # copy existing projects + PROJECTS_COPY := $(PROJECTS) + + # empty PROJECTS + PROJECTS := + + # populate PROJECTS with unit tests. + include $(THRUST_MKDIR)/testing.mk + + # Once PROJECTS is populated with unit tests, re-add the previous projects. + PROJECTS += $(PROJECTS_COPY) +endif + +ifneq ($(TEST_EXAMPLES),) + # Copy existing projects. + PROJECTS_COPY := $(PROJECTS) + + # Empty PROJECTS. + PROJECTS := + + # Populate PROJECTS with examples. + include $(THRUST_MKDIR)/examples.mk + + # Once PROJECTS is populated with examples, re-add the previous projects. + PROJECTS += $(PROJECTS_COPY) +endif + +ifdef VULCAN_TOOLKIT_BASE + include $(VULCAN_TOOLKIT_BASE)/build/common.mk +else + include ../build/common.mk +endif + +ifeq ($(OS), win32) + CREATE_DVS_PACKAGE = $(ZIP) -r built/CUDA-thrust-package.zip bin thrust/internal/test thrust/internal/scripts thrust/internal/benchmark $(DVS_COMMON_TEST_PACKAGE_FILES) + APPEND_H_DVS_PACKAGE = $(ZIP) -rg built/CUDA-thrust-package.zip thrust -9 -i *.h + APPEND_INL_DVS_PACKAGE = $(ZIP) -rg built/CUDA-thrust-package.zip thrust -9 -i *.inl + APPEND_CUH_DVS_PACKAGE = $(ZIP) -rg built/CUDA-thrust-package.zip thrust -9 -i *.cuh + MAKE_DVS_PACKAGE = $(CREATE_DVS_PACKAGE) && $(APPEND_H_DVS_PACKAGE) && $(APPEND_INL_DVS_PACKAGE) && $(APPEND_CUH_DVS_PACKAGE) +else + TAR_FILES = bin thrust/internal/test thrust/internal/scripts thrust/internal/benchmark $(DVS_COMMON_TEST_PACKAGE_FILES) + TAR_FILES += `find -L thrust \( -name "*.cuh" -o -name "*.h" -o -name "*.inl" \)` + MAKE_DVS_PACKAGE = tar -I bzip2 -chvf built/CUDA-thrust-package.tar.bz2 $(TAR_FILES) +endif + +COPY_CUB_FOR_PACKAGING = rm -rf cub && cp -rp ../cub/cub cub + +DVS_OPTIONS := + +ifneq ($(TARGET_ARCH),$(HOST_ARCH)) + DVS_OPTIONS += TARGET_ARCH=$(TARGET_ARCH) +endif +ifeq ($(TARGET_ARCH),ARMv7) + DVS_OPTIONS += ABITYPE=$(ABITYPE) +endif + +THRUST_DVS_BUILD = release + +pack: + $(COPY_CUB_FOR_PACKAGING) + cd .. && $(MAKE_DVS_PACKAGE) + +dvs: + $(COPY_CUB_FOR_PACKAGING) +# Build the CUDA Runtime in GVS, because GVS has no CUDA Runtime component. +# This is a temporary workaround until the Tegra team adds a CUDA Runtime +# component, which they have promised to do. +ifdef GVS + $(MAKE) $(DVS_OPTIONS) -s -C ../cuda $(THRUST_DVS_BUILD) +endif + $(MAKE) $(DVS_OPTIONS) $(THRUST_DVS_BUILD) THRUST_DVS=1 + cd .. && $(MAKE_DVS_PACKAGE) + +dvs_release: + $(MAKE) dvs THRUST_DVS_BUILD=release + +dvs_debug: + $(MAKE) dvs THRUST_DVS_BUILD=debug + +include $(THRUST_MKDIR)/dependencies.mk + diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 6209bb423..000000000 --- a/NOTICE +++ /dev/null @@ -1,26 +0,0 @@ -Thrust includes soruce code from the Boost Iterator, Tuple, System, and Random Number libraries. - - Boost Software License - Version 1.0 - August 17th, 2003 - - Permission is hereby granted, free of charge, to any person or organization - obtaining a copy of the software and accompanying documentation covered by - this license (the "Software") to use, reproduce, display, distribute, - execute, and transmit the Software, and to prepare derivative works of the - Software, and to permit third-parties to whom the Software is furnished to - do so, all subject to the following: - - The copyright notices in the Software and this entire statement, including - the above license grant, this restriction and the following disclaimer, - must be included in all copies of the Software, in whole or in part, and - all derivative works of the Software, unless such copies or derivative - works are solely in the form of machine-executable object code generated by - a source language processor. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - diff --git a/README.md b/README.md index a98077d94..b885389d4 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,253 @@ -Thrust: Code at the speed of light -================================== +:warning: **The Thrust repository has been archived and is now part of the unified [nvidia/cccl repository](https://github.com/nvidia/cccl). See the [announcement here](https://github.com/NVIDIA/cccl/discussions/520) for more information. Please visit the new repository for the latest updates.** :warning: -Thrust is a parallel algorithms library which resembles the C++ Standard -Template Library (STL). Thrust's **high-level** interface greatly enhances -programmer **productivity** while enabling performance portability between -GPUs and multicore CPUs. **Interoperability** with established technologies -(such as CUDA, TBB, and OpenMP) facilitates integration with existing -software. Develop **high-performance** applications rapidly with Thrust! +# Thrust: The C++ Parallel Algorithms Library -Examples --------- + + + + +
ExamplesGodboltDocumentation
-Thrust is best explained through examples. The following source code -generates random numbers serially and then transfers them to a parallel -device where they are sorted. +Thrust is the C++ parallel algorithms library which inspired the introduction + of parallel algorithms to the C++ Standard Library. +Thrust's **high-level** interface greatly enhances programmer **productivity** + while enabling performance portability between GPUs and multicore CPUs. +It builds on top of established parallel programming frameworks (such as CUDA, + TBB, and OpenMP). +It also provides a number of general-purpose facilities similar to those found + in the C++ Standard Library. -```c++ +The NVIDIA C++ Standard Library is an open source project; it is available on + [GitHub] and included in the NVIDIA HPC SDK and CUDA Toolkit. +If you have one of those SDKs installed, no additional installation or compiler + flags are needed to use libcu++. + +## Examples + +Thrust is best learned through examples. + +The following example generates random numbers serially and then transfers them + to a parallel device where they are sorted. + +```cuda #include #include #include #include #include -#include -#include +#include -int main(void) -{ - // generate 32M random numbers serially +int main() { + // Generate 32M random numbers serially. + thrust::default_random_engine rng(1337); + thrust::uniform_int_distribution dist; thrust::host_vector h_vec(32 << 20); - std::generate(h_vec.begin(), h_vec.end(), rand); + thrust::generate(h_vec.begin(), h_vec.end(), [&] { return dist(rng); }); - // transfer data to the device + // Transfer data to the device. thrust::device_vector d_vec = h_vec; - // sort data on the device (846M keys per second on GeForce GTX 480) + // Sort data on the device. thrust::sort(d_vec.begin(), d_vec.end()); - // transfer data back to host + // Transfer data back to host. thrust::copy(d_vec.begin(), d_vec.end(), h_vec.begin()); - - return 0; } ``` - -This code sample computes the sum of 100 random numbers in parallel: -```c++ +[See it on Godbolt](https://godbolt.org/z/GeWEd8Er9) + +This example demonstrates computing the sum of some random numbers in parallel: + +```cuda #include #include #include #include #include -#include -#include +#include -int main(void) -{ - // generate random data serially - thrust::host_vector h_vec(100); - std::generate(h_vec.begin(), h_vec.end(), rand); +int main() { + // Generate random data serially. + thrust::default_random_engine rng(1337); + thrust::uniform_real_distribution dist(-50.0, 50.0); + thrust::host_vector h_vec(32 << 20); + thrust::generate(h_vec.begin(), h_vec.end(), [&] { return dist(rng); }); - // transfer to device and compute sum - thrust::device_vector d_vec = h_vec; - int x = thrust::reduce(d_vec.begin(), d_vec.end(), 0, thrust::plus()); - return 0; + // Transfer to device and compute the sum. + thrust::device_vector d_vec = h_vec; + double x = thrust::reduce(d_vec.begin(), d_vec.end(), 0, thrust::plus()); } ``` - -Refer to the [Quick Start Guide](http://github.com/thrust/thrust/wiki/Quick-Start-Guide) page for further information and examples. -Contributors ------------- +[See it on Godbolt](https://godbolt.org/z/cnsbWWME7) + +This example show how to perform such a reduction asynchronously: + +```cuda +#include +#include +#include +#include +#include +#include +#include +#include + +int main() { + // Generate 32M random numbers serially. + thrust::default_random_engine rng(123456); + thrust::uniform_real_distribution dist(-50.0, 50.0); + thrust::host_vector h_vec(32 << 20); + thrust::generate(h_vec.begin(), h_vec.end(), [&] { return dist(rng); }); + + // Asynchronously transfer to the device. + thrust::device_vector d_vec(h_vec.size()); + thrust::device_event e = thrust::async::copy(h_vec.begin(), h_vec.end(), + d_vec.begin()); + + // After the transfer completes, asynchronously compute the sum on the device. + thrust::device_future f0 = thrust::async::reduce(thrust::device.after(e), + d_vec.begin(), d_vec.end(), + 0.0, thrust::plus()); + + // While the sum is being computed on the device, compute the sum serially on + // the host. + double f1 = std::accumulate(h_vec.begin(), h_vec.end(), 0.0, thrust::plus()); +} +``` + +[See it on Godbolt](https://godbolt.org/z/be54efaKj) + +## Getting The Thrust Source Code + +Thrust is a header-only library; there is no need to build or install the project +unless you want to run the Thrust unit tests. + +The CUDA Toolkit provides a recent release of the Thrust source code in +`include/thrust`. This will be suitable for most users. + +Users that wish to contribute to Thrust or try out newer features should +recursively clone the Thrust Github repository: + +``` +git clone --recursive https://github.com/NVIDIA/thrust.git +``` + +## Using Thrust From Your Project + +For CMake-based projects, we provide a CMake package for use with +`find_package`. See the [CMake README](thrust/cmake/README.md) for more +information. Thrust can also be added via `add_subdirectory` or tools like +the [CMake Package Manager](https://github.com/cpm-cmake/CPM.cmake). + +For non-CMake projects, compile with: +- The Thrust include path (`-I`) +- The libcu++ include path (`-I/dependencies/libcudacxx/`) +- The CUB include path, if using the CUDA device system (`-I/dependencies/cub/`) +- By default, the CPP host system and CUDA device system are used. + These can be changed using compiler definitions: + - `-DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_XXX`, + where `XXX` is `CPP` (serial, default), `OMP` (OpenMP), or `TBB` (Intel TBB) + - `-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_XXX`, where `XXX` is + `CPP`, `OMP`, `TBB`, or `CUDA` (default). + +## Developing Thrust + +Thrust uses the [CMake build system] to build unit tests, examples, and header + tests. +To build Thrust as a developer, it is recommended that you use our + containerized development system: + +```bash +# Clone Thrust and CUB repos recursively: +git clone --recursive https://github.com/NVIDIA/thrust.git +cd thrust + +# Build and run tests and examples: +ci/local/build.bash +``` + +That does the equivalent of the following, but in a clean containerized + environment which has all dependencies installed: + +```bash +# Clone Thrust and CUB repos recursively: +git clone --recursive https://github.com/NVIDIA/thrust.git +cd thrust + +# Create build directory: +mkdir build +cd build + +# Configure -- use one of the following: +cmake .. # Command line interface. +ccmake .. # ncurses GUI (Linux only). +cmake-gui # Graphical UI, set source/build directories in the app. + +# Build: +cmake --build . -j ${NUM_JOBS} # Invokes make (or ninja, etc). + +# Run tests and examples: +ctest +``` + +By default, a serial `CPP` host system, `CUDA` accelerated device system, and + C++14 standard are used. +This can be changed in CMake and via flags to `ci/local/build.bash` + +More information on configuring your Thrust build and creating a pull request + can be found in the [contributing section]. + +## Licensing + +Thrust is an open source project developed on [GitHub]. +Thrust is distributed under the [Apache License v2.0 with LLVM Exceptions]; + some parts are distributed under the [Apache License v2.0] and the + [Boost License v1.0]. + +## CI Status + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[GitHub]: https://github.com/nvidia/thrust + +[CMake section]: https://nvidia.github.io/thrust/setup/cmake_options.html +[contributing section]: https://nvidia.github.io/thrust/contributing.html + +[CMake build system]: https://cmake.org + +[Apache License v2.0 with LLVM Exceptions]: https://llvm.org/LICENSE.txt +[Apache License v2.0]: https://www.apache.org/licenses/LICENSE-2.0.txt +[Boost License v1.0]: https://www.boost.org/LICENSE_1_0.txt -The original creators of Thrust are [Jared Hoberock](http://github.com/jaredhoberock) and [Nathan Bell](http://research.nvidia.com/users/nathan-bell). diff --git a/SConscript b/SConscript deleted file mode 100644 index 39797f99f..000000000 --- a/SConscript +++ /dev/null @@ -1,43 +0,0 @@ -import os -import re -Import('env') - -# clone the environment so as not to pollute the parent -my_env = env.Clone() - -# divine the version number from thrust/version.h -version = int(re.search('THRUST_VERSION ([0-9]+)', File('#thrust/version.h').get_contents()).group(1)) -major = int(version / 100000) -minor = int(version / 100) % 1000 -subminor = version % 100 - -# create the Thrust zip -for item in my_env.RecursiveGlob('*', '#thrust'): - my_env.InstallAs(os.path.join('thrust', Dir('#thrust').rel_path(item)), item) -# grab the CHANGELOG as well -my_env.Install('thrust', '#CHANGELOG') - -# make sure to change directory into the variant dir to ensure the paths are correct in the zipfile -# note Zip uses the special site_scons/site_tools/zip.py to WAR an issue with the chdir parameter -thrust_zipfile = my_env.Zip('thrust-{0}.{1}.{2}.zip'.format(major,minor,subminor), 'thrust', chdir = 1) -my_env.Alias('dist', thrust_zipfile) - - -# create the examples zip -# do not recurse into the 'targets' directory, should it exist -for item in my_env.RecursiveGlob('*', '#examples', 'targets'): - # avoid included SCons-related files in the distribution - # XXX would be nice if we could ignore all dotfiles and anything in .gitignore - if item.get_path(item.get_dir()) not in ['SConscript','.sconsign.dblite']: - my_env.InstallAs(os.path.join('examples', Dir('#examples').rel_path(item)), item) -# make sure to change directory into the variant dir to ensure the paths are correct in the zipfile -# note Zip uses the special site_scons/site_tools/zip.py to WAR an issue with the chdir parameter -examples_zipfile = my_env.Zip('examples-{0}.{1}.zip'.format(major,minor), 'examples', chdir = 1) -my_env.Alias('dist', examples_zipfile) - -# generate documentation -# note that thrust.dox instructs doxygen to output to the targets directory -public_headers = my_env.RecursiveGlob('*.h', '#thrust', exclude='detail') -thrust_docs = my_env.Command('doc/html', public_headers, 'doxygen doc/thrust.dox') -my_env.Alias('doc', thrust_docs) - diff --git a/SConstruct b/SConstruct deleted file mode 100644 index e96445c13..000000000 --- a/SConstruct +++ /dev/null @@ -1,476 +0,0 @@ -"""Exports a SCons construction environment 'env' with configuration common to all build projects""" -EnsureSConsVersion(1,2) - -import os -import platform -import glob -import itertools -import subprocess - - -def RecursiveGlob(env, pattern, directory = Dir('.'), exclude = '\B'): - """Recursively globs a directory and its children, returning a list of sources. - Allows exclusion of directories given a regular expression. - """ - directory = Dir(directory) - - result = directory.glob(pattern) - - for n in directory.glob('*'): - # only recurse into directories which aren't in the blacklist - import re - if isinstance(n,type(directory)) and not re.match(exclude, directory.rel_path(n)): - result.extend(RecursiveGlob(env, pattern, n, exclude)) - return result - - -# map features to the list of compiler switches implementing them -gnu_compiler_flags = { - 'warn_all' : ['-Wall'], - 'warnings_as_errors' : ['-Werror'], - 'release' : ['-O2'], - 'debug' : ['-g'], - 'exception_handling' : [], - 'cpp' : [], - 'omp' : ['-fopenmp'], - 'tbb' : [], - 'cuda' : [], - 'workarounds' : [] -} - -clang_compiler_flags = { - 'warn_all' : ['-Wall'], - 'warnings_as_errors' : ['-Werror'], - 'release' : ['-O2'], - 'debug' : ['-g'], - 'exception_handling' : [], - 'cpp' : [], - 'omp' : ['-fopenmp'], - 'tbb' : [], - 'cuda' : [], - 'workarounds' : [] -} - -msvc_compiler_flags = { - 'warn_all' : ['/Wall'], - 'warnings_as_errors' : ['/WX'], - 'release' : ['/Ox'], - 'debug' : ['/Zi', '-D_DEBUG', '/MTd'], - 'exception_handling' : ['/EHsc'], - 'cpp' : [], - 'omp' : ['/openmp'], - 'tbb' : [], - 'cuda' : [], - - # avoid min/max problems due to windows.h - # suppress warnings due to "decorated name length exceeded" - 'workarounds' : ['/DNOMINMAX', '/wd4503'] -} - -compiler_to_flags = { - 'g++' : gnu_compiler_flags, - 'cl' : msvc_compiler_flags, - 'clang++' : clang_compiler_flags -} - -gnu_linker_flags = { - 'debug' : [], - 'release' : [], - 'workarounds' : [] -} - -nv_linker_flags = gnu_linker_flags - -clang_linker_flags = { - 'debug' : [], - 'release' : [], - 'workarounds' : ['-stdlib=libstdc++'] -} - -msvc_linker_flags = { - 'debug' : ['/debug'], - 'release' : [], - 'workarounds' : ['/nologo'] -} - -linker_to_flags = { - 'gcc' : gnu_linker_flags, - 'link' : msvc_linker_flags, - 'nvcc' : nv_linker_flags, - 'clang++' : clang_linker_flags -} - - -def cuda_installation(): - """Returns the details of CUDA's installation - returns (bin_path,lib_path,inc_path,library_name) - """ - - # determine defaults - if os.name == 'nt': - bin_path = 'C:/CUDA/bin' - lib_path = 'C:/CUDA/lib' - inc_path = 'C:/CUDA/include' - elif os.name == 'posix': - bin_path = '/usr/local/cuda/bin' - lib_path = '/usr/local/cuda/lib' - inc_path = '/usr/local/cuda/include' - else: - raise ValueError, 'Error: unknown OS. Where is nvcc installed?' - - if master_env['PLATFORM'] != 'darwin' and platform.machine()[-2:] == '64': - lib_path += '64' - - # override with environement variables - if 'CUDA_BIN_PATH' in os.environ: - bin_path = os.path.abspath(os.environ['CUDA_BIN_PATH']) - if 'CUDA_LIB_PATH' in os.environ: - lib_path = os.path.abspath(os.environ['CUDA_LIB_PATH']) - if 'CUDA_INC_PATH' in os.environ: - inc_path = os.path.abspath(os.environ['CUDA_INC_PATH']) - - return (bin_path,lib_path,inc_path,'cudart') - - -def omp_installation(CXX): - """Returns the details of OpenMP's installation - returns (bin_path,lib_path,inc_path,library_name) - """ - - bin_path = '' - lib_path = '' - inc_path = '' - - # the name of the library is compiler-dependent - library_name = '' - if CXX == 'g++': - library_name = 'gomp' - elif CXX == 'cl': - library_name = 'VCOMP' - elif CXX == 'clang++': - raise NotImplementedError, "OpenMP not supported together with clang" - else: - raise ValueError, "Unknown compiler. What is the name of the OpenMP library?" - - return (bin_path,lib_path,inc_path,library_name) - - -def tbb_installation(env): - """Returns the details of TBB's installation - returns (bin_path,lib_path,inc_path,library_name) - """ - - # determine defaults - if os.name == 'nt': - try: - # we assume that TBBROOT exists in the environment - root = env['ENV']['TBBROOT'] - - # choose bitness - bitness = 'ia32' - if platform.machine()[-2:] == '64': - bitness = 'intel64' - - # choose msvc version - msvc_version = 'vc' + str(int(float(env['MSVC_VERSION']))) - - # assemble paths - bin_path = os.path.join(root, 'bin', bitness, msvc_version) - lib_path = os.path.join(root, 'lib', bitness, msvc_version) - inc_path = os.path.join(root, 'include') - - except: - raise ValueError, 'Where is TBB installed?' - else: - bin_path = '' - lib_path = '' - inc_path = '' - - return (bin_path,lib_path,inc_path,'tbb') - - -def inc_paths(env, host_backend, device_backend): - """Returns a list of include paths needed by the compiler""" - result = [] - thrust_inc_path = Dir('.') - - # note that the thrust path comes before the cuda path, which - # may itself contain a different version of thrust - result.append(thrust_inc_path) - - if host_backend == 'cuda' or device_backend == 'cuda': - cuda_inc_path = cuda_installation()[2] - result.append(cuda_inc_path) - - if host_backend == 'tbb' or device_backend == 'tbb': - tbb_inc_path = tbb_installation(env)[2] - result.append(tbb_inc_path) - - return result - - -def lib_paths(env, host_backend, device_backend): - """Returns a list of lib paths needed by the linker""" - result = [] - - if host_backend == 'cuda' or device_backend == 'cuda': - cuda_lib_path = cuda_installation()[1] - result.append(cuda_lib_path) - - if host_backend == 'tbb' or device_backend == 'tbb': - tbb_lib_path = tbb_installation(env)[1] - result.append(tbb_lib_path) - - return result - - -def libs(env, CCX, host_backend, device_backend): - """Returns a list of libraries to link against""" - result = [] - - # when compiling with g++, link against the standard library - # we don't have to do this with cl - if CCX == 'g++': - result.append('stdc++') - result.append('m') - - # link against backend-specific runtimes - if host_backend == 'cuda' or device_backend == 'cuda': - result.append(cuda_installation()[3]) - - # XXX clean this up - if env['cdp']: - result.append('cudadevrt') - - if host_backend == 'omp' or device_backend == 'omp': - result.append(omp_installation(CCX)[3]) - - if host_backend == 'tbb' or device_backend == 'tbb': - result.append(tbb_installation(env)[3]) - - return result - - -def linker_flags(LINK, mode, platform, device_backend, arch): - """Returns a list of command line flags needed by the linker""" - result = [] - - flags = linker_to_flags[LINK] - - # debug/release - result.extend(flags[mode]) - - # unconditional workarounds - result.extend(flags['workarounds']) - - return result - - -def macros(mode, host_backend, device_backend): - """Returns a list of preprocessor macros needed by the compiler""" - result = [] - - # backend defines - result.append('-DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_' + host_backend.upper()) - result.append('-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_' + device_backend.upper()) - - if mode == 'debug': - # turn on thrust debug mode - result.append('-DTHRUST_DEBUG') - - return result - - -def cc_compiler_flags(CXX, mode, platform, host_backend, device_backend, warn_all, warnings_as_errors): - """Returns a list of command line flags needed by the c or c++ compiler""" - # start with all platform-independent preprocessor macros - result = macros(mode, host_backend, device_backend) - - flags = compiler_to_flags[CXX] - - # continue with unconditional flags - - # exception handling - result.extend(flags['exception_handling']) - - # finish with conditional flags - - # debug/release - result.extend(flags[mode]) - - # enable host_backend code generation - result.extend(flags[host_backend]) - - # enable device_backend code generation - result.extend(flags[device_backend]) - - # Wall - if warn_all: - result.extend(flags['warn_all']) - - # Werror - if warnings_as_errors: - result.extend(flags['warnings_as_errors']) - - # workarounds - result.extend(flags['workarounds']) - - return result - - -def nv_compiler_flags(mode, device_backend, arch, cdp): - """Returns a list of command line flags specific to nvcc""" - result = [] - for machine_arch in arch: - # transform arch_XX to compute_XX - virtual_arch = machine_arch.replace('sm','compute') - # the weird -gencode flag is formatted like this: - # -gencode=arch=compute_10,code=\"sm_20,compute_20\" - result.append('-gencode=arch={0},\\"code={1},{2}\\"'.format(virtual_arch, machine_arch, virtual_arch)) - - if mode == 'debug': - # turn on debug mode - # XXX make this work when we've debugged nvcc -G - #result.append('-G') - pass - if device_backend != 'cuda': - result.append("--x=c++") - if cdp != False: - result.append("-rdc=true") - - if device_backend == 'cuda' and master_env['PLATFORM'] == 'darwin': - (release, versioninfo, machine) = platform.mac_ver() - if(release[0:5] == '10.8.'): - result.append('-ccbin') - result.append(master_env.subst('$CXX')) - - return result - - -def command_line_variables(): - # allow the user discretion to select the MSVC version - vars = Variables() - if os.name == 'nt': - vars.Add(EnumVariable('MSVC_VERSION', 'MS Visual C++ version', None, allowed_values=('8.0', '9.0', '10.0'))) - - # add a variable to handle the host backend - vars.Add(ListVariable('host_backend', 'The host backend to target', 'cpp', - ['cpp', 'omp', 'tbb'])) - - # add a variable to handle the device backend - vars.Add(ListVariable('device_backend', 'The parallel device backend to target', 'cuda', - ['cuda', 'omp', 'tbb', 'cpp'])) - - # add a variable to handle release/debug mode - vars.Add(EnumVariable('mode', 'Release versus debug mode', 'release', - allowed_values = ('release', 'debug'))) - - # XXX allow the option to send sm_1x to nvcc even nvcc may not support it - vars.Add(ListVariable('arch', 'Compute capability code generation', 'sm_20', - ['sm_10', 'sm_11', 'sm_12', 'sm_13', - 'sm_20', 'sm_21', - 'sm_30', 'sm_32', 'sm_35', 'sm_37', - 'sm_50'])) - - # add a variable to handle CUDA dynamic parallelism - vars.Add(BoolVariable('cdp', 'Enable CUDA dynamic parallelism', False)) - - # add a variable to handle warnings - # only enable Wall by default on compilers other than cl - vars.Add(BoolVariable('Wall', 'Enable all compilation warnings', os.name != 'nt')) - - # add a variable to treat warnings as errors - vars.Add(BoolVariable('Werror', 'Treat warnings as errors', os.name != 'nt')) - - return vars - - -# create a master Environment -vars = command_line_variables() - -master_env = Environment(variables = vars, tools = ['default', 'nvcc', 'zip']) - -# XXX it might be a better idea to harvest help text from subsidiary -# SConscripts and only add their help text if one of their targets -# is scheduled to be built -Help(vars.GenerateHelpText(master_env)) - -# enable RecursiveGlob -master_env.AddMethod(RecursiveGlob) - -# add CUDA's lib dir to LD_LIBRARY_PATH so that we can execute commands -# which depend on shared libraries (e.g., cudart) -# we don't need to do this on windows -if master_env['PLATFORM'] == 'posix': - master_env['ENV'].setdefault('LD_LIBRARY_PATH', []).append(cuda_installation()[1]) -elif master_env['PLATFORM'] == 'darwin': - master_env['ENV'].setdefault('DYLD_LIBRARY_PATH', []).append(cuda_installation()[1]) - # Check if g++ really is g++ - if(master_env.subst('$CXX') == 'g++'): - output = subprocess.check_output(['g++','--version']) - if(output.find('clang') != -1): - # It's actually clang - master_env.Replace(CXX = 'clang++') - if(master_env.subst('$CC') == 'gcc'): - output = subprocess.check_output(['gcc','--version']) - if(output.find('clang') != -1): - # It's actually clang - master_env.Replace(CC = 'clang') - if(master_env.subst('$LINK') == 'clang'): - master_env.Replace(CC = 'clang++') - -elif master_env['PLATFORM'] == 'win32': - master_env['ENV']['TBBROOT'] = os.environ['TBBROOT'] - master_env['ENV']['PATH'] += ';' + tbb_installation(master_env)[0] - - -# get the list of requested backends -host_backends = master_env.subst('$host_backend').split() -device_backends = master_env.subst('$device_backend').split() - -for (host,device) in itertools.product(host_backends, device_backends): - # clone the master environment for this config - env = master_env.Clone() - - # populate the environment - env.Append(CPPPATH = inc_paths(env, host, device)) - - env.Append(CCFLAGS = cc_compiler_flags(env.subst('$CXX'), env['mode'], env['PLATFORM'], host, device, env['Wall'], env['Werror'])) - - env.Append(NVCCFLAGS = nv_compiler_flags(env['mode'], device, env['arch'], env['cdp'])) - - env.Append(LIBS = libs(env, env.subst('$CXX'), host, device)) - - # XXX this probably doesn't belong here - # XXX ideally we'd integrate this into site_scons - if 'cudadevrt' in env['LIBS']: - # nvcc is required to link against cudadevrt - env.Replace(LINK = 'nvcc') - - if os.name == 'nt': - # the nv linker uses the same command line as the gnu linker - env['LIBDIRPREFIX'] = '-L' - env['LIBLINKPREFIX'] = '-l' - env['LIBLINKSUFFIX'] = '' - env.Replace(LINKCOM = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS') - - # we Replace instead of Append, to avoid picking-up MSVC-specific flags on Windows - env.Replace(LINKFLAGS = linker_flags(env.subst('$LINK'), env['mode'], env['PLATFORM'], device, env['arch'])) - - env.Append(LIBPATH = lib_paths(env, host, device)) - - # assemble the name of this configuration's targets directory - targets_dir = 'targets/{0}_host_{1}_device_{2}'.format(host, device, env['mode']) - - # allow subsidiary SConscripts to peek at the backends - env['host_backend'] = host - env['device_backend'] = device - - # invoke each SConscript with a variant directory - env.SConscript('examples/SConscript', exports='env', variant_dir = 'examples/' + targets_dir, duplicate = 0) - env.SConscript('testing/SConscript', exports='env', variant_dir = 'testing/' + targets_dir, duplicate = 0) - env.SConscript('performance/SConscript', exports='env', variant_dir = 'performance/' + targets_dir, duplicate = 0) - -env = master_env -master_env.SConscript('SConscript', exports='env', variant_dir = 'targets', duplicate = False) - diff --git a/THANKS b/THANKS deleted file mode 100644 index 5829b113f..000000000 --- a/THANKS +++ /dev/null @@ -1,32 +0,0 @@ -Thrust is an open source library of parallel algorithms with an interface -resembling the C++ Standard Template Library (STL). The primary developers -of Thrust are Jared Hoberock [1] and Nathan Bell [2] of NVIDIA Research. - -We wish to thank the following people, who have made important intellectual -and/or software contributions to the project: - - * Andrew Corrigan - * David Tarjan - * Duane Merrill - * Erich Elsen - * Gregory Diamos - * Manjunath Kudlur - * Mark Harris - * Michael Garland - * Nadathur Satish - * Nathan Whitehead - * Ryuta Suzuki - * Shubho Sengupta - * Thomas Bradley - -We also thank the compiler group at NVIDIA for their continued improvements to -nvcc. In particular, we appreciate the work Bastiaan Aarts has done to enhance -nvcc's C++ support. - -Lastly, Thrust has greatly benefited from the design and implementation of -the Boost Iterator, Tuple, System, Phoenix, and Random Number libraries [3]. - -[1] http://research.nvidia.com/users/jared-hoberock -[2] http://research.nvidia.com/users/nathan-bell -[3] http://www.boost.org/ - diff --git a/ci/axis/cpu.yml b/ci/axis/cpu.yml new file mode 100644 index 000000000..cc393169d --- /dev/null +++ b/ci/axis/cpu.yml @@ -0,0 +1,61 @@ +# Copyright (c) 2018-2020 NVIDIA Corporation +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# Released under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. + +SDK_TYPE: + - cuda + +SDK_VER: + - 11.7.0-devel + +OS_TYPE: + - ubuntu + +OS_VER: + - 20.04 + +CXX_TYPE: + - clang + - gcc + - icc + +CXX_VER: + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + - latest + +exclude: + # Excludes by `CXX_VER`. + - CXX_TYPE: gcc + CXX_VER: 12 + - CXX_TYPE: gcc + CXX_VER: latest + - CXX_TYPE: clang + CXX_VER: 5 + - CXX_TYPE: clang + CXX_VER: 6 + - CXX_TYPE: clang + CXX_VER: latest + - CXX_TYPE: icc + CXX_VER: 5 + - CXX_TYPE: icc + CXX_VER: 6 + - CXX_TYPE: icc + CXX_VER: 7 + - CXX_TYPE: icc + CXX_VER: 8 + - CXX_TYPE: icc + CXX_VER: 9 + - CXX_TYPE: icc + CXX_VER: 10 + - CXX_TYPE: icc + CXX_VER: 11 + - CXX_TYPE: icc + CXX_VER: 12 diff --git a/ci/axis/gpu.yml b/ci/axis/gpu.yml new file mode 100644 index 000000000..550083aab --- /dev/null +++ b/ci/axis/gpu.yml @@ -0,0 +1,22 @@ +# Copyright (c) 2018-2020 NVIDIA Corporation +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# Released under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. + +SDK_TYPE: + - cuda + +SDK_VER: + - 11.7.0-devel + +OS_TYPE: + - ubuntu + +OS_VER: + - 20.04 + +CXX_TYPE: + - gcc + +CXX_VER: + - 9 diff --git a/ci/common/build.bash b/ci/common/build.bash new file mode 100755 index 000000000..37aafaf8b --- /dev/null +++ b/ci/common/build.bash @@ -0,0 +1,439 @@ +#! /usr/bin/env bash + +# Copyright (c) 2018-2022 NVIDIA Corporation +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# Released under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. + +################################################################################ +# Thrust and CUB build script for gpuCI +################################################################################ + +set -e # Stop on errors. + +# append variable value +# Appends ${value} to ${variable}, adding a space before ${value} if +# ${variable} is not empty. +function append { + tmp="${!1:+${!1} }${2}" + eval "${1}=\${tmp}" +} + +# log args... +# Prints out ${args[*]} with a gpuCI log prefix and a newline before and after. +function log() { + printf "\n>>>> %s\n\n" "${*}" +} + +# print_with_trailing_blank_line args... +# Prints ${args[*]} with one blank line following, preserving newlines within +# ${args[*]} but stripping any preceding ${args[*]}. +function print_with_trailing_blank_line { + printf "%s\n\n" "${*}" +} + +# echo_and_run name args... +# Echo ${args[@]}, then execute ${args[@]} +function echo_and_run { + echo "${1}: ${@:2}" + ${@:2} +} + +# echo_and_run_timed name args... +# Echo ${args[@]}, then execute ${args[@]} and report how long it took, +# including ${name} in the output of the time. +function echo_and_run_timed { + echo "${@:2}" + TIMEFORMAT=$'\n'"${1} Time: %lR" + time ${@:2} +} + +# join_delimit [value [value [...]]] +# Combine all values into a single string, separating each by a single character +# delimiter. Eg: +# foo=(bar baz kramble) +# joined_foo=$(join_delimit "|" "${foo[@]}") +# echo joined_foo # "bar|baz|kramble" +function join_delimit { + local IFS="${1}" + shift + echo "${*}" +} + +################################################################################ +# VARIABLES - Set up bash and environmental variables. +################################################################################ + +# Get the variables the Docker container set up for us: ${CXX}, ${CUDACXX}, etc. +set +e # Don't stop on errors from /etc/cccl.bashrc. +source /etc/cccl.bashrc +set -e # Stop on errors. + +# Configure sccache. +if [[ "${CXX_TYPE}" == "nvcxx" ]]; then + log "Disabling sccache (nvcxx not supported)" + unset ENABLE_SCCACHE +elif [[ "${BUILD_MODE}" == "pull-request" || "${BUILD_MODE}" == "branch" ]]; then + # gpuCI builds cache in S3. + export ENABLE_SCCACHE="gpuCI" + # Change to 'thrust-aarch64' if we add aarch64 builds to gpuCI: + export SCCACHE_S3_KEY_PREFIX=thrust-linux64 # [linux64] + export SCCACHE_BUCKET=rapids-sccache-east + export SCCACHE_REGION=us-east-2 + export SCCACHE_IDLE_TIMEOUT=32768 +else + export ENABLE_SCCACHE="local" + # local builds cache locally + export SCCACHE_DIR="${WORKSPACE}/build-sccache" +fi + +# Set sccache compiler flags +if [[ -n "${ENABLE_SCCACHE}" ]]; then + export CMAKE_CUDA_COMPILER_LAUNCHER="sccache" + export CMAKE_CXX_COMPILER_LAUNCHER="sccache" + export CMAKE_C_COMPILER_LAUNCHER="sccache" +fi + +# Set path. +export PATH=/usr/local/cuda/bin:${PATH} + +# Set home to the job's workspace. +export HOME=${WORKSPACE} + +# Per-process memory util logs: +MEMMON_LOG=${WORKSPACE}/build/memmon_log + +# Switch to the build directory. +cd ${WORKSPACE} +mkdir -p build +cd build + +# Remove any old .ninja_log file so the PrintNinjaBuildTimes step is accurate: +rm -f .ninja_log + +if [[ -z "${CMAKE_BUILD_TYPE}" ]]; then + CMAKE_BUILD_TYPE="Release" +fi + +CMAKE_BUILD_FLAGS="--" + +# The Docker image sets up `${CXX}` and `${CUDACXX}`. +append CMAKE_FLAGS "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" +append CMAKE_FLAGS "-DCMAKE_CUDA_COMPILER='${CUDACXX}'" + +if [[ "${CXX_TYPE}" == "nvcxx" ]]; then + # NVC++ isn't properly detected by CMake, so we have to tell CMake to ignore + # detection and explicit provide the compiler ID. Ninja currently isn't + # supported, so we just use makefiles. + append CMAKE_FLAGS "-DCMAKE_CUDA_COMPILER_FORCED=ON" + append CMAKE_FLAGS "-DCMAKE_CUDA_COMPILER_ID=NVCXX" + # We use NVC++ "slim" image which only contain a single CUDA toolkit version. + # When using NVC++ in an environment without GPUs (like our CPU-only + # builders) it unfortunately defaults to the oldest CUDA toolkit version it + # supports, even if that version is not in the image. So, we have to + # explicitly tell NVC++ it which CUDA toolkit version to use. + CUDA_VER=$(echo ${SDK_VER} | sed 's/.*\(cuda[0-9]\+\.[0-9]\+\)/\1/') + append CMAKE_FLAGS "-DCMAKE_CUDA_FLAGS=-gpu=${CUDA_VER}" + # Don't stop on build failures. + append CMAKE_BUILD_FLAGS "-k" +else + if [[ "${CXX_TYPE}" == "icc" ]]; then + # Only the latest version of the Intel C++ compiler, which NVCC doesn't + # officially support yet, is freely available. + append CMAKE_FLAGS "-DCMAKE_CUDA_FLAGS=-allow-unsupported-compiler" + fi + # We're using NVCC so we need to set the host compiler. + append CMAKE_FLAGS "-DCMAKE_CXX_COMPILER='${CXX}'" + append CMAKE_FLAGS "-G Ninja" + # Don't stop on build failures. + append CMAKE_BUILD_FLAGS "-k0" +fi + +DETERMINE_PARALLELISM_FLAGS="" + +# Used to limit the number of default build threads. Any build/link +# steps that exceed this limit will cause this script to report a +# failure. Tune this using the memmon logs printed after each run. +# +# Build steps that take more memory than this limit should +# be split into multiple steps/translation units. Any temporary +# increases to this threshold should be reverted ASAP. The goal +# to do decrease this as much as possible and not increase it. +if [[ -z "${MIN_MEMORY_PER_THREAD}" ]]; then + if [[ "${CXX_TYPE}" == "nvcxx" ]]; then + MIN_MEMORY_PER_THREAD=3.0 # GiB + elif [[ "${CXX_TYPE}" == "icc" ]]; then + MIN_MEMORY_PER_THREAD=2.5 # GiB + else + MIN_MEMORY_PER_THREAD=2.0 # GiB + fi +fi +append DETERMINE_PARALLELISM_FLAGS "--min-memory-per-thread ${MIN_MEMORY_PER_THREAD}" + +if [[ -n "${PARALLEL_LEVEL}" ]]; then + append DETERMINE_PARALLELISM_FLAGS "-j ${PARALLEL_LEVEL}" +fi + +# COVERAGE_PLAN options: +# * Exhaustive +# * Thorough +# * Minimal +if [[ -z "${COVERAGE_PLAN}" ]]; then + # `ci/local/build.bash` always sets a coverage plan, so we can assume we're + # in gpuCI if one was not set. + if [[ "${CXX_TYPE}" == "nvcxx" ]]; then + # Today, NVC++ builds take too long to do anything more than Minimal. + COVERAGE_PLAN="Minimal" + elif [[ "${BUILD_TYPE}" == "cpu" ]] && [[ "${BUILD_MODE}" == "branch" ]]; then + # Post-commit CPU CI builds. + COVERAGE_PLAN="Exhaustive" + elif [[ "${BUILD_TYPE}" == "cpu" ]]; then + # Pre-commit CPU CI builds. + COVERAGE_PLAN="Thorough" + elif [[ "${BUILD_TYPE}" == "gpu" ]]; then + # Pre- and post-commit GPU CI builds. + COVERAGE_PLAN="Minimal" + fi +fi + +case "${COVERAGE_PLAN}" in + Exhaustive) + append CMAKE_FLAGS "-DTHRUST_ENABLE_MULTICONFIG=ON" + append CMAKE_FLAGS "-DTHRUST_IGNORE_DEPRECATED_CPP_11=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_DIALECT_ALL=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_CPP=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_TBB=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_OMP=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_CUDA=ON" + append CMAKE_FLAGS "-DTHRUST_INCLUDE_CUB_CMAKE=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_WORKLOAD=LARGE" + ;; + Thorough) + # Build the legacy bench.cu. We'll probably want to remove this when we + # switch to the new, heavier thrust_benchmarks project. + append CMAKE_FLAGS "-DTHRUST_ENABLE_BENCHMARKS=ON" + append CMAKE_FLAGS "-DTHRUST_ENABLE_MULTICONFIG=ON" + append CMAKE_FLAGS "-DTHRUST_IGNORE_DEPRECATED_CPP_11=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_DIALECT_ALL=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_CPP=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_TBB=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_OMP=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_CUDA=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_WORKLOAD=SMALL" + append CMAKE_FLAGS "-DTHRUST_INCLUDE_CUB_CMAKE=ON" + append CMAKE_FLAGS "-DTHRUST_AUTO_DETECT_COMPUTE_ARCHS=ON" + if [[ "${CXX_TYPE}" != "nvcxx" ]]; then + # NVC++ can currently only target one compute architecture at a time. + append CMAKE_FLAGS "-DTHRUST_ENABLE_COMPUTE_50=ON" + append CMAKE_FLAGS "-DTHRUST_ENABLE_COMPUTE_60=ON" + append CMAKE_FLAGS "-DTHRUST_ENABLE_COMPUTE_70=ON" + fi + append CMAKE_FLAGS "-DTHRUST_ENABLE_COMPUTE_80=ON" + ;; + Minimal) + append CMAKE_FLAGS "-DTHRUST_ENABLE_MULTICONFIG=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_DIALECT_LATEST=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_CPP=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_TBB=OFF" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_OMP=OFF" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_ENABLE_SYSTEM_CUDA=ON" + append CMAKE_FLAGS "-DTHRUST_MULTICONFIG_WORKLOAD=SMALL" + append CMAKE_FLAGS "-DTHRUST_INCLUDE_CUB_CMAKE=ON" + append CMAKE_FLAGS "-DTHRUST_AUTO_DETECT_COMPUTE_ARCHS=ON" + if [[ "${BUILD_TYPE}" == "cpu" ]] && [[ "${CXX_TYPE}" == "nvcxx" ]]; then + # If no GPU is automatically detected, NVC++ insists that you explicitly + # provide an architecture. + # TODO: This logic should really be moved into CMake, but it will be + # tricky to do that until CMake officially supports NVC++. + append CMAKE_FLAGS "-DTHRUST_ENABLE_COMPUTE_80=ON" + fi + ;; +esac + +if [[ -n "${@}" ]]; then + append CMAKE_BUILD_FLAGS "${@}" +fi + +append CTEST_FLAGS "--output-on-failure" + +CTEST_EXCLUSION_REGEXES=() + +if [[ "${BUILD_TYPE}" == "cpu" ]]; then + CTEST_EXCLUSION_REGEXES+=("^cub" "^thrust.*cuda") +fi + +if [[ -n "${CTEST_EXCLUSION_REGEXES[@]}" ]]; then + CTEST_EXCLUSION_REGEX=$(join_delimit "|" "${CTEST_EXCLUSION_REGEXES[@]}") + append CTEST_FLAGS "-E ${CTEST_EXCLUSION_REGEX}" +fi + +if [[ -n "${@}" ]]; then + CTEST_INCLUSION_REGEX=$(join_delimit "|" "${@}") + append CTEST_FLAGS "-R ^${CTEST_INCLUSION_REGEX[@]}$" +fi + +# Export variables so they'll show up in the logs when we report the environment. +export COVERAGE_PLAN +export CMAKE_FLAGS +export CMAKE_BUILD_FLAGS +export CTEST_FLAGS + +################################################################################ +# ENVIRONMENT - Configure and print out information about the environment. +################################################################################ + +log "Determine system topology..." + +# Set `${PARALLEL_LEVEL}` if it is unset; otherwise, this just reports the +# system topology. +source ${WORKSPACE}/ci/common/determine_build_parallelism.bash ${DETERMINE_PARALLELISM_FLAGS} + +log "Get environment..." + +env | sort + +log "Check versions..." + +# We use sed and echo below to ensure there is always one and only trailing +# line following the output from each tool. + +${CXX} --version 2>&1 | sed -Ez '$ s/\n*$/\n/' + +echo + +${CUDACXX} --version 2>&1 | sed -Ez '$ s/\n*$/\n/' + +echo + +cmake --version 2>&1 | sed -Ez '$ s/\n*$/\n/' + +if [[ "${BUILD_TYPE}" == "gpu" ]]; then + echo + nvidia-smi 2>&1 | sed -Ez '$ s/\n*$/\n/' +fi + +if [[ -n "${ENABLE_SCCACHE}" ]]; then + echo + # Set sccache statistics to zero to capture clean run. + sccache --version + sccache --zero-stats | grep location +fi + +################################################################################ +# BUILD - Build Thrust and CUB examples and tests. +################################################################################ + +log "Configure Thrust and CUB..." + +echo_and_run_timed "Configure" cmake .. --log-level=VERBOSE ${CMAKE_FLAGS} +configure_status=$? + +log "Build Thrust and CUB..." + +# ${PARALLEL_LEVEL} needs to be passed after we run +# determine_build_parallelism.bash, so it can't be part of ${CMAKE_BUILD_FLAGS}. +set +e # Don't stop on build failures. + +# Monitor memory usage. Thresholds in GiB: +python3 ${WORKSPACE}/ci/common/memmon.py \ + --log-threshold 0.0 \ + --fail-threshold ${MIN_MEMORY_PER_THREAD} \ + --log-file ${MEMMON_LOG} \ + & +memmon_pid=$! + +echo_and_run_timed "Build" cmake --build . ${CMAKE_BUILD_FLAGS} -j ${PARALLEL_LEVEL} +build_status=$? + +# Stop memmon: +kill -s SIGINT ${memmon_pid} + +# Re-enable exit on failure: +set -e + +################################################################################ +# TEST - Run Thrust and CUB examples and tests. +################################################################################ + +log "Test Thrust and CUB..." + +( + # Make sure test_status captures ctest, not tee: + # https://stackoverflow.com/a/999259/11130318 + set -o pipefail + echo_and_run_timed "Test" ctest ${CTEST_FLAGS} | tee ctest_log +) +test_status=$? + +################################################################################ +# COMPILATION STATS +################################################################################ + +if [[ -n "${ENABLE_SCCACHE}" ]]; then + # Get sccache stats after the compile is completed + COMPILE_REQUESTS=$(sccache -s | grep "Compile requests \+ [0-9]\+$" | awk '{ print $NF }') + CACHE_HITS=$(sccache -s | grep "Cache hits \+ [0-9]\+$" | awk '{ print $NF }') + HIT_RATE=$(echo - | awk "{printf \"%.2f\n\", $CACHE_HITS / $COMPILE_REQUESTS * 100}") + log "sccache stats (${HIT_RATE}% hit):" + sccache -s +fi + +################################################################################ +# COMPILE TIME INFO: Print the 20 longest running build steps (ninja only) +################################################################################ + +if [[ -f ".ninja_log" ]]; then + log "Checking slowest build steps:" + echo_and_run "CompileTimeInfo" cmake -P ../cmake/PrintNinjaBuildTimes.cmake | head -n 23 +fi + +################################################################################ +# RUNTIME INFO: Print the 20 longest running test steps +################################################################################ + +if [[ -f "ctest_log" ]]; then + log "Checking slowest test steps:" + echo_and_run "TestTimeInfo" cmake -DLOGFILE=ctest_log -P ../cmake/PrintCTestRunTimes.cmake | head -n 20 +fi + +################################################################################ +# MEMORY_USAGE +################################################################################ + +memmon_status=0 +if [[ -f "${MEMMON_LOG}" ]]; then + log "Checking memmon logfile: ${MEMMON_LOG}" + + if [[ -n "$(grep -E "^FAIL" ${MEMMON_LOG})" ]]; then + log "error: Some build steps exceeded memory threshold (${MIN_MEMORY_PER_THREAD} GiB):" + grep -E "^FAIL" ${MEMMON_LOG} + memmon_status=1 + else + log "Top memory usage per build step (all less than limit of ${MIN_MEMORY_PER_THREAD} GiB):" + if [[ -s ${MEMMON_LOG} ]]; then + # Not empty: + head -n5 ${MEMMON_LOG} + else + echo "None detected above logging threshold." + fi + fi +fi + +################################################################################ +# SUMMARY - Print status of each step and exit with failure if needed. +################################################################################ + +log "Summary:" +echo "Warnings:" +# Not currently a failure; sccache makes these unreliable and intermittent: +echo "- Build Memory Check: ${memmon_status}" +echo "Failures:" +echo "- Configure Error Code: ${configure_status}" +echo "- Build Error Code: ${build_status}" +echo "- Test Error Code: ${test_status}" + +if [[ "${configure_status}" != "0" ]] || \ + [[ "${build_status}" != "0" ]] || \ + [[ "${test_status}" != "0" ]]; then + exit 1 +fi diff --git a/ci/common/determine_build_parallelism.bash b/ci/common/determine_build_parallelism.bash new file mode 100755 index 000000000..9813fcb2f --- /dev/null +++ b/ci/common/determine_build_parallelism.bash @@ -0,0 +1,119 @@ +#! /usr/bin/env bash + +# Copyright (c) 2018-2020 NVIDIA Corporation +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# Released under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. + +function usage { + echo "Usage: ${0} [flags...]" + echo + echo "Examine the system topology to determine a reasonable amount of build" + echo "parallelism." + echo + echo "Exported variables:" + echo " \${LOGICAL_CPUS} : Logical processors (e.g. threads)." + echo " \${PHYSICAL_CPUS} : Physical processors (e.g. cores)." + echo " \${TOTAL_MEM} : Total system memory [GB]." + echo " \${MAX_THREADS_PER_CORE} : Maximum threads per core allowed." + echo " \${MIN_MEMORY_PER_THREAD} : Minimum memory [GB] per thread allowed." + echo " \${CPU_BOUND_THREADS} : # of build threads constrained by processors." + echo " \${MEM_BOUND_THREADS} : # of build threads constrained by memory [GB]." + echo " \${PARALLEL_LEVEL} : Determined # of build threads." + echo " \${MEM_PER_THREAD} : Memory [GB] per build thread." + echo + echo "-h, -help, --help" + echo " Print this message." + echo + echo "-q, --quiet" + echo " Print nothing and only export variables." + echo + echo "-j , --jobs " + echo " Explicitly set the number of build threads to use." + echo + echo "--max-threads-per-core " + echo " Specify the maximum threads per core allowed (default: ${MAX_THREADS_PER_CORE} [threads/core])." + echo + echo "--min-memory-per-thread " + echo " Specify the minimum memory per thread allowed (default: ${MIN_MEMORY_PER_THREAD} [GBs/thread])." + + exit -3 +} + +QUIET=0 + +export MAX_THREADS_PER_CORE=2 +export MIN_MEMORY_PER_THREAD=4 # [GB] + +while test ${#} != 0 +do + case "${1}" in + -h) ;& + -help) ;& + --help) usage ;; + -q) ;& + --quiet) QUIET=1 ;; + -j) ;& + --jobs) + shift # The next argument is the number of threads. + PARALLEL_LEVEL="${1}" + ;; + --max-threads-per-core) + shift # The next argument is the number of threads per core. + MAX_THREADS_PER_CORE="${1}" + ;; + --min-memory-per-thread) + shift # The next argument is the amount of memory per thread. + MIN_MEMORY_PER_THREAD="${1}" + ;; + esac + shift +done + +# https://stackoverflow.com/a/23378780 +if [ $(uname) == "Darwin" ]; then + export LOGICAL_CPUS=$(sysctl -n hw.logicalcpu_max) + export PHYSICAL_CPUS=$(sysctl -n hw.physicalcpu_max) +else + export LOGICAL_CPUS=$(lscpu -p | egrep -v '^#' | wc -l) + export PHYSICAL_CPUS=$(lscpu -p | egrep -v '^#' | sort -u -t, -k 2,4 | wc -l) +fi + +export TOTAL_MEM=$(awk "BEGIN { printf \"%0.4g\", $(grep MemTotal /proc/meminfo | awk '{ print $2 }') / (1024 * 1024) }") + +export CPU_BOUND_THREADS=$(awk "BEGIN { printf \"%.04g\", int(${PHYSICAL_CPUS} * ${MAX_THREADS_PER_CORE}) }") +export MEM_BOUND_THREADS=$(awk "BEGIN { printf \"%.04g\", int(${TOTAL_MEM} / ${MIN_MEMORY_PER_THREAD}) }") + +if [[ -z "${PARALLEL_LEVEL}" ]]; then + # Pick the smaller of the two as the default. + if [[ "${MEM_BOUND_THREADS}" -lt "${CPU_BOUND_THREADS}" ]]; then + export PARALLEL_LEVEL=${MEM_BOUND_THREADS} + else + export PARALLEL_LEVEL=${CPU_BOUND_THREADS} + fi +else + EXPLICIT_PARALLEL_LEVEL=1 +fi + +# This can be a floating point number. +export MEM_PER_THREAD=$(awk "BEGIN { printf \"%.04g\", ${TOTAL_MEM} / ${PARALLEL_LEVEL} }") + +if [[ "${QUIET}" == 0 ]]; then + echo "Logical CPUs: ${LOGICAL_CPUS} [threads]" + echo "Physical CPUs: ${PHYSICAL_CPUS} [cores]" + echo "Total Mem: ${TOTAL_MEM} [GBs]" + echo "Max Threads Per Core: ${MAX_THREADS_PER_CORE} [threads/core]" + echo "Min Memory Per Threads: ${MIN_MEMORY_PER_THREAD} [GBs/thread]" + echo "CPU Bound Threads: ${CPU_BOUND_THREADS} [threads]" + echo "Mem Bound Threads: ${MEM_BOUND_THREADS} [threads]" + + echo -n "Parallel Level: ${PARALLEL_LEVEL} [threads]" + if [[ -n "${EXPLICIT_PARALLEL_LEVEL}" ]]; then + echo " (explicitly set)" + else + echo + fi + + echo "Mem Per Thread: ${MEM_PER_THREAD} [GBs/thread]" +fi + diff --git a/ci/common/memmon.py b/ci/common/memmon.py new file mode 100755 index 000000000..505503733 --- /dev/null +++ b/ci/common/memmon.py @@ -0,0 +1,110 @@ +#! /usr/bin/env python + +# Copyright (c) 2022 NVIDIA Corporation +# Reply-To: Allison Vacanti +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# Released under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. + +help_text = """%(prog)s [reference.json compare.json | reference_dir/ compare_dir/] + +This script: + +1. Runs `top -bco RES`, continuously extracting the memory usage of each process. +2. If a process uses more than `log_threshold` GiB and exceeds any other recorded + entry for the process, it is stored in `entries`. +3. When this script receives SIGINT, it writes two files: + * `log_file` will contain all recorded max-memory-per-process entries + * `fail_file` will contain all entries that exceed `fail_threshold` +""" + +import argparse +import os +import re +import signal +import sys + +from subprocess import Popen, PIPE, STDOUT + +parser = argparse.ArgumentParser(prog='memmon.py', usage=help_text) +parser.add_argument('--log-threshold', type=float, dest='log_threshold', + default=0.5, + help='Logging threshold in GiB.') +parser.add_argument('--fail-threshold', type=float, dest='fail_threshold', + default=2, + help='Failure threshold in GiB.') +parser.add_argument('--log-file', type=str, dest='log_file', default='memmon_log', + help='Output file for log entries.') +args, unused = parser.parse_known_args() + +entries = {} + + +def signal_handler(sig, frame): + # Sort by mem: + sortentries = sorted(entries.items(), key=lambda x: x[1], reverse=True) + + lf = open(args.log_file, "w") + + for com, mem in sortentries: + status = "PASS" + if mem >= args.fail_threshold: + status = "FAIL" + line = "%4s | %3.1f GiB | %s\n" % (status, mem, com) + lf.write(line) + + lf.close() + sys.exit(0) + + +signal.signal(signal.SIGINT, signal_handler) + +# Find the toprc config file and configure top's env. +# This config: +# - Hides all columns except for RES and COMMAND +# - Sorts by RES +# - Enables long command strings (-c) +script_dir = os.path.dirname(os.path.realpath(__file__)) +config_dir = os.path.join(script_dir, 'memmon_config') + +proc = Popen(["top", "-b", "-w", "512"], + stdin=PIPE, stdout=PIPE, stderr=STDOUT, + env={"XDG_CONFIG_HOME": config_dir}) + +regex = re.compile("^\\s*([0-9.]+[kmgtp]?)\\s+(.+)\\s*$") + + +# Convert a memory string from top into floating point GiB +def parse_mem(mem_str): + if mem_str[-1] == "k": + return float(mem_str[:-1]) / (1024 * 1024) + elif mem_str[-1] == "m": + return float(mem_str[:-1]) / (1024) + elif mem_str[-1] == "g": + return float(mem_str[:-1]) + elif mem_str[-1] == "t": + return float(mem_str[:-1]) * 1024 + elif mem_str[-1] == "p": # please no + return float(mem_str[:-1]) * 1024 * 1024 + # bytes: + return float(mem_str) / (1024 * 1024 * 1024) + + +for line in proc.stdout: + line = line.decode() + match = regex.match(line) + if match: + mem = parse_mem(match.group(1)) + if mem < args.log_threshold and mem < args.fail_threshold: + continue + com = match.group(2) + if com in entries and entries[com] > mem: + continue + if mem >= args.fail_threshold: + # Print a notice immediately -- this helps identify the failures + # as they happen, since `com` may not provide enough info. + print("memmon.py failure: Build step exceed memory threshold:\n" + " - Threshold: %3.1f GiB\n" + " - Usage: %3.1f GiB\n" + " - Command: %s" % (args.fail_threshold, mem, com)) + entries[com] = mem diff --git a/ci/common/memmon_config/procps/toprc b/ci/common/memmon_config/procps/toprc new file mode 100644 index 000000000..883a482ce --- /dev/null +++ b/ci/common/memmon_config/procps/toprc @@ -0,0 +1,16 @@ +top's Config File (Linux processes with windows) +Id:i, Mode_altscr=0, Mode_irixps=1, Delay_time=3.0, Curwin=0 +Def fieldscur=%(34;@D7:9&')*+,-./012568<>?ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij + winflags=193972, sortindx=18, maxtasks=0, graph_cpus=0, graph_mems=0 + summclr=1, msgsclr=1, headclr=3, taskclr=1 +Job fieldscur=(Ļ@<)*+,-./012568>?ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij + winflags=193844, sortindx=0, maxtasks=0, graph_cpus=0, graph_mems=0 + summclr=6, msgsclr=6, headclr=7, taskclr=6 +Mem fieldscur=?@ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij + winflags=193844, sortindx=3, maxtasks=0, graph_cpus=0, graph_mems=0 + summclr=3, msgsclr=3, headclr=2, taskclr=3 +Fixed_widest=0, Summ_mscale=1, Task_mscale=0, Zero_suppress=0 + diff --git a/ci/cpu/build.bash b/ci/cpu/build.bash new file mode 100755 index 000000000..69b99bbec --- /dev/null +++ b/ci/cpu/build.bash @@ -0,0 +1,14 @@ +#! /usr/bin/env bash + +# Copyright (c) 2018-2020 NVIDIA Corporation +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# Released under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. + +################################################################################ +# Thrust and CUB build script for gpuCI (CPU-only) +################################################################################ + +export PARALLEL_LEVEL=${PARALLEL_LEVEL:-4} + +source ${WORKSPACE}/ci/common/build.bash diff --git a/ci/gpu/build.bash b/ci/gpu/build.bash new file mode 100755 index 000000000..f6cdf021c --- /dev/null +++ b/ci/gpu/build.bash @@ -0,0 +1,14 @@ +#! /usr/bin/env bash + +# Copyright (c) 2018-2020 NVIDIA Corporation +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# Released under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. + +################################################################################ +# Thrust and CUB build script for gpuCI (heterogeneous) +################################################################################ + +export PARALLEL_LEVEL=${PARALLEL_LEVEL:-4} + +source ${WORKSPACE}/ci/common/build.bash diff --git a/ci/local/build.bash b/ci/local/build.bash new file mode 100755 index 000000000..8b20ef063 --- /dev/null +++ b/ci/local/build.bash @@ -0,0 +1,224 @@ +#! /usr/bin/env bash + +# Copyright (c) 2018-2020 NVIDIA Corporation +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# Released under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. + +################################################################################ +# Thrust and CUB local containerized build script +################################################################################ + +function usage { + echo "Usage: ${0} [flags...] [cmake-targets...]" + echo + echo "Build and test your local repository using a gpuCI Docker image." + echo "If CMake targets are specified, only those targets are built and tested." + echo "Otherwise, everything is built and tested." + echo + echo "-h, -help, --help" + echo " Print this message." + echo + echo "-r , --repository " + echo " Path to the repository (default: ${REPOSITORY_PATH})." + echo + echo "-i , --image " + echo " Docker image to use (default: ${IMAGE})" + echo + echo "-l, --local-image" + echo " Use the local version of the image instead of pulling from Docker hub." + echo + echo "-s, --shell-only" + echo " Skip building and testing and launch an interactive shell instead." + echo + echo "-d, --disable-gpus" + echo " Don't start the container with the NVIDIA runtime and GPUs attached." + echo + echo "-c, --clean" + echo " If the build directory already exists, delete it." + echo + echo "-j , --jobs " + echo " Number of threads to use when building (default: inferred)." + echo + echo "-b , --cmake-build-type " + echo " CMake build type to use, either Release, RelWithDebInfo, or Debug" + echo " (default: ${CMAKE_BUILD_TYPE})." + echo + echo "-p , --coverage-plan " + echo " Coverage plan to use, either Exhaustive, Thorough, or Minimal" + echo " (default: ${COVERAGE_PLAN})." + echo + + exit -3 +} + +SCRIPT_PATH=$(cd $(dirname ${0}); pwd -P) + +REPOSITORY_PATH=$(realpath ${SCRIPT_PATH}/../..) + +################################################################################ +# FLAGS - Process command line flags. +################################################################################ + +IMAGE="gpuci/cccl:cuda11.7.0-devel-ubuntu20.04-gcc9" + +LOCAL_IMAGE=0 + +SHELL_ONLY=0 + +BUILD_TYPE="gpu" + +CLEAN=0 + +PARALLEL_LEVEL="" + +CMAKE_BUILD_TYPE="Release" + +COVERAGE_PLAN="Minimal" + +TARGETS="" + +while test ${#} != 0 +do + case "${1}" in + -h) ;& + -help) ;& + --help) usage ;; + -r) ;& + --repository) + shift # The next argument is the path. + REPOSITORY_PATH="${1}" + ;; + -i) ;& + --image) + shift # The next argument is the image. + IMAGE="${1}" + ;; + -l) ;& + --local-image) LOCAL_IMAGE=1 ;; + -s) ;& + --shell-only) SHELL_ONLY=1 ;; + -d) ;& + --disable-gpus) BUILD_TYPE="cpu" ;; + -c) ;& + --clean) CLEAN=1 ;; + -j) ;& + --jobs) + shift # The next argument is the number of threads. + PARALLEL_LEVEL="${1}" + ;; + -b) ;& + --cmake-build-type) + shift # The next argument is the build type. + CMAKE_BUILD_TYPE="${1}" + ;; + -p) ;& + --coverage-plan) + shift # The next argument is the coverage plan. + COVERAGE_PLAN="${1}" + ;; + *) + TARGETS="${TARGETS:+${TARGETS} }${1}" + ;; + esac + shift +done + +################################################################################ +# PATHS - Setup paths for the container. +################################################################################ + +# ${REPOSITORY_PATH} is the local filesystem path to the Git repository being +# built and tested. It can be set with the --repository flag. +# +# ${BUILD_PATH} is the local filesystem path that will be used for the build. It +# is named after the image name, allowing multiple image builds to coexist on +# the local filesystem. +# +# ${REPOSITORY_PATH_IN_CONTAINER} is the location of ${REPOSITORY_PATH} inside +# the container. +# +# ${BUILD_PATH_IN_CONTAINER} is the location of ${BUILD_PATH} inside the +# container. + +BUILD_PATH=${REPOSITORY_PATH}/build_$(echo "$(basename "${IMAGE}")" | sed -e 's/:/_/g' | sed -e 's/-/_/g') + +if [[ "${CLEAN}" != 0 ]]; then + rm -rf ${BUILD_PATH} +fi + +mkdir -p ${BUILD_PATH} + +BASE_PATH_IN_CONTAINER="/cccl" + +REPOSITORY_PATH_IN_CONTAINER="${BASE_PATH_IN_CONTAINER}/$(basename "${REPOSITORY_PATH}")" + +BUILD_PATH_IN_CONTAINER="${BASE_PATH_IN_CONTAINER}/$(basename "${REPOSITORY_PATH}")/build" + +################################################################################ +# ENVIRONMENT - Setup the thunk build script that will be run by the container. +################################################################################ + +# We have to run `ldconfig` to rebuild `ld.so.cache` to work around this +# failure on Debian: https://github.com/NVIDIA/nvidia-docker/issues/1399 + +COMMAND="sudo ldconfig; sudo ldconfig" +if [[ "${SHELL_ONLY}" != 0 ]]; then + COMMAND="${COMMAND}; bash" +else + COMMAND="${COMMAND}; ${REPOSITORY_PATH_IN_CONTAINER}/ci/common/build.bash ${TARGETS} || bash" +fi + +################################################################################ +# GPU - Setup GPUs. +################################################################################ + +if [[ "${BUILD_TYPE}" == "gpu" ]]; then + # Limit GPUs available to the container based on ${CUDA_VISIBLE_DEVICES}. + if [[ -z "${CUDA_VISIBLE_DEVICES}" ]]; then + VISIBLE_DEVICES="all" + else + VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES}" + fi + + DOCKER_MAJOR_VER=$(docker -v | sed 's/[^[0-9]*\([0-9]*\).*/\1/') + GPU_OPTS="--gpus device=${VISIBLE_DEVICES}" + if [[ "${DOCKER_MAJOR_VER}" -lt 19 ]] + then + GPU_OPTS="--runtime=nvidia -e NVIDIA_VISIBLE_DEVICES='${VISIBLE_DEVICES}'" + fi +fi + +################################################################################ +# LAUNCH - Pull and launch the container. +################################################################################ + +NVIDIA_DOCKER_INSTALLED=$(docker info 2>&1 | grep -i runtime | grep -c nvidia) +if [[ "${NVIDIA_DOCKER_INSTALLED}" == 0 ]]; then + echo "NVIDIA Docker not found, the build may fail." + echo "Please install it if you encounter issues: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#installing-docker-ce" +fi + +if [[ "${LOCAL_IMAGE}" == 0 ]]; then + docker pull "${IMAGE}" +fi + +docker run --rm -it ${GPU_OPTS} \ + --cap-add=SYS_PTRACE \ + --user "$(id -u)":"$(id -g)" \ + -v "${REPOSITORY_PATH}":"${REPOSITORY_PATH_IN_CONTAINER}" \ + -v "${BUILD_PATH}":"${BUILD_PATH_IN_CONTAINER}" \ + -v /etc/passwd:/etc/passwd:ro \ + -v /etc/group:/etc/group:ro \ + -v /etc/subuid:/etc/subuid:ro \ + -v /etc/subgid:/etc/subgid:ro \ + -v /etc/shadow:/etc/shadow:ro \ + -v /etc/gshadow:/etc/gshadow:ro \ + -e "WORKSPACE=${REPOSITORY_PATH_IN_CONTAINER}" \ + -e "BUILD_TYPE=${BUILD_TYPE}" \ + -e "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" \ + -e "COVERAGE_PLAN=${COVERAGE_PLAN}" \ + -e "PARALLEL_LEVEL=${PARALLEL_LEVEL}" \ + -w "${BUILD_PATH_IN_CONTAINER}" \ + "${IMAGE}" bash -c "${COMMAND}" + diff --git a/cmake/AppendOptionIfAvailable.cmake b/cmake/AppendOptionIfAvailable.cmake new file mode 100644 index 000000000..52dc12216 --- /dev/null +++ b/cmake/AppendOptionIfAvailable.cmake @@ -0,0 +1,14 @@ +include_guard(GLOBAL) +include(CheckCXXCompilerFlag) + +macro (APPEND_OPTION_IF_AVAILABLE _FLAG _LIST) + +string(MAKE_C_IDENTIFIER "CXX_FLAG_${_FLAG}" _VAR) +check_cxx_compiler_flag(${_FLAG} ${_VAR}) + +if (${${_VAR}}) + list(APPEND ${_LIST} ${_FLAG}) +endif () + +endmacro () + diff --git a/cmake/DetectSupportedStandards.cmake b/cmake/DetectSupportedStandards.cmake new file mode 100644 index 000000000..5dceefdab --- /dev/null +++ b/cmake/DetectSupportedStandards.cmake @@ -0,0 +1,47 @@ +# Detect the langauge standards supported by the current compilers. +# +# Usage: detect_supported_cxx_standards( ) +# +# - var_prefix: Used to name result variables, +# e.g. ${var_prefix}_${lang}_XX_SUPPORTED will be TRUE or FALSE. Defined for +# each XX in ${standards}. +# - lang: The language to test: C, CXX, or CUDA. +# - standards: List of any standard versions. +# +# Example: detect_supported_cxx_standards(PROJ CXX 11 14 17) +# - Sets the following variables in the parent scope to TRUE or FALSE: +# - PROJ_CXX_11_SUPPORTED +# - PROJ_CXX_14_SUPPORTED +# - PROJ_CXX_17_SUPPORTED +# +function(detect_supported_standards prefix lang) + string(TOLOWER "${lang}_std" feature_prefix) + foreach(standard IN LISTS ARGN) + set(var_name "${prefix}_${lang}_${standard}_SUPPORTED") + if ("${feature_prefix}_${standard}" IN_LIST CMAKE_${lang}_COMPILE_FEATURES) + set(${var_name} TRUE) + else() + set(${var_name} FALSE) + endif() + + + if (standard EQUAL 17 AND + (lang STREQUAL "CXX" OR lang STREQUAL "CUDA") AND + ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND + CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7) OR + (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND + CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8))) + # Special cases: + # gcc < 7 and clang < 8 don't fully support C++17. + # They accept the flag and have partial support, but nvcc will refuse + # to enable it and falls back to the default dialect for the current + # CXX compiler version. This breaks our CI. + # CMake's COMPILE_FEATURES var reports that these compilers support C++17, + # but we can't rely on it, so manually disable the dialect in these cases. + set(${var_name} FALSE) + endif() + + message(STATUS "Testing ${lang}${standard} Support: ${${var_name}}") + set(${var_name} ${${var_name}} PARENT_SCOPE) + endforeach() +endfunction() diff --git a/cmake/PrintCTestRunTimes.cmake b/cmake/PrintCTestRunTimes.cmake new file mode 100644 index 000000000..bf23b9bb6 --- /dev/null +++ b/cmake/PrintCTestRunTimes.cmake @@ -0,0 +1,109 @@ +## This CMake script parses the output of ctest and prints a formatted list +## of individual test runtimes, sorted longest first. +## +## ctest > ctest_log +## cmake -DLOGFILE=ctest_log \ +## -P PrintCTestRunTimes.cmake +## +################################################################################ + +cmake_minimum_required(VERSION 3.15) + +# Prepend the string with "0" until the string length equals the specified width +function(pad_string_with_zeros string_var width) + set(local_string "${${string_var}}") + string(LENGTH "${local_string}" size) + while(size LESS width) + string(PREPEND local_string "0") + string(LENGTH "${local_string}" size) + endwhile() + set(${string_var} "${local_string}" PARENT_SCOPE) +endfunction() + +################################################################################ + +if (NOT LOGFILE) + message(FATAL_ERROR "Missing -DLOGFILE= argument.") +endif() + +# Check if logfile exists +if (NOT EXISTS "${LOGFILE}") + message(FATAL_ERROR "LOGFILE does not exist ('${LOGFILE}').") +endif() + +string(JOIN "" regex + "^[ ]*[0-9]+/[0-9]+[ ]+Test[ ]+#" + "([0-9]+)" # Test ID + ":[ ]+" + "(.+)" # Test Name + "[ ]+\\.+[ ]+" + "(.+[^ ])" # Result + "[ ]+" + "([0-9]+)" # Seconds + "\\.[0-9]+[ ]+sec[ ]*$" +) + +message(DEBUG "Regex: ${regex}") + +# Read the logfile and generate a map / keylist +set(keys) +file(STRINGS "${LOGFILE}" lines) +foreach(line ${lines}) + + # Parse each build time + string(REGEX MATCH "${regex}" _DUMMY "${line}") + + if (CMAKE_MATCH_COUNT EQUAL 4) + set(test_id "${CMAKE_MATCH_1}") + set(test_name "${CMAKE_MATCH_2}") + set(test_result "${CMAKE_MATCH_3}") + set(tmp "${CMAKE_MATCH_4}") # floor(runtime_seconds) + + # Compute human readable time + math(EXPR days "${tmp} / (60 * 60 * 24)") + math(EXPR tmp "${tmp} - (${days} * 60 * 60 * 24)") + math(EXPR hours "${tmp} / (60 * 60)") + math(EXPR tmp "${tmp} - (${hours} * 60 * 60)") + math(EXPR minutes "${tmp} / (60)") + math(EXPR tmp "${tmp} - (${minutes} * 60)") + math(EXPR seconds "${tmp}") + + # Format time components + pad_string_with_zeros(days 3) + pad_string_with_zeros(hours 2) + pad_string_with_zeros(minutes 2) + pad_string_with_zeros(seconds 2) + + # Construct table entry + # Later values in the file for the same command overwrite earlier entries + string(MAKE_C_IDENTIFIER "${test_id}" key) + string(JOIN " | " ENTRY_${key} + "${days}d ${hours}h ${minutes}m ${seconds}s" + "${test_result}" + "${test_id}: ${test_name}" + ) + + # Record the key: + list(APPEND keys "${key}") + endif() +endforeach() + +list(REMOVE_DUPLICATES keys) + +# Build the entry list: +set(entries) +foreach(key ${keys}) + list(APPEND entries "${ENTRY_${key}}") +endforeach() + +if (NOT entries) + message(FATAL_ERROR "LOGFILE contained no test times ('${LOGFILE}').") +endif() + +# Sort in descending order: +list(SORT entries ORDER DESCENDING) + +# Dump table: +foreach(entry ${entries}) + message(STATUS ${entry}) +endforeach() diff --git a/cmake/PrintNinjaBuildTimes.cmake b/cmake/PrintNinjaBuildTimes.cmake new file mode 100644 index 000000000..65d243d35 --- /dev/null +++ b/cmake/PrintNinjaBuildTimes.cmake @@ -0,0 +1,101 @@ +## This CMake script parses a .ninja_log file (LOGFILE) and prints a list of +## build/link times, sorted longest first. +## +## cmake -DLOGFILE=<.ninja_log file> \ +## -P PrintNinjaBuildTimes.cmake +## +## If LOGFILE is omitted, the current directory's .ninja_log file is used. +################################################################################ + +cmake_minimum_required(VERSION 3.15) + +# Prepend the string with "0" until the string length equals the specified width +function(pad_string_with_zeros string_var width) + set(local_string "${${string_var}}") + string(LENGTH "${local_string}" size) + while(size LESS width) + string(PREPEND local_string "0") + string(LENGTH "${local_string}" size) + endwhile() + set(${string_var} "${local_string}" PARENT_SCOPE) +endfunction() + +################################################################################ + +if (NOT LOGFILE) + set(LOGFILE ".ninja_log") +endif() + +# Check if logfile exists +if (NOT EXISTS "${LOGFILE}") + message(FATAL_ERROR "LOGFILE does not exist ('${LOGFILE}').") +endif() + +# Read the logfile and generate a map / keylist +set(keys) +file(STRINGS "${LOGFILE}" lines) +foreach(line ${lines}) + + # Parse each build time + string(REGEX MATCH + "^([0-9]+)\t([0-9]+)\t[0-9]+\t([^\t]+)+\t[0-9a-fA-F]+$" _DUMMY "${line}") + + if (CMAKE_MATCH_COUNT EQUAL 3) + set(start_ms ${CMAKE_MATCH_1}) + set(end_ms ${CMAKE_MATCH_2}) + set(command "${CMAKE_MATCH_3}") + math(EXPR runtime_ms "${end_ms} - ${start_ms}") + + # Compute human readable time + math(EXPR days "${runtime_ms} / (1000 * 60 * 60 * 24)") + math(EXPR runtime_ms "${runtime_ms} - (${days} * 1000 * 60 * 60 * 24)") + math(EXPR hours "${runtime_ms} / (1000 * 60 * 60)") + math(EXPR runtime_ms "${runtime_ms} - (${hours} * 1000 * 60 * 60)") + math(EXPR minutes "${runtime_ms} / (1000 * 60)") + math(EXPR runtime_ms "${runtime_ms} - (${minutes} * 1000 * 60)") + math(EXPR seconds "${runtime_ms} / 1000") + math(EXPR milliseconds "${runtime_ms} - (${seconds} * 1000)") + + # Format time components + pad_string_with_zeros(days 3) + pad_string_with_zeros(hours 2) + pad_string_with_zeros(minutes 2) + pad_string_with_zeros(seconds 2) + pad_string_with_zeros(milliseconds 3) + + # Construct table entry + # Later values in the file for the same command overwrite earlier entries + string(MAKE_C_IDENTIFIER "${command}" key) + set(ENTRY_${key} + "${days}d ${hours}h ${minutes}m ${seconds}s ${milliseconds}ms | ${command}" + ) + + # Record the key: + list(APPEND keys "${key}") + endif() +endforeach() + +list(REMOVE_DUPLICATES keys) + +# Build the entry list: +set(entries) +foreach(key ${keys}) + list(APPEND entries "${ENTRY_${key}}") +endforeach() + +if (NOT entries) + message(FATAL_ERROR "LOGFILE contained no build entries ('${LOGFILE}').") +endif() + +# Sort in descending order: +list(SORT entries) +list(REVERSE entries) + +# Dump table: +message(STATUS "-----------------------+----------------------------") +message(STATUS "Time | Command ") +message(STATUS "-----------------------+----------------------------") + +foreach(entry ${entries}) + message(STATUS ${entry}) +endforeach() diff --git a/cmake/ThrustAddSubdir.cmake b/cmake/ThrustAddSubdir.cmake new file mode 100644 index 000000000..d48aa1415 --- /dev/null +++ b/cmake/ThrustAddSubdir.cmake @@ -0,0 +1,6 @@ +find_package(Thrust REQUIRED CONFIG + NO_DEFAULT_PATH # Only check the explicit path in HINTS: + HINTS "${CMAKE_CURRENT_LIST_DIR}/.." + COMPONENTS ${THRUST_REQUIRED_SYSTEMS} + OPTIONAL_COMPONENTS ${THRUST_OPTIONAL_SYSTEMS} +) diff --git a/cmake/ThrustBuildCompilerTargets.cmake b/cmake/ThrustBuildCompilerTargets.cmake new file mode 100644 index 000000000..aed0ec170 --- /dev/null +++ b/cmake/ThrustBuildCompilerTargets.cmake @@ -0,0 +1,191 @@ +# +# This file defines the `thrust_build_compiler_targets()` function, which +# creates the following interface targets: +# +# thrust.compiler_interface +# - Interface target providing compiler-specific options needed to build +# Thrust's tests, examples, etc. +# +# thrust.compiler_interface_cppXX +# - Interface targets providing compiler-specific options that should only be +# applied to certain dialects of C++. May not be defined for all dialects. +# +# thrust.promote_cudafe_warnings +# - Interface target that adds warning promotion for NVCC cudafe invocations. +# - Only exists to work around github issue #1174 on tbb.cuda configurations. +# - May be combined with thrust.compiler_interface when #1174 is fully resolved. +# +# thrust.silence_unreachable_code_warnings +# - Interface target that silences unreachable code warnings. +# - Used to selectively disable such warnings in unit tests caused by +# unconditionally thrown exceptions. + +function(thrust_build_compiler_targets) + set(cxx_compile_definitions) + set(cxx_compile_options) + + thrust_update_system_found_flags() + + if ("MSVC" STREQUAL "${CMAKE_CXX_COMPILER_ID}") + append_option_if_available("/W4" cxx_compile_options) + + # Treat all warnings as errors. This is only supported on Release builds, + # as `nv_exec_check_disable` doesn't seem to work with MSVC debug iterators + # and spurious warnings are emitted. + # See NVIDIA/thrust#1273, NVBug 3129879. + if (CMAKE_BUILD_TYPE STREQUAL "Release") + append_option_if_available("/WX" cxx_compile_options) + endif() + + # Suppress overly-pedantic/unavoidable warnings brought in with /W4: + # C4324: structure was padded due to alignment specifier + append_option_if_available("/wd4324" cxx_compile_options) + # C4505: unreferenced local function has been removed + # The CUDA `host_runtime.h` header emits this for + # `__cudaUnregisterBinaryUtil`. + append_option_if_available("/wd4505" cxx_compile_options) + # C4706: assignment within conditional expression + # MSVC doesn't provide an opt-out for this warning when the assignment is + # intentional. Clang will warn for these, but suppresses the warning when + # double-parentheses are used around the assignment. We'll let Clang catch + # unintentional assignments and suppress all such warnings on MSVC. + append_option_if_available("/wd4706" cxx_compile_options) + + # Disabled loss-of-data conversion warnings. + # TODO Re-enable. + append_option_if_available("/wd4244" cxx_compile_options) + + # Disable warning about applying unary operator- to unsigned type. + # TODO Re-enable. + append_option_if_available("/wd4146" cxx_compile_options) + + # MSVC STL assumes that `allocator_traits`'s allocator will use raw pointers, + # and the `__DECLSPEC_ALLOCATOR` macro causes issues with thrust's universal + # allocators: + # warning C4494: 'std::allocator_traits<_Alloc>::allocate' : + # Ignoring __declspec(allocator) because the function return type is not + # a pointer or reference + # See https://github.com/microsoft/STL/issues/696 + append_option_if_available("/wd4494" cxx_compile_options) + + # Some of the async tests require /bigobj to fit all their sections into the + # object files: + append_option_if_available("/bigobj" cxx_compile_options) + + # "Oh right, this is Visual Studio." + list(APPEND cxx_compile_definitions "NOMINMAX") + else() + append_option_if_available("-Werror" cxx_compile_options) + append_option_if_available("-Wall" cxx_compile_options) + append_option_if_available("-Wextra" cxx_compile_options) + append_option_if_available("-Winit-self" cxx_compile_options) + append_option_if_available("-Woverloaded-virtual" cxx_compile_options) + append_option_if_available("-Wcast-qual" cxx_compile_options) + append_option_if_available("-Wpointer-arith" cxx_compile_options) + append_option_if_available("-Wunused-local-typedef" cxx_compile_options) + append_option_if_available("-Wvla" cxx_compile_options) + + # Disable GNU extensions (flag is clang only) + append_option_if_available("-Wgnu" cxx_compile_options) + # Calling a variadic macro with zero args is a GNU extension until C++20, + # but the THRUST_PP_ARITY macro is used with zero args. Need to see if this + # is a real problem worth fixing. + append_option_if_available("-Wno-gnu-zero-variadic-macro-arguments" cxx_compile_options) + + # This complains about functions in CUDA system headers when used with nvcc. + append_option_if_available("-Wno-unused-function" cxx_compile_options) + endif() + + if ("GNU" STREQUAL "${CMAKE_CXX_COMPILER_ID}") + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.3) + # GCC 7.3 complains about name mangling changes due to `noexcept` + # becoming part of the type system; we don't care. + append_option_if_available("-Wno-noexcept-type" cxx_compile_options) + endif() + endif() + + if ("Intel" STREQUAL "${CMAKE_CXX_COMPILER_ID}") + # Disable warning that inlining is inhibited by compiler thresholds. + append_option_if_available("-diag-disable=11074" cxx_compile_options) + append_option_if_available("-diag-disable=11076" cxx_compile_options) + endif() + + if ("NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + # Today: + # * NVCC accepts CUDA C++ in .cu files but not .cpp files. + # * NVC++ accepts CUDA C++ in .cpp files but not .cu files. + # TODO: This won't be necessary in the future. + list(APPEND cxx_compile_options -cppsuffix=cu) + endif() + + add_library(thrust.compiler_interface INTERFACE) + + foreach (cxx_option IN LISTS cxx_compile_options) + target_compile_options(thrust.compiler_interface INTERFACE + $<$:${cxx_option}> + $<$,$>:${cxx_option}> + # Only use -Xcompiler with NVCC, not NVC++. + # + # CMake can't split genexs, so this can't be formatted better :( + # This is: + # if (using CUDA and CUDA_COMPILER is NVCC) add -Xcompiler=opt: + $<$,$>:-Xcompiler=${cxx_option}> + ) + endforeach() + + foreach (cxx_definition IN LISTS cxx_compile_definitions) + # Add these for both CUDA and CXX targets: + target_compile_definitions(thrust.compiler_interface INTERFACE + ${cxx_definition} + ) + endforeach() + + # Display warning numbers from nvcc cudafe errors: + target_compile_options(thrust.compiler_interface INTERFACE + # If using CUDA w/ NVCC... + $<$,$>:-Xcudafe=--display_error_number> + ) + + # Tell NVCC to be quiet about deprecated GPU targets: + target_compile_options(thrust.compiler_interface INTERFACE + # If using CUDA w/ NVCC... + $<$,$>:-Wno-deprecated-gpu-targets> + ) + + # This is kept separate for Github issue #1174. + add_library(thrust.promote_cudafe_warnings INTERFACE) + target_compile_options(thrust.promote_cudafe_warnings INTERFACE + $<$,$>:-Xcudafe=--promote_warnings> + ) + + # Some of our unit tests unconditionally throw exceptions, and compilers will + # detect that the following instructions are unreachable. This is intentional + # and unavoidable in these cases. This target can be used to silence + # unreachable code warnings. + add_library(thrust.silence_unreachable_code_warnings INTERFACE) + if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + target_compile_options(thrust.silence_unreachable_code_warnings INTERFACE + $<$:/wd4702> + $<$,$>:-Xcompiler=/wd4702> + ) + endif() + + # These targets are used for dialect-specific options: + add_library(thrust.compiler_interface_cpp11 INTERFACE) + add_library(thrust.compiler_interface_cpp14 INTERFACE) + + if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # C4127: conditional expression is constant + # Disable this MSVC warning for C++11/C++14. In C++17, we can use + # THRUST_IF_CONSTEXPR to address these warnings. + target_compile_options(thrust.compiler_interface_cpp11 INTERFACE + $<$:/wd4127> + $<$,$>:-Xcompiler=/wd4127> + ) + target_compile_options(thrust.compiler_interface_cpp14 INTERFACE + $<$:/wd4127> + $<$,$>:-Xcompiler=/wd4127> + ) + endif() + +endfunction() diff --git a/cmake/ThrustBuildTargetList.cmake b/cmake/ThrustBuildTargetList.cmake new file mode 100644 index 000000000..f4adaf546 --- /dev/null +++ b/cmake/ThrustBuildTargetList.cmake @@ -0,0 +1,339 @@ +# This file provides utilities for building and working with thrust +# configuration targets. +# +# THRUST_TARGETS +# - Built by the calling the `thrust_build_target_list()` function. +# - Each item is the name of a thrust interface target that is configured for a +# certain combination of host/device/dialect. +# +# thrust_build_target_list() +# - Creates the THRUST_TARGETS list. +# +# The following functions can be used to test/set metadata on a thrust target: +# +# thrust_get_target_property( ) +# - Checks the ${prop} target property on thrust target ${target_name} +# and sets the ${prop_var} variable in the caller's scope. +# - is any valid cmake identifier. +# - is the name of a thrust target. +# - is one of the following: +# - HOST: The host system. Valid values: CPP, OMP, TBB. +# - DEVICE: The device system. Valid values: CUDA, CPP, OMP, TBB. +# - DIALECT: The C++ dialect. Valid values: 11, 14, 17, 20. +# - PREFIX: A unique prefix that should be used to name all +# targets/tests/examples that use this configuration. +# +# thrust_get_target_properties() +# - Defines ${target_name}_${prop} in the caller's scope, for `prop` in: +# HOST, DEVICE, DIALECT, PREFIX. See above for details. +# +# thrust_clone_target_properties( ) +# - Set the HOST, DEVICE, DIALECT, PREFIX metadata on ${dst_target} to match +# ${src_target}. See above for details. +# - This *MUST* be called on any targets that link to another thrust target +# to ensure that dialect information is updated correctly, e.g. +# `thrust_clone_target_properties(${my_thrust_test} ${some_thrust_target})` + +define_property(TARGET PROPERTY _THRUST_HOST + BRIEF_DOCS "A target's host system: CPP, TBB, or OMP." + FULL_DOCS "A target's host system: CPP, TBB, or OMP." +) +define_property(TARGET PROPERTY _THRUST_DEVICE + BRIEF_DOCS "A target's device system: CUDA, CPP, TBB, or OMP." + FULL_DOCS "A target's device system: CUDA, CPP, TBB, or OMP." +) +define_property(TARGET PROPERTY _THRUST_DIALECT + BRIEF_DOCS "A target's C++ dialect: 11, 14, or 17." + FULL_DOCS "A target's C++ dialect: 11, 14, or 17." +) +define_property(TARGET PROPERTY _THRUST_PREFIX + BRIEF_DOCS "A prefix describing the config, eg. 'thrust.cpp.cuda.cpp14'." + FULL_DOCS "A prefix describing the config, eg. 'thrust.cpp.cuda.cpp14'." +) + +function(thrust_set_target_properties target_name host device dialect prefix) + set_target_properties(${target_name} + PROPERTIES + _THRUST_HOST ${host} + _THRUST_DEVICE ${device} + _THRUST_DIALECT ${dialect} + _THRUST_PREFIX ${prefix} + ) + + get_property(langs GLOBAL PROPERTY ENABLED_LANGUAGES) + set(standard_features) + if (CUDA IN_LIST langs) + list(APPEND standard_features cuda_std_${dialect}) + endif() + if (CXX IN_LIST langs) + list(APPEND standard_features cxx_std_${dialect}) + endif() + + get_target_property(type ${target_name} TYPE) + if (${type} STREQUAL "INTERFACE_LIBRARY") + target_compile_features(${target_name} INTERFACE + ${standard_features} + ) + else() + target_compile_features(${target_name} PUBLIC + ${standard_features} + ) + set_target_properties(${target_name} + PROPERTIES + CXX_STANDARD ${dialect} + CUDA_STANDARD ${dialect} + # Must manually request that the standards above are actually respected + # or else CMake will silently fail to configure the targets correctly... + # Note that this doesn't actually work as of CMake 3.16: + # https://gitlab.kitware.com/cmake/cmake/-/issues/20953 + # We'll leave these properties enabled in hopes that they will someday + # work. + CXX_STANDARD_REQUIRED ON + CUDA_STANDARD_REQUIRED ON + ARCHIVE_OUTPUT_DIRECTORY "${THRUST_LIBRARY_OUTPUT_DIR}" + LIBRARY_OUTPUT_DIRECTORY "${THRUST_LIBRARY_OUTPUT_DIR}" + RUNTIME_OUTPUT_DIRECTORY "${THRUST_EXECUTABLE_OUTPUT_DIR}" + ) + + # CMake still emits errors about empty CUDA_ARCHITECTURES when CMP0104 + # is set to OLD. This suppresses the errors for good. + if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) + set_target_properties(${target_name} + PROPERTIES + CUDA_ARCHITECTURES OFF + ) + endif() + + if ("CUDA" STREQUAL "${device}" AND + "NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + set_target_properties(${target_name} PROPERTIES + CUDA_RESOLVE_DEVICE_SYMBOLS OFF + ) + endif() + endif() +endfunction() + +# Get a thrust property from a target and store it in var_name +# thrust_get_target_property( [HOST|DEVICE|DIALECT|PREFIX] +macro(thrust_get_target_property prop_var target_name prop) + get_property(${prop_var} TARGET ${target_name} PROPERTY _THRUST_${prop}) +endmacro() + +# Defines the following string variables in the caller's scope: +# - ${target_name}_HOST +# - ${target_name}_DEVICE +# - ${target_name}_DIALECT +# - ${target_name}_PREFIX +macro(thrust_get_target_properties target_name) + thrust_get_target_property(${target_name}_HOST ${target_name} HOST) + thrust_get_target_property(${target_name}_DEVICE ${target_name} DEVICE) + thrust_get_target_property(${target_name}_DIALECT ${target_name} DIALECT) + thrust_get_target_property(${target_name}_PREFIX ${target_name} PREFIX) +endmacro() + +# Set one target's THRUST_* properties to match another target +function(thrust_clone_target_properties dst_target src_target) + thrust_get_target_properties(${src_target}) + thrust_set_target_properties(${dst_target} + ${${src_target}_HOST} + ${${src_target}_DEVICE} + ${${src_target}_DIALECT} + ${${src_target}_PREFIX} + ) +endfunction() + +# Set ${var_name} to TRUE or FALSE in the caller's scope +function(_thrust_is_config_valid var_name host device dialect) + if (THRUST_MULTICONFIG_ENABLE_SYSTEM_${host} AND + THRUST_MULTICONFIG_ENABLE_SYSTEM_${device} AND + THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${dialect} AND + "${host}_${device}" IN_LIST THRUST_MULTICONFIG_WORKLOAD_${THRUST_MULTICONFIG_WORKLOAD}_CONFIGS) + set(${var_name} TRUE PARENT_SCOPE) + else() + set(${var_name} FALSE PARENT_SCOPE) + endif() +endfunction() + +function(_thrust_init_target_list) + set(THRUST_TARGETS "" CACHE INTERNAL "" FORCE) +endfunction() + +function(_thrust_add_target_to_target_list target_name host device dialect prefix) + thrust_set_target_properties(${target_name} ${host} ${device} ${dialect} ${prefix}) + + target_link_libraries(${target_name} INTERFACE + thrust.compiler_interface + ) + + # dialect-specific interface: + if (TARGET thrust.compiler_interface_cpp${dialect}) + target_link_libraries(${target_name} INTERFACE + thrust.compiler_interface_cpp${dialect} + ) + endif() + + # Workaround Github issue #1174. cudafe promote TBB header warnings to + # errors, even when they're -isystem includes. + if ((NOT host STREQUAL "TBB") OR (NOT device STREQUAL "CUDA")) + target_link_libraries(${target_name} INTERFACE + thrust.promote_cudafe_warnings + ) + endif() + + set(THRUST_TARGETS ${THRUST_TARGETS} ${target_name} CACHE INTERNAL "" FORCE) + + set(label "${host}.${device}.cpp${dialect}") + string(TOLOWER "${label}" label) + message(STATUS "Enabling Thrust configuration: ${label}") +endfunction() + +function(_thrust_build_target_list_multiconfig) + # Detect supported dialects if requested -- this must happen after CUDA is + # enabled, if it's going to be enabled. + if (THRUST_MULTICONFIG_ENABLE_DIALECT_ALL OR + THRUST_MULTICONFIG_ENABLE_DIALECT_LATEST) + message(STATUS "Testing for supported language standards...") + include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/DetectSupportedStandards.cmake") + detect_supported_standards(THRUST CXX ${THRUST_CPP_DIALECT_OPTIONS}) + if (THRUST_CUDA_FOUND) + detect_supported_standards(THRUST CUDA ${THRUST_CPP_DIALECT_OPTIONS}) + endif() + + # Take the union of supported standards in CXX and CUDA: + set(supported_dialects) + set(latest_dialect 11) + foreach(standard IN LISTS THRUST_CPP_DIALECT_OPTIONS) + if ((THRUST_CXX_${standard}_SUPPORTED) AND + ((NOT THRUST_CUDA_FOUND) OR THRUST_CUDA_${standard}_SUPPORTED)) + + # MSVC silently promotes C++11 to C++14 -- skip it: + if ((${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) AND (standard EQUAL 11)) + continue() + endif() + + list(APPEND supported_dialects ${standard}) + if (latest_dialect LESS standard) + set(latest_dialect ${standard}) + endif() + endif() + endforeach() + + if (THRUST_MULTICONFIG_ENABLE_DIALECT_ALL) + foreach(standard IN LISTS THRUST_CPP_DIALECT_OPTIONS) + if (standard IN_LIST supported_dialects) + set(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${standard} ON CACHE BOOL + "Generate C++${dialect} build configurations." FORCE + ) + else() + set(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${standard} OFF CACHE BOOL + "Generate C++${dialect} build configurations." FORCE + ) + endif() + endforeach() + elseif(THRUST_MULTICONFIG_ENABLE_DIALECT_LATEST) + foreach(standard IN LISTS THRUST_CPP_DIALECT_OPTIONS) + if (standard EQUAL latest_dialect) + set(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${standard} ON CACHE BOOL + "Generate C++${dialect} build configurations." FORCE + ) + else() + set(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${standard} OFF CACHE BOOL + "Generate C++${dialect} build configurations." FORCE + ) + endif() + endforeach() + endif() + endif() + + # Supported versions of MSVC do not distinguish between C++11 and C++14. + # Warn the user that they may be generating a ton of redundant targets if + # they explicitly requested this configuration. + if ("MSVC" STREQUAL "${CMAKE_CXX_COMPILER_ID}" AND + THRUST_MULTICONFIG_ENABLE_DIALECT_CPP11) + message(WARNING + "Supported versions of MSVC (2017+) do not distinguish between C++11 " + "and C++14. The requested C++11 targets may be redundant." + ) + endif() + + # Build THRUST_TARGETS + foreach(host IN LISTS THRUST_HOST_SYSTEM_OPTIONS) + foreach(device IN LISTS THRUST_DEVICE_SYSTEM_OPTIONS) + foreach(dialect IN LISTS THRUST_CPP_DIALECT_OPTIONS) + _thrust_is_config_valid(config_valid ${host} ${device} ${dialect}) + if (config_valid) + set(prefix "thrust.${host}.${device}.cpp${dialect}") + string(TOLOWER "${prefix}" prefix) + + # Configure a thrust interface target for this host/device + set(target_name "${prefix}") + thrust_create_target(${target_name} + HOST ${host} + DEVICE ${device} + ${THRUST_TARGET_FLAGS} + ) + + # Set configuration metadata for this thrust interface target: + _thrust_add_target_to_target_list(${target_name} + ${host} ${device} ${dialect} ${prefix} + ) + + # Create a meta target for all targets in this configuration: + add_custom_target(${prefix}.all) + add_dependencies(thrust.all ${prefix}.all) + endif() + endforeach() # dialects + endforeach() # devices + endforeach() # hosts + + list(LENGTH THRUST_TARGETS count) + message(STATUS "${count} unique thrust.host.device.dialect configurations generated") +endfunction() + +function(_thrust_build_target_list_singleconfig) + set(host ${THRUST_HOST_SYSTEM}) + set(device ${THRUST_DEVICE_SYSTEM}) + set(dialect ${THRUST_CPP_DIALECT}) + set(prefix "thrust") # single config + + _thrust_add_target_to_target_list(thrust ${host} ${device} ${dialect} ${prefix}) +endfunction() + +# Build a ${THRUST_TARGETS} list containing target names for all +# requested configurations +function(thrust_build_target_list) + # Clear the list of targets: + _thrust_init_target_list() + + # Generic config flags: + set(THRUST_TARGET_FLAGS) + macro(add_flag_option flag docstring default) + set(opt "THRUST_${flag}") + option(${opt} "${docstring}" "${default}") + mark_as_advanced(${opt}) + if (${${opt}}) + list(APPEND THRUST_TARGET_FLAGS ${flag}) + endif() + endmacro() + add_flag_option(IGNORE_DEPRECATED_CPP_DIALECT "Don't warn about any deprecated C++ standards and compilers." OFF) + add_flag_option(IGNORE_DEPRECATED_CPP_11 "Don't warn about deprecated C++11." OFF) + add_flag_option(IGNORE_DEPRECATED_COMPILER "Don't warn about deprecated compilers." OFF) + add_flag_option(IGNORE_CUB_VERSION_CHECK "Don't warn about mismatched CUB versions." OFF) + add_flag_option(IGNORE_DEPRECATED_API "Don't warn about deprecated Thrust or CUB APIs." OFF) + + # Top level meta-target. Makes it easier to just build thrust targets when + # building both CUB and Thrust. Add all project files here so IDEs will be + # aware of them. This will not generate build rules. + file(GLOB_RECURSE all_sources + RELATIVE "${CMAKE_CURRENT_LIST_DIR}" + "${Thrust_SOURCE_DIR}/thrust/*.h" + "${Thrust_SOURCE_DIR}/thrust/*.inl" + ) + add_custom_target(thrust.all SOURCES ${all_sources}) + + if (THRUST_ENABLE_MULTICONFIG) + _thrust_build_target_list_multiconfig() + else() + _thrust_build_target_list_singleconfig() + endif() +endfunction() diff --git a/cmake/ThrustCompilerHacks.cmake b/cmake/ThrustCompilerHacks.cmake new file mode 100644 index 000000000..5f7b0d98e --- /dev/null +++ b/cmake/ThrustCompilerHacks.cmake @@ -0,0 +1,110 @@ +# Set up compiler paths and apply temporary hacks to support NVC++. +# This file must be included before enabling any languages. + +# Temporary hacks to make NVC++ work; this requires you to define +# `CMAKE_CUDA_COMPILER_ID=NVCXX and `CMAKE_CUDA_COMPILER_FORCED=ON`. +if ("NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + # If using NVC++, don't set CXX compiler + if (NOT "${CMAKE_CXX_COMPILER}" STREQUAL "") + unset(CMAKE_CXX_COMPILER CACHE) + message(FATAL_ERROR "You are using NVC++ as your CUDA C++ compiler, but have" + " specified a different ISO C++ compiler; NVC++ acts as both, so please" + " unset the CMAKE_CXX_COMPILER variable." + ) + endif() + + # We don't set CMAKE_CUDA_HOST_COMPILER for NVC++; if we do, CMake tries to + # pass `-ccbin ${CMAKE_CUDA_HOST_COMPILER}` to NVC++, which it doesn't + # understand. + if (NOT "${CMAKE_CUDA_HOST_COMPILER}" STREQUAL "") + unset(CMAKE_CUDA_HOST_COMPILER CACHE) + message(FATAL_ERROR "You are using NVC++ as your CUDA C++ compiler, but have" + " specified a different host ISO C++ compiler; NVC++ acts as both, so" + " please unset the CMAKE_CUDA_HOST_COMPILER variable." + ) + endif() + + set(CMAKE_CXX_COMPILER "${CMAKE_CUDA_COMPILER}") + set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -stdpar") + set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${CMAKE_CUDA_COMPILER}") + set(CMAKE_CUDA_LINK_EXECUTABLE + " -o ") + + # Setup CMAKE_CXX_LIBRARY_ARCHITECTURE on Debian/Ubuntu so that find_package + # works properly. + if (EXISTS /etc/debian_version) + if (NOT CMAKE_CXX_LIBRARY_ARCHITECTURE) + file(GLOB files_in_lib RELATIVE /lib /lib/*-linux-gnu* ) + foreach (file ${files_in_lib}) + if ("${file}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}") + set(CMAKE_CXX_LIBRARY_ARCHITECTURE ${file}) + break() + endif() + endforeach() + endif() + if (NOT CMAKE_LIBRARY_ARCHITECTURE) + set(CMAKE_LIBRARY_ARCHITECTURE ${CMAKE_CXX_LIBRARY_ARCHITECTURE}) + endif() + endif() +endif() + +# We don't set CMAKE_CUDA_HOST_COMPILER for NVC++; if we do, CMake tries to +# pass `-ccbin ${CMAKE_CUDA_HOST_COMPILER}` to NVC++, which it doesn't +# understand. +if ((NOT "NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}")) + if (NOT ("${CMAKE_CUDA_HOST_COMPILER}" STREQUAL "" OR + "${CMAKE_CUDA_HOST_COMPILER}" STREQUAL "${CMAKE_CXX_COMPILER}")) + set(tmp "${CMAKE_CUDA_HOST_COMPILER}") + unset(CMAKE_CUDA_HOST_COMPILER CACHE) + message(FATAL_ERROR + "For convenience, Thrust's test harness uses CMAKE_CXX_COMPILER for the " + "CUDA host compiler. Refusing to overwrite specified " + "CMAKE_CUDA_HOST_COMPILER -- please reconfigure without setting this " + "variable. Currently:\n" + "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\n" + "CMAKE_CUDA_HOST_COMPILER=${tmp}" + ) + endif () + set(CMAKE_CUDA_HOST_COMPILER "${CMAKE_CXX_COMPILER}") +endif () + +# Temporary hacks to make NVC++ work; this requires you to define +# `CMAKE_CUDA_COMPILER_ID=NVCXX and `CMAKE_CUDA_COMPILER_FORCED=ON`. +if ("NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + # Need 3.17 for the properties used below. + cmake_minimum_required(VERSION 3.17) + + set(CMAKE_CUDA_STANDARD_DEFAULT 03) + + set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "-std=c++03") + set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "-std=c++03") + set(CMAKE_CUDA03_STANDARD__HAS_FULL_SUPPORT TRUE) + set_property(GLOBAL PROPERTY CMAKE_CUDA03_KNOWN_FEATURES) + + set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "-std=c++11") + set(CMAKE_CUDA11_STANDARD__HAS_FULL_SUPPORT TRUE) + set_property(GLOBAL PROPERTY CMAKE_CUDA11_KNOWN_FEATURES) + + set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14") + set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14") + set(CMAKE_CUDA14_STANDARD__HAS_FULL_SUPPORT TRUE) + set_property(GLOBAL PROPERTY CMAKE_CUDA14_KNOWN_FEATURES) + + set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "-std=c++17") + set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "-std=c++17") + set(CMAKE_CUDA17_STANDARD__HAS_FULL_SUPPORT TRUE) + set_property(GLOBAL PROPERTY CMAKE_CUDA17_KNOWN_FEATURES) + + include(Internal/FeatureTesting) + include(Compiler/CMakeCommonCompilerMacros) + cmake_record_cuda_compile_features() + + set(CMAKE_CUDA_COMPILE_FEATURES + ${CMAKE_CUDA03_COMPILE_FEATURES} + ${CMAKE_CUDA11_COMPILE_FEATURES} + ${CMAKE_CUDA14_COMPILE_FEATURES} + ${CMAKE_CUDA17_COMPILE_FEATURES} + ${CMAKE_CUDA20_COMPILE_FEATURES} + ) +endif() diff --git a/cmake/ThrustCudaConfig.cmake b/cmake/ThrustCudaConfig.cmake new file mode 100644 index 000000000..a585c7910 --- /dev/null +++ b/cmake/ThrustCudaConfig.cmake @@ -0,0 +1,200 @@ +enable_language(CUDA) + +set(THRUST_KNOWN_COMPUTE_ARCHS 50 52 53 60 61 62 70 72 75 80 86) + +if (NVIDIA STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER 11.7) + list(APPEND THRUST_KNOWN_COMPUTE_ARCHS 90) + endif() + if (CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0) + list(APPEND THRUST_KNOWN_COMPUTE_ARCHS 35 37) + endif() +else() + list(APPEND THRUST_KNOWN_COMPUTE_ARCHS 35 37 90) +endif() + +# Split CUDA_FLAGS into 3 parts: +# +# THRUST_CUDA_FLAGS_BASE: Common CUDA flags for all targets. +# THRUST_CUDA_FLAGS_RDC: Additional CUDA flags for targets compiled with RDC. +# THRUST_CUDA_FLAGS_NO_RDC: Additional CUDA flags for targets compiled without RDC. +# +# This is necessary because CUDA SMs 5.3, 6.2, and 7.2 do not support RDC, but +# we want to always build some targets (e.g. testing/cuda/*) with RDC. +# We work around this by building the "always RDC" targets without support for +# those SMs. This requires two sets of CUDA_FLAGS. +# +# Enabling any of those SMs along with the ENABLE_RDC options will result in a +# configuration error. +# +# Because of how CMake handles the CMAKE_CUDA_FLAGS variables, every target +# generated in a given directory will use the same value for CMAKE_CUDA_FLAGS, +# which is determined at the end of the directory's scope. This means caution +# should be used when trying to build different targets with different flags, +# since they might not behave as expected. This will improve with CMake 3.18, +# which add the DEVICE_LINK genex, fixing the issue with using per-target +# CUDA_FLAGS: https://gitlab.kitware.com/cmake/cmake/-/issues/18265 +set(THRUST_CUDA_FLAGS_BASE "${CMAKE_CUDA_FLAGS}") +set(THRUST_CUDA_FLAGS_RDC) +set(THRUST_CUDA_FLAGS_NO_RDC) + +# Archs that don't support RDC: +set(no_rdc_archs 53 62 72) + +# Find the highest arch: +list(SORT THRUST_KNOWN_COMPUTE_ARCHS) +list(LENGTH THRUST_KNOWN_COMPUTE_ARCHS max_idx) +math(EXPR max_idx "${max_idx} - 1") +list(GET THRUST_KNOWN_COMPUTE_ARCHS ${max_idx} highest_arch) + +option(THRUST_AUTO_DETECT_COMPUTE_ARCHS + "If ON, compute architectures for all GPUs in the current system are enabled and all other compute architectures are disabled." + OFF +) + +if (THRUST_AUTO_DETECT_COMPUTE_ARCHS) + if ("NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + message(STATUS "Thrust: Using NVC++ builtin automatic compute architecture detection.") + else() + set(detect_compute_archs_source ${Thrust_SOURCE_DIR}/cmake/detect_compute_archs.cu) + set(detect_compute_archs_exe ${PROJECT_BINARY_DIR}/detect_compute_archs) + set(detect_compute_archs_error_log ${PROJECT_BINARY_DIR}/detect_compute_archs.stderr.log) + execute_process( + COMMAND ${CMAKE_CUDA_COMPILER} + -std=c++11 + -o ${detect_compute_archs_exe} + --run + ${detect_compute_archs_source} + OUTPUT_VARIABLE detected_archs + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_FILE ${detect_compute_archs_error_log}) + if ("NONE" STREQUAL "${detected_archs}") + set(detected_message " none") + else() + foreach (arch IN LISTS detected_archs) + string(APPEND detected_message " sm_${arch}") + endforeach() + endif() + message(STATUS "Thrust: Automatically detected compute architectures:${detected_message}") + endif() +endif() + +set(option_init OFF) +if ("NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + set(option_init ON) +endif() +option(THRUST_DISABLE_ARCH_BY_DEFAULT + "If ON, then all compute architectures are disabled on the initial CMake run." + ${option_init} +) + +set(option_init ON) +if (THRUST_DISABLE_ARCH_BY_DEFAULT OR THRUST_AUTO_DETECT_COMPUTE_ARCHS) + set(option_init OFF) +endif() + +set(num_archs_enabled 0) +foreach (arch IN LISTS THRUST_KNOWN_COMPUTE_ARCHS) + set(this_option_init ${option_init}) + + if (${arch} IN_LIST detected_archs) + set(this_option_init ON) + endif() + + option(THRUST_ENABLE_COMPUTE_${arch} + "Enable code generation for tests for sm_${arch}" + ${this_option_init} + ) + + if (NOT THRUST_ENABLE_COMPUTE_${arch}) + continue() + endif() + + math(EXPR num_archs_enabled "${num_archs_enabled} + 1") + + if ("NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + if (NOT ${num_archs_enabled} EQUAL 1) + message(FATAL_ERROR + "NVCXX does not support compilation for multiple device architectures " + "at once." + ) + endif() + set(arch_flag "-gpu=cc${arch}") + elseif ("Clang" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + set(arch_flag "--cuda-gpu-arch=sm_${arch}") + else() + set(arch_flag "-gencode arch=compute_${arch},code=sm_${arch}") + endif() + + string(APPEND compute_message " sm_${arch}") + string(APPEND THRUST_CUDA_FLAGS_NO_RDC " ${arch_flag}") + if (NOT arch IN_LIST no_rdc_archs) + string(APPEND THRUST_CUDA_FLAGS_RDC " ${arch_flag}") + endif() +endforeach() + +if (NOT "NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + option(THRUST_ENABLE_COMPUTE_FUTURE + "Enable code generation for tests for compute_${highest_arch}" + ${option_init} + ) + if (THRUST_ENABLE_COMPUTE_FUTURE) + string(APPEND THRUST_CUDA_FLAGS_BASE + " -gencode arch=compute_${highest_arch},code=compute_${highest_arch}" + ) + string(APPEND compute_message " compute_${highest_arch}") + endif() +endif() + +message(STATUS "Thrust: Explicitly enabled compute architectures:${compute_message}") + +# RDC is off by default in NVCC and on by default in NVC++. Turning off RDC +# isn't currently supported by NVC++. So, we default to RDC off for NVCC and +# RDC on for NVC++. +set(option_init OFF) +if ("NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + set(option_init ON) +endif() + +option(THRUST_ENABLE_TESTS_WITH_RDC + "Build all Thrust tests with RDC; tests that require RDC are not affected by this option." + ${option_init} +) + +option(THRUST_ENABLE_EXAMPLES_WITH_RDC + "Build all Thrust examples with RDC; examples which require RDC are not affected by this option." + ${option_init} +) + +# Check for RDC/SM compatibility and error/warn if necessary +foreach (sm IN LISTS no_rdc_archs) + set(sm_opt THRUST_ENABLE_COMPUTE_${sm}) + if (${sm_opt}) + foreach (opt IN ITEMS TESTS EXAMPLES) + set(rdc_opt THRUST_ENABLE_${opt}_WITH_RDC) + if (${rdc_opt}) + message(FATAL_ERROR + "${rdc_opt} is incompatible with ${sm_opt}, since sm_${sm} does not " + "support RDC." + ) + endif() + endforeach() + + message(NOTICE + "sm_${sm} does not support RDC. Targets that require RDC will be built " + "without support for this architecture." + ) + endif() +endforeach() + + +# +# Clang CUDA options +# +if ("Clang" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + set(THRUST_CUDA_FLAGS_BASE "${THRUST_CUDA_FLAGS_BASE} -Wno-unknown-cuda-version -Xclang=-fcuda-allow-variadic-functions") +endif() + + +# By default RDC is not used: +set(CMAKE_CUDA_FLAGS "${THRUST_CUDA_FLAGS_BASE} ${THRUST_CUDA_FLAGS_NO_RDC}") diff --git a/cmake/ThrustFindThrust.cmake b/cmake/ThrustFindThrust.cmake new file mode 100644 index 000000000..39a79e4b7 --- /dev/null +++ b/cmake/ThrustFindThrust.cmake @@ -0,0 +1,42 @@ +function(_thrust_find_thrust_multiconfig) + # Check which systems are enabled by multiconfig: + set(req_systems) + if (THRUST_MULTICONFIG_ENABLE_SYSTEM_CUDA) + list(APPEND req_systems CUDA) + endif() + if (THRUST_MULTICONFIG_ENABLE_SYSTEM_CPP) + list(APPEND req_systems CPP) + endif() + if (THRUST_MULTICONFIG_ENABLE_SYSTEM_TBB) + list(APPEND req_systems TBB) + endif() + if (THRUST_MULTICONFIG_ENABLE_SYSTEM_OMP) + list(APPEND req_systems OMP) + endif() + + find_package(Thrust REQUIRED CONFIG + NO_DEFAULT_PATH # Only check the explicit path in HINTS: + HINTS "${Thrust_SOURCE_DIR}" + COMPONENTS ${req_systems} + ) +endfunction() + +function(_thrust_find_thrust_singleconfig) + find_package(Thrust REQUIRED CONFIG + NO_DEFAULT_PATH # Only check the explicit path in HINTS: + HINTS "${Thrust_SOURCE_DIR}" + ) + # Create target now to prepare system found flags: + thrust_create_target(thrust FROM_OPTIONS ${THRUST_TARGET_FLAGS}) + thrust_debug_target(thrust "${THRUST_VERSION}") +endfunction() + +# Build a ${THRUST_TARGETS} list containing target names for all +# requested configurations +function(thrust_find_thrust) + if (THRUST_ENABLE_MULTICONFIG) + _thrust_find_thrust_multiconfig() + else() + _thrust_find_thrust_singleconfig() + endif() +endfunction() diff --git a/cmake/ThrustHeaderTesting.cmake b/cmake/ThrustHeaderTesting.cmake new file mode 100644 index 000000000..3b3e00ca8 --- /dev/null +++ b/cmake/ThrustHeaderTesting.cmake @@ -0,0 +1,140 @@ +# For every public header, build a translation unit containing `#include
` +# to let the compiler try to figure out warnings in that header if it is not otherwise +# included in tests, and also to verify if the headers are modular enough. +# .inl files are not globbed for, because they are not supposed to be used as public +# entrypoints. + +# Meta target for all configs' header builds: +add_custom_target(thrust.all.headers) + +foreach(thrust_target IN LISTS THRUST_TARGETS) + thrust_get_target_property(config_host ${thrust_target} HOST) + thrust_get_target_property(config_device ${thrust_target} DEVICE) + thrust_get_target_property(config_prefix ${thrust_target} PREFIX) + set(config_systems ${config_host} ${config_device}) + + string(TOLOWER "${config_host}" host_lower) + string(TOLOWER "${config_device}" device_lower) + + # GLOB ALL THE THINGS + set(headers_globs thrust/*.h) + set(headers_exclude_systems_globs thrust/system/*/*) + set(headers_systems_globs + thrust/system/${host_lower}/* + thrust/system/${device_lower}/* + ) + set(headers_exclude_details_globs + thrust/detail/* + thrust/*/detail/* + thrust/*/*/detail/* + ) + + # Get all .h files... + file(GLOB_RECURSE headers + RELATIVE "${Thrust_SOURCE_DIR}/thrust" + CONFIGURE_DEPENDS + ${headers_globs} + ) + + # ...then remove all system specific headers... + file(GLOB_RECURSE headers_exclude_systems + RELATIVE "${Thrust_SOURCE_DIR}/thrust" + CONFIGURE_DEPENDS + ${headers_exclude_systems_globs} + ) + list(REMOVE_ITEM headers ${headers_exclude_systems}) + + # ...then add all headers specific to the selected host and device systems back again... + file(GLOB_RECURSE headers_systems + RELATIVE ${Thrust_SOURCE_DIR}/thrust + CONFIGURE_DEPENDS + ${headers_systems_globs} + ) + list(APPEND headers ${headers_systems}) + + # ...and remove all the detail headers (also removing the detail headers from the selected systems). + file(GLOB_RECURSE headers_exclude_details + RELATIVE "${Thrust_SOURCE_DIR}/thrust" + CONFIGURE_DEPENDS + ${headers_exclude_details_globs} + ) + list(REMOVE_ITEM headers ${headers_exclude_details}) + + # List of headers that aren't implemented for all backends, but are implemented for CUDA. + set(partially_implemented_CUDA + async/copy.h + async/for_each.h + async/reduce.h + async/scan.h + async/sort.h + async/transform.h + event.h + future.h + ) + + # List of headers that aren't implemented for all backends, but are implemented for CPP. + set(partially_implemented_CPP + ) + + # List of headers that aren't implemented for all backends, but are implemented for TBB. + set(partially_implemented_TBB + ) + + # List of headers that aren't implemented for all backends, but are implemented for OMP. + set(partially_implemented_OMP + ) + + # List of all partially implemented headers. + set(partially_implemented + ${partially_implemented_CUDA} + ${partially_implemented_CPP} + ${partially_implemented_TBB} + ${partially_implemented_OMP} + ) + list(REMOVE_DUPLICATES partially_implemented) + + set(headertest_srcs) + + foreach (header IN LISTS headers) + if ("${header}" IN_LIST partially_implemented) + # This header is partially implemented on _some_ backends... + if (NOT "${header}" IN_LIST partially_implemented_${config_device}) + # ...but not on the selected one. + continue() + endif() + endif() + + set(headertest_src_ext .cpp) + if ("CUDA" STREQUAL "${config_device}") + set(headertest_src_ext .cu) + endif() + + set(headertest_src "headers/${config_prefix}/${header}${headertest_src_ext}") + configure_file("${Thrust_SOURCE_DIR}/cmake/header_test.in" "${headertest_src}") + + list(APPEND headertest_srcs "${headertest_src}") + endforeach() + + set(headertest_target ${config_prefix}.headers) + add_library(${headertest_target} OBJECT ${headertest_srcs}) + target_link_libraries(${headertest_target} PUBLIC ${thrust_target}) + # Wrap Thrust/CUB in a custom namespace to check proper use of ns macros: + target_compile_definitions(${headertest_target} PRIVATE + "THRUST_WRAPPED_NAMESPACE=wrapped_thrust" + "CUB_WRAPPED_NAMESPACE=wrapped_cub" + ) + thrust_clone_target_properties(${headertest_target} ${thrust_target}) + + # Disable macro checks on TBB; the TBB atomic implementation uses `I` and + # our checks will issue false errors. + if ("TBB" IN_LIST config_systems) + target_compile_definitions(${headertest_target} + PRIVATE THRUST_IGNORE_MACRO_CHECKS + ) + endif() + + thrust_fix_clang_nvcc_build_for(${headertest_target}) + + add_dependencies(thrust.all.headers ${headertest_target}) + add_dependencies(${config_prefix}.all ${headertest_target}) +endforeach() diff --git a/cmake/ThrustInstallRules.cmake b/cmake/ThrustInstallRules.cmake new file mode 100644 index 000000000..98e72e196 --- /dev/null +++ b/cmake/ThrustInstallRules.cmake @@ -0,0 +1,58 @@ +# Bring in CMAKE_INSTALL_LIBDIR +include(GNUInstallDirs) + +# Thrust is a header library; no need to build anything before installing: +set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY TRUE) + +install(DIRECTORY "${Thrust_SOURCE_DIR}/thrust" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + FILES_MATCHING + PATTERN "*.h" + PATTERN "*.inl" +) + +install(DIRECTORY "${Thrust_SOURCE_DIR}/thrust/cmake/" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/thrust" + PATTERN *.cmake.in EXCLUDE +) +# Need to configure a file to store the infix specified in +# CMAKE_INSTALL_INCLUDEDIR since it can be defined by the user +set(install_location "${CMAKE_INSTALL_LIBDIR}/cmake/thrust") +configure_file("${Thrust_SOURCE_DIR}/thrust/cmake/thrust-header-search.cmake.in" + "${Thrust_BINARY_DIR}/thrust/cmake/thrust-header-search.cmake" + @ONLY) +install(FILES "${Thrust_BINARY_DIR}/thrust/cmake/thrust-header-search.cmake" + DESTINATION "${install_location}") + +# Depending on how Thrust is configured, libcudacxx and CUB's CMake scripts may +# or may not be include()'d, so force include their install rules when requested. +# By default, these projects are installed alongside Thrust. This is controlled by +# THRUST_INSTALL_CUB_HEADERS and THRUST_INSTALL_LIBCUDACXX_HEADERS. +option(THRUST_INSTALL_CUB_HEADERS "Include CUB headers when installing." ON) +if (THRUST_INSTALL_CUB_HEADERS) + # Use a function to limit scope of the CUB_*_DIR vars: + function(_thrust_install_cub_headers) + # Fake these for the logic in CUBInstallRules.cmake: + set(CUB_SOURCE_DIR "${Thrust_SOURCE_DIR}/dependencies/cub/") + set(CUB_BINARY_DIR "${Thrust_BINARY_DIR}/cub-config/") + set(CUB_ENABLE_INSTALL_RULES ON) + set(CUB_IN_THRUST OFF) + include("${Thrust_SOURCE_DIR}/dependencies/cub/cmake/CubInstallRules.cmake") + endfunction() + + _thrust_install_cub_headers() +endif() + +option(THRUST_INSTALL_LIBCUDACXX_HEADERS "Include libcudacxx headers when installing." ON) +if (THRUST_INSTALL_LIBCUDACXX_HEADERS) + # Use a function to limit scope of the libcudacxx_*_DIR vars: + function(_thrust_install_libcudacxx_headers) + # Fake these for the logic in libcudacxxInstallRules.cmake: + set(libcudacxx_SOURCE_DIR "${Thrust_SOURCE_DIR}/dependencies/libcudacxx/") + set(libcudacxx_BINARY_DIR "${Thrust_BINARY_DIR}/libcudacxx-config/") + set(libcudacxx_ENABLE_INSTALL_RULES ON) + include("${Thrust_SOURCE_DIR}/dependencies/libcudacxx/cmake/libcudacxxInstallRules.cmake") + endfunction() + + _thrust_install_libcudacxx_headers() +endif() diff --git a/cmake/ThrustMultiConfig.cmake b/cmake/ThrustMultiConfig.cmake new file mode 100644 index 000000000..aa9fc0226 --- /dev/null +++ b/cmake/ThrustMultiConfig.cmake @@ -0,0 +1,129 @@ +# This file defines thrust_configure_multiconfig(), which sets up and handles +# the MultiConfig options that allow multiple host/device/dialect configurations +# to be generated from a single thrust build. + +function(thrust_configure_multiconfig) + option(THRUST_ENABLE_MULTICONFIG "Enable multiconfig options for coverage testing." OFF) + + # Dialects: + set(THRUST_CPP_DIALECT_OPTIONS + 11 14 17 20 + CACHE INTERNAL "C++ dialects supported by Thrust." FORCE + ) + + if (THRUST_ENABLE_MULTICONFIG) + # Handle dialect options: + foreach (dialect IN LISTS THRUST_CPP_DIALECT_OPTIONS) + set(default_value OFF) + if (dialect EQUAL 14) # Default to just 14 on: + set(default_value ON) + endif() + option(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${dialect} + "Generate C++${dialect} build configurations." + ${default_value} + ) + endforeach() + + # Option to enable all standards supported by the CUDA and CXX compilers: + option(THRUST_MULTICONFIG_ENABLE_DIALECT_ALL + "Generate build configurations for all C++ standards supported by the configured compilers." + OFF + ) + + # Option to enable only the most recent supported dialect: + option(THRUST_MULTICONFIG_ENABLE_DIALECT_LATEST + "Generate a single build configuration for the most recent C++ standard supported by the configured compilers." + OFF + ) + + # Systems: + option(THRUST_MULTICONFIG_ENABLE_SYSTEM_CPP "Generate build configurations that use CPP." ON) + option(THRUST_MULTICONFIG_ENABLE_SYSTEM_CUDA "Generate build configurations that use CUDA." ON) + option(THRUST_MULTICONFIG_ENABLE_SYSTEM_OMP "Generate build configurations that use OpenMP." OFF) + option(THRUST_MULTICONFIG_ENABLE_SYSTEM_TBB "Generate build configurations that use TBB." OFF) + + # CMake fixed C++17 support for NVCC + MSVC targets in 3.18.3: + if (THRUST_MULTICONFIG_ENABLE_DIALECT_CPP17 AND + THRUST_MULTICONFIG_ENABLE_SYSTEM_CUDA) + cmake_minimum_required(VERSION 3.18.3) + endif() + + # Workload: + # - `SMALL`: [3 configs] Minimal coverage and validation of each device system against the `CPP` host. + # - `MEDIUM`: [6 configs] Cheap extended coverage. + # - `LARGE`: [8 configs] Expensive extended coverage. Include all useful build configurations. + # - `FULL`: [12 configs] The complete cross product of all possible build configurations. + # + # Config | Workloads | Value | Expense | Note + # ---------|-----------|------------|-----------|----------------------------- + # CPP/CUDA | F L M S | Essential | Expensive | Validates CUDA against CPP + # CPP/OMP | F L M S | Essential | Cheap | Validates OMP against CPP + # CPP/TBB | F L M S | Essential | Cheap | Validates TBB against CPP + # CPP/CPP | F L M | Important | Cheap | Tests CPP as device + # OMP/OMP | F L M | Important | Cheap | Tests OMP as host + # TBB/TBB | F L M | Important | Cheap | Tests TBB as host + # TBB/CUDA | F L | Important | Expensive | Validates TBB/CUDA interop + # OMP/CUDA | F L | Important | Expensive | Validates OMP/CUDA interop + # TBB/OMP | F | Not useful | Cheap | Mixes CPU-parallel systems + # OMP/TBB | F | Not useful | Cheap | Mixes CPU-parallel systems + # TBB/CPP | F | Not Useful | Cheap | Parallel host, serial device + # OMP/CPP | F | Not Useful | Cheap | Parallel host, serial device + + set(THRUST_MULTICONFIG_WORKLOAD SMALL CACHE STRING + "Limit host/device configs: SMALL (up to 3 h/d combos per dialect), MEDIUM(6), LARGE(8), FULL(12)" + ) + set_property(CACHE THRUST_MULTICONFIG_WORKLOAD PROPERTY STRINGS + SMALL MEDIUM LARGE FULL + ) + set(THRUST_MULTICONFIG_WORKLOAD_SMALL_CONFIGS + CPP_OMP CPP_TBB CPP_CUDA + CACHE INTERNAL "Host/device combos enabled for SMALL workloads." FORCE + ) + set(THRUST_MULTICONFIG_WORKLOAD_MEDIUM_CONFIGS + ${THRUST_MULTICONFIG_WORKLOAD_SMALL_CONFIGS} + CPP_CPP TBB_TBB OMP_OMP + CACHE INTERNAL "Host/device combos enabled for MEDIUM workloads." FORCE + ) + set(THRUST_MULTICONFIG_WORKLOAD_LARGE_CONFIGS + ${THRUST_MULTICONFIG_WORKLOAD_MEDIUM_CONFIGS} + OMP_CUDA TBB_CUDA + CACHE INTERNAL "Host/device combos enabled for LARGE workloads." FORCE + ) + set(THRUST_MULTICONFIG_WORKLOAD_FULL_CONFIGS + ${THRUST_MULTICONFIG_WORKLOAD_LARGE_CONFIGS} + OMP_CPP TBB_CPP OMP_TBB TBB_OMP + CACHE INTERNAL "Host/device combos enabled for FULL workloads." FORCE + ) + + # Hide the single config options if they exist from a previous run: + if (DEFINED THRUST_HOST_SYSTEM) + set_property(CACHE THRUST_HOST_SYSTEM PROPERTY TYPE INTERNAL) + set_property(CACHE THRUST_DEVICE_SYSTEM PROPERTY TYPE INTERNAL) + endif() + if (DEFINED THRUST_CPP_DIALECT) + set_property(CACHE THRUST_CPP_DIALECT PROPERTY TYPE INTERNAL) + endif() + + else() # Single config: + # Restore system option visibility if these cache options already exist + # from a previous run. + if (DEFINED THRUST_HOST_SYSTEM) + set_property(CACHE THRUST_HOST_SYSTEM PROPERTY TYPE STRING) + set_property(CACHE THRUST_DEVICE_SYSTEM PROPERTY TYPE STRING) + endif() + + set(THRUST_CPP_DIALECT 14 + CACHE STRING "The C++ standard to target: ${THRUST_CPP_DIALECT_OPTIONS}" + ) + set_property(CACHE THRUST_CPP_DIALECT + PROPERTY STRINGS + ${THRUST_CPP_DIALECT_OPTIONS} + ) + + # CMake fixed C++17 support for NVCC + MSVC targets in 3.18.3: + if (THRUST_CPP_DIALECT EQUAL 17 AND + THRUST_DEVICE_SYSTEM STREQUAL "CUDA") + cmake_minimum_required(VERSION 3.18.3) + endif() + endif() +endfunction() diff --git a/cmake/ThrustRunExample.cmake b/cmake/ThrustRunExample.cmake new file mode 100644 index 000000000..24e9dd2bb --- /dev/null +++ b/cmake/ThrustRunExample.cmake @@ -0,0 +1,49 @@ +# Inputs: +# +# Variable | Type | Doc +# ---------------------|----------|-------------------------------------- +# EXAMPLE_EXECUTABLE | FilePath | Path to example executable +# FILECHECK_ENABLED | Boolean | Run FileCheck comparison test +# FILECHECK_EXECUTABLE | FilePath | Path to the LLVM FileCheck utility +# REFERENCE_FILE | FilePath | Path to the FileCheck reference file + +if (FILECHECK_ENABLED) + if (NOT EXISTS "${REFERENCE_FILE}") + message(FATAL_ERROR + "FileCheck requested for '${EXAMPLE_EXECUTABLE}', but reference file " + "does not exist at '${REFERENCE_FILE}`." + ) + endif() + + # If the reference file is empty, validate that the example doesn't + # produce any output. + file(SIZE "${REFERENCE_FILE}" file_size) + message("${REFERENCE_FILE}: ${file_size} bytes") + + if (file_size EQUAL 0) + set(check_empty_output TRUE) + set(filecheck_command) + else() + set(check_empty_output FALSE) + set(filecheck_command COMMAND "${FILECHECK_EXECUTABLE}" "${REFERENCE_FILE}") + endif() +endif() + +execute_process( + COMMAND "${EXAMPLE_EXECUTABLE}" + ${filecheck_command} + RESULT_VARIABLE exit_code + OUTPUT_VARIABLE stdout + ERROR_VARIABLE stderr +) + +if (NOT 0 EQUAL exit_code) + message(FATAL_ERROR "${EXAMPLE_EXECUTABLE} failed (${exit_code}):\n${stderr}") +endif() + +if (check_empty_output) + string(LENGTH "${stdout}" stdout_size) + if (NOT stdout_size EQUAL 0) + message(FATAL_ERROR "${EXAMPLE_EXECUTABLE}: output received, but not expected:\n${stdout}") + endif() +endif() diff --git a/cmake/ThrustRunTest.cmake b/cmake/ThrustRunTest.cmake new file mode 100644 index 000000000..0d03129f0 --- /dev/null +++ b/cmake/ThrustRunTest.cmake @@ -0,0 +1,8 @@ +execute_process( + COMMAND "${THRUST_BINARY}" + RESULT_VARIABLE EXIT_CODE +) + +if (NOT "0" STREQUAL "${EXIT_CODE}") + message(FATAL_ERROR "${THRUST_BINARY} failed (${EXIT_CODE})") +endif () diff --git a/cmake/ThrustUtilities.cmake b/cmake/ThrustUtilities.cmake new file mode 100644 index 000000000..6bbb1200a --- /dev/null +++ b/cmake/ThrustUtilities.cmake @@ -0,0 +1,25 @@ +# Given a cu_file (e.g. foo/bar.cu) relative to CMAKE_CURRENT_SOURCE_DIR +# and a thrust_target, create a cpp file that includes the .cu file, and set +# ${cpp_file_var} in the parent scope to the full path of the new file. The new +# file will be generated in: +# ${CMAKE_CURRENT_BINARY_DIR}//${cu_file}.cpp +function(thrust_wrap_cu_in_cpp cpp_file_var cu_file thrust_target) + thrust_get_target_property(prefix ${thrust_target} PREFIX) + set(wrapped_source_file "${CMAKE_CURRENT_SOURCE_DIR}/${cu_file}") + set(cpp_file "${CMAKE_CURRENT_BINARY_DIR}/${prefix}/${cu_file}.cpp") + configure_file("${Thrust_SOURCE_DIR}/cmake/wrap_source_file.cpp.in" "${cpp_file}") + set(${cpp_file_var} "${cpp_file}" PARENT_SCOPE) +endfunction() + +# Enable RDC for a CUDA target. Encapsulates compiler hacks: +function(thrust_enable_rdc_for_cuda_target target_name) + if ("NVCXX" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") + set_target_properties(${target_name} PROPERTIES + COMPILE_FLAGS "-gpu=rdc" + ) + else() + set_target_properties(${target_name} PROPERTIES + CUDA_SEPARABLE_COMPILATION ON + ) + endif() +endfunction() diff --git a/cmake/detect_compute_archs.cu b/cmake/detect_compute_archs.cu new file mode 100644 index 000000000..1d30dca4b --- /dev/null +++ b/cmake/detect_compute_archs.cu @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +int main(int argc, char** argv) { + std::set archs; + int devices; + if ((cudaGetDeviceCount(&devices) == cudaSuccess) && (devices > 0)) { + for (int dev = 0; dev < devices; ++dev) { + char buff[32]; + cudaDeviceProp prop; + if(cudaGetDeviceProperties(&prop, dev) != cudaSuccess) continue; + sprintf(buff, "%d%d", prop.major, prop.minor); + archs.insert(buff); + } + } + if (archs.empty()) { + printf("NONE"); + } else { + bool first = true; + for(const auto& arch : archs) { + printf(first ? "%s" : ";%s", arch.c_str()); + first = false; + } + } + printf("\n"); +} diff --git a/cmake/filecheck_smoke_test b/cmake/filecheck_smoke_test new file mode 100644 index 000000000..aad1b0fd1 --- /dev/null +++ b/cmake/filecheck_smoke_test @@ -0,0 +1 @@ +SMOKE diff --git a/cmake/header_test.in b/cmake/header_test.in new file mode 100644 index 000000000..250dd5170 --- /dev/null +++ b/cmake/header_test.in @@ -0,0 +1,61 @@ +// This source file checks that: +// 1) Header compiles without error. +// 2) Common macro collisions with platform/system headers are avoided. + +// Turn off failures for certain configurations: +#define THRUST_CPP11_REQUIRED_NO_ERROR +#define THRUST_CPP14_REQUIRED_NO_ERROR +#define THRUST_MODERN_GCC_REQUIRED_NO_ERROR + +#ifndef THRUST_IGNORE_MACRO_CHECKS + +// Define THRUST_MACRO_CHECK(macro, header), which emits a diagnostic indicating +// a potential macro collision and halts. +// +// Hacky way to build a string, but it works on all tested platforms. +#define THRUST_MACRO_CHECK(MACRO, HEADER) \ + THRUST_MACRO_CHECK_IMPL(Identifier MACRO should not be used from Thrust \ + headers due to conflicts with HEADER macros.) + +// Use raw platform checks instead of the THRUST_HOST_COMPILER macros since we +// don't want to #include any headers other than the one being tested. +// +// This is only implemented for MSVC/GCC/Clang. +#if defined(_MSC_VER) // MSVC + +// Fake up an error for MSVC +#define THRUST_MACRO_CHECK_IMPL(msg) \ + /* Print message that looks like an error: */ \ + __pragma(message(__FILE__ ":" THRUST_MACRO_CHECK_IMPL0(__LINE__) \ + ": error: " #msg)) \ + /* abort compilation due to static_assert or syntax error: */ \ + static_assert(false, #msg); +#define THRUST_MACRO_CHECK_IMPL0(x) THRUST_MACRO_CHECK_IMPL1(x) +#define THRUST_MACRO_CHECK_IMPL1(x) #x + +#elif defined(__clang__) || defined(__GNUC__) + +// GCC/clang are easy: +#define THRUST_MACRO_CHECK_IMPL(msg) THRUST_MACRO_CHECK_IMPL0(GCC error #msg) +#define THRUST_MACRO_CHECK_IMPL0(expr) _Pragma(#expr) + +#endif + +// complex.h conflicts +#define I THRUST_MACRO_CHECK('I', complex.h) + +// windows.h conflicts +#define small THRUST_MACRO_CHECK('small', windows.h) +// We can't enable these checks without breaking some builds -- some standard +// library implementations unconditionally `#undef` these macros, which then +// causes random failures later. +// Leaving these commented out as a warning: Here be dragons. +//#define min(...) THRUST_MACRO_CHECK('min', windows.h) +//#define max(...) THRUST_MACRO_CHECK('max', windows.h) + +// termios.h conflicts (NVIDIA/thrust#1547) +#define B0 THRUST_MACRO_CHECK("B0", termios.h) + +#endif // THRUST_IGNORE_MACRO_CHECKS + +#include diff --git a/cmake/wrap_source_file.cpp.in b/cmake/wrap_source_file.cpp.in new file mode 100644 index 000000000..3015238cc --- /dev/null +++ b/cmake/wrap_source_file.cpp.in @@ -0,0 +1 @@ +#include <${wrapped_source_file}> diff --git a/dependencies/cub b/dependencies/cub new file mode 160000 index 000000000..b2e8bccb8 --- /dev/null +++ b/dependencies/cub @@ -0,0 +1 @@ +Subproject commit b2e8bccb8c0cd15279974fe4b9b8d6fcd1842b57 diff --git a/dependencies/libcudacxx b/dependencies/libcudacxx new file mode 160000 index 000000000..55dd2c993 --- /dev/null +++ b/dependencies/libcudacxx @@ -0,0 +1 @@ +Subproject commit 55dd2c99346baa3a14949a0f7e9c41865e434eda diff --git a/doc/thrust.dox b/doc/thrust.dox deleted file mode 100644 index f1dc884f8..000000000 --- a/doc/thrust.dox +++ /dev/null @@ -1,1078 +0,0 @@ -# Doxyfile 1.3.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = thrust - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = targets/doc - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, -# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en -# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, -# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited -# members of a class in the documentation of that class as if those members were -# ordinary class members. Constructors, destructors and assignment operators of -# the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. It is allowed to use relative paths in the argument list. - -STRIP_FROM_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explict @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# reimplements. - -INHERIT_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = thrust examples - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp -# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = examples - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories -# that are symbolic links (a Unix filesystem feature) are excluded from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = */detail/* - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = examples - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. - -INPUT_FILTER = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output dir. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimised for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assigments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = NO - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = NO - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse the -# parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. Note that this -# option is superceded by the HAVE_DOT option below. This is only a fallback. It is -# recommended to install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similiar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found on the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes that -# lay further from the root node will be omitted. Note that setting this option to -# 1 or 2 may greatly reduce the computation time needed for large code bases. Also -# note that a graph may be further truncated if the graph's image dimensions are -# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). -# If 0 is used for the depth value (the default), the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/doc/thrust_logo.png b/doc/thrust_logo.png deleted file mode 100644 index 123794b6a..000000000 Binary files a/doc/thrust_logo.png and /dev/null differ diff --git a/doc/thrust_logo.svg b/doc/thrust_logo.svg deleted file mode 100644 index 4fd82acaf..000000000 --- a/doc/thrust_logo.svg +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - Thrust - - diff --git a/docs/doxybook/config.json b/docs/doxybook/config.json new file mode 100644 index 000000000..56b7a238b --- /dev/null +++ b/docs/doxybook/config.json @@ -0,0 +1,49 @@ +{ + "baseUrl": "{{ site.baseurl }}/api/", + "copyImages": true, + "fileExt": "md", + "filesFilter": [], + "folderClassesName": "classes", + "folderExamplesName": "examples", + "folderFilesName": "files", + "folderGroupsName": "groups", + "folderNamespacesName": "namespaces", + "folderRelatedPagesName": "pages", + "imagesFolder": "images", + "indexClassesName": "index_classes", + "indexClassesTitle": "Classes", + "indexExamplesName": "index_examples", + "indexExamplesTitle": "Examples", + "indexFilesName": "index_files", + "indexFilesTitle": "Files", + "indexGroupsName": "index_groups", + "indexGroupsTitle": "Groups", + "indexInFolders": false, + "indexNamespacesName": "index_namespaces", + "indexNamespacesTitle": "namespaces", + "indexRelatedPagesName": "index_pages", + "indexRelatedPagesTitle": "pages", + "linkLowercase": true, + "linkAndInlineCodeAsHTML": true, + "linkSuffix": ".html", + "mainPageInRoot": false, + "mainPageName": "indexpage", + "sort": false, + "templateIndexClasses": "index_classes", + "templateIndexExamples": "index_examples", + "templateIndexFiles": "index_files", + "templateIndexGroups": "index_groups", + "templateIndexNamespaces": "index_namespaces", + "templateIndexRelatedPages": "index_pages", + "templateKindClass": "kind_class", + "templateKindDir": "kind_file", + "templateKindExample": "kind_page", + "templateKindFile": "kind_file", + "templateKindGroup": "kind_nonclass", + "templateKindInterface": "kind_class", + "templateKindNamespace": "kind_nonclass", + "templateKindPage": "kind_page", + "templateKindStruct": "kind_class", + "templateKindUnion": "kind_class", + "useFolders": true +} diff --git a/docs/doxybook/templates/class_members.tmpl b/docs/doxybook/templates/class_members.tmpl new file mode 100644 index 000000000..cb5f65f38 --- /dev/null +++ b/docs/doxybook/templates/class_members.tmpl @@ -0,0 +1,210 @@ +{%- if exists("publicClasses") or exists("publicTypes") or exists("publicAttributes") or exists("publicFunctions") or exists("friends") -%} + {%- set has_public_members = true -%} +{%- endif -%} +{%- if exists("protectedClasses") or exists("protectedTypes") or exists("protectedAttributes") or exists("protectedFunctions") -%} + {%- set has_protected_members = true -%} +{%- endif -%} +{%- if exists("baseClasses") -%} + {%- for base in baseClasses -%} + {%- if existsIn(base, "publicClasses") or existsIn(base, "publicTypes") or existsIn(base, "publicAttributes") or existsIn(base, "publicFunctions") or existsIn(base, "friends") -%} + {%- set has_public_members = true -%} + {%- endif -%} + {%- if existsIn(base, "protectedClasses") or existsIn(base, "protectedTypes") or existsIn(base, "protectedAttributes") or existsIn(base, "protectedFunctions") -%} + {%- set has_protected_members = true -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} + +{%- if exists("includes") -%} + #include {{includes}}{{ noop() -}} +
+{%- endif -%} +{%- include "synopsis_template_parameters.tmpl" -%} +{%- include "synopsis_kind.tmpl" -%}{% include "name_qualified.tmpl" %} { +{%- set synopsis_indent_width = 2 -%} +{%- set names_qualified = false -%} +{%- if default(has_public_members, false) -%} + public:{{- noop() -}} +{%- endif -%} +{%- if exists("publicTypes") -%} + {%- for child in publicTypes -%} + {%- include "synopsis_type.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "publicTypes") -%} + {%- for child in base.publicTypes -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_type.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if exists("publicClasses") -%} + {%- for child in publicClasses -%} + {%- include "synopsis_class.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "publicClasses") -%} + {%- for child in base.publicClasses -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_class.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if exists("friends") -%} + {%- for child in friends -%} + {%- if child.type == "class" or child.type == "struct" -%} + {%- include "synopsis_friend_class.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "friends") -%} + {%- for child in base.friends -%} + {%- if child.type == "class" or child.type == "struct" -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_friend_class.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endif -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if exists("publicAttributes") -%} + {%- for child in publicAttributes -%} + {%- include "synopsis_variable.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "publicAttributes") -%} + {%- for child in base.publicAttributes -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_variable.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if exists("publicFunctions") -%} + {%- for child in publicFunctions -%} + {%- include "synopsis_function.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "publicFunctions") -%} + {%- for child in base.publicFunctions -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_function.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if exists("friends") -%} + {%- for child in friends -%} + {%- if child.type != "class" and child.type != "struct" -%} + {%- include "synopsis_friend_function.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "friends") -%} + {%- for child in base.friends -%} + {%- if child.type != "class" and child.type != "struct" -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_friend_function.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endif -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if default(has_public_members, false) -%} + {%- if default(has_protected_members, false) -%} +
+ {%- endif -%} +{%- endif -%} +{#- Reset leading line breaks for protected members -#}{{ noop() -}} +{%- set synopsis_needs_leading_line_break = false -%} +{%- if default(has_protected_members, false) -%} + protected:{{- noop() -}} +{%- endif -%} +{%- if exists("protectedTypes") -%} + {%- for child in protectedTypes -%} + {%- include "synopsis_type.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "protectedTypes") -%} + {%- for child in base.protectedTypes -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_type.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if exists("protectedClasses") -%} + {%- for child in protectedClasses -%} + {%- include "synopsis_class.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "protectedClasses") -%} + {%- for child in base.protectedClasses -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_class.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if exists("protectedAttributes") -%} + {%- for child in protectedAttributes -%} + {%- include "synopsis_variable.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "protectedAttributes") -%} + {%- for child in base.protectedAttributes -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_variable.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- if exists("protectedFunctions") -%} + {%- for child in protectedFunctions -%} + {%- include "synopsis_function.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("baseClasses") -%}{%- for base in baseClasses -%} + {%- if existsIn(base, "protectedFunctions") -%} + {%- for child in base.protectedFunctions -%} + {%- set synopsis_is_inherited = true -%} + {%- include "synopsis_function.tmpl" -%} + {%- set synopsis_is_inherited = false -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%}{%- endif -%} +{%- set synopsis_indent_width = 0 -%} +}; +
+ diff --git a/docs/doxybook/templates/class_members_details.tmpl b/docs/doxybook/templates/class_members_details.tmpl new file mode 100644 index 000000000..a77eec5ef --- /dev/null +++ b/docs/doxybook/templates/class_members_details.tmpl @@ -0,0 +1,49 @@ +{%- if exists("publicClasses") -%}## Member Classes + + {%- for child in publicClasses -%} + {% include "title_member.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("publicTypes") -%}## Member Types + + {%- for child in publicTypes -%} + {% include "title_member.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("publicAttributes") %}## Member Variables + + {%- for child in publicAttributes -%} + {% include "title_member.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("publicFunctions") %}## Member Functions + + {%- for child in publicFunctions -%} + {% include "title_member.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("protectedTypes") -%}## Protected Member Types + {%- for child in publicTypes -%} + {% include "title_member.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{% endif -%} +{%- if exists("protectedAttributes") -%}## Protected Member Variables + + {%- for child in protectedAttributes -%} + {% include "title_member.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("protectedFunctions") -%}## Protected Member Functions + + {%- for child in protectedFunctions -%} + {% include "title_member.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} + diff --git a/docs/doxybook/templates/details.tmpl b/docs/doxybook/templates/details.tmpl new file mode 100644 index 000000000..d72119abf --- /dev/null +++ b/docs/doxybook/templates/details.tmpl @@ -0,0 +1,206 @@ +{%- if exists("brief") -%}{{brief}} + +{% endif -%} +{%- if exists("details") -%}{{details}} + +{% endif -%} +{%- if exists("inbody") -%}{{inbody}} + +{% endif -%} +{%- if exists("tests") -%}**Test**: + {%- if length(tests) == 1 -%}{{first(tests)}} + {%- else -%} + {%- for item in tests -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("note") -%}**Note**: + {%- if length(note) == 1 -%}{{first(note)}} + {%- else -%} + {%- for item in note -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("remark") -%}**Remark**: + {%- if length(remark) == 1 -%}{{first(remark)}} + {%- else -%} + {%- for item in remark -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("attention") -%}**Attention**: + {%- if length(attention) == 1 -%}{{first(attention)}} + {%- else -%} + {%- for item in attention -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("bugs") -%}**Bug**: + {%- if length(bugs) == 1 -%}{{first(bugs)}} + {%- else -%} + {%- for item in bugs -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("warning") -%}**Warning**: + {%- if length(warning) == 1 -%}{{first(warning)}} + {%- else -%} + {%- for item in warning -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("todos") -%}**TODO**: + {%- if length(todos) == 1 -%}{{first(todos)}} + {%- else -%} + {%- for item in todos -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("templateParamsList") -%}**Template Parameters**: + {%- if length(templateParamsList) == 1 -%}**`{{get(first(templateParamsList), "name")}}`**: {{get(first(templateParamsList), "text")}} + {%- else -%} + {%- for param in templateParamsList -%}* **`{{param.name}}`** {{param.text}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("paramList") -%}**Function Parameters**: + {%- if length(paramList) == 1 -%}**`{{get(first(paramList), "name")}}`**: {{get(first(paramList), "text")}} + {%- else -%} + {%- for param in paramList -%}* **`{{param.name}}`** {{param.text}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("pre") -%}**Preconditions**: + {%- if length(pre) == 1 -%}{{first(pre)}} + {%- else -%} + {%- for item in pre -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("post") -%}**Postconditions**: + {%- if length(post) == 1 -%}{{first(post)}} + {%- else -%} + {%- for item in post -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("invariant") -%}**Invariant**: + {%- if length(invariant) == 1 -%}{{first(invariant)}} + {%- else -%} + {%- for item in invariant -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("returns") or exists("returnsList") -%}**Returns**: + {%- if exists("returns") and exists("returnsList") -%} + {%- for item in returns -%}* {{item}} + {%- endfor -%} + {%- for item in returnsList -%}* **`{{item.name}}`**: {{item.text}} + {%- endfor -%} + {%- else if exists("returns") -%} + {%- if length(returns) == 1 -%}{{first(returns)}} + {%- else -%} + {%- for item in returns -%}* {{item}} + {%- endfor -%} + {%- endif -%} + {%- else if exists("returnsList") -%} + {%- if length(returnsList) == 1 -%}**`{{get(first(returnsList), "name")}}`** {{get(first(returnsList), "text")}} + {%- else -%} + {%- for item in returnsList -%}* **`{{item.name}}`**: {{item.text}} + {%- endfor -%} + {%- endif -%} + {%- endif %} +{% endif -%} +{%- if exists("exceptionsList") -%}**Exceptions**: + {%- if length(exceptionsList) == 1 -%}**`{{get(first(exceptionsList), "name")}}`**: {{get(first(exceptionsList), "text")}} + {%- else -%} + {%- for param in exceptionsList -%}* **`{{param.name}}`**: {{param.text}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("deprecated") -%}**Deprecated**: {{deprecated}} + +{% endif -%} +{%- if exists("authors") -%}**Author**: + {%- if length(authors) == 1 -%}{{first(authors)}} + {%- else -%} + {%- for item in authors -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("copyright") -%}**Copyright**: + {%- if length(copyright) == 1 -%}{{first(copyright)}} + {%- else -%} + {%- for item in copyright -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("version") -%}**Version**: + {%- if length(version) == 1 -%}{{first(version)}} + {%- else -%} + {%- for item in version -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("since") -%}**Since**: + {%- if length(since) == 1 -%}{{first(since)}} + {%- else -%} + {%- for item in since -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("date") -%}**Date**: + {%- if length(date) == 1 -%}{{first(date)}} + {%- else -%} + {%- for item in date -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("baseClasses") -%}**Inherits From**: + {%- if length(baseClasses) == 1 -%} + {%- if existsIn(first(baseClasses), "url") -%}[`{{get(first(baseClasses), "name")}}`]({{get(first(baseClasses), "url")}}) + {%- else -%}`{{get(first(baseClasses), "name")}}` + {%- endif -%} + {%- else -%} + {%- for base in baseClasses -%} + {%- if existsIn(baseClasses, "url") -%}* [`{{base.name}}`]({{base.url}}) + {%- else -%}* `{{base.name}}` + {%- endif -%} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("derivedClasses") -%}**Inherited By**: + {%- if length(derivedClasses) == 1 -%} + {%- if existsIn(first(derivedClasses), "url") -%}[`{{get(first(derivedClasses), "name")}}`]({{get(first(derivedClasses), "url")}}) + {%- else -%}`{{get(first(derivedClasses), "name")}}` + {%- endif -%} + {%- else -%} + {%- for derived in derivedClasses -%} + {%- if existsIn(first(derivedClasses), "url") -%}* [`{{derived.name}}`]({{derived.url}}) + {%- else -%}* `{{derived.name}}`{%- endif -%} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("reimplements") -%}**Implements**: [`{{reimplements.name}}`]({{reimplements.url}}) + +{% endif -%} +{%- if exists("reimplementedBy") -%}**Implemented By**: + {%- if length(reimplementedBy) == 1 -%} + {%- if existsIn(first(reimplementedBy), "url") -%}[`{{get(first(reimplementedBy), "name")}}`]({{get(first(reimplementedBy), "url")}}) + {%- else -%}`{{get(first(reimplementedBy), "name")}}` + {%- endif -%} + {%- else -%} + {%- for impl in reimplementedBy -%} + {%- if existsIn(first(reimplementedBy), "url") -%}* [`{{impl.name}}`]({{impl.url}}) + {%- else -%}* `{{impl.name}}` + {%- endif -%} + {%- endfor -%} + {%- endif %} +{% endif -%} +{%- if exists("see") -%}**See**: + {%- if length(see) == 1 -%}{{first(see)}} + {%- else -%} + {%- for item in see -%}* {{item}} + {%- endfor -%} + {%- endif %} +{% endif -%} diff --git a/docs/doxybook/templates/frontmatter.tmpl b/docs/doxybook/templates/frontmatter.tmpl new file mode 100644 index 000000000..d3b1e5b4f --- /dev/null +++ b/docs/doxybook/templates/frontmatter.tmpl @@ -0,0 +1,43 @@ +--- +{%- if exists("title") -%} + title: {{title}} +{%- else if exists("name") -%} + title: {{name}} +{%- endif -%} +{%- if exists("summary") -%} + summary: {{summary}} +{%- endif -%} +{%- if exists("moduleBreadcrumbs") -%} + {%- if length(moduleBreadcrumbs) > 0 -%} + parent: {{ get(last(moduleBreadcrumbs), "title") }} + {%- endif -%} + {%- if length(moduleBreadcrumbs) > 1 -%} + grand_parent: {{ get(index(moduleBreadcrumbs, -2), "title") }} + {%- else if length(moduleBreadcrumbs == 1) and exists("kind") and kind == "group" -%} + grand_parent: API + {%- endif -%} +{%- else if exists("kind") and kind == "group" -%} + parent: API +{%- endif -%} +{%- if exists("kind") and kind == "group" -%} + nav_exclude: false +{%- else -%} + nav_exclude: true +{%- endif -%} +has_children: true +has_toc: false +--- + +{%- if exists("title") -%} + {%- if exists("kind") and kind in ["class", "struct", "namespace"] -%} + # {{title(kind)}} `{{title}}` + {%- else -%} + # {{title}} + {%- endif -%} +{%- else if exists("name") -%} + {%- if exists("kind") and kind != "page" -%} + # {{name}} {{title(kind)}} Reference + {%- else -%} + # {{name}} + {%- endif -%} +{%- endif %} diff --git a/docs/doxybook/templates/index.tmpl b/docs/doxybook/templates/index.tmpl new file mode 100644 index 000000000..e28f37729 --- /dev/null +++ b/docs/doxybook/templates/index.tmpl @@ -0,0 +1,14 @@ +{%- if exists("children") -%}{%- for child in children -%} + {%- for i in range(default(index_depth, 0)) -%} + {{- noop() }} {{ noop() -}} + {%- endfor -%} + * {{ noop() -}} + {{ render("name_qualified.tmpl", child) }}{{ noop() -}} + {%- if existsIn(child, "brief") -%} + {{- noop() }}
{{ child.brief -}} + {%- endif %} + {%- if existsIn(child, "children") -%} + {%- set child.index_depth = default(index_depth, 0) + 1 -%} + {{- render("index.tmpl", child) -}} + {%- endif -%} +{%- endfor -%}{%- endif -%} diff --git a/docs/doxybook/templates/index_classes.tmpl b/docs/doxybook/templates/index_classes.tmpl new file mode 100644 index 000000000..1ccdf71e9 --- /dev/null +++ b/docs/doxybook/templates/index_classes.tmpl @@ -0,0 +1,2 @@ +{% include "frontmatter.tmpl" -%} +{% include "index.tmpl" -%} diff --git a/docs/doxybook/templates/index_examples.tmpl b/docs/doxybook/templates/index_examples.tmpl new file mode 100644 index 000000000..1ccdf71e9 --- /dev/null +++ b/docs/doxybook/templates/index_examples.tmpl @@ -0,0 +1,2 @@ +{% include "frontmatter.tmpl" -%} +{% include "index.tmpl" -%} diff --git a/docs/doxybook/templates/index_files.tmpl b/docs/doxybook/templates/index_files.tmpl new file mode 100644 index 000000000..1ccdf71e9 --- /dev/null +++ b/docs/doxybook/templates/index_files.tmpl @@ -0,0 +1,2 @@ +{% include "frontmatter.tmpl" -%} +{% include "index.tmpl" -%} diff --git a/docs/doxybook/templates/index_groups.tmpl b/docs/doxybook/templates/index_groups.tmpl new file mode 100644 index 000000000..1ccdf71e9 --- /dev/null +++ b/docs/doxybook/templates/index_groups.tmpl @@ -0,0 +1,2 @@ +{% include "frontmatter.tmpl" -%} +{% include "index.tmpl" -%} diff --git a/docs/doxybook/templates/index_namespaces.tmpl b/docs/doxybook/templates/index_namespaces.tmpl new file mode 100644 index 000000000..1ccdf71e9 --- /dev/null +++ b/docs/doxybook/templates/index_namespaces.tmpl @@ -0,0 +1,2 @@ +{% include "frontmatter.tmpl" -%} +{% include "index.tmpl" -%} diff --git a/docs/doxybook/templates/index_pages.tmpl b/docs/doxybook/templates/index_pages.tmpl new file mode 100644 index 000000000..1ccdf71e9 --- /dev/null +++ b/docs/doxybook/templates/index_pages.tmpl @@ -0,0 +1,2 @@ +{% include "frontmatter.tmpl" -%} +{% include "index.tmpl" -%} diff --git a/docs/doxybook/templates/kind_class.tmpl b/docs/doxybook/templates/kind_class.tmpl new file mode 100644 index 000000000..e5650b69b --- /dev/null +++ b/docs/doxybook/templates/kind_class.tmpl @@ -0,0 +1,4 @@ +{% include "frontmatter.tmpl" -%} +{%- if hasDetails -%}{% include "details.tmpl" -%}{%- endif -%} +{% include "class_members.tmpl" -%} +{% include "class_members_details.tmpl" -%} diff --git a/docs/doxybook/templates/kind_example.tmpl b/docs/doxybook/templates/kind_example.tmpl new file mode 100644 index 000000000..48501318b --- /dev/null +++ b/docs/doxybook/templates/kind_example.tmpl @@ -0,0 +1,2 @@ +{% include "frontmatter.tmpl" -%} +{%- if exists("details") -%}{{details}}{%- endif -%} diff --git a/docs/doxybook/templates/kind_file.tmpl b/docs/doxybook/templates/kind_file.tmpl new file mode 100644 index 000000000..c883442f1 --- /dev/null +++ b/docs/doxybook/templates/kind_file.tmpl @@ -0,0 +1,10 @@ +{% include "frontmatter.tmpl" -%} +{%- if hasDetails -%}{% include "details.tmpl" -%}{%- endif -%} +{% include "nonclass_members_details.tmpl" -%} +{% include "nonclass_members.tmpl" -%} +{%- if exists("programlisting") -%} + +```cpp +{{programlisting}} +``` +{%- endif -%} diff --git a/docs/doxybook/templates/kind_group.tmpl b/docs/doxybook/templates/kind_group.tmpl new file mode 100644 index 000000000..1ff7342a4 --- /dev/null +++ b/docs/doxybook/templates/kind_group.tmpl @@ -0,0 +1,4 @@ +{% include "frontmatter.tmpl" -%} +{%- if hasDetails %}{% include "details.tmpl" -%}{%- endif -%} +{% include "nonclass_members.tmpl" -%} +{% include "nonclass_members_details.tmpl" -%} diff --git a/docs/doxybook/templates/kind_nonclass.tmpl b/docs/doxybook/templates/kind_nonclass.tmpl new file mode 100644 index 000000000..299208c41 --- /dev/null +++ b/docs/doxybook/templates/kind_nonclass.tmpl @@ -0,0 +1,8 @@ +{% include "frontmatter.tmpl" -%} +{%- if hasDetails %}{% include "details.tmpl" -%}{%- endif -%} +{% if kind == "namespace" -%} + {%- include "namespace_members.tmpl" -%} +{%- else -%} + {%- include "nonclass_members.tmpl" -%} +{%- endif -%} +{% include "nonclass_members_details.tmpl" -%} diff --git a/docs/doxybook/templates/kind_page.tmpl b/docs/doxybook/templates/kind_page.tmpl new file mode 100644 index 000000000..48501318b --- /dev/null +++ b/docs/doxybook/templates/kind_page.tmpl @@ -0,0 +1,2 @@ +{% include "frontmatter.tmpl" -%} +{%- if exists("details") -%}{{details}}{%- endif -%} diff --git a/docs/doxybook/templates/member_details.tmpl b/docs/doxybook/templates/member_details.tmpl new file mode 100644 index 000000000..14b34dcfc --- /dev/null +++ b/docs/doxybook/templates/member_details.tmpl @@ -0,0 +1,39 @@ +{%- if exists("type") and type in ["class", "struct"] -%} + + {%- include "synopsis_class.tmpl" -%} + +{%- else if kind == "enum" -%} + {%- include "table_header_enum.tmpl" -%} + {%- for enumerator in enumvalues -%}{{- render("table_row_enum.tmpl", enumerator) -}} + {%- endfor %} +{%- else if kind in ["typedef", "using"] -%} + + {%- include "synopsis_template_parameters.tmpl" -%} + {%- include "synopsis_kind.tmpl" -%}{{name}}{%- include "synopsis_initializer.tmpl" -%};{{- noop() -}} + +{%- else if kind in ["variable", "property"] -%} + + {%- include "synopsis_template_parameters.tmpl" -%} + {%- include "synopsis_type_and_leading_specifiers.tmpl" -%}{{name}}{%- include "synopsis_initializer.tmpl" -%};{{- noop() -}} + +{%- else if kind in ["function", "slot", "signal", "event"] -%} + + {%- include "synopsis_template_parameters.tmpl" -%} + {% include "synopsis_function_type_and_leading_specifiers.tmpl" -%} + {{name}}({%- include "synopsis_function_parameters.tmpl" -%}){%- include "synopsis_function_trailing_specifiers.tmpl" -%};{{- noop() -}} + +{%- else if kind == "friend" -%} + {%- if type != "class" and type != "struct" -%} + + {% include "synopsis_template_parameters.tmpl" -%} + {% include "synopsis_function_type_and_leading_specifiers.tmpl" -%} + {{name}}({%- include "synopsis_function_parameters.tmpl" -%}){%- include "synopsis_function_trailing_specifiers.tmpl" -%};{{- noop() -}} + + {%- endif -%} +{%- else if kind == "define" -%} + {#- We have no way to get the parameters to function-like -#}{{ noop() -}} + {#- macros, and the macro definitions in `initializer` fields -#}{{ noop() -}} + {#- don't have line breaks. So we can't render a useful -#}{{ noop() -}} + {#- synopsis. -#}{{ noop() -}} +{% endif -%} +{% include "details.tmpl" -%} diff --git a/docs/doxybook/templates/name.tmpl b/docs/doxybook/templates/name.tmpl new file mode 100644 index 000000000..09f15420e --- /dev/null +++ b/docs/doxybook/templates/name.tmpl @@ -0,0 +1,5 @@ +{%- if default(names_qualified, true) -%} + {{- render("name_qualified.tmpl", child) -}} +{%- else -%} + {{- render("name_unqualified.tmpl", child) -}} +{%- endif -%} diff --git a/docs/doxybook/templates/name_qualified.tmpl b/docs/doxybook/templates/name_qualified.tmpl new file mode 100644 index 000000000..da088dd34 --- /dev/null +++ b/docs/doxybook/templates/name_qualified.tmpl @@ -0,0 +1,7 @@ +{%- if exists("qualifiedname") -%} + {{- escape(qualifiedname) -}} +{%- else if exists("name") -%} + {{- escape(name) -}} +{%- else -%} + {{- escape(title) -}} +{%- endif -%} diff --git a/docs/doxybook/templates/name_unqualified.tmpl b/docs/doxybook/templates/name_unqualified.tmpl new file mode 100644 index 000000000..2a0d73725 --- /dev/null +++ b/docs/doxybook/templates/name_unqualified.tmpl @@ -0,0 +1,5 @@ +{%- if exists("name") -%} + {{- escape(stripNamespace(name)) -}} +{%- else -%} + {{- escape(stripNamespace(title)) -}} +{%- endif -%} diff --git a/docs/doxybook/templates/namespace_members.tmpl b/docs/doxybook/templates/namespace_members.tmpl new file mode 100644 index 000000000..8bb4bdffc --- /dev/null +++ b/docs/doxybook/templates/namespace_members.tmpl @@ -0,0 +1,43 @@ + +{%- if exists("includes") -%} + #include {{includes}}{{ noop() -}} +
+{%- endif -%} +{%- include "synopsis_kind.tmpl" -%}{% include "name_qualified.tmpl" %} { +{%- set synopsis_needs_leading_line_break = true -%} +{%- set names_qualified = false -%} +{%- if exists("namespaces") -%} + {%- for child in namespaces -%} + {%- include "synopsis_namespace_abbreviated.tmpl" -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("publicClasses") -%} + {%- for child in publicClasses -%} + {%- include "synopsis_class.tmpl" -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("publicTypes") -%} + {%- for child in publicTypes -%} + {%- include "synopsis_type.tmpl" -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("publicAttributes") -%} + {%- for child in publicAttributes -%} + {%- include "synopsis_variable.tmpl" -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("publicFunctions") -%} + {%- for child in publicFunctions -%} + {%- if existsIn(child, "type") -%} + {#- If the child doesn't have a type, it's probably a -#}{{- noop() -}} + {#- constructor that Doxygen put into a non-class entity -#}{{- noop() -}} + {#- due to a bug whose nature is beyond me. -#}{{- noop() -}} + {%- include "synopsis_function.tmpl" -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +} {{ noop() -}} + /* {%- include "synopsis_kind.tmpl" -%}{% include "name_qualified.tmpl" %} */{{ noop() -}} + +
+ diff --git a/docs/doxybook/templates/nonclass_members.tmpl b/docs/doxybook/templates/nonclass_members.tmpl new file mode 100644 index 000000000..af3d39c17 --- /dev/null +++ b/docs/doxybook/templates/nonclass_members.tmpl @@ -0,0 +1,60 @@ +{%- if exists("groups") %}## Groups + + {%- for child in sort(groups) -%}* **[{{ child.title }}]({{ child.url }})**{% if existsIn(child, "brief") %}: {{ child.brief }}{% endif %} + {%- endfor %} +{% endif -%} +{%- if exists("dirs") %}## Directories + + {%- for child in dirs -%}* **[`{{ child.name }}`]({{ child.url }})**{% if existsIn(child, "brief") %}: {{ child.brief }}{% endif %} + {%- endfor %} +{% endif -%} +{%- if exists("files") %}## Files + + {%- include "table_header_brief.tmpl" -%} + {%- for child in files -%}{{- render("table_row_brief.tmpl", child) -}} + {%- endfor %} +{% endif -%} + +{%- if exists("namespaces") -%} + {%- for child in namespaces -%} + {%- include "synopsis_namespace_abbreviated.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("publicClasses") -%} + {%- for child in publicClasses -%} + {%- include "synopsis_class.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("publicTypes") -%} + {%- for child in publicTypes -%} + {%- include "synopsis_type.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("publicAttributes") -%} + {%- for child in publicAttributes -%} + {%- include "synopsis_variable.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("publicFunctions") -%} + {%- for child in publicFunctions -%} + {%- if existsIn(child, "type") -%} + {#- If the child doesn't have a type, it's probably a -#}{{- noop() -}} + {#- constructor that Doxygen put into a non-class entity -#}{{- noop() -}} + {#- due to a bug whose nature is beyond me. -#}{{- noop() -}} + {%- include "synopsis_function.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +{%- if exists("defines") -%} + {%- for child in defines -%} + {%- include "synopsis_macro.tmpl" -%} + {%- set synopsis_needs_leading_line_break = true -%} + {%- endfor -%} +{%- endif -%} + + diff --git a/docs/doxybook/templates/nonclass_members_details.tmpl b/docs/doxybook/templates/nonclass_members_details.tmpl new file mode 100644 index 000000000..c941f22f7 --- /dev/null +++ b/docs/doxybook/templates/nonclass_members_details.tmpl @@ -0,0 +1,35 @@ +{%- if exists("publicClasses") -%}## Member Classes + + {%- for child in publicClasses -%} + {% include "title_nonmember.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("publicTypes") -%}## Types + + {%- for child in publicTypes -%} + {% include "title_nonmember.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("publicAttributes") %}## Variables + + {%- for child in publicAttributes -%} + {% include "title_nonmember.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("publicFunctions") %}## Functions + + {%- for child in publicFunctions -%} + {% include "title_nonmember.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} +{%- if exists("defines") %}## Macros + + {%- for child in defines -%} + {% include "title_nonmember.tmpl" %} + {{- render("member_details.tmpl", child) -}} + {%- endfor %} +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_brief.tmpl b/docs/doxybook/templates/synopsis_brief.tmpl new file mode 100644 index 000000000..2f48cec1d --- /dev/null +++ b/docs/doxybook/templates/synopsis_brief.tmpl @@ -0,0 +1,8 @@ +{%- if exists("brief") -%} + {{ noop() -}} + {%- if default(synopsis_indent_width, 0) != 0 -%} + {%- include "synopsis_indent.tmpl" -%} + {%- endif -%} + /* {{ brief }} */{{ noop() -}} + {{ noop() -}} +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_class.tmpl b/docs/doxybook/templates/synopsis_class.tmpl new file mode 100644 index 000000000..a5492997c --- /dev/null +++ b/docs/doxybook/templates/synopsis_class.tmpl @@ -0,0 +1,16 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- include "synopsis_inherited_from.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_brief.tmpl", child) -}} +{#- The Doxygen metadata that a parent has on its nested -#}{{ noop() -}} +{#- classes doesn't include their template parameters. -#}{{ noop() -}} +{#- Fortunately, we have the refid of the nested class, so -#}{{ noop() -}} +{#- so we can just load the data from their page. -#}{{ noop() -}} +{%- set child_class = load(child.refid)) -%} +{%- set child_class.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_template_parameters.tmpl", child_class) -}} +{{ noop() -}} + {%- include "synopsis_indent.tmpl" -%} + {{- render("synopsis_kind_abbreviated.tmpl", child) -}} + {% include "name.tmpl" %};{{ noop() -}} + diff --git a/docs/doxybook/templates/synopsis_friend_class.tmpl b/docs/doxybook/templates/synopsis_friend_class.tmpl new file mode 100644 index 000000000..39f23bb09 --- /dev/null +++ b/docs/doxybook/templates/synopsis_friend_class.tmpl @@ -0,0 +1,14 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- include "synopsis_inherited_from.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_brief.tmpl", child) -}} +{{- render("synopsis_template_parameters.tmpl", child) -}} +{#- Unfortunately, the refid and URL for a friend class -#}{{ noop() -}} +{#- incorrectly refers to a definition on the local -#}{{ noop() -}} +{#- page, instead of the friend class's own page. -#}{{ noop() -}} +{#- So we don't link to friend classes. -#}{{ noop() -}} +{{ noop() -}} + {%- include "synopsis_indent.tmpl" -%} + {{- render("synopsis_kind_abbreviated.tmpl", child) -}} + {{- render("name_qualified.tmpl", child) -}};{{ noop() -}} + diff --git a/docs/doxybook/templates/synopsis_friend_function.tmpl b/docs/doxybook/templates/synopsis_friend_function.tmpl new file mode 100644 index 000000000..440989c23 --- /dev/null +++ b/docs/doxybook/templates/synopsis_friend_function.tmpl @@ -0,0 +1,19 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- include "synopsis_inherited_from.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_brief.tmpl", child) -}} +{{- render("synopsis_template_parameters.tmpl", child) -}} +{#- Unfortunately, the refid and URL for a friend class -#}{{ noop() -}} +{#- incorrectly refers to a definition on the local -#}{{ noop() -}} +{#- page, instead of the friend class's own page. -#}{{ noop() -}} +{#- So we don't link to friend classes. -#}{{ noop() -}} +{{ noop() -}} + {%- include "synopsis_indent.tmpl" -%} + friend {{- render("synopsis_type_and_leading_specifiers.tmpl", child) -}} + +{{ noop() -}} + {%- include "synopsis_indent.tmpl" -%} + {{- render("name_qualified.tmpl", child) -}}{{ noop() -}} + ({{- render("synopsis_function_parameters.tmpl", child) -}}){{ noop() -}} + {{- render("synopsis_function_trailing_specifiers.tmpl", child) -}};{{ noop() -}} + diff --git a/docs/doxybook/templates/synopsis_function.tmpl b/docs/doxybook/templates/synopsis_function.tmpl new file mode 100644 index 000000000..93a3e822e --- /dev/null +++ b/docs/doxybook/templates/synopsis_function.tmpl @@ -0,0 +1,12 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- include "synopsis_inherited_from.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_brief.tmpl", child) -}} +{{- render("synopsis_template_parameters.tmpl", child) -}} +{{- render("synopsis_function_type_and_leading_specifiers.tmpl", child) -}} +{{ noop() -}} + {%- include "synopsis_indent.tmpl" -%} + {% include "name.tmpl" %}{{ noop() -}} + ({{- render("synopsis_function_parameters.tmpl", child) -}}){{ noop() -}} + {{- render("synopsis_function_trailing_specifiers.tmpl", child) -}};{{- noop() -}} + diff --git a/docs/doxybook/templates/synopsis_function_parameters.tmpl b/docs/doxybook/templates/synopsis_function_parameters.tmpl new file mode 100644 index 000000000..204a52c50 --- /dev/null +++ b/docs/doxybook/templates/synopsis_function_parameters.tmpl @@ -0,0 +1,11 @@ +{%- for param in params -%} + {%- if not loop.is_first -%}  {%- endif -%} + {{- param.type -}} + {%- if not isEmpty(param.name) %} {% endif -%} + {{- param.name -}} + {%- if existsIn(param, "defvalPlain") %} = {{ escape(param.defvalPlain) }}{% endif -%} + {%- if not loop.is_last -%} + , + {{- noop() }}{% include "synopsis_indent.tmpl" -%} + {%- endif -%} +{%- endfor -%} diff --git a/docs/doxybook/templates/synopsis_function_trailing_specifiers.tmpl b/docs/doxybook/templates/synopsis_function_trailing_specifiers.tmpl new file mode 100644 index 000000000..bbde0f1dd --- /dev/null +++ b/docs/doxybook/templates/synopsis_function_trailing_specifiers.tmpl @@ -0,0 +1,5 @@ +{%- if const %} const{% endif -%} +{%- if override %} override{% endif -%} +{%- if default %} = default{% endif -%} +{%- if deleted %} = deleted{% endif -%} +{%- if pureVirtual %} = 0{% endif -%} diff --git a/docs/doxybook/templates/synopsis_function_type_and_leading_specifiers.tmpl b/docs/doxybook/templates/synopsis_function_type_and_leading_specifiers.tmpl new file mode 100644 index 000000000..5cde64d28 --- /dev/null +++ b/docs/doxybook/templates/synopsis_function_type_and_leading_specifiers.tmpl @@ -0,0 +1,6 @@ +{%- if default(virtual, false) or default(static, false) or default(explicit, false) or default(type, false) -%} + {{ noop() -}} + {%- include "synopsis_indent.tmpl" -%} + {%- include "synopsis_type_and_leading_specifiers.tmpl" -%} + {{ noop() -}} +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_indent.tmpl b/docs/doxybook/templates/synopsis_indent.tmpl new file mode 100644 index 000000000..a2d7193a6 --- /dev/null +++ b/docs/doxybook/templates/synopsis_indent.tmpl @@ -0,0 +1,5 @@ +{%- if default(synopsis_indent_width, false) -%} + {%- for i in range(synopsis_indent_width) -%} +  {{ noop() -}} + {%- endfor -%} +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_inherited_from.tmpl b/docs/doxybook/templates/synopsis_inherited_from.tmpl new file mode 100644 index 000000000..fd88b649c --- /dev/null +++ b/docs/doxybook/templates/synopsis_inherited_from.tmpl @@ -0,0 +1,4 @@ +{%- if default(synopsis_is_inherited, false) != false -%} + {%- set base.synopsis_indent_width = default(synopsis_indent_width, 0) -%} + {{- render("synopsis_inherited_from_comment.tmpl", base) -}} +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_inherited_from_comment.tmpl b/docs/doxybook/templates/synopsis_inherited_from_comment.tmpl new file mode 100644 index 000000000..4afda1250 --- /dev/null +++ b/docs/doxybook/templates/synopsis_inherited_from_comment.tmpl @@ -0,0 +1,8 @@ +{{ noop() -}} + {%- if default(synopsis_indent_width, 0) != 0 -%} + {%- include "synopsis_indent.tmpl" -%} + {%- endif -%} + /* Inherited from {{ noop() -}} + {%- include "name_qualified.tmpl" -%}{{ noop() -}} + */{{ noop() -}} +{{ noop() -}} diff --git a/docs/doxybook/templates/synopsis_initializer.tmpl b/docs/doxybook/templates/synopsis_initializer.tmpl new file mode 100644 index 000000000..dd159979d --- /dev/null +++ b/docs/doxybook/templates/synopsis_initializer.tmpl @@ -0,0 +1,3 @@ +{%- if kind == "using" %} = {{ escape(type) -}} +{%- else if exists("initializer") %} {{ escape(initializer) -}} +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_initializer_abbreviated.tmpl b/docs/doxybook/templates/synopsis_initializer_abbreviated.tmpl new file mode 100644 index 000000000..2bc4d4856 --- /dev/null +++ b/docs/doxybook/templates/synopsis_initializer_abbreviated.tmpl @@ -0,0 +1 @@ +{% if kind == "using" or exists("initializer") %} = see below{% endif -%} diff --git a/docs/doxybook/templates/synopsis_kind.tmpl b/docs/doxybook/templates/synopsis_kind.tmpl new file mode 100644 index 000000000..34cd602a9 --- /dev/null +++ b/docs/doxybook/templates/synopsis_kind.tmpl @@ -0,0 +1,9 @@ +{%- if kind == "interface" %}class {{ noop() -}} +{%- else if kind == "namespace" %}namespace {{ noop() -}} +{%- else if kind == "typedef" %}typedef {{ type -}} +{%- else if kind == "enum" %}enum {% if strong %}class {% endif -%} {{ noop() -}} +{%- else if kind == "friend" %}friend {{ noop() -}} + {%- if type == "class" or type == "struct" %}{{ type }} {% endif -%} +{%- else if kind == "define" %}#define {{ noop() -}} +{%- else %}{{ kind }} {{ noop() -}} +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_kind_abbreviated.tmpl b/docs/doxybook/templates/synopsis_kind_abbreviated.tmpl new file mode 100644 index 000000000..881582773 --- /dev/null +++ b/docs/doxybook/templates/synopsis_kind_abbreviated.tmpl @@ -0,0 +1,9 @@ +{%- if kind == "interface" %}class {{ noop() -}} +{%- else if kind == "namespace" %}namespace {{ noop() -}} +{%- else if kind == "typedef" %}typedef see below {{ noop() -}} +{%- else if kind == "enum" %}enum {% if strong %}class {% endif -%} +{%- else if kind == "friend" %}friend {{ noop() -}} + {%- if type == "class" or type == "struct" %}{{type}} {% endif -%} +{%- else if kind == "define" %}#define {{ noop() -}} +{%- else %}{{ kind }} {{ noop() -}} +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_leading_line_break.tmpl b/docs/doxybook/templates/synopsis_leading_line_break.tmpl new file mode 100644 index 000000000..13a1574e3 --- /dev/null +++ b/docs/doxybook/templates/synopsis_leading_line_break.tmpl @@ -0,0 +1,3 @@ +{%- if default(synopsis_needs_leading_line_break, false) -%} +
+{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_macro.tmpl b/docs/doxybook/templates/synopsis_macro.tmpl new file mode 100644 index 000000000..612773439 --- /dev/null +++ b/docs/doxybook/templates/synopsis_macro.tmpl @@ -0,0 +1,7 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{ noop() -}} + {{- render("synopsis_kind.tmpl", child) -}} + {{- render("name_qualified.tmpl", child) -}}{{ noop() -}} + {{- render("synopsis_initializer_abbreviated.tmpl", child) -}};{{ noop() -}} + diff --git a/docs/doxybook/templates/synopsis_member_namespace_abbreviated.tmpl b/docs/doxybook/templates/synopsis_member_namespace_abbreviated.tmpl new file mode 100644 index 000000000..682f615c9 --- /dev/null +++ b/docs/doxybook/templates/synopsis_member_namespace_abbreviated.tmpl @@ -0,0 +1,7 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_brief.tmpl", child) -}} +{{ noop() -}} + {{- render("synopsis_kind_abbreviated.tmpl", child) -}} + {{- render("name_qualified.tmpl", child) -}} { }{{ noop() -}} + diff --git a/docs/doxybook/templates/synopsis_namespace_abbreviated.tmpl b/docs/doxybook/templates/synopsis_namespace_abbreviated.tmpl new file mode 100644 index 000000000..682f615c9 --- /dev/null +++ b/docs/doxybook/templates/synopsis_namespace_abbreviated.tmpl @@ -0,0 +1,7 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_brief.tmpl", child) -}} +{{ noop() -}} + {{- render("synopsis_kind_abbreviated.tmpl", child) -}} + {{- render("name_qualified.tmpl", child) -}} { }{{ noop() -}} + diff --git a/docs/doxybook/templates/synopsis_template_parameters.tmpl b/docs/doxybook/templates/synopsis_template_parameters.tmpl new file mode 100644 index 000000000..4391c3d99 --- /dev/null +++ b/docs/doxybook/templates/synopsis_template_parameters.tmpl @@ -0,0 +1,14 @@ +{%- if exists("templateParams") -%} + {% include "synopsis_indent.tmpl" -%}template <{{ noop() -}} + {%- for param in templateParams -%} + {%- if not loop.is_first %}{% include "synopsis_indent.tmpl" -%}  {% endif -%} + {{- param.type -}} + {%- if not isEmpty(param.name) %} {% endif -%} + {{- param.name -}} + {%- if existsIn(param, "defvalPlain") %} = {{ escape(param.defvalPlain) }}{% endif -%} + {%- if not loop.is_last -%} + , + {{- noop() }}{% include "synopsis_indent.tmpl" -%} + {%- endif -%} + {%- endfor -%}> +{%- endif -%} diff --git a/docs/doxybook/templates/synopsis_type.tmpl b/docs/doxybook/templates/synopsis_type.tmpl new file mode 100644 index 000000000..586555f08 --- /dev/null +++ b/docs/doxybook/templates/synopsis_type.tmpl @@ -0,0 +1,11 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- include "synopsis_inherited_from.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_brief.tmpl", child) -}} +{{- render("synopsis_template_parameters.tmpl", child) -}} +{{ noop() -}} + {%- include "synopsis_indent.tmpl" -%} + {{- render("synopsis_kind_abbreviated.tmpl", child) -}} + {% include "name.tmpl" %}{{ noop() -}} + {{- render("synopsis_initializer_abbreviated.tmpl", child) -}};{{ noop() -}} + diff --git a/docs/doxybook/templates/synopsis_type_and_leading_specifiers.tmpl b/docs/doxybook/templates/synopsis_type_and_leading_specifiers.tmpl new file mode 100644 index 000000000..12136020f --- /dev/null +++ b/docs/doxybook/templates/synopsis_type_and_leading_specifiers.tmpl @@ -0,0 +1,4 @@ +{%- if default(virtual, false) %}virtual {% endif -%} +{%- if default(static, false) %}static {% endif -%} +{%- if default(explicit, false) %}explicit {% endif -%} +{%- if exists("type") %}{{ type }} {% endif -%} diff --git a/docs/doxybook/templates/synopsis_variable.tmpl b/docs/doxybook/templates/synopsis_variable.tmpl new file mode 100644 index 000000000..52c48da50 --- /dev/null +++ b/docs/doxybook/templates/synopsis_variable.tmpl @@ -0,0 +1,11 @@ +{%- include "synopsis_leading_line_break.tmpl" -%} +{%- include "synopsis_inherited_from.tmpl" -%} +{%- set child.synopsis_indent_width = default(synopsis_indent_width, 0) -%} +{{- render("synopsis_brief.tmpl", child) -}} +{{- render("synopsis_template_parameters.tmpl", child) -}} +{{ noop() -}} + {%- include "synopsis_indent.tmpl" -%} + {{- render("synopsis_type_and_leading_specifiers.tmpl", child) -}} + {% include "name.tmpl" %}{{ noop() -}} + {{- render("synopsis_initializer_abbreviated.tmpl", child) -}};{{ noop() -}} + diff --git a/docs/doxybook/templates/table_header_brief.tmpl b/docs/doxybook/templates/table_header_brief.tmpl new file mode 100644 index 000000000..ed13f970f --- /dev/null +++ b/docs/doxybook/templates/table_header_brief.tmpl @@ -0,0 +1,2 @@ +| Name | Description | +|------|-------------| diff --git a/docs/doxybook/templates/table_header_enum.tmpl b/docs/doxybook/templates/table_header_enum.tmpl new file mode 100644 index 000000000..cdf95bc6f --- /dev/null +++ b/docs/doxybook/templates/table_header_enum.tmpl @@ -0,0 +1,2 @@ +| Enumerator | Value | Description | +|------------|-------|-------------| diff --git a/docs/doxybook/templates/table_row_brief.tmpl b/docs/doxybook/templates/table_row_brief.tmpl new file mode 100644 index 000000000..1d599755f --- /dev/null +++ b/docs/doxybook/templates/table_row_brief.tmpl @@ -0,0 +1 @@ +| **[`{{name}}`]({{url}})** | {% if exists("brief") %}{{brief}}{% endif %} | diff --git a/docs/doxybook/templates/table_row_enum.tmpl b/docs/doxybook/templates/table_row_enum.tmpl new file mode 100644 index 000000000..77c205be3 --- /dev/null +++ b/docs/doxybook/templates/table_row_enum.tmpl @@ -0,0 +1 @@ +| `{{ name }}` | {% if exists("initializer") -%}`{{ escape(replace(initializer, "= ", "")) }}`{%- endif %} | {% if exists("brief") -%}{{ brief }}{%- endif %} | diff --git a/docs/doxybook/templates/title_kind.tmpl b/docs/doxybook/templates/title_kind.tmpl new file mode 100644 index 000000000..100db2e84 --- /dev/null +++ b/docs/doxybook/templates/title_kind.tmpl @@ -0,0 +1,4 @@ +{%- if child.kind == "using" %}Type Alias{{ noop() -}} +{%- else -%}{{ title(child.kind) -}} +{%- endif -%} +{%- if child.kind == "enum" and child.strong %} Class{%- endif -%} diff --git a/docs/doxybook/templates/title_leading.tmpl b/docs/doxybook/templates/title_leading.tmpl new file mode 100644 index 000000000..54eb7e967 --- /dev/null +++ b/docs/doxybook/templates/title_leading.tmpl @@ -0,0 +1,4 @@ +

+{%- if existsIn(child, "kind") and child.kind in ["class", "struct"] -%} + {{ noop() -}} +{%- endif -%} diff --git a/docs/doxybook/templates/title_member.tmpl b/docs/doxybook/templates/title_member.tmpl new file mode 100644 index 000000000..50e70f378 --- /dev/null +++ b/docs/doxybook/templates/title_member.tmpl @@ -0,0 +1,4 @@ +{%- include "title_leading.tmpl" -%} + {%- include "title_kind.tmpl" -%} + {{- noop() }} {% include "name_qualified.tmpl" %}::{{ render("name_unqualified.tmpl", child) }} +{%- include "title_trailing.tmpl" -%} diff --git a/docs/doxybook/templates/title_nonmember.tmpl b/docs/doxybook/templates/title_nonmember.tmpl new file mode 100644 index 000000000..4ea9797fd --- /dev/null +++ b/docs/doxybook/templates/title_nonmember.tmpl @@ -0,0 +1,5 @@ +{%- include "title_leading.tmpl" -%} + {%- include "title_kind.tmpl" -%} + {{- noop() }} {{render("name_qualified.tmpl", child)}} +{%- include "title_trailing.tmpl" -%} + diff --git a/docs/doxybook/templates/title_trailing.tmpl b/docs/doxybook/templates/title_trailing.tmpl new file mode 100644 index 000000000..fcc4f24e6 --- /dev/null +++ b/docs/doxybook/templates/title_trailing.tmpl @@ -0,0 +1,4 @@ +{%- if existsIn(child, "kind") and child.kind in ["class", "struct"] -%} + +{%- endif -%} +

diff --git a/docs/doxygen/config.dox b/docs/doxygen/config.dox new file mode 100644 index 000000000..7e06e3545 --- /dev/null +++ b/docs/doxygen/config.dox @@ -0,0 +1,2611 @@ +# Doxyfile 1.9.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = Thrust + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = . + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = YES + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = NO + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = YES + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = NO + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = thrust + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = *detail* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = examples + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = NO + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = build_docs/doxygen/html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7-latest/tex.html +# #tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /