Skip to content

Commit 015d335

Browse files
fknorrpsalz
authored andcommitted
Document celerity::allow_by_ref, remove CELERITY_STRICT_CGF_SAFETY macro
1 parent 2886ae2 commit 015d335

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

docs/pitfalls.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ have been unwound by the time it is being called.
3131

3232
For this reason Celerity by default enforces that tasks only capture
3333
surrounding variables by value, rather than by reference. If you know what
34-
you are doing and would like to disable this check, you can define the
35-
following macro before including Celerity:
34+
you are doing and would like to disable this check, you can use the
35+
`distr_queue::submit` overload accepting reference captures:
3636

3737
```cpp
38-
#define CELERITY_STRICT_CGF_SAFETY 0
39-
#include <celerity/celerity.h>
38+
distr_queue q;
39+
q.submit(celerity::allow_by_ref, [&](celerity::handler &cgh) {...});
4040
```

include/buffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class buffer {
127127
//
128128
// (The reason why we make this a shared_ptr is so that Celerity buffers
129129
// still satisfy StandardLayoutType, which we use as a crude safety check;
130-
// see CELERITY_STRICT_CGF_SAFETY macro).
130+
// see distr_queue::submit).
131131
std::shared_ptr<cl::sycl::buffer<DataT, Dims>> faux_buf;
132132
};
133133

include/distr_queue.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
#include "runtime.h"
77
#include "task_manager.h"
88

9-
#if !defined(CELERITY_STRICT_CGF_SAFETY)
10-
#define CELERITY_STRICT_CGF_SAFETY 1
11-
#endif
12-
139
namespace celerity {
1410
namespace detail {
1511

@@ -23,8 +19,9 @@ namespace detail {
2319

2420
} // namespace detail
2521

26-
struct allow_by_ref_t {
27-
} inline constexpr allow_by_ref{};
22+
struct allow_by_ref_t {};
23+
24+
inline constexpr allow_by_ref_t allow_by_ref{};
2825

2926
class distr_queue {
3027
public:
@@ -40,21 +37,32 @@ class distr_queue {
4037
distr_queue& operator=(const distr_queue&) = delete;
4138
distr_queue& operator=(distr_queue&&) = delete;
4239

40+
/**
41+
* Submits a command group to the queue.
42+
*
43+
* Invoke via `q.submit(celerity::allow_by_ref, [&](celerity::handler &cgh) {...})`.
44+
*
45+
* With this overload, CGF may capture by-reference. This may lead to lifetime issues with asynchronous execution, so using the `submit(cgf)` overload is
46+
* preferred in the common case.
47+
*/
4348
template <typename CGF>
4449
void submit(allow_by_ref_t, CGF cgf) {
4550
// (Note while this function could be made static, it must not be! Otherwise we can't be sure the runtime has been initialized.)
46-
detail::runtime::get_instance().get_task_manager().create_task(cgf);
51+
detail::runtime::get_instance().get_task_manager().create_task(std::move(cgf));
4752
}
4853

54+
/**
55+
* Submits a command group to the queue.
56+
*
57+
* CGF must not capture by reference. This is a conservative safety check to avoid lifetime issues when command groups are executed asynchronously.
58+
*
59+
* If you know what you are doing, you can use the `allow_by_ref` overload of `submit` to bypass this check.
60+
*/
4961
template <typename CGF>
5062
void submit(CGF cgf) {
51-
#if CELERITY_STRICT_CGF_SAFETY
5263
static_assert(detail::is_safe_cgf<CGF>, "The provided command group function is not multi-pass execution safe. Please make sure to only capture by "
5364
"value. If you know what you're doing, use submit(celerity::allow_by_ref, ...).");
54-
#endif
55-
56-
// (Note while this function could be made static, it must not be! Otherwise we can't be sure the runtime has been initialized.)
57-
detail::runtime::get_instance().get_task_manager().create_task(cgf);
65+
submit(allow_by_ref, std::move(cgf));
5866
}
5967

6068
/**

0 commit comments

Comments
 (0)