创建后的pcopyin

时间:2013-04-08 10:09:12

标签: openacc

在嵌套数据环境中,我要问这个问题要清楚这两个子句的行为。

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

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

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

现在阅读API的v2的草案,我理解的是第二个pcopyin子句完全没有做任何因为数据已经在加速器上分配,并且由于数据已经存在于加速器上,不应进行分配或转移。是吗?

当我用这种示例测试CAPS编译器时,我想我已经获得了我期望的行为。是不是因为API有些含糊不清?对于v2,如果我想做这种事情,我应该用更新来替换我的copyin子句吗?

1 个答案:

答案 0 :(得分:1)

我认为你已经解释了v1.0 Spec的错误(很容易读错了,你并不孤单)。 只有当变量列表不存在时,“present_or_ ”才会执行“某事”。

所以在你的情况下,“#pragma acc pcopyin(a [0:20])”不应该做任何事情(因为“创建”,当我用CAPS编译器3.3.2检查这里的行为时会发生什么

以下是我为检查行为而编写的示例(请将present_or_copyin(a [0:20]更改为copyin(a [0:20])以查看行为不同:我修改数组之间的“a” “present”和“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,