外部函数使用的设备内存中的变量如何? [英] How is variable in device memory used by external function?
问题描述
在此代码中:
#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],value)
中替换 present(variable [:1])
intfun
pragma,我得到以下运行时错误:
How is int value
recognized to be on device memory in intfun
? If I replace present(variable[:1])
by present(variable[:1],value)
in the intfun
pragma, I get the following runtime error:
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
只在输入数据
指令中复制一次,即它不会在并行
指令 intfun
。 OpenACC是如何工作的?
I don't understand why specifying that value
is present
leads to the failure above. I checked with NVVP that value
is only copied once in the enter data
directive, i.e. it is not copied again in the parallel
directive in intfun
. How does OpenACC work its magic?
推荐答案
你会被你自己的语法和你指出的已经。
You're getting confused again by your own syntax and over what was pointed out to you already.
在
code> main 中的 intfun
中的值 copyin(value)
函数调用通过值传递 value
,这意味着它会对其进行复制。因此,将它添加到 present()
语句没有意义,因为它在设备上不存在。编译器必须复制它。(当你根本没有提到它时,编译器会自动识别它是需要的,并为你复制它。)
value
in intfun
is not the same as value
that you did copyin(value)
in main
. The function call passes value
by value, meaning it makes a copy of it. Therefore adding it to a present()
clause makes no sense because it is not present on the device. The compiler must copy it in. (And when you don't mention it at all, the compiler automatically recognizes that it is needed and copies it in for you.)
设备上存在的项目是 main
-scope变量 value
是 intfun
不使用。给所有的变量同名可能不会帮助你理解这一点。
The item that is present on the device is the main
-scope variable value
, which is not used by intfun
. Giving all your variables the same name is probably not helping you understand this.
为了演示这个,让我们通过 value
而非 :
To demonstrate this, let's pass value
by reference instead of by 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
,并将它添加到 present
条款是合法和有效的。
Now the main-scope variable value
is on the device, the compiler knows it, it will be used by intfun
directly, and adding it to the present
clause is legal and functional.
这篇关于外部函数使用的设备内存中的变量如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!