Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matrix 即使输入相同,CUDA内核也会给出不同的结果_Matrix_Cuda - Fatal编程技术网

Matrix 即使输入相同,CUDA内核也会给出不同的结果

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>

我想写一个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;
}
#包括
#包括
#包括
#包括
#包括
静态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组成的矩阵,但每次运行程序时,生成的矩阵总是不同的。有什么建议会导致这样的结果吗?我分配的内存错了吗?再次感谢!