[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Question on matrix preallocation
Hello,
when using petsc (version 2.3.2 on a linux 32bit Intel architecture) to
set up a serial sparse linear system of equations, I recently noticed
the well-known allocation performance problem: The matrix setup needs
more memory than preallocated with a fixed number of column entries for
all rows.
Thus, I switched to the strategy described in the Users Manual (first
counting the number of matrix entries for each row individually and then
using the nnz parameter in MatCreateSeqAIJ()). But this did not change
the dynamic allocation behaviour at all.
Therefore, I tried to bring everything down to a (very) small test
example. I set up a nnz-1D-array of type int and length 4 which holds
the number of expected non-zero column entries for each row of a matrix
(in particular 2 columns in row 0). Using this nnz-array, I create a 4x4
matrix. Afterwards, I set the entry (0,0) of the matrix to a non-zero
value.
The source code part for this simple test can be found in the attached
file testMatPreallocation.cpp.
When I run this test (with the additional -info runtime option), the one
and only matrix entry setting results in an additional memory allocation
(see attached file commandLineOutput.txt)!
This is quite surprising, as I would have expected enough preallocated
memory for the matrix, which is also visible from the output. Am I
misusing or missing something necessary to make the preallocation work?
Thanks in advance for any hints,
best regards
Tobias Neckel
--
Dipl.-Tech. Math. Tobias Neckel
Institut für Informatik V, TU München
Boltzmannstr. 3, 85748 Garching
Tel.: 089/289-18602
Email: neckel@xxxxxxxxx
URL: http://www5.in.tum.de/persons/neckel.html
14:33:53 debug petsc::PETScLibTest::testMatPreallocation() start PETSc mat preallocation test
[0] PetscCommDuplicate(): Duplicating a communicator 1140850688 -2080374784 max tags = 2147483647
[0] MatAssemblyEnd_SeqAIJ(): Matrix size: 4 X 4; storage space: 10 unneeded,0 used
[0] MatAssemblyEnd_SeqAIJ(): Number of mallocs during MatSetValues() is 0
[0] MatAssemblyEnd_SeqAIJ(): Maximum nonzeros in any row is 0
[0] Mat_CheckInode(): Found 1 nodes of 4. Limit used: 5. Using Inode routines
[0] MatAssemblyEnd_SeqAIJ(): Matrix size: 4 X 4; storage space: 14 unneeded,1 used
[0] MatAssemblyEnd_SeqAIJ(): Number of mallocs during MatSetValues() is 1
[0] MatAssemblyEnd_SeqAIJ(): Maximum nonzeros in any row is 1
[0] Mat_CheckInode(): Found 2 nodes of 4. Limit used: 5. Using Inode routines
14:33:53 debug petsc::PETScLibTest::testMatPreallocation() stop PETSc mat preallocation test
#undef __FUNCT__
#define __FUNCT__ "petsc::PETScLibTest::testMatPreallocation"
void petsc::PETScLibTest::testMatPreallocation(){
_log.debug("testMatPreallocation()","start PETSc mat preallocation test");
Mat matrix;
const int rows = 4;
const int cols = 4;
int nnzCounter[rows];
for (int i=0; i<rows; i++) {
nnzCounter[i] = 0;
}
nnzCounter[0] = 2;
nnzCounter[1] = 4;
nnzCounter[2] = 3;
nnzCounter[3] = 1;
_ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD, rows, cols,
PETSC_NULL, nnzCounter, &matrix);
PETSc_CHKERRQ(_ierr);
MatInfo info;
_ierr = MatGetInfo(matrix,MAT_GLOBAL_SUM,&info);
PETSc_CHKERRQ(_ierr);
int expectedNonzerosUsed = 0;
int expectedNonzerosAllocated = 10;
int expectedNonzerosUnneeded = expectedNonzerosAllocated - expectedNonzerosUsed;
validateEquals( (PetscInt)info.nz_used, expectedNonzerosUsed, "testMatPreallocation()");
validateEquals( (PetscInt)info.nz_allocated, expectedNonzerosAllocated, "testMatPreallocation()");
validateEquals( (PetscInt)info.nz_unneeded, expectedNonzerosUnneeded, "testMatPreallocation()");
_ierr = MatAssemblyBegin(matrix,MAT_FINAL_ASSEMBLY);
PETSc_CHKERRQ(_ierr);
_ierr = MatAssemblyEnd(matrix,MAT_FINAL_ASSEMBLY);
PETSc_CHKERRQ(_ierr);
double dummyValue = 1.5;
int row = 0;
int col = 0;
_ierr = MatSetValue(matrix, row, col, dummyValue, ADD_VALUES);
PETSc_CHKERRQ(_ierr);
_ierr = MatAssemblyBegin(matrix,MAT_FINAL_ASSEMBLY);
PETSc_CHKERRQ(_ierr);
_ierr = MatAssemblyEnd(matrix,MAT_FINAL_ASSEMBLY);
PETSc_CHKERRQ(_ierr);
_log.debug("testMatPreallocation()","stop PETSc mat preallocation test");
}