【问题标题】:CUDA - cudaMallocPitch and cudaMemcpy2D use, Error: InvalidValue, InvalidPitchValueCUDA - cudaMallocPitch 和 cudaMemcpy2D 使用,错误:InvalidValue,InvalidPitchValue
【发布时间】:2014-08-14 08:24:18
【问题描述】:

好的,所以我正在尝试为 cuda 制作一个 2D 数组,但这变得很痛苦。错误在标题中并且发生在 cudaMemcpy2D。我认为这个问题对于训练有素的眼睛来说是显而易见的。提前感谢您的帮助,我已经领先于目前正在学习指针的班级。

#include <cuda_runtime.h>
#include <iostream>
#pragma comment (lib, "cudart")

/* Program purpose: pass a 10 x 10 matrix and multiply it by another 10x10 matrix */

float matrix1_host[100][100];
float matrix2_host[100][100];

float* matrix1_device;
float* matrix2_device;  
size_t pitch;
cudaError_t err;

__global__ void addMatrix(float* matrix1_device,float* matrix2_device, size_t pitch){
    // How this works
    // first we start to cycle through the rows by using the thread's ID
    // then we calculate an address from the address of a point in the row, by adding the pitch (size of each row) and  * it by
    // the amount of rows we've already completed, then we can use that address of somewhere at a start of a row to get the colums 
    // in the row with a normal array grab. 

    int r = threadIdx.x;

        float* rowofMat1 = (float*)((char*)matrix1_device + r * pitch);
        float* rowofMat2 = (float*)((char*)matrix2_device + r * pitch);
        for (int c = 0; c < 100; ++c) {
             rowofMat1[c] += rowofMat2[c];
        }

}

void initCuda(){
    err = cudaMallocPitch((void**)matrix1_device, &pitch, 100 * sizeof(float), 100);
    err = cudaMallocPitch((void**)matrix2_device, &pitch, 100 * sizeof(float), 100); 
    //err = cudaMemcpy(matrix1_device, matrix1_host, 100*100*sizeof(float), cudaMemcpyHostToDevice);
    //err = cudaMemcpy(matrix2_device, matrix2_host, 100*100*sizeof(float), cudaMemcpyHostToDevice);
    err = cudaMemcpy2D(matrix1_device, 100*sizeof(float), matrix1_host, pitch, 100*sizeof(float), 100, cudaMemcpyHostToDevice);
    err = cudaMemcpy2D(matrix2_device, 100*sizeof(float), matrix2_host, pitch, 100*sizeof(float), 100, cudaMemcpyHostToDevice);
}

void populateArrays(){
    for(int x = 0; x < 100; x++){
        for(int y = 0; y < 100; y++){
            matrix1_host[x][y] = (float) x + y;
            matrix2_host[y][x] = (float) x + y;
        }
    }
}

void runCuda(){
    dim3 dimBlock ( 100 );
    dim3 dimGrid ( 1 );
    addMatrix<<<dimGrid, dimBlock>>>(matrix1_device, matrix2_device, 100*sizeof(float)); 
    //err = cudaMemcpy(matrix1_host, matrix1_device, 100*100*sizeof(float), cudaMemcpyDeviceToHost);
    err = cudaMemcpy2D(matrix1_host, 100*sizeof(float), matrix1_device, pitch, 100*sizeof(float),100, cudaMemcpyDeviceToHost);
    //cudaMemcpy(matrix1_host, matrix1_device, 100*100*sizeof(float), cudaMemcpyDeviceToHost);
}

void cleanCuda(){
    err = cudaFree(matrix1_device);
    err = cudaFree(matrix2_device);

    err = cudaDeviceReset();
}


int main(){
    populateArrays();
    initCuda();
    runCuda();
    cleanCuda();
    std::cout << cudaGetErrorString(cudaGetLastError());
    system("pause");
    return 0;
}

【问题讨论】:

    标签: c++ cuda


    【解决方案1】:

    首先,通常你应该为matrix1 和matrix2 设置一个单独的音高变量。在这种情况下,它们将与从 API 调用返回的值相同 cudaMallocPitch,但在一般情况下,它们可能不是。

    在您的cudaMemcpy2D 行中,the second parameter to the call 是目标音高。这只是当您为此特定目标矩阵(即第一个参数)调用cudaMallocPitch 时返回的音高值。

    第四个参数是音源音高。由于这是通过普通主机分配进行分配的,因此除了以字节为单位的宽度外,它没有间距。

    所以你的第二个和第四个参数交换了。

    所以不要这样:

    err = cudaMemcpy2D(matrix1_device, 100*sizeof(float), matrix1_host, pitch, 100*sizeof(float), 100, cudaMemcpyHostToDevice);
    

    试试这个:

    err = cudaMemcpy2D(matrix1_device, pitch, matrix1_host, 100*sizeof(float), 100*sizeof(float), 100, cudaMemcpyHostToDevice);
    

    第二次调用cudaMemcpy2D 也是如此。第三次调用实际上没问题,因为它的方向相反,源矩阵和目标矩阵交换了,所以它们与你的音高参数正确对齐。

    【讨论】:

    • 好吧,所以我改变了一些东西,我在想第一个是主机阵列的间距,这让我很困惑。虽然我仍然收到错误 11 InvalidValue
    • 嗯,你在做相当草率的错误检查,所以你真的不知道错误来自哪一行。这是他们教你在课堂上进行错误检查的方式吗?您应该check each and every cuda return value,尤其是当您遇到问题时。无论如何,我错过了您对cudaMallocPitch 的参数也不正确,您需要一个&符号来获取您传递的指针的地址:err = cudaMallocPitch((void**)&amp;matrix1_device, ...
    • 其实我用调试器逐行检查错误的值。它完全来自 cudaMemcpy2D 的第一行,但除此之外,谢谢你,因为这是问题所在,我已经被困了一段时间了。
    猜你喜欢
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多