Как выполнить основные операции (+ - * /) на графическом процессоре и сохранить результат на нем - PullRequest
0 голосов
/ 09 мая 2019

У меня есть следующая строка кода, gamma - это переменная процессора, которую мне нужно будет скопировать в GPU.gamma_x и delta также сохраняются в CPU.Есть ли способ, которым я могу выполнить следующую строку и сохранить его результат непосредственно на GPU?Таким образом, в основном, хост gamma, gamma_x и delta на GPU и получить вывод следующей строки на GPU.Это значительно ускорило бы мой код для строк после.Я пробовал с magma_dcopy, но до сих пор не смог найти способ заставить его работать, потому что вывод magma_ddot - удвоение ЦП.

gamma = -(gamma_x[i+1] + magma_ddot(i,&d_gamma_x[1],1,&(d_l2)[1],1, queue))/delta;

1 Ответ

1 голос
/ 10 мая 2019

Очень краткий ответ - нет, вы не можете этого сделать, или, по крайней мере, если вы используете magma_ddot.

Однако magma_ddot сама по себе является лишь очень тонкой оболочкой для cublasDdot, и функция cublas полностью поддерживает сохранение результата операции в памяти графического процессора, а не его возврат вhost.

В теории вы можете сделать что-то вроде этого:

// before the apparent loop you have not shown us:
double* dotresult;
cudaMalloc(&dotresult, sizeof(double));

for (int i=....) { 
    // ...

    // magma_ddot(i,&d_gamma_x[1],1,&(d_l2)[1],1, queue);
    cublasSetPointerMode( queue->cublas_handle(), CUBLAS_POINTER_MODE_DEVICE);
    cublasDdot(queue->cublas_handle(), i, &d_gamma_x[1], 1, &(d_l2)[1], 1, &dotresult);
    cudaDeviceSynchronize();
    cublasSetPointerMode( queue->cublas_handle(), CUBLAS_POINTER_MODE_HOST);

    // Now dotresult holds the magma_ddot result in device memory

    // ...

}

Обратите внимание, что магма может взорваться в зависимости от того, как вы ее используете, потому что магма используетВнутренние CUBLAS и то, как состояние CUBLAS и асинхронные операции обрабатываются внутри Magma, полностью не документированы.Сказав это, если вы осторожны, все должно быть в порядке.

Чтобы затем выполнить ваши вычисления, либо напишите очень простое ядро ​​и запустите его с одним потоком, либо, возможно, используйте простой вызов thrust с лямбда-выражениемв зависимости от ваших предпочтений.Я оставляю это как упражнение для читателя.

...