Ошибка Cuda (209): cudaLaunchKernel вернул cudaErrorNoKernelImageForDevice - PullRequest
0 голосов
/ 14 июля 2020

Операционная система: CentOS 7 Cuda Toolkit Версия: 11.0

Информация о драйвере и графическом процессоре Nvidia:

NVIDIA-SMI 450.51.05 Версия драйвера: 450.51.05 Версия CUDA: 11.0 Графический процессор: Quadro M2000M

снимок экрана с подробностями nvidia-smi

Я новичок в программировании cuda, поэтому очень приветствую любое руководство. У меня очень простая программа cuda c ++, которая вычисляет сумму двух массивов в объединенной памяти на GPU. Однако похоже, что ядро ​​не запускается из-за ошибки cudaErrorNoKernelImageForDevice. Код ниже:

using namespace std;
#include <iostream>
#include <math.h>
#include <cuda_runtime_api.h>
__global__
void add(int n, float *x, float*y){
for (int i = 0; i < n; i++)
y[i] = x[i] + y[i];
}

int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!

int N = 1<<20;
float *x, *y;

cudaMallocManaged((void**)&x, N*sizeof(float));
cudaMallocManaged((void**)&y, N*sizeof(float));

for(int i = 0; i < N; i++){
x[i] = 1.0f;
y[i] = 2.0f;
}

add<<<1, 1>>>(N, x, y);
cudaGetLastError();
    /**
     * This indicates that there is no kernel image available that is suitable
     * for the device. This can occur when a user specifies code generation
     * options for a particular CUDA source file that do not include the
     * corresponding device configuration.
     *
     *    cudaErrorNoKernelImageForDevice       =     209,
     */

cudaDeviceSynchronize();

float maxError = 0.0f;
for (int i = 0; i < N; i++){
maxError = fmax(maxError, fabs(y[i]-3.0f));
}

cudaFree(x);
cudaFree(y);

return 0;


}

1 Ответ

1 голос
/ 15 июля 2020

Ошибка здесь возникает из-за того, что ядро ​​CUDA должно быть скомпилировано таким образом, чтобы результирующий код (PTX или SASS) был совместим с графическим процессором, на котором оно выполняется. Это топи c с множеством нюансов, поэтому, пожалуйста, обратитесь к таким вопросам, как это (и ссылки там), чтобы получить дополнительную информацию.

Архитектура графического процессора, когда мы хотим Точность называется вычислительной способностью . Вы можете узнать о вычислительных возможностях вашего графического процессора либо с помощью поиска в Google, либо запустив deviceQuery пример кода CUDA . Вычислительные возможности выражаются как (основные). (Второстепенные), поэтому что-то вроде вычислительных возможностей 5.2 или 7.0, и т. Д. c.

При компиляции кода необходимо указать вычислительные возможности (или, если нет, будет подразумеваться вычислительная мощность по умолчанию ). Если вы укажете вычислительные возможности при компиляции способом, который соответствует вашему графическому процессору, все должно быть в порядке. Однако код с более новыми / более высокими вычислительными возможностями обычно не работает на графических процессорах со старыми / более низкими вычислительными возможностями. В этом случае вы увидите ошибки, подобные описанным вами:

cudaErrorNoKernelImageForDevice

209

«нет двоичного кода для GPU»

или аналогичные. Вы также можете вообще не увидеть явной ошибки, если не выполняете правильную проверку ошибок CUDA . Решение состоит в том, чтобы сопоставить вычислительные возможности, указанные во время компиляции, с графическим процессором, на котором вы собираетесь работать. Способ сделать это будет зависеть от используемой инструментальной цепочки / IDE. Для базовых c nvcc использование командной строки:

nvcc -arch=sm_XY ...

будет указывать вычислительную мощность XY

Для Eclipse / Nsight Eclipse / Nsight Visual Studio можно указать вычислительные возможности в свойствах проекта. В зависимости от инструмента это может быть выражено как значения переключателя (например, compute_XY, sm_XY) или может быть выражено численно как XY

...