Revert "[clang][extract-api] Use relative includes"
[llvm-project.git] / clang / docs / SYCLSupport.rst
blob6b529e3eb012784cdaa5bccb6b8638201cceb3a6
1 =============================================
2 SYCL Compiler and Runtime architecture design
3 =============================================
5 .. contents::
6    :local:
8 Introduction
9 ============
11 This document describes the architecture of the SYCL compiler and runtime
12 library. More details are provided in
13 `external document <https://github.com/intel/llvm/blob/sycl/sycl/doc/CompilerAndRuntimeDesign.md>`_\ ,
14 which are going to be added to clang documentation in the future.
16 Address space handling
17 ======================
19 The SYCL specification represents pointers to disjoint memory regions using C++
20 wrapper classes on an accelerator to enable compilation with a standard C++
21 toolchain and a SYCL compiler toolchain. Section 3.8.2 of SYCL 2020
22 specification defines
23 `memory model <https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#_sycl_device_memory_model>`_\ ,
24 section 4.7.7 - `address space classes <https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#_address_space_classes>`_
25 and section 5.9 covers `address space deduction <https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#_address_space_deduction>`_.
26 The SYCL specification allows two modes of address space deduction: "generic as
27 default address space" (see section 5.9.3) and "inferred address space" (see
28 section 5.9.4). Current implementation supports only "generic as default address
29 space" mode.
31 SYCL borrows its memory model from OpenCL however SYCL doesn't perform
32 the address space qualifier inference as detailed in
33 `OpenCL C v3.0 6.7.8 <https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_C.html#addr-spaces-inference>`_.
35 The default address space is "generic-memory", which is a virtual address space
36 that overlaps the global, local, and private address spaces. SYCL mode enables
37 following conversions:
39 - explicit conversions to/from the default address space from/to the address
40   space-attributed type
41 - implicit conversions from the address space-attributed type to the default
42   address space
43 - explicit conversions to/from the global address space from/to the
44   ``__attribute__((opencl_global_device))`` or
45   ``__attribute__((opencl_global_host))`` address space-attributed type
46 - implicit conversions from the ``__attribute__((opencl_global_device))`` or
47   ``__attribute__((opencl_global_host))`` address space-attributed type to the
48   global address space
50 All named address spaces are disjoint and sub-sets of default address space.
52 The SPIR target allocates SYCL namespace scope variables in the global address
53 space.
55 Pointers to default address space should get lowered into a pointer to a generic
56 address space (or flat to reuse more general terminology). But depending on the
57 allocation context, the default address space of a non-pointer type is assigned
58 to a specific address space. This is described in
59 `common address space deduction rules <https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#subsec:commonAddressSpace>`_
60 section.
62 This is also in line with the behaviour of CUDA (`small example
63 <https://godbolt.org/z/veqTfo9PK>`_).
65 ``multi_ptr`` class implementation example:
67 .. code-block:: C++
69    // check that SYCL mode is ON and we can use non-standard decorations
70    #if defined(__SYCL_DEVICE_ONLY__)
71    // GPU/accelerator implementation
72    template <typename T, address_space AS> class multi_ptr {
73      // DecoratedType applies corresponding address space attribute to the type T
74      // DecoratedType<T, global_space>::type == "__attribute__((opencl_global)) T"
75      // See sycl/include/CL/sycl/access/access.hpp for more details
76      using pointer_t = typename DecoratedType<T, AS>::type *;
78      pointer_t m_Pointer;
79      public:
80      pointer_t get() { return m_Pointer; }
81      T& operator* () { return *reinterpret_cast<T*>(m_Pointer); }
82    }
83    #else
84    // CPU/host implementation
85    template <typename T, address_space AS> class multi_ptr {
86      T *m_Pointer; // regular undecorated pointer
87      public:
88      T *get() { return m_Pointer; }
89      T& operator* () { return *m_Pointer; }
90    }
91    #endif
93 Depending on the compiler mode, ``multi_ptr`` will either decorate its internal
94 data with the address space attribute or not.
96 To utilize clang's existing functionality, we reuse the following OpenCL address
97 space attributes for pointers:
99 .. list-table::
100    :header-rows: 1
102    * - Address space attribute
103      - SYCL address_space enumeration
104    * - ``__attribute__((opencl_global))``
105      - global_space, constant_space
106    * - ``__attribute__((opencl_global_device))``
107      - global_space
108    * - ``__attribute__((opencl_global_host))``
109      - global_space
110    * - ``__attribute__((opencl_local))``
111      - local_space
112    * - ``__attribute__((opencl_private))``
113      - private_space
116 .. code-block:: C++
118     //TODO: add support for __attribute__((opencl_global_host)) and __attribute__((opencl_global_device)).