Странная ошибка при использовании cudaMemcpy: cudaErrorLaunchFailure

У меня есть код CUDA, который работает как показано ниже:

cpyDataGPU --> CPU     

while(nsteps){

    cudaKernel1<<<,>>>
    function1();    
    cudaKernel2<<<,>>>

}

cpyDataGPU --> CPU

И функция1 такая:

function1{

    cudaKernel3<<<,>>>
    cudaKernel4<<<,>>>

    cpyNewNeedDataCPU --> GPU   // Error line
    cudaKernel5<<<,>>>
}

Согласно документации cudaMemcpy, эта функция может выдавать 4 разных кода ошибки: "cudaSuccess", "cudaErrorInvalidValue", "cudaErrorInvalidDevicePointer" и "cudaErrorInvalidMemcpyDirection".

Тем не менее я получаю следующую ошибку: "cudaErrorLaunchFailure": "Исключительная ситуация произошла на устройстве при выполнении ядра. Общие причины включают разыменование недопустимого указателя устройства и доступ за пределами разделяемой памяти. Устройство нельзя использовать до тех пор, пока не будет вызвана функция cudaThreadExit(). Все существующие выделения памяти устройства недействительны и должны быть восстановлены, если программа продолжит использовать CUDA."

Кто-нибудь знает, почему я получаю эту ошибку? Что я делаю неправильно?

Имеет ли смысл копировать данные CPU ->GPU после предыдущих вызовов ядра ¿? Проблема в том, что мне нужно копировать эти данные здесь на каждом шаге, потому что они могут меняться на каждом шаге "пока".

Так много заранее!

2 ответа

Решение

В документации, на которую вы ссылаетесь, также говорится:

Обратите внимание, что эта функция также может возвращать коды ошибок из предыдущих асинхронных запусков.

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

Самая распространенная причина этой ошибки - доступ за пределами допустимого уровня, очень похожий на segfault на территории x86.

cudaErrorLaunchFailure: исключение произошло на устройстве при выполнении ядра. Распространенные причины включают разыменование недопустимого указателя устройства и доступ к разделяемой памяти. Устройство нельзя использовать до тех пор, пока не будет вызвана функция cudaThreadExit(). Все существующие выделения памяти устройства недействительны и должны быть восстановлены, если программа продолжит использовать CUDA.

Самый простой способ отладить это - использовать cuda-memcheck. Кроме того, вы можете определить, какое ядро ​​не удалось, вызвав cudaDeviceSynchronize() после каждого запуска ядра и проверки возвращаемого значения.

Вы проверяете статус ошибки после вызова ваших ядер? Потому что (почти?) Все вызовы cuda могут вернуть ошибку предыдущего неудачного вызова или ядра. Так как вы получаете ошибку запуска, я подозреваю, что одно из ядер до того, как копия станет реальным источником ошибки.

Другие вопросы по тегам