52 void add_spec(
const T &a, T &b,
53 gmm::abstract_null_type, gmm::abstract_vector){
59 void add_spec(
const T &a, T &b,
60 gmm::abstract_null_type, gmm::abstract_matrix){
66 void add_list(
const T &a, T &b){
67 GMM_ASSERT2(a.size() == b.size(),
"size mismatch");
70 auto ita_end = end(a);
71 for (;ita != ita_end; ++ita, ++itb) gmm::add(*ita, *itb);
76 void add_spec(
const T &a, T &b,
77 gmm::abstract_vector, gmm::abstract_vector){
83 void add_spec(
const T &a, T &b,
84 gmm::abstract_matrix, gmm::abstract_vector){
90 void equal_resize_spec(T &a,
const T &b,
91 gmm::abstract_null_type, gmm::abstract_vector){
92 gmm::resize(a, gmm::vect_size(b));
97 void equal_resize_spec(T &a,
const T &b,
98 gmm::abstract_null_type, gmm::abstract_matrix){
99 gmm::resize(a, gmm::mat_nrows(b), gmm::mat_ncols(b));
104 void equal_resize_list(T &a,
const T &b){
105 GMM_ASSERT2(a.empty(),
"the first list should be still empty");
109 auto ita_end = end(a);
110 using Component =
typename T::value_type;
111 using AlgoC =
typename gmm::linalg_traits<Component>::linalg_type;
112 for (;ita != ita_end; ++ita, ++itb){
113 equal_resize_spec(*ita, *itb, gmm::abstract_null_type{}, AlgoC{});
119 void equal_resize_spec(T &a,
const T &b,
120 gmm::abstract_vector, gmm::abstract_vector){
121 equal_resize_list(a, b);
126 void equal_resize_spec(T &a,
const T &b,
127 gmm::abstract_matrix, gmm::abstract_vector){
128 equal_resize_list(a, b);
136 using AlgoT =
typename gmm::linalg_traits<T>::linalg_type;
137 using Component =
typename T::value_type;
138 using AlgoC =
typename gmm::linalg_traits<Component>::linalg_type;
139 detail::add_spec(a, b, AlgoC{}, AlgoT{});
147 using AlgoT =
typename gmm::linalg_traits<T>::linalg_type;
148 using Component =
typename T::value_type;
149 using AlgoC =
typename gmm::linalg_traits<Component>::linalg_type;
150 detail::equal_resize_spec(a, b, AlgoC{}, AlgoT{});
167 if (distributed.num_threads() == 1)
return;
170 for(
size_type t = 1; t != distributed.num_threads(); ++t){
176 if (distributed.num_threads() == 1 ||
177 distributed.this_thread() == 0)
return original;
178 else return distributed;
185 T& operator = (
const T &x){
186 return distributed = x;
190 if (distributed.num_threads() == 1)
return;
194 cerr <<
"Accumulation distribution should not run in parallel";
199 auto to_add = vector<T*>{};
200 to_add.push_back(&original);
201 for (
size_type t = 1; t != distributed.num_threads(); ++t){
202 to_add.push_back(&distributed(t));
209 while (to_add.size() > 1){
211 auto i = distributed.this_thread() * 2;
212 if (i + 1 < to_add.size()){
213 auto &target = *to_add[i];
214 auto &source = *to_add[i + 1];
215 gen_add(source, target);
219 for (
auto it = begin(to_add), ite = end(to_add);
220 it != end(to_add) && next(it) != end(to_add);
221 it = to_add.erase(next(it)));
Takes a matrix or vector, or vector of matrices or vectors and creates an empty copy on each thread.
Use this template class for any object you want to distribute to open_MP threads.
Tools for multithreaded, OpenMP and Boost based parallelization.
#define GETFEM_OMP_PARALLEL(body)
Organizes a proper parallel omp section:
Basic definitions and tools of GMM.
size_t size_type
used as the common size type in the library
GEneric Tool for Finite Element Methods.
void equal_resize(T &a, const T &b)
Resize 'a' to the same size as 'b'.
void gen_add(const T &a, T &b)
Generic addition for gmm types as well as vectors of gmm types.
bool me_is_multithreaded_now()
is the program running in the parallel section