问题
In this code:
#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;
}
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
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?
回答1:
You're getting confused again by your own syntax and over what was pointed out to you already.
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.)
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.
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
$
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.
来源:https://stackoverflow.com/questions/26003954/how-is-variable-in-device-memory-used-by-external-function