OpenMP 目标任务减少

OpenMP Target Task reduction

我正在使用 OpenMP 目标卸载将一些嵌套循环卸载到 gpu。我正在使用 nowait 将其调整为异步。这使它成为一项任务。使用相同的输入值,结果与未卸载时的结果不同(例如 cpu:sum=0.99,卸载 sum=0.5)。 删除 nowait 子句时效果很好。所以我认为问题是它变成了一个 OpenMP 任务,我正在努力把它做好。

#pragma omp target teams distribute parallel for reduction( +: sum) collapse(2) nowait depend(in: a, b) depend(out: sum)
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {   
            double c = 0;
            
            for (int k = 0; k < n; k++)
            {
                c += /* some computation */
            }
            
            sum += fabs(c); 
        }
    }

OpenMP 5.2 specification 状态:

The target construct generates a target task. The generated task region encloses the target region. If a depend clause is present, it is associated with the target task. [...]. If the nowait clause is present, execution of the target task may be deferred. If the nowait clause is not present, the target task is an included task.

这意味着您的代码在任务中执行,可能延迟执行(使用nowait)。因此,在最坏的情况下,它可以在并行结束时执行,但总是在等待目标任务的所有相关任务和 taskwait 指令之前执行(或包含类似行为的指令,如 taskgroup ).因此,您无需在此时间段内修改工作数组(或释放它们)。如果这样做,则行为未定义。

您要特别注意代码中同步点任务依赖的正确性(我们无法检查使用当前提供的不完整代码)。