LINUX.ORG.RU

CUDA: помогите найти ошибку в коде


0

1

Уже несколько дней мучаюсь с дебагом кода на CUDA.

Написал два варианта кода. Для CUDA:

__global__ void gpu_process(float* input, float* weights, float* output, int psize, int size)
{
	int i = blockIdx.x*blockDim.x + threadIdx.x;
	int j = blockIdx.y*blockDim.y + threadIdx.y;
	if(i < psize && j < size)
		output[j] += input[i] * weights[i * size + j];
}
void process(float* input, float* weights, float* output, size_t psize, size_t size)
{
	float* in_d, *w_d, *out_d;
	cudaMalloc((void**)&in_d, psize * sizeof(float));
	cudaMalloc((void**)&w_d, psize * size * sizeof(float));
	cudaMalloc((void**)&out_d, size * sizeof(float));
	for(size_t i = 0; i < size; i++)
		output[i] = 0;
	cudaMemcpy(in_d, input, psize * sizeof(float), cudaMemcpyHostToDevice);
	cudaMemcpy(w_d, weights, psize * size * sizeof(float), cudaMemcpyHostToDevice);
	cudaMemcpy(out_d, output, size * sizeof(float), cudaMemcpyHostToDevice);
	int rx = psize, ry = size, block_x = min((int)psize, 32), block_y = min((int)size, 32);
	dim3 dimBlock(block_x, block_y);
	dim3 dimGrid(ceil(float(rx) / block_x), ceil(float(ry) / block_y));
	gpu_process<<<dimGrid, dimBlock>>>(in_d, w_d, out_d, psize, size);
	cudaThreadSynchronize();
	cudaMemcpy(output, out_d, size * sizeof(float), cudaMemcpyDeviceToHost);
	cudaFree(in_d);
	cudaFree(out_d);
	cudaFree(w_d);
}
То же самое для CPU:
int blockIdxx, blockIdxy, blockDimx, blockDimy, threadIdxx, threadIdxy;
void cpu_process(float* input, float* weights, float* output, int psize, int size)
{
	int i = blockIdxx*blockDimx + threadIdxx;
	int j = blockIdxy*blockDimy + threadIdxy;
	if(i < psize && j < size)
		output[j] += input[i] * weights[i * size + j];
}
void process(float* input, float* weights, float* output, size_t psize, size_t size)
{
	for(size_t i = 0; i < size; i++)
			output[i] = 0;
	int rx = psize, ry = size, block_x = min((int)psize, 32), block_y = min((int)size, 32);
	blockDimx = block_x;
	blockDimy = block_y;
	int gridDimx = ceil(float(rx) / block_x), gridDimy = ceil(float(ry) / block_y);
	for(blockIdxx = 0; blockIdxx < gridDimx; blockIdxx++)
		for(blockIdxy = 0; blockIdxy < gridDimy; blockIdxy++)
			for(threadIdxx = 0; threadIdxx < blockDimx; threadIdxx++)
				for(threadIdxy = 0; threadIdxy < blockDimy; threadIdxy++)
					cpu_process(input, weights, output, psize, size);
}
Почему версия для CPU выводит именно то, что ожидалось, а CUDA - всякий бред?

Deleted

Последнее исправление: Deleted (всего исправлений: 1)
roman@franchuk-r> nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2011 NVIDIA Corporation
Built on Thu_May_12_11:09:45_PDT_2011
Cuda compilation tools, release 4.0, V0.2.1221[/quote]
Карта: GeForce GT 525M. Найденные в инете примеры куды работают.
Deleted
()

Кде минимальная рабочая программа? А не кусок кода.

anonymous
()

Разобрался, в чем проблемма: output[j] += input * weights[i * size + j]; - так делать нельзя, += не атомарный и если много потоков одновременно имеют один и тот же j, то получается бред. Помогли на stackoverflow.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.