49
46
//-----------------------------------------------------------------------------
52
//-----------------------------------------------------------------------------
53
dolfin::MPICommunicator::MPICommunicator()
55
MPI_Comm_dup(MPI_COMM_WORLD, &communicator);
57
//-----------------------------------------------------------------------------
58
dolfin::MPICommunicator::~MPICommunicator()
60
MPI_Comm_free(&communicator);
62
//-----------------------------------------------------------------------------
63
MPI_Comm& dolfin::MPICommunicator::operator*()
67
//-----------------------------------------------------------------------------
68
//-----------------------------------------------------------------------------
69
void dolfin::MPINonblocking::wait_all()
73
boost::mpi::wait_all(reqs.begin(), reqs.end());
77
48
//-----------------------------------------------------------------------------
78
49
//-----------------------------------------------------------------------------
79
50
unsigned int dolfin::MPI::process_number()
52
deprecation("MPI::process_number",
54
"MPI::process_number() has been replaced by MPI::rank(MPI_Comm).");
81
57
SubSystemsManager::init_mpi();
83
59
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
86
65
//-----------------------------------------------------------------------------
87
66
unsigned int dolfin::MPI::num_processes()
68
deprecation("MPI::num_processes",
70
"MPI::num_processes() has been replaced by MPI::size(MPI_Comm).");
89
73
SubSystemsManager::init_mpi();
91
75
MPI_Comm_size(MPI_COMM_WORLD, &size);
94
//-----------------------------------------------------------------------------
95
bool dolfin::MPI::is_broadcaster()
81
//-----------------------------------------------------------------------------
82
unsigned int dolfin::MPI::rank(const MPI_Comm comm)
85
SubSystemsManager::init_mpi();
87
MPI_Comm_rank(comm, &rank);
93
//-----------------------------------------------------------------------------
94
unsigned int dolfin::MPI::size(const MPI_Comm comm)
97
SubSystemsManager::init_mpi();
99
MPI_Comm_size(comm, &size);
105
//-----------------------------------------------------------------------------
106
bool dolfin::MPI::is_broadcaster(const MPI_Comm comm)
97
108
// Always broadcast from processor number 0
98
return num_processes() > 1 && process_number() == 0;
109
return size(comm) > 1 && rank(comm) == 0;
100
111
//-----------------------------------------------------------------------------
101
bool dolfin::MPI::is_receiver()
112
bool dolfin::MPI::is_receiver(const MPI_Comm comm)
103
114
// Always receive on processors with numbers > 0
104
return num_processes() > 1 && process_number() > 0;
106
//-----------------------------------------------------------------------------
107
void dolfin::MPI::barrier()
109
MPICommunicator comm;
112
//-----------------------------------------------------------------------------
113
std::size_t dolfin::MPI::global_offset(std::size_t range, bool exclusive)
115
MPICommunicator mpi_comm;
116
boost::mpi::communicator comm(*mpi_comm, boost::mpi::comm_duplicate);
115
return size(comm) > 1 && rank(comm) > 0;
117
//-----------------------------------------------------------------------------
118
void dolfin::MPI::barrier(const MPI_Comm comm)
124
//-----------------------------------------------------------------------------
125
std::size_t dolfin::MPI::global_offset(const MPI_Comm comm,
126
std::size_t range, bool exclusive)
118
129
// Compute inclusive or exclusive partial reduction
119
std::size_t offset = boost::mpi::scan(comm, range, std::plus<std::size_t>());
130
std::size_t offset = 0;
131
MPI_Scan(&range, &offset, 1, mpi_type<std::size_t>(), MPI_SUM, comm);
125
//-----------------------------------------------------------------------------
126
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(std::size_t N)
128
return local_range(process_number(), N);
130
//-----------------------------------------------------------------------------
131
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(unsigned int process,
134
return local_range(process, N, num_processes());
136
//-----------------------------------------------------------------------------
137
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(unsigned int process,
139
unsigned int num_processes)
139
//-----------------------------------------------------------------------------
140
std::pair<std::size_t, std::size_t>
141
dolfin::MPI::local_range(const MPI_Comm comm, std::size_t N)
143
return local_range(comm, rank(comm), N);
145
//-----------------------------------------------------------------------------
146
std::pair<std::size_t, std::size_t>
147
dolfin::MPI::local_range(const MPI_Comm comm, unsigned int process,
150
return compute_local_range(process, N, size(comm));
152
//-----------------------------------------------------------------------------
153
std::pair<std::size_t, std::size_t>
154
dolfin::MPI::compute_local_range(unsigned int process,
141
158
// Compute number of items per process and remainder
142
const std::size_t n = N / num_processes;
143
const std::size_t r = N % num_processes;
159
const std::size_t n = N / size;
160
const std::size_t r = N % size;
145
162
// Compute local range
146
163
std::pair<std::size_t, std::size_t> range;
177
195
return r + (index - r * (n + 1)) / n;
179
197
//-----------------------------------------------------------------------------
180
//-----------------------------------------------------------------------------
182
//-----------------------------------------------------------------------------
183
//-----------------------------------------------------------------------------
184
void dolfin::MPINonblocking::wait_all()
186
dolfin_error("MPI.h",
187
"call MPINonblocking::wait_all",
188
"DOLFIN has been configured without MPI support");
190
//-----------------------------------------------------------------------------
191
//-----------------------------------------------------------------------------
192
unsigned int dolfin::MPI::process_number()
196
//-----------------------------------------------------------------------------
197
unsigned int dolfin::MPI::num_processes()
201
//-----------------------------------------------------------------------------
202
bool dolfin::MPI::is_broadcaster()
206
//-----------------------------------------------------------------------------
207
bool dolfin::MPI::is_receiver()
211
//-----------------------------------------------------------------------------
212
void dolfin::MPI::barrier()
214
dolfin_error("MPI.cpp",
216
"Your DOLFIN installation has been built without MPI support");
218
//-----------------------------------------------------------------------------
219
std::size_t dolfin::MPI::global_offset(std::size_t range, bool exclusive)
223
//-----------------------------------------------------------------------------
224
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(std::size_t N)
226
return std::make_pair(0, N);
228
//-----------------------------------------------------------------------------
229
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(unsigned int process,
232
if (process != 0 || num_processes() > 1)
234
dolfin_error("MPI.cpp",
235
"access local range for process",
236
"DOLFIN has not been configured with MPI support");
238
return std::make_pair(0, N);
240
//-----------------------------------------------------------------------------
241
std::pair<std::size_t, std::size_t>
242
dolfin::MPI::local_range(unsigned int process, std::size_t N,
243
unsigned int num_processes)
245
if (process != 0 || num_processes > 1)
247
dolfin_error("MPI.cpp",
248
"access local range for process",
249
"DOLFIN has not been configured with MPI support");
251
return std::make_pair(0, N);
253
//-----------------------------------------------------------------------------
254
unsigned int dolfin::MPI::index_owner(std::size_t i, std::size_t N)
256
dolfin_assert(i < N);
259
//-----------------------------------------------------------------------------