31#ifdef DEAL_II_WITH_PSBLAS
35namespace PSCToolkitWrappers
39 : psblas_sparse_matrix(nullptr)
40 , psblas_descriptor(nullptr)
47 Assert(psblas_descriptor.get() ==
nullptr,
48 ExcMessage(
"PSBLAS matrix descriptor must not be initialized."));
50 Assert(psblas_sparsity_pattern.psblas_descriptor.get() !=
nullptr,
51 ExcMessage(
"The given SparsityPattern is not valid."));
53 this->communicator = communicator;
54 Assert(communicator != MPI_COMM_NULL,
55 ExcMessage(
"MPI_COMM_NULL passed to SparseMatrix::reinit()."));
57 psblas_descriptor = psblas_sparsity_pattern.psblas_descriptor;
60 psblas_sparse_matrix = psb_c_new_dspmat();
64 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
65 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
72 if (psblas_sparse_matrix !=
nullptr && psblas_descriptor.get() !=
nullptr)
75 int err = psb_c_dspfree(psblas_sparse_matrix, psblas_descriptor.get());
76 Assert(err == 0, ExcCallingPSBLASFunction(err,
"psb_c_dspfree"));
96 ExcMessage(
"An empty IndexSet has been given."));
99 ExcMessage(
"MPI_COMM_NULL passed to SparseMatrix::reinit()."));
103 if (psblas_sparse_matrix !=
nullptr && psblas_descriptor.get() !=
nullptr)
105 int err = psb_c_dspfree(psblas_sparse_matrix, psblas_descriptor.get());
106 Assert(err == 0, ExcCallingPSBLASFunction(err,
"psb_c_dspfree"));
107 psblas_sparse_matrix =
nullptr;
111 psblas_descriptor.reset(psb_c_new_descriptor(),
112 PSCToolkitWrappers::internal::DescriptorDeleter());
115 const std::vector<types::global_dof_index> &indexes =
118 psb_i_t number_of_local_indexes = indexes.size();
121 std::vector<psb_l_t> vl(number_of_local_indexes);
122 for (psb_i_t i = 0; i < number_of_local_indexes; ++i)
124 const auto psblas_index =
static_cast<psb_l_t
>(indexes[i]);
126 vl[i] = psblas_index;
130 psb_c_cdall_vl(number_of_local_indexes,
132 *InitFinalize::get_psblas_context(),
133 psblas_descriptor.get());
136 psblas_sparse_matrix = psb_c_new_dspmat();
140 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
141 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
143 state = internal::State::Build;
152 Assert(psblas_sparsity_pattern.psblas_descriptor.get() !=
nullptr,
153 ExcMessage(
"The given SparsityPattern is not valid."));
155 this->communicator = communicator;
156 Assert(communicator != MPI_COMM_NULL,
157 ExcMessage(
"MPI_COMM_NULL passed to SparseMatrix::reinit()."));
160 if (psblas_sparse_matrix !=
nullptr && psblas_descriptor.get() !=
nullptr)
162 int err = psb_c_dspfree(psblas_sparse_matrix, psblas_descriptor.get());
163 Assert(err == 0, ExcCallingPSBLASFunction(err,
"psb_c_dspfree"));
164 psblas_sparse_matrix =
nullptr;
167 psblas_descriptor = psblas_sparsity_pattern.psblas_descriptor;
170 psblas_sparse_matrix = psb_c_new_dspmat();
174 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
175 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
177 state = internal::State::Build;
193 "SparsityPattern and IndexSet have different number of rows"));
199 if (psblas_sparse_matrix !=
nullptr && psblas_descriptor.get() !=
nullptr)
201 int err = psb_c_dspfree(psblas_sparse_matrix, psblas_descriptor.get());
202 Assert(err == 0, ExcCallingPSBLASFunction(err,
"psb_c_dspfree"));
203 psblas_sparse_matrix =
nullptr;
214 "Each row has to be owned by exactly one owner (n_rows()=") +
215 std::to_string(sparsity_pattern.
n_rows()) +
216 " but sum(local_rows.n_elements())=" +
217 std::to_string(row_owners) +
")"));
220 this->communicator = communicator;
223 psblas_descriptor.reset(psb_c_new_descriptor(),
224 PSCToolkitWrappers::internal::DescriptorDeleter());
227 const std::vector<types::global_dof_index> indexes =
229 const psb_i_t n_local =
static_cast<psb_i_t
>(indexes.size());
231 std::vector<psb_l_t> vl(n_local);
232 for (psb_i_t i = 0; i < n_local; ++i)
234 const auto idx =
static_cast<psb_l_t
>(indexes[i]);
239 psb_c_cdall_vl(n_local,
241 *InitFinalize::get_psblas_context(),
242 psblas_descriptor.get());
246 psblas_sparse_matrix = psb_c_new_dspmat();
252 const psb_l_t local_row_start =
254 const psb_l_t local_row_end =
255 local_row_start +
static_cast<psb_l_t
>(local_rows.
n_elements());
258 for (psb_l_t i = local_row_start; i < local_row_end; ++i)
260 const auto row_length =
261 static_cast<psb_i_t
>(sparsity_pattern.
row_length(i));
265 std::vector<psb_l_t> irw(row_length, i);
266 std::vector<psb_l_t> icl(row_length);
270 sparsity_pattern.
begin(i);
271 p != sparsity_pattern.
end(i);
274 const auto col =
static_cast<psb_l_t
>(p->column());
279 err = psb_c_cdins(row_length,
282 psblas_descriptor.get());
283 Assert(err == 0, ExcInsertionInPSBLASMatrix(err));
288 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
289 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
295 psb_c_dspall_remote(psblas_sparse_matrix, psblas_descriptor.get());
296 Assert(err == 0, ExcAllocationPSBLASMatrix(err));
299 state = internal::State::Build;
305 SparseMatrix::local_size()
const
307 return psb_c_cd_get_local_rows(psblas_descriptor.get());
311 std::pair<SparseMatrix::size_type, SparseMatrix::size_type>
312 SparseMatrix::local_range()
const
314 std::vector<psb_l_t> local_indices(local_size());
315 int err = psb_c_cd_get_global_indices(local_indices.data(),
318 psblas_descriptor.get());
320 ExcCallingPSBLASFunction(err,
"psb_c_cd_get_global_indices"));
322 return {local_indices[0], local_indices.back() + 1};
328 SparseMatrix::in_local_range(
const size_type index)
const
339 return psb_c_cd_get_global_rows(psblas_descriptor.get());
347 return psb_c_cd_get_global_cols(psblas_descriptor.get());
355 return psb_c_dnnz(psblas_sparse_matrix, psblas_descriptor.get());
370 int err = psb_c_dspins(
371 1, &irw, &icl, &
val, psblas_sparse_matrix, psblas_descriptor.get());
372 Assert(err == 0, ExcInsertionInPSBLASMatrix(err));
381 const auto psblas_index_i =
static_cast<psb_l_t
>(i);
383 const auto psblas_index_j =
static_cast<psb_l_t
>(j);
386 return psb_c_dmatgetelem(psblas_sparse_matrix,
389 psblas_descriptor.get());
414 SparseMatrix::get_psblas_matrix()
const
416 return psblas_sparse_matrix;
422 SparseMatrix::get_psblas_descriptor()
const
424 return psblas_descriptor.get();
430 SparseMatrix::get_mpi_communicator()
const
441 Assert(psblas_sparse_matrix !=
nullptr,
442 ExcMessage(
"PSBLAS matrix has not been initialized."));
449 const unsigned int n_indices = indices.size();
450 psb_i_t nz = n_indices * n_indices;
453 std::vector<psb_l_t> irw(nz);
454 std::vector<psb_l_t> icl(nz);
455 std::vector<psb_d_t>
val(nz);
456 for (
unsigned int i = 0; i < n_indices; ++i)
458 for (
unsigned int j = 0; j < n_indices; ++j)
460 const auto psblas_row_index =
static_cast<psb_l_t
>(indices[i]);
461 const auto psblas_col_index =
static_cast<psb_l_t
>(indices[j]);
464 irw[i * n_indices + j] = psblas_row_index;
465 icl[i * n_indices + j] = psblas_col_index;
471 int err = psb_c_dspins(nz,
475 psblas_sparse_matrix,
476 psblas_descriptor.get());
478 Assert(err == 0, ExcInsertionInPSBLASMatrix(err));
492 int info = psb_c_dspins(1 ,
496 psblas_sparse_matrix,
497 psblas_descriptor.get());
498 Assert(info == 0, ExcInsertionInPSBLASMatrix(info));
506 const std::vector<SparseMatrix::size_type> &col_indices,
511 Assert(col_indices.size() == ncols,
514 add(row, ncols, col_indices.data(), values,
false,
false);
522 const std::vector<SparseMatrix::size_type> &col_indices,
523 const std::vector<SparseMatrix::value_type> &values,
527 Assert(col_indices.size() == ncols,
531 add(row, ncols, col_indices.data(),
values.data(),
false,
false);
544 std::vector<psb_l_t> irw(ncols);
545 std::vector<psb_l_t> icl(ncols);
548 irw[i] =
static_cast<psb_l_t
>(row);
549 icl[i] =
static_cast<psb_l_t
>(col_indices[i]);
552 int info = psb_c_dspins(ncols ,
556 psblas_sparse_matrix,
557 psblas_descriptor.get());
558 Assert(info == 0, ExcInsertionInPSBLASMatrix(info));
569 if (!psb_c_cd_is_asb(psblas_descriptor.get()))
571 err = psb_c_cdasb(psblas_descriptor.get());
572 Assert(err == 0, ExcAssemblePSBLASDescriptor(err));
576 if (!psb_c_dis_matasb(psblas_sparse_matrix, psblas_descriptor.get()))
579 err = psb_c_dspasb(psblas_sparse_matrix, psblas_descriptor.get());
580 Assert(err == 0, ExcAssemblePSBLASMatrix(err));
581 state = internal::State::Assembled;
590 Assert(psblas_sparse_matrix !=
nullptr,
591 ExcMessage(
"PSBLAS matrix has not been initialized."));
592 Assert(src.psblas_vector !=
nullptr,
593 ExcMessage(
"Source PSBLAS vector has not been initialized."));
595 Assert(state == internal::State::Assembled,
596 ExcMessage(
"PSBLAS matrix has not been assembled."));
599 psblas_sparse_matrix,
603 psblas_descriptor.get());
604 Assert(err == 0, ExcMatVecPSBLAS(err));
612 Assert(psblas_sparse_matrix !=
nullptr,
613 ExcMessage(
"PSBLAS matrix has not been initialized."));
614 Assert(src.psblas_vector !=
nullptr,
615 ExcMessage(
"Source PSBLAS vector has not been initialized."));
617 Assert(state == internal::State::Assembled,
618 ExcMessage(
"PSBLAS matrix has not been assembled."));
621 psblas_sparse_matrix,
625 psblas_descriptor.get());
626 Assert(err == 0, ExcMatVecPSBLAS(err));
634 Assert(psblas_sparse_matrix !=
nullptr,
635 ExcMessage(
"PSBLAS matrix has not been initialized."));
636 Assert(src.psblas_vector !=
nullptr,
637 ExcMessage(
"Source PSBLAS vector has not been initialized."));
639 Assert(state == internal::State::Assembled,
640 ExcMessage(
"PSBLAS matrix has not been assembled."));
644 psblas_sparse_matrix,
648 psblas_descriptor.get(),
651 Assert(err == 0, ExcMatVecPSBLAS(err));
659 Assert(psblas_sparse_matrix !=
nullptr,
660 ExcMessage(
"PSBLAS matrix has not been initialized."));
661 Assert(src.psblas_vector !=
nullptr,
662 ExcMessage(
"Source PSBLAS vector has not been initialized."));
664 Assert(state == internal::State::Assembled,
665 ExcMessage(
"PSBLAS matrix has not been assembled."));
669 psblas_sparse_matrix,
673 psblas_descriptor.get(),
676 Assert(err == 0, ExcMatVecPSBLAS(err));
706 SparseMatrix::trace()
const
712 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)