0

私は現在、高性能コンピューティングを目的として CUDA を学んでいます。Jacobi Iterations を実装するプロジェクトがあります。プログラムのどこかにメモリ エラーがあり、それを追跡するのに苦労しています。

私のヤコビカーネルは1回の反復を正しく実行し、現在、古いマトリックスと新しいマトリックスの最大差の計算に取り組んでいます。次のコード行をコメントアウトすると:

//diff[idx] = BJacobi[idx] - AJacobi[idx];

できます。ただし、このコード行を含めると、BJacbi のデータが AJacobi のデータの一部で上書きされます (または、少なくとも AJacobi のデータだと思います。ほぼ同じパターンです)。割り当ての問題のように思えますが、どこにあるのかわかりません。

__global__ 
void jacobi(float *diff, float *AJacobi, float *BJacobi, int *bitMask, int size) 
{
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    float sum = 0.0;
    int count = 0;

    if(idx < size * size)
    {
        if(bitMask[idx] == 0)
        { 
            //if left side of matrix
            if(idx - 1 > 0 && idx % size != 0) {
                sum += AJacobi[ idx - 1 ];
                count++;
            }
            //if right side of matrix
            if(idx + 1 < size * size && (idx + 1) % size != 0)
            {
                sum += AJacobi[ idx + 1 ];
                count++;
            }
            //if top of matrix
            if(idx - size > 0)
            {
                sum += AJacobi[ idx - size ];
                count++;
            }
            //if bottom of matrix
            if(idx + size < size * size)
            {
                sum  += AJacobi[ idx + size ];
                count++;
            }
            BJacobi[idx] = sum / count;
        }
        else BJacobi[idx] = AJacobi[idx];
    }

    //diff[idx] = BJacobi[idx] - AJacobi[idx];
}

私の主な機能では

readSparceMatrix(argv[1], &matrix);
array_size = matrix.rowSize * matrix.rowSize;

//we want as many or more threads then data.
dimGrid = array_size / THREADS + 1;
dimBlock = THREADS;

// ---------------------- START ALLOCATION OF DEVICE MEMEORY
err = cudaMalloc( (void**)&diff, array_size * sizeof(float)); 
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
    exit(1);
} 
err = cudaMalloc( (void**)&AJacobi, array_size * sizeof(float) );
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
    exit(1);
} 
err = cudaMalloc( (void**)&BJacobi, array_size * sizeof(float) ); 
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
    exit(1);
} 
err = cudaMalloc( (void**)&MaxDiffTree, array_size * sizeof(float) ); 
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
    exit(1);
} 
err = cudaMalloc( (void**)&bitMask, array_size * sizeof(int) ); 
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMalloc: %s\n", cudaGetErrorString(err));
    exit(1);
} 


// ---------------------- START INTITILIZATION OF DEVICE MEMERY 
err = cudaMemset(diff, 1.0, array_size * sizeof(float));
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
    exit(1);
} 

err = cudaMemset(BJacobi, 0.0, array_size * sizeof(float));
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
    exit(1);
} 

err = cudaMemset(MaxDiffTree, 0.0, array_size * sizeof(float));
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
    exit(1);
} 

err = cudaMemcpy(AJacobi, matrix.data, array_size * sizeof(float) ,cudaMemcpyHostToDevice);
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
    exit(1);
} 

err = cudaMemcpy(bitMask, matrix.mask, array_size * sizeof(int) ,cudaMemcpyHostToDevice);
if (err != cudaSuccess) {
    fprintf (stderr, "cudaMemcpy: %s\n", cudaGetErrorString(err));
    exit(1);
} 

// ---------------------- START MAIN JACOBI LOOP
//while(MaxDiff >  delta){

jacobi<<<dimGrid, dimBlock>>>(diff, AJacobi, BJacobi, bitMask,  matrix.rowSize);
4

1 に答える 1

1

したがって、これは実際には単純なエラーであり、私はそれを理解するのにかなりの時間を費やしました. データよりも多くのスレッドがあるために問題が発生しました。そのため、配列の範囲外にあるスレッド インデックスを持つスレッドがあります。私のコードの最初の if ステートメントはそれをチェックするためのものですが、私の diff 割り当てはインデックス チェックの範囲外でした。if チェックの下に diff ステートメントを移動すると、問題が解決しました。

if(idx < size * size){
    if(bitMask[idx] == 0){ 
        //if left side of matrix
        if(idx - 1 > 0 && idx % size != 0) {
            sum += src[ idx - 1 ];
            count++;
        }
        //if right side of matrix
        if(idx + 1 < size * size && (idx + 1) % size != 0)
        {
            sum += src[ idx + 1 ];
            count++;
        }
        //if top of matrix
        if(idx - size > 0)
        {
            sum += src[ idx - size ];
            count++;
        }
        //if bottom of matrix
        if(idx + size < size * size)
        {
            sum  += src[ idx + size ];
            count++;
        }
        dst[idx] = sum / count;
    }
    else dst[idx] = src[idx];

    diff[idx] = dst[idx] - src[idx];
}   
于 2013-03-05T06:54:48.970 に答える