1
1
openmpi/ompi/mpi/cxx/intercepts.cc
Brian Barrett 39dbeeedfb * rename locking code from ompi to opal
This commit was SVN r6327.
2005-07-03 22:45:48 +00:00

181 строка
5.5 KiB
C++

// -*- c++ -*-
//
// Copyright (c) 2004-2005 The Trustees of Indiana University.
// All rights reserved.
// Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
// All rights reserved.
// Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
// University of Stuttgart. All rights reserved.
// Copyright (c) 2004-2005 The Regents of the University of California.
// All rights reserved.
// $COPYRIGHT$
//
// Additional copyrights may follow
//
// $HEADER$
//
#include "mpicxx.h"
#include <stdio.h>
extern "C"
void ompi_mpi_cxx_throw_excptn_fctn(MPI_Comm *, int *errcode, ...)
{
#if OMPI_HAVE_CXX_EXCEPTION_SUPPORT
throw(MPI::Exception(*errcode));
#else
// Ick. This is really ugly, but necesary if someone uses a C compiler
// and -lmpi++ (which can legally happen in the LAM MPI implementation,
// and probably in MPICH and others who include -lmpi++ by default in their
// wrapper compilers)
fprintf(stderr, "MPI 2 C++ exception throwing is disabled, MPI::mpi_errno has the error code\n");
MPI::mpi_errno = *errcode;
#endif
}
MPI::Comm::mpi_comm_map_t MPI::Comm::mpi_comm_map;
MPI::Comm::mpi_err_map_t MPI::Comm::mpi_err_map;
MPI::Comm::key_fn_map_t MPI::Comm::key_fn_map;
opal_mutex_t *MPI::Comm::mpi_comm_map_mutex = NULL;
opal_mutex_t *MPI::Comm::mpi_err_map_mutex = NULL;
opal_mutex_t *MPI::Comm::key_fn_map_mutex = NULL;
extern "C"
void ompi_mpi_cxx_errhandler_intercept(MPI_Comm *mpi_comm, int *err, ...)
{
MPI::Comm* comm = MPI::Comm::mpi_err_map[*mpi_comm];
if (comm && comm->my_errhandler) {
va_list ap;
va_start(ap, err);
comm->my_errhandler->handler_fn(*comm, err, ap);
va_end(ap);
}
}
MPI::Op* MPI::Intracomm::current_op;
extern "C" void
ompi_mpi_cxx_op_intercept(void *invec, void *outvec, int *len,
MPI_Datatype *datatype)
{
MPI::Op* op = MPI::Intracomm::current_op;
MPI::Datatype thedata = *datatype;
((MPI::User_function*)op->op_user_function)(invec, outvec, *len, thedata);
//JGS the above cast is a bit of a hack, I'll explain:
// the type for the PMPI::Op::op_user_function is PMPI::User_function
// but what it really stores is the user's MPI::User_function supplied when
// the user did an Op::Init. We need to cast the function pointer back to
// the MPI::User_function. The reason the PMPI::Op::op_user_function was
// not declared a MPI::User_function instead of a PMPI::User_function is
// that without namespaces we cannot do forward declarations.
// Anyway, without the cast the code breaks on HP LAM with the aCC compiler.
}
extern "C" int
ompi_mpi_cxx_copy_attr_intercept(MPI_Comm oldcomm, int keyval,
void *extra_state, void *attribute_val_in,
void *attribute_val_out, int *flag)
{
int ret = 0;
MPI::Comm::key_pair_t* copy_and_delete =
MPI::Comm::key_fn_map[keyval];
MPI::Comm::Copy_attr_function* copy_fn;
copy_fn = copy_and_delete->first;
MPI::Comm::comm_pair_t *comm_type =
MPI::Comm::mpi_comm_map[oldcomm];
// Just in case...
if (comm_type == 0)
return MPI::ERR_OTHER;
MPI::Intracomm intracomm;
MPI::Intercomm intercomm;
MPI::Graphcomm graphcomm;
MPI::Cartcomm cartcomm;
int thetype = (int)comm_type->second;
bool bflag = (bool)*flag;
switch (thetype) {
case eIntracomm:
intracomm = MPI::Intracomm(*comm_type->first);
ret = copy_fn(intracomm, keyval, extra_state,
attribute_val_in, attribute_val_out, bflag);
break;
case eIntercomm:
intercomm = MPI::Intercomm(*comm_type->first);
ret = copy_fn(intercomm, keyval, extra_state,
attribute_val_in, attribute_val_out, bflag);
break;
case eGraphcomm:
graphcomm = MPI::Graphcomm(*comm_type->first);
ret = copy_fn(graphcomm, keyval, extra_state,
attribute_val_in, attribute_val_out, bflag);
break;
case eCartcomm:
cartcomm = MPI::Cartcomm(*comm_type->first);
ret = copy_fn(cartcomm, keyval, extra_state,
attribute_val_in, attribute_val_out, bflag);
break;
}
*flag = (int)bflag;
return ret;
}
extern "C" int
ompi_mpi_cxx_delete_attr_intercept(MPI_Comm comm, int keyval,
void *attribute_val, void *extra_state)
{
int ret = 0;
MPI::Comm::key_pair_t *copy_and_delete =
MPI::Comm::key_fn_map[keyval];
MPI::Comm::Delete_attr_function* delete_fn;
delete_fn = copy_and_delete->second;
MPI::Comm::comm_pair_t *comm_type =
MPI::Comm::mpi_comm_map[comm];
// Just in case...
if (comm_type == 0)
return MPI::ERR_OTHER;
MPI::Intracomm intracomm;
MPI::Intercomm intercomm;
MPI::Graphcomm graphcomm;
MPI::Cartcomm cartcomm;
int thetype = (long)(comm_type->second);
if (delete_fn > (MPI::Comm::Delete_attr_function*) 100) {
switch (thetype) {
case eIntracomm:
intracomm = MPI::Intracomm(*comm_type->first);
ret = delete_fn(intracomm, keyval, attribute_val, extra_state);
break;
case eIntercomm:
intercomm = MPI::Intercomm(*comm_type->first);
ret = delete_fn(intercomm, keyval, attribute_val, extra_state);
break;
case eGraphcomm:
graphcomm = MPI::Graphcomm(*comm_type->first);
ret = delete_fn(graphcomm, keyval, attribute_val, extra_state);
break;
case eCartcomm:
cartcomm = MPI::Cartcomm(*comm_type->first);
ret = delete_fn(cartcomm, keyval, attribute_val, extra_state);
break;
}
} else
ret = MPI::ERR_OTHER;
return ret;
}