@@ -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*/
9001075long SparseMatrix::getNZGlobalElementCount () const
9011076{
902- long nElement = getBlockSize () * getNZGlobalCount ();
1077+ long nGlobalNZ = getNZGlobalCount ();
9031078
904- return nElement ;
1079+ return getNZElementCount (nGlobalNZ) ;
9051080}
9061081
9071082/* *
0 commit comments