2017-01-26 7 views
0

Ubuntu 14.04でNVIDIA GEFORCE 840MでCUDA 7.5を使用したHD画像処理に取り組んでいます。私は3750 * 3750のイメージを持っています。この次元の配列を初期化するのには問題があります。cudaを使用して大きな画像を初期化する

1)cudaMallocに代わりmalloc

2)のcudaMallocを使用する:kがあるまで次のコードは、およそ

__device__ int sImg; 

__device__ int *B; 

/* ############################### INITILIAZE ############################## */ 

__global__ void initialize(int *tab, int v, int s) 
{  
    int k = blockDim.x*blockIdx.x + threadIdx.x ; 
    if (k < s) 
    tab[k] = v; 
} 

/* ########################### The parent kernel ########################### */ 

__global__ void EDGE(int *A, int *C ,int h, int w, int dim, int nbScales) 
{ 
    sImg = dim*dim; 
    cudaMalloc((void**)&B,sImg*sizeof(int)); 

    int threadsPerBlock = 256; 
    int blocksPerGrid = (sImg + threadsPerBlock -1)/threadsPerBlock; 

    /// I have troubles here, it does not complete the process 
    initialize<<<blocksPerGrid,threadsPerBlock>>>(B,0,sImg); 
    cudaDeviceSynchronize(); 
    initialize<<<blocksPerGrid,threadsPerBlock>>>(C,0,sImg); 
    cudaDeviceSynchronize(); 

    /// A transormation into frequency domain 
    FSDWT <<< 1 , nbScales >>> (A,B, h, w,dim,nbScales); 
    cudaDeviceSynchronize(); 

    /// Tresholding the transform          
    Treshold<<<1,1>>>(B,C,dim*dim); 
    cudaDeviceSynchronize(); 

    cudaFree(B); 
} 

/* ############################ call from host ############################ */ 

extern "C" void EDGE_host(int *A,int *B,int h,int w,int dim, int nbScales) 
{ 
    EDGE <<< 1 , 1 >>> (A,B, h, w,dim,nbScales); 
} 

4000は

+1

あなた 'それがホスト上で実行するためにはるかに適したコードが含まれているようparentKernel'に見える - 私は、ダイナミック並列処理を使用しての練習以外のカーネルとして、それを実行する理由を考えることはできません。それは意図的なのでしょうか? – tera

+0

さらに、返されたエラーをすべてのCUDAコールでチェックします。それは下の私の答えがなぜ重要であるかを示すでしょう。 – tera

+0

私はここに私のコードを置くことができません。なぜなら私は多くの子カーネルと操作を持っているからです。私はちょうど他のカーネルに移動する前に子供を初期化するより複雑な解決したい。 CUDAはエラーを返さない – assma

答えて

1

[OK]を、物事のカップルは、ありがとうございました実行しますdim*dimの代わりにsizeImageを使用してください(私は同じものと仮定します)

+0

mallocをcudaMallocに置き換え、dim * dimをsizeImageに置き換えますが、計算は4511で終了します。 – assma

+0

修正するたびに元の質問のコードを更新できますか? – pSoLT

+1

また、 'parentKernel'の使い方をもっと詳しく説明できますか? – pSoLT

1

Memorデバイスコードから作られたyの割り当ては、限られたサイズのプールから満たされる。 cudaDeviceSetLimit(cudaLimitMallocHeapSize, ...)を呼び出す前にデバイス側の割り当て用にさらに多くのメモリを確保するか、cudaMalloc()を使用してホスト側からメモリを割り当てます。

メモリをどれくらい選択するかを選択するときは、デバイス上でmalloc()を呼び出すとスレッドごとに個別の割り当てが行われるため、並列で実行されるスレッドの数が増えると要件がすぐに増えます。あなたの場合のように、カーネルがメモリを解放しない場合、必要なメモリは、並列で実行されるスレッドの数ではなく、実行されるスレッドの総数とともに増加します。

0

大変ありがとうございました 私の問題はテラ氏の答えで解決しました。効果的には、メモリ割り当てに問題がありました。カーネルを呼び出す前にmain関数に次の行を追加しました。

cudaDeviceSetLimit(cudaLimitMallocHeapSize, 128*1024*1024);

関連する問題