如何处理CUDA的“ cudaMallocPitch”功能中的“ cudaErrorMissingConfiguration”?

时间:2019-08-17 14:36:20

标签: cuda gpu

我正在使用CUDA制作Mandelbrot设置程序。但是,除非要解决CUDA的 cudaErrorMissingConfiguration 函数中的cudaMallocPitch(),否则我无法采取更多措施。你能告诉我一些事情吗?

我的GPU是GeForce RTX 2060 SUPER。

我将在下面显示您的命令行。

> nvcc MandelbrotCUDA.cu -o MandelbrotCUDA -O3

我尝试cudaDeviceSetLimit( cudaLimitMallocHeapSize, 7*1024*1024*1024 )来 调整堆大小。

cudaDeviceSetLimit成功了。

但是我不能再踩一步。我无法打印“ CUDA malloc完成!”

#include <iostream>
#include <thrust/complex.h>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;

#define D 0.0000025 // Tick
#define LIMIT_N 255 
#define INF_NUM 2

#define PLOT_METHOD 2 // dat file : 0, ppm file : 1, ppm file with C : 2 

__global__
void calculation(const int indexTotalX, const int indexTotalY, int ***n, thrust::complex<double> ***c){ // n, c are the pointers of dN, dC.

    for(int i = 0; i < indexTotalY ; i++){
        for(int j = 0; j < indexTotalX; j++){ 
            thrust::complex<double> z(0.0f, 0.0f);
            n[i][j] = 0;
            for(int ctr=1;  ctr <= LIMIT_N ; ctr++){  
                z = z*z + (*(c[i][j]));
                n[i][j] = n[i][j] + (abs(z) < INF_NUM);
            }
        }
    }
}

int main(){

    // Data Path
    string filePath = "Y:\\Documents\\Programming\\mandelbrot\\";
    string fileName = "mandelbrot4.ppm";
    string filename = filePath+fileName;

    //complex<double> c[N][M];
    double xRange[2] = {-0.76, -0.74};
    double yRange[2] = {0.05, 0.1};

    const int indexTotalX = (xRange[1]-xRange[0])/D;
    const int indexTotalY = (yRange[1]-yRange[0])/D;

    thrust::complex<double> **c;
    //c = new complex<double> [N];
    cout << "debug_n" << endl;
    int **n;
    n = new int* [indexTotalY];
    c = new thrust::complex<double> * [indexTotalY];
    for(int i=0;i<indexTotalY;i++){
        n[i] = new int [indexTotalX];
        c[i] = new thrust::complex<double> [indexTotalX];
    }

    cout << "debug_n_end" << endl;

    for(int i = 0; i < indexTotalY; i++){
        for(int j = 0; j < indexTotalX; j++){
            thrust::complex<double> tmp( xRange[0]+j*D, yRange[0]+i*D );
            c[i][j] = tmp;
            //n[i*sqrt(N)+j] = 0;
        }
    }

    // CUDA malloc
    cout << "CUDA malloc initializing..." << endl;  

    int **dN;
    thrust::complex<double> **dC;

    cudaError_t error;


    error = cudaDeviceSetLimit(cudaLimitMallocHeapSize, 7*1024*1024*1024);
    if(error != cudaSuccess){
        cout << "cudaDeviceSetLimit's ERROR CODE = " << error << endl;
        return 0;
    }

    size_t tmpPitch;
    error = cudaMallocPitch((void **)dN, &tmpPitch,(size_t)(indexTotalY*sizeof(int)), (size_t)(indexTotalX*sizeof(int)));
    if(error != cudaSuccess){
        cout << "CUDA ERROR CODE = " << error << endl;
        cout << "indexTotalX = " << indexTotalX << endl;
        cout << "indexTotalY = " << indexTotalY << endl;
        return 0;
    }

    cout << "CUDA malloc done!" << endl;

这是下面的控制台消息。

debug_n
debug_n_end
CUDA malloc initializing...
CUDA ERROR CODE = 1
indexTotalX = 8000
indexTotalY = 20000

1 个答案:

答案 0 :(得分:1)

这里有几个问题:

int **dN;
...
error = cudaMallocPitch((void **)dN, &tmpPitch,(size_t)(indexTotalY*sizeof(int)), (size_t)(indexTotalX*sizeof(int)));

在CUDA分配中使用的正确指针类型是单个指针:

int *dN;

不是双指针:

int **dN;

(因此您尝试使用的内核会传递三指针:

void calculation(const int indexTotalX, const int indexTotalY, int ***n, thrust::complex<double> ***c){ // n, c are the pointers of dN, dC.

几乎可以肯定是行不通的,并且不应以这种方式进行设计,但这不是您要问的问题。)

指针通过其地址传递给分配函数:

error = cudaMallocPitch((void **)&dN,

对于cudaMallocPitch,仅水平请求的维度按数据元素的大小缩放。分配高度不会以这种方式缩放。另外,我将假设X对应于您的分配宽度,Y对应于您的分配高度,因此您也将这些参数取反了:

error = cudaMallocPitch((void **)&dN, &tmpPitch,(size_t)(indexTotalX*sizeof(int)), (size_t)(indexTotalY));

cudaLimitMallocHeapSize不需要进行任何此项设置。它将应用于in-kernel allocations。在8GB卡上保留7GB也可能会引起问题。除非您确定需要(显示的内容并不需要),否则我将直接删除它。

$ cat t1488.cu
#include <iostream>
#include <thrust/complex.h>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;

#define D 0.0000025 // Tick
#define LIMIT_N 255
#define INF_NUM 2

#define PLOT_METHOD 2 // dat file : 0, ppm file : 1, ppm file with C : 2

__global__
void calculation(const int indexTotalX, const int indexTotalY, int ***n, thrust::complex<double> ***c){ // n, c are the pointers of dN, dC.

    for(int i = 0; i < indexTotalY ; i++){
        for(int j = 0; j < indexTotalX; j++){
            thrust::complex<double> z(0.0f, 0.0f);
            n[i][j] = 0;
            for(int ctr=1;  ctr <= LIMIT_N ; ctr++){
                z = z*z + (*(c[i][j]));
                n[i][j] = n[i][j] + (abs(z) < INF_NUM);
            }
        }
    }
}

int main(){

    // Data Path
    string filePath = "Y:\\Documents\\Programming\\mandelbrot\\";
    string fileName = "mandelbrot4.ppm";
    string filename = filePath+fileName;

    //complex<double> c[N][M];
    double xRange[2] = {-0.76, -0.74};
    double yRange[2] = {0.05, 0.1};

    const int indexTotalX = (xRange[1]-xRange[0])/D;
    const int indexTotalY = (yRange[1]-yRange[0])/D;

    thrust::complex<double> **c;
    //c = new complex<double> [N];
    cout << "debug_n" << endl;
    int **n;
    n = new int* [indexTotalY];
    c = new thrust::complex<double> * [indexTotalY];
    for(int i=0;i<indexTotalY;i++){
        n[i] = new int [indexTotalX];
        c[i] = new thrust::complex<double> [indexTotalX];
    }

    cout << "debug_n_end" << endl;

    for(int i = 0; i < indexTotalY; i++){
        for(int j = 0; j < indexTotalX; j++){
            thrust::complex<double> tmp( xRange[0]+j*D, yRange[0]+i*D );
            c[i][j] = tmp;
            //n[i*sqrt(N)+j] = 0;
        }
    }

    // CUDA malloc
    cout << "CUDA malloc initializing..." << endl;

    int *dN;
    thrust::complex<double> **dC;

    cudaError_t error;


    size_t tmpPitch;
    error = cudaMallocPitch((void **)&dN, &tmpPitch,(size_t)(indexTotalX*sizeof(int)), (size_t)(indexTotalY));
    if(error != cudaSuccess){
        cout << "CUDA ERROR CODE = " << error << endl;
        cout << "indexTotalX = " << indexTotalX << endl;
        cout << "indexTotalY = " << indexTotalY << endl;
        return 0;
    }

    cout << "CUDA malloc done!" << endl;
}
$ nvcc -o t1488 t1488.cu
t1488.cu(68): warning: variable "dC" was declared but never referenced

$ cuda-memcheck ./t1488
========= CUDA-MEMCHECK
debug_n
debug_n_end
CUDA malloc initializing...
CUDA malloc done!
========= ERROR SUMMARY: 0 errors
$