1

CSR/CSC* マトリックスを Fortran で管理する際によくある問題についてお聞きしたいと思います。N 個の実数値を持つベクトル V があるとします。ベクトルは、特定のサイズで事前に割り当てられています。ここで、インデックス P の中央に値を追加する必要があります。ブルート フォース コードは次のようになります。

allocate(tempV(N))
tempV=V
deallocate(V)
allocate(V(N+1))
V=(/tempV(1:P-1), newValue, tempV(P:N)/)
deallocate(tempV)

明らかに、一度行えば問題ありませんが、何千回も繰り返すのはあまり効率的ではありません。メモリは、挿入したい値ごとに4回いっぱいになり、空になります。

この問題に取り組むためのより良い手順を知りたいです。プレーンな Fortran (推奨) を提案できますが、MKL/Lapack/Blas などのライブラリによるソリューションも提案できます。

補遺: RESHAPEでできますか? この定義(Fortran ブックの定義と同じ)を実行すると、次のようなことができます。

REAL, DIMENSION(1:1) :: newPad = (/ newValue /)
V=RESHAPE(V, (/ N+1 /), PAD=newPad)

V の末尾に値が追加されたので、次の順列を作成します。

V=(/ V(1:P-1), V(N+1:N+1), V(P:N) /)

このようにして、一時的なベクトルを明示的に作成して割り当てを失うことを回避できます。

RESHAPE は既にライブラリで並列化できるため、効率的でスケーラブルでしょうか?


* PS : 明確にするために、CSR = 圧縮スパース行形式、CSC = 圧縮スパース列形式、詳細はこちら:

MKL 定義: http://software.intel.com/sites/products/documentation/hpc/mkl/mklman/GUID-9FCEB1C4-670D-4738-81D2-F378013412B0.htm

4

2 に答える 2

3

Fortran 2003 サブルーチンmove_allocは、この目的のために導入されました。実際にデータをコピーすることなく、割り当てステータス、配列境界、動的型、型パラメーター、および値をソースからターゲットに移動します。ソース変数の割り当てが解除されます。

move_allocコピー操作が 1 回だけ必要な短い例を使用したコードの変更:

allocate(tempV(N+1)) 
tempV(:P-1) = V(:P-1)
tempV(P)    = newValue
tempV(P+1:) = V(P:) 
call move_alloc(tempV, V)

もちろん、一度に複数のアイテムに対してこれを行うと、割り当てのオーバーヘッドが削減されますが、それは不可能な場合があります。

編集
F2003 機能を使用できない場合のポインタの推奨については、おそらく次のようなサブルーチンを使用できます。

pure subroutine insert(arr, val, pos)
  real, pointer, intent(inout) :: arr(:)
  real, intent(in)             :: val
  integer, intent(in)          :: pos

  real, pointer :: temp(:)

  if(associated(arr)) then
    allocate(temp(lbound(arr,1):ubound(arr,1) + 1))
    ! ...or perhaps check/do something if pos is not within these bounds

    temp(:pos-1) = arr(:pos-1)
    temp(pos)    = val 
    temp(pos+1:) = arr(pos:)

    deallocate(arr)
    arr => temp
  endif
end subroutine insert

もちろん、これを目的に合わせて簡単に調整したり、より一般的なものにすることもできます。これは、割り当てられたポインター変数で使用できます。

real, pointer :: V(:)
! :
allocate(V(10))
V = 1.
! :
call insert(V, 3.141592, 5)
于 2013-01-30T16:45:44.953 に答える
1

問題は、挿入直後に CSR 形式が必要かどうか、またはより挿入しやすい形式で最初に挿入を増やしてから CSR に変換できるかどうかです。

sparskitとその連結リスト ストレージ形式を確認するか、新しい要素の連結リストを自分で作成し、挿入が完了したら、データの再シャッフルを大幅に省いて、新しい CSR 形式のマトリックスを構築できます .

于 2013-01-31T11:38:43.893 に答える