2017-07-03 16 views
0

私は、この例では、各行に最大128個の要素を持つ(この例では)次元2e8 x 1e6の大きな疎行列にEigenを使用しています。 docsに従って、私はreserveに非ゼロ要素を挿入する前にメモリを割り当てるように呼びます。大きな行列の場合、reservestd::bad_alloc例外をスローします。Eigen :: SparseMatrix :: reserveの割り振り例外

$ clang++ -march=native -O3 -isystem eigen-3.3.3 test_sparse.cpp -o test_sparse && ./test_sparse 
Reserving memory 
terminate called after throwing an instance of 'std::bad_alloc' 
    what(): std::bad_alloc 
[1] 26431 abort  ./test_sparse 

q = 49に行あたりの非ゼロ要素の数を減少させるかまたは以下の微細実行:Ubuntuの16.04でclang++又はg++でコンパイル

#include <iostream> 
#include <Eigen/Core> 
#include <Eigen/Sparse> 

int main() 
{ 
    typedef Eigen::SparseMatrix<float, Eigen::RowMajor, long long int> SparseMat; 

    size_t n = 1000000, r = 200; 
    SparseMat T (r*n, n); 

    std::cerr << "Reserving memory" << std::endl; 

    size_t q = 128; 
    T.reserve(Eigen::VectorXi::Constant(r*n, q)); 

    std::cerr << "Ready to start inserting elements..." << std::endl; 
} 

は、実行時にstd::bad_alloc例外をスローします。 q = 50以上を設定すると、エラーが発生します。同様のテストが行​​列サイズを保持します。

StorageIndexには64ビット整数型を明示的に使用しています。 2^63-1 = 9.2e18よりも小さいので、この行列の1.28e8の非ゼロ要素を索引付けするには、64ビットで十分なはずです。限界では、このサイズの密な行列(2e8 x 1e6 = 2e14 < 9.2e18)をインデックスするだけでも十分であるはずです。

したがって、私の質問は以下のとおりです。

  1. は、私は、64ビットStorageIndexは、これらの行列の次元のために十分 であると仮定する正しいですか?

  2. もしそうなら、これはバグですか、私の例では間違っていますか?

  3. ない場合、私はまた__int128_tを試してみましたが、それは次のよう コンパイラエラー生成: EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); をどのように私は、関連する特性を追加することができますか?

  4. 最後に、トリプレットからの初期化などを使用して、この問題を回避できますか?

+0

を提供することができますか? –

+0

良い点ですが、私の64GBは1行あたり128要素では不十分です。 – ChD

答えて

0

std::bad_alloc通常、あなたが

T.reserve(Eigen::VectorXi::Constant(r*n, q));がメモリ内のR * N * Q = 1000000 * 200 * 128山車を割り当て、私は驚かないメモリを使い果たし、あなたは〜100ギガバイトを割り当てるしようとしている与えられた意味。技術の現在の状態で

ない非常に多くのマシンは、私が固有に慣れていないんだけど何バイトのデータのご予約しようとしている、あなたは十分なメモリを持っていないので、多くのメモリ

+0

あなたは優秀な点を作っていますが、行ごとに128個の浮動小数点は、私が利用できる64GBのRAMには実際には収まりませんが、 'q = 50'の例は(〜37GB)必要です。これを回避する方法の提案(メモリを増やすことを除く) – ChD

+0

@ChDそれは連続したメモリのチャンクですか?その場合、断片化のために使用可能なメモリが不足している可能性があります。 –

+0

はい、そうだと思います。また、q = 50の37GBは値(行列係数)のためのものに過ぎず、そのインデックスは同じ量の空間を占めます。 8GBシステムでもq = 8を使用していましたが、メモリーはボトルネックにはなりませんでした。しかし、拡張されたマトリックスの場合は明らかです。私にそれを指摘してくれてありがとう。 – ChD

関連する問題