Ich verwende Eigen für eine große, spärliche Matrix von (in diesem Beispiel) Dimensionen 2e8 x 1e6, die höchstens 128 Elemente in jeder Zeile hat. Gemäß dem docs rufe ich reserve
auf, um Speicher zuzuordnen, bevor die Nicht-Null-Elemente eingefügt werden. Bei großen Matrizen löst reserve
eine std::bad_alloc
Ausnahme aus.Zuordnung Ausnahme in Eigen :: SparseMatrix :: Reserve
#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;
}
Kompilieren mit clang++
oder g++
auf Ubuntu 16.04 führt den std::bad_alloc
Ausnahme während der Laufzeit:
$ 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
Verringerung der Anzahl der Nicht-Null-Elementen pro Zeile q = 49
oder darunter läuft gut. Einstellung q = 50
oder höher erzeugt den Fehler. Ähnliche Tests gelten für die Matrixgröße.
Beachten Sie auch, dass ich explizit den 64-Bit-Integer-Typ für die StorageIndex
verwenden. Es ist mein Verständnis, dass 64-Bit ausreichend sein sollte, um die 1.28e8 Nicht-Null-Elemente in dieser Matrix zu indizieren, weil sie kleiner als 2^63-1 = 9.2e18 ist. Im Limit sollte es sogar ausreichen, eine dichte Matrix dieser Größe zu indizieren (2e8 x 1e6 = 2e14 < 9.2e18).
Daher meine Fragen sind:
Am ich richtig anzunehmen, dass die 64-Bit-
StorageIndex
für diese Matrix Dimensionen ausreichend ist?Wenn ja, ist das ein Fehler oder ist in meinem Beispiel etwas falsch?
Wenn nicht, ich habe auch versucht,
__int128_t
, aber das erzeugt den folgenden Compiler-Fehler:EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
Wie kann ich die relevanten Merkmale hinzufügen?Kann dieses Problem schließlich umgangen werden, indem zum Beispiel die Initialisierung von Triplets verwendet wird?
Ich bin nicht mit Eigen vertraut, aber wie viele Bytes von Daten versuchen Sie zu reservieren und haben Sie genug Speicher haben? –
Guter Punkt, meine 64 GB sind nicht ausreichend für 128 Elemente pro Zeile. – ChD