Yet Another eXchange Tool  DO_NOT_EDIT_HERE
xt_redist_collection_static.c
Go to the documentation of this file.
1 
12 /*
13  * Keywords:
14  * Maintainer: Jörg Behrens <behrens@dkrz.de>
15  * Moritz Hanke <hanke@dkrz.de>
16  * Thomas Jahns <jahns@dkrz.de>
17  * URL: https://doc.redmine.dkrz.de/yaxt/html/
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions are
21  * met:
22  *
23  * Redistributions of source code must retain the above copyright notice,
24  * this list of conditions and the following disclaimer.
25  *
26  * Redistributions in binary form must reproduce the above copyright
27  * notice, this list of conditions and the following disclaimer in the
28  * documentation and/or other materials provided with the distribution.
29  *
30  * Neither the name of the DKRZ GmbH nor the names of its contributors
31  * may be used to endorse or promote products derived from this software
32  * without specific prior written permission.
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
35  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
36  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
37  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
38  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
41  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  */
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49 
50 #include <assert.h>
51 #include <limits.h>
52 #include <stdbool.h>
53 #include <stdlib.h>
54 
55 #include <mpi.h>
56 
57 #include "core/core.h"
58 #include "core/ppm_xfuncs.h"
59 #include "xt/xt_mpi.h"
60 #include "xt_mpi_internal.h"
63 #include "ensure_array_size.h"
64 #include "xt/xt_redist.h"
65 #include "xt_redist_internal.h"
66 #include "xt/xt_sort.h"
67 
68 
69 static size_t
71  const MPI_Aint *displacements, Xt_redist *redists,
72  size_t num_redists, MPI_Comm comm,
73  enum xt_msg_direction direction,
74  MPI_Datatype (*get_MPI_datatype)(Xt_redist,int)) {
75 
76  int block_lengths[num_redists];
77  MPI_Datatype datatypes[num_redists];
78 
79  for (size_t i = 0; i < num_redists; ++i)
80  block_lengths[i] = 1;
81 
82  size_t num_ranks[num_redists], rank_pos[num_redists];
83  int *restrict ranks[num_redists];
84  bool ranks_left = false;
85  /* get lists of ranks to send/receive message to/from */
86  for (size_t j = 0; j < num_redists; ++j) {
87  num_ranks[j]
88  = (size_t)xt_redist_get_msg_ranks(redists[j], direction,
89  (int **)(ranks + j));
90  /* sort list */
91  xt_sort_int(ranks[j], num_ranks[j]);
92  ranks_left |= (num_ranks[j] > 0);
93  rank_pos[j] = 0;
94  }
95 
96  size_t num_messages = ranks_left
97  ? xt_ranks_uniq_count(num_redists, num_ranks, (const int **)ranks) : 0;
98  struct Xt_redist_msg *p = NULL;
99  if (num_messages) {
100  p = xmalloc(sizeof (*p) * num_messages);
101  for (size_t i = 0; i < num_messages; ++i) {
102  int min_rank = INT_MAX;
103  for (size_t j = 0; j < num_redists; ++j)
104  if (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] < min_rank)
105  min_rank = ranks[j][rank_pos[j]];
106 
107  for (size_t j = 0; j < num_redists; ++j)
108  datatypes[j] =
109  (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank)
110  ? get_MPI_datatype(redists[j], min_rank) : MPI_DATATYPE_NULL;
111 
112  p[i].rank = min_rank;
113  p[i].datatype
114  = xt_create_compound_datatype(num_redists, displacements, datatypes,
115  block_lengths, comm);
116  for (size_t j = 0; j < num_redists; ++j) {
117  if (datatypes[j] != MPI_DATATYPE_NULL)
118  xt_mpi_call(MPI_Type_free(datatypes+j), comm);
119  rank_pos[j]
120  += (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank);
121  }
122  }
123  }
124  for (size_t j = 0; j < num_redists; ++j)
125  free(ranks[j]);
126  *msgs = p;
127  return num_messages;
128 }
129 
130 Xt_redist
131 xt_redist_collection_static_new(Xt_redist * redists, int num_redists,
132  const MPI_Aint src_displacements[num_redists],
133  const MPI_Aint dst_displacements[num_redists],
134  MPI_Comm comm) {
135 
136  struct Xt_redist_msg *send_msgs, *recv_msgs;
137 
138  int tag_offset;
139  MPI_Comm new_comm = xt_mpi_comm_smart_dup(comm, &tag_offset);
140 
141  xt_redist_check_comms(redists, num_redists, comm);
142 
143  size_t num_redists_ = num_redists >= 0 ? (size_t)num_redists : 0;
144  size_t nsend
145  = generate_msg_infos(&send_msgs, src_displacements, redists, num_redists_,
147 
148  size_t nrecv
149  = generate_msg_infos(&recv_msgs, dst_displacements, redists, num_redists_,
151 
152  Xt_redist redist_collection =
153  xt_redist_single_array_base_new((int)nsend, (int)nrecv,
154  send_msgs, recv_msgs, new_comm);
155  xt_mpi_comm_smart_dedup(&new_comm, tag_offset);
156  return redist_collection;
157 }
158 
159 /*
160  * Local Variables:
161  * c-basic-offset: 2
162  * coding: utf-8
163  * indent-tabs-mode: nil
164  * show-trailing-whitespace: t
165  * require-trailing-newline: t
166  * End:
167  */
xt_msg_direction
void xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm)
Definition: xt_redist.c:137
redistribution of data, non-public declarations
add versions of standard API functions not returning on error
MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank)
Definition: xt_redist.c:82
MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank)
Definition: xt_redist.c:87
static size_t generate_msg_infos(struct Xt_redist_msg **msgs, const MPI_Aint *displacements, Xt_redist *redists, size_t num_redists, MPI_Comm comm, enum xt_msg_direction direction, MPI_Datatype(*get_MPI_datatype)(Xt_redist, int))
MPI_Datatype xt_create_compound_datatype(size_t num_redists, const MPI_Aint displacements[num_redists], const MPI_Datatype datatypes[num_redists], const int block_lengths[num_redists], MPI_Comm comm)
Definition: xt_redist.c:181
Xt_redist xt_redist_single_array_base_new(int nsend, int nrecv, struct Xt_redist_msg *send_msgs, struct Xt_redist_msg *recv_msgs, MPI_Comm comm)
redistribution of data
MPI_Datatype datatype
Xt_redist xt_redist_collection_static_new(Xt_redist *redists, int num_redists, const MPI_Aint src_displacements[num_redists], const MPI_Aint dst_displacements[num_redists], MPI_Comm comm)
MPI_Comm xt_mpi_comm_smart_dup(MPI_Comm comm, int *tag_offset)
Definition: xt_mpi.c:850
void xt_mpi_comm_smart_dedup(MPI_Comm *comm, int tag_offset)
Definition: xt_mpi.c:901
int xt_redist_get_msg_ranks(Xt_redist redist, enum xt_msg_direction direction, int **ranks)
Definition: xt_redist.c:97
#define xt_mpi_call(call, comm)
Definition: xt_mpi.h:68
#define xmalloc(size)
Definition: ppm_xfuncs.h:66
void(* xt_sort_int)(int *a, size_t n)
Definition: xt_sort.c:53
size_t xt_ranks_uniq_count(size_t num_rank_sets, size_t *restrict num_ranks, const int *ranks[num_rank_sets])
Definition: xt_redist.c:152
int MPI_Comm
Definition: core.h:64
utility routines for MPI