29#ifdef DEAL_II_WITH_PSBLAS
33namespace PSCToolkitWrappers
37 : psblas_sparse_matrix(nullptr)
38 , psblas_descriptor(nullptr)
45 Assert(psblas_descriptor.get() ==
nullptr,
46 ExcMessage(
"PSBLAS matrix descriptor must not be initialized."));
48 Assert(psblas_sparsity_pattern.psblas_descriptor.get() !=
nullptr,
49 ExcMessage(
"The given SparsityPattern is not valid."));
51 this->communicator = communicator;
52 Assert(communicator != MPI_COMM_NULL,
53 ExcMessage(
"MPI_COMM_NULL passed to SparseMatrix::reinit()."));
55 psblas_descriptor = psblas_sparsity_pattern.psblas_descriptor;
58 psblas_sparse_matrix = psb_c_new_dspmat();
62 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
63 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
70 if (psblas_sparse_matrix !=
nullptr && psblas_descriptor.get() !=
nullptr)
73 int err = psb_c_dspfree(psblas_sparse_matrix, psblas_descriptor.get());
74 Assert(err == 0, ExcCallingPSBLASFunction(err,
"psb_c_dspfree"));
94 ExcMessage(
"An empty IndexSet has been given."));
97 ExcMessage(
"MPI_COMM_NULL passed to SparseMatrix::reinit()."));
101 if (psblas_sparse_matrix !=
nullptr && psblas_descriptor.get() !=
nullptr)
103 int err = psb_c_dspfree(psblas_sparse_matrix, psblas_descriptor.get());
104 Assert(err == 0, ExcCallingPSBLASFunction(err,
"psb_c_dspfree"));
105 psblas_sparse_matrix =
nullptr;
109 psblas_descriptor.reset(psb_c_new_descriptor(),
110 PSCToolkitWrappers::internal::DescriptorDeleter());
113 const std::vector<types::global_dof_index> &indexes =
116 psb_i_t number_of_local_indexes = indexes.size();
119 std::vector<psb_l_t> vl(number_of_local_indexes);
120 for (psb_i_t i = 0; i < number_of_local_indexes; ++i)
122 const auto psblas_index =
static_cast<psb_l_t
>(indexes[i]);
124 vl[i] = psblas_index;
128 psb_c_cdall_vl(number_of_local_indexes,
130 *InitFinalize::get_psblas_context(),
131 psblas_descriptor.get());
134 psblas_sparse_matrix = psb_c_new_dspmat();
138 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
139 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
141 state = internal::State::Build;
150 Assert(psblas_sparsity_pattern.psblas_descriptor.get() !=
nullptr,
151 ExcMessage(
"The given SparsityPattern is not valid."));
153 this->communicator = communicator;
154 Assert(communicator != MPI_COMM_NULL,
155 ExcMessage(
"MPI_COMM_NULL passed to SparseMatrix::reinit()."));
158 if (psblas_sparse_matrix !=
nullptr && psblas_descriptor.get() !=
nullptr)
160 int err = psb_c_dspfree(psblas_sparse_matrix, psblas_descriptor.get());
161 Assert(err == 0, ExcCallingPSBLASFunction(err,
"psb_c_dspfree"));
162 psblas_sparse_matrix =
nullptr;
165 psblas_descriptor = psblas_sparsity_pattern.psblas_descriptor;
168 psblas_sparse_matrix = psb_c_new_dspmat();
172 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
173 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
175 state = internal::State::Build;
191 "SparsityPattern and IndexSet have different number of rows"));
197 if (psblas_sparse_matrix !=
nullptr && psblas_descriptor.get() !=
nullptr)
199 int err = psb_c_dspfree(psblas_sparse_matrix, psblas_descriptor.get());
200 Assert(err == 0, ExcCallingPSBLASFunction(err,
"psb_c_dspfree"));
201 psblas_sparse_matrix =
nullptr;
212 "Each row has to be owned by exactly one owner (n_rows()=") +
213 std::to_string(sparsity_pattern.
n_rows()) +
214 " but sum(local_rows.n_elements())=" +
215 std::to_string(row_owners) +
")"));
218 this->communicator = communicator;
221 psblas_descriptor.reset(psb_c_new_descriptor(),
222 PSCToolkitWrappers::internal::DescriptorDeleter());
225 const std::vector<types::global_dof_index> indexes =
227 const psb_i_t n_local =
static_cast<psb_i_t
>(indexes.size());
229 std::vector<psb_l_t> vl(n_local);
230 for (psb_i_t i = 0; i < n_local; ++i)
232 const auto idx =
static_cast<psb_l_t
>(indexes[i]);
237 psb_c_cdall_vl(n_local,
239 *InitFinalize::get_psblas_context(),
240 psblas_descriptor.get());
244 psblas_sparse_matrix = psb_c_new_dspmat();
250 const psb_l_t local_row_start =
252 const psb_l_t local_row_end =
253 local_row_start +
static_cast<psb_l_t
>(local_rows.
n_elements());
256 for (psb_l_t i = local_row_start; i < local_row_end; ++i)
258 const auto row_length =
259 static_cast<psb_i_t
>(sparsity_pattern.
row_length(i));
263 std::vector<psb_l_t> irw(row_length, i);
264 std::vector<psb_l_t> icl(row_length);
268 sparsity_pattern.
begin(i);
269 p != sparsity_pattern.
end(i);
272 const auto col =
static_cast<psb_l_t
>(p->column());
277 err = psb_c_cdins(row_length,
280 psblas_descriptor.get());
281 Assert(err == 0, ExcInsertionInPSBLASMatrix(err));
286 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
287 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
293 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
294 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
297 state = internal::State::Build;
303 SparseMatrix::local_size()
const
305 return psb_c_cd_get_local_rows(psblas_descriptor.get());
309 std::pair<SparseMatrix::size_type, SparseMatrix::size_type>
310 SparseMatrix::local_range()
const
312 std::vector<psb_l_t> local_indices(local_size());
313 int err = psb_c_cd_get_global_indices(local_indices.data(),
316 psblas_descriptor.get());
318 ExcCallingPSBLASFunction(err,
"psb_c_cd_get_global_indices"));
320 return {local_indices[0], local_indices.back() + 1};
326 SparseMatrix::in_local_range(
const size_type index)
const
337 return psb_c_cd_get_global_rows(psblas_descriptor.get());
345 return psb_c_cd_get_global_cols(psblas_descriptor.get());
353 return psb_c_dnnz(psblas_sparse_matrix, psblas_descriptor.get());
368 int err = psb_c_dspins(
369 1, &irw, &icl, &
val, psblas_sparse_matrix, psblas_descriptor.get());
370 Assert(err == 0, ExcInsertionInPSBLASMatrix(err));
379 const auto psblas_index_i =
static_cast<psb_l_t
>(i);
381 const auto psblas_index_j =
static_cast<psb_l_t
>(j);
384 return psb_c_dmatgetelem(psblas_sparse_matrix,
387 psblas_descriptor.get());
412 SparseMatrix::get_psblas_matrix()
const
414 return psblas_sparse_matrix;
420 SparseMatrix::get_psblas_descriptor()
const
422 return psblas_descriptor.get();
428 SparseMatrix::get_mpi_communicator()
const
439 Assert(psblas_sparse_matrix !=
nullptr,
440 ExcMessage(
"PSBLAS matrix has not been initialized."));
447 const unsigned int n_indices = indices.size();
448 psb_i_t nz = n_indices * n_indices;
451 std::vector<psb_l_t> irw(nz);
452 std::vector<psb_l_t> icl(nz);
453 std::vector<psb_d_t>
val(nz);
454 for (
unsigned int i = 0; i < n_indices; ++i)
456 for (
unsigned int j = 0; j < n_indices; ++j)
458 const auto psblas_row_index =
static_cast<psb_l_t
>(indices[i]);
459 const auto psblas_col_index =
static_cast<psb_l_t
>(indices[j]);
462 irw[i * n_indices + j] = psblas_row_index;
463 icl[i * n_indices + j] = psblas_col_index;
469 int err = psb_c_dspins(nz,
473 psblas_sparse_matrix,
474 psblas_descriptor.get());
476 Assert(err == 0, ExcInsertionInPSBLASMatrix(err));
490 int info = psb_c_dspins(1 ,
494 psblas_sparse_matrix,
495 psblas_descriptor.get());
496 Assert(info == 0, ExcInsertionInPSBLASMatrix(info));
504 const std::vector<SparseMatrix::size_type> &col_indices,
509 Assert(col_indices.size() == ncols,
512 add(row, ncols, col_indices.data(), values,
false,
false);
520 const std::vector<SparseMatrix::size_type> &col_indices,
521 const std::vector<SparseMatrix::value_type> &values,
525 Assert(col_indices.size() == ncols,
529 add(row, ncols, col_indices.data(),
values.data(),
false,
false);
542 std::vector<psb_l_t> irw(ncols);
543 std::vector<psb_l_t> icl(ncols);
546 irw[i] =
static_cast<psb_l_t
>(row);
547 icl[i] =
static_cast<psb_l_t
>(col_indices[i]);
550 int info = psb_c_dspins(ncols ,
554 psblas_sparse_matrix,
555 psblas_descriptor.get());
556 Assert(info == 0, ExcInsertionInPSBLASMatrix(info));
567 if (!psb_c_cd_is_asb(psblas_descriptor.get()))
569 err = psb_c_cdasb(psblas_descriptor.get());
570 Assert(err == 0, ExcAssemblePSBLASDescriptor(err));
574 if (!psb_c_dis_matasb(psblas_sparse_matrix, psblas_descriptor.get()))
577 err = psb_c_dspasb(psblas_sparse_matrix, psblas_descriptor.get());
578 Assert(err == 0, ExcAssemblePSBLASMatrix(err));
579 state = internal::State::Assembled;
588 Assert(psblas_sparse_matrix !=
nullptr,
589 ExcMessage(
"PSBLAS matrix has not been initialized."));
590 Assert(src.psblas_vector !=
nullptr,
591 ExcMessage(
"Source PSBLAS vector has not been initialized."));
593 Assert(state == internal::State::Assembled,
594 ExcMessage(
"PSBLAS matrix has not been assembled."));
597 psblas_sparse_matrix,
601 psblas_descriptor.get());
602 Assert(err == 0, ExcMatVecPSBLAS(err));
610 Assert(psblas_sparse_matrix !=
nullptr,
611 ExcMessage(
"PSBLAS matrix has not been initialized."));
612 Assert(src.psblas_vector !=
nullptr,
613 ExcMessage(
"Source PSBLAS vector has not been initialized."));
615 Assert(state == internal::State::Assembled,
616 ExcMessage(
"PSBLAS matrix has not been assembled."));
619 psblas_sparse_matrix,
623 psblas_descriptor.get());
624 Assert(err == 0, ExcMatVecPSBLAS(err));
632 Assert(psblas_sparse_matrix !=
nullptr,
633 ExcMessage(
"PSBLAS matrix has not been initialized."));
634 Assert(src.psblas_vector !=
nullptr,
635 ExcMessage(
"Source PSBLAS vector has not been initialized."));
637 Assert(state == internal::State::Assembled,
638 ExcMessage(
"PSBLAS matrix has not been assembled."));
642 psblas_sparse_matrix,
646 psblas_descriptor.get(),
649 Assert(err == 0, ExcMatVecPSBLAS(err));
657 Assert(psblas_sparse_matrix !=
nullptr,
658 ExcMessage(
"PSBLAS matrix has not been initialized."));
659 Assert(src.psblas_vector !=
nullptr,
660 ExcMessage(
"Source PSBLAS vector has not been initialized."));
662 Assert(state == internal::State::Assembled,
663 ExcMessage(
"PSBLAS matrix has not been assembled."));
667 psblas_sparse_matrix,
671 psblas_descriptor.get(),
674 Assert(err == 0, ExcMatVecPSBLAS(err));
704 SparseMatrix::trace()
const
710 idx < local_indices.second;
size_type row_length(const size_type row) const
bool is_ascending_and_one_to_one(const MPI_Comm communicator) const
size_type n_elements() const
size_type nth_index_in_set(const size_type local_index) const
std::vector< size_type > get_index_vector() const
std::size_t n_nonzero_elements() const
void Tvmult(OutVector &dst, const InVector &src) const
void set(const size_type i, const size_type j, const number value)
SparseMatrix< number > & copy_from(const SparseMatrix< somenumber > &source)
virtual ~SparseMatrix() override
void vmult_add(OutVector &dst, const InVector &src) const
number diag_element(const size_type i) const
void vmult(OutVector &dst, const InVector &src) const
const number & operator()(const size_type i, const size_type j) const
number el(const size_type i, const size_type j) const
std::unique_ptr< number[]> val
void add(const size_type i, const size_type j, const number value)
friend class SparseMatrix
void compress(VectorOperation::values)
real_type frobenius_norm() const
void Tvmult_add(OutVector &dst, const InVector &src) const
real_type linfty_norm() const
real_type l1_norm() const
virtual void reinit(const SparsityPattern &sparsity)
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define AssertIntegerConversion(index1, index2)
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcSourceEqualsDestination()
#define AssertIsFinite(number)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotQuadratic()
static ::ExceptionBase & ExcMessage(std::string arg1)
std::pair< types::global_dof_index, types::global_dof_index > local_range
@ matrix
Contents is actually a matrix.
T sum(const T &t, const MPI_Comm mpi_communicator)