*/
AlignedVector<Number> values;
+ /**
+ * Convenience function used at the end of initialization or
+ * reinitialization. Resets (if necessary) the loop partitioner to the
+ * correct state, based on its current state and the length of the vector.
+ */
+ void
+ maybe_reset_thread_partitioner();
+
+ /**
+ * Actual implementation of the reinit functions.
+ */
+ void
+ do_reinit(const size_type new_size,
+ const bool omit_zeroing_entries,
+ const bool reset_partitioner);
+
/**
* For parallel loops with TBB, this member variable stores the affinity
* information of loops.
inline void
Vector<Number>::swap(Vector<Number> &v)
{
- std::swap(values, v.values);
+ values.swap(v.values);
+ std::swap(thread_loop_partitioner, v.thread_loop_partitioner);
}
// the load stuff again from the archive
ar &static_cast<Subscriptor &>(*this);
ar &values;
+ maybe_reset_thread_partitioner();
}
#endif
copy_petsc_vector(const PETScWrappers::VectorBase &v,
::dealii::Vector<Number> & out)
{
+ if (v.size() == 0)
+ {
+ out.reinit(0);
+ return;
+ }
// Create a sequential PETSc vector and then copy over the entries into
// the deal.II vector.
Vec sequential_vector;
template <typename Number>
Vector<Number>::Vector(const PETScWrappers::VectorBase &v)
{
- if (v.size() != 0)
- {
- internal::copy_petsc_vector(v, *this);
- }
+ internal::copy_petsc_vector(v, *this);
}
#endif
AssertThrow(ierr == 0, ExcTrilinosError(ierr));
std::copy(start_ptr[0], start_ptr[0] + size(), begin());
+
+ maybe_reset_thread_partitioner();
}
}
if (PointerComparison::equal(this, &v))
return *this;
- thread_loop_partitioner = v.thread_loop_partitioner;
if (size() != v.size())
reinit(v, true);
inline Vector<Number> &
Vector<Number>::operator=(const Vector<Number2> &v)
{
- thread_loop_partitioner = v.thread_loop_partitioner;
if (size() != v.size())
reinit(v, true);
inline void
Vector<Number>::reinit(const size_type n, const bool omit_zeroing_entries)
{
- const std::size_t old_size = size();
-
- // avoid allocating if the new size is not larger than the old size
- if (n <= size())
- {
- thread_loop_partitioner =
- std::make_shared<parallel::internal::TBBPartitioner>();
- if (n == 0)
- {
- values.clear();
- }
- else if (n != size())
- values.resize_fast(n);
-
- if (!omit_zeroing_entries)
- values.fill();
- return;
- }
-
- // otherwise size() < n and we must allocate
- AlignedVector<Number> new_values;
- new_values.resize_fast(n);
- if (!omit_zeroing_entries)
- new_values.fill();
- new_values.swap(values);
-
- if (old_size != size())
- {
- // only reset the partitioner if we actually expect a significant vector
- // size
- if (size() >=
- 4 * internal::VectorImplementation::minimum_parallel_grain_size)
- thread_loop_partitioner =
- std::make_shared<parallel::internal::TBBPartitioner>();
- }
+ do_reinit(n, omit_zeroing_entries, true);
}
inline void
Vector<Number>::grow_or_shrink(const size_type n)
{
- const std::size_t old_size = size();
- if (n == 0)
- {
- values.clear();
- thread_loop_partitioner =
- std::make_shared<parallel::internal::TBBPartitioner>();
- return;
- }
-
values.resize(n);
- if (old_size != n)
- {
- // only reset the partitioner if we actually expect a significant vector
- // size
- if (size() >=
- 4 * internal::VectorImplementation::minimum_parallel_grain_size)
- thread_loop_partitioner =
- std::make_shared<parallel::internal::TBBPartitioner>();
- }
+ maybe_reset_thread_partitioner();
}
Vector<Number>::reinit(const Vector<Number2> &v,
const bool omit_zeroing_entries)
{
+ do_reinit(v.size(), omit_zeroing_entries, false);
thread_loop_partitioner = v.thread_loop_partitioner;
-
- reinit(v.size(), omit_zeroing_entries);
}
}
+
+template <typename Number>
+void
+Vector<Number>::maybe_reset_thread_partitioner()
+{
+ if (size() >= 4 * internal::VectorImplementation::minimum_parallel_grain_size)
+ {
+ if (thread_loop_partitioner == nullptr)
+ thread_loop_partitioner =
+ std::make_shared<parallel::internal::TBBPartitioner>();
+ }
+ else
+ thread_loop_partitioner.reset();
+}
+
+
+
+template <typename Number>
+void
+Vector<Number>::do_reinit(const size_type new_size,
+ const bool omit_zeroing_entries,
+ const bool reset_partitioner)
+{
+ if (new_size <= size())
+ {
+ if (new_size == 0)
+ {
+ values.clear();
+ }
+ else
+ {
+ values.resize_fast(new_size);
+ if (!omit_zeroing_entries)
+ values.fill();
+ }
+ }
+ else
+ {
+ // otherwise size() < new_size and we must allocate
+ AlignedVector<Number> new_values;
+ new_values.resize_fast(new_size);
+ if (!omit_zeroing_entries)
+ new_values.fill();
+ new_values.swap(values);
+ }
+
+ if (reset_partitioner)
+ maybe_reset_thread_partitioner();
+}
+
+
DEAL_II_NAMESPACE_CLOSE
#endif