test_redist_common.c 9.13 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
 * @file test_redist_common.c
 *
 * @copyright Copyright  (C)  2016 Jörg Behrens <behrens@dkrz.de>
 *                                 Moritz Hanke <hanke@dkrz.de>
 *                                 Thomas Jahns <jahns@dkrz.de>
 *
 * @author Jörg Behrens <behrens@dkrz.de>
 *         Moritz Hanke <hanke@dkrz.de>
 *         Thomas Jahns <jahns@dkrz.de>
 */
/*
 * Keywords:
 * Maintainer: Jörg Behrens <behrens@dkrz.de>
 *             Moritz Hanke <hanke@dkrz.de>
 *             Thomas Jahns <jahns@dkrz.de>
 * URL: https://doc.redmine.dkrz.de/yaxt/html/
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are
 * met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the name of the DKRZ GmbH nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
Thomas Jahns's avatar
Thomas Jahns committed
46
47
48
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
49

50
51
#include <string.h>

52
53
54
#include "yaxt.h"
#include "tests.h"
#include "test_redist_common.h"
55
#include "core/core.h"
56
57
58
59
#include "core/ppm_xfuncs.h"

/*
 * build xmap for destination list containing all odd elements of
60
 * source list dimensioned 1 to src_num_indices
61
62
63
64
65
66
67
68
69
70
71
 */
Xt_xmap
build_odd_selection_xmap(int src_num_indices)
{
  enum {
    selection_stride = 2,
  };
  if (src_num_indices < 0)
    PUT_ERR("error: src_num_indices < 0");
  Xt_int *index_list = xmalloc((size_t)src_num_indices
                               * sizeof (index_list[0]));
72
  for (int i = 0; i < src_num_indices; ++i)
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    index_list[i] = (Xt_int)(i + 1);
  Xt_idxlist src_idxlist = xt_idxvec_new(index_list, src_num_indices);
  int dst_num_indices
    = (int)((src_num_indices + selection_stride - 1) / selection_stride);
  for (int i = 0; i < dst_num_indices; ++i)
    index_list[i] = (Xt_int)(i * selection_stride + 1);
  Xt_idxlist dst_idxlist = xt_idxvec_new(index_list, dst_num_indices);
  free(index_list);
  Xt_xmap xmap = xt_xmap_all2all_new(src_idxlist, dst_idxlist, MPI_COMM_WORLD);
  xt_idxlist_delete(src_idxlist);
  xt_idxlist_delete(dst_idxlist);
  return xmap;
}

87
88
89
90
91
92
93
94
95
int communicators_are_congruent(MPI_Comm comm1, MPI_Comm comm2) {

  int result;

  xt_mpi_call(MPI_Comm_compare(comm1, comm2, &result), MPI_COMM_WORLD);

  return ((result == MPI_IDENT) || (result == MPI_CONGRUENT));
}

96
void
97
98
99
100
101
102
check_redist_(Xt_redist redist,
              int sync_mode,
              int num_redists,
              const void *src[],
              size_t dst_num_elems, void *dst[],
              void *dst_buf_base,
103
104
105
              prepare_dst dst_prep,
              const void *dst_prep_info,
              const void *ref_dst_data,
106
107
108
              MPI_Datatype dst_data_dt,
              MPI_Datatype ref_dst_data_dt,
              const char *file, int line)
109
{
110
111
112
113
114
115
116
  MPI_Comm comm = xt_redist_get_MPI_Comm(redist);
  size_t dt_extent;
  {
    MPI_Aint dt_lb, dt_extent_;
    xt_mpi_call(MPI_Type_get_extent(dst_data_dt, &dt_lb, &dt_extent_), comm);
    dt_extent = (size_t)dt_extent_;
  }
117
  size_t dst_size = dst_num_elems * dt_extent;
118
119
120
121
  int start_txmode = sync_mode == sync_mode_test_a ? 1 : 0,
    end_txmode = sync_mode == sync_mode_test_s ? 1 : 2;
  for (int txmode = start_txmode; txmode < end_txmode; ++txmode) {
    dst_prep(dst_buf_base, dst_prep_info, dst_num_elems);
122
    if (txmode == 0) {
123
      xt_redist_s_exchange(redist, num_redists, src, dst);
124
    } else {
125
      wrap_a_exchange(redist, num_redists, src, dst);
126
    }
127
128
    bool compare_failed = false;
    if (dst_data_dt == ref_dst_data_dt) {
129
      compare_failed = memcmp(dst_buf_base, ref_dst_data, dst_size);
130
    } else if (dst_data_dt == MPI_DOUBLE && ref_dst_data_dt == MPI_INT) {
131
      const double *dst_cmp = dst_buf_base;
132
      const int *ref_dst_cmp = ref_dst_data;
133
      for (size_t i = 0; i < dst_num_elems; ++i)
134
135
        compare_failed |= (dst_cmp[i] != ref_dst_cmp[i]);
    } else if (dst_data_dt == MPI_DOUBLE && ref_dst_data_dt == MPI_LONG) {
136
      const double *dst_cmp = dst_buf_base;
137
      const long *ref_dst_cmp = ref_dst_data;
138
      for (size_t i = 0; i < dst_num_elems; ++i)
139
140
        compare_failed |= (dst_cmp[i] != ref_dst_cmp[i]);
    } else if (dst_data_dt == MPI_DOUBLE && ref_dst_data_dt == MPI_SHORT) {
141
      const double *dst_cmp = dst_buf_base;
142
      const short *ref_dst_cmp = ref_dst_data;
143
      for (size_t i = 0; i < dst_num_elems; ++i)
144
145
        compare_failed |= (dst_cmp[i] != ref_dst_cmp[i]);
    } else if (dst_data_dt == MPI_DOUBLE && ref_dst_data_dt == MPI_LONG_LONG) {
146
      const double *dst_cmp = dst_buf_base;
147
      const long long *ref_dst_cmp = ref_dst_data;
148
      for (size_t i = 0; i < dst_num_elems; ++i)
149
150
151
        compare_failed |= (dst_cmp[i] != ref_dst_cmp[i]);
    } else if (dst_data_dt == MPI_DOUBLE
               && ref_dst_data_dt == MPI_DATATYPE_NULL) {
152
      const double *dst_cmp = dst_buf_base;
153
      for (size_t i = 0; i < dst_num_elems; ++i)
154
155
156
157
158
159
        compare_failed |= (dst_cmp[i] != (double)i);
    } else
      Xt_abort(comm, "internal error: unhandled test case!", file, line);
    if (compare_failed)
      PUT_ERR("error in xt_redist_s/a_exchange, called from %s, line %d\n",
              file, line);
160
  }
161
162
}

163
164
165
166
167
168
169
170
171
void
fill_array_double(void *dst, const void *dst_prep_info, size_t dst_num_elems)
{
  (void)dst_prep_info;
  double *restrict a = dst;
  for (size_t i = 0; i < dst_num_elems; ++i)
    a[i] = -1;
}

Thomas Jahns's avatar
Thomas Jahns committed
172
173
174
175
176
177
178
179
180
void
fill_array_float(void *dst, const void *dst_prep_info, size_t dst_num_elems)
{
  (void)dst_prep_info;
  float *restrict a = dst;
  for (size_t i = 0; i < dst_num_elems; ++i)
    a[i] = -1;
}

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
void
fill_array_long(void *dst, const void *dst_prep_info, size_t dst_num_elems)
{
  (void)dst_prep_info;
  long *restrict a = dst;
  for (size_t i = 0; i < dst_num_elems; ++i)
    a[i] = -1L;
}

void
fill_array_int(void *dst, const void *dst_prep_info, size_t dst_num_elems)
{
  (void)dst_prep_info;
  int *restrict a = dst;
  for (size_t i = 0; i < dst_num_elems; ++i)
    a[i] = -1;
}

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
void
fill_array_short(void *dst, const void *dst_prep_info, size_t dst_num_elems)
{
  (void)dst_prep_info;
  short *restrict a = dst;
  for (size_t i = 0; i < dst_num_elems; ++i)
    a[i] = (short)-1;
}

void
fill_array_long_long(void *dst, const void *dst_prep_info, size_t dst_num_elems)
{
  (void)dst_prep_info;
  long long *restrict a = dst;
  for (size_t i = 0; i < dst_num_elems; ++i)
    a[i] = -1;
}

void
fill_array_xt_int(void *dst, const void *dst_prep_info, size_t dst_num_elems)
{
  (void)dst_prep_info;
  Xt_int *restrict a = dst;
  for (size_t i = 0; i < dst_num_elems; ++i)
    a[i] = (Xt_int)-1;
}

226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
void
check_wait_request_(Xt_request *request, const char *file, int line)
{
#ifndef VERBOSE
  (void)file;
  (void)line;
#endif
  if (*request == XT_REQUEST_NULL)
    PUT_ERR("request ==  XT_REQUEST_NULL before xt_request_wait: %s, line %d\n",
            file, line);
  xt_request_wait(request);
  if (*request != XT_REQUEST_NULL)
    PUT_ERR("request !=  XT_REQUEST_NULL after xt_request_wait: %s, line %d\n",
            file, line);
}

243
244
245
246
247
248
void
wrap_a_exchange(Xt_redist redist, int num_data_p, const void *src_data_p[],
                void *dst_data_p[])
{
  Xt_request request;
  xt_redist_a_exchange(redist, num_data_p, src_data_p, dst_data_p, &request);
249
  check_wait_request(&request);
250
251
252
253
254
255
256
}

void
wrap_a_exchange1(Xt_redist redist, const void *src_data_p, void *dst_data_p)
{
  Xt_request request;
  xt_redist_a_exchange1(redist, src_data_p, dst_data_p, &request);
257
  check_wait_request(&request);
258
259
}

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

int
exchanger_id_by_name(const char *name)
{
  int exchanger_new;
  if (!strcmp(name, "irecv_isend"))
    exchanger_new = xt_exchanger_irecv_isend;
  else if (!strcmp(name, "irecv_isend_packed"))
    exchanger_new = xt_exchanger_irecv_isend_packed;
  else if (!strcmp(name, "irecv_send"))
    exchanger_new = xt_exchanger_irecv_send;
  else if (!strcmp(name, "mix_irecv_isend"))
    exchanger_new = xt_exchanger_mix_isend_irecv;
  else if (!strcmp(name, "neigh_alltoall"))
    exchanger_new = xt_exchanger_neigh_alltoall;
  else
    exchanger_new = -1;
  return exchanger_new;
}

280
281
282
283
284
285
286
287
288
/*
 * Local Variables:
 * c-basic-offset: 2
 * coding: utf-8
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */