2017-07-03 55 views
0

我使用本徵爲大,稀疏矩陣(在此實例中)的尺寸2E8 X 1E6,其具有在每行至多128個元件。根據docs,在插入非零元素之前,我呼叫reserve分配內存。對於大型矩陣,reserve會拋出std::bad_alloc異常。分配例外在本徵::稀疏矩陣::儲備

#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; 
} 

clang++g++在Ubuntu 16.04編譯在運行時將引發std::bad_alloc異常:

$ 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的數目或以下運行良好。設置q = 50或更高版本會產生錯誤。類似的測試適用於矩陣大小。

還請注意,我明確地使用64位整數類型爲StorageIndex。我的理解是64位應該足夠用來索引這個矩陣中的1.28e8非零元素,因爲它小於2^63-1 = 9.2e18。在極限情況下,它應該足以索引這種大小的密集矩陣(2e8 x 1e6 = 2e14 < 9.2e18)。

因此,我的問題是:

  1. 我是正確的假設,64位StorageIndex是這些矩陣尺寸足夠 ?

  2. 如果是這樣,這是一個bug或者是錯誤的東西在我的例子嗎?

  3. 如果沒有,我也試過__int128_t,但產生以下 編譯器錯誤: EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); 如何添加相關的特質?

  4. 最後,可這個問題被規避,例如使用從三胞胎的初始化?

+0

我不熟悉的本徵,但如何數據的字節數,你想保留和你有足夠的內存? –

+0

好點,我的64GB不足以支持每行128個元素。 – ChD

回答

0

std::bad_alloc通常意味着你跑出來的內存,給你想分配〜100GB並不讓我感到吃驚

T.reserve(Eigen::VectorXi::Constant(r*n, q));分配R * N * Q = 1000000輛* 200輛* 128輛內存花車。

在目前的技術狀態

沒有很多的機器能提供這麼多的內存

+0

您提出了一個很好的觀點,每行128個浮點數確實不適用於我已有的64GB RAM,儘管'q = 50'的示例應該(〜37GB)。有關如何解決此問題的任何建議(除了獲得更多內存)? – ChD

+0

@ChD這是一塊連續的內存嗎?如果是這樣,由於碎片可能沒有足夠的可用內存。 –

+0

是的,我認爲是。此外,q = 50的37GB僅適用於數值(矩陣係數),而它們的指數將佔用相等的空間量。一段時間以來,我一直在使用q = 8,即使在8GB系統上,內存也不是瓶頸。但對於擴展矩陣來說,它顯然是。謝謝你指點我。我需要重新考慮問題表達式:-) – ChD