From 5c30e75e270137b724d07441141579e0f131095d Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 24 Feb 2022 15:26:13 -0700 Subject: [PATCH] Error out with too large Trilinos sparsity patterns. --- source/lac/trilinos_sparsity_pattern.cc | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/source/lac/trilinos_sparsity_pattern.cc b/source/lac/trilinos_sparsity_pattern.cc index 71111b2b6e..2dd0ffc391 100644 --- a/source/lac/trilinos_sparsity_pattern.cc +++ b/source/lac/trilinos_sparsity_pattern.cc @@ -257,6 +257,18 @@ namespace TrilinosWrappers graph.reset(); column_space_map = std::make_unique(col_map); + AssertThrow((TrilinosWrappers::max_my_gid(row_map) - + TrilinosWrappers::min_my_gid(row_map)) * + std::uint64_t(n_entries_per_row) < + std::numeric_limits::max(), + ExcMessage("The TrilinosWrappers use Epetra internally which " + "uses 'signed int' to represent local indices. " + "Therefore, only 2,147,483,647 nonzero matrix " + "entries can be stored on a single process, " + "but you are requesting more than that. " + "If possible, use more MPI processes.")); + + // for more than one processor, need to specify only row map first and // let the matrix entries decide about the column map (which says which // columns are present in the matrix, not to be confused with the @@ -303,6 +315,9 @@ namespace TrilinosWrappers TrilinosWrappers::n_global_elements(row_map)); column_space_map = std::make_unique(col_map); + + // Translate the vector of row lengths into one that only stores + // those entries that related to the locally stored rows of the matrix: std::vector local_entries_per_row( TrilinosWrappers::max_my_gid(row_map) - TrilinosWrappers::min_my_gid(row_map)); @@ -310,6 +325,17 @@ namespace TrilinosWrappers local_entries_per_row[i] = n_entries_per_row[TrilinosWrappers::min_my_gid(row_map) + i]; + AssertThrow(std::accumulate(local_entries_per_row.begin(), + local_entries_per_row.end(), + std::uint64_t(0)) < + std::numeric_limits::max(), + ExcMessage("The TrilinosWrappers use Epetra internally which " + "uses 'signed int' to represent local indices. " + "Therefore, only 2,147,483,647 nonzero matrix " + "entries can be stored on a single process, " + "but you are requesting more than that. " + "If possible, use more MPI processes.")); + if (row_map.Comm().NumProc() > 1) graph = std::make_unique( Copy, row_map, local_entries_per_row.data(), false @@ -360,6 +386,17 @@ namespace TrilinosWrappers n_entries_per_row[row - first_row] = static_cast(sp.row_length(row)); + AssertThrow(std::accumulate(n_entries_per_row.begin(), + n_entries_per_row.end(), + std::uint64_t(0)) < + std::numeric_limits::max(), + ExcMessage("The TrilinosWrappers use Epetra internally which " + "uses 'signed int' to represent local indices. " + "Therefore, only 2,147,483,647 nonzero matrix " + "entries can be stored on a single process, " + "but you are requesting more than that. " + "If possible, use more MPI processes.")); + if (row_map.Comm().NumProc() > 1) graph = std::make_unique(Copy, row_map, -- 2.39.5