cuda & cublas: вызов глобальной функции после использования cublas

0

Я пишу программу, которая включает в себя некоторое умножение матрицы-вектора и наименее квадратное решение, использующее cublas & cula API. Программа будет многократно повторяться. на каждом шаге я должен установить одну матрицу в определенную строку до нуля.

Я попытался скопировать всю матрицу (50 * 1000 или больше) в CPU и установить одну строку в ноль, а затем скопировать матрицу обратно, но это слишком трудоемко, потому что программа будет повторять 10 и более раз. Поэтому я решил написать функцию ядра.

Глобальная функция:

__global__ void Setzero(float* A, int index) /* A is the matrix and in col-major , index is the row I want to set zero */
{
    int ind=blockDim.x*blockIdx.x+threadIdx.x;
    if( ((ind%N)==index ) && (ind<50000) )  //notice matrix is in col-major ,matrix size is 50000
    {   
    A[ind]=0.0;
        ind+=blockDim.x*blockIdx.x;
    }
    else    ;
        __syncthreads();   
}

Вопрос в том, когда я это делаю (используйте cublas перед вызовом функции):

cudaMalloc((void**)&A_Gpu_trans,sizeof(float)*50000);
cudaMemcpy(A_Gpu_trans,A_trans,sizeof(float)*M*N,cudaMemcpyHostToDevice);
cublasSgemv_v2(handle,CUBLAS_OP_N,1000,50,&al,A_Gpu_trans,1000,err_gpu,1,&beta,product,1);
dim3 dimBlock(16,1);
dim3 dimGrid((50000-1)/16+1,1);
Setzero<<<dimGrid,dimBlock>>>(A_Gpu_trans,Index);

Он возвращает ошибку:

a __host__ function("Setzero") redeclared with __global__.

и другая ошибка:

MSB3721: команда "" C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\bin\nvcc.exe "-gencode = arch = compute_10, code = \" sm_10, compute_10\"--use-local -env --cl-версия 2010 -ccbin "D:\Program Files\Microsoft Visual Studio 10.0\VC\bin" -I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -G --keep-dir Debug -maxrregcount = 0 --machine 32 --compile -cudart static -G -DWIN32 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc/W3/nologo/Od/Zi/RTC1/MDd" -o Debug\kernel.cu.obj "C:\Users\Administrator\documents\visual studio 2010\Projects\OOmp\OOmp\kernel.cu "" return 2.

Странно, когда я использую только API cublas & cula, я могу получить правильный ответ.

Теги:
cuda
visual-studio-2010
cublas

2 ответа

0
Лучший ответ

Хотя вы не Setzero это в своем вопросе, у вас явно есть другая функция-хозяин, называемая Setzero где-то в вашем коде. Простое решение - переименовать ядро на что-то другое.

Основная причина, по которой инструментальная цепочка CUDA испускает ошибку, заключается в том, что синтаксис вызова ядра Setzero<<< >>> в API времени выполнения заставляет интерфейс CUDA создавать хост-функцию с тем же именем, что и ядро с соответствующим списком аргументов и замените запуск ядра для вызова этой функции. Эта хост-функция содержит необходимые вызовы API для запуска ядра. Имея еще одну функцию хоста с тем же именем, что и ядро, вы побеждаете этот процесс и вызываете ошибку компиляции.

  • 0
    Спасибо, я получил решение
1

Кроме того, ваша функция ошибочна и дико неэффективна...

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

Более того, вы запускаете один поток для каждой записи матрицы, и только 1/N из них действительно что-то делают.

Лучшим подходом является запуск только потоков, соответствующих записям, которые будут установлены на ноль. Что-то вроде этого:

__global__ void Setzero(float* A, int index) 
{
  int ind=blockDim.x*blockIdx.x+threadIdx.x;
  if (ind < M)   
    A[index+N*ind]=0.0;
}

и вы запускаете потоки M (или, точнее, потоковые потоки (M/256) из 256 потоков нитей каждый или любой размер блока, который вы хотите).

Например:

int block_size = 256; // usually a good choice
int num_blocks = (M + block_size - 1) / block_size;
Setzero<<<num_blocks, block_size>>>(A, index);
  • 0
    Спасибо . Но когда M> 512, что является максимальным потоком на блок. Мне нужно загрузить два блока. Нужна ли мне что-то еще или что-то еще?
  • 0
    Да, хороший момент, я немного обновил свое ядро.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню