Skip to content

Commit eb87e56

Browse files
authored
Implement P0843 inplace_vector (#1936)
* Implement P0843 `inplace_vector` This implements `inplace_vector` a resizable container with a fixed capacity that stores its elements in a local array. Due to the fact that everything is local we are more or less save regarding host device issues, as long as users do not pass around references of it. The exception guarantees are not 100% clear yet, so I implemented them on a best effort basis. We might need to revisit what we guarantee in case of an exception.
1 parent 7d4be26 commit eb87e56

File tree

21 files changed

+5500
-9
lines changed

21 files changed

+5500
-9
lines changed

docs/libcudacxx/standard_api/container_library.rst

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Container Library
88
:maxdepth: 1
99

1010
container_library/array
11+
container_library/inplace_vector
1112
container_library/mdspan
1213
container_library/span
1314

@@ -23,6 +24,9 @@ Any Standard C++ header not listed below is omitted.
2324
* - `\<cuda/std/array\> <https://en.cppreference.com/w/cpp/header/array>`_
2425
- Fixed size array
2526
- libcu++ 1.8.0 / CCCL 2.0.0 / CUDA 11.7
27+
* - `\<cuda/std/inplace_vector\> <https://en.cppreference.com/w/cpp/header/inplace_vector>`_
28+
- Flexible size container with fixed capacity
29+
- libcu++ 2.6.0 / CCCL 2.6.0
2630
* - `\<cuda/std/span\> <https://en.cppreference.com/w/cpp/header/span>`_
2731
- Non - owning view into a contiguous sequence of objects
2832
- libcu++ 2.1.0 / CCCL 2.1.0 / CUDA 12.2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.. _libcudacxx-standard-api-container-inplace-vector:
2+
3+
``<cuda/std/inplace_vector>``
4+
==============================
5+
6+
Extensions
7+
----------
8+
9+
- Most features of ``<inplace_vector>`` are made available in C++14 onwards
10+
11+
Restrictions
12+
------------
13+
14+
- The range based interface is only available with ranges support in C++17

libcudacxx/include/cuda/std/__memory/construct_at.h

+23-9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <cuda/std/__type_traits/is_array.h>
3232
#include <cuda/std/__type_traits/is_constant_evaluated.h>
3333
#include <cuda/std/__type_traits/is_trivially_constructible.h>
34+
#include <cuda/std/__type_traits/is_trivially_destructible.h>
3435
#include <cuda/std/__type_traits/is_trivially_move_assignable.h>
3536
#include <cuda/std/__type_traits/void_t.h>
3637
#include <cuda/std/__utility/declval.h>
@@ -181,26 +182,39 @@ __construct_at(_Tp* __location, _Args&&... __args)
181182
// The internal functions are available regardless of the language version (with the exception of the `__destroy_at`
182183
// taking an array).
183184
template <class _ForwardIterator>
184-
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX20 _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator);
185+
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX14 _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator);
185186

186-
template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
187-
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX20 void __destroy_at(_Tp* __loc)
187+
_CCCL_EXEC_CHECK_DISABLE
188+
template <class _Tp,
189+
__enable_if_t<!is_array<_Tp>::value, int> = 0,
190+
__enable_if_t<!is_trivially_destructible<_Tp>::value, int> = 0>
191+
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX14 void __destroy_at(_Tp* __loc)
188192
{
189193
_LIBCUDACXX_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
190194
__loc->~_Tp();
191195
}
192196

197+
_CCCL_EXEC_CHECK_DISABLE
198+
template <class _Tp,
199+
__enable_if_t<!is_array<_Tp>::value, int> = 0,
200+
__enable_if_t<is_trivially_destructible<_Tp>::value, int> = 0>
201+
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX14 void __destroy_at(_Tp* __loc)
202+
{
203+
_LIBCUDACXX_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
204+
(void) __loc;
205+
}
206+
193207
#if _CCCL_STD_VER >= 2020
194208
template <class _Tp, __enable_if_t<is_array<_Tp>::value, int> = 0>
195-
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX20 void __destroy_at(_Tp* __loc)
209+
_LIBCUDACXX_INLINE_VISIBILITY constexpr void __destroy_at(_Tp* __loc)
196210
{
197211
_LIBCUDACXX_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
198212
_CUDA_VSTD::__destroy(_CUDA_VSTD::begin(*__loc), _CUDA_VSTD::end(*__loc));
199213
}
200-
#endif
214+
#endif // _CCCL_STD_VER >= 2020
201215

202216
template <class _ForwardIterator>
203-
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX20 _ForwardIterator
217+
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX14 _ForwardIterator
204218
__destroy(_ForwardIterator __first, _ForwardIterator __last)
205219
{
206220
for (; __first != __last; ++__first)
@@ -211,7 +225,7 @@ __destroy(_ForwardIterator __first, _ForwardIterator __last)
211225
}
212226

213227
template <class _BidirectionalIterator>
214-
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX20 _BidirectionalIterator
228+
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX14 _BidirectionalIterator
215229
__reverse_destroy(_BidirectionalIterator __first, _BidirectionalIterator __last)
216230
{
217231
while (__last != __first)
@@ -222,7 +236,7 @@ __reverse_destroy(_BidirectionalIterator __first, _BidirectionalIterator __last)
222236
return __last;
223237
}
224238

225-
#if _CCCL_STD_VER > 2014
239+
#if _CCCL_STD_VER >= 2017
226240

227241
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
228242
_LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX20 void destroy_at(_Tp* __loc) noexcept
@@ -256,7 +270,7 @@ _LIBCUDACXX_INLINE_VISIBILITY _CCCL_CONSTEXPR_CXX20 _ForwardIterator destroy_n(_
256270
return __first;
257271
}
258272

259-
#endif // _CCCL_STD_VER > 2014
273+
#endif // _CCCL_STD_VER >= 2017
260274

261275
_LIBCUDACXX_END_NAMESPACE_STD
262276

libcudacxx/include/cuda/std/__ranges/concepts.h

+15
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#endif // no system header
2222

2323
#include <cuda/std/__concepts/constructible.h>
24+
#include <cuda/std/__concepts/convertible_to.h>
2425
#include <cuda/std/__concepts/movable.h>
2526
#include <cuda/std/__concepts/same_as.h>
2627
#include <cuda/std/__iterator/concepts.h>
@@ -288,6 +289,20 @@ _LIBCUDACXX_CONCEPT viewable_range = _LIBCUDACXX_FRAGMENT(__viewable_range_, _Tp
288289

289290
# endif // _CCCL_STD_VER >= 2017
290291

292+
//[container.intro.reqmts]
293+
# if _CCCL_STD_VER >= 2020
294+
template <class _Range, class _Tp>
295+
concept __container_compatible_range = input_range<_Range> && convertible_to<range_reference_t<_Range>, _Tp>;
296+
# else // ^^^ C++20 ^^^ / vvv C++17 vvv
297+
template <class _Range, class _Tp>
298+
_LIBCUDACXX_CONCEPT_FRAGMENT(
299+
__container_compatible_range_,
300+
requires()(requires(input_range<_Range>), requires(convertible_to<range_reference_t<_Range>, _Tp>)));
301+
302+
template <class _Range, class _Tp>
303+
_LIBCUDACXX_CONCEPT __container_compatible_range = _LIBCUDACXX_FRAGMENT(__container_compatible_range_, _Range, _Tp);
304+
# endif // _CCCL_STD_VER <= 2017
305+
291306
#endif // _CCCL_STD_VER >= 2017 && !_CCCL_COMPILER_MSVC_2017
292307

293308
_LIBCUDACXX_END_NAMESPACE_RANGES
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of libcu++, the C++ Standard Library for your entire system,
4+
// under the Apache License v2.0 with LLVM Exceptions.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
// SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCUDACXX___RANGES_FROM_RANGE_H
11+
#define _LIBCUDACXX___RANGES_FROM_RANGE_H
12+
13+
#include <cuda/std/detail/__config>
14+
15+
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
16+
# pragma GCC system_header
17+
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
18+
# pragma clang system_header
19+
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
20+
# pragma system_header
21+
#endif // no system header
22+
23+
_LIBCUDACXX_BEGIN_NAMESPACE_STD
24+
25+
struct from_range_t
26+
{};
27+
28+
_CCCL_GLOBAL_CONSTANT from_range_t from_range{};
29+
30+
_LIBCUDACXX_END_NAMESPACE_STD
31+
32+
#endif // _LIBCUDACXX___RANGES_FROM_RANGE_H
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
// SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES.
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#ifndef _LIBCUDACXX___RANGES_UNWRAP_SENTINEL_H
12+
#define _LIBCUDACXX___RANGES_UNWRAP_SENTINEL_H
13+
14+
#include <cuda/std/detail/__config>
15+
16+
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
17+
# pragma GCC system_header
18+
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
19+
# pragma clang system_header
20+
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
21+
# pragma system_header
22+
#endif // no system header
23+
24+
#include <cuda/std/__iterator/advance.h>
25+
#include <cuda/std/__ranges/access.h>
26+
#include <cuda/std/__ranges/concepts.h>
27+
28+
_LIBCUDACXX_BEGIN_NAMESPACE_RANGES
29+
30+
#if _CCCL_STD_VER >= 2017 && !defined(_CCCL_COMPILER_MSVC_2017)
31+
32+
_LIBCUDACXX_TEMPLATE(class _Range)
33+
_LIBCUDACXX_REQUIRES(forward_range<_Range>)
34+
_CCCL_NODISCARD _LIBCUDACXX_INLINE_VISIBILITY constexpr iterator_t<_Range> __unwrap_end(_Range& __range)
35+
{
36+
if constexpr (common_range<_Range>)
37+
{
38+
return _CUDA_VRANGES::end(__range);
39+
}
40+
else
41+
{
42+
auto __ret = _CUDA_VRANGES::begin(__range);
43+
_CUDA_VRANGES::advance(__ret, _CUDA_VRANGES::end(__range));
44+
return __ret;
45+
}
46+
_LIBCUDACXX_UNREACHABLE();
47+
}
48+
49+
#endif // _CCCL_STD_VER >= 2017 && !_CCCL_COMPILER_MSVC_2017
50+
51+
_LIBCUDACXX_END_NAMESPACE_RANGES
52+
53+
#endif // _LIBCUDACXX___RANGES_UNWRAP_SENTINEL_H

libcudacxx/include/cuda/std/detail/libcxx/include/__config

+5
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ extern "C++" {
469469
# define _LIBCUDACXX_LAUNDER(...) __builtin_launder(__VA_ARGS__)
470470
# endif // __check_builtin(builtin_launder)
471471

472+
// Seems that launder is broken with old clang-9 and nvcc-11.1
473+
# if (defined(_CCCL_COMPILER_CLANG) && __clang_major__ < 10) && defined(_CCCL_CUDACC_BELOW_11_3)
474+
# undef _LIBCUDACXX_LAUNDER
475+
# endif // nvcc < 11.3 && clang-9
476+
472477
// Disabled due to libstdc++ conflict
473478
# if 0 // __check_builtin(decay)
474479
# define _LIBCUDACXX_DECAY(...) __decay(__VA_ARGS__)

0 commit comments

Comments
 (0)