код выполняется, но функция gpu не будет выполнена - PullRequest
1 голос
/ 18 июня 2019

Я получил две функции: Функция add_cpu работает нормально, а функция add_gpu - нет.

Я попытался проверить параметры сумм в программном обеспечении моего драйвера графического процессора и снова и снова читать мой код. Я попробовал точно такой же код на другой машине, и он работал нормально. Результат checkError на текущей машине равен 1, чего не должно быть. И результат checkError на моем ноутбуке равен 0, что правильно. У кого-нибудь есть какие-либо предположения о том, что проблема с графической картой или системой? Я понятия не имею, в чем здесь проблема. Я пропустил какой-то вариант?

#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <iostream>
#include <math.h>

#define out std::cout <<
#define end << std::endl

__global__
void add_gpu( int n, float* x, float* y ) {
    for ( int i = 0; i < n; i++ ) y[i] = x[i] + y[i];
}

void add_cpu( int n, float* x, float* y ) {
    for ( int i = 0; i < n; i++ ) y[i] = x[i] + y[i];
}

void init( int n, float* x, float* y ) {
    for ( int i = 0; i < n; i++ ) {
        x[i] = 1.0f;
        y[i] = 2.0f;
    }
}

int checkError( int n, float f, float* y ) {
    float c = 0.0f;
    for ( int i = 0; i < n; i++ ) c = fmax( c, fabs( y[i] - f ) );
    return c;
}

void print( int n, float* obj, char* str = "obj: " ) {
    out str << obj[0];
    for ( int i = 1; i < n; i++ ) out ", " << obj[i];
    out "" end;
}

int main( ) {
    int n = 1 << 5;
    float* x, * y;
    float error = 0.0f;

    cudaMallocManaged( &x, n * sizeof( float ) );
    cudaMallocManaged( &y, n * sizeof( float ) );

    init( n, x, y );
    print( n, x, "x" );
    print( n, y, "y" );
    add_gpu<< <1, 1 >> > ( n, x, y );
    //add_cpu(n, x, y);
    cudaDeviceSynchronize( );
    print( n, y, "y" );

    error = checkError( n, 3.0f, y );
    out "error: " << error end;

    cudaFree( x );
    cudaFree( y );

    return 0;
}

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Я не вижу точно, где проблема, но для ее устранения необходимо проверить ошибки cuda. ​​

Большинство функций cuda возвращают статус cuda.Вы можете использовать небольшую функцию-обертку, например, для проверки ошибок

checkCudaError(const cudaError_t error) {
    if (error != cudaSuccess) {
        std::cout << "Cuda error: " << cudaGetErrorString(error) << std::endl;
        // maybe do something else
    }
}

и вызова функции, например cudaMallocManaged () , таким образом

checkCudaError(cudaMallocManaged(&x, n * sizeof(float));

Для всех операцийкоторые выполняются на устройстве (например, в пользовательских ядрах), вы должны запустить ядро ​​и после этого вызвать

cudaGetLastError()

и, возможно, также использовать checkCudaError ()

checkCudaError(cudaGetLastError())

Обратите внимание, что cudaGetLastError () всегда будет возвращать ошибку, если в какой-то момент произошла ошибка, и поэтому вам нужно найти место, где произошла первая ошибка.Вот почему вы должны проверять ошибку cuda каждый раз, когда графический процессор используется каким-либо образом.

0 голосов
/ 18 июня 2019

https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__MEMORY.html#group__CUDART__MEMORY_1gc263dbe6574220cc776b45438fc351e8

Не копируя данные на устройство, ваш графический процессор не знает эти данные и не копируя их обратно, ваш хост не знает результатов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...