Skip to content

Commit 0f49fb5

Browse files
committed
Switch to optional and references
Signed-off-by: Larsen, Steffen <[email protected]>
1 parent 3c7f491 commit 0f49fb5

File tree

7 files changed

+201
-37
lines changed

7 files changed

+201
-37
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
//==-------- optional.hpp - limited variant of std::optional -------- C++ --==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
// ===--------------------------------------------------------------------=== //
8+
9+
#pragma once
10+
11+
#include <optional>
12+
#include <type_traits>
13+
14+
namespace sycl {
15+
inline namespace _V1 {
16+
namespace detail {
17+
18+
// ABI-stable implementation of optional to avoid reliance on potentially
19+
// differing implementations of std::optional when crossing the library
20+
// boundary.
21+
template <typename T> class optional {
22+
public:
23+
constexpr optional() noexcept {}
24+
constexpr optional(std::nullopt_t) noexcept : optional() {}
25+
26+
template <typename U>
27+
constexpr optional(const optional<U> &Other)
28+
: ContainsValue{Other.ContainsValue} {
29+
new (Storage) T(Other.Value);
30+
}
31+
template <typename U>
32+
constexpr optional(optional<U> &&Other)
33+
: ContainsValue{std::move(Other.ContainsValue)} {
34+
new (Storage) T(std::move(Other.Value));
35+
}
36+
37+
constexpr optional(T &&Value) : ContainsValue{true} {
38+
new (Storage) T(std::move(Value));
39+
}
40+
41+
constexpr optional(const T &Value) : ContainsValue{true} {
42+
new (Storage) T(Value);
43+
}
44+
45+
template <typename U>
46+
constexpr optional(const std::optional<U> &Other) : ContainsValue{Other} {
47+
if (Other)
48+
new (Storage) T(*Other);
49+
}
50+
51+
~optional() {
52+
if (has_value())
53+
reinterpret_cast<T *>(Storage)->~T();
54+
}
55+
56+
optional &operator=(std::nullopt_t) noexcept {
57+
if (has_value())
58+
reinterpret_cast<T *>(Storage)->~T();
59+
ContainsValue = false;
60+
return *this;
61+
}
62+
63+
template <typename U> optional &operator=(const optional<U> &Other) {
64+
if (has_value())
65+
reinterpret_cast<T *>(Storage)->~T();
66+
ContainsValue = Other;
67+
new (Storage) T(Other.Value);
68+
return *this;
69+
}
70+
template <typename U> optional &operator=(optional<U> &&Other) noexcept {
71+
if (has_value())
72+
reinterpret_cast<T *>(Storage)->~T();
73+
ContainsValue = Other;
74+
new (Storage) T(std::move(Other.Value));
75+
return *this;
76+
}
77+
78+
optional &operator=(T &&Value){
79+
if (has_value())
80+
reinterpret_cast<T *>(Storage)->~T();
81+
ContainsValue = true;
82+
new (Storage) T(std::move(Value));
83+
return *this;
84+
}
85+
86+
optional &operator=(const T &Value){
87+
if (has_value())
88+
reinterpret_cast<T *>(Storage)->~T();
89+
ContainsValue = true;
90+
new (Storage) T(Value);
91+
return *this;
92+
}
93+
94+
template <typename U>
95+
optional &operator=(const std::optional<U> &Other) {
96+
if (has_value())
97+
reinterpret_cast<T *>(Storage)->~T();
98+
ContainsValue = Other;
99+
if (Other)
100+
new (Storage) T(*Other);
101+
return *this;
102+
}
103+
104+
constexpr bool has_value() const noexcept { return ContainsValue; }
105+
constexpr explicit operator bool() const noexcept { return has_value(); }
106+
107+
constexpr T &value() & {
108+
if (!has_value())
109+
throw std::bad_optional_access{};
110+
return *reinterpret_cast<T *>(Storage);
111+
}
112+
constexpr const T &value() const & {
113+
if (!has_value())
114+
throw std::bad_optional_access{};
115+
return *reinterpret_cast<const T *>(Storage);
116+
}
117+
constexpr T &&value() && {
118+
if (!has_value())
119+
throw std::bad_optional_access{};
120+
return std::move(*reinterpret_cast<T *>(Storage));
121+
}
122+
constexpr const T &&value() const && {
123+
if (!has_value())
124+
throw std::bad_optional_access{};
125+
return std::move(*reinterpret_cast<const T *>(Storage));
126+
}
127+
128+
template <class U> constexpr T value_or(U &&DefaultVal) {
129+
return has_value() ? value() : static_cast<T>(std::forward<U>(DefaultVal));
130+
}
131+
template <class U> constexpr T value_or(U &&DefaultVal) const {
132+
return has_value() ? std::move(value())
133+
: static_cast<T>(std::forward<U>(DefaultVal));
134+
}
135+
136+
constexpr T &operator*() & { return value(); }
137+
constexpr const T &operator*() const & { return value(); }
138+
constexpr T &&operator*() && { return value(); }
139+
constexpr const T &&operator*() const && { return value(); }
140+
141+
private:
142+
alignas(alignof(T)) char Storage[sizeof(T)] = {0};
143+
bool ContainsValue = false;
144+
};
145+
146+
} // namespace detail
147+
} // namespace _V1
148+
} // namespace sycl

sycl/include/sycl/queue.hpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
#include <sycl/detail/export.hpp> // for __SYCL_EXPORT
2323
#include <sycl/detail/info_desc_helpers.hpp> // for is_queue_info_...
2424
#include <sycl/detail/kernel_desc.hpp> // for KernelInfo
25-
#include <sycl/detail/owner_less_base.hpp> // for OwnerLessBase
26-
#include <sycl/device.hpp> // for device
27-
#include <sycl/device_selector.hpp> // for device_selector
28-
#include <sycl/event.hpp> // for event
29-
#include <sycl/exception.hpp> // for make_error_code
30-
#include <sycl/exception_list.hpp> // for defaultAsyncHa...
25+
#include <sycl/detail/optional.hpp>
26+
#include <sycl/detail/owner_less_base.hpp> // for OwnerLessBase
27+
#include <sycl/device.hpp> // for device
28+
#include <sycl/device_selector.hpp> // for device_selector
29+
#include <sycl/event.hpp> // for event
30+
#include <sycl/exception.hpp> // for make_error_code
31+
#include <sycl/exception_list.hpp> // for defaultAsyncHa...
3132
#include <sycl/ext/oneapi/device_global/device_global.hpp> // for device_global
3233
#include <sycl/ext/oneapi/device_global/properties.hpp> // for device_image_s...
3334
#include <sycl/ext/oneapi/experimental/graph.hpp> // for command_graph...
@@ -94,12 +95,15 @@ struct SubmissionInfoImpl;
9495

9596
class __SYCL_EXPORT SubmissionInfo {
9697
public:
97-
SubmissionInfo() = default;
98+
SubmissionInfo();
9899

99-
void SetPostProcessing(const SubmitPostProcessF &PostProcessorFunc);
100-
void
101-
SetSecondaryQueue(const std::shared_ptr<detail::queue_impl> &SecondaryQueue);
100+
sycl::detail::optional<SubmitPostProcessF> &PostProcessorFunc();
101+
const sycl::detail::optional<SubmitPostProcessF> &PostProcessorFunc() const;
102102

103+
std::shared_ptr<detail::queue_impl> &SecondaryQueue();
104+
const std::shared_ptr<detail::queue_impl> &SecondaryQueue() const;
105+
106+
private:
103107
std::shared_ptr<SubmissionInfoImpl> impl = nullptr;
104108
};
105109
} // namespace detail
@@ -2806,10 +2810,11 @@ class __SYCL_EXPORT queue : public detail::OwnerLessBase<queue> {
28062810
detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
28072811
detail::SubmissionInfo SI{};
28082812
if (SecondaryQueuePtr)
2809-
SI.SetSecondaryQueue(detail::getSyclObjImpl(*SecondaryQueuePtr));
2813+
SI.SecondaryQueue() = detail::getSyclObjImpl(*SecondaryQueuePtr);
28102814
#if __SYCL_USE_FALLBACK_ASSERT
2811-
SI.SetPostProcessing([this, &SecondaryQueuePtr, &TlsCodeLocCapture](
2812-
bool IsKernel, bool KernelUsesAssert, event &E) {
2815+
SI.PostProcessorFunc() = [this, &SecondaryQueuePtr, &TlsCodeLocCapture](
2816+
bool IsKernel, bool KernelUsesAssert,
2817+
event &E) {
28132818
if (IsKernel && !device_has(aspect::ext_oneapi_native_assert) &&
28142819
KernelUsesAssert && !device_has(aspect::accelerator)) {
28152820
// __devicelib_assert_fail isn't supported by Device-side Runtime
@@ -2819,7 +2824,7 @@ class __SYCL_EXPORT queue : public detail::OwnerLessBase<queue> {
28192824
submitAssertCapture(*this, E, SecondaryQueuePtr,
28202825
TlsCodeLocCapture.query());
28212826
}
2822-
});
2827+
};
28232828
#endif // __SYCL_USE_FALLBACK_ASSERT
28242829
return submit_with_event_impl(CGF, SI, TlsCodeLocCapture.query(),
28252830
TlsCodeLocCapture.isToplevel());

sycl/source/detail/queue_impl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ event queue_impl::submit_impl(const std::function<void(handler &)> &CGF,
374374
if (Type == CGType::Kernel)
375375
Streams = std::move(Handler.MStreamStorage);
376376

377-
if (SubmitInfo.impl && SubmitInfo.impl->MPostProcessorFunc) {
378-
auto &PostProcess = *(SubmitInfo.impl->MPostProcessorFunc);
377+
if (SubmitInfo.PostProcessorFunc()) {
378+
auto &PostProcess = *SubmitInfo.PostProcessorFunc();
379379

380380
bool IsKernel = Type == CGType::Kernel;
381381
bool KernelUsesAssert = false;

sycl/source/detail/queue_impl.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ enum QueueOrder { Ordered, OOO };
6969

7070
// Implementation of the submission information storage.
7171
struct SubmissionInfoImpl {
72-
std::optional<detail::SubmitPostProcessF> MPostProcessorFunc = std::nullopt;
72+
optional<detail::SubmitPostProcessF> MPostProcessorFunc = std::nullopt;
7373
std::shared_ptr<detail::queue_impl> MSecondaryQueue = nullptr;
7474
};
7575

@@ -345,9 +345,9 @@ class queue_impl {
345345
const SubmitPostProcessF *PostProcess = nullptr) {
346346
event ResEvent;
347347
SubmissionInfo SI{};
348-
SI.SetSecondaryQueue(SecondQueue);
348+
SI.SecondaryQueue() = SecondQueue;
349349
if (PostProcess)
350-
SI.SetPostProcessing(*PostProcess);
350+
SI.PostProcessorFunc() = *PostProcess;
351351
return submit_with_event(CGF, Self, SI, Loc, IsTopCodeLoc);
352352
}
353353

@@ -364,10 +364,10 @@ class queue_impl {
364364
const std::shared_ptr<queue_impl> &Self,
365365
const SubmissionInfo &SubmitInfo,
366366
const detail::code_location &Loc, bool IsTopCodeLoc) {
367-
if (SubmitInfo.impl && SubmitInfo.impl->MSecondaryQueue) {
367+
if (SubmitInfo.SecondaryQueue()) {
368368
event ResEvent;
369369
const std::shared_ptr<queue_impl> SecondQueue =
370-
SubmitInfo.impl->MSecondaryQueue;
370+
SubmitInfo.SecondaryQueue();
371371
try {
372372
ResEvent = submit_impl(CGF, Self, Self, SecondQueue,
373373
/*CallerNeedsEvent=*/true, Loc, IsTopCodeLoc,
@@ -390,9 +390,9 @@ class queue_impl {
390390
const SubmissionInfo &SubmitInfo,
391391
const detail::code_location &Loc,
392392
bool IsTopCodeLoc) {
393-
if (SubmitInfo.impl && SubmitInfo.impl->MSecondaryQueue) {
393+
if (SubmitInfo.SecondaryQueue()) {
394394
const std::shared_ptr<queue_impl> SecondQueue =
395-
SubmitInfo.impl->MSecondaryQueue;
395+
SubmitInfo.SecondaryQueue();
396396
try {
397397
submit_impl(CGF, Self, Self, SecondQueue,
398398
/*CallerNeedsEvent=*/false, Loc, IsTopCodeLoc, SubmitInfo);

sycl/source/queue.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,24 @@ namespace sycl {
2121
inline namespace _V1 {
2222

2323
namespace detail {
24-
void SubmissionInfo::SetPostProcessing(
25-
const SubmitPostProcessF &PostProcessorFunc) {
26-
if (!impl)
27-
impl = std::make_shared<SubmissionInfoImpl>();
28-
impl->MPostProcessorFunc = std::move(PostProcessorFunc);
24+
SubmissionInfo::SubmissionInfo()
25+
: impl{std::make_shared<SubmissionInfoImpl>()} {}
26+
27+
optional<SubmitPostProcessF> &SubmissionInfo::PostProcessorFunc() {
28+
return impl->MPostProcessorFunc;
29+
}
30+
31+
const optional<SubmitPostProcessF> &SubmissionInfo::PostProcessorFunc() const {
32+
return impl->MPostProcessorFunc;
33+
}
34+
35+
std::shared_ptr<detail::queue_impl> & SubmissionInfo::SecondaryQueue() {
36+
return impl->MSecondaryQueue;
2937
}
3038

31-
void SubmissionInfo::SetSecondaryQueue(
32-
const std::shared_ptr<detail::queue_impl> &SecondaryQueue) {
33-
if (!impl)
34-
impl = std::make_shared<SubmissionInfoImpl>();
35-
impl->MSecondaryQueue = SecondaryQueue;
39+
const std::shared_ptr<detail::queue_impl> &
40+
SubmissionInfo::SecondaryQueue() const {
41+
return impl->MSecondaryQueue;
3642
}
3743
} // namespace detail
3844

@@ -216,14 +222,14 @@ event queue::submit_impl_and_postprocess(
216222
std::function<void(handler &)> CGH, const detail::code_location &CodeLoc,
217223
const detail::SubmitPostProcessF &PostProcess) {
218224
detail::SubmissionInfo SI{};
219-
SI.SetPostProcessing(std::move(PostProcess));
225+
SI.PostProcessorFunc() = std::move(PostProcess);
220226
return submit_with_event_impl(CGH, SI, CodeLoc, true);
221227
}
222228
event queue::submit_impl_and_postprocess(
223229
std::function<void(handler &)> CGH, const detail::code_location &CodeLoc,
224230
const detail::SubmitPostProcessF &PostProcess, bool IsTopCodeLoc) {
225231
detail::SubmissionInfo SI{};
226-
SI.SetPostProcessing(std::move(PostProcess));
232+
SI.PostProcessorFunc() = std::move(PostProcess);
227233
return submit_with_event_impl(CGH, SI, CodeLoc, IsTopCodeLoc);
228234
}
229235

sycl/test/abi/sycl_symbols_linux.dump

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3238,8 +3238,6 @@ _ZN4sycl3_V16detail13lgamma_r_implEfPi
32383238
_ZN4sycl3_V16detail13make_platformEmNS0_7backendE
32393239
_ZN4sycl3_V16detail13select_deviceERKSt8functionIFiRKNS0_6deviceEEE
32403240
_ZN4sycl3_V16detail13select_deviceERKSt8functionIFiRKNS0_6deviceEEERKNS0_7contextE
3241-
_ZN4sycl3_V16detail14SubmissionInfo17SetSecondaryQueueERKSt10shared_ptrINS1_10queue_implEE
3242-
_ZN4sycl3_V16detail14SubmissionInfo17SetPostProcessingERKSt8functionIFvbbRNS0_5eventEEE
32433241
_ZN4sycl3_V16detail14addCounterInitERNS0_7handlerERSt10shared_ptrINS1_10queue_implEERS4_IiE
32443242
_ZN4sycl3_V16detail14getBorderColorENS0_19image_channel_orderE
32453243
_ZN4sycl3_V16detail14tls_code_loc_t5queryEv
@@ -3249,6 +3247,10 @@ _ZN4sycl3_V16detail14tls_code_loc_tC2ERKNS1_13code_locationE
32493247
_ZN4sycl3_V16detail14tls_code_loc_tC2Ev
32503248
_ZN4sycl3_V16detail14tls_code_loc_tD1Ev
32513249
_ZN4sycl3_V16detail14tls_code_loc_tD2Ev
3250+
_ZN4sycl3_V16detail14SubmissionInfo14SecondaryQueueEv
3251+
_ZN4sycl3_V16detail14SubmissionInfo17PostProcessorFuncEv
3252+
_ZN4sycl3_V16detail14SubmissionInfoC1Ev
3253+
_ZN4sycl3_V16detail14SubmissionInfoC2Ev
32523254
_ZN4sycl3_V16detail16AccessorBaseHost10getAccDataEv
32533255
_ZN4sycl3_V16detail16AccessorBaseHost14getAccessRangeEv
32543256
_ZN4sycl3_V16detail16AccessorBaseHost14getMemoryRangeEv
@@ -3706,6 +3708,8 @@ _ZNK4sycl3_V16detail12buffer_plain13handleReleaseEv
37063708
_ZNK4sycl3_V16detail12buffer_plain15getNativeVectorENS0_7backendE
37073709
_ZNK4sycl3_V16detail12buffer_plain22get_allocator_internalEv
37083710
_ZNK4sycl3_V16detail12buffer_plain7getSizeEv
3711+
_ZNK4sycl3_V16detail14SubmissionInfo14SecondaryQueueEv
3712+
_ZNK4sycl3_V16detail14SubmissionInfo17PostProcessorFuncEv
37093713
_ZNK4sycl3_V16detail16AccessorBaseHost11getElemSizeEv
37103714
_ZNK4sycl3_V16detail16AccessorBaseHost11getPropListEv
37113715
_ZNK4sycl3_V16detail16AccessorBaseHost13isPlaceholderEv

sycl/test/include_deps/sycl_detail_core.hpp.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
// CHECK-NEXT: nd_item.hpp
129129
// CHECK-NEXT: nd_range.hpp
130130
// CHECK-NEXT: sub_group.hpp
131+
// CHECK-NEXT: detail/optional.hpp
131132
// CHECK-NEXT: device.hpp
132133
// CHECK-NEXT: kernel_bundle_enums.hpp
133134
// CHECK-NEXT: event.hpp

0 commit comments

Comments
 (0)