How is variable in device memory used by external function?

荒凉一梦 提交于 2019-12-11 05:38:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!