Lapack: 暗黙的および明瀺的なすべおの単粟床ワヌクスペヌスク゚リでの粟床の䜎䞋

䜜成日 2021幎07月19日  Â·  6コメント  Â·  ゜ヌス: Reference-LAPACK/lapack

みなさん、こんにちは。

最近、lapackeむンタヌフェヌスを介しおssyevdを䜿甚しおいるずきに゚ラヌに遭遇したした。
これは、䞀般的なlapackむンタヌフェヌスの問題を瀺しおいたす。 こんなふうになりたす

lapackの暙準むンタヌフェヌスによるず、ssyevdのような倚くのルヌチンは2回呌び出す必芁がありたす。
特定のマトリックスサむズに必芁なスクラッチメモリの量をルヌチンに尋ねるず、
そしお、必芁なスクラッチメモリセクションを䜿甚しお、ルヌチンを本栌的に呌び出したす。
パラメヌタずしお。

この最初の呌び出しをよく芋るず、必芁なメモリサむズが返されたす。
ssyevdのようなルヌチンの堎合、lapackのドキュメントによるず、
メモリ芁件は、 float倀ぞのポむンタを介しお返されたす。
したがっお、メモリを蚈算するずきは、䞀連の倀を通過したす。

calculate memory       ->    store value in reference   ->  retrieve the value for use (allocation)
    int64                            float                              int64

これは、ilp64むンタヌフェむスの堎合はint64であり、それ以倖の堎合はint32になりたす。
したがっお、本質的には、メモリ倀の䞭間的な短瞮がありたす。
63ビットから24ビット!!!
より正確には、IEEE 754フロヌト衚珟の最も倖偎のセットビット間の24ビットたで
32ビット敎数の堎合でも、31ビットから24ビットに短瞮されたす。

したがっお、過去のようにメモリ芁件の蚈算を「手動で」呌び出す堎合
どこがうたくいかないかを知るチャンスがあるかもしれたせんが、それでも短絡を防ぐこずはできたせん
浮動小数点倀に。 最新のlapackeむンタヌフェヌスを介しお自動メモリ割り圓おを䜿甚する堎合
ルヌチンが䞖話をするこずを宣䌝しおいるので、あなたは䜕が間違っおいる可胜性があるのか​​さえ分かりたせん
それ自䜓ですべおのメモリ管理の

これは、lapackのすべおの単粟床ルヌチンs / cで発生したす。
䞭間ステップずしおのメモリ芁件。
倍粟床に切り替えるず、代わりに倍粟床参照が䜿甚されたす。
代わりに䞭間倀を53ビットに増やしたすが、これはただ64ビットに近くありたせん
64ビットむンタヌフェむスを想定したす。

回避策、4぀の可胜な方法

  1. 単䞀たたは耇雑なlapackルヌチンを䜿甚する堎合は、Clapackeむンタヌフェむスを介した自動メモリ割り圓おを䜿甚しないでください。
  2. 2呌び出しlapack関数メ゜ッドを䜿甚する堎合、メモリ蚈算にはdoubleルヌチンを䜿甚したす
  3. lapackルヌチンのリファレンス実装を芋お、必芁なメモリを自分で蚈算しおください
  4. フロヌト/耇玠行列を䜿甚する堎合は、小さい行列サむズのみを䜿甚しおください

他の人々はこれに出くわしたしたが、本圓の原因にそれを远いかけたせんでした、䟋えば
ssyevdの有効な入力でint64をサポヌトするopenBLASビルドが倱敗する

少なくずも2回の呌び出し方法では、これはバグではなく、蚭蚈䞊の欠陥であるこずを匷調する必芁がありたす。
lapackeの自動メモリ割り圓おの堎合、かなり深刻なバグず芋なす必芁がありたす。

よろしく、

酞化剀

最も参考になるコメント

lworkをIN / OUTに倉曎するこずは、元々は優れた゜リュヌションですが、䞋䜍互換性はありたせん。 その堎合、アプリケヌションは、LAPACKのバヌゞョンが<= 3.10たずえばであるか> 3.10であるかを認識しお、lworkの入手先を知る必芁がありたす。 さらに悪いこずに、アプリケヌションがconst倀を枡す堎合がありたすconstのたたであるず期埅したす。そのため、LAPACKがその動䜜を倉曎しおその倀を䞊曞きするず、非垞に有害になりたすUB。 たずえば、MAGMAでは次のようになりたす。

    const magma_int_t ineg_one = -1;
    ...
            magma_int_t query_magma, query_lapack;
            magma_zgesdd( *jobz, M, N,
                          unused, lda, runused,
                          unused, ldu,
                          unused, ldv,
                          dummy, ineg_one,  // overwriting ineg_one would break MAGMA
                          #ifdef COMPLEX
                          runused,
                          #endif
                          iunused, &info );
            assert( info == 0 );
            query_magma = (magma_int_t) MAGMA_Z_REAL( dummy[0] );

私が数幎前に提案しおMAGMAに実装した゜リュヌションは、work [1]で返されたlworkを少し切り䞊げるために、単にsgesddなどで行われるため、戻り倀は垞に意図した倀以䞊になりたす。 https://bitbucket.org/icl/magma/src/master/control/magma_zauxiliary.cppを参照し、 ください。 生成された単粟床バヌゞョンのリリヌスを参照しおください。基本的に眮換

    WORK( 1 ) = MAXWRK

ず

    WORK( 1 ) = lapack_roundup_lwork( MAXWRK )

ここで、関数lapack_roundup_lworkは、 magma_*make_lworkず同様に、わずかに切り䞊げたす。 MAGMAでは、単粟床epsを䜿甚し、蚈算を2倍にしお、1 + epsを掛けお切り䞊げたした。 そうすれば、既存のアプリケヌションは、ワヌクスペヌスク゚リを倉曎するこずなく正しく動䜜したす。

さらにテストした結果、lwork> 2 ^ 54の堎合、LAPACK定矩slamch "eps"= 5.96e-ではなく、むプシロン= 1.19e-07別名ulpのC / C ++ / Fortran定矩を䜿甚する必芁があるこずがわかりたした。 08別名ナニット䞞め、u。 ulpを䜿甚しおいる堎合、蚈算は1回で実行できるように芋えたす。

党おのコメント6件

圓時は䜜業配列ポむンタヌを介しおサむズを返すために理にかなっおいるず思いたすが、サむズ指定子を入力/出力倉数に倉換しお正確な倀を返すのを劚げるものは䜕でしょうか 次に、「最新の」呌び出し元は最初にそれを確認し、lworkがただ​​-1の堎合にのみ、䜜業配列メンバヌに頌りたす。「叀い」呌び出し元は倉曎に気づきたせん。

たた、おそらく圓時必芁だったLWORKは物理的に倧きすぎおこの問題を解決できず、ilp64がそれを明らかにしたした。 2呌び出し方匏ではなく、実行時にNB倀が導出される日を倢芋おいたす。

これに関連する2぀のディスカッションスレッドは次のずおりです。
https://icl.cs.utk.edu/lapack-forum/viewtopic.php?t=1418
http://icl.cs.utk.edu/lapack-forum/archives/lapack/msg00827.html

これは、On ^ 2ワヌクスペヌスを必芁ずするアルゎリズムで特に問題になりたす。 On * nbワヌクスペヌスを必芁ずするアルゎリズムの堎合、これはそれほど問題ではありたせん。

はい、これは蚭蚈䞊の欠陥です。

@ martin-frbgC _workむンタヌフェヌスの倉曎案はどのようになりたすか そこにのみ入力ずしおLWORKがありたす。 LWORKをINPUT / OUTPUTに倉曎するず、倧きな倉曎がありたす。 この問題を解決するためのアむデアはありたすか 芋る
https://github.com/Reference-LAPACK/lapack/blob/aa631b4b4bd13f6ae2dbab9ae9da209e1e05b0fc/LAPACKE/src/lapacke_dgeqrf_work.c#L35

LAPACK_dgeqrf__workspace_queryなどのワヌクスペヌス割り圓おサブルヌチンを䜜成するこずもでき、これにより必芁なワヌクスペヌスが返されるず考えおいたした。

りェルプ、私の狡猟な蚈画は、地味なずきは実際には機胜したせん...
しかし、これらは実際には2぀の問題だず思いたす。1぀はlapack_intでオヌバヌフロヌする䜜業サむズであり、もう1぀は粟床が限られおいるために䞍実衚瀺のみです。蚈算されたサむズを切り䞊げお埌者を予枬するこずは可胜でしょうか。 「いく぀かの」未䜿甚のメモリ

はい、これは蚭蚈䞊の欠陥です。

私はここで2぀の異なる欠陥を芋るこずができたす

  1. LAPACKの堎合ルヌチンは実倉数を䜿甚しお䜜業サむズを返したす。
  2. LAPACKEの堎合ルヌチンはLAPACKからの欠陥を䌝播したす。

@ martin-frbgのアむデアは、1の良い解決策です。 新しいFortranコヌドでは、WORK1の代わりにLWORKの戻り倀を䜿甚できたす。 眮換のためのいく぀かの半自動手順でコヌドを倉曎しおみるこずができたす。 たずえば、 ssyevd.fでは、眮き換えるこずができたす

  ELSE IF( LQUERY ) THEN
     RETURN
  END IF

に

  ELSE IF( LQUERY ) THEN
     LWORK = LOPT
     RETURN
  END IF

@langouが瀺唆するように、 LAPACKE_dgeqrf__work_query()远加するず、2が解決されたすが、この倉曎に関連する䜜業はたくさんありたす。

lworkをIN / OUTに倉曎するこずは、元々は優れた゜リュヌションですが、䞋䜍互換性はありたせん。 その堎合、アプリケヌションは、LAPACKのバヌゞョンが<= 3.10たずえばであるか> 3.10であるかを認識しお、lworkの入手先を知る必芁がありたす。 さらに悪いこずに、アプリケヌションがconst倀を枡す堎合がありたすconstのたたであるず期埅したす。そのため、LAPACKがその動䜜を倉曎しおその倀を䞊曞きするず、非垞に有害になりたすUB。 たずえば、MAGMAでは次のようになりたす。

    const magma_int_t ineg_one = -1;
    ...
            magma_int_t query_magma, query_lapack;
            magma_zgesdd( *jobz, M, N,
                          unused, lda, runused,
                          unused, ldu,
                          unused, ldv,
                          dummy, ineg_one,  // overwriting ineg_one would break MAGMA
                          #ifdef COMPLEX
                          runused,
                          #endif
                          iunused, &info );
            assert( info == 0 );
            query_magma = (magma_int_t) MAGMA_Z_REAL( dummy[0] );

私が数幎前に提案しおMAGMAに実装した゜リュヌションは、work [1]で返されたlworkを少し切り䞊げるために、単にsgesddなどで行われるため、戻り倀は垞に意図した倀以䞊になりたす。 https://bitbucket.org/icl/magma/src/master/control/magma_zauxiliary.cppを参照し、 ください。 生成された単粟床バヌゞョンのリリヌスを参照しおください。基本的に眮換

    WORK( 1 ) = MAXWRK

ず

    WORK( 1 ) = lapack_roundup_lwork( MAXWRK )

ここで、関数lapack_roundup_lworkは、 magma_*make_lworkず同様に、わずかに切り䞊げたす。 MAGMAでは、単粟床epsを䜿甚し、蚈算を2倍にしお、1 + epsを掛けお切り䞊げたした。 そうすれば、既存のアプリケヌションは、ワヌクスペヌスク゚リを倉曎するこずなく正しく動䜜したす。

さらにテストした結果、lwork> 2 ^ 54の堎合、LAPACK定矩slamch "eps"= 5.96e-ではなく、むプシロン= 1.19e-07別名ulpのC / C ++ / Fortran定矩を䜿甚する必芁があるこずがわかりたした。 08別名ナニット䞞め、u。 ulpを䜿甚しおいる堎合、蚈算は1回で実行できるように芋えたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡