我想写一个CUDA内核,它将乘以2个矩阵NxN大小。我确实设法做到了,但没有线程合作......现在我想用线程合作来做,我遵循SDK中提供的代码。但由于某种原因,内核返回不同的结果。所以这是.cu文件:
#include<stdio.h>
#include<cuda.h>
#include<cuda_runtime.h>
#include<cuda_runtime_api.h>
#include<device_functions.h>
static void HandleError(cudaError_t err, const char *file, int line)
{
if(err!=cudaSuccess){
printf("%s in %s file at line %s\n", cudaGetErrorString(err), file, line);
exit(EXIT_FAILURE);
}
}
#define HANDLE_ERROR(err) (HandleError(err, __FILE__, __LINE__))
#ifndef _MATRIXMUL_KERNEL_H_
#define _MATRIXMUL_KERNEL_H_
#define ORDER 4
__global__ void matrixMul( int* A, int* B, int* C, int wA, int wB)
{
int bx = blockIdx.x;
int by = blockIdx.y;
int tx = threadIdx.x;
int ty = threadIdx.y;
int aBegin = wA * ORDER * by;
int aEnd = aBegin + wA - 1;
int aStep = ORDER;
int bBegin = ORDER * bx;
int bStep = ORDER * wB;
int Csub=0;
for (int a = aBegin, b = bBegin; a <= aEnd; a += aStep, b += bStep)
{
__shared__ int As[ORDER][ORDER];
__shared__ int Bs[ORDER][ORDER];
As[ty][tx] = A[a + wA * ty + tx];
Bs[ty][tx] = B[b + wB * ty + tx];
__syncthreads();
#pragma unroll
for (int k = 0; k < ORDER; ++k)
Csub += As[ty][k] * Bs[k][tx];
__syncthreads();
}
int c = wB * ORDER * by + ORDER * bx;
C[c + wB * ty + tx] = Csub;
}
#endif
int main()
{
int *a=(int*)malloc(ORDER*ORDER*sizeof(int));
int *b=(int*)malloc(ORDER*ORDER*sizeof(int));
int *c=(int*)malloc(ORDER*ORDER*sizeof(int));
int *dev_a, *dev_b, *dev_c;
HANDLE_ERROR(cudaMalloc((void**)&dev_a, ORDER*ORDER*sizeof(int*)));
HANDLE_ERROR(cudaMalloc((void**)&dev_b, ORDER*ORDER*sizeof(int*)));
HANDLE_ERROR(cudaMalloc((void**)&dev_c, ORDER*ORDER*sizeof(int*)));
for(int i=0; i<ORDER*ORDER; i++)
{
a[i]=1;
b[i]=2;
}
HANDLE_ERROR(cudaMemcpy(dev_a, a, ORDER*ORDER*sizeof(int), cudaMemcpyHostToDevice));
HANDLE_ERROR(cudaMemcpy(dev_b, b, ORDER*ORDER*sizeof(int), cudaMemcpyHostToDevice));
matrixMul<<<ORDER, ORDER>>>(dev_a, dev_b, dev_c, ORDER, ORDER);
HANDLE_ERROR(cudaMemcpy(c, dev_c, ORDER*ORDER*sizeof(int), cudaMemcpyDeviceToHost));
for(int i=0; i<ORDER*ORDER; i++)
{
if((i%ORDER)==0)
printf("\n\n");
printf("%d\t", a[i]);
}
for(int i=0; i<ORDER*ORDER; i++)
{
if((i%ORDER)==0)
printf("\n\n");
printf("%d\t", b[i]);
}
for(int i=0; i<ORDER*ORDER; i++)
{
if((i%ORDER)==0)
printf("\n\n");
printf("%d\t", c[i]);
}
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return 0;
}
是的,我知道没有“真正的”问题......但如果有人能指出我的正确方向,我将不胜感激。谢谢!
如果您需要更多代码示例,请告诉我,我将编辑问题。
编辑#1:我忘了提到......我无法在Visual Studi 2010中实现nvcc,所以我无法使用调试器。有关于此的任何建议吗?编辑#2 :更新了问题,因此它显示了CUDA内核和主要内容。
答案 0 :(得分:1)
您的内核似乎正确,如果您的线程几何是BLOCKSIZE x BLOCKSIZE
。是这样的吗?
如果那不是你的问题:
既然你说你没有线程同步就可以正常工作,你可能会得到正确的内存分配。
尝试使用4x4的线程几何和以下两个矩阵进行测试:
1 1 1 1 1 0 0 0
2 2 2 2 0 1 0 0
3 3 3 3 0 0 1 0
5 5 5 5 0 0 0 1
输出应该给你一个关于可能出错的提示。