Как переменная в памяти устройства используется внешней функцией?

В этом коде:

#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]) от 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 работает своим волшебством?

1

Решение

Вас снова смущает ваш собственный синтаксис и то, что вам уже было указано.

value в intfun это не то же самое, что value что ты сделал copyin(value) в 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 непосредственно и добавив его в present Статья является законной и функциональной.

4

Другие решения


По вопросам рекламы [email protected]