bader created this revision.
bader added reviewers: Anastasia, keryell, Naghasan.
Herald added subscribers: ebevhan, yaxunl.
bader requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.
Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D99488

Files:
  clang/docs/SYCLSupport.md

Index: clang/docs/SYCLSupport.md
===================================================================
--- clang/docs/SYCLSupport.md
+++ clang/docs/SYCLSupport.md
@@ -813,6 +813,113 @@
 The SPIR-V specific functions are implemented in for the SYCL host device here:
 `sycl/source/spirv_ops.cpp`.
 
+### Address spaces handling
+
+SYCL specification uses C++ classes to represent pointers to disjoint memory
+regions on an accelerator to enable compilation with standard C++ toolchain and
+SYCL compiler toolchain. Section 3.8.2 of SYCL 2020 specification defines
+[memory model](https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#_sycl_device_memory_model),
+section 4.7.7 - [address space classes](https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#_address_space_classes)
+and section 5.9.2 covers [address space deduction](https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#_address_space_deduction).
+
+For instance:
+
+``` C++
+// check that SYCL mode is ON and we can use non-standard decorations
+#if defined(__SYCL_DEVICE_ONLY__)
+// GPU/accelerator implementation
+template <typename T, address_space AS> class multi_ptr {
+  // DecoratedType applies corresponding address space attribute to the type T
+  // DecoratedType<T, global_space>::type == "__attribute__((opencl_global)) T"
+  // See sycl/include/CL/sycl/access/access.hpp for more details
+  using pointer_t = typename DecoratedType<T, AS>::type *;
+
+  pointer_t m_Pointer;
+  public:
+  pointer_t get() { return m_Pointer; }
+  T& operator* () { return *reinterpret_cast<T*>(m_Pointer); }
+}
+#else
+// CPU/host implementation
+template <typename T, address_space AS> class multi_ptr {
+  T *m_Pointer; // regular undecorated pointer
+  public:
+  T *get() { return m_Pointer; }
+  T& operator* () { return *m_Pointer; }
+}
+#endif
+```
+
+Depending on the compiler mode `multi_ptr` will either decorate internal data
+with address space attribute or not.
+
+The main address space semantic difference of SYCL mode from OpenCL is that
+SYCL doesn't assign OpenCL generic address space to a declaration's type without
+explicit address space attribute. Similar to other single-source C++-based GPU
+programming modes like OpenMP/CUDA/HIP, SYCL uses clang's "default" address
+space for types with no address space attributes. During the lowering to LLVM
+IR, the default address space is mapped to the SPIR generic address space.
+Declarations are assigned to the relevant memory region depending on their
+declaration context and pointers to them are cast to generic. This design has
+two important features: keeps the type system consistent with C++ on one hand
+and enable tools for emitting device code aligned with SPIR memory model (and
+other GPU targets).
+
+So inside a function, this variable declaration:
+
+```C++
+int var;
+```
+
+SYCL device compiler turns into
+
+```C++
+VarDecl  var 'int'
+```
+
+OpenCL compiler turn into
+
+```C++
+VarDecl  var '__private int'
+```
+
+Changing variable type has massive and destructive effect in C++. For instance
+this does not compile in C++ for OpenCL mode:
+
+```C++
+template<typename T1, typename T2>
+struct is_same {
+    static constexpr int value = 0;
+};
+
+template<typename T>
+struct is_same<T, T> {
+    static constexpr int value = 1;
+};
+
+void foo(int p) {
+    static_assert(is_same<decltype(p), int>::value, "int is not an int?"); // Fails: p is '__private int' != 'int'
+    static_assert(is_same<decltype(&p), int*>::value, "int* is not an int*?");  // Fails: p is '__private int*' != '__generic int*'
+}
+```
+
+To utilize existing clang's functionality, we re-use following OpenCL address
+space attributes in SYCL mode:
+
+| Address space attribute | SYCL address_space enumeration |
+|-------------------------|--------------------------------|
+| `__attribute__((opencl_global))` | global_space, constant_space |
+| `__attribute__((opencl_global_host))` | global_host_space |
+| `__attribute__((opencl_global_device))` | global_device_space |
+| `__attribute__((opencl_local))` | local_space |
+| `__attribute__((opencl_private))` | private_space |
+| `__attribute__((opencl_constant))` | N/A
+
+> **NOTE**: although SYCL device compiler supports
+`__attribute__((opencl_constant))`, the use of this attribute is limited within
+SYCL implementation. An OpenCL constant pointer can not be casted to a pointer
+with any other address space (including default).
+
 ### Compiler/Runtime interface
 
 ## SYCL Runtime architecture
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to