Проверка ошибок АЭС и CUDA - PullRequest
0 голосов
/ 22 мая 2018

Я снова унаследовал код, который выглядит подозрительно;в основном это так:

(void) nppiFilter...(...);
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess)
{
    std::cerr << cudaGetErrorString(err);
}

Мы игнорируем ошибку АЭС, но вместо этого проверяем ошибку CUDA.

Во-первых, АЭС устанавливает флаг ошибки CUDA на ошибку?Я почти уверен, что ответ «не явно», поэтому этот код пропустит ошибки, связанные только с NPP, но я хочу проверить.

Во-вторых, необходимо ли проверить обе ошибки или этого будет достаточно:

NppStatus nppErr = nppiFilter...(...);
if (nppErr != NPP_NO_ERROR)
{
    std::cerr << "NPP error " << nppErr;
}

Или я должен проверить оба на всякий случай?Есть NPP_CUDA_KERNEL_EXECUTION_ERROR, который подсказывает мне, что может быть полезна проверка cudaGetLastError(), но так ли это?

1 Ответ

0 голосов
/ 22 мая 2018

Во-первых, АЭС устанавливает флаг ошибки CUDA на ошибку?

Нет, это не так.Состояние ошибки CUDA может быть установлено чем-то скрытым, выполняемым NPP, но NPP специально не устанавливает состояние ошибки CUDA.

Или я должен проверить оба варианта на всякий случай?

Достаточно просто проверить состояние АЭС.Однако, если вы хотите выполнить дополнительный анализ отладки, может быть полезно проверить состояние ошибки CUDA.На самом деле, я часто запускаю cuda-memcheck, когда ищу дополнительные подсказки.Единственное нормальное значение, которое это может иметь, - предоставить «дополнительные ключи».

Безопасное предположение состоит в том, что многие библиотеки CUDA могут иметь функции, которые запускают работу асинхронно.То есть: базовая активность графического процессора все еще может происходить даже после того, как функция вернула управление потоку ЦП.В таких случаях ожидается, что хорошо спроектированная библиотека будет перехватывать ошибки из-за асинхронной активности «позже», когда вы делаете последующий вызов библиотеки или вызов API CUDA (возможно, для получения рассчитанных данных с устройства на хост).

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

error = cudaGetLastError();

(если только это не следует непосредственно за вызовом API CUDA и это ваша стратегия **)

и я бы не предложил произвольно вставлять:

error = cudaDeviceSynchronize();

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

Это, очевидно, в некоторой степени вопрос мнения.Возможно, вы захотите довести проверку ошибок до крайнего уровня.Это не должно сильно влиять на вашу программу, если вы не вставляете синхронизирующие вызовы для проверки ошибок.

Мои комментарии выше в основном касаются того, как я написал бы рабочий код.В целях обучения или в любое время, когда у вас возникают проблемы с кодом, который вы пишете, обычно рекомендуется очень строго относиться к проверке ошибок и действительно вставлять дополнительную проверку ошибок, чтобы перехватывать асинхронные ошибки для локализацииошибка для конкретной функции.

** Возможно, вы захотите вставить:

error = cudaGetLastError();

после каждого вызова ядра в ваш код.Это отлавливает любые ошибки ядра, которые обнаруживаются во время запуска, такие как неверные размеры сетки.Этот тип вызова должен быть относительно легким.

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