Commit 16c239c4 authored by Thomas Jahns's avatar Thomas Jahns 🤸
Browse files

Handle potential unavailability of MPI_Neighbor_alltoallw more gracefully.

* This way, the constructor cannot ever be invoked if the MPI version is < 3.
parent 4334d020
...@@ -253,6 +253,9 @@ FCFLAGS="$FCFLAGS ${FPP_DEFOPT}XT_MPI_AINT_KIND=$xt_mpi_aint_kind" ...@@ -253,6 +253,9 @@ FCFLAGS="$FCFLAGS ${FPP_DEFOPT}XT_MPI_AINT_KIND=$xt_mpi_aint_kind"
AC_CHECK_SIZEOF([MPI_Datatype],,[@%:@include <mpi.h>]) AC_CHECK_SIZEOF([MPI_Datatype],,[@%:@include <mpi.h>])
AS_IF([test $ac_cv_sizeof_MPI_Datatype -eq 0], AS_IF([test $ac_cv_sizeof_MPI_Datatype -eq 0],
[AC_MSG_FAILURE([Could not detect size of MPI_Datatype!])]) [AC_MSG_FAILURE([Could not detect size of MPI_Datatype!])])
AC_COMPUTE_INT([MPI_VERSION], [MPI_VERSION], [@%:@include <mpi.h>],
[AC_MSG_ERROR([cannot determine MPI version!])])
AM_CONDITIONAL([USE_MPI3],[test $MPI_VERSION -ge 3])
CFLAGS=$save_CFLAGS CFLAGS=$save_CFLAGS
AS_CASE(["$MPI_FINT"], AS_CASE(["$MPI_FINT"],
[int],[XT_MPI_FINT_MAX=INT_MAX XT_MPI_FINT_FC_KIND=c_int], [int],[XT_MPI_FINT_MAX=INT_MAX XT_MPI_FINT_FC_KIND=c_int],
......
...@@ -149,11 +149,15 @@ libyaxt_c_la_SOURCES = \ ...@@ -149,11 +149,15 @@ libyaxt_c_la_SOURCES = \
xt_exchanger_irecv_isend.h \ xt_exchanger_irecv_isend.h \
xt_exchanger_irecv_isend_packed.c \ xt_exchanger_irecv_isend_packed.c \
xt_exchanger_irecv_isend_packed.h \ xt_exchanger_irecv_isend_packed.h \
xt_exchanger_neigh_alltoall.c \
xt_exchanger_neigh_alltoall.h \ xt_exchanger_neigh_alltoall.h \
xt_exchanger_mix_isend_irecv.c \ xt_exchanger_mix_isend_irecv.c \
xt_exchanger_mix_isend_irecv.h xt_exchanger_mix_isend_irecv.h
if USE_MPI3
libyaxt_c_la_SOURCES += \
xt_exchanger_neigh_alltoall.c
endif
libyaxt_la_SOURCES = \ libyaxt_la_SOURCES = \
xt_idxlist_collection_f.f90 \ xt_idxlist_collection_f.f90 \
xt_xmap_intersection_f.f90 \ xt_xmap_intersection_f.f90 \
......
...@@ -92,7 +92,12 @@ static const struct { ...@@ -92,7 +92,12 @@ static const struct {
{ "mix_irecv_isend", { "mix_irecv_isend",
xt_exchanger_mix_isend_irecv_new, xt_exchanger_mix_isend_irecv }, xt_exchanger_mix_isend_irecv_new, xt_exchanger_mix_isend_irecv },
{ "neigh_alltoall", { "neigh_alltoall",
xt_exchanger_neigh_alltoall_new, xt_exchanger_neigh_alltoall }, #if MPI_VERSION >= 3
xt_exchanger_neigh_alltoall_new,
#else
(Xt_exchanger_new)0,
#endif
xt_exchanger_neigh_alltoall },
}; };
enum { enum {
...@@ -108,15 +113,25 @@ xt_exchanger_id_by_name(const char *name) ...@@ -108,15 +113,25 @@ xt_exchanger_id_by_name(const char *name)
return -1; return -1;
} }
int xt_config_get_exchange_method(Xt_config config) static inline size_t
exchanger_by_function(Xt_exchanger_new exchanger_new)
{ {
Xt_exchanger_new exchanger_new = config->exchanger_new;
for (size_t i = 0; i < num_exchanger; ++i) for (size_t i = 0; i < num_exchanger; ++i)
if (exchanger_table[i].f == exchanger_new) if (exchanger_table[i].f == exchanger_new)
return (int)i; return i;
return SIZE_MAX;
}
int xt_config_get_exchange_method(Xt_config config)
{
Xt_exchanger_new exchanger_new = config->exchanger_new;
size_t eentry = exchanger_by_function(exchanger_new);
if (eentry != SIZE_MAX)
return exchanger_table[eentry].code;
static const char fmt[] static const char fmt[]
= "error: unexpected exchanger function (%p)!\n"; = "error: unexpected exchanger function (%p)!";
char buf[sizeof (fmt) + 9]; char buf[sizeof (fmt) + 3*sizeof(void *)];
sprintf(buf, fmt, (void *)exchanger_new); sprintf(buf, fmt, (void *)exchanger_new);
Xt_abort(Xt_default_comm, buf, "xt_config.c", __LINE__); Xt_abort(Xt_default_comm, buf, "xt_config.c", __LINE__);
} }
...@@ -124,16 +139,32 @@ int xt_config_get_exchange_method(Xt_config config) ...@@ -124,16 +139,32 @@ int xt_config_get_exchange_method(Xt_config config)
void xt_config_set_exchange_method(Xt_config config, int method) void xt_config_set_exchange_method(Xt_config config, int method)
{ {
static const char fmt[]
= "error: user-requested exchanger code (%d) does not exist!";
char buf[sizeof (fmt) + 3*sizeof(int)];
const char *msg = buf;
for (size_t i = 0; i < num_exchanger; ++i) for (size_t i = 0; i < num_exchanger; ++i)
if (exchanger_table[i].code == method) { if (exchanger_table[i].code == method) {
config->exchanger_new = exchanger_table[i].f; Xt_exchanger_new exchanger_new;
if (exchanger_table[i].f) {
exchanger_new = exchanger_table[i].f;
} else {
exchanger_new = xt_default_config.exchanger_new;
size_t default_entry = exchanger_by_function(exchanger_new);
if (default_entry == SIZE_MAX) {
msg = "error: invalid default exchanger constructor!";
goto abort;
}
fprintf(stderr, "warning: %s exchanger unavailable, using "
"%s instead\n",
exchanger_table[i].name, exchanger_table[default_entry].name);
}
config->exchanger_new = exchanger_new;
return; return;
} }
static const char fmt[]
= "error: user-requested exchanger code (%d) does not exist!\n";
char buf[sizeof (fmt) + 9];
sprintf(buf, fmt, method); sprintf(buf, fmt, method);
Xt_abort(Xt_default_comm, buf, "xt_config.c", __LINE__); abort:
Xt_abort(Xt_default_comm, msg, "xt_config.c", __LINE__);
} }
void void
...@@ -144,6 +175,9 @@ xt_config_defaults_init(void) ...@@ -144,6 +175,9 @@ xt_config_defaults_init(void)
int exchanger_id = xt_exchanger_id_by_name(config_env); int exchanger_id = xt_exchanger_id_by_name(config_env);
if (exchanger_id != -1) if (exchanger_id != -1)
xt_config_set_exchange_method(&xt_default_config, exchanger_id); xt_config_set_exchange_method(&xt_default_config, exchanger_id);
else
fprintf(stderr, "warning: Unexpected value "
"for XT_CONFIG_DEFAULT_EXCHANGE_METHOD=%s\n", config_env);
} }
} }
......
...@@ -47,17 +47,12 @@ ...@@ -47,17 +47,12 @@
#include <config.h> #include <config.h>
#endif #endif
#include <mpi.h>
#include "xt_exchanger_neigh_alltoall.h"
#include "core/core.h"
#if MPI_VERSION >= 3
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <mpi.h>
#include "core/core.h"
#include "core/ppm_xfuncs.h" #include "core/ppm_xfuncs.h"
#include "xt/xt_mpi.h" #include "xt/xt_mpi.h"
#include "xt_mpi_internal.h" #include "xt_mpi_internal.h"
...@@ -67,6 +62,7 @@ ...@@ -67,6 +62,7 @@
#include "xt/xt_request.h" #include "xt/xt_request.h"
#include "xt/xt_request_msgs.h" #include "xt/xt_request_msgs.h"
#include "xt_exchanger.h" #include "xt_exchanger.h"
#include "xt_exchanger_neigh_alltoall.h"
#define MAX(a,b) ((a) >= (b) ? (a) : (b)) #define MAX(a,b) ((a) >= (b) ? (a) : (b))
...@@ -309,26 +305,6 @@ xt_exchanger_neigh_alltoall_get_msg_ranks(Xt_exchanger exchanger, ...@@ -309,26 +305,6 @@ xt_exchanger_neigh_alltoall_get_msg_ranks(Xt_exchanger exchanger,
return (int)nmsg; return (int)nmsg;
} }
// #if MPI_VERSION >= 3
#else
Xt_exchanger
xt_exchanger_neigh_alltoall_new(int nsend, int nrecv,
const struct Xt_redist_msg *send_msgs,
const struct Xt_redist_msg *recv_msgs,
MPI_Comm comm, int tag_offset) {
(void)nsend; (void)nrecv; (void)send_msgs; (void)recv_msgs; (void)tag_offset;
Xt_abort(comm, "ERROR(xt_exchanger_neigh_alltoall_new): "
"exchanger_neigh_alltoall requires MPI version 3.0 or higher",
__FILE__, __LINE__);
return NULL;
}
// #if MPI_VERSION >= 3
#endif
/* /*
* Local Variables: * Local Variables:
* c-basic-offset: 2 * c-basic-offset: 2
......
...@@ -130,7 +130,9 @@ static Xt_exchanger_new *parse_options(int *argc, char ***argv) ...@@ -130,7 +130,9 @@ static Xt_exchanger_new *parse_options(int *argc, char ***argv)
[xt_exchanger_irecv_isend] = xt_exchanger_irecv_isend_new, [xt_exchanger_irecv_isend] = xt_exchanger_irecv_isend_new,
[xt_exchanger_irecv_isend_packed] = xt_exchanger_irecv_isend_packed_new, [xt_exchanger_irecv_isend_packed] = xt_exchanger_irecv_isend_packed_new,
[xt_exchanger_mix_isend_irecv] = xt_exchanger_mix_isend_irecv_new, [xt_exchanger_mix_isend_irecv] = xt_exchanger_mix_isend_irecv_new,
#if MPI_VERSION >= 3
[xt_exchanger_neigh_alltoall] = xt_exchanger_neigh_alltoall_new, [xt_exchanger_neigh_alltoall] = xt_exchanger_neigh_alltoall_new,
#endif
}; };
enum { enum {
num_exchanger = sizeof (exchanger_table) / sizeof (exchanger_table[0]), num_exchanger = sizeof (exchanger_table) / sizeof (exchanger_table[0]),
...@@ -479,10 +481,11 @@ test_rr(MPI_Comm comm, Xt_exchanger_new exchanger_new) ...@@ -479,10 +481,11 @@ test_rr(MPI_Comm comm, Xt_exchanger_new exchanger_new)
static void static void
test_intercomm_all2all(MPI_Comm comm, Xt_exchanger_new exchanger_new) test_intercomm_all2all(MPI_Comm comm, Xt_exchanger_new exchanger_new)
{ {
#if MPI_VERSION >= 3
// inter-communicator's are not defined for virtual topologies, which are // inter-communicator's are not defined for virtual topologies, which are
// used by xt_exchanger_neigh_alltoall_new // used by xt_exchanger_neigh_alltoall_new
if (exchanger_new == xt_exchanger_neigh_alltoall_new) return; if (exchanger_new == xt_exchanger_neigh_alltoall_new) return;
#endif
int my_rank, comm_size; int my_rank, comm_size;
xt_mpi_call(MPI_Comm_rank(comm, &my_rank), comm); xt_mpi_call(MPI_Comm_rank(comm, &my_rank), comm);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment