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