44 const COM::Window::Proc_map &proc_map =
_appl_window->proc_map();
50 std::map<int,int>::const_iterator it=proc_map.begin();
57 const COM::Attribute* my_pconn){
60 ( my_pconn ==NULL || my_pconn->window() ==
_appl_window));
68 "Pane_communicator must be initialized with a nodal or elemental attribute");
71 int att_id = att->id();
72 int local_npanes =
_panes.size();
74 void** pointers =
new void*[local_npanes];
75 int *sizes =
new int[local_npanes];
76 int *strides =
new int[local_npanes];
78 for (
int i=0;
i < local_npanes; ++
i) {
79 COM::Attribute *attribute =
_panes[
i]->attribute(att_id);
80 pointers[
i] = attribute->pointer();
81 sizes[
i] = attribute->size_of_real_items();
82 strides[
i] = attribute->stride();
84 init(pointers, att->data_type(), att->size_of_components(), sizes, strides);
85 delete[] pointers; pointers = NULL;
86 delete[] sizes; sizes=NULL;
87 delete[] strides; strides = NULL;
92 int ncomp,
const int *sizes,
const int *strds) {
99 int local_npanes =
_panes.size();
109 _sizes.insert(
_sizes.end(), sizes, sizes+local_npanes);
112 _sizes.resize( local_npanes);
113 for (
int i=0;
i<local_npanes; ++
i)
118 if ( strds)
_strds.insert(
_strds.end(), strds, strds+local_npanes);
122 for (
int i=0;
i<local_npanes; ++
i) {
127 const int *vs = (
const int*)pconn->pointer();
128 int vs_size=pconn->size_of_real_items();
139 const int vs_gsize=pconn->size_of_items();
169 const int* ptr,
int& index,
const int n_items,
171 if ( n_items == 0)
return;
174 int count=0, np= ptr[index];
177 for (
int j=0;
j<np; block_size+=ptr[index+block_size+1]+2, ++
j) {
178 if (
owner_rank( ptr[index+block_size]) >=0) ++count;
187 for (
int p=0,
j=0; p<np; ++p, index+=ptr[index+1]+2) {
196 pcb.
tag = 100 + ((lpid>lqid) ?
206 std::vector<std::vector<bool> > *involved) {
208 "Cannot begin a new update until all prior updates are finished.");
214 int local_npanes =
_panes.size();
216 if ( involved) { involved->clear(); involved->resize( local_npanes); }
219 for (
int i=0;
i<local_npanes; ++
i) {
220 if ( involved) (*involved)[
i].resize(
_sizes[
i],
false);
224 const int *vs = (
const int*)pconn->pointer();
228 char *ptr = ((
char*)
_ptrs[i])-strd_bytes;
231 std::vector< Pane_comm_buffers> *buffs =NULL;
239 else if (btype ==
GNR) {
242 else if (btype ==
GCR)
250 for (
int j=0,
nj=buffs->size();
j<
nj; ++
j) {
259 pcb->
outbuf.resize( bufsize);
264 (*involved)[
i][vs[ from]-1] =
true;
275 if ( rank == pcb->
rank) {
279 if (
_panes[i]->
id() > vs[pcb->
index]) tag += tag_max;
298 pcb->
inbuf.resize( bufsize);
300 if ( rank == pcb->
rank) {
306 if (
_panes[i]->
id() < vs[pcb->
index]) tag += tag_max;
329 pcb->
inbuf.resize( bufsize);
337 for (
int k=0,from=pcb->
index+2,
n=vs[pcb->
index+1];
k<
n;
k+=2, from+=2){
352 if (
_comm!=MPI_COMM_NULL) {
354 std::vector< MPI_Status> status(
_reqs_send.size());
365 void reduce_int( MPI_Op op, T *a, T *b,
int size)
throw(
int) {
367 {
for (
int i=0;
i<size; ++
i) b[
i] += a[
i]; }
369 {
for (
int i=0;
i<size; ++
i) b[
i] *= a[
i]; }
375 {
for (
int i=0;
i<size; ++
i) b[
i] |= a[
i]; }
376 else if ( op == MPI_BAND)
377 {
for (
int i=0;
i<size; ++
i) b[
i] &= a[
i]; }
379 {
for (
int i=0;
i<size; ++
i) b[
i] = a[
i] || b[
i]; }
381 {
for (
int i=0;
i<size; ++
i) b[
i] = a[
i] && b[
i]; }
389 {
for (
int i=0;
i<size; ++
i) b[
i] += a[
i]; }
391 {
for (
int i=0;
i<size; ++
i) b[
i] *= a[
i]; }
406 if (
_comm!=MPI_COMM_NULL) {
420 char *ptr = ((
char*)
_ptrs[i])-strd_bytes;
423 const int *vs = (
const int*)pconn->pointer();
433 ((
char*)&ptr[strd_bytes*vs[ to]]),
_ncomp);
437 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
439 (
int*)&ptr[strd_bytes*vs[ to]],
_ncomp);
443 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
445 (
float*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
449 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
451 (
double*)&ptr[strd_bytes*vs[ to]],
_ncomp);
465 for (
int i=0;
i<size; ++
i) {
472 for (
int i=0;
i<size; ++
i) {
481 for (
int i=0; ; ++
i) {
482 if ( a[
i]!=0) { isa_nonzero = 1;
break; }
483 else if (
i==size)
return;
487 for (
int i=0;
i<size; ++
i)
488 if ( b[
i]!=0) { isb_nonzero = 1;
break; }
491 for (
int j=0;
j<size; ++
j) b[
j] -= a[
j];
493 for (
int j=0;
j<size; ++
j) b[
j] = a[
j];
502 if (
_comm!=MPI_COMM_NULL) {
516 char *ptr = ((
char*)
_ptrs[i])-strd_bytes;
519 const int *vs = (
const int*)pconn->pointer();
529 (
char*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
533 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
535 (
int*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
539 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
541 (
float*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
545 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
547 (
double*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
565 if (
_comm!=MPI_COMM_NULL) {
579 char *ptr = ((
char*)
_ptrs[i])-strd_bytes;
582 const int *vs = (
const int*)pconn->pointer();
592 (
char*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
596 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
598 (
int*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
602 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
604 (
float*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
608 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
610 (
double*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
628 if (
_comm!=MPI_COMM_NULL) {
642 char *ptr = ((
char*)
_ptrs[i])-strd_bytes;
645 const int *vs = (
const int*)pconn->pointer();
655 (
char*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
659 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
661 (
int*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
665 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
667 (
float*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
671 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
673 (
double*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
687 for (
int i=0;
i<size; ++
i) {
698 if (
_comm!=MPI_COMM_NULL) {
714 char *ptr = ((
char*)
_ptrs[i])-strd_bytes;
717 const int *vs = (
const int*)pconn->pointer();
727 (
char*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
731 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
733 (
int*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
737 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
739 (
float*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
743 for (
int k=0,
nk=vs[pcb.
index+1], to=pcb.
index+2; k<
nk; ++k, ++to)
745 (
double*)&ptr[ strd_bytes*vs[ to]],
_ncomp);
763 std::map<int,int> nodes_to_mult;
764 std::map<int,int>::iterator nodes_to_mult_pos;
765 int num_panes = (int)
_panes.size();
768 for(
int i = 0;
i < num_panes; ++
i){
770 const int *vs = (
const int*)pconn->pointer();
773 int vs_size=pconn->size_of_real_items();
776 char *ptr = ((
char*)
_ptrs[i])-strd_bytes;
780 nodes_to_mult.clear();
781 for(
int j=1;
j<vs_size;
j+= vs[
j+1]+2){
785 for(
int k=0;
k< vs[j+1]; ++
k){
786 nodes_to_mult_pos = nodes_to_mult.find(vs[j+
k+2]);
787 if (nodes_to_mult_pos != nodes_to_mult.end())
788 nodes_to_mult_pos->second++;
790 nodes_to_mult.insert(std::make_pair(vs[j+
k+2],2));
801 for(nodes_to_mult_pos=nodes_to_mult.begin();
802 nodes_to_mult_pos!=nodes_to_mult.end();
803 ++nodes_to_mult_pos){
804 shared_id = nodes_to_mult_pos->first;
806 mult = nodes_to_mult_pos->second;
808 ((
char*)&ptr[ strd_bytes*shared_id])[
k] /= mult;
814 for(nodes_to_mult_pos=nodes_to_mult.begin();
815 nodes_to_mult_pos!=nodes_to_mult.end();
816 ++nodes_to_mult_pos){
817 shared_id = nodes_to_mult_pos->first;
819 mult = nodes_to_mult_pos->second;
821 ((
int*)&ptr[ strd_bytes*shared_id])[
k] /= mult;
827 for(nodes_to_mult_pos=nodes_to_mult.begin();
828 nodes_to_mult_pos!=nodes_to_mult.end();
829 ++nodes_to_mult_pos){
830 shared_id = nodes_to_mult_pos->first;
831 mult = nodes_to_mult_pos->second;
833 ((
float*)&ptr[ strd_bytes*shared_id])[
k] /= (float)mult;
839 for(nodes_to_mult_pos=nodes_to_mult.begin();
840 nodes_to_mult_pos!=nodes_to_mult.end();
841 ++nodes_to_mult_pos){
842 shared_id = nodes_to_mult_pos->first;
843 mult = nodes_to_mult_pos->second;
845 ((
double*)&ptr[ strd_bytes*shared_id])[
k] /= (double)mult;
int COMMPI_Comm_rank(MPI_Comm c)
int COMMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request *request)
Begins a nonblocking receive.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_BYTE
void update_ghost_values()
std::vector< void * > _ptrs
An array of pointers to the data for all local panes.
#define MAP_END_NAMESPACE
void update_value(T *a, T *b, int size)
int COM_Type
Indices for derived data types.
std::vector< int > _sizes
The sizes of the arrays for all local panes.
#define COM_assertion(EX)
Error checking utility similar to the assert macro of the C language.
Utility for constructing pane connectivities in parallel.
std::map< int, int > _lpaneid_map
Mapping from user-defined pane ids to internal IDs, which are unique and contiguous across all proces...
std::vector< std::vector< Pane_comm_buffers > > _gnr_buffs
Buffer for ghost nodes to receive.
void reduce_on_shared_nodes(MPI_Op)
Perform a reduction operation using locally cached values of the shared nodes, assuming begin_update_...
Buffers for outgoing and incoming messages of a specific pane to be communicated with another pane (e...
void reduce_average_on_shared_nodes()
Reduce to the average of values using locally cached values of the shared nodes, assuming begin_updat...
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_COMM_SELF
Pane_communicator(COM::Window *w, MPI_Comm c=MPI_COMM_WORLD)
Constructor from a communicator.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_MAX
void reduce_diff_on_shared_nodes()
Compute difference of non-zero values of each shared node, assuming there are at most two non-zero va...
#define COM_assertion_msg(EX, msg)
void reduce_real(MPI_Op op, T *a, T *b, int size)
Local level implementation of reduce operations.
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
std::vector< int > _strds
The strides of the arrays for all local panes.
This file contains the prototypes for Roccom API.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_MIN
int owner_rank(const int pane_id) const
Obtain the process rank of a given pane.
Handles communication of shared nodes, ghost nodes or ghost cells across panes.
void reduce_diff(T *a, T *b, int size)
int COMMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
Begins a nonblocking send.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_BAND INTEGER MPI_BOR
void end_update()
Finalizes updating by calling MPI_Waitall on all send requests.
std::vector< std::vector< Pane_comm_buffers > > _rns_buffs
Buffer for real nodes to send.
void init_pane_comm_buffers(std::vector< Pane_comm_buffers > &pcb, const int *ptr, int &index, const int n_items, const int lpid)
Initialize a Pane_comm_buffers for ghost information.
std::vector< std::vector< Pane_comm_buffers > > _rcs_buffs
Buffer for real cells to send.
void reduce_minabs(T *a, T *b, int size)
std::vector< std::vector< Pane_comm_buffers > > _shr_buffs
Shared node pane communication buffers.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_LAND
std::vector< MPI_Request > _reqs_recv
std::vector< std::pair< int, int > > _reqs_indices
The indices in buffs for each pending nonblocking receive request.
std::vector< char > inbuf
void reduce_int(MPI_Op op, T *a, T *b, int size)
Local level implementation of reduce operations.
std::vector< std::vector< Pane_comm_buffers > > _gcr_buffs
Buffer for ghost cells to receive.
int COM_get_sizeof(const COM_Type type, int c)
std::vector< char > outbuf
std::vector< MPI_Request > _reqs_send
Arrays of pending nonblocking MPI requests. Same format as _shr_buffs.
int lpaneid(const int pane_id) const
For a given pane, obtain an internal pane ID which is unique and contiguous across processes...
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_BAND INTEGER MPI_LOR
int _type
The base data type, number of components, and the number of bytes of all components for the data to b...
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
void reduce_maxabs_on_shared_nodes()
Reduce to the value with the maximum absolute value using locally cached values of shared nodes...
void init(void **ptrs, COM_Type type, int ncomp, const int *sizes=NULL, const int *strds=NULL)
Initialize the communication buffers.
int _my_pconn_id
The id of the pconn being used.
#define MAP_BEGIN_NAMESPACE
const MPI_Comm _comm
MPI Communicator.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_PROD
void reduce_maxabs(T *a, T *b, int size)
void begin_update(const Buff_type btype, std::vector< std::vector< bool > > *involved=NULL)
Initiates updating by calling MPI_Isend and MPI_Irecv.
void reduce_minabs_on_shared_nodes()
Reduce to the value with the maximum absolute value using locally cached values of shared nodes...
int _total_npanes
The total number of panes on all processes.
std::vector< COM::Pane * > _panes
Vector of all local panes.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_SUM
COM::Window * _appl_window
Reference to the application window.