FortranコードからPETScに複雑なスパース行列を取得する最も効率的な方法は何ですか?これは問題に依存することを理解しているので、以下に関連する詳細をできるだけ多く記載するようにしました。
私は一緒に遊んでてきたFEAST固有値ソルバー[1]タイプの問題のためのの次元は行列AとBがあるN、およびほとんどすべての時間が解決費やされているN × N複素線形をM0右側のシステム。Nは大きく(3DでのFE基底関数の数)、M0は小さい(私の場合はM0〜20に興味がある)。行列AとBは実対称でスパースであり、解を必要とする複雑な問題はz A − Bであり、ここでzは複素数です。FEASTの作成者は、この正確な固有値と固有ベクトルを取得するために、この線形システムの解の精度をそれほど高くする必要がないことを示唆しているようです。そのため、いくつかの高速反復ソルバーは、これに対する優れたソリューションとなる可能性があります。
これまでのところ、複雑なシステムにLapackを使用してきましたが、これは私のコンピューターでにうまく機能します。Nが大きい場合、最適なソルバーがまだわからないので、PETScを使用して、そこで反復ソルバーを試してみたかったのです。
私は単純なCドライバーを作成し、それをFortranから呼び出しました。すべてのコードについては[2]を参照してください。問題はこの部分にあります(更新:マトリックスを作成するためにすべての行をここに配置しました。これが関連していること):
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);
これは非常に遅くなります(つまり、N〜1500の場合、これはおそらく2秒かかりますが、実際にはすぐに解決されます)。実際、MatSetValues
固有値の計算全体に対して、ラインは常にほぼ100%かかります...行列A_は、 Fortranの2Dマトリックス。私は無効にしようとしましたMAT_IGNORE_ZERO_ENTRIES
が、違いはありませんでした。だから問題は単純に、1500のような中程度のNでも、いくつかの疎行列形式を使用する必要があるということだと思いますが、それは正しいですか?
MatCreateSeqAIJWithArrays
MatCreateSeqAIJWithArrays
この問題に対するこのCSRのアプローチが正しいのか、それとも私が間違っているのかを知りたいのです(明らかに、私のオリジナルのアプローチMatSetValues
は最適ではありません)。ヒントをありがとう。
[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
MatSetValues()
。既存の行列を変換する場合、各行に対してMatCreateSeqAIJWithArrays
呼び出しMatSeqAIJSetPreallocation
を行うよりも、一度呼び出すだけの方が高速ではないMatSetValues
ですか?