在此代码中:
#include <iostream>
void intfun(int * variable, int value){
#pragma acc parallel present(variable[:1]) num_gangs(1) num_workers(1)
{
*variable = value;
}
}
int main(){
int var, value = 29;
#pragma acc enter data create(var) copyin(value)
intfun(&var,value);
#pragma acc exit data copyout(var) delete(value)
std::cout << var << std::endl;
}
int value
如何识别intfun
设备内存?如果我在present(variable[:1])
pragma中将present(variable[:1],value)
替换为intfun
,则会出现以下运行时错误:
FATAL ERROR: data in PRESENT clause was not found on device 1: name=_43144_33_value
file:/opt/pgi/linux86-64/14.9/include/CC/iostream intfun__FPii line:5
Present table dump for device[1]: NVIDIA Tesla GPU 1, compute capability 3.5
host:0x7fffc11faa28 device:0x2303f20200 size:4 presentcount:1 line:14 name:_43152_14_value
host:0x7fffc11faa34 device:0x2303f20000 size:4 presentcount:2 line:14 name:_43152_9_var
我不明白为什么指定value
present
会导致上述失败。我查看了NVVP,value
仅在enter data
指令中复制了一次,即它不会再次复制到parallel
中的intfun
指令中。 OpenACC如何发挥其神奇作用?
答案 0 :(得分:4)
您已经通过自己的语法和已经指出的内容再次感到困惑。
value
中的{p> intfun
与您在value
中copyin(value)
的{{1}}不同。函数调用按值传递main
,这意味着它会生成副本。因此,将其添加到value
子句没有任何意义,因为它在设备上不存在。编译器必须将其复制。(当你完全没有提到它时,编译器会自动识别它是否需要并为你复制它。)
设备上存在的项目是present()
- 范围变量main
,value
未使用 }。给所有变量赋予相同的名称可能无助于您理解这一点。
为了证明这一点,让我们通过引用而不是按值传递intfun
:
value
现在主要范围变量$ cat main8.cpp
#include <iostream>
void intfun(int * variable, int &value){
#pragma acc parallel present(variable[:1],value) num_gangs(1) num_workers(1)
{
*variable = value;
}
}
int main(){
int var, value = 29;
#pragma acc enter data create(var) copyin(value)
intfun(&var,value);
#pragma acc exit data copyout(var) delete(value)
std::cout << var << std::endl;
}
[user2@dc12 misc]$ pgcpp -acc -Minfo main8.cpp
intfun(int *, int &):
5, Generating present(variable[:1])
Generating present(value[:])
Accelerator kernel generated
Generating Tesla code
main:
14, Generating enter data copyin(value)
Generating enter data create(var)
17, Generating exit data delete(value)
Generating exit data copyout(var)
$ ./a.out
29
$
在设备上,编译器知道它,它将由value
直接使用,并将其添加到intfun
子句是合法的,功能