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 枚举 |
---|---|
|
global_space, constant_space |
|
global_space |
|
global_space |
|
local_space |
|
private_space |
//TODO: add support for __attribute__((opencl_global_host)) and __attribute__((opencl_global_device)).