Skip to content

Commit aa69e4d

Browse files
authored
[SYCL] Implement diagnostic for !access_mode::read + const T (#8169)
According to [Read only accessors](https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#_read_only_accessors) A const qualified DataT is only allowed for a read-only accessor. This PR: - Implements Implement diagnostic for !access_mode::read + const T - Adds test to for above diagnostic - Updates affected tests. - Assigns access::mode:read to access mode of local accessor when the data type is constant. The previous value was access::mode:read, which lead to an assert after implementing above diagnostic.
1 parent e47b588 commit aa69e4d

File tree

5 files changed

+84
-25
lines changed

5 files changed

+84
-25
lines changed

sycl/include/sycl/accessor.hpp

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ class accessor_common {
314314
AccessMode == access::mode::discard_read_write;
315315

316316
constexpr static bool IsAccessReadOnly = AccessMode == access::mode::read;
317+
static constexpr bool IsConst = std::is_const<DataT>::value;
317318

318319
constexpr static bool IsAccessReadWrite =
319320
AccessMode == access::mode::read_write;
@@ -371,6 +372,13 @@ class accessor_common {
371372
};
372373
};
373374

375+
template <typename DataT> constexpr access::mode accessModeFromConstness() {
376+
if constexpr (std::is_const<DataT>::value)
377+
return access::mode::read;
378+
else
379+
return access::mode::read_write;
380+
}
381+
374382
template <typename MayBeTag1, typename MayBeTag2>
375383
constexpr access::mode deduceAccessMode() {
376384
// property_list = {} is not properly detected by deduction guide,
@@ -1020,10 +1028,15 @@ class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(accessor) accessor :
10201028
static constexpr bool IsGlobalBuf = AccessorCommonT::IsGlobalBuf;
10211029
static constexpr bool IsHostBuf = AccessorCommonT::IsHostBuf;
10221030
static constexpr bool IsPlaceH = AccessorCommonT::IsPlaceH;
1031+
static constexpr bool IsConst = AccessorCommonT::IsConst;
10231032
template <int Dims>
10241033
using AccessorSubscript =
10251034
typename AccessorCommonT::template AccessorSubscript<Dims>;
10261035

1036+
static_assert(
1037+
!IsConst || IsAccessReadOnly,
1038+
"A const qualified DataT is only allowed for a read-only accessor");
1039+
10271040
using ConcreteASPtrType = typename detail::DecoratedType<DataT, AS>::type *;
10281041

10291042
using RefType = detail::const_if_const_AS<AS, DataT> &;
@@ -2392,7 +2405,13 @@ class __SYCL_SPECIAL_CLASS local_accessor_base :
23922405
access::target::local, IsPlaceholder>;
23932406

23942407
using AccessorCommonT::AS;
2395-
using AccessorCommonT::IsAccessAnyWrite;
2408+
2409+
// Cannot do "using AccessorCommonT::Flag" as it doesn't work with g++ as host
2410+
// compiler, for some reason.
2411+
static constexpr bool IsAccessAnyWrite = AccessorCommonT::IsAccessAnyWrite;
2412+
static constexpr bool IsAccessReadOnly = AccessorCommonT::IsAccessReadOnly;
2413+
static constexpr bool IsConst = AccessorCommonT::IsConst;
2414+
23962415
template <int Dims>
23972416
using AccessorSubscript =
23982417
typename AccessorCommonT::template AccessorSubscript<
@@ -2485,7 +2504,8 @@ class __SYCL_SPECIAL_CLASS local_accessor_base :
24852504
local_accessor_base(handler &, const detail::code_location CodeLoc =
24862505
detail::code_location::current())
24872506
#ifdef __SYCL_DEVICE_ONLY__
2488-
: impl(range<AdjustedDim>{1}){}
2507+
: impl(range<AdjustedDim>{1}) {
2508+
}
24892509
#else
24902510
: LocalAccessorBaseHost(range<3>{1, 1, 1}, AdjustedDim, sizeof(DataT)) {
24912511
detail::constructorNotification(nullptr, LocalAccessorBaseHost::impl.get(),
@@ -2494,11 +2514,10 @@ class __SYCL_SPECIAL_CLASS local_accessor_base :
24942514
}
24952515
#endif
24962516

2497-
template <int Dims = Dimensions,
2498-
typename = detail::enable_if_t<Dims == 0>>
2499-
local_accessor_base(handler &, const property_list &propList,
2500-
const detail::code_location CodeLoc =
2501-
detail::code_location::current())
2517+
template <int Dims = Dimensions, typename = detail::enable_if_t<Dims == 0>>
2518+
local_accessor_base(
2519+
handler &, const property_list &propList,
2520+
const detail::code_location CodeLoc = detail::code_location::current())
25022521
#ifdef __SYCL_DEVICE_ONLY__
25032522
: impl(range<AdjustedDim>{1}) {
25042523
(void)propList;
@@ -2517,7 +2536,8 @@ class __SYCL_SPECIAL_CLASS local_accessor_base :
25172536
range<Dimensions> AllocationSize, handler &,
25182537
const detail::code_location CodeLoc = detail::code_location::current())
25192538
#ifdef __SYCL_DEVICE_ONLY__
2520-
: impl(AllocationSize){}
2539+
: impl(AllocationSize) {
2540+
}
25212541
#else
25222542
: LocalAccessorBaseHost(detail::convertToArrayOfN<3, 1>(AllocationSize),
25232543
AdjustedDim, sizeof(DataT)) {
@@ -2527,12 +2547,11 @@ class __SYCL_SPECIAL_CLASS local_accessor_base :
25272547
}
25282548
#endif
25292549

2530-
template <int Dims = Dimensions,
2531-
typename = detail::enable_if_t<(Dims > 0)>>
2532-
local_accessor_base(range<Dimensions> AllocationSize, handler &,
2533-
const property_list &propList,
2534-
const detail::code_location CodeLoc =
2535-
detail::code_location::current())
2550+
template <int Dims = Dimensions, typename = detail::enable_if_t<(Dims > 0)>>
2551+
local_accessor_base(
2552+
range<Dimensions> AllocationSize, handler &,
2553+
const property_list &propList,
2554+
const detail::code_location CodeLoc = detail::code_location::current())
25362555
#ifdef __SYCL_DEVICE_ONLY__
25372556
: impl(AllocationSize) {
25382557
(void)propList;
@@ -2634,6 +2653,10 @@ class __SYCL_EBO __SYCL_SPECIAL_CLASS accessor<
26342653
using local_acc =
26352654
local_accessor_base<DataT, Dimensions, AccessMode, IsPlaceholder>;
26362655

2656+
static_assert(
2657+
!local_acc::IsConst || local_acc::IsAccessReadOnly,
2658+
"A const qualified DataT is only allowed for a read-only accessor");
2659+
26372660
// Use base classes constructors
26382661
using local_acc::local_acc;
26392662

@@ -2663,14 +2686,20 @@ class __SYCL_EBO __SYCL_SPECIAL_CLASS accessor<
26632686

26642687
template <typename DataT, int Dimensions = 1>
26652688
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor
2666-
: public local_accessor_base<DataT, Dimensions, access::mode::read_write,
2689+
: public local_accessor_base<DataT, Dimensions,
2690+
detail::accessModeFromConstness<DataT>(),
26672691
access::placeholder::false_t>,
26682692
public detail::OwnerLessBase<local_accessor<DataT, Dimensions>> {
26692693

26702694
using local_acc =
2671-
local_accessor_base<DataT, Dimensions, access::mode::read_write,
2695+
local_accessor_base<DataT, Dimensions,
2696+
detail::accessModeFromConstness<DataT>(),
26722697
access::placeholder::false_t>;
26732698

2699+
static_assert(
2700+
!local_acc::IsConst || local_acc::IsAccessReadOnly,
2701+
"A const qualified DataT is only allowed for a read-only accessor");
2702+
26742703
// Use base classes constructors
26752704
using local_acc::local_acc;
26762705

sycl/test/basic_tests/accessor/accessor_ptr_alias.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ template <typename DataT, int Dims> void CheckLocalAccessor() {
4040

4141
template <typename DataT, int Dims> void CheckAccessorForModes() {
4242
CheckDeviceAccessor<DataT, Dims, sycl::access::mode::read>();
43-
CheckDeviceAccessor<DataT, Dims, sycl::access::mode::read_write>();
44-
CheckDeviceAccessor<DataT, Dims, sycl::access::mode::write>();
4543
CheckLocalAccessor<DataT, Dims>();
44+
if constexpr (!std::is_const<DataT>::value) {
45+
CheckDeviceAccessor<DataT, Dims, sycl::access::mode::read_write>();
46+
CheckDeviceAccessor<DataT, Dims, sycl::access::mode::write>();
47+
}
4648
}
4749

4850
template <typename DataT> void CheckAccessorForAllDimsAndModes() {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clangxx -fsycl -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note %s
2+
3+
#include <sycl/sycl.hpp>
4+
5+
using namespace sycl;
6+
7+
constexpr size_t dataSize = 1;
8+
9+
int main() {
10+
const int a[dataSize] = {1};
11+
12+
try {
13+
auto defaultQueue = queue{};
14+
auto bufA = buffer<const int, 1>{a, range{dataSize}};
15+
defaultQueue.submit([&](handler &cgh) {
16+
// expected-error@sycl/accessor.hpp:* {{A const qualified DataT is only allowed for a read-only accessor}}
17+
accessor accA{bufA, cgh, read_write};
18+
});
19+
20+
defaultQueue.throw_asynchronous();
21+
} catch (const exception &e) {
22+
std::cout << "Exception caught: " << e.what() << std::endl;
23+
}
24+
return 0;
25+
}

sycl/test/basic_tests/accessor/host_accessor_get_pointer_type.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ void CheckHostAccessor() {
1818

1919
template <typename DataT, int Dims> void CheckHostAccessorForModes() {
2020
CheckHostAccessor<DataT, Dims, sycl::access::mode::read>();
21-
CheckHostAccessor<DataT, Dims, sycl::access::mode::read_write>();
22-
CheckHostAccessor<DataT, Dims, sycl::access::mode::write>();
21+
if constexpr (!std::is_const<DataT>::value) {
22+
CheckHostAccessor<DataT, Dims, sycl::access::mode::read_write>();
23+
CheckHostAccessor<DataT, Dims, sycl::access::mode::write>();
24+
}
2325
}
2426

2527
template <typename DataT> void CheckHostAccessorForAllDimsAndModes() {

sycl/test/regression/accessor_subscript_and_ref_type.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,14 @@ template <typename DataT, access::mode AccessMode> void CheckAccAllDims() {
8181
}
8282

8383
template <typename DataT> void CheckAccAllAccessModesAndDims() {
84-
CheckAccAllDims<DataT, access::mode::write>();
85-
CheckAccAllDims<DataT, access::mode::read_write>();
86-
CheckAccAllDims<DataT, access::mode::discard_write>();
87-
CheckAccAllDims<DataT, access::mode::discard_read_write>();
8884
CheckAccAllDims<DataT, access::mode::read>();
89-
if constexpr (!std::is_const_v<DataT>)
85+
if constexpr (!std::is_const_v<DataT>) {
86+
CheckAccAllDims<DataT, access::mode::write>();
87+
CheckAccAllDims<DataT, access::mode::read_write>();
88+
CheckAccAllDims<DataT, access::mode::discard_write>();
89+
CheckAccAllDims<DataT, access::mode::discard_read_write>();
9090
CheckAccAllDims<DataT, access::mode::atomic>();
91+
}
9192
}
9293

9394
int main() {

0 commit comments

Comments
 (0)