SYCL 编译器和运行时架构设计

简介

本文档描述了 SYCL 编译器和运行时库的架构。更多详细信息可以在 外部文档 中找到,这些文档将在未来添加到 clang 文档中。

地址空间处理

SYCL 规范使用 C++ 包装类在加速器上表示指向不相交内存区域的指针,以便使用标准 C++ 工具链和 SYCL 编译器工具链进行编译。SYCL 2020 规范的第 3.8.2 节定义了 内存模型,第 4.7.7 节 - 地址空间类,第 5.9 节涵盖了 地址空间推断。SYCL 规范允许两种地址空间推断模式:“通用作为默认地址空间”(参见第 5.9.3 节)和“推断的地址空间”(参见第 5.9.4 节)。当前实现仅支持“通用作为默认地址空间”模式。

SYCL 从 OpenCL 中借鉴了其内存模型,但是 SYCL 不会像 OpenCL C v3.0 6.7.8 中详细说明的那样执行地址空间限定词推断。

默认地址空间是“通用内存”,它是一个虚拟地址空间,与全局、局部和私有地址空间重叠。SYCL 模式支持以下转换

  • 从默认地址空间到/从带地址空间属性的类型进行显式转换

  • 从带地址空间属性的类型到默认地址空间进行隐式转换

  • 从全局地址空间到/从 __attribute__((opencl_global_device))__attribute__((opencl_global_host)) 带地址空间属性的类型进行显式转换

  • __attribute__((opencl_global_device))__attribute__((opencl_global_host)) 带地址空间属性的类型到全局地址空间进行隐式转换

所有命名地址空间都是不相交的,并且是默认地址空间的子集。

SPIR 目标在全局地址空间中分配 SYCL 命名空间作用域变量。

指向默认地址空间的指针应该降低为指向通用地址空间的指针(或为了重用更通用的术语,降低为平坦指针)。但是,根据分配上下文,非指针类型的默认地址空间将分配给特定地址空间。这在 通用地址空间推断规则 部分进行了描述。

这也与 CUDA 的行为一致(小型示例)。

multi_ptr 类实现示例

// 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

根据编译器模式,multi_ptr 将在其内部数据上添加地址空间属性或不添加。

为了利用 clang 的现有功能,我们对指针重用了以下 OpenCL 地址空间属性

地址空间属性

SYCL address_space 枚举

__attribute__((opencl_global))

global_space, constant_space

__attribute__((opencl_global_device))

global_space

__attribute__((opencl_global_host))

global_space

__attribute__((opencl_local))

local_space

__attribute__((opencl_private))

private_space

//TODO: add support for __attribute__((opencl_global_host)) and __attribute__((opencl_global_device)).