~ubuntu-branches/ubuntu/wily/dolfin/wily

« back to all changes in this revision

Viewing changes to dolfin/common/MPI.cpp

  • Committer: Package Import Robot
  • Author(s): Johannes Ring
  • Date: 2014-09-22 14:35:34 UTC
  • mfrom: (1.1.17) (19.1.23 sid)
  • Revision ID: package-import@ubuntu.com-20140922143534-0yi89jyuqbgdxwm9
Tags: 1.4.0+dfsg-4
* debian/control: Disable libcgal-dev on i386, mipsel and sparc.
* debian/rules: Remove bad directives in pkg-config file dolfin.pc
  (closes: #760658).
* Remove debian/libdolfin-dev.lintian-overrides.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
// Modified by Ola Skavhaug 2008-2009
21
21
// Modified by Niclas Jansson 2009
22
22
// Modified by Joachim B Haga 2012
23
 
//
24
 
// First added:  2007-11-30
25
 
// Last changed: 2012-11-17
26
23
 
27
24
#include <numeric>
28
25
#include <dolfin/log/dolfin_log.h>
47
44
  return info;
48
45
}
49
46
//-----------------------------------------------------------------------------
50
 
 
51
 
 
52
 
//-----------------------------------------------------------------------------
53
 
dolfin::MPICommunicator::MPICommunicator()
54
 
{
55
 
  MPI_Comm_dup(MPI_COMM_WORLD, &communicator);
56
 
}
57
 
//-----------------------------------------------------------------------------
58
 
dolfin::MPICommunicator::~MPICommunicator()
59
 
{
60
 
  MPI_Comm_free(&communicator);
61
 
}
62
 
//-----------------------------------------------------------------------------
63
 
MPI_Comm& dolfin::MPICommunicator::operator*()
64
 
{
65
 
  return communicator;
66
 
}
67
 
//-----------------------------------------------------------------------------
68
 
//-----------------------------------------------------------------------------
69
 
void dolfin::MPINonblocking::wait_all()
70
 
{
71
 
  if (!reqs.empty())
72
 
  {
73
 
    boost::mpi::wait_all(reqs.begin(), reqs.end());
74
 
    reqs.clear();
75
 
  }
76
 
}
 
47
#endif
77
48
//-----------------------------------------------------------------------------
78
49
//-----------------------------------------------------------------------------
79
50
unsigned int dolfin::MPI::process_number()
80
51
{
 
52
  deprecation("MPI::process_number",
 
53
              "1.4", "1.5",
 
54
              "MPI::process_number() has been replaced by MPI::rank(MPI_Comm).");
 
55
 
 
56
#ifdef HAS_MPI
81
57
  SubSystemsManager::init_mpi();
82
58
  int rank;
83
59
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
84
60
  return rank;
 
61
#else
 
62
  return 0;
 
63
#endif
85
64
}
86
65
//-----------------------------------------------------------------------------
87
66
unsigned int dolfin::MPI::num_processes()
88
67
{
 
68
  deprecation("MPI::num_processes",
 
69
              "1.4", "1.5",
 
70
              "MPI::num_processes() has been replaced by MPI::size(MPI_Comm).");
 
71
 
 
72
#ifdef HAS_MPI
89
73
  SubSystemsManager::init_mpi();
90
74
  int size;
91
75
  MPI_Comm_size(MPI_COMM_WORLD, &size);
92
76
  return size;
93
 
}
94
 
//-----------------------------------------------------------------------------
95
 
bool dolfin::MPI::is_broadcaster()
 
77
#else
 
78
  return 1;
 
79
#endif
 
80
}
 
81
//-----------------------------------------------------------------------------
 
82
unsigned int dolfin::MPI::rank(const MPI_Comm comm)
 
83
{
 
84
#ifdef HAS_MPI
 
85
  SubSystemsManager::init_mpi();
 
86
  int rank;
 
87
  MPI_Comm_rank(comm, &rank);
 
88
  return rank;
 
89
#else
 
90
  return 0;
 
91
#endif
 
92
}
 
93
//-----------------------------------------------------------------------------
 
94
unsigned int dolfin::MPI::size(const MPI_Comm comm)
 
95
{
 
96
#ifdef HAS_MPI
 
97
  SubSystemsManager::init_mpi();
 
98
  int size;
 
99
  MPI_Comm_size(comm, &size);
 
100
  return size;
 
101
#else
 
102
  return 1;
 
103
#endif
 
104
}
 
105
//-----------------------------------------------------------------------------
 
106
bool dolfin::MPI::is_broadcaster(const MPI_Comm comm)
96
107
{
97
108
  // Always broadcast from processor number 0
98
 
  return num_processes() > 1 && process_number() == 0;
 
109
  return size(comm) > 1 && rank(comm) == 0;
99
110
}
100
111
//-----------------------------------------------------------------------------
101
 
bool dolfin::MPI::is_receiver()
 
112
bool dolfin::MPI::is_receiver(const MPI_Comm comm)
102
113
{
103
114
  // Always receive on processors with numbers > 0
104
 
  return num_processes() > 1 && process_number() > 0;
105
 
}
106
 
//-----------------------------------------------------------------------------
107
 
void dolfin::MPI::barrier()
108
 
{
109
 
  MPICommunicator comm;
110
 
  MPI_Barrier(*comm);
111
 
}
112
 
//-----------------------------------------------------------------------------
113
 
std::size_t dolfin::MPI::global_offset(std::size_t range, bool exclusive)
114
 
{
115
 
  MPICommunicator mpi_comm;
116
 
  boost::mpi::communicator comm(*mpi_comm, boost::mpi::comm_duplicate);
117
 
 
 
115
  return size(comm) > 1 && rank(comm) > 0;
 
116
}
 
117
//-----------------------------------------------------------------------------
 
118
void dolfin::MPI::barrier(const MPI_Comm comm)
 
119
{
 
120
#ifdef HAS_MPI
 
121
  MPI_Barrier(comm);
 
122
#endif
 
123
}
 
124
//-----------------------------------------------------------------------------
 
125
std::size_t dolfin::MPI::global_offset(const MPI_Comm comm,
 
126
                                       std::size_t range, bool exclusive)
 
127
{
 
128
#ifdef HAS_MPI
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);
120
132
  if (exclusive)
121
133
    offset -= range;
122
 
 
123
134
  return offset;
124
 
}
125
 
//-----------------------------------------------------------------------------
126
 
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(std::size_t N)
127
 
{
128
 
  return local_range(process_number(), N);
129
 
}
130
 
//-----------------------------------------------------------------------------
131
 
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(unsigned int process,
132
 
                                                             std::size_t N)
133
 
{
134
 
  return local_range(process, N, num_processes());
135
 
}
136
 
//-----------------------------------------------------------------------------
137
 
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(unsigned int process,
138
 
                                                             std::size_t N,
139
 
                                                             unsigned int num_processes)
 
135
#else
 
136
  return 0;
 
137
#endif
 
138
}
 
139
//-----------------------------------------------------------------------------
 
140
std::pair<std::size_t, std::size_t>
 
141
dolfin::MPI::local_range(const MPI_Comm comm, std::size_t N)
 
142
{
 
143
  return local_range(comm, rank(comm), N);
 
144
}
 
145
//-----------------------------------------------------------------------------
 
146
std::pair<std::size_t, std::size_t>
 
147
dolfin::MPI::local_range(const MPI_Comm comm, unsigned int process,
 
148
                         std::size_t N)
 
149
{
 
150
  return compute_local_range(process, N, size(comm));
 
151
}
 
152
//-----------------------------------------------------------------------------
 
153
std::pair<std::size_t, std::size_t>
 
154
dolfin::MPI::compute_local_range(unsigned int process,
 
155
                                 std::size_t N,
 
156
                                 unsigned int size)
140
157
{
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;
144
161
 
145
162
  // Compute local range
146
163
  std::pair<std::size_t, std::size_t> range;
158
175
  return range;
159
176
}
160
177
//-----------------------------------------------------------------------------
161
 
unsigned int dolfin::MPI::index_owner(std::size_t index, std::size_t N)
 
178
unsigned int dolfin::MPI::index_owner(const MPI_Comm comm,
 
179
                                      std::size_t index, std::size_t N)
162
180
{
163
181
  dolfin_assert(index < N);
164
182
 
165
183
  // Get number of processes
166
 
  const unsigned int _num_processes = num_processes();
 
184
  const unsigned int _size = size(comm);
167
185
 
168
186
  // Compute number of items per process and remainder
169
 
  const std::size_t n = N / _num_processes;
170
 
  const std::size_t r = N % _num_processes;
 
187
  const std::size_t n = N / _size;
 
188
  const std::size_t r = N % _size;
171
189
 
172
190
  // First r processes own n + 1 indices
173
191
  if (index < r * (n + 1))
177
195
  return r + (index - r * (n + 1)) / n;
178
196
}
179
197
//-----------------------------------------------------------------------------
180
 
//-----------------------------------------------------------------------------
181
 
#else
182
 
//-----------------------------------------------------------------------------
183
 
//-----------------------------------------------------------------------------
184
 
void dolfin::MPINonblocking::wait_all()
185
 
{
186
 
  dolfin_error("MPI.h",
187
 
               "call MPINonblocking::wait_all",
188
 
               "DOLFIN has been configured without MPI support");
189
 
}
190
 
//-----------------------------------------------------------------------------
191
 
//-----------------------------------------------------------------------------
192
 
unsigned int dolfin::MPI::process_number()
193
 
{
194
 
  return 0;
195
 
}
196
 
//-----------------------------------------------------------------------------
197
 
unsigned int dolfin::MPI::num_processes()
198
 
{
199
 
  return 1;
200
 
}
201
 
//-----------------------------------------------------------------------------
202
 
bool dolfin::MPI::is_broadcaster()
203
 
{
204
 
  return false;
205
 
}
206
 
//-----------------------------------------------------------------------------
207
 
bool dolfin::MPI::is_receiver()
208
 
{
209
 
  return false;
210
 
}
211
 
//-----------------------------------------------------------------------------
212
 
void dolfin::MPI::barrier()
213
 
{
214
 
  dolfin_error("MPI.cpp",
215
 
               "call MPI::barrier",
216
 
               "Your DOLFIN installation has been built without MPI support");
217
 
}
218
 
//-----------------------------------------------------------------------------
219
 
std::size_t dolfin::MPI::global_offset(std::size_t range, bool exclusive)
220
 
{
221
 
  return 0;
222
 
}
223
 
//-----------------------------------------------------------------------------
224
 
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(std::size_t N)
225
 
{
226
 
  return std::make_pair(0, N);
227
 
}
228
 
//-----------------------------------------------------------------------------
229
 
std::pair<std::size_t, std::size_t> dolfin::MPI::local_range(unsigned int process,
230
 
                                                             std::size_t N)
231
 
{
232
 
  if (process != 0 || num_processes() > 1)
233
 
  {
234
 
    dolfin_error("MPI.cpp",
235
 
                 "access local range for process",
236
 
                 "DOLFIN has not been configured with MPI support");
237
 
  }
238
 
  return std::make_pair(0, N);
239
 
}
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)
244
 
{
245
 
  if (process != 0 || num_processes > 1)
246
 
  {
247
 
    dolfin_error("MPI.cpp",
248
 
                 "access local range for process",
249
 
                 "DOLFIN has not been configured with MPI support");
250
 
  }
251
 
  return std::make_pair(0, N);
252
 
}
253
 
//-----------------------------------------------------------------------------
254
 
unsigned int dolfin::MPI::index_owner(std::size_t i, std::size_t N)
255
 
{
256
 
  dolfin_assert(i < N);
257
 
  return 0;
258
 
}
259
 
//-----------------------------------------------------------------------------
260
 
#endif