OpenMP 支持

Clang 完全支持 OpenMP 4.5,几乎支持 5.0 的所有内容,以及 5.1/2 的大部分内容。Clang 支持卸载到 X86_64、AArch64、PPC64[LE]、NVIDIA GPU(所有型号)和 AMD GPU(所有型号)。

此外,LLVM OpenMP 运行时 libomp 在 Linux、Windows 和 macOS 上的 x86、x86_64、AArch64 和 PPC64 上支持 OpenMP 工具接口 (OMPT)。OMPT 也支持 NVIDIA 和 AMD GPU。

有关 OpenMP 5.0 和 5.1 支持功能列表,请参见 OpenMP 实现细节OpenMP 51 实现细节

总体改进

  • 新的折叠子句方案,以避免昂贵的余数运算。通过使用乘法和加法替换昂贵的余数运算,在使用折叠子句折叠循环嵌套后计算循环索引变量。

  • 在循环嵌套上使用折叠子句时,默认行为是自动将循环计数器的表示扩展到 64 位,用于编译时不知道折叠循环的大小的情况。为了防止这种保守的选择,并使用最多 32 位,请使用 -fopenmp-optimistic-collapse 编译你的程序。

GPU 设备支持

数据共享模式

Clang 支持 Cuda 设备的两种数据共享模型:GenericCuda 模式。默认模式是 GenericCuda 模式可以提供额外的性能,并且可以使用 -fopenmp-cuda-mode 标志激活。在 Generic 模式中,可以在并行区域中共享的所有局部变量都存储在全局内存中。在 Cuda 模式中,局部变量在线程之间不共享,用户有责任在并行区域中的线程之间共享所需的数据。通常,优化器能够将 Generic 模式的成本降低到 Cuda 模式级别,但该标志以及其他假设标志可以用于调整。

Cuda 设备不支持或有限支持的功能

  • 不支持取消构造。

  • 不支持 Doacross 循环嵌套。

  • 仅支持平凡类型的用户定义的归约。

  • 嵌套并行性:内部并行区域按顺序执行。

  • 支持 OpenMP 目标区域的调试信息,但有时可能需要手动指定要检查的变量的地址类。在某些情况下,局部变量实际上是在全局内存中分配的,但调试信息可能不知道它。

OpenMP 5.0 实现细节

下表提供了 OpenMP 5.0 各种功能及其实现状态的快速概述。有关更多信息或如果你想帮助实现,请在 Discourse 论坛(运行时 - OpenMP 类别) 上发布。

类别

功能

状态

审阅

循环

在规范循环形式中支持 !=

已完成

D54441

循环

#pragma omp loop (指令)

部分完成

D145823 (组合形式)

循环

#pragma omp loop bind

正在进行

D144634 (需要审阅)

循环

折叠不完全嵌套循环

已完成

循环

折叠非矩形嵌套循环

已完成

循环

C++ 范围基础 for 循环

已完成

循环

子句:SIMD 指令的 if

已完成

循环

包含扫描(匹配 C++17 PSTL)

已完成

内存管理

内存分配器

已完成

r341687,r357929

内存管理

分配指令和分配子句

已完成

r355614,r335952

OMPD

OMPD 接口

已完成

https://reviews.llvm.org/D99914 (仅支持 HOST(CPU) 和 Linux

OMPT

OMPT 接口(回调支持)

已完成

线程亲和性

线程亲和性

已完成

任务

taskloop 归约

已完成

任务

任务亲和性

不在上游

https://github.com/jklinkenberg/openmp/tree/task-affinity

任务

子句:依赖于 taskwait 构造

已完成

D113540 (仅常规代码生成)

任务

依赖对象和可分离任务

已完成

任务

任务的 mutexinoutset 依赖类型

已完成

D53380,D57576

任务

组合 taskloop 构造

已完成

任务

master taskloop

已完成

任务

parallel master taskloop

已完成

任务

master taskloop simd

已完成

任务

parallel master taskloop simd

已完成

SIMD

SIMD 代码内的原子和 simd 构造

已完成

SIMD

SIMD 非临时

已完成

设备

从初始化程序推断目标函数

正在进行

设备

从初始化程序推断目标变量

已完成

D146418

设备

OMP_TARGET_OFFLOAD 环境变量

已完成

D50522

设备

支持完整的 'defaultmap' 功能

已完成

D69204

设备

设备特定函数

已完成

设备

子句:device_type

已完成

设备

子句:扩展设备

已完成

设备

子句:uses_allocators 子句

已完成

设备

子句:in_reduction

正在进行

r308768

设备

omp_get_device_num()

已完成

D54342,D128347

设备

引用的结构映射

未认领

设备

嵌套目标声明

已完成

D51378

设备

隐式映射 'this' (this[:1])

已完成

D55982

设备

允许访问引用计数(omp_target_is_present)

已完成

设备

需要指令

已完成

设备

子句:unified_shared_memory

已完成

D52625,D52359

设备

子句:unified_address

部分完成

设备

子句:reverse_offload

部分完成

D52780,D155003

设备

子句:atomic_default_mem_order

已完成

D53513

设备

子句:dynamic_allocators

未认领部分

D53079

设备

用户定义的映射器

已完成

D56326,D58638,D58523,D58074,D60972,D59474

设备

使用隐式映射器映射数组节

已完成

https://github.com/llvm/llvm-project/pull/101101

设备

映射 lambda 表达式

已完成

D51107

设备

子句:use_device_addr 用于目标数据

已完成

设备

支持 map 子句上的 close 修饰符

已完成

D55719,D55892

设备

主机设备上的 teams 构造

已完成

r371553

设备

支持目标更新的非连续数组节

已完成

设备

指针附件

已完成

原子

原子构造的提示

已完成

D51233

基础语言

C11 支持

已完成

基础语言

C++11/14/17 支持

已完成

基础语言

lambda 支持

已完成

其他

数组整形

已完成

D74144

其他

库关闭(omp_pause_resource[_all])

已完成

D55078

其他

元指令

大部分已完成

D91944

其他

lastprivate 子句的条件修饰符

已完成

其他

迭代器和多依赖

已完成

其他

depobj 指令和 depobj 依赖类型

已完成

其他

用户定义的函数变体

已完成.

D67294, D64095, D71847, D71830, D109635

其他

基于指针/指向指针的引用的数组归约

已完成

其他

防止在子句中定义新类型

已完成

内存模型

内存模型更新(seq_cst、acq_rel、release、acquire 等)

已完成

OpenMP 5.1 实现细节

下表提供了 OpenMP 5.1 各种功能及其实现状态的快速概述。有关更多信息或如果你想帮助实现,请在 Discourse 论坛(运行时 - OpenMP 类别) 上发布。

类别

功能

状态

审阅

原子

原子构造上的 'compare' 子句

已完成

D120290, D120007, D118632, D120200, D116261, D118547, D116637

原子

原子构造上的 'fail' 子句

正在进行

D123235 (正在进行)

基础语言

C++ 属性说明符语法

已完成

D105648

设备

'present' map 类型修饰符

已完成

D83061, D83062, D84422

设备

'present' 运动修饰符

已完成

D84711, D84712

设备

'present' 在 defaultmap 子句中

已完成

D92427

设备

基于 'present' 修饰符的 map 子句重新排序

未认领

设备

设备特定环境变量

未认领

设备

omp_target_is_accessible 例程

未认领

设备

omp_get_mapped_ptr 例程

已完成

D141545

设备

新的异步目标内存复制例程

已完成

D136103

设备

目标构造上的 thread_limit 子句

部分完成

D141540 (卸载)、D152054 (主机,正在进行)

设备

目标构造上的 has_device_addr 子句

未认领

设备

map 子句或 motion 子句中的迭代器

未认领

设备

declare target 指令上的 indirect 子句

未认领

设备

允许在设备上对映射对象的虚拟函数调用

部分完成

设备

互操作构造

部分完成

解析/语义完成:D98558、D98834、D98815

设备

用于查询互操作属性的各种例程

部分完成

D106674

循环

循环平铺变换

已完成

D76342

循环

循环展开变换

已完成

D99459

循环

'order' 子句中的 'reproducible'/'unconstrained' 修饰符

部分完成

D127855

内存管理

分配指令和子句的对齐方式

已完成

D115683

内存管理

新的内存管理例程

未认领

内存管理

对 omp_alloctrait_key 枚举的更改

未认领

内存模型

flush 构造上的 seq_cst 子句

未认领

其他

'omp_all_memory' 关键字及其在 'depend' 子句中的使用

已完成

D125828、D126321

其他

错误指令

已完成

D139166

其他

范围构造

已完成

D157933、https://github.com/llvm/llvm-project/pull/109197

其他

用于控制和查询团队区域的例程

部分完成

D95003 (仅 libomp)

其他

对 ompt_scope_endpoint_t 枚举的更改

未认领

其他

omp_display_env 例程

已完成

D74956

其他

扩展的 OMP_PLACES 语法

未认领

其他

OMP_NUM_TEAMS 和 OMP_TEAMS_THREAD_LIMIT 环境变量

已完成

D138769

其他

上下文说明符中的 'target_device' 选择器

正在进行

其他

begin/end 声明变体

已完成

D71179

其他

调度构造和函数变体参数调整

正在进行

D99537、D99679

其他

假设指令

正在进行

其他

假设指令

已完成

其他

无指令

已完成

D123286

其他

掩码构造和相关的组合构造

正在进行

D99995、D100514

其他

default(firstprivate) & default(private)

已完成

D75591 (firstprivate)、D125912 (private)

其他

弃用 master 构造

未认领

OMPT

在 ompt_sync_region_t 枚举中添加了新的屏障类型

未认领

OMPT

在 ompt_target_data_op_t 枚举中添加了异步数据传输

未认领

OMPT

在 ompt_state_t 枚举中添加了新的屏障状态值

未认领

OMPT

用于外部监控接口的新的 'emi' 回调

已完成

OMPT

设备跟踪接口

未认领

任务

taskloop 构造的 'strict' 修饰符

未认领

任务

depend 子句中的 inoutset

已完成

D97085、D118383

任务

taskwait 上的 nowait 子句

部分完成

解析/语义完成:D131830、D141531

OpenMP 扩展

下表简要概述了各种 OpenMP 扩展及其实现状态。这些扩展目前未在任何标准中定义,因此提供了指向相关 LLVM 文档的链接。随着这些扩展的成熟,将考虑将其纳入标准化。请在 Discourse 论坛 (运行时 - OpenMP 类别) 上发布您的反馈。

类别

功能

状态

审阅

原子扩展

‘atomic’ 严格嵌套在 ‘teams’ 中

已建模

D126323

设备扩展

‘ompx_hold’ 映射类型修饰符

已建模

D106509, D106510

设备扩展

‘target teams’ 结构上的 ‘ompx_bare’ 子句

已建模

#66844, #70612

设备扩展

‘target teams ompx_bare’ 结构上的多维 ‘num_teams’ 和 ‘thread_limit’ 子句

部分完成

#99732, #101407, #102715