19#ifdef DEAL_II_WITH_PSBLAS
20# include <psb_base_cbind.h>
21# include <psb_c_base.h>
22# include <psb_c_dbase.h>
26namespace PSCToolkitWrappers
30 : psblas_vector(nullptr)
31 , psblas_context(InitFinalize::get_psblas_context())
32 , psblas_descriptor(nullptr)
34 , state(internal::
State::Default)
35 , last_action(VectorOperation::unknown)
43 reinit(v.owned_elements, v.ghost_indices, v.communicator);
45 reinit(v.owned_elements, v.communicator);
53 if (state != internal::State::Default)
56 ierr = psb_c_dgefree(psblas_vector, psblas_descriptor.get());
66 psblas_vector =
nullptr;
69 reinit(local_partitioning, communicator);
79 psblas_vector =
nullptr;
82 reinit(local_partitioning, ghost_indices, communicator);
90 const bool omit_zeroing_entries)
92 Assert(communicator != MPI_COMM_NULL,
93 ExcMessage(
"MPI_COMM_NULL passed to Vector::reinit()."));
96 const bool is_vector_changed =
size() != local_partitioning.
size();
97 owned_elements = local_partitioning;
102 if (psblas_descriptor.get() ==
nullptr || is_vector_changed ==
true)
104 psblas_descriptor.reset(psb_c_new_descriptor(),
105 internal::DescriptorDeleter());
108 const std::vector<types::global_dof_index> &indexes =
111 const auto number_of_local_indexes =
114 std::vector<psb_l_t> vl(number_of_local_indexes);
115 for (std::size_t i = 0; i < number_of_local_indexes; ++i)
117 const auto psblas_index =
static_cast<psb_l_t
>(indexes[i]);
119 vl[i] = psblas_index;
123 psblas_context = InitFinalize::get_psblas_context();
124 ierr = psb_c_cdall_vl(number_of_local_indexes,
127 psblas_descriptor.get());
130 Assert(ierr == 0, ExcInitializePSBLASDescriptor(ierr));
134 psblas_vector = psb_c_new_dvector();
136 ierr = psb_c_dgeall_remote_options(psblas_vector,
137 psblas_descriptor.get(),
140 Assert(ierr == 0, ExcInitializePSBLASVector(ierr));
142 if (omit_zeroing_entries ==
false)
144 ierr = psb_c_dvect_set_scal(psblas_vector, 0.0);
146 ExcCallingPSBLASFunction(ierr,
"psb_c_dvect_set_scal"));
148 state = internal::State::Assembled;
160 ExcMessage(
"MPI_COMM_NULL passed to Vector::reinit()."));
163 const bool is_vector_changed =
size() != local_partitioning.
size();
165 owned_elements = local_partitioning;
166 ghost_indices = ghosts;
170 if (psblas_descriptor.get() ==
nullptr || is_vector_changed ==
true)
172 psblas_descriptor.reset(psb_c_new_descriptor(),
173 internal::DescriptorDeleter());
176 const std::vector<types::global_dof_index> &indexes =
179 const auto number_of_local_indexes =
182 std::vector<psb_l_t> vl(number_of_local_indexes);
183 std::vector<psb_i_t> lidx(number_of_local_indexes);
184 for (std::size_t i = 0; i < number_of_local_indexes; ++i)
186 const auto psblas_index =
static_cast<psb_l_t
>(indexes[i]);
187 const auto idx =
static_cast<psb_i_t
>(i);
190 vl[i] = psblas_index;
201 psblas_context = InitFinalize::get_psblas_context();
202 ierr = psb_c_cdall_vl_lidx(number_of_local_indexes,
206 psblas_descriptor.get());
208 Assert(ierr == 0, ExcInitializePSBLASDescriptor(ierr));
211 const std::vector<types::global_dof_index> &ghost_indexes =
212 ghost_indices.get_index_vector();
213 const auto number_of_ghost_indices = ghost_indexes.size();
215 std::vector<psb_l_t> global_ghost_indices(number_of_ghost_indices);
216 std::vector<psb_i_t> local_ghost_indices(number_of_ghost_indices);
218 psb_i_t extended_idx_counter = number_of_local_indexes;
219 for (std::size_t i = 0; i < number_of_ghost_indices; ++i)
221 const auto psblas_index =
static_cast<psb_l_t
>(ghost_indexes[i]);
223 global_ghost_indices[i] = psblas_index;
224 const auto idx =
static_cast<psb_i_t
>(extended_idx_counter);
226 local_ghost_indices[i] = extended_idx_counter++;
230 ierr = psb_c_cdins_lidx(number_of_ghost_indices,
231 global_ghost_indices.data(),
232 local_ghost_indices.data(),
233 psblas_descriptor.get());
235 Assert(ierr == 0, ExcCallingPSBLASFunction(ierr,
"psb_c_cdins_lidx"));
240 ierr = psb_c_cdasb(psblas_descriptor.get());
241 Assert(ierr == 0, ExcAssemblePSBLASDescriptor(ierr));
244 psblas_vector = psb_c_new_dvector();
246 ierr = psb_c_dgeall_remote_options(psblas_vector,
247 psblas_descriptor.get(),
250 Assert(ierr == 0, ExcInitializePSBLASVector(ierr));
255 ierr = psb_c_dgeasb_options(psblas_vector,
256 psblas_descriptor.get(),
258 Assert(ierr == 0, ExcAssemblePSBLASVector(ierr));
260 state = internal::State::Assembled;
269 psblas_descriptor = v.psblas_descriptor;
275 if (!omit_zeroing_entries)
277 int ierr = psb_c_dvect_set_scal(psblas_vector, 0.0);
279 ExcCallingPSBLASFunction(ierr,
"psb_c_dvect_set_scal"));
286 omit_zeroing_entries);
299 Assert(v.state == internal::State::Assembled,
300 ExcInvalidStateAssembled(v.state));
306 psblas_descriptor = v.psblas_descriptor;
321 psblas_descriptor.get());
328 state = internal::State::Assembled;
340 int ierr = psb_c_dvect_set_scal(psblas_vector, s);
341 Assert(ierr == 0, ExcCallingPSBLASFunction(ierr,
"psb_c_dvect_set_scal"));
356 Vector::get_psblas_descriptor()
const
358 return psblas_descriptor.get();
364 Vector::get_psblas_vector()
const
366 return psblas_vector;
374 if (state != internal::State::Default)
376 int ierr = psb_c_dgefree(psblas_vector, psblas_descriptor.get());
377 Assert(ierr == 0, ExcFreePSBLASVector(ierr));
380 psblas_vector =
nullptr;
381 owned_elements.clear();
382 owned_elements.set_size(0);
383 ghost_indices.clear();
384 owned_elements.set_size(0);
385 state = internal::State::Default;
395 Assert(state == internal::State::Assembled,
396 ExcInvalidStateAssembled(state));
397 return psb_c_dgenrmi(psblas_vector, psblas_descriptor.get());
405 Assert(state == internal::State::Assembled,
406 ExcInvalidStateAssembled(state));
407 return psb_c_dgeasum(psblas_vector, psblas_descriptor.get());
415 Assert(state == internal::State::Assembled,
416 ExcInvalidStateAssembled(state));
417 return psb_c_dgenrm2(psblas_vector, psblas_descriptor.get());
425 const value_type *start_ptr = psb_c_dvect_f_get_pnt(psblas_vector);
429 for (
const value_type *ptr = start_ptr; ptr != end_ptr; ++ptr)
430 local_sum_of_values += *ptr;
442 const value_type *start_ptr = psb_c_dvect_f_get_pnt(psblas_vector);
443 Assert(start_ptr !=
nullptr,
444 ExcMessage(
"Error getting underlying PSBLAS vector."));
446 const bool has_nonzero_local =
447 std::any_of(start_ptr,
451 unsigned int num_nonzero =
453 return num_nonzero == 0;
466 int ierr = psb_c_dgeaxpby(
467 a, v.psblas_vector, 0.0, psblas_vector, psblas_descriptor.get());
476 return owned_elements.n_elements();
485 return psb_c_dgedot(psblas_vector,
487 psblas_descriptor.get());
501 psblas_descriptor.get());
516 psblas_descriptor.get());
523 Vector::set(
const std::vector<Vector::size_type> &indices,
524 const std::vector<Vector::value_type> &values)
530 psb_i_t nz = indices.size();
534 std::vector<psb_l_t> irw(nz);
535 std::vector<psb_d_t> val(nz);
536 for (psb_i_t i = 0; i < nz; ++i)
538 const auto psblas_index =
static_cast<psb_l_t
>(indices[i]);
540 irw[i] = psblas_index;
542 psb_c_dgetelem(psblas_vector, irw[i], psblas_descriptor.get());
545 int ierr = psb_c_dgeins(nz ,
549 psblas_descriptor.get());
552 Assert(ierr == 0, ExcInsertionInPSBLASVector(ierr));
558 Vector::add(
const std::vector<Vector::size_type> &indices,
559 const std::vector<Vector::value_type> &values)
564 ExcMessage(
"Indices and values size mismatch."));
566 psb_i_t nz = indices.size();
569 std::vector<psb_l_t> irw(nz);
570 std::vector<psb_d_t> val(nz);
571 for (psb_i_t i = 0; i < nz; ++i)
573 const auto psblas_index =
static_cast<psb_l_t
>(indices[i]);
575 irw[i] = psblas_index;
579 int ierr = psb_c_dgeins(nz ,
583 psblas_descriptor.get());
585 Assert(ierr == 0, ExcInsertionInPSBLASVector(ierr));
595 int ierr = psb_c_dgeaxpby(s,
599 psblas_descriptor.get());
600 Assert(ierr == 0, ExcAXPBY(ierr));
610 value_type *start_ptr = psb_c_dvect_f_get_pnt(psblas_vector);
612 while (start_ptr != end_ptr)
630 psblas_descriptor.get());
631 Assert(ierr == 0, ExcAXPBY(ierr));
640 int ierr = psb_c_dgeaxpby(
641 a,
V.psblas_vector, s, psblas_vector, psblas_descriptor.get());
642 Assert(ierr == 0, ExcAXPBY(ierr));
651 value_type *start_ptr = psb_c_dvect_f_get_pnt(psblas_vector);
652 value_type *start_ptr_v = psb_c_dvect_f_get_pnt(v.psblas_vector);
654 while (start_ptr != end_ptr)
656 *start_ptr *= (*start_ptr_v);
670 return psb_c_dgedot(psblas_vector,
672 psblas_descriptor.get());
681 std::swap(psblas_vector, v.psblas_vector);
682 std::swap(psblas_descriptor, v.psblas_descriptor);
683 std::swap(ghosted, v.ghosted);
684 std::swap(this->last_action, v.last_action);
686 IndexSet temp(ghost_indices);
687 ghost_indices = v.ghost_indices;
688 v.ghost_indices = temp;
697 ExcMessage(
"Calling compress() is only useful if a vector "
698 "has been written into, but this is a vector with ghost "
699 "elements and consequently is read-only. It does "
700 "not make sense to call compress() for such "
704 Assert(state != internal::State::Default, ExcInvalidDefault());
709 "Missing compress() or calling with wrong VectorOperation argument."));
713 if (!psb_c_cd_is_asb(psblas_descriptor.get()))
715 ierr = psb_c_cdasb(psblas_descriptor.get());
716 Assert(ierr == 0, ExcAssemblePSBLASDescriptor(ierr));
721 ierr = psb_c_dgeasb_options(psblas_vector,
722 psblas_descriptor.get(),
725 ierr = psb_c_dgeasb_options(psblas_vector,
726 psblas_descriptor.get(),
731 Assert(ierr == 0, ExcAssemblePSBLASVector(ierr));
732 state = internal::State::Assembled;
743 int ierr = psb_c_dhalo(psblas_vector, psblas_descriptor.get());
void subtract_set(const IndexSet &other)
std::vector< size_type > get_index_vector() const
bool has_ghost_elements() const
void add(const std::vector< size_type > &indices, const std::vector< OtherNumber > &values)
Vector< Number > & operator=(const Number s)
Number operator*(const Vector< Number2 > &V) const
Number mean_value() const
Number add_and_dot(const Number a, const Vector< Number > &V, const Vector< Number > &W)
MPI_Comm get_mpi_communicator() const
types::global_dof_index size_type
virtual size_type size() const override
void equ(const Number a, const Vector< Number > &u)
void sadd(const Number s, const Vector< Number > &V)
real_type l2_norm() const
virtual ~Vector() override=default
real_type linfty_norm() const
Vector< Number > & operator+=(const Vector< Number > &V)
void scale(const Vector< Number > &scaling_factors)
IndexSet locally_owned_elements() const
AlignedVector< Number > values
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
size_type locally_owned_size() const
virtual void swap(Vector< Number > &v) noexcept
void compress(VectorOperation::values operation=VectorOperation::unknown) const
Vector< Number > & operator-=(const Vector< Number > &V)
void update_ghost_values() const
std::size_t memory_consumption() const
real_type l1_norm() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define AssertIntegerConversion(index1, index2)
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcGhostsPresent()
#define Assert(cond, exc)
#define AssertIsFinite(number)
#define AssertDimension(dim1, dim2)
#define AssertNothrow(cond, exc)
static ::ExceptionBase & ExcInvalidState()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
T sum(const T &t, const MPI_Comm mpi_communicator)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
*braid_SplitCommworld & comm