OpenACC Управление 2D перемещением данных

Как обменять двухмерный элемент между центральным процессором и графическим процессором?
Я пытался использовать этот 2d элемент как w [0: (n_hidden * i) -1], но обратная связь с компилятором говорит мне, что что-то не так

Это функция алгоритма RBM:

double RBM::propdown(int *h, int i, double b) {
#pragma acc data region \
copyin(w[0:(n_hidden*i)-1],h[0:n_hidden],b) create(pre_sigmoid_activation)
double pre_sigmoid_activation = 0.0;
#pragma acc parallel loop reduction(+:pre_sigmoid_activation)
for(int j=0; j<n_hidden; j++) {
pre_sigmoid_activation += W[j][i] * h[j];
}
pre_sigmoid_activation += b;
return sigmoid(pre_sigmoid_activation);
#pragma acc exit data \
delete ( pre_sigmoid_activation)
}

1

Решение

Не нужно линеаризовать массив. Просто используйте несколько скобок.

#pragma acc data copyin(W[0:n_hidden][0:N])

Я вижу и ряд других вопросов.

В директиве data нет предложения «region». Вы можете путать это с предложением «ввод данных» или моделью PGI Accelerator, которая была основой для OpenACC.

Нет необходимости помещать «b» в предложение data, поскольку оно фактически не используется в области вычислений. Кроме того, помещая его в предложение data, вы делаете «b» глобальной ссылкой на устройство. Лучше оставить скаляры, доступные только для чтения, из предложений данных, чтобы значение передавалось в качестве аргумента, а не для его получения из глобальной памяти.

Опять же, поместив скалярную переменную «pre_sigmoid_activation» в предложение данных, вы создали глобальную переменную. Здесь результат сокращения будет сохранен в этой переменной устройства и не будет автоматически обновляться на хосте. Для этого вам нужно добавить директиву «update». Еще лучше, просто удалите его из предложения данных, и результат сокращения будет обновлен до переменной хоста.

У вас есть непревзойденная директива «выходных данных» (должна быть соответствующая директива «вводить данные»). Кроме того, директива помещается после оператора return, поэтому никогда не будет выполняться, оставляя данные на устройстве.

Наконец, поскольку C ++ чувствителен к регистру, убедитесь, что имена переменных в директивах OpenACC соответствуют фактическим именам переменных. т.е. «W» вместо «w».

Вот как я бы написал цикл. Обратите внимание, что я не знаю размер второго измерения «W», поэтому просто использовал «N». Пожалуйста, обновите соответственно.

#pragma acc data copyin(W[0:n_hidden][0:N],h[0:n_hidden])
{
#pragma acc parallel loop reduction(+:pre_sigmoid_activation)
for(int j=0; j<n_hidden; j++) {
pre_sigmoid_activation += W[j][i] * h[j];
}
}
2

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

Других решений пока нет …

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