Skip to content

Commit

Permalink
[SYCL] Support const lambdas in detail::type_erased_cgfo_ty (#16819)
Browse files Browse the repository at this point in the history
  • Loading branch information
aelovikov-intel authored Jan 29, 2025
1 parent 0e5b5ee commit adeaea8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
12 changes: 6 additions & 6 deletions sycl/include/sycl/handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,12 @@ class type_erased_cgfo_ty {
// by a queue. The function object can be a named type, lambda function or
// std::function.
template <typename T> struct invoker {
static void call(void *object, handler &cgh) {
(*static_cast<T *>(object))(cgh);
static void call(const void *object, handler &cgh) {
(*const_cast<T *>(static_cast<const T *>(object)))(cgh);
}
};
void *object;
using invoker_ty = void (*)(void *, handler &);
const void *object;
using invoker_ty = void (*)(const void *, handler &);
const invoker_ty invoker_f;

public:
Expand All @@ -183,15 +183,15 @@ class type_erased_cgfo_ty {
// NOTE: Even if `T` is a pointer to a function, `&f` is a pointer to a
// pointer to a function and as such can be casted to `void *` (pointer to
// a function cannot be casted).
: object(static_cast<void *>(&f)), invoker_f(&invoker<T>::call) {}
: object(static_cast<const void *>(&f)), invoker_f(&invoker<T>::call) {}
~type_erased_cgfo_ty() = default;

type_erased_cgfo_ty(const type_erased_cgfo_ty &) = delete;
type_erased_cgfo_ty(type_erased_cgfo_ty &&) = delete;
type_erased_cgfo_ty &operator=(const type_erased_cgfo_ty &) = delete;
type_erased_cgfo_ty &operator=(type_erased_cgfo_ty &&) = delete;

void operator()(sycl::handler &cgh) const { invoker_f(object, cgh); }
void operator()(handler &cgh) const { invoker_f(object, cgh); }
};

class kernel_bundle_impl;
Expand Down
26 changes: 26 additions & 0 deletions sycl/test-e2e/Basic/cgfo_const_lambda.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: %{build} -o %t.out
// RUN: %{run} %t.out

#include <sycl/detail/core.hpp>

int main() {
sycl::queue q;
sycl::buffer<int, 1> b{1};
sycl::host_accessor{b}[0] = 0;

auto l = [&](sycl::handler &cgh) {
sycl::accessor acc{b, cgh};
cgh.single_task([=]() { ++acc[0]; });
};
q.submit(l);
assert(sycl::host_accessor{b}[0] == 1);

const auto cl = [&](sycl::handler &cgh) {
sycl::accessor acc{b, cgh};
cgh.single_task([=]() { ++acc[0]; });
};
q.submit(cl);
assert(sycl::host_accessor{b}[0] == 2);

return 0;
}

0 comments on commit adeaea8

Please sign in to comment.