From 49e7b20b064893627a5b403449fdc29edf1cd3d8 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Fri, 28 Sep 2018 03:47:55 +0200 Subject: [PATCH] Fix compiling with THREADS=ON --- include/deal.II/base/timer.h | 2 ++ include/deal.II/fe/fe_tools.templates.h | 16 +++++++---- include/deal.II/lac/block_matrix_base.h | 6 +++- .../lac/la_parallel_vector.templates.h | 10 ++++++- include/deal.II/lac/precondition.h | 8 ++++++ .../deal.II/lac/swappable_vector.templates.h | 22 +++++++++++---- include/deal.II/lac/tensor_product_matrix.h | 8 ++++-- include/deal.II/lac/vector_memory.templates.h | 10 +++++++ .../deal.II/matrix_free/dof_info.templates.h | 25 +++++++++++++---- source/base/flow_function.cc | 10 +++++++ source/base/function_cspline.cc | 6 ++++ source/base/function_parser.cc | 8 ++++-- source/base/index_set.cc | 2 ++ source/base/logstream.cc | 26 +++++++++++++---- source/base/polynomial.cc | 16 ++++++++++- source/base/polynomials_abf.cc | 2 ++ source/base/polynomials_bdm.cc | 2 ++ source/base/polynomials_raviart_thomas.cc | 28 ++++++++++--------- source/base/polynomials_rt_bubbles.cc | 2 ++ source/base/timer.cc | 6 ++++ source/fe/fe_dgq.cc | 4 +++ source/fe/fe_nedelec.cc | 4 +++ source/fe/fe_poly_tensor.cc | 6 ++++ source/fe/fe_q_base.cc | 4 +++ source/fe/fe_system.cc | 4 +++ source/fe/mapping_fe_field.cc | 2 ++ source/fe/mapping_q_eulerian.cc | 2 ++ source/lac/lapack_full_matrix.cc | 16 +++++++++++ source/lac/scalapack.cc | 20 +++++++++++-- 29 files changed, 231 insertions(+), 46 deletions(-) diff --git a/include/deal.II/base/timer.h b/include/deal.II/base/timer.h index 1acb5750d2..1fad47765f 100644 --- a/include/deal.II/base/timer.h +++ b/include/deal.II/base/timer.h @@ -910,7 +910,9 @@ private: * A lock that makes sure that this class gives reasonable results even when * used with several threads. */ +#ifdef DEAL_II_WITH_THREADS Threads::Mutex mutex; +#endif }; diff --git a/include/deal.II/fe/fe_tools.templates.h b/include/deal.II/fe/fe_tools.templates.h index c741bc0c24..9721e87519 100644 --- a/include/deal.II/fe/fe_tools.templates.h +++ b/include/deal.II/fe/fe_tools.templates.h @@ -1281,7 +1281,9 @@ namespace FETools // they're in an anonymous namespace) in order to make icc happy // (which otherwise reports a multiply defined symbol when linking // libraries for more than one space dimension together +#ifdef DEAL_II_WITH_THREADS static Threads::Mutex fe_name_map_lock; +#endif // This is the map used by FETools::get_fe_by_name and // FETools::add_fe_name. It is only accessed by functions in this @@ -2404,13 +2406,15 @@ namespace FETools "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_")); if (name_end < name.size()) name.erase(name_end); - // first make sure that no other - // thread intercepts the - // operation of this function; - // for this, acquire the lock - // until we quit this function + // first make sure that no other + // thread intercepts the + // operation of this function; + // for this, acquire the lock + // until we quit this function +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock( internal::FEToolsAddFENameHelper::fe_name_map_lock); +#endif Assert( internal::FEToolsAddFENameHelper::fe_name_map[dim][spacedim].find(name) == @@ -2566,8 +2570,10 @@ namespace FETools { // Make sure no other thread // is just adding an element +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock( internal::FEToolsAddFENameHelper::fe_name_map_lock); +#endif AssertThrow(fe_name_map.find(name_part) != fe_name_map.end(), FETools::ExcInvalidFEName(name)); diff --git a/include/deal.II/lac/block_matrix_base.h b/include/deal.II/lac/block_matrix_base.h index 13c9b4a335..955d43d69c 100644 --- a/include/deal.II/lac/block_matrix_base.h +++ b/include/deal.II/lac/block_matrix_base.h @@ -1724,7 +1724,9 @@ BlockMatrixBase::set(const size_type row, // lock access to the temporary data structure to // allow multiple threads to call this function concurrently +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(temporary_data.mutex); +# endif // Resize scratch arrays if (temporary_data.column_indices.size() < this->n_block_cols()) @@ -1980,8 +1982,10 @@ BlockMatrixBase::add(const size_type row, return; } - // Lock scratch arrays, then resize them + // Lock scratch arrays, then resize them +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(temporary_data.mutex); +# endif if (temporary_data.column_indices.size() < this->n_block_cols()) { diff --git a/include/deal.II/lac/la_parallel_vector.templates.h b/include/deal.II/lac/la_parallel_vector.templates.h index f008b8ce53..7a63627e51 100644 --- a/include/deal.II/lac/la_parallel_vector.templates.h +++ b/include/deal.II/lac/la_parallel_vector.templates.h @@ -875,7 +875,9 @@ namespace LinearAlgebra #ifdef DEAL_II_WITH_MPI // make this function thread safe +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif // allocate import_data in case it is not set up yet if (import_data == nullptr && partitioner->n_import_indices() > 0) @@ -928,7 +930,9 @@ namespace LinearAlgebra // compress_requests.size() == 0 // make this function thread safe +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif Assert(partitioner->n_import_indices() == 0 || import_data != nullptr, ExcNotInitialized()); @@ -974,8 +978,10 @@ namespace LinearAlgebra partitioner->n_import_indices() == 0) return; - // make this function thread safe + // make this function thread safe +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif // allocate import_data in case it is not set up yet if (import_data == nullptr && partitioner->n_import_indices() > 0) @@ -1033,7 +1039,9 @@ namespace LinearAlgebra if (update_ghost_values_requests.size() > 0) { // make this function thread safe +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif partitioner->export_to_ghosted_array_finish( ArrayView(data.values.get() + partitioner->local_size(), diff --git a/include/deal.II/lac/precondition.h b/include/deal.II/lac/precondition.h index 45bdb20c13..595f2aa305 100644 --- a/include/deal.II/lac/precondition.h +++ b/include/deal.II/lac/precondition.h @@ -2308,7 +2308,9 @@ PreconditionChebyshev::vmult( VectorType & dst, const VectorType &src) const { +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif if (eigenvalues_are_initialized == false) estimate_eigenvalues(src); @@ -2334,7 +2336,9 @@ PreconditionChebyshev::Tvmult( VectorType & dst, const VectorType &src) const { +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif if (eigenvalues_are_initialized == false) estimate_eigenvalues(src); @@ -2360,7 +2364,9 @@ PreconditionChebyshev::step( VectorType & dst, const VectorType &src) const { +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif if (eigenvalues_are_initialized == false) estimate_eigenvalues(src); @@ -2387,7 +2393,9 @@ PreconditionChebyshev::Tstep( VectorType & dst, const VectorType &src) const { +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif if (eigenvalues_are_initialized == false) estimate_eigenvalues(src); diff --git a/include/deal.II/lac/swappable_vector.templates.h b/include/deal.II/lac/swappable_vector.templates.h index 54963f8920..64b98682d2 100644 --- a/include/deal.II/lac/swappable_vector.templates.h +++ b/include/deal.II/lac/swappable_vector.templates.h @@ -75,10 +75,12 @@ SwappableVector::operator=(const SwappableVector &v) if (filename != "") kill_file(); - // if in MT mode, block all other - // operations. if not in MT mode, - // this is a no-op + // if in MT mode, block all other + // operations. if not in MT mode, + // this is a no-op +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->lock); +#endif Vector::operator=(v); data_is_preloaded = false; @@ -107,7 +109,9 @@ SwappableVector::swap_out(const std::string &name) // if in MT mode, block all other // operations. if not in MT mode, // this is a no-op +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->lock); +#endif // check that we have not called // @p alert without the respective @@ -131,7 +135,9 @@ SwappableVector::reload() // possibly existing @p alert // calls. if not in MT mode, this // is a no-op +#ifdef DEAL_II_WITH_THREADS lock.lock(); +#endif // if data was already preloaded, // then there is no more need to @@ -147,10 +153,12 @@ SwappableVector::reload() // needed data_is_preloaded = false; - // release lock. the lock is - // also released in the other - // branch of the if-clause +// release lock. the lock is +// also released in the other +// branch of the if-clause +#ifdef DEAL_II_WITH_THREADS lock.unlock(); +#endif } } @@ -225,7 +233,9 @@ SwappableVector::kill_file() // (there should be none, but who // knows). if not in MT mode, // this is a no-op +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->lock); +#endif // this is too bad: someone // requested the vector in advance, diff --git a/include/deal.II/lac/tensor_product_matrix.h b/include/deal.II/lac/tensor_product_matrix.h index 53fcb039f1..6d86f64dbd 100644 --- a/include/deal.II/lac/tensor_product_matrix.h +++ b/include/deal.II/lac/tensor_product_matrix.h @@ -477,8 +477,10 @@ TensorProductMatrixSymmetricSumBase::vmult( { AssertDimension(dst_view.size(), this->m()); AssertDimension(src_view.size(), this->n()); +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); - const unsigned int n = +# endif + const unsigned int n = Utilities::fixed_power(size > 0 ? size : eigenvalues[0].size()); tmp_array.resize_fast(n * 2); constexpr int kernel_size = size > 0 ? size : 0; @@ -545,8 +547,10 @@ TensorProductMatrixSymmetricSumBase::apply_inverse( { AssertDimension(dst_view.size(), this->n()); AssertDimension(src_view.size(), this->m()); +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); - const unsigned int n = size > 0 ? size : eigenvalues[0].size(); +# endif + const unsigned int n = size > 0 ? size : eigenvalues[0].size(); tmp_array.resize_fast(Utilities::fixed_power(n)); constexpr int kernel_size = size > 0 ? size : 0; internal::EvaluatorTensorProduct::GrowingVectorMemory( , current_alloc(0) , log_statistics(log_statistics) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif pool.initialize(initial_size); } @@ -106,7 +108,9 @@ template inline VectorType * GrowingVectorMemory::alloc() { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif ++total_alloc; ++current_alloc; @@ -136,7 +140,9 @@ template inline void GrowingVectorMemory::free(const VectorType *const v) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif for (typename std::vector::iterator i = pool.data->begin(); i != pool.data->end(); @@ -158,7 +164,9 @@ template inline void GrowingVectorMemory::release_unused_memory() { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif if (pool.data != nullptr) pool.data->clear(); @@ -170,7 +178,9 @@ template inline std::size_t GrowingVectorMemory::memory_consumption() const { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif std::size_t result = sizeof(*this); const typename std::vector::const_iterator end = pool.data->end(); diff --git a/include/deal.II/matrix_free/dof_info.templates.h b/include/deal.II/matrix_free/dof_info.templates.h index a3400b2b50..349aade886 100644 --- a/include/deal.II/matrix_free/dof_info.templates.h +++ b/include/deal.II/matrix_free/dof_info.templates.h @@ -1286,11 +1286,15 @@ namespace internal static constexpr unsigned int bucket_size_threading = 256; void - compute_row_lengths(const unsigned int begin, - const unsigned int end, - const DoFInfo & dof_info, + compute_row_lengths(const unsigned int begin, + const unsigned int end, + const DoFInfo & dof_info, +#ifdef DEAL_II_WITH_THREADS std::vector &mutexes, - std::vector & row_lengths) +#else + std::vector &, +#endif + std::vector &row_lengths) { std::vector scratch; const unsigned int n_components = dof_info.start_components.back(); @@ -1313,8 +1317,11 @@ namespace internal // that are within the range of one lock at once const unsigned int next_bucket = (*it / bucket_size_threading + 1) * bucket_size_threading; +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock( mutexes[*it / bucket_size_threading]); +#endif + for (; it != end_unique && *it < next_bucket; ++it) { AssertIndexRange(*it, row_lengths.size()); @@ -1329,8 +1336,12 @@ namespace internal const unsigned int end, const DoFInfo & dof_info, const std::vector &row_lengths, - std::vector & mutexes, - dealii::SparsityPattern & connectivity_dof) +#ifdef DEAL_II_WITH_THREADS + std::vector &mutexes, +#else + std::vector &, +#endif + dealii::SparsityPattern &connectivity_dof) { std::vector scratch; const unsigned int n_components = dof_info.start_components.back(); @@ -1351,8 +1362,10 @@ namespace internal { const unsigned int next_bucket = (*it / bucket_size_threading + 1) * bucket_size_threading; +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock( mutexes[*it / bucket_size_threading]); +#endif for (; it != end_unique && *it < next_bucket; ++it) if (row_lengths[*it] > 0) connectivity_dof.add(*it, block); diff --git a/source/base/flow_function.cc b/source/base/flow_function.cc index 8dae6dc072..8bf63deeef 100644 --- a/source/base/flow_function.cc +++ b/source/base/flow_function.cc @@ -57,7 +57,9 @@ namespace Functions // guard access to the aux_* // variables in multithread mode +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif for (unsigned int d = 0; d < dim + 1; ++d) aux_values[d].resize(n_points); @@ -87,7 +89,9 @@ namespace Functions // guard access to the aux_* // variables in multithread mode +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif for (unsigned int d = 0; d < dim + 1; ++d) aux_values[d].resize(n_points); @@ -110,7 +114,9 @@ namespace Functions // guard access to the aux_* // variables in multithread mode +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif for (unsigned int d = 0; d < dim + 1; ++d) aux_values[d].resize(n_points); @@ -132,7 +138,9 @@ namespace Functions // guard access to the aux_* // variables in multithread mode +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif for (unsigned int d = 0; d < dim + 1; ++d) aux_gradients[d].resize(n_points); @@ -160,7 +168,9 @@ namespace Functions // guard access to the aux_* // variables in multithread mode +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif for (unsigned int d = 0; d < dim + 1; ++d) aux_values[d].resize(n_points); diff --git a/source/base/function_cspline.cc b/source/base/function_cspline.cc index cdc9972c49..46c83e8b82 100644 --- a/source/base/function_cspline.cc +++ b/source/base/function_cspline.cc @@ -73,7 +73,9 @@ namespace Functions // GSL functions may modify gsl_interp_accel *acc object (last argument). // This can only work in multithreaded applications if we lock the data // structures via a mutex. +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(acc_mutex); +# endif const double x = p[0]; Assert(x >= interpolation_points.front() && @@ -94,7 +96,9 @@ namespace Functions // GSL functions may modify gsl_interp_accel *acc object (last argument). // This can only work in multithreaded applications if we lock the data // structures via a mutex. +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(acc_mutex); +# endif const double x = p[0]; Assert(x >= interpolation_points.front() && @@ -118,7 +122,9 @@ namespace Functions // GSL functions may modify gsl_interp_accel *acc object (last argument). // This can only work in multithreaded applications if we lock the data // structures via a mutex. +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(acc_mutex); +# endif const double x = p[0]; Assert(x >= interpolation_points.front() && diff --git a/source/base/function_parser.cc b/source/base/function_parser.cc index 769c681851..3d27017dd0 100644 --- a/source/base/function_parser.cc +++ b/source/base/function_parser.cc @@ -241,8 +241,10 @@ namespace internal double mu_rand_seed(double seed) { +# ifdef DEAL_II_WITH_THREADS static Threads::Mutex rand_mutex; std::lock_guard lock(rand_mutex); +# endif static boost::random::uniform_real_distribution<> uniform_distribution(0, 1); @@ -261,8 +263,10 @@ namespace internal double mu_rand() { - static Threads::Mutex rand_mutex; - std::lock_guard lock(rand_mutex); +# ifdef DEAL_II_WITH_THREADS + static Threads::Mutex rand_mutex; + std::lock_guard lock(rand_mutex); +# endif static boost::random::uniform_real_distribution<> uniform_distribution(0, 1); static boost::random::mt19937 rng( diff --git a/source/base/index_set.cc b/source/base/index_set.cc index 5a491e5f7a..7b69d4f06e 100644 --- a/source/base/index_set.cc +++ b/source/base/index_set.cc @@ -129,7 +129,9 @@ IndexSet::do_compress() const // via a mutex, so that users can call 'const' functions from threads // in parallel (and these 'const' functions can then call compress() // which itself calls the current function) +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(compress_mutex); +#endif // see if any of the contiguous ranges can be merged. do not use // std::vector::erase in-place as it is quadratic in the number of diff --git a/source/base/logstream.cc b/source/base/logstream.cc index c1c97a3379..976c99064f 100644 --- a/source/base/logstream.cc +++ b/source/base/logstream.cc @@ -27,8 +27,10 @@ DEAL_II_NAMESPACE_OPEN namespace { +#ifdef DEAL_II_WITH_THREADS Threads::Mutex log_lock; Threads::Mutex write_lock; +#endif } // namespace @@ -191,7 +193,9 @@ LogStream::operator<<(std::ostream &(*p)(std::ostream &)) if (query_streambuf.flushed()) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(write_lock); +#endif // Print the line head in case of a previous newline: if (at_newline) @@ -218,7 +222,9 @@ LogStream::attach(std::ostream & o, const bool print_job_id, const std::ios_base::fmtflags flags) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(log_lock); +#endif file = &o; o.setf(flags); if (print_job_id) @@ -229,7 +235,9 @@ LogStream::attach(std::ostream & o, void LogStream::detach() { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(log_lock); +#endif file = nullptr; } @@ -347,9 +355,11 @@ LogStream::width(const std::streamsize wide) unsigned int LogStream::depth_console(const unsigned int n) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(log_lock); - const unsigned int h = std_depth; - std_depth = n; +#endif + const unsigned int h = std_depth; + std_depth = n; return h; } @@ -358,9 +368,11 @@ LogStream::depth_console(const unsigned int n) unsigned int LogStream::depth_file(const unsigned int n) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(log_lock); - const unsigned int h = file_depth; - file_depth = n; +#endif + const unsigned int h = file_depth; + file_depth = n; return h; } @@ -369,9 +381,11 @@ LogStream::depth_file(const unsigned int n) bool LogStream::log_thread_id(const bool flag) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(log_lock); - const bool h = print_thread_id; - print_thread_id = flag; +#endif + const bool h = print_thread_id; + print_thread_id = flag; return h; } diff --git a/source/base/polynomial.cc b/source/base/polynomial.cc index 141d55dd6c..2bc3f1d25a 100644 --- a/source/base/polynomial.cc +++ b/source/base/polynomial.cc @@ -38,8 +38,10 @@ DEAL_II_NAMESPACE_OPEN // more fine-grained solution namespace { +#ifdef DEAL_II_WITH_THREADS Threads::Mutex coefficients_lock; -} +#endif +} // namespace @@ -1006,7 +1008,9 @@ namespace Polynomials // of this function // for this, acquire the lock // until we quit this function +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(coefficients_lock); +#endif // The first 2 coefficients // are hard-coded @@ -1066,9 +1070,13 @@ namespace Polynomials } else if (k == 2) { +#ifdef DEAL_II_WITH_THREADS coefficients_lock.unlock(); +#endif compute_coefficients(1); +#ifdef DEAL_II_WITH_THREADS coefficients_lock.lock(); +#endif std::vector c2(3); @@ -1091,9 +1099,13 @@ namespace Polynomials // allow the called // function to acquire it // itself +#ifdef DEAL_II_WITH_THREADS coefficients_lock.unlock(); +#endif compute_coefficients(k - 1); +#ifdef DEAL_II_WITH_THREADS coefficients_lock.lock(); +#endif std::vector ck(k + 1); @@ -1140,7 +1152,9 @@ namespace Polynomials // then get a pointer to the array // of coefficients. do that in a MT // safe way +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(coefficients_lock); +#endif return *recursive_coefficients[k]; } diff --git a/source/base/polynomials_abf.cc b/source/base/polynomials_abf.cc index b8ca149a93..bf698b1ea4 100644 --- a/source/base/polynomials_abf.cc +++ b/source/base/polynomials_abf.cc @@ -86,7 +86,9 @@ PolynomialsABF::compute( // using a mutex to make sure they // are not used by multiple threads // at once +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif p_values.resize((values.size() == 0) ? 0 : n_sub); p_grads.resize((grads.size() == 0) ? 0 : n_sub); diff --git a/source/base/polynomials_bdm.cc b/source/base/polynomials_bdm.cc index 51491c0a0b..860b853658 100644 --- a/source/base/polynomials_bdm.cc +++ b/source/base/polynomials_bdm.cc @@ -85,7 +85,9 @@ PolynomialsBDM::compute( // are not used by multiple threads // at once { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif p_values.resize((values.size() == 0) ? 0 : n_sub); p_grads.resize((grads.size() == 0) ? 0 : n_sub); diff --git a/source/base/polynomials_raviart_thomas.cc b/source/base/polynomials_raviart_thomas.cc index 8bf74e9881..9505832a04 100644 --- a/source/base/polynomials_raviart_thomas.cc +++ b/source/base/polynomials_raviart_thomas.cc @@ -80,21 +80,23 @@ PolynomialsRaviartThomas::compute( Assert(fourth_derivatives.size() == n_pols || fourth_derivatives.size() == 0, ExcDimensionMismatch(fourth_derivatives.size(), n_pols)); - // have a few scratch - // arrays. because we don't want to - // re-allocate them every time this - // function is called, we make them - // static. however, in return we - // have to ensure that the calls to - // the use of these variables is - // locked with a mutex. if the - // mutex is removed, several tests - // (notably - // deal.II/create_mass_matrix_05) - // will start to produce random - // results in multithread mode +// have a few scratch +// arrays. because we don't want to +// re-allocate them every time this +// function is called, we make them +// static. however, in return we +// have to ensure that the calls to +// the use of these variables is +// locked with a mutex. if the +// mutex is removed, several tests +// (notably +// deal.II/create_mass_matrix_05) +// will start to produce random +// results in multithread mode +#ifdef DEAL_II_WITH_THREADS static Threads::Mutex mutex; std::lock_guard lock(mutex); +#endif static std::vector p_values; static std::vector> p_grads; diff --git a/source/base/polynomials_rt_bubbles.cc b/source/base/polynomials_rt_bubbles.cc index 117d244723..8cc0447c6f 100644 --- a/source/base/polynomials_rt_bubbles.cc +++ b/source/base/polynomials_rt_bubbles.cc @@ -73,8 +73,10 @@ PolynomialsRT_Bubbles::compute( // using a mutex to make sure they are not used by multiple threads // at once { +#ifdef DEAL_II_WITH_THREADS static Threads::Mutex mutex; std::lock_guard lock(mutex); +#endif static std::vector> p_values; static std::vector> p_grads; diff --git a/source/base/timer.cc b/source/base/timer.cc index e2a1fba761..433bcb132c 100644 --- a/source/base/timer.cc +++ b/source/base/timer.cc @@ -412,7 +412,9 @@ TimerOutput::~TimerOutput() void TimerOutput::enter_subsection(const std::string §ion_name) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif Assert(section_name.empty() == false, ExcMessage("Section string is empty.")); @@ -457,7 +459,9 @@ TimerOutput::leave_subsection(const std::string §ion_name) Assert(!active_sections.empty(), ExcMessage("Cannot exit any section because none has been entered!")); +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif if (section_name != "") { @@ -873,7 +877,9 @@ TimerOutput::enable_output() void TimerOutput::reset() { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif sections.clear(); active_sections.clear(); timer_all.restart(); diff --git a/source/fe/fe_dgq.cc b/source/fe/fe_dgq.cc index 439fb5d7b5..a923c88fbf 100644 --- a/source/fe/fe_dgq.cc +++ b/source/fe/fe_dgq.cc @@ -408,7 +408,9 @@ FE_DGQ::get_prolongation_matrix( // initialization upon first request if (this->prolongation[refinement_case - 1][child].n() == 0) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); +#endif // if matrix got updated while waiting for the lock if (this->prolongation[refinement_case - 1][child].n() == @@ -488,7 +490,9 @@ FE_DGQ::get_restriction_matrix( // initialization upon first request if (this->restriction[refinement_case - 1][child].n() == 0) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); +#endif // if matrix got updated while waiting for the lock... if (this->restriction[refinement_case - 1][child].n() == diff --git a/source/fe/fe_nedelec.cc b/source/fe/fe_nedelec.cc index 51f5fe7515..367cd35799 100644 --- a/source/fe/fe_nedelec.cc +++ b/source/fe/fe_nedelec.cc @@ -2985,7 +2985,9 @@ FE_Nedelec::get_prolongation_matrix( // initialization upon first request if (this->prolongation[refinement_case - 1][child].n() == 0) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); +#endif // if matrix got updated while waiting for the lock if (this->prolongation[refinement_case - 1][child].n() == @@ -3047,7 +3049,9 @@ FE_Nedelec::get_restriction_matrix( // initialization upon first request if (this->restriction[refinement_case - 1][child].n() == 0) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); +#endif // if matrix got updated while waiting for the lock... if (this->restriction[refinement_case - 1][child].n() == diff --git a/source/fe/fe_poly_tensor.cc b/source/fe/fe_poly_tensor.cc index 2dc68bc749..f68b05c36c 100644 --- a/source/fe/fe_poly_tensor.cc +++ b/source/fe/fe_poly_tensor.cc @@ -201,7 +201,9 @@ FE_PolyTensor::shape_value_component( Assert(i < this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell)); Assert(component < dim, ExcIndexRange(component, 0, dim)); +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(cache_mutex); +#endif if (cached_point != p || cached_values.size() == 0) { @@ -247,7 +249,9 @@ FE_PolyTensor::shape_grad_component( Assert(i < this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell)); Assert(component < dim, ExcIndexRange(component, 0, dim)); +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(cache_mutex); +#endif if (cached_point != p || cached_grads.size() == 0) { @@ -294,7 +298,9 @@ FE_PolyTensor::shape_grad_grad_component( Assert(i < this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell)); Assert(component < dim, ExcIndexRange(component, 0, dim)); +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(cache_mutex); +#endif if (cached_point != p || cached_grad_grads.size() == 0) { diff --git a/source/fe/fe_q_base.cc b/source/fe/fe_q_base.cc index fd4f429c22..09a7b01f1f 100644 --- a/source/fe/fe_q_base.cc +++ b/source/fe/fe_q_base.cc @@ -1232,7 +1232,9 @@ FE_Q_Base::get_prolongation_matrix( // initialization upon first request if (this->prolongation[refinement_case - 1][child].n() == 0) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); +#endif // if matrix got updated while waiting for the lock if (this->prolongation[refinement_case - 1][child].n() == @@ -1434,7 +1436,9 @@ FE_Q_Base::get_restriction_matrix( // initialization upon first request if (this->restriction[refinement_case - 1][child].n() == 0) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); +#endif // if matrix got updated while waiting for the lock... if (this->restriction[refinement_case - 1][child].n() == diff --git a/source/fe/fe_system.cc b/source/fe/fe_system.cc index 89f88c634f..a10d8c14b0 100644 --- a/source/fe/fe_system.cc +++ b/source/fe/fe_system.cc @@ -718,7 +718,9 @@ FESystem::get_restriction_matrix( // initialization upon first request if (this->restriction[refinement_case - 1][child].n() == 0) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); +#endif // check if updated while waiting for lock if (this->restriction[refinement_case - 1][child].n() == @@ -815,7 +817,9 @@ FESystem::get_prolongation_matrix( // restriction matrix if (this->prolongation[refinement_case - 1][child].n() == 0) { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(this->mutex); +#endif if (this->prolongation[refinement_case - 1][child].n() == this->dofs_per_cell) diff --git a/source/fe/mapping_fe_field.cc b/source/fe/mapping_fe_field.cc index 5289c9d1e7..879388ff8d 100644 --- a/source/fe/mapping_fe_field.cc +++ b/source/fe/mapping_fe_field.cc @@ -321,7 +321,9 @@ MappingFEField::get_vertices( euler_dof_handler->get_fe().n_components())); { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(fe_values_mutex); +#endif fe_values.reinit(dof_cell); fe_values.get_function_values(*euler_vector, values); } diff --git a/source/fe/mapping_q_eulerian.cc b/source/fe/mapping_q_eulerian.cc index e4bd088f83..530c0c8432 100644 --- a/source/fe/mapping_q_eulerian.cc +++ b/source/fe/mapping_q_eulerian.cc @@ -221,7 +221,9 @@ MappingQEulerian::MappingQEulerianGeneric:: // fill shift vector for each support point using an fe_values object. make // sure that the fe_values variable isn't used simultaneously from different // threads +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(fe_values_mutex); +#endif fe_values.reinit(dof_cell); if (mg_vector) { diff --git a/source/lac/lapack_full_matrix.cc b/source/lac/lapack_full_matrix.cc index e075424f79..40393811b4 100644 --- a/source/lac/lapack_full_matrix.cc +++ b/source/lac/lapack_full_matrix.cc @@ -670,7 +670,9 @@ LAPACKFullMatrix::vmult(Vector & w, } case svd: { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif AssertDimension(v.size(), this->n()); AssertDimension(w.size(), this->m()); // Compute V^T v @@ -705,7 +707,9 @@ LAPACKFullMatrix::vmult(Vector & w, } case inverse_svd: { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif AssertDimension(w.size(), this->n()); AssertDimension(v.size(), this->m()); // Compute U^T v @@ -805,7 +809,9 @@ LAPACKFullMatrix::Tvmult(Vector & w, } case svd: { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif AssertDimension(w.size(), this->n()); AssertDimension(v.size(), this->m()); @@ -841,7 +847,9 @@ LAPACKFullMatrix::Tvmult(Vector & w, } case inverse_svd: { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif AssertDimension(v.size(), this->n()); AssertDimension(w.size(), this->m()); @@ -996,7 +1004,9 @@ LAPACKFullMatrix::Tmmult(LAPACKFullMatrix & C, // https://stackoverflow.com/questions/3548069/multiplying-three-matrices-in-blas-with-the-middle-one-being-diagonal // http://mathforum.org/kb/message.jspa?messageID=3546564 +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif // First, get V*B into "work" array work.resize(kk * nn); // following http://icl.cs.utk.edu/lapack-forum/viewtopic.php?f=2&t=768#p2577 @@ -1369,7 +1379,9 @@ template number LAPACKFullMatrix::norm(const char type) const { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif Assert(state == LAPACKSupport::matrix || state == LAPACKSupport::inverse_matrix, @@ -1447,7 +1459,9 @@ template number LAPACKFullMatrix::reciprocal_condition_number(const number a_norm) const { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif Assert(state == cholesky, ExcState(state)); number rcond = 0.; @@ -1480,7 +1494,9 @@ template number LAPACKFullMatrix::reciprocal_condition_number() const { +#ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +#endif Assert(property == upper_triangular || property == lower_triangular, ExcProperty(property)); number rcond = 0.; diff --git a/source/lac/scalapack.cc b/source/lac/scalapack.cc index 8067646a20..57c96e37e6 100644 --- a/source/lac/scalapack.cc +++ b/source/lac/scalapack.cc @@ -1388,7 +1388,9 @@ ScaLAPACKMatrix::eigenpairs_symmetric( Assert(property == LAPACKSupport::symmetric, ExcMessage("Matrix has to be symmetric for this operation.")); +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif const bool use_values = (std::isnan(eigenvalue_limits.first) || std::isnan(eigenvalue_limits.second)) ? @@ -1719,7 +1721,9 @@ ScaLAPACKMatrix::eigenpairs_symmetric_MRRR( Assert(property == LAPACKSupport::symmetric, ExcMessage("Matrix has to be symmetric for this operation.")); +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif const bool use_values = (std::isnan(eigenvalue_limits.first) || std::isnan(eigenvalue_limits.second)) ? @@ -1956,7 +1960,9 @@ ScaLAPACKMatrix::compute_SVD(ScaLAPACKMatrix *U, ExcDimensionMismatch(grid->blacs_context, VT->grid->blacs_context)); } +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif std::vector sv(std::min(n_rows, n_columns)); @@ -2071,7 +2077,9 @@ ScaLAPACKMatrix::least_squares(ScaLAPACKMatrix &B, ExcMessage( "Use identical block-cyclic distribution for matrices A and B")); +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); +# endif if (grid->mpi_process_is_active) { @@ -2223,8 +2231,10 @@ ScaLAPACKMatrix::reciprocal_condition_number( Assert(state == LAPACKSupport::cholesky, ExcMessage( "Matrix has to be in Cholesky state before calling this function.")); +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); - NumberType rcond = 0.; +# endif + NumberType rcond = 0.; if (grid->mpi_process_is_active) { @@ -2326,8 +2336,10 @@ ScaLAPACKMatrix::norm_general(const char type) const Assert(state == LAPACKSupport::matrix || state == LAPACKSupport::inverse_matrix, ExcMessage("norms can be called in matrix state only.")); +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); - NumberType res = 0.; +# endif + NumberType res = 0.; if (grid->mpi_process_is_active) { @@ -2387,8 +2399,10 @@ ScaLAPACKMatrix::norm_symmetric(const char type) const ExcMessage("norms can be called in matrix state only.")); Assert(property == LAPACKSupport::symmetric, ExcMessage("Matrix has to be symmetric for this operation.")); +# ifdef DEAL_II_WITH_THREADS std::lock_guard lock(mutex); - NumberType res = 0.; +# endif + NumberType res = 0.; if (grid->mpi_process_is_active) { -- 2.39.5