Was ist der effizienteste Weg, um eine komplexe Matrix mit geringer Dichte von meinem Fortran-Code auf PETSc zu übertragen? Ich verstehe, dass dies problemabhängig ist, deshalb habe ich versucht, so viele relevante Details wie möglich unten anzugeben.
Ich habe mit dem FEAST-Eigenwertlöser [1] für Probleme vom Typ , die Dimension der Matrizen A und B ist N , und fast die ganze Zeit wird damit verbracht, N × N komplexe lineare zu lösen System mit M0 rechts. N ist groß (Anzahl der FE-Basisfunktionen in 3D), M0 ist klein (in meinem Fall interessiert mich M0 ~ 20). Die Matrizen A und B sind real, symmetrisch und dünn, und das komplexe Problem, das gelöst werden muss, ist z A - B , wobei zist eine komplexe Zahl. Der Autor von FEAST scheint zu vermuten, dass die Genauigkeit der Lösung für dieses lineare System nicht sehr hoch sein muss, um hochgenaue Eigenwerte und Eigenvektoren zu erhalten. Daher könnten einige schnelle iterative Löser eine gute Lösung dafür sein.
Bisher habe ich nur Lapack für das komplexe System verwendet, und das funktioniert hervorragend für auf meinem Computer. Für größere N weiß ich noch nicht, was der beste Löser ist, deshalb wollte ich einfach PETSc verwenden und dort mit den iterativen Lösern spielen.
Ich habe einen einfachen C-Treiber geschrieben und ihn von Fortran aus aufgerufen, siehe [2] für den gesamten Code, aber das Problem liegt nur bei diesem Teil (Update: Ich habe hier alle Zeilen eingefügt, um die Matrix zu erstellen, wie ich gerade festgestellt habe dass dies relevant ist):
ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr);
ierr = MatSetFromOptions(A);CHKERRQ(ierr);
ierr = MatSetOption(A,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr);
ierr = MatSetUp(A);CHKERRQ(ierr);
for (i=0; i<n; i++) col[i] = i;
ierr = MatSetValues(A,n,col,n,col,A_,INSERT_VALUES);CHKERRQ(ierr);
Was extrem langsam ist (dh für N ~ 1500 dauert dies vielleicht 2 Sekunden, während das tatsächliche Lösen sofort erfolgt), tatsächlich MatSetValues
dauert die Linie fast 100% der Zeit für die gesamte Eigenwertberechnung ... Die Matrix A_ ist a 2D-Matrix, die aus Fortran stammt. Ich habe versucht, das zu deaktivieren, MAT_IGNORE_ZERO_ENTRIES
aber es machte keinen Unterschied. Ich denke also, dass das Problem einfach darin besteht, dass ich selbst für moderates N wie 1500 ein spärliches Matrixformat verwenden muss. Ist das richtig?
MatCreateSeqAIJWithArrays
MatCreateSeqAIJWithArrays
Ich würde gerne wissen, ob dieser CSR-Ansatz für dieses Problem richtig ist oder ob ich es falsch mache (eindeutig ist mein ursprünglicher Ansatz mit dem MatSetValues
nicht optimal). Danke für alle Tipps.
[1] http://www.ecs.umass.edu/~polizzi/feast/
[2] https://github.com/certik/hfsolver/pull/14
[3] http://www.mcs.anl.gov/petsc/petsc-3.1/docs/manualpages/Mat/MatCreateSeqAIJWithArrays.html
quelle
MatSetValues()
. Ist es für die Übersetzung einer vorhandenen Matrix nicht schneller, nurMatCreateSeqAIJWithArrays
einmal anzurufen, als anzurufen ,MatSeqAIJSetPreallocation
und dannMatSetValues
für jede Zeile?MatSetValues()
Vergleich zur Berechnung der Einträge und zur Lösung des Systems sehr gering. AußerdemMatSetValues[Blocked][Local]()
verhindert das Zusammenstellen mit, dass Ihr Code von einem bestimmten Matrixformat abhängt, sodass Sie zur Laufzeit Speicherformate auswählen können.