Matrix CUDA矩阵乘法的结果不正确

Matrix CUDA矩阵乘法的结果不正确,matrix,cuda,multiplication,Matrix,Cuda,Multiplication,让我先为这篇文章道歉。我知道有几篇帖子问了我同样的问题,但我已经尝试了给出的解决方案,我仍然没有得到CUDA矩阵乘法的正确结果 从我所遵循的示例中,我非常确定我在内核中的算法是正确的。我相信我在将2D数组传递到内核时不会遇到任何问题,因为它们是通过引用传递的,所以我觉得2D解决方案数组应该在主机中打印数组时包含正确的答案,但实际上并非如此 我的dim3 dimGrid(B,B)和dim3 dimThreads(T,T)变量可能有问题吗?我是CUDA框架的新手,我仍在尝试对其进行思考。如有任何建议

让我先为这篇文章道歉。我知道有几篇帖子问了我同样的问题,但我已经尝试了给出的解决方案,我仍然没有得到CUDA矩阵乘法的正确结果

从我所遵循的示例中,我非常确定我在内核中的算法是正确的。我相信我在将2D数组传递到内核时不会遇到任何问题,因为它们是通过引用传递的,所以我觉得2D解决方案数组应该在主机中打印数组时包含正确的答案,但实际上并非如此

我的dim3 dimGrid(B,B)和dim3 dimThreads(T,T)变量可能有问题吗?我是CUDA框架的新手,我仍在尝试对其进行思考。如有任何建议,将不胜感激。我的代码如下:

#include <stdio.h>
#include <cuda.h>
#include <stdlib.h>

__global__ void MatMultiply (int *a, int *b, int *c, int N) {
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;
    int val = 0;

    for (int e = 0; e < N; ++e) {
        val += a[row*N + e] * b[e*N + col];
    }
    c[row*N+col] = val;
}

int main(void) {
    int N, B, T;

    printf("Input integer for matrix dimension size: ");
    scanf("%d", &N);

    printf("Input number of threads in a block: ");
    scanf("%d", &T);

    printf("Input number of blocks in a grid: ");
    scanf("%d", &B);

    int size = N * N * sizeof(int);

    int *a, *b, *c;

    a = (int*)malloc(size);
    b = (int*)malloc(size);
    c = (int*)malloc(size);

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            a[i*N+j] = j + i*N;
            b[i*N+j] = j + i*N;
            c[i*N+j] = j + i*N;
        }
    }

    int *dev_a, *dev_b, *dev_c;

    cudaMalloc((void**)&dev_a, size);
    cudaMalloc((void**)&dev_b, size);
    cudaMalloc((void**)&dev_c, size);

    cudaMemcpy(dev_a, a, size, cudaMemcpyHostToDevice);
    cudaMemcpy(dev_b, b, size, cudaMemcpyHostToDevice);
    cudaMemcpy(dev_c, c, size, cudaMemcpyHostToDevice);

    dim3 dimGrid(B, B);
    dim3 dimThreads(T, T);
    MatMultiply<<<B, T>>>(dev_a,dev_b,dev_c, N);

    cudaMemcpy(c, dev_c, size, cudaMemcpyDeviceToHost);


    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            printf("%d\t", b[i*N + j]);
        }
        printf("\n");
    }

    free(a);
    free(b);
    free(c);

    cudaFree(dev_a);
    cudaFree(dev_b);
    cudaFree(dev_c);

    return 0;
}
#包括
#包括
#包括
__全局无效MatMultiply(int*a,int*b,int*c,int N){
int row=blockIdx.y*blockDim.y+threadIdx.y;
int col=blockIdx.x*blockDim.x+threadIdx.x;
int-val=0;
对于(int e=0;e

再次感谢。

您没有在内核调用中使用
dimGrid
dimThreads
变量。相反,您只是启动一维线程块的一维网格


除此之外,您没有检查任何错误。

您没有在内核调用中使用
dimGrid
dimThreads
变量。相反,您只是启动一维线程块的一维网格


除此之外,您没有检查任何错误。

因此,这里的问题似乎在于设置线程和块以及使用threadIdx、blockDim和gridDim

注意:此特定问题的实际解决方案位于“实际解决方案”标签上

threadIdx的名称表示线程的ID。这意味着该值,或者更准确地说,它的threadIdx.x和threadIdx.y组件将从0的值变为指定的线程计数,或者更确切地说,是存储在blockDim.x和blockDim.y中的每个块的线程数。比如一个电话

someKernel<<<1,32>>>( .... );
现在让我们看看你的变量是如何反应的

row would go from 0 to 0
col would go from 0 to 1023
所以,这大概不是你真正想要的。您希望行和列都从0变为N-1,对吗?好吧,你就是这样做的:

int row = threadIdx.x + blockIdx.x * blockDim.x;
int col = threadIdx.y + blockIdx.y * blockDim.y;
还要确保有足够的螺纹覆盖矩阵的尺寸。这就是确保将*threadsPerBlock*blocksPerGrid*设置为大于N。这通常最好通过以下方式完成:

threads = 32
dim3 threadsPerBlock ( threads, threads ); 
blocks = (N / threads) + 1; 
dim3 blocksPerGrid ( blocks, blocks );
“但是如果我使它大于N,那么我可能会有一些我不需要的线程”——你说——“我不想让它们工作!”先生,你这么说是明智的。您可以通过简单的if子句来解决这个问题,在该子句中,您将包含您的计算,如下所示:

if ( row < N && col < N )
{
     // your add... err... code here
}
if(行

希望有帮助。享受CUDA;)

因此,这里的问题似乎在于设置线程和块以及使用threadIdx、blockDim和gridDim

注意:此特定问题的实际解决方案位于“实际解决方案”标签上

threadIdx的名称表示线程的ID。这意味着该值,或者更准确地说,它的threadIdx.x和threadIdx.y组件将从0的值变为指定的线程计数,或者更确切地说,是存储在blockDim.x和blockDim.y中的每个块的线程数。比如一个电话

someKernel<<<1,32>>>( .... );
现在让我们看看你的变量是如何反应的

row would go from 0 to 0
col would go from 0 to 1023
所以,这大概不是你真正想要的。您希望行和列都从0变为N-1,对吗?好吧,你就是这样做的:

int row = threadIdx.x + blockIdx.x * blockDim.x;
int col = threadIdx.y + blockIdx.y * blockDim.y;
还要确保有足够的螺纹覆盖矩阵的尺寸。这就是确保将*threadsPerBlock*blocksPerGrid*设置为大于N。这通常最好通过以下方式完成:

threads = 32
dim3 threadsPerBlock ( threads, threads ); 
blocks = (N / threads) + 1; 
dim3 blocksPerGrid ( blocks, blocks );
“但是如果我使它大于N,那么我可能会有一些我不需要的线程”——你说——“我不想让它们工作!”先生,你这么说是明智的。您可以通过简单的if子句来解决这个问题,在该子句中,您将包含您的计算,如下所示:

if ( row < N && col < N )
{
     // your add... err... code here
}
if(行

希望有帮助。享受CUDA;)

另外,在最后,您将打印出矩阵
b
,这是您的输入矩阵之一。您可能需要打印出
c
。谢谢。我不知道我是怎么错过的。一切似乎都很好