Matrix 即使输入相同,CUDA内核也会给出不同的结果
我想写一个CUDA内核,将乘以2个矩阵NxN大小。我确实做到了,但是没有线程的配合。。。现在我想通过线程协作来完成它,我遵循了SDK中提供的代码。但由于某些原因,内核返回不同的结果。下面是.cu文件:Matrix 即使输入相同,CUDA内核也会给出不同的结果,matrix,cuda,Matrix,Cuda,我想写一个CUDA内核,将乘以2个矩阵NxN大小。我确实做到了,但是没有线程的配合。。。现在我想通过线程协作来完成它,我遵循了SDK中提供的代码。但由于某些原因,内核返回不同的结果。下面是.cu文件: #include<stdio.h> #include<cuda.h> #include<cuda_runtime.h> #include<cuda_runtime_api.h> #include<device_functions.h>
#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;
}
#包括
#包括
#包括
#包括
#包括
静态void HandleError(cudaError\u t err,const char*文件,int行)
{
if(err!=cudaSuccess){
printf(“%s在%s文件中的第%s行\n”,cudaGetErrorString(err),file,line);
退出(退出失败);
}
}
#定义句柄错误(err)(句柄错误(err,文件,行)
#ifndef MATRIXMUL KERNEL H_
#定义_矩阵_内核_H_
#定义顺序4
__全局无效矩阵(int*A、int*B、int*C、int-wA、int-wB)
{
int bx=blockIdx.x;
int by=blockIdx.y;
int tx=线程idx.x;
int ty=threadIdx.y;
int-aBegin=wA*订单*by;
int aEnd=aBegin+wA-1;
int aStep=订单;
int-bBegin=订单*bx;
int bStep=订单*wB;
int Csub=0;
对于(inta=aBegin,b=bBegin;a如果线程几何体是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
输出应该会提示您可能出现的错误。此代码有很多错误。我建议您获取“Cuda示例”的副本在那里,作者们做了一个矩阵乘法,并解释了一切。我有那本书,但我找不到矩阵乘法的例子/解释。虽然,有一个两个向量求和的例子。可能是你弄错了这两个吗?我想Azrael3000是指Kirk和Hwu编写的大规模并行处理器的编程at book使用矩阵乘法内核作为例子,大约有一半的书…非常详细。Z0K4我已经有一段时间没有读过了。所以是的,可能只有向量的求和。但是,矩阵乘法只是向量的求和几次。所以你可以从那里开始。真的吗你说过乘法和求和……我已经编写了乘法矩阵的内核,但是没有线程协作。现在我想(如果可能的话)用线程协作来实现,这样过程会更快。但是谢谢你的回复,也谢谢你花时间帮我!;)@Brendan Wood我刚拿到这本书,看起来它正是我需要的……我还没有机会看一看,但我确实浏览了目录,结果是…矩阵乘法示例,但我仍然不知道它们是否使用共享内存!谢谢!很抱歉我的反应太晚…我不知道怎么做,但不知怎的我没有看到你的答案。谢谢你的帮助!我已经更新了代码,现在矩阵是4x4。第一个是用1填充,第二个用2填充。输出应该是由数字8组成的矩阵,但每次运行程序时,生成的矩阵总是不同的。有什么建议会导致这样的结果吗?我分配的内存错了吗?再次感谢!