Skip to content

Commit afb1e61

Browse files
committed
[SYCL] Move an accessor pointer to global_device space
With this patch an accessor pointer to global buffer is moved from global space to global_device space. That is done to distinguish this pointer from those USM pointers, that are allocated global space or global_host space, in compile time. In addition to this change there are added explicit conversion operator from global_device to global space for multi_ptr class and implicit convertion for atomic class from global_device for global space. The last change isn't covered by specification published here: #1840 , but is required to pass atomic_api CTS. Signed-off-by: Dmitry Sidorov <[email protected]>
1 parent 14af095 commit afb1e61

File tree

8 files changed

+91
-6
lines changed

8 files changed

+91
-6
lines changed

sycl/include/CL/sycl/access/access.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ template <access::target accessTarget> struct TargetToAS {
124124
access::address_space::global_space;
125125
};
126126

127+
template <> struct TargetToAS<access::target::global_buffer> {
128+
constexpr static access::address_space AS =
129+
access::address_space::global_device_space;
130+
};
131+
127132
template <> struct TargetToAS<access::target::local> {
128133
constexpr static access::address_space AS =
129134
access::address_space::local_space;

sycl/include/CL/sycl/atomic.hpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class atomic {
184184
detail::GetSpirvMemoryScope<addressSpace>::scope;
185185

186186
public:
187+
using AtomicPtrType = typename detail::PtrValueType<T, addressSpace>::type;
187188
template <typename pointerT>
188189
#ifdef __SYCL_DEVICE_ONLY__
189190
atomic(multi_ptr<pointerT, addressSpace> ptr)
@@ -197,6 +198,37 @@ class atomic {
197198
"T and pointerT must be same size");
198199
}
199200

201+
#ifdef __SYCL_DEVICE_ONLY__
202+
AtomicPtrType *getPtr() const { return Ptr; }
203+
#else
204+
std::atomic<T> *getPtr() const { return Ptr; }
205+
#endif
206+
207+
// Create atomic in global_space with one from global_device_space
208+
template <access::address_space _Space = addressSpace,
209+
typename = typename std::enable_if<
210+
_Space == addressSpace &&
211+
addressSpace == access::address_space::global_space>::type>
212+
atomic(const atomic<T, access::address_space::global_device_space> &RHS) {
213+
#ifdef __SYCL_DEVICE_ONLY__
214+
Ptr = RHS.getPtr();
215+
#else
216+
Ptr = reinterpret_cast<std::atomic<T> *>(RHS.getPtr());
217+
#endif
218+
}
219+
220+
template <access::address_space _Space = addressSpace,
221+
typename = typename std::enable_if<
222+
_Space == addressSpace &&
223+
addressSpace == access::address_space::global_space>::type>
224+
atomic(const atomic<T, access::address_space::global_device_space> &&RHS) {
225+
#ifdef __SYCL_DEVICE_ONLY__
226+
Ptr = RHS.getPtr();
227+
#else
228+
Ptr = reinterpret_cast<std::atomic<T> *>(RHS.getPtr());
229+
#endif
230+
}
231+
200232
void store(T Operand, memory_order Order = memory_order::relaxed) {
201233
__spirv_AtomicStore(
202234
Ptr, SpirvScope, detail::getSPIRVMemorySemanticsMask(Order), Operand);
@@ -299,7 +331,7 @@ class atomic {
299331

300332
private:
301333
#ifdef __SYCL_DEVICE_ONLY__
302-
typename detail::PtrValueType<T, addressSpace>::type *Ptr;
334+
AtomicPtrType *Ptr;
303335
#else
304336
std::atomic<T> *Ptr;
305337
#endif

sycl/include/CL/sycl/handler.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ class __SYCL_EXPORT handler {
506506
access::placeholder IsPH>
507507
detail::enable_if_t<Dim == 0 && Mode == access::mode::atomic, T>
508508
readFromFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Src) const {
509-
atomic<T, access::address_space::global_space> AtomicSrc = Src;
509+
atomic<T, access::address_space::global_device_space> AtomicSrc = Src;
510510
return AtomicSrc.load();
511511
}
512512

@@ -529,7 +529,7 @@ class __SYCL_EXPORT handler {
529529
access::placeholder IsPH>
530530
detail::enable_if_t<Dim == 0 && Mode == access::mode::atomic, void>
531531
writeToFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Dst, T V) const {
532-
atomic<T, access::address_space::global_space> AtomicDst = Dst;
532+
atomic<T, access::address_space::global_device_space> AtomicDst = Dst;
533533
AtomicDst.store(V);
534534
}
535535

sycl/include/CL/sycl/intel/atomic_ref.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ using IsValidAtomicType =
4343
template <cl::sycl::access::address_space AS>
4444
using IsValidAtomicAddressSpace =
4545
bool_constant<AS == access::address_space::global_space ||
46-
AS == access::address_space::local_space>;
46+
AS == access::address_space::local_space ||
47+
AS == access::address_space::global_device_space>;
4748

4849
// DefaultOrder parameter is limited to read-modify-write orders
4950
template <memory_order Order>
@@ -138,7 +139,7 @@ class atomic_ref_base {
138139
"intel::atomic_ref does not yet support pointer types");
139140
static_assert(detail::IsValidAtomicAddressSpace<AddressSpace>::value,
140141
"Invalid atomic address_space. Valid address spaces are: "
141-
"global_space, local_space");
142+
"global_space, local_space, global_device_space");
142143
static_assert(
143144
detail::IsValidDefaultOrder<DefaultOrder>::value,
144145
"Invalid default memory_order for atomics. Valid defaults are: "

sycl/include/CL/sycl/multi_ptr.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,22 @@ template <typename ElementType, access::address_space Space> class multi_ptr {
275275
return multi_ptr(m_Pointer - r);
276276
}
277277

278+
// Explicit conversion to global_space
279+
// Only available if Space == address_space::global_device_space ||
280+
// Space == address_space::global_host_space
281+
template <access::address_space _Space = Space,
282+
typename = typename std::enable_if<
283+
_Space == Space &&
284+
(Space == access::address_space::global_device_space ||
285+
Space == access::address_space::global_host_space)>::type>
286+
explicit
287+
operator multi_ptr<ElementType, access::address_space::global_space>() const {
288+
using global_pointer_t = typename detail::PtrValueType<
289+
ElementType, access::address_space::global_space>::type *;
290+
return multi_ptr<ElementType, access::address_space::global_space>(
291+
(global_pointer_t)m_Pointer);
292+
}
293+
278294
// Only if Space == global_space
279295
template <access::address_space _Space = Space,
280296
typename = typename std::enable_if<

sycl/test/check_device_code/kernel_arguments_as.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//
66
// CHECK: %struct{{.*}}AccWrapper = type { %"class{{.*}}cl::sycl::accessor" }
77
// CHECK: %"class{{.*}}cl::sycl::accessor" = type { %"class{{.*}}AccessorImplDevice", %[[UNION:.*]] }
8-
// CHECK: %[[UNION]] = type { i32 addrspace(1)* }
8+
// CHECK: %[[UNION]] = type { i32 addrspace(5)* }
99
// CHECK: %struct{{.*}}AccWrapper = type { %"class{{.*}}cl::sycl::accessor" }
1010
// CHECK-NEXT: %"class{{.*}}cl::sycl::accessor" = type { %"class{{.*}}LocalAccessorBaseDevice", i32 addrspace(3)* }
1111
//

sycl/test/multi_ptr/multi_ptr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ template <typename T> void testMultPtr() {
9898
global_ptr<void> ptr_8 = global_ptr<void>(ptr_7);
9999
host_ptr<void> ptr_9((void *)RawPtr);
100100
global_ptr<void> ptr_10 = global_ptr<void>(ptr_9);
101+
device_ptr<T> ptr_11(accessorData_1);
102+
global_ptr<T> ptr_12 = global_ptr<T>(ptr_11);
101103

102104
innerFunc<T>(wiID.get(0), ptr_1, ptr_2, local_ptr);
103105
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
2+
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
3+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
4+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
5+
6+
#include <CL/sycl.hpp>
7+
8+
using namespace cl::sycl;
9+
10+
void test_conversion(queue q) {
11+
int init = 0;
12+
{
13+
buffer<int> in_buf(&init, 1);
14+
15+
q.submit([&](handler &cgh) {
16+
auto in = in_buf.template get_access<access::mode::atomic>(cgh);
17+
cgh.single_task<class conversion>([=]() {
18+
cl::sycl::atomic<int, access::address_space::global_space> atm = in[0];
19+
atm.store(42);
20+
});
21+
});
22+
}
23+
assert(init == 42 && "verification failed");
24+
}
25+
26+
int main() {
27+
queue q;
28+
test_conversion(q);
29+
}

0 commit comments

Comments
 (0)