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.
- 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;
}
}
- 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?
- 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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist ein sehr Alter Beitrag und ich möchte hervorheben, dass
cuSPARSE
(seit einiger Zeit) macht die Verfahren für die Multiplikation zwischen sparse-Matrizen oder zwischen einer sparse-matrix und eine Dichte Vektor zur Verfügung.Für die
csr
- format, die entsprechenden routine für die Multiplikation zwischen einer sparse-matrix und eine Dichte Vektor istcusparse<t>csrmv
. Unten, eine voll gearbeitet-Beispiel zeigt Ihre Verwendung.Möchten Sie vielleicht einen Blick auf die sehr gute SCHWELLE Bibliothek. Sie implementieren sparse-Matrizen in einer Vielzahl von Formaten (coo, csr, ellpack -, diagonal-und einen hybrid zwischen ellpack und coo). Jede mit Ihren eigenen Vorteile, wie in der Dokumentation beschrieben. Die meisten von Ihnen sind "standard" sparse-matrix-Formate, über die weitere Informationen finden Sie online. Nicht eine komplette Antwort auf deine Frage, aber vielleicht sollte es einen Ausgangspunkt.