Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.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
用Cuda实现非方矩阵乘法_C_Matrix_Cuda - Fatal编程技术网

用Cuda实现非方矩阵乘法

用Cuda实现非方矩阵乘法,c,matrix,cuda,C,Matrix,Cuda,我在最后几天开始与cuda合作。编写一个将两个大小为nxn的矩阵相乘的程序并没有问题。在内核函数中,我使用了以下代码: for(int i = 0; i < width; i++){ sum += a[row * width + i] * b[i * width + col]; c[row * width + col] = sum; } 如何设计核函数,将大小为1 x N的矩阵与大小为N x M的矩阵相乘我现在找到了解决此问题的方法:

我在最后几天开始与cuda合作。编写一个将两个大小为nxn的矩阵相乘的程序并没有问题。在内核函数中,我使用了以下代码:

    for(int i = 0; i < width; i++){
        sum += a[row * width + i] * b[i * width + col];
        c[row * width + col] = sum;
    }

如何设计核函数,将大小为1 x N的矩阵与大小为N x M的矩阵相乘

我现在找到了解决此问题的方法:

    #include <stdio.h>
#include <iostream>

using namespace std;

__global__
void kernel(float *a, float *b, float *c, int N, int M) {
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    float sum = 0;
    if (tid < M) {
        for (int i = 0; i < N; i++)
            sum += a[i] * b[(i * M) + tid];
        c[tid] = sum;

    }
}

int main(void) {

    float *dev_a, *dev_b, *dev_c;

    int N = 16;
    int M = 12;

    float a[N];
    float b[N][M];
    float c[M];

    for (int i = 0; i < N; i++) {
        a[i] = 1.0;
    }

    for (int i = 0; i < N; i++) {
        for (int e = 0; e < M; e++) {
            b[i][e] = 1.0;
        }
    }

    cudaMalloc((void**) &dev_a, sizeof(float) * N);
    cudaMalloc((void**) &dev_b, sizeof(float) * N * M);
    cudaMalloc((void**) &dev_c, sizeof(float) * M);

    cudaMemcpy(dev_a, a, sizeof(float) * N, cudaMemcpyHostToDevice);
    cudaMemcpy(dev_b, b, sizeof(float) * N * M, cudaMemcpyHostToDevice);

    kernel<<<M / 256 + 1, 256>>>(dev_a, dev_b, dev_c, N, M);

    cudaMemcpy(c, dev_c, sizeof(float) * M, cudaMemcpyDeviceToHost);

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

    for (int i = 0; i < M; i++) {
        cout << c[i] << endl;
    }

    return 0;
}

但我还有一个问题。出于性能原因,将内核中的for循环操作拆分为几个内核有意义吗?

大小为N的矩阵-你是说N x N?我不理解这里的问题。您所展示的代码只是一行和一列的内积。为什么存储在循环中?无论涉及到矩阵的其他维度如何,它都不会改变。不,我想将一维矩阵N乘以二维矩阵nxm。存储结果的矩阵必须是M大@Talonmes,我没有更改上面的代码。将两个大小为N x N的矩阵相乘可以很好地工作。但是对于非平方矩阵,它没有。尽管我在索引中使用了高度参数,但最简单的事情是将两个矩阵都填充到平方类型,并在内核中添加范围检查,以避免不必要的计算通常是将1xN矩阵与NxM矩阵相乘以生成1xM矩阵称为矩阵向量乘法。如果您对性能感兴趣,请使用cublas。如果您想编写自己的代码,正如@Talonmes已经指出的那样,像您所展示的那样的矩阵乘法内核应该可以工作。如果你不能让它工作并且需要帮助,你可能应该在这里,在这个问题上提供一个,而不是在一个外部链接中。它应该是一个完整的代码,而不仅仅是一个内核。