Разве в CUDA нет API-вызова, похожего на calloc()?
Из рассмотрения Справочника по API CUDA 5.5 и Руководства по программированию CUDA C видно, что cudaCalloc()
эквивалентный для стандартной библиотеки C встроенный графический процессор calloc()
,
- Неужели нет никакой API-функциональности для выделения буфера, инициализированного для всех нулей?
- Есть ли что-то лучшее, что я могу сделать, чем позвонить
cudaMalloc()
а потомcudaMemset()
?
4 ответа
Неужели нет никакой API-функциональности для выделения буфера, инициализированного для всех нулей?
Там действительно нет.
Есть ли что-то лучшее, что я могу сделать, что cudaMalloc(), а затем cudaMemset()?
Вы можете использовать макрос, если это для удобства (вы не сказали нам, что вы подразумеваете под лучше, если ответ на первый вопрос - нет):
#define cudaCalloc(A, B, C) \
do { \
cudaError_t __cudaCalloc_err = cudaMalloc(A, B*C); \
if (__cudaCalloc_err == cudaSuccess) cudaMemset(*A, 0, B*C); \
} while (0)
Вышеупомянутый макрос будет работать с проверкой ошибок, которую я обычно делаю (которая основана на использовании cudaGetLastError()
; или вы можете встроить предпочитаемую проверку ошибок непосредственно в макрос, если хотите. Смотрите этот вопрос об обработке ошибок.
Вот решение со встроенной функцией.
devPtr
должен быть указателем на указатель на что-либо. Используя
void*
в качестве аргумента функции освобождает вызывающую сторону от применения приведения .
inline cudaError_t
_cuda_calloc( void *devPtr, size_t size )
{
cudaError_t err = cudaMalloc( (void**)devPtr, size );
if( err == cudaSuccess ) err = cudaMemset( *(void**)devPtr, 0, size );
return err;
}
Если вам нужен простой способ обнуления новых выделений, вы можете использовать thrust::device_vector
, который по умолчанию создает свои элементы. Для примитивных типов это такое же поведение, как calloc
,
В CUDA нет внутренней операции вызова. Вы можете использовать следующее:
cudaMalloc(...)
cudaMemcpyAsync(..)
Обратите внимание, что это не заставляет хост ждать операции установки памяти.