17 #ifndef __deal2__parallel_vector_templates_h 18 #define __deal2__parallel_vector_templates_h 21 #include <deal.II/base/config.h> 22 #include <deal.II/lac/parallel_vector.h> 32 template <
typename Number>
36 #ifdef DEAL_II_WITH_MPI 37 for (size_type j=0; j<compress_requests.size(); j++)
38 MPI_Request_free(&compress_requests[j]);
39 compress_requests.clear();
40 for (size_type j=0; j<update_ghost_values_requests.size(); j++)
41 MPI_Request_free(&update_ghost_values_requests[j]);
42 update_ghost_values_requests.clear();
48 template <
typename Number>
52 if (new_alloc_size > allocated_size)
54 Assert (((allocated_size > 0 && val != 0) ||
58 val =
new Number[new_alloc_size];
59 allocated_size = new_alloc_size;
61 else if (new_alloc_size == 0)
72 template <
typename Number>
82 vector_view.reinit (size, val);
94 this->operator = (Number());
96 vector_is_ghosted =
false;
101 template <
typename Number>
102 template <
typename Number2>
107 clear_mpi_requests();
117 const size_type new_allocated_size = partitioner->local_size() +
118 partitioner->n_ghost_indices();
119 resize_val (new_allocated_size);
120 vector_view.reinit (partitioner->local_size(), val);
123 Assert (vector_view.size() == partitioner->local_size(),
127 this->operator= (Number());
129 if (import_data != 0)
131 delete [] import_data;
140 vector_is_ghosted =
false;
145 template <
typename Number>
149 const MPI_Comm communicator)
152 std_cxx1x::shared_ptr<const Utilities::MPI::Partitioner> new_partitioner
154 ghost_indices, communicator));
155 reinit (new_partitioner);
160 template <
typename Number>
163 const MPI_Comm communicator)
167 std_cxx1x::shared_ptr<const Utilities::MPI::Partitioner> new_partitioner
169 ghost_indices, communicator));
170 reinit (new_partitioner);
175 template <
typename Number>
179 clear_mpi_requests();
180 partitioner = partitioner_in;
183 const size_type new_allocated_size = partitioner->local_size() +
184 partitioner->n_ghost_indices();
185 resize_val (new_allocated_size);
186 vector_view.reinit (partitioner->local_size(), val);
189 this->operator= (Number());
191 if (import_data != 0)
193 delete [] import_data;
202 vector_is_ghosted =
false;
207 template <
typename Number>
210 const bool call_update_ghost_values)
215 vector_view = c.vector_view;
216 if (call_update_ghost_values ==
true)
217 update_ghost_values();
219 vector_is_ghosted =
false;
224 template <
typename Number>
227 ::VectorOperation::values operation)
229 Assert (vector_is_ghosted ==
false,
230 ExcMessage (
"Cannot call compress() on a ghosted vector"));
232 #ifdef DEAL_II_WITH_MPI 240 if (operation == VectorOperation::insert)
255 const size_type n_ghost_targets = part.
ghost_targets().size();
260 if (compress_requests.size() == 0)
263 const unsigned int channel = counter + 400;
264 unsigned int current_index_start = 0;
265 compress_requests.resize (n_import_targets + n_ghost_targets);
268 if (import_data == 0)
270 for (size_type i=0; i<n_import_targets; i++)
272 MPI_Recv_init (&import_data[current_index_start],
279 &compress_requests[i]);
286 for (size_type i=0; i<n_ghost_targets; i++)
288 MPI_Send_init (&this->val[current_index_start],
295 &compress_requests[n_import_targets+i]);
303 compress_requests.size());
304 if (compress_requests.size() > 0)
306 int ierr = MPI_Startall(compress_requests.size(),&compress_requests[0]);
310 #else // ifdef DEAL_II_WITH_MPI 318 template <
typename Number>
322 #ifdef DEAL_II_WITH_MPI 327 if (operation == VectorOperation::insert)
344 const size_type n_ghost_targets = part.
ghost_targets().size();
346 if (operation != ::VectorOperation::insert)
348 compress_requests.size());
351 if (compress_requests.size() > 0 && n_import_targets > 0)
353 int ierr = MPI_Waitall (n_import_targets, &compress_requests[0],
354 MPI_STATUSES_IGNORE);
357 Number *read_position = import_data;
358 std::vector<std::pair<size_type, size_type> >::const_iterator
365 if (operation != ::VectorOperation::insert)
367 for (size_type j=my_imports->first; j<my_imports->second; j++)
368 local_element(j) += *read_position++;
371 for (size_type j=my_imports->first; j<my_imports->second;
372 j++, read_position++)
373 Assert(*read_position == 0. ||
374 std::abs(local_element(j) - *read_position) <
375 std::abs(local_element(j)) * 1000. *
376 std::numeric_limits<Number>::epsilon(),
377 ExcMessage(
"Inserted elements do not match."));
381 if (compress_requests.size() > 0 && n_ghost_targets > 0)
383 int ierr = MPI_Waitall (n_ghost_targets,
384 &compress_requests[n_import_targets],
385 MPI_STATUSES_IGNORE);
399 template <
typename Number>
403 #ifdef DEAL_II_WITH_MPI 414 const size_type n_ghost_targets = part.
ghost_targets().size();
419 if (update_ghost_values_requests.size() == 0)
423 size_type current_index_start = part.
local_size();
424 update_ghost_values_requests.resize (n_import_targets+n_ghost_targets);
425 for (size_type i=0; i<n_ghost_targets; i++)
429 MPI_Recv_init (const_cast<Number *>(&val[current_index_start]),
436 &update_ghost_values_requests[i]);
445 current_index_start = 0;
446 for (size_type i=0; i<n_import_targets; i++)
448 MPI_Send_init (&import_data[current_index_start],
454 &update_ghost_values_requests[n_ghost_targets+i]);
464 Number *write_position = import_data;
465 std::vector<std::pair<size_type, size_type> >::const_iterator
468 for (size_type j=my_imports->first; j<my_imports->second; j++)
469 *write_position++ = local_element(j);
473 update_ghost_values_requests.size());
474 if (update_ghost_values_requests.size() > 0)
476 int ierr = MPI_Startall(update_ghost_values_requests.size(),
477 &update_ghost_values_requests[0]);
487 template <
typename Number>
491 #ifdef DEAL_II_WITH_MPI 495 partitioner->import_targets().size(),
496 update_ghost_values_requests.size());
497 if (update_ghost_values_requests.size() > 0)
502 int ierr = MPI_Waitall (update_ghost_values_requests.size(),
503 &update_ghost_values_requests[0],
504 MPI_STATUSES_IGNORE);
508 vector_is_ghosted =
true;
513 template <
typename Number>
517 #ifdef DEAL_II_WITH_MPI 523 int ierr = MPI_Testall (update_ghost_values_requests.size(),
524 &update_ghost_values_requests[0],
525 &flag, MPI_STATUSES_IGNORE);
528 ExcMessage(
"MPI found unfinished update_ghost_values() requests" 529 "when calling swap, which is not allowed"));
530 ierr = MPI_Testall (compress_requests.size(), &compress_requests[0],
531 &flag, MPI_STATUSES_IGNORE);
534 ExcMessage(
"MPI found unfinished compress() requests " 535 "when calling swap, which is not allowed"));
538 std::swap (compress_requests, v.compress_requests);
539 std::swap (update_ghost_values_requests, v.update_ghost_values_requests);
542 std::swap (partitioner, v.partitioner);
543 std::swap (allocated_size, v.allocated_size);
544 std::swap (val, v.val);
545 std::swap (import_data, v.import_data);
546 std::swap (vector_is_ghosted, v.vector_is_ghosted);
550 vector_view.reinit (partitioner->local_size(), val);
551 v.vector_view.reinit (v.partitioner->local_size(), v.val);
556 template <
typename Number>
560 std::size_t memory =
sizeof(*this);
561 memory +=
sizeof (Number) * static_cast<std::size_t>(allocated_size);
566 if (partitioner.use_count() > 0)
567 memory += partitioner->memory_consumption()/partitioner.use_count()+1;
568 if (import_data != 0)
569 memory += (
static_cast<std::size_t
>(partitioner->n_import_indices())*
576 template <
typename Number>
579 const unsigned int precision,
580 const bool scientific,
581 const bool across)
const 585 std::ios::fmtflags old_flags = out.flags();
586 unsigned int old_precision = out.precision (precision);
588 out.precision (precision);
590 out.setf (std::ios::scientific, std::ios::floatfield);
592 out.setf (std::ios::fixed, std::ios::floatfield);
597 #ifdef DEAL_II_WITH_MPI 598 if (partitioner->n_mpi_processes() > 1)
599 for (
unsigned int i=0; i<partitioner->this_mpi_process(); i++)
600 MPI_Barrier (partitioner->get_communicator());
603 out <<
"Process #" << partitioner->this_mpi_process() << std::endl
604 <<
"Local range: [" << partitioner->local_range().first <<
", " 605 << partitioner->local_range().second <<
"), global size: " 606 << partitioner->size() << std::endl
607 <<
"Vector data:" << std::endl;
609 for (size_type i=0; i<partitioner->local_size(); ++i)
610 out << local_element(i) <<
' ';
612 for (size_type i=0; i<partitioner->local_size(); ++i)
613 out << local_element(i) << std::endl;
616 if (vector_is_ghosted)
618 out <<
"Ghost entries (global index / value):" << std::endl;
620 for (size_type i=0; i<partitioner->n_ghost_indices(); ++i)
621 out <<
'(' << partitioner->ghost_indices().nth_index_in_set(i)
622 <<
'/' << local_element(partitioner->local_size()+i) <<
") ";
624 for (size_type i=0; i<partitioner->n_ghost_indices(); ++i)
625 out <<
'(' << partitioner->ghost_indices().nth_index_in_set(i)
626 <<
'/' << local_element(partitioner->local_size()+i) <<
")" 632 #ifdef DEAL_II_WITH_MPI 633 if (partitioner->n_mpi_processes() > 1)
635 MPI_Barrier (partitioner->get_communicator());
637 for (
unsigned int i=partitioner->this_mpi_process()+1;
638 i<partitioner->n_mpi_processes(); i++)
639 MPI_Barrier (partitioner->get_communicator());
645 out.flags (old_flags);
646 out.precision(old_precision);
654 DEAL_II_NAMESPACE_CLOSE
unsigned int n_ghost_indices() const
const std::vector< std::pair< types::global_dof_index, types::global_dof_index > > & import_indices() const
#define AssertDimension(dim1, dim2)
void compress_start(const unsigned int communication_channel=0,::VectorOperation::values operation=VectorOperation::add)
unsigned int this_mpi_process() const
types::global_dof_index size() const
void swap(Vector< Number > &v)
void compress_finish(::VectorOperation::values operation)
std_cxx1x::shared_ptr< const Utilities::MPI::Partitioner > partitioner
::ExceptionBase & ExcMessage(std::string arg1)
void reinit(const size_type size, const bool fast=false)
void resize_val(const size_type new_allocated_size)
const MPI_Comm & get_communicator() const
#define AssertThrow(cond, exc)
const std::vector< std::pair< unsigned int, types::global_dof_index > > & ghost_targets() const
::ExceptionBase & ExcIO()
const std::vector< std::pair< unsigned int, types::global_dof_index > > & import_targets() const
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
#define Assert(cond, exc)
void update_ghost_values_finish() const
void update_ghost_values_start(const unsigned int communication_channel=0) const
unsigned int n_import_indices() const
void clear_mpi_requests()
unsigned int n_mpi_processes() const
::ExceptionBase & ExcNotInitialized()
void copy_from(const Vector< Number > &in_vector, const bool call_update_ghost_values=false)
std::size_t memory_consumption() const
::ExceptionBase & ExcInternalError()
unsigned int local_size() const