5 #include <Eigen/Sparse>
16 template<
typename MatrixType>
20 SystemVectors(std::vector<MatrixType> sys, std::vector<Eigen::VectorXd> vec):
31 static std::pair<std::vector<int>, std::vector<int>>
35 std::vector<int> start(nb_threads);
36 std::vector<int> end(nb_threads);
39 unsigned batch_size = nb_elements / nb_threads;
40 unsigned batch_remainder = nb_elements % nb_threads;
43 for (
unsigned i = 0; i < nb_threads; ++i) {
44 if (i < batch_remainder){
45 start[i] = i * batch_size + i;
46 end[i] = start[i] + batch_size + 1;
49 start[i] = i * batch_size + batch_remainder;
50 end[i] = start[i] + batch_size;
54 return std::make_pair(start, end);
59 std::function<
void(
size_t start,
size_t end)> functor,
62 unsigned nb_threads_hint = std::thread::hardware_concurrency();
63 unsigned nb_threads = nb_threads_hint == 0 ? 8 : (nb_threads_hint);
68 std::vector<std::thread> my_threads(nb_threads);
72 for (
unsigned i = 0; i < nb_threads; ++i) {
73 my_threads[i] = std::thread(functor, start[i], end[i]);
77 for(
unsigned i = 0; i < nb_threads; ++i) {
78 functor(start[i], end[i]);
84 std::for_each(my_threads.begin(), my_threads.end(), std::mem_fn(&std::thread::join));
89 static inline SystemVectors<Eigen::SparseMatrix<double>>
92 std::vector<std::pair<size_t, size_t>> size_systems,
93 std::vector<size_t> size_vectors,
94 std::function<
void(
size_t start,
size_t end, std::vector<std::list<Eigen::Triplet<double>>> * triplets, std::vector<Eigen::VectorXd> * vecs)> batch_local_assembly,
99 std::vector<Eigen::SparseMatrix<double>> systems;
100 systems.reserve(size_systems.size());
101 std::vector<Eigen::VectorXd> vectors;
102 for (
auto size : size_vectors){
103 vectors.emplace_back(Eigen::VectorXd::Zero(size));
108 unsigned nb_threads_hint = std::thread::hardware_concurrency();
109 unsigned nb_threads = nb_threads_hint == 0 ? 8 : (nb_threads_hint);
115 std::vector<std::vector<std::list<Eigen::Triplet<double> > > > triplets(nb_threads, std::vector<std::list<Eigen::Triplet<double> > >(size_systems.size()));
116 std::vector<std::vector<Eigen::VectorXd>> vecs(nb_threads, vectors);
119 std::vector<std::thread> my_threads(nb_threads);
120 for (
unsigned i = 0; i < nb_threads; ++i) {
121 my_threads[i] = std::thread(batch_local_assembly, start[i], end[i], &triplets[i], &vecs[i]);
126 std::for_each(my_threads.begin(), my_threads.end(), std::mem_fn(&std::thread::join));
129 for (
size_t i = 0; i < size_systems.size(); i++){
130 systems.emplace_back(Eigen::SparseMatrix<double>(size_systems[i].first, size_systems[i].second));
131 size_t n_triplets = 0;
132 for (
auto triplets_thread : triplets) {
133 n_triplets += triplets_thread[i].size();
135 std::vector<Eigen::Triplet<double>> all_triplets(n_triplets);
136 auto triplet_index = all_triplets.begin();
137 for (
auto triplets_thread : triplets) {
138 triplet_index = std::copy(triplets_thread[i].begin(), triplets_thread[i].end(), triplet_index);
140 systems[i].setFromTriplets(all_triplets.begin(), all_triplets.end());
143 for (
size_t i = 0; i < size_vectors.size(); i++){
144 for (
auto vec_thread : vecs){
145 vectors[i] += vec_thread[i];
150 std::vector<std::list<Eigen::Triplet<double> > > triplets(size_systems.size());
151 batch_local_assembly(0, nb_elements, &triplets, &vectors);
152 for (
size_t i = 0; i < size_systems.size(); i++){
153 systems.emplace_back(Eigen::SparseMatrix<double>(size_systems[i].first, size_systems[i].second));
154 systems[i].setFromTriplets(triplets[i].begin(), triplets[i].end());
161 static inline std::pair<Eigen::SparseMatrix<double>, Eigen::VectorXd>
165 std::function<
void(
size_t start,
size_t end, std::list<Eigen::Triplet<double>> * triplets, Eigen::VectorXd * rhs)> batch_local_assembly,
169 std::function<void(
size_t start,
size_t end, std::vector<std::list<Eigen::Triplet<double>>> * triplets, std::vector<Eigen::VectorXd> * vecs)>
170 new_batch_local_assembly = [&](
size_t start,
size_t end, std::vector<std::list<Eigen::Triplet<double>>> * triplets, std::vector<Eigen::VectorXd> * vecs)->
void
171 {batch_local_assembly(start, end, &(*triplets)[0], &(*vecs)[0]);};
173 return std::make_pair(systems[0], vectors[0]);
178 static inline std::tuple<Eigen::SparseMatrix<double>, Eigen::VectorXd, Eigen::SparseMatrix<double>, Eigen::VectorXd>
182 std::pair<size_t, size_t> size_Mat2,
184 std::function<
void(
size_t start,
size_t end, std::list<Eigen::Triplet<double>> * triplets1, Eigen::VectorXd * vec1, std::list<Eigen::Triplet<double>> * triplets2, Eigen::VectorXd * vec2)> batch_local_assembly,
188 std::function<void(
size_t start,
size_t end, std::vector<std::list<Eigen::Triplet<double>>> * triplets, std::vector<Eigen::VectorXd> * vecs)>
189 new_batch_local_assembly = [&](
size_t start,
size_t end, std::vector<std::list<Eigen::Triplet<double>>> * triplets, std::vector<Eigen::VectorXd> * vecs)->
void
190 {batch_local_assembly(start, end, &(*triplets)[0], &(*vecs)[0], &(*triplets)[1], &(*vecs)[1]);};
191 auto [systems, vectors] =
parallel_assembly_system(nb_elements, {std::make_pair(size_system1, size_system1), size_Mat2}, {size_system1, size_b2}, new_batch_local_assembly,
use_threads);
192 return std::make_tuple(systems[0], vectors[0], systems[1], vectors[1]);
static SystemVectors< Eigen::SparseMatrix< double > > parallel_assembly_system(size_t nb_elements, std::vector< std::pair< size_t, size_t >> size_systems, std::vector< size_t > size_vectors, std::function< void(size_t start, size_t end, std::vector< std::list< Eigen::Triplet< double >>> *triplets, std::vector< Eigen::VectorXd > *vecs)> batch_local_assembly, bool use_threads=true)
Function to assemble global matrices from a procedure that compute local triplets.
Definition: parallel_for.hpp:90
static std::pair< std::vector< int >, std::vector< int > > distributeLoad(size_t nb_elements, unsigned nb_threads)
Function to distribute elements (considered as jobs) over threads. It returns a pair of vectors indic...
Definition: parallel_for.hpp:32
static void parallel_for(unsigned nb_elements, std::function< void(size_t start, size_t end)> functor, bool use_threads=true)
Generic function to execute threaded processes.
Definition: parallel_for.hpp:58
SystemVectors(std::vector< MatrixType > sys, std::vector< Eigen::VectorXd > vec)
Constructor.
Definition: parallel_for.hpp:20
std::vector< Eigen::VectorXd > vectors
Definition: parallel_for.hpp:27
std::vector< MatrixType > systems
Definition: parallel_for.hpp:24
bool use_threads
Definition: HHO_DiffAdvecReac.hpp:47
Definition: ddr-magnetostatics.hpp:40
Struct to store the systems and vector.
Definition: parallel_for.hpp:18