5#ifndef DUNE_GRID_YASPGRID_TORUS_HH
6#define DUNE_GRID_YASPGRID_TORUS_HH
19#include <dune/common/binaryfunctions.hh>
20#include <dune/common/streamoperators.hh>
45 template<
class Communication,
int d>
79 for (
int i=0; i<d; i++)
86 if (inc != _comm.size())
87 DUNE_THROW(Dune::Exception,
"Communicator size and result of the given load balancer do not match!");
138 for (
int i=d-1; i>=0; i--)
139 if (c[i]<0 || c[i]>=_dims[i])
return false;
148 for (
int i=d-1; i>=0; i--)
159 for (
int i=0; i<d; i++)
coord[i] =
coord[i]%_dims[i];
161 for (
int i=0; i<d; i++)
rank +=
coord[i]*_increment[i];
169 coord[dir] = (
coord[dir]+_dims[dir]+cnt)%_dims[dir];
180 for (
int i=0; i<d; i++)
182 if (
coord[i]%2==1) c += power;
187 for (
int i=0; i<d; i++)
189 if (_dims[i]>1 &&
coord[i]==_dims[i]-1) c += power;
206 for (
int i=0; i<d; ++i)
216 for (
int i=0; i<d; i++)
221 if (
coord[i]==0 && periodic[i]==
false)
return false;
226 if (
coord[i]==_dims[i]-1 && periodic[i]==
false)
return false;
246 for (
int i=0; i<d; i++)
249 int m = size_in[i]/_dims[i];
250 int r = size_in[i]%_dims[i];
254 if (
coord[i]<_dims[i]-r)
256 origin_out[i] = origin_in[i] +
coord[i]*m;
262 origin_out[i] = origin_in[i] + (_dims[i]-r)*m + (
coord[i]-(_dims[i]-r))*(m+1);
267 return maxsize/(sz/_comm.size());
307 for (
int j=0; j<d; ++j)
333 typename std::deque<CommPartner>::const_iterator i;
365 task.buffer = buffer;
367 if (
rank!=_comm.rank())
368 _sendrequests.push_back(task);
370 _localsendrequests.push_back(task);
378 task.buffer = buffer;
380 if (
rank!=_comm.rank())
381 _recvrequests.push_back(task);
383 _localrecvrequests.push_back(task);
390 if (_localsendrequests.size()!=_localrecvrequests.size())
392 std::cout <<
"[" <<
rank() <<
"]: ERROR: local sends/receives do not match in exchange!" << std::endl;
395 for (
unsigned int i=0; i<_localsendrequests.size(); i++)
397 if (_localsendrequests[i].size!=_localrecvrequests[i].size)
399 std::cout <<
"[" <<
rank() <<
"]: ERROR: size in local sends/receive does not match in exchange!" << std::endl;
402 memcpy(_localrecvrequests[i].buffer,_localsendrequests[i].buffer,_localsendrequests[i].size);
404 _localsendrequests.clear();
405 _localrecvrequests.clear();
410 std::vector<MPI_Request> requests(_sendrequests.size() + _recvrequests.size());
411 MPI_Request* req = requests.data();
414 for (
unsigned int i=0; i<_sendrequests.size(); i++)
419 MPI_Isend(_sendrequests[i].buffer, _sendrequests[i].size, MPI_BYTE,
420 _sendrequests[i].
rank, _tag, _comm, req++);
424 for (
unsigned int i=0; i<_recvrequests.size(); i++)
429 MPI_Irecv(_recvrequests[i].buffer, _recvrequests[i].size, MPI_BYTE,
430 _recvrequests[i].
rank, _tag, _comm, req++);
434 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
437 _sendrequests.clear();
438 _recvrequests.clear();
446 _comm.template allreduce<Dune::Max<double>,
double>(&x, &res, 1);
453 s <<
"[" <<
rank() <<
"]: Torus " <<
procs() <<
" processor(s) arranged as " <<
dims() << std::endl;
456 s <<
"[" <<
rank() <<
"]: send to "
457 <<
"rank=" << i.rank()
458 <<
" index=" << i.index()
459 <<
" delta=" << i.delta() <<
" dist=" << i.distance() << std::endl;
463 s <<
"[" <<
rank() <<
"]: recv from "
464 <<
"rank=" << i.rank()
465 <<
" index=" << i.index()
466 <<
" delta=" << i.delta() <<
" dist=" << i.distance() << std::endl;
478 std::fill(delta.begin(), delta.end(), -1);
487 for (
int i=0; i<d; i++)
488 nb[i] = ( me[i]+_dims[i]+delta[i] ) % _dims[i];
494 for (
int i=0; i<d; i++)
500 _recvlist.push_back(cp);
501 cp.index = last-index;
502 _sendlist.push_front(cp);
509 for (
int i=0; i<d; i++)
529 std::deque<CommPartner> _sendlist;
530 std::deque<CommPartner> _recvlist;
532 mutable std::vector<CommTask> _sendrequests;
533 mutable std::vector<CommTask> _recvrequests;
534 mutable std::vector<CommTask> _localsendrequests;
535 mutable std::vector<CommTask> _localrecvrequests;
540 template <
class Communication,
int d>
This file provides tools to partition YaspGrids. If you want to write your own partitioner,...
std::ostream & operator<<(std::ostream &out, const PartitionType &type)
write a PartitionType to a stream
Definition: gridenums.hh:72
Include standard header files.
Definition: agrid.hh:60
void abs(const DofVectorPointer< int > &dofVector)
Definition: dofvector.hh:328
constexpr Overlap overlap
PartitionSet for the overlap partition.
Definition: partitionset.hh:278
a base class for the yaspgrid partitioning strategy
Definition: partitioning.hh:39
virtual void partition(const iTupel &, int, iTupel &, int) const =0
Torus()
constructor making uninitialized object
Definition: torus.hh:67
int color(int rank) const
assign color to given rank
Definition: torus.hh:197
double partition(int rank, iTupel origin_in, iTupel size_in, iTupel &origin_out, iTupel &size_out) const
partition the given grid onto the torus and return the piece of the process with given rank; returns ...
Definition: torus.hh:239
int dims(int i) const
return dimensions of torus in direction i
Definition: torus.hh:118
iTupel coord() const
return own coordinates
Definition: torus.hh:100
int rank() const
return own rank
Definition: torus.hh:94
const iTupel & dims() const
return dimensions of torus
Definition: torus.hh:112
int rank_relative(int rank, int dir, int cnt) const
return rank of process where its coordinate in direction dir has offset cnt (handles periodic case)
Definition: torus.hh:166
void recv(int rank, void *buffer, int size) const
store a receive request; buffers are received in order; handles also local requests with memcpy
Definition: torus.hh:374
void send(int rank, void *buffer, int size) const
store a send request; buffers are sent in order; handles also local requests with memcpy
Definition: torus.hh:361
Torus(Communication comm, int tag, iTupel size, int overlap, const Yasp::Partitioning< d > *partitioner)
make partitioner from communicator and coarse mesh size
Definition: torus.hh:71
int neighbors() const
return the number of neighbors, which is
Definition: torus.hh:203
void print(std::ostream &s) const
print contents of torus object
Definition: torus.hh:451
double global_max(double x) const
global max
Definition: torus.hh:443
Communication comm() const
return communicator
Definition: torus.hh:124
int color(const iTupel &coord) const
assign color to given coordinate
Definition: torus.hh:174
ProcListIterator recvend() const
last process in receive list
Definition: torus.hh:355
bool is_neighbor(iTupel delta, std::bitset< d > periodic) const
return true if neighbor with given delta is a neighbor under the given periodicity
Definition: torus.hh:212
ProcListIterator sendend() const
end of send list
Definition: torus.hh:343
int procs() const
return number of processes
Definition: torus.hh:106
iTupel rank_to_coord(int rank) const
map rank to coordinate in torus using lexicographic ordering
Definition: torus.hh:144
std::array< int, d > iTupel
type used to pass tupels in and out
Definition: torus.hh:49
ProcListIterator sendbegin() const
first process in send list
Definition: torus.hh:337
void exchange() const
exchange messages stored in request buffers; clear request buffers afterwards
Definition: torus.hh:387
ProcListIterator recvbegin() const
first process in receive list
Definition: torus.hh:349
int coord_to_rank(iTupel coord) const
map coordinate in torus to rank using lexicographic ordering
Definition: torus.hh:157
bool inside(iTupel c) const
return true if coordinate is inside torus
Definition: torus.hh:136
int tag() const
return tag used by torus
Definition: torus.hh:130
iTupel delta() const
return distance vector
Definition: torus.hh:291
bool operator==(const ProcListIterator &iter) const
Return true when two iterators point to same member.
Definition: torus.hh:313
bool operator!=(const ProcListIterator &iter) const
Return true when two iterators do not point to same member.
Definition: torus.hh:320
int rank() const
return rank of neighboring process
Definition: torus.hh:285
ProcListIterator(typename std::deque< CommPartner >::const_iterator iter)
make an iterator
Definition: torus.hh:279
ProcListIterator & operator++()
Increment iterator to next cell.
Definition: torus.hh:326
int index() const
return index in proclist
Definition: torus.hh:297
int distance() const
return 1-norm of distance vector
Definition: torus.hh:303