私は、この例では、各行に最大128個の要素を持つ(この例では)次元2e8 x 1e6の大きな疎行列にEigenを使用しています。 docsに従って、私はreserve
に非ゼロ要素を挿入する前にメモリを割り当てるように呼びます。大きな行列の場合、reserve
はstd::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)をインデックスするだけでも十分であるはずです。
したがって、私の質問は以下のとおりです。
は、私は、64ビット
StorageIndex
は、これらの行列の次元のために十分 であると仮定する正しいですか?もしそうなら、これはバグですか、私の例では間違っていますか?
ない場合、私はまた
__int128_t
を試してみましたが、それは次のよう コンパイラエラー生成:EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
をどのように私は、関連する特性を追加することができますか?最後に、トリプレットからの初期化などを使用して、この問題を回避できますか?
を提供することができますか? –
良い点ですが、私の64GBは1行あたり128要素では不十分です。 – ChD