Skip to content

Commit

Permalink
Merge pull request #405 from StreamHPC/fix-optional-emplace
Browse files Browse the repository at this point in the history
Fix optional emplace
  • Loading branch information
Snektron authored May 7, 2024
2 parents 99fc0cb + c876f93 commit dc0a981
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Documentation for rocThrust available at
* Updated internal use of custom iterator in `thrust::detail::unique_by_key` to use rocPRIM's `rocprim::unique_by_key`.
* Updated `adjecent_difference` to make use of `rocprim:adjecent_difference` when iterators are comparable and not equal otherwise use `rocprim:adjacent_difference_inplace`.

### Fixes
* Fixed incorrect implementation of `thrust::optional<T&>::emplace()`.

### Known issues
* `thrust::reduce_by_key` outputs are not bit-wise reproducible, as run-to-run results for pseudo-associative reduction operators (e.g. floating-point arithmetic operators) are not deterministic on the same device.

Expand Down Expand Up @@ -47,7 +50,7 @@ Documentation for rocThrust available at

## rocThrust 2.18.0 for ROCm 5.7

### Fixes
### Fixes
* `lower_bound`, `upper_bound`, and `binary_search` failed to compile for certain types.
* Fixed issue where `transform_iterator` would not compile with `__device__`-only operators.

Expand Down
38 changes: 38 additions & 0 deletions test/test_optional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,41 @@ TEST(OptionalTests, IsTriviallyCopyable)
static_assert(std::is_trivially_copyable<thrust::optional<uint64_t>>::value == true,
"type is not trivially copyable even though it should be!");
}

TEST(OptionalTests, EmplaceReference)
{
// See https://github.com/ROCm/rocThrust/issues/404
{
int a = 10;

thrust::optional<int&> maybe(a);

int b = 20;
maybe.emplace(b);

ASSERT_EQ(maybe.value(), 20);
// Emplacing with b shouldn't change a
ASSERT_EQ(a, 10);

int c = 30;
maybe.emplace(c);

ASSERT_EQ(maybe.value(), 30);
ASSERT_EQ(b, 20);
}

{
thrust::optional<int&> maybe;

int b = 21;
maybe.emplace(b);

ASSERT_EQ(maybe.value(), 21);

int c = 31;
maybe.emplace(c);

ASSERT_EQ(maybe.value(), 31);
ASSERT_EQ(b, 21);
}
}
11 changes: 4 additions & 7 deletions thrust/optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -2746,14 +2746,11 @@ template <class T> class optional<T &> {
///
/// \group emplace
__thrust_exec_check_disable__
template <class... Args>
template <class U>
__host__ __device__
T &emplace(Args &&... args) noexcept {
static_assert(std::is_constructible<T, Args &&...>::value,
"T must be constructible with Args");

*this = nullopt;
this->construct(std::forward<Args>(args)...);
T &emplace(U& u) noexcept {
m_value = addressof(u);
return *m_value;
}

/// Swaps this optional with the other.
Expand Down

0 comments on commit dc0a981

Please sign in to comment.