В этом коде:
#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 работает своим волшебством?
Вас снова смущает ваш собственный синтаксис и то, что вам уже было указано.
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
Статья является законной и функциональной.