bader updated this revision to Diff 334420.
bader marked 24 inline comments as done.
bader added a comment.

Applied code review suggestions

Resolved merge conflicts with D99190 <https://reviews.llvm.org/D99190>.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D99488/new/

https://reviews.llvm.org/D99488

Files:
  clang/docs/SYCLSupport.md

Index: clang/docs/SYCLSupport.md
===================================================================
--- clang/docs/SYCLSupport.md
+++ clang/docs/SYCLSupport.md
@@ -192,6 +192,124 @@
 document
 [SYCL Kernel Parameter Handling and Array Support](https://github.com/intel/llvm/blob/sycl/sycl/doc/KernelParameterPassing.md).
 
+### Address space handling
+
+The SYCL specification represents pointers to disjoint memory regions using C++
+wrapper classes on an accelerator to enable compilation with a standard C++
+toolchain and a 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 covers [address space deduction](https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#_address_space_deduction).
+
+The main address space semantic difference between SYCL and OpenCL is that SYCL
+doesn't perform the address space qualifier inference detailed in
+[OpenCL C v3.0 6.7.8](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_C.html#addr-spaces-inference).
+
+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
+explicit address space attribute. This design has two important features: it
+keeps the type system consistent with C++ 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;
+```
+
+The SYCL device compiler turns into:
+
+```C++
+VarDecl  var 'int'
+```
+
+while the OpenCL compiler turns it into:
+
+```C++
+VarDecl  var '__private int'
+```
+
+Changing the type of a variable can have observable effects in C++. For example,
+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*'
+}
+```
+
+`multi_ptr` class implementation example:
+
+``` 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 its internal
+data with the address space attribute or not.
+
+To utilize clang's existing functionality, we reuse the following OpenCL address
+space attributes for pointers:
+
+| Address space attribute | SYCL address_space enumeration |
+|-------------------------|--------------------------------|
+| `__attribute__((opencl_global))` | global_space, constant_space |
+| `__attribute__((opencl_local))` | local_space |
+| `__attribute__((opencl_private))` | private_space |
+
+    TODO: add support for `__attribute__((opencl_global_host))` and
+    `__attribute__((opencl_global_device))`.
+
+The default address space is "generic-memory", which is a virtual address space
+that overlaps the global, local, and private address spaces. SYCL mode enables
+conversion to/from the default address space from/to the address
+space-attributed type.
+
+The SPIR target allocates SYCL namespace scope variables in the global address
+space.
+
+Pointers to Default address space should get lowered into a pointer to a generic
+address space (or flat to reuse more general terminology). But depending on the
+allocation context, the default address space of a non-pointer type is assigned
+to a specific address space. This is described in
+https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#subsec:commonAddressSpace.
+
+This is also in line with the behaviour of CUDA (small example
+https://godbolt.org/z/veqTfo9PK).
+
 [//]: # (TODO: move KernelParameterPassing.md to llvm-project)
 
 [1]: https://github.com/intel/llvm/blob/sycl/sycl/doc/CompilerAndRuntimeDesign.md
\ No newline at end of file
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to