Skip to content

Commit 7eb58f6

Browse files
committed
LA: add a function to display information about a sparse matrix
1 parent 8294bc1 commit 7eb58f6

File tree

4 files changed

+181
-2
lines changed

4 files changed

+181
-2
lines changed

src/LA/system_matrix.cpp

Lines changed: 177 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,178 @@ void SparseMatrix::squeeze()
436436
squeezeValueStorage();
437437
}
438438

439+
/*!
440+
* Displays matrix information.
441+
*
442+
* \param stream is the output stream
443+
* \param negligiblity is the threshold below which the values are considered
444+
* negligible
445+
* \param[in] indent is the number of spaces to prepend to each row
446+
*/
447+
void SparseMatrix::display(std::ostream &stream, double negligiblity, int indent) const
448+
{
449+
// Initialize padding
450+
std::string padding(indent, ' ');
451+
452+
// Display base information
453+
int blockSize = getBlockSize();
454+
int nBlockElements = blockSize * blockSize;
455+
456+
stream << padding << "General information" << std::endl;
457+
stream << padding << " Block size ............................................ " << blockSize << std::endl;
458+
459+
// Gather local information
460+
long nRows = getRowCount();
461+
long nCols = getColCount();
462+
463+
long nRowElements = getRowElementCount();
464+
long nColElements = getColElementCount();
465+
466+
long nNZBlocks = getNZCount();
467+
long nNZElements = getNZElementCount();
468+
469+
long maxRowNZBlocks = getMaxRowNZCount();
470+
long maxRowNZElements = getMaxRowNZElementCount();
471+
472+
// Count local non-negligible blocks and elements
473+
int nZeroStreak = 0;
474+
long nNZBlockValues = 0;
475+
long nNZElementValues = 0;
476+
for (long k = 0; k < nNZElements; ++k) {
477+
double value = m_values[k];
478+
if (!bitpit::utils::DoubleFloatingEqual()(value, 0., negligiblity, negligiblity)) {
479+
++nNZElementValues;
480+
nZeroStreak = 0;
481+
} else {
482+
++nZeroStreak;
483+
}
484+
485+
if ((k % nBlockElements) == 0) {
486+
if (nZeroStreak < nBlockElements) {
487+
++nNZBlockValues;
488+
}
489+
nZeroStreak = 0;
490+
}
491+
}
492+
493+
// Evaluate local sparisty
494+
std::size_t nBlocks = nRows * nCols;
495+
std::size_t nElements = nRowElements * nColElements;
496+
497+
double blockSparsity = static_cast<double>(nBlocks - nNZBlocks) / nBlocks;
498+
double elementSparsity = static_cast<double>(nElements - nNZElements) / nElements;
499+
500+
double blockValueSparsity = static_cast<double>(nBlocks - nNZBlockValues) / nBlocks;
501+
double elementValueSparsity = static_cast<double>(nElements - nNZElementValues) / nElements;
502+
503+
// Evaluate local memory usage
504+
double valueStorageMemory = nNZElements * sizeof(decltype(m_values)::value_type);
505+
506+
// Display local information
507+
stream << padding << "Local information: " << std::endl;
508+
stream << padding << " Maximum number of non-zero blocks per row ............. " << maxRowNZBlocks << std::endl;
509+
stream << padding << " Maximum number of non-zero elements per row ........... " << maxRowNZElements << std::endl;
510+
stream << padding << " Number of block rows .................................. " << nRows << std::endl;
511+
stream << padding << " Number of block columns ............................... " << nCols << std::endl;
512+
stream << padding << " Number of non-zero blocks (pattern) ................... " << nNZBlocks << std::endl;
513+
stream << padding << " Number of non-zero elements (pattern) ................. " << nNZElements << std::endl;
514+
stream << padding << " Number of non-zero blocks (non-neglibile values) ...... " << nNZBlockValues << std::endl;
515+
stream << padding << " Number of non-zero elements (non-neglibile values) .... " << nNZElementValues << std::endl;
516+
stream << padding << " Sparsity of the blocks (pattern) ...................... " << blockSparsity << std::endl;
517+
stream << padding << " Sparsity of the elements (pattern) .................... " << elementSparsity << std::endl;
518+
stream << padding << " Sparsity of the blocks (non-neglibile values) ......... " << blockValueSparsity << std::endl;
519+
stream << padding << " Sparsity of the elements (non-neglibile values) ....... " << elementValueSparsity << std::endl;
520+
521+
stream << padding << " Memory used by the value storage ...................... ";
522+
if (valueStorageMemory > 1024 * 1024 * 1024) {
523+
stream << valueStorageMemory / (1024 * 1024 * 1024) << " GB";
524+
} else if (valueStorageMemory > 1024 * 1024) {
525+
stream << valueStorageMemory / (1024 * 1024) << " MB";
526+
} else if (valueStorageMemory > 1024) {
527+
stream << valueStorageMemory / (1024) << " KB";
528+
}
529+
stream << std::endl;
530+
531+
#if BITPIT_ENABLE_MPI==1
532+
// Display global information
533+
if (isPartitioned()) {
534+
// Get MPI data types
535+
MPI_Datatype valueMPIDataType;
536+
if (std::is_same<decltype(m_values)::value_type, double>::value) {
537+
valueMPIDataType = MPI_DOUBLE;
538+
} else if (std::is_same<decltype(m_values)::value_type, float>::value) {
539+
valueMPIDataType = MPI_FLOAT;
540+
} else {
541+
throw std::runtime_error("Unable to identify the MPI data type of the matrix values.");
542+
}
543+
544+
// Gather global information
545+
long nGlobalRows = getRowGlobalCount();
546+
long nGlobalCols = getColGlobalCount();
547+
548+
long nGlobalRowElements = getRowGlobalElementCount();
549+
long nGlobalColElements = getColGlobalElementCount();
550+
551+
long nGlobalNZBlocks = getNZGlobalCount();
552+
long nGlobalNZElements = getNZGlobalElementCount();
553+
554+
long maxGlobalRowNZBlocks;
555+
long maxGlobalRowNZElements;
556+
MPI_Allreduce(&maxRowNZBlocks, &maxGlobalRowNZBlocks, 1, MPI_LONG, MPI_MAX, getCommunicator());
557+
MPI_Allreduce(&maxRowNZElements, &maxGlobalRowNZElements, 1, MPI_LONG, MPI_MAX, getCommunicator());
558+
559+
// Count global non-negligible blocks and elements
560+
long nGlobalNZBlockValues;
561+
long nGlobalNZElementValues;
562+
MPI_Allreduce(&nNZBlockValues, &nGlobalNZBlockValues, 1, MPI_LONG, MPI_SUM, getCommunicator());
563+
MPI_Allreduce(&nNZElementValues, &nGlobalNZElementValues, 1, MPI_LONG, MPI_SUM, getCommunicator());
564+
565+
// Evaluate global sparisty
566+
std::size_t nGlobalBlocks = nGlobalRows * nGlobalCols;
567+
std::size_t nGlobalElements = nGlobalRowElements * nGlobalColElements;
568+
569+
double globalBlockSparsity = static_cast<double>(nGlobalBlocks - nGlobalNZBlocks) / nGlobalBlocks;
570+
double globalElementSparsity = static_cast<double>(nGlobalElements - nGlobalNZElements) / nGlobalElements;
571+
572+
double globalBlockValueSparsity = static_cast<double>(nGlobalBlocks - nGlobalNZBlockValues) / nGlobalBlocks;
573+
double globalElementValueSparsity = static_cast<double>(nGlobalElements - nGlobalNZElementValues) / nGlobalElements;
574+
575+
// Evaluate global memory usage
576+
double valueStorageGlobalMemory;
577+
MPI_Allreduce(&valueStorageMemory, &valueStorageGlobalMemory, 1, valueMPIDataType, MPI_SUM, getCommunicator());
578+
579+
// Display information
580+
stream << padding << "Global information: " << std::endl;
581+
stream << padding << " Maximum number of non-zero blocks per row ............. " << maxGlobalRowNZBlocks << std::endl;
582+
stream << padding << " Maximum number of non-zero elements per row ........... " << maxGlobalRowNZElements << std::endl;
583+
stream << padding << " Number of block columns ............................... " << nGlobalCols << std::endl;
584+
stream << padding << " Number of block rows .................................. " << nGlobalRows << std::endl;
585+
stream << padding << " Number of non-zero blocks (pattern) ................... " << nGlobalNZBlocks << std::endl;
586+
stream << padding << " Number of non-zero elements (pattern) ................. " << nGlobalNZElements << std::endl;
587+
stream << padding << " Number of non-zero blocks (non-neglibile values) ...... " << nGlobalNZBlockValues << std::endl;
588+
stream << padding << " Number of non-zero elements (non-neglibile values) .... " << nGlobalNZElementValues << std::endl;
589+
stream << padding << " Sparsity of the blocks (pattern) ...................... " << globalBlockSparsity << std::endl;
590+
stream << padding << " Sparsity of the elements (pattern) .................... " << globalElementSparsity << std::endl;
591+
stream << padding << " Sparsity of the blocks (non-neglibile values) ......... " << globalBlockValueSparsity << std::endl;
592+
stream << padding << " Sparsity of the elements (non-neglibile values) ....... " << globalElementValueSparsity << std::endl;
593+
594+
stream << padding << " Memory used by the value storage ...................... ";
595+
if (valueStorageGlobalMemory > 1024 * 1024 * 1024) {
596+
stream << valueStorageGlobalMemory / (1024 * 1024 * 1024) << " GB";
597+
} else if (valueStorageGlobalMemory > 1024 * 1024) {
598+
stream << valueStorageGlobalMemory / (1024 * 1024) << " MB";
599+
} else if (valueStorageGlobalMemory > 1024) {
600+
stream << valueStorageGlobalMemory / (1024) << " KB";
601+
}
602+
stream << std::endl;
603+
}
604+
#endif
605+
606+
// Display information
607+
stream << padding << "Display information: " << std::endl;
608+
stream << padding << " Negligibility threshold ............................... " << negligiblity << std::endl;
609+
}
610+
439611
/**
440612
* Initialize the storage for the pattern.
441613
*/
@@ -552,6 +724,9 @@ void SparseMatrix::assembly()
552724
if (m_partitioned) {
553725
MPI_Allreduce(&m_maxRowNZ, &m_global_maxRowNZ, 1, MPI_LONG, MPI_MAX, m_communicator);
554726
MPI_Allreduce(&m_nNZ, &m_global_nNZ, 1, MPI_LONG, MPI_SUM, m_communicator);
727+
} else {
728+
m_global_maxRowNZ = m_maxRowNZ;
729+
m_global_nNZ = m_nNZ;
555730
}
556731
#endif
557732

@@ -899,9 +1074,9 @@ long SparseMatrix::getMaxRowNZGlobalCount() const
8991074
*/
9001075
long SparseMatrix::getNZGlobalElementCount() const
9011076
{
902-
long nElement = getBlockSize() * getNZGlobalCount();
1077+
long nGlobalNZ = getNZGlobalCount();
9031078

904-
return nElement;
1079+
return getNZElementCount(nGlobalNZ);
9051080
}
9061081

9071082
/**

src/LA/system_matrix.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class SparseMatrix {
5858
void clear(bool release = false);
5959
void squeeze();
6060

61+
virtual void display(std::ostream &stream, double negligiblity, int indent = 0) const;
62+
6163
void assembly();
6264
bool isAssembled() const;
6365

test/integration_tests/LA/test_LA_parallel_00001.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ int subtest_001(int rank, int nProcs)
7272
}
7373

7474
matrix.assembly();
75+
matrix.display(log::cout(), 1e-14, 0);
7576

7677
// Build system
7778
log::cout() << "Building system..." << std::endl;

test/integration_tests/LA/test_LA_parallel_00002.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ int subtest_001(int rank, int nProcs)
7979
matrix.addRow(rowPattern, rowValues);
8080
}
8181
matrix.assembly();
82+
matrix.display(log::cout(), 1e-14, 0);
8283

8384
// Build system
8485
log::cout() << "Building system..." << std::endl;

0 commit comments

Comments
 (0)