Я пытаюсь установить постоянные значения в постоянной памяти графического процессора перед запуском ядра, которому нужны эти значения.
Мой код (упрощенно):
__constant__ size_t con_N;
int main()
{
size_t N;
size_t* dev_N = NULL;
cudaError_t cudaStatus;
//[...]
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, &con_N);
if (cudaStatus != cudaSuccess) {
cout<<"cudaGetSymbolAddress (dev_N) failed: "<<cudaGetErrorString(cudaStatus)<<endl;
}
Я планировал потом cudaMemcpy
отправить N
на dev_N
.
Однако все, что я получил на этом этапе кода, это:
cudaGetSymbolAddress (dev_N) failed: invalid device symbol
Я работаю с CUDA 6.5, поэтому это не проблема с цитируемыми символами, как в большинстве вопросов и ответов, которые я проверял до сих пор.
Я попытался заменить con_N
на con_N[1]
(и удалить &
перед con_N
в параметрах cudaGetSymbolAddress
): результат тот же.
Поскольку прототипом этой функции является cudaGetSymbolAddress(void **devPtr , const void* symbol )
, я предположил, что он хочет получить адрес моего символа. Однако я попытался использовать cudaStatus = cudaGetSymbolAddress((void **)&dev_N, (const void*) con_N);
и получил то же сообщение.
Я также получаю такое же сообщение об ошибке, когда удаляю cudaGetSymbolAddress((void **)&dev_N, &con_N)
и вместо этого использую cudaMemcpyToSymbol(&con_N, &N, sizeof(size_t))
.
Боюсь, что упустил что-то важное. Любая помощь будет оценена.
2 ответа
Правильное использование cudaGetSymbolAddress
:
cudaGetSymbolAddress((void **)&dev_N, con_N)
Я показываю это на простом примере ниже.
Как поясняется в документации, символ должен физически находиться на устройстве. Соответственно, использование &con_N
в вызове API кажется бессмысленным, поскольку, будучи cudaGetSymbolAddress
API хоста, доступ к адресу чего-либо, находящегося на устройстве, напрямую с хоста невозможен. Я не уверен, что прототип, представленный в документе CUDA Runtime API, лучше читать как `
template<class T>
cudaError_t cudaGetSymbolAddress (void **devPtr, const T symbol)
С ссылкой на символ устройства вместо адреса символа устройства .
#include <stdio.h>
__constant__ int const_symbol;
/********************/
/* CUDA ERROR CHECK */
/********************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
/***************/
/* TEST KERNEL */
/***************/
__global__ void kernel() {
printf("Address of symbol from device = %p\n", &const_symbol);
}
/********/
/* MAIN */
/********/
int main()
{
const int N = 16;
int *pointer = NULL;
gpuErrchk(cudaGetSymbolAddress((void**)&pointer, const_symbol));
kernel<<<1,1>>>();
printf("Address of symbol from host = %p\n", pointer);
return 0;
}
На мой взгляд, строка вашего кода должна быть исправлена, как показано ниже.
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, con_N);
Надеюсь, это тебе поможет.
Похожие вопросы
Связанные вопросы
Новые вопросы
memory-management
Процесс динамического распределения и освобождения частей физической памяти для того, чтобы отвечать на программные запросы с, по возможности, справедливостью и без голодания среди запрашивающих.
cudaGetSymbolAddress((void **)&dev_N, con_N)
, но только потому, что весь код, о котором я говорю, был в файле .cpp, а не в файле .cu. Обертывание моих вызовов решило мои проблемы с компиляцией (благодаря этой теме: stackoverflow.com/questions/20535683/… )