Sparse-matrix-Vektor-Multiplikation in CUDA

Ich versuche zu implementieren matrix-Vektor-Multiplikation auf der GPU (mit CUDA).

In meinem C++ - code (CPU), lade ich die matrix als eine Dichte matrix, und dann führe ich die matrix-Vektor-Multiplikation mit CUDA. Ich bin auch mit shared memory, die Leistung zu verbessern.

  1. Wie kann ich laden Sie die matrix in einer effizienten Art und Weise, zu wissen, dass meine matrix ist eine sparse-matrix?

Unten ist mein C++ - Funktion zum laden der matrix:

int readMatrix( char* filename, float* &matrix, unsigned int *dim = NULL, int majority = ROW_MAJOR )
{
    unsigned int w, h, x, y, num_entries;

    float val;

    std::ifstream file( filename );

    if ( file )
    {
        file >> h >> w >> num_entries;
        cout << w << " " << h << " " << num_entries << "\n";

        assert( w == h || w == 1 || h == 1 );

        if( dim != NULL ) *dim = std::max( w, h );

        matrix = new float[ w * h ];

        unsigned int i;
        for( i = 0; i < num_entries; i++ ){

            if( file.eof() ) break;

            file >> y >> x >> val;

            if( majority == ROW_MAJOR ){

                matrix[ w * y + x ] = val;

            } else if( majority == COLUMN_MAJOR ){

                matrix[ h * x + y ] = val;
            }
        }
        file.close();

        if( i == num_entries )
            std::cout << "\nFile read successfully\n"; 
        else
            std::cout << "\nFile read successfully but seems defective:\n num entries read = " << i << ", entries epected = " << num_entries << "\n"; 

        //print first few elements
        if( w == h ){
            for( unsigned int i = 0; i < w; i++ ){

                printf("\n");
                for( unsigned int j = 0; j < h; j++ ){

                    printf("%.2f ", matrix[ j + w * i ] );
                }
            }   
        }
        else{   

            printf("\n");
            for( unsigned int j = 0; j < h; j++ ){

                printf("%.2f ", matrix[ j ] );
            }
        }

    } else {

        std::cout << "Unable to open file\n";
        return false;
    }

    return true;
}

Unten ist mein CUDA-Kernel-Funktion, mit der die matrix-Vektor-Multiplikation:

__global__ void
_cl_matrix_vector_( float *A, float *b, float *x, int dim )
{
    extern __shared__ float vec[];
    unsigned int idx = blockIdx.x * blockDim.x + threadIdx.x;
    float temp = 0.0;
    int vOffs = 0;

    //load vector into shared memory
    for (int i = 0; i < (dim/blockDim.x) + 1 ; ++i, vOffs+= blockDim.x) {
        vec[vOffs + threadIdx.x] = b[vOffs + threadIdx.x];
    }

    //make sure all threads are synchronized
     __syncthreads();

    if (idx < dim) {
        temp = 0.0;
        //dot product (multiplication)
        for (int i = 0; i < dim; i++){
            temp += A[idx * dim + i] * vec[i];
        }
         x[idx] = temp;
    } 

}
  1. Was sind die notwendigen Veränderungen, die ich machen muss um auf meine CUDA-code zu berücksichtigen, dass meine matrix ist eine sparse-matrix?
  2. Fand ich heraus, aus einem forum, die können wir auch die Polsterung, um in der Lage sein, um die Leistung zu optimieren, aber dies erfordert, mich zu ändern die Weise, die ich Lesen Sie die matrix /Sortieren der matrix. Irgendwelche Ideen, wie diese umzusetzen Polsterung in der Art, wie ich Lesen Sie die matrix und die Berechnung ausführen?
  • Die richtige Antwort hängt ganz von dem format, in dem die sparse-matrix gespeichert ist. Siehe nvidia.com/object/nvidia_research_pub_001.html für ein Papier, das beschreibt die Vorzüge der verschiedenen sparse-Formate auf GPUs.
InformationsquelleAutor all_by_grace | 2011-05-11
Schreibe einen Kommentar