cudaMemcpyToSymbol
копирует в постоянную переменную, здесь вы пытаетесь скопировать несколько байтов типа int
(выделенный массив) в указатель типа int *
.Эти типы не являются одинаковыми, следовательно, invalid type
.Чтобы это работало, вам нужно скопировать массив (int
) (выделенный) на устройство (статическая длина), массив (int
(постоянный)), например:
__device__ __constant__ int dic[LEN];
Пример из Руководство по программированию в CUDA C (которое я предлагаю вам прочитать - это неплохо!):
__constant__ float constData[256];
float data[256];
cudaMemcpyToSymbol(constData, data, sizeof(data));
cudaMemcpyFromSymbol(data, constData, sizeof(data));
Насколько мне известно, вы также можете cudaMemcpyToSymbol
указатель на указатель (в отличие от вашего примерагде вы копируете массив в указатель), но помните только, что указатель будет постоянным, а не память, на которую он указывает на вашем устройстве.Если вы собираетесь пойти по этому пути, вам нужно будет добавить cudaMalloc
, а затем cudaMemcpyToSymbol
полученный ptr в память устройства на ваше устройство __constant__
var.ОПЯТЬ, в этом случае значения массива НЕ БУДУТ постоянными - ТОЛЬКО указатель на память будет.
Ваш вызов для этого случая будет выглядеть примерно так:
int * d_dic;
cudaMalloc((void **) &d_dic, num_codewords*(bSizeY*bSizeX)*sizeof(int));
cudaMemcpyToSymbol(c_dic_ptr, &d_Dic, sizeof(int *));
Также выследует обернуть ваши вызовы CUDA во время отладки внутри логики проверки ошибок.Я заимствовал следующую логику из talonmies :
__inline __host__ void gpuAssert(cudaError_t code, 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);
}
}
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
Для вызова просто оберните в него свой вызов CUDA следующим образом:
gpuErrchk(cudaMemcpyToSymbol(dic, flatDic, num_codewords*(bSizeY*bSizeX)*sizeof(int)));
Программирование завершитсяс сообщением об ошибке, если у вас возникли проблемы с выделением ресурсов или другие распространенные ошибки.
Чтобы проверить ядро, выполните что-то вроде:
MyKernel<<<BLK,THRD>>>(vars...);
//Make sure nothing went wrong.
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());
Благодаря talonmies длякод проверки ошибок!
Примечание: Даже если вы выполняете ванильное cudaMemcpy
, ваш код потерпит неудачу, так как вы не cudaMalloc
отредактировали память для своего массива - в этом случае, однако, сбой, скорее всего, будет эквивалентен ошибке в графическом процессоре (вероятно, *)1047 *), поскольку указатель будет содержать какое-то нежелательное значение, и вы будете пытаться записать в память адрес, заданный этим нежелательным значением.