首页 > 解决方案 > 如何将向量的数据传递给 CUDA 内核?

问题描述

所以我有这个关于卷积的任务,我必须将 .wav 过滤器应用于另一个 .wav 文件。我必须使用 CUDA 来做到这一点。这是我的 CUDA 内核:


__global__ void MyConvolveCUDA(const double* A, const double* B, double* C, int n, int m) {

    int i = threadIdx.x + blockIdx.x * blockDim.x;
    int j = threadIdx.y + blockIdx.y * blockDim.y;

    int min, max;
    if (i >= m - 1) min = i - m + 1; else min = 0;
    if (i < n - 1) max = i; else max = n - 1;

    if (j <= min) j = min;
    else if (j >= max) j = max;

    C[i] = A[i] * B[j - i];
}

这是我尝试的功能。我使用了一个自定义库来读取音频文件(它们被正确读取和所有内容),所以我将简化音频文件的代码部分:


void MyConvolveCUDA_Run() {

    //Let's say that  'filter' is the filter i want to apply to the 'audio' file. 'output' is the file I 
    //want to export in the end. The '.samples' function accesses the samples' part of the audio file, 
    //and the 'save' function saves the file using the given name.

    int n = audio.samples.size(),
        m = filter.samples.size();

    //These are the device copies of the data I want to proccess.
    double* audioCUDA = nullptr;
    double* filterCUDA = nullptr;
    double* outputCUDA = nullptr;

    cudaMalloc((void **)&audioCUDA, n * sizeof(double));
    cudaMalloc((void **)&filterCUDA, n * sizeof(double));
    cudaMalloc((void **)&outputCUDA, (n + m - 1) * sizeof(double));

    cudaMemcpy(audioCUDA, audio.samples[0].data(), n * sizeof(double), cudaMemcpyHostToDevice);
    cudaMemcpy(filterCUDA, filter.samples[0].data(), m * sizeof(double), cudaMemcpyHostToDevice);

    MyConvolveCUDA << < 32, 32 >> > (audioCUDA, filterCUDA, outputCUDA, n, m);
    cudaDeviceSynchronize();

    cudaMemcpy(output.samples[0].data(), outputCUDA, (n + m - 1) * sizeof(double), cudaMemcpyDeviceToHost);

    cudaFree(audioCUDA); cudaFree(filterCUDA); cudaFree(outputCUDA);

    output.save("CUDA_output.wav");
}

你能明白怎么回事吗?我想检查传递给 MyConvolveCUDA 的数组,但每次尝试时都会出现访问冲突错误。

提前致谢!

标签: c++cudaconvolution

解决方案


您正在启动 CUDA 内核MyConvolveCUDAMyConvolveCUDA<<<32,32>>>这意味着您正在启动 32 个块,每个块有 32 个线程(1024 个线程)。在内核中,您使用的是 2D 线程索引,但您只启动了 1D 线程。

MyConvolveCUDA<<<M,N>>>被解释为

MyConvolveCUDA<<<dim3(M,1,1),dim3(M,1,1)>>>

其中 M 是块数,N 是每个内核的线程数,即;我们仅在 x 方向上启动线程。为此,threadIdx.y并且blockIdx.y将始终为 0。

如果您想在 2 维中启动它,那么您应该将内核称为MyConvolveCUDA<<<dim3(M,N),dim3(M,N)>>>.

要检查内核中的数组,您可以像这样打印它们

int i = threadIdx.x + blockIdx.x * blockDim.x;
# if __CUDA_ARCH__>=200 
    if(i==0){
        for(int iter=0;iter<n;iter++)
            printf("%ld ", A[iter]); 
        for(int iter=0;iter<m;iter++)
            printf("%ld ", B[iter]); 
    }
#endif 

推荐阅读