0

我问这个问题是为了明确这两个子句在嵌套数据环境中的行为。

当我第一次阅读 openACC API 时,我想如果我有以下代码:

#pragma acc create(a[0:20])
{
  #pragma acc pcopyin(a[0:20])
  {
    ...
  }
} 

第一个子句在加速器上分配必要的内存,然后pcopyin子句将数据从主机复制到加速器(不分配)。

现在阅读第 2 版 API 的草稿,我的理解是第二个pcopyin子句完全没有做任何事情,因为数据已经在加速器上分配,并且由于数据已经存在于加速器上,所以不应该进行分配或传输. 是对的吗?

当我用这种示例测试 CAPS 编译器时,我认为我获得了预期的行为。是不是因为 API 中的一些歧义?对于 v2,如果我想做这类事情,我应该用更新替换我的 copyin 子句吗?

4

1 回答 1

1

我认为您对 v1.0 规范的解释是错误的(很容易读错,您并不孤单)。“present_or_ something ”仅在变量列表不存在时才执行“ something ”。

因此,在您的情况下,“#pragma acc pcopyin(a[0:20])”不应该做任何事情(因为“创建”,当我使用 CAPS Compiler 3.3.2 检查此处的行为时会发生这种情况

这是我为检查行为而编写的示例(请将 present_or_copyin(a[0:20] 更改为 copyin(a[0:20] 以查看行为不同:我在“present”之间修改数组“a” " 和 "present_or_copyin",所以 present_or_copyin 或 "copyin" 导致不同的结果):

#include <stdio.h>

int main(void) {

    int a[20], b[20], i;

    for (i = 0; i < 20; i++) {
        a[i] = 42;
    }


    #pragma acc data, create(a[0:20]) copyout(b[0:20])
    {
    // will upload the array of 42
        #pragma acc data copyin(a[0:20])
        {
            // executed on the host, not seen on GPU
            for (i = 0; i < 20; i++) {
                a[i] = 666;
            }
            // has no effect: already present
            #pragma acc data present_or_copyin(a[0:20])
            {
                #pragma acc kernels, private(i)
                #pragma acc loop independent
                for (i = 0; i < 20; i++) {
                    a[i] += i;
                }
                #pragma acc kernels, private(i)
                #pragma acc loop independent
                for (i = 0; i < 20; i++) {
                    b[i] = a[i];
                }

            }
        }
    }
    for (i = 0; i < 20; i++) {
        printf("%d, ", b[i]);
    }
    printf("\n");

}

使用“present_or_copyin”这个示例程序写道:

42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,

使用“copyin”这个示例程序写道:

666、667、668、669、670、671、672、673、674、675、676、677、678、679、680、681、682、683、684、685、

于 2013-04-09T12:34:03.937 回答