1
1

A number of MPI-2 compliance fixes for the C++ bindings:

* Added Create_errhandler for MPI::File
  * Make errors_throw_exceptions a first-class predefined exception
    handler, and make it work for Comm, File, and Win
  * Deal with error handlers and attributes for Files, Types, and Wins
    like we do with Comms - can't just cast the callbacks from C++
    signatures to C signatures.  Callbacks will then fire with the
    C object, not the C++ object.  That's bad.

Refs trac:455

This commit was SVN r12945.

The following Trac tickets were found above:
  Ticket 455 --> https://svn.open-mpi.org/trac/ompi/ticket/455
Этот коммит содержится в:
Brian Barrett 2006-12-30 23:41:42 +00:00
родитель 47601e315e
Коммит 1ba97181dc
21 изменённых файлов: 564 добавлений и 288 удалений

Просмотреть файл

@ -49,7 +49,7 @@ OBJ_CLASS_INSTANCE(ompi_errhandler_t, opal_object_t, ompi_errhandler_construct,
ompi_errhandler_t ompi_mpi_errhandler_null;
ompi_errhandler_t ompi_mpi_errors_are_fatal;
ompi_errhandler_t ompi_mpi_errors_return;
ompi_errhandler_t ompi_mpi_errors_throw_exceptions;
/*
* Local state to know when the three intrinsics have been freed; see
@ -58,6 +58,7 @@ ompi_errhandler_t ompi_mpi_errors_return;
static bool null_freed = false;
static bool fatal_freed = false;
static bool return_freed = false;
static bool throw_freed = false;
/*
@ -110,6 +111,17 @@ int ompi_errhandler_init(void)
strncpy (ompi_mpi_errors_return.eh_name, "MPI_ERRORS_RETURN",
strlen("MPI_ERRORS_RETURN")+1 );
/* If we're going to use C++, functions will be fixed up during MPI::Init */
OBJ_CONSTRUCT( &ompi_mpi_errors_throw_exceptions, ompi_errhandler_t );
ompi_mpi_errors_are_fatal.eh_mpi_object_type = OMPI_ERRHANDLER_TYPE_PREDEFINED;
ompi_mpi_errors_are_fatal.eh_fortran_function = false;
ompi_mpi_errors_are_fatal.eh_comm_fn = ompi_mpi_errors_are_fatal_comm_handler;
ompi_mpi_errors_are_fatal.eh_file_fn = ompi_mpi_errors_are_fatal_file_handler;
ompi_mpi_errors_are_fatal.eh_win_fn = ompi_mpi_errors_are_fatal_win_handler ;
ompi_mpi_errors_are_fatal.eh_fort_fn = NULL;
strncpy (ompi_mpi_errors_are_fatal.eh_name, "MPI_ERRORS_THROW_EXCEPTIONS",
strlen("MPI_ERRORS_THROW_EXCEPTIONS")+1 );
/* All done */
return OMPI_SUCCESS;
@ -138,6 +150,9 @@ int ompi_errhandler_finalize(void)
while (!return_freed) {
OBJ_DESTRUCT(&ompi_mpi_errors_return);
}
while (!throw_freed) {
OBJ_DESTRUCT(&ompi_mpi_errors_throw_exceptions);
}
/* JMS Add stuff here checking for unreleased errorhandlers,
similar to communicators, info handles, etc. */
@ -260,5 +275,7 @@ static void ompi_errhandler_destruct(ompi_errhandler_t *errhandler)
fatal_freed = true;
} else if (&ompi_mpi_errors_return == errhandler) {
return_freed = true;
} else if (&ompi_mpi_errors_throw_exceptions == errhandler) {
throw_freed = true;
}
}

Просмотреть файл

@ -107,6 +107,12 @@ OMPI_DECLSPEC extern ompi_errhandler_t ompi_mpi_errors_are_fatal;
*/
OMPI_DECLSPEC extern ompi_errhandler_t ompi_mpi_errors_return;
/**
* Global variable for MPI::ERRORS_THROW_EXCEPTIONS. Will abort if
* MPI_INIT wasn't called as MPI::INIT
*/
OMPI_DECLSPEC extern ompi_errhandler_t ompi_mpi_errors_throw_exceptions;
/**
* Table for Fortran <-> C errhandler handle conversion
*/

Просмотреть файл

@ -27,7 +27,10 @@ lib_LTLIBRARIES = libmpi_cxx.la
libmpi_cxx_la_SOURCES = \
mpicxx.cc \
intercepts.cc \
comm.cc
comm.cc \
datatype.cc \
file.cc \
win.cc
headers = \
mpicxx.h \

Просмотреть файл

@ -35,23 +35,11 @@
// construction
MPI::Comm::Comm()
{
if (mpi_comm_map_mutex == NULL)
mpi_comm_map_mutex = OBJ_NEW(opal_mutex_t);
if (mpi_err_map_mutex == NULL)
mpi_err_map_mutex = OBJ_NEW(opal_mutex_t);
if (key_fn_map_mutex == NULL)
key_fn_map_mutex = OBJ_NEW(opal_mutex_t);
}
// copy
MPI::Comm::Comm(const Comm_Null& data) : Comm_Null(data)
{
if (mpi_comm_map_mutex == NULL)
mpi_comm_map_mutex = OBJ_NEW(opal_mutex_t);
if (mpi_err_map_mutex == NULL)
mpi_err_map_mutex = OBJ_NEW(opal_mutex_t);
if (key_fn_map_mutex == NULL)
key_fn_map_mutex = OBJ_NEW(opal_mutex_t);
}
@ -61,11 +49,11 @@ MPI::Comm::Free(void)
MPI_Comm save = mpi_comm;
(void)MPI_Comm_free(&mpi_comm);
OPAL_THREAD_LOCK(mpi_comm_map_mutex);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
if (MPI::Comm::mpi_comm_map[save] != 0)
delete MPI::Comm::mpi_comm_map[save];
MPI::Comm::mpi_comm_map.erase(save);
OPAL_THREAD_UNLOCK(mpi_comm_map_mutex);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}
@ -73,9 +61,9 @@ void
MPI::Comm::Set_errhandler(const MPI::Errhandler& errhandler)
{
my_errhandler = (MPI::Errhandler *)&errhandler;
OPAL_THREAD_LOCK(mpi_err_map_mutex);
MPI::Comm::mpi_err_map[mpi_comm] = this;
OPAL_THREAD_UNLOCK(mpi_err_map_mutex);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Comm::mpi_comm_err_map[mpi_comm] = this;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
(void)MPI_Errhandler_set(mpi_comm, errhandler);
}
@ -88,14 +76,14 @@ MPI::Comm::Create_keyval(MPI::Comm::_MPI2CPP_COPYATTRFN_* comm_copy_attr_fn,
void* extra_state)
{
int keyval;
(void)MPI_Keyval_create(ompi_mpi_cxx_copy_attr_intercept,
ompi_mpi_cxx_delete_attr_intercept,
(void)MPI_Keyval_create(ompi_mpi_cxx_comm_copy_attr_intercept,
ompi_mpi_cxx_comm_delete_attr_intercept,
&keyval, extra_state);
key_pair_t* copy_and_delete =
new key_pair_t(comm_copy_attr_fn, comm_delete_attr_fn);
OPAL_THREAD_LOCK(key_fn_map_mutex);
MPI::Comm::key_fn_map[keyval] = copy_and_delete;
OPAL_THREAD_UNLOCK(key_fn_map_mutex);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Comm::mpi_comm_key_fn_map[keyval] = copy_and_delete;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
return keyval;
}
@ -105,11 +93,11 @@ MPI::Comm::Free_keyval(int& comm_keyval)
{
int save = comm_keyval;
(void)MPI_Keyval_free(&comm_keyval);
OPAL_THREAD_LOCK(key_fn_map_mutex);
if (MPI::Comm::key_fn_map[save] != 0)
delete MPI::Comm::key_fn_map[save];
MPI::Comm::key_fn_map.erase(save);
OPAL_THREAD_UNLOCK(key_fn_map_mutex);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
if (MPI::Comm::mpi_comm_key_fn_map[save] != 0)
delete MPI::Comm::mpi_comm_key_fn_map[save];
MPI::Comm::mpi_comm_key_fn_map.erase(save);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}
@ -132,11 +120,11 @@ MPI::Comm::Set_attr(int comm_keyval, const void* attribute_val) const
else
type = eIntracomm;
}
OPAL_THREAD_LOCK(mpi_comm_map_mutex);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
if (MPI::Comm::mpi_comm_map[mpi_comm] == 0) {
comm_pair_t* comm_type = new comm_pair_t((Comm*) this, type);
MPI::Comm::mpi_comm_map[mpi_comm] = comm_type;
}
OPAL_THREAD_UNLOCK(mpi_comm_map_mutex);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
(void)MPI_Attr_put(mpi_comm, comm_keyval, (void*) attribute_val);
}

Просмотреть файл

@ -431,16 +431,13 @@ public: // JGS hmmm, these used by errhandler_intercept
typedef ::std::pair<Comm*, CommType> comm_pair_t;
typedef ::std::map<MPI_Comm, comm_pair_t*> mpi_comm_map_t;
static mpi_comm_map_t mpi_comm_map;
static opal_mutex_t *mpi_comm_map_mutex;
typedef ::std::map<MPI_Comm, Comm*> mpi_err_map_t;
static mpi_err_map_t mpi_err_map;
static opal_mutex_t *mpi_err_map_mutex;
typedef ::std::map<MPI_Comm, Comm*> mpi_comm_err_map_t;
static mpi_comm_err_map_t mpi_comm_err_map;
typedef ::std::pair<Comm::_MPI2CPP_COPYATTRFN_*, Comm::_MPI2CPP_DELETEATTRFN_*> key_pair_t;
typedef ::std::map<int, key_pair_t*> key_fn_map_t;
static key_fn_map_t key_fn_map;
static opal_mutex_t *key_fn_map_mutex;
typedef ::std::map<int, key_pair_t*> mpi_comm_key_fn_map_t;
static mpi_comm_key_fn_map_t mpi_comm_key_fn_map;
void init() {
my_errhandler = (Errhandler*)0;

Просмотреть файл

@ -539,10 +539,10 @@ MPI::Comm::Create_errhandler(MPI::Comm::_MPI2CPP_ERRHANDLERFN_* function)
{
MPI_Errhandler errhandler;
// $%%@#%# AIX/POE 2.3.0.0 makes us put in this cast here
(void)MPI_Errhandler_create((MPI_Handler_function*) ompi_mpi_cxx_errhandler_intercept,
(void)MPI_Comm_create_errhandler((MPI_Handler_function*) ompi_mpi_cxx_comm_errhandler_intercept,
&errhandler);
MPI::Errhandler temp(errhandler);
temp.handler_fn = (void(*)(MPI::Comm&, int*, ...))function;
temp.comm_handler_fn = (void(*)(MPI::Comm&, int*, ...))function;
return temp;
}

68
ompi/mpi/cxx/datatype.cc Обычный файл
Просмотреть файл

@ -0,0 +1,68 @@
// -*- c++ -*-
//
// Copyright (c) 2006 Los Alamos National Security, LLC. All rights
// reserved.
// $COPYRIGHT$
//
// Additional copyrights may follow
//
// $HEADER$
//
// do not include ompi_config.h because it kills the free/malloc defines
#include "mpi.h"
#include "ompi/mpi/cxx/mpicxx.h"
#include "opal/threads/mutex.h"
void
MPI::Datatype::Free()
{
MPI_Datatype save = mpi_datatype;
(void)MPI_Type_free(&mpi_datatype);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Datatype::mpi_type_map.erase(save);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}
int
MPI::Datatype::Create_keyval(MPI::Datatype::Copy_attr_function* type_copy_attr_fn,
MPI::Datatype::Delete_attr_function* type_delete_attr_fn,
void* extra_state)
{
int keyval;
(void) MPI_Type_create_keyval(ompi_mpi_cxx_type_copy_attr_intercept,
ompi_mpi_cxx_type_delete_attr_intercept,
&keyval, extra_state);
key_pair_t* copy_and_delete =
new key_pair_t(type_copy_attr_fn, type_delete_attr_fn);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Datatype::mpi_type_key_fn_map[keyval] = copy_and_delete;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
return keyval;
}
void
MPI::Datatype::Free_keyval(int& type_keyval)
{
int save = type_keyval;
(void) MPI_Type_free_keyval(&type_keyval);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Datatype::mpi_type_key_fn_map.erase(save);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}
void
MPI::Datatype::Set_attr(int type_keyval, const void* attribute_val)
{
(void) MPI_Type_set_attr(mpi_datatype, type_keyval, const_cast<void *>(attribute_val));
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
if (MPI::Datatype::mpi_type_map[mpi_datatype] == 0) {
MPI::Datatype::mpi_type_map[mpi_datatype] = (Datatype*) this;
}
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}

Просмотреть файл

@ -196,7 +196,13 @@ protected:
MPI_Datatype mpi_datatype;
#endif
public:
typedef ::std::map<MPI_Datatype, Datatype*> mpi_type_map_t;
static mpi_type_map_t mpi_type_map;
typedef ::std::pair<Datatype::Copy_attr_function*, Datatype::Delete_attr_function*> key_pair_t;
typedef ::std::map<int, key_pair_t*> mpi_type_key_fn_map_t;
static mpi_type_key_fn_map_t mpi_type_key_fn_map;
};

Просмотреть файл

@ -137,12 +137,6 @@ MPI::Datatype::Commit()
(void)MPI_Type_commit(&mpi_datatype);
}
inline void
MPI::Datatype::Free()
{
(void)MPI_Type_free(&mpi_datatype);
}
inline void
MPI::Datatype::Pack(const void* inbuf, int incount,
void *outbuf, int outsize,
@ -203,21 +197,6 @@ MPI::Datatype::Dup() const
}
inline int
MPI::Datatype::Create_keyval(MPI::Datatype::Copy_attr_function*
type_copy_attr_fn,
MPI::Datatype::Delete_attr_function*
type_delete_attr_fn, void* extra_state)
{
int key;
(void) MPI_Type_create_keyval((MPI_Type_copy_attr_function *)
type_copy_attr_fn,
(MPI_Type_delete_attr_function *)
type_delete_attr_fn, &key, extra_state);
return key;
}
inline void
MPI::Datatype::Delete_attr(int type_keyval)
{
@ -225,12 +204,6 @@ MPI::Datatype::Delete_attr(int type_keyval)
}
inline void
MPI::Datatype::Free_keyval(int& type_keyval)
{
(void) MPI_Type_free_keyval(&type_keyval);
}
inline bool
MPI::Datatype::Get_attr(int type_keyval,
@ -270,12 +243,6 @@ MPI::Datatype::Get_name(char* type_name, int& resultlen) const
}
inline void
MPI::Datatype::Set_attr(int type_keyval, const void* attribute_val)
{
(void) MPI_Type_set_attr(mpi_datatype, type_keyval, const_cast<void *>(attribute_val));
}
inline void
MPI::Datatype::Set_name(const char* type_name)

Просмотреть файл

@ -20,46 +20,6 @@
class Errhandler {
public:
#if 0 /* OMPI_ENABLE_MPI_PROFILING */
// construction / destruction
inline Errhandler() { }
inline virtual ~Errhandler() { }
inline Errhandler(MPI_Errhandler i)
: pmpi_errhandler(i) { }
// copy / assignment
inline Errhandler(const Errhandler& e)
: pmpi_errhandler(e.pmpi_errhandler) { }
inline Errhandler(const PMPI::Errhandler& e)
: pmpi_errhandler(e) { }
inline Errhandler& operator=(const Errhandler& e) {
pmpi_errhandler = e.pmpi_errhandler; return *this; }
// comparison
inline bool operator==(const Errhandler &a) {
return (bool)(pmpi_errhandler == a.pmpi_errhandler); }
inline bool operator!=(const Errhandler &a) {
return (bool)!(*this == a); }
// inter-language operability
inline Errhandler& operator= (const MPI_Errhandler &i) {
pmpi_errhandler = i; return *this; }
inline operator MPI_Errhandler() const { return pmpi_errhandler; }
// inline operator MPI_Errhandler*() { return pmpi_errhandler; }
inline operator const PMPI::Errhandler&() const { return pmpi_errhandler; }
#else
// construction / destruction
inline Errhandler()
: mpi_errhandler(MPI_ERRHANDLER_NULL) {}
@ -71,12 +31,17 @@ public:
// copy / assignment
inline Errhandler(const Errhandler& e)
: handler_fn(e.handler_fn), mpi_errhandler(e.mpi_errhandler) { }
: comm_handler_fn(e.comm_handler_fn),
file_handler_fn(e.file_handler_fn),
win_handler_fn(e.win_handler_fn),
mpi_errhandler(e.mpi_errhandler) { }
inline Errhandler& operator=(const Errhandler& e)
{
mpi_errhandler = e.mpi_errhandler;
handler_fn = e.handler_fn;
comm_handler_fn = e.comm_handler_fn;
file_handler_fn = e.file_handler_fn;
win_handler_fn = e.win_handler_fn;
return *this;
}
@ -94,8 +59,6 @@ public:
inline operator MPI_Errhandler() const { return mpi_errhandler; }
// inline operator MPI_Errhandler*() { return &mpi_errhandler; }
#endif
//
// Errhandler access functions
@ -103,41 +66,9 @@ public:
virtual void Free();
#if !0 /* OMPI_ENABLE_MPI_PROFILING */
Comm::Errhandler_fn* handler_fn;
#endif
Comm::Errhandler_fn* comm_handler_fn;
File::Errhandler_fn* file_handler_fn;
Win::Errhandler_fn* win_handler_fn;
protected:
#if 0 /* OMPI_ENABLE_MPI_PROFILING */
PMPI::Errhandler pmpi_errhandler;
#else
MPI_Errhandler mpi_errhandler;
#endif
public:
// took out the friend decls
//private:
//this is for ERRORS_THROW_EXCEPTIONS
//this is called from MPI::Real_init
inline void init() const {
#if ! 0 /* OMPI_ENABLE_MPI_PROFILING */
// $%%@#%# AIX/POE 2.3.0.0 makes us put in this cast here
(void)MPI_Errhandler_create((MPI_Handler_function*) &ompi_mpi_cxx_throw_excptn_fctn,
const_cast<MPI_Errhandler *>(&mpi_errhandler));
#else
pmpi_errhandler.init();
#endif
}
//this is for ERRORS_THROW_EXCEPTIONS
//this is called from MPI::Finalize
inline void free() const {
#if ! 0 /* OMPI_ENABLE_MPI_PROFILING */
(void)MPI_Errhandler_free(const_cast<MPI_Errhandler *>(&mpi_errhandler));
#else
pmpi_errhandler.free();
#endif
}
};

38
ompi/mpi/cxx/file.cc Обычный файл
Просмотреть файл

@ -0,0 +1,38 @@
// -*- c++ -*-
//
// Copyright (c) 2006 Los Alamos National Security, LLC. All rights
// reserved.
// $COPYRIGHT$
//
// Additional copyrights may follow
//
// $HEADER$
//
// do not include ompi_config.h because it kills the free/malloc defines
#include "mpi.h"
#include "ompi/mpi/cxx/mpicxx.h"
#include "opal/threads/mutex.h"
void
MPI::File::Close()
{
MPI_File save = mpi_file;
(void) MPI_File_close(&mpi_file);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::File::mpi_file_map.erase(save);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}
void
MPI::File::Set_errhandler(const MPI::Errhandler& errhandler)
{
my_errhandler = (MPI::Errhandler *)&errhandler;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::File::mpi_file_map[mpi_file] = this;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
(void)MPI_File_set_errhandler(mpi_file, errhandler);
}

Просмотреть файл

@ -255,11 +255,15 @@ public:
void Write_shared(const void* buf, int count,
const MPI::Datatype& datatype, MPI::Status& status);
void Call_errhandler(int errorcode) const;
typedef void Errhandler_fn(MPI::File &, int *, ... );
static MPI::Errhandler Create_errhandler(Errhandler_fn* function);
MPI::Errhandler Get_errhandler() const;
void Set_errhandler(const MPI::Errhandler& errhandler);
typedef void Errhandler_fn(MPI::File &, int *, ... );
protected:
#if 0 /* OMPI_ENABLE_MPI_PROFILING */
@ -269,5 +273,11 @@ protected:
MPI_File mpi_file;
#endif
public:
Errhandler* my_errhandler;
typedef ::std::map<MPI_File, File*> mpi_file_map_t;
static mpi_file_map_t mpi_file_map;
};

Просмотреть файл

@ -17,12 +17,6 @@
// $HEADER$
//
inline void
MPI::File::Close()
{
(void) MPI_File_close(&mpi_file);
}
inline void
MPI::File::Delete(const char* filename, const MPI::Info& info)
@ -638,16 +632,26 @@ MPI::File::Write_shared(const void* buf, int count,
}
inline MPI::Errhandler
MPI::File::Create_errhandler(MPI::File::Errhandler_fn* function)
{
MPI_Errhandler errhandler;
(void) MPI_File_create_errhandler((MPI_File_errhandler_fn *) ompi_mpi_cxx_file_errhandler_intercept,
&errhandler);
MPI::Errhandler temp(errhandler);
temp.file_handler_fn = (void(*)(MPI::File&, int* , ...)) function;
return temp;
}
inline MPI::Errhandler
MPI::File::Get_errhandler() const
{
MPI_Errhandler err;
(void) MPI_File_get_errhandler(mpi_file, &err);
return err;
return *my_errhandler;
}
inline void
MPI::File::Set_errhandler(const MPI::Errhandler& errhandler)
inline void
MPI::File::Call_errhandler(int errorcode) const
{
(void) MPI_File_set_errhandler(mpi_file, errhandler);
(void) MPI_File_call_errhandler(mpi_file, errorcode);
}

Просмотреть файл

@ -59,6 +59,12 @@ Init(int& argc, char**& argv);
void
Init();
void
InitializeIntercepts();
void
FinalizeIntercepts();
void
Real_init();

Просмотреть файл

@ -87,9 +87,7 @@ MPI::Wtick()
inline void
MPI::Real_init()
{
// This is here even though ERRORS_THROW_EXCEPTIONS is a const
// function; there's no way around this. :-(
MPI::ERRORS_THROW_EXCEPTIONS.init();
MPI::InitializeIntercepts();
}
@ -110,9 +108,7 @@ MPI::Init()
inline void
MPI::Finalize()
{
// Prevent a memory leak by calling this hidden "free" function here
// (even though ERRORS_THROW_EXCEPTIONS is a const object)
MPI::ERRORS_THROW_EXCEPTIONS.free();
FinalizeIntercepts();
(void)MPI_Finalize();
}

Просмотреть файл

@ -22,14 +22,27 @@
#include "mpicxx.h"
#include <stdio.h>
extern "C"
void ompi_mpi_cxx_throw_excptn_fctn(MPI_Comm *, int *errcode, ...)
#include "ompi_config.h"
#include "ompi/errhandler/errhandler.h"
#include "opal/threads/mutex.h"
MPI::Comm::mpi_comm_map_t MPI::Comm::mpi_comm_map;
MPI::Comm::mpi_comm_err_map_t MPI::Comm::mpi_comm_err_map;
MPI::Comm::mpi_comm_key_fn_map_t MPI::Comm::mpi_comm_key_fn_map;
MPI::Win::mpi_win_map_t MPI::Win::mpi_win_map;
MPI::Win::mpi_win_key_fn_map_t MPI::Win::mpi_win_key_fn_map;
MPI::Datatype::mpi_type_map_t MPI::Datatype::mpi_type_map;
MPI::Datatype::mpi_type_key_fn_map_t MPI::Datatype::mpi_type_key_fn_map;
MPI::File::mpi_file_map_t MPI::File::mpi_file_map;
opal_mutex_t *MPI::mpi_map_mutex;
extern "C"
void ompi_mpi_cxx_throw_exception(int *errcode)
{
/* Portland compiler raises a warning if va_start is not used in a
* variable argument function */
va_list ap;
va_start(ap, errcode);
va_end(ap);
#if OMPI_HAVE_CXX_EXCEPTION_SUPPORT
throw(MPI::Exception(*errcode));
#else
@ -42,22 +55,103 @@ void ompi_mpi_cxx_throw_excptn_fctn(MPI_Comm *, int *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;
extern "C"
void ompi_mpi_cxx_comm_throw_excptn_fctn(MPI_Comm *, int *errcode, ...)
{
/* Portland compiler raises a warning if va_start is not used in a
* variable argument function */
va_list ap;
va_start(ap, errcode);
ompi_mpi_cxx_throw_exception(errcode);
va_end(ap);
}
extern "C"
void ompi_mpi_cxx_file_throw_excptn_fctn(MPI_File *, int *errcode, ...)
{
va_list ap;
va_start(ap, errcode);
ompi_mpi_cxx_throw_exception(errcode);
va_end(ap);
}
extern "C"
void ompi_mpi_cxx_win_throw_excptn_fctn(MPI_Win *, int *errcode, ...)
{
va_list ap;
va_start(ap, errcode);
ompi_mpi_cxx_throw_exception(errcode);
va_end(ap);
}
void
MPI::InitializeIntercepts()
{
ompi_mpi_errors_throw_exceptions.eh_comm_fn =
ompi_mpi_cxx_comm_throw_excptn_fctn;
ompi_mpi_errors_throw_exceptions.eh_file_fn =
ompi_mpi_cxx_file_throw_excptn_fctn;
ompi_mpi_errors_throw_exceptions.eh_win_fn =
ompi_mpi_cxx_win_throw_excptn_fctn;
MPI::mpi_map_mutex = OBJ_NEW(opal_mutex_t);
}
void
MPI::FinalizeIntercepts()
{
OBJ_RELEASE(MPI::mpi_map_mutex);
}
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, ...)
void ompi_mpi_cxx_comm_errhandler_intercept(MPI_Comm *mpi_comm, int *err, ...)
{
MPI::Comm* comm = MPI::Comm::mpi_err_map[*mpi_comm];
MPI::Comm* comm;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
comm = MPI::Comm::mpi_comm_err_map[*mpi_comm];
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
if (comm && comm->my_errhandler) {
va_list ap;
va_start(ap, err);
comm->my_errhandler->handler_fn(*comm, err, ap);
comm->my_errhandler->comm_handler_fn(*comm, err, ap);
va_end(ap);
}
}
extern "C"
void ompi_mpi_cxx_file_errhandler_intercept(MPI_File *mpi_file, int *err, ...)
{
MPI::File* file;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
file = MPI::File::mpi_file_map[*mpi_file];
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
if (file && file->my_errhandler) {
va_list ap;
va_start(ap, err);
file->my_errhandler->file_handler_fn(*file, err, ap);
va_end(ap);
}
}
extern "C"
void ompi_mpi_cxx_win_errhandler_intercept(MPI_Win *mpi_win, int *err, ...)
{
MPI::Win* win;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
win = MPI::Win::mpi_win_map[*mpi_win];
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
if (win && win->my_errhandler) {
va_list ap;
va_start(ap, err);
win->my_errhandler->win_handler_fn(*win, err, ap);
va_end(ap);
}
}
@ -181,19 +275,24 @@ ompi_mpi_cxx_op_intercept(void *invec, void *outvec, int *len,
cxx_callback(invec, outvec, *len, cxx_datatype);
}
//
// Attribute copy functions -- comm, type, and win
//
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)
ompi_mpi_cxx_comm_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::key_pair_t* copy_and_delete;
MPI::Comm::Copy_attr_function* copy_fn;
copy_fn = copy_and_delete->first;
MPI::Comm::comm_pair_t *comm_type;
MPI::Comm::comm_pair_t *comm_type =
MPI::Comm::mpi_comm_map[oldcomm];
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
copy_and_delete = MPI::Comm::mpi_comm_key_fn_map[keyval];
copy_fn = copy_and_delete->first;
comm_type = MPI::Comm::mpi_comm_map[oldcomm];
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
// Just in case...
@ -236,19 +335,20 @@ ompi_mpi_cxx_copy_attr_intercept(MPI_Comm oldcomm, int keyval,
}
extern "C" int
ompi_mpi_cxx_delete_attr_intercept(MPI_Comm comm, int keyval,
void *attribute_val, void *extra_state)
ompi_mpi_cxx_comm_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::key_pair_t * copy_and_delete;
MPI::Comm::Delete_attr_function* delete_fn;
delete_fn = copy_and_delete->second;
MPI::Comm::comm_pair_t *comm_type;
MPI::Comm::comm_pair_t *comm_type =
MPI::Comm::mpi_comm_map[comm];
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
copy_and_delete = MPI::Comm::mpi_comm_key_fn_map[keyval];
delete_fn = copy_and_delete->second;
comm_type = MPI::Comm::mpi_comm_map[comm];
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
// Just in case...
@ -286,6 +386,100 @@ ompi_mpi_cxx_delete_attr_intercept(MPI_Comm comm, int keyval,
return ret;
}
extern "C" int
ompi_mpi_cxx_type_copy_attr_intercept(MPI_Datatype oldtype, int keyval,
void *extra_state, void *attribute_val_in,
void *attribute_val_out, int *flag)
{
int ret = 0;
MPI::Datatype::key_pair_t* copy_and_delete;
MPI::Datatype::Copy_attr_function* copy_fn;
MPI::Datatype *cxx_oldtype;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
cxx_oldtype = MPI::Datatype::mpi_type_map[oldtype];
copy_and_delete = MPI::Datatype::mpi_type_key_fn_map[keyval];
copy_fn = copy_and_delete->first;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
bool bflag = OPAL_INT_TO_BOOL(*flag);
ret = copy_fn(*cxx_oldtype, keyval, extra_state, attribute_val_in,
attribute_val_out, bflag);
*flag = (int)bflag;
return ret;
}
extern "C" int
ompi_mpi_cxx_type_delete_attr_intercept(MPI_Datatype type, int keyval,
void *attribute_val, void *extra_state)
{
int ret = 0;
MPI::Datatype::key_pair_t* copy_and_delete;
MPI::Datatype::Delete_attr_function* delete_fn;
MPI::Datatype *cxx_type;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
cxx_type = MPI::Datatype::mpi_type_map[type];
copy_and_delete = MPI::Datatype::mpi_type_key_fn_map[keyval];
delete_fn = copy_and_delete->second;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
ret = delete_fn(*cxx_type, keyval, attribute_val, extra_state);
return ret;
}
extern "C" int
ompi_mpi_cxx_win_copy_attr_intercept(MPI_Win oldwin, int keyval,
void *extra_state, void *attribute_val_in,
void *attribute_val_out, int *flag)
{
int ret = 0;
MPI::Win::key_pair_t* copy_and_delete;
MPI::Win::Copy_attr_function* copy_fn;
MPI::Win *cxx_oldwin;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
cxx_oldwin = MPI::Win::mpi_win_map[oldwin];
copy_and_delete = MPI::Win::mpi_win_key_fn_map[keyval];
copy_fn = copy_and_delete->first;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
bool bflag = OPAL_INT_TO_BOOL(*flag);
ret = copy_fn(*cxx_oldwin, keyval, extra_state, attribute_val_in,
attribute_val_out, bflag);
*flag = (int)bflag;
return ret;
}
extern "C" int
ompi_mpi_cxx_win_delete_attr_intercept(MPI_Win win, int keyval,
void *attribute_val, void *extra_state)
{
int ret = 0;
MPI::Win::key_pair_t* copy_and_delete;
MPI::Win::Delete_attr_function* delete_fn;
MPI::Win *cxx_win;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
cxx_win = MPI::Win::mpi_win_map[win];
copy_and_delete = MPI::Win::mpi_win_key_fn_map[keyval];
delete_fn = copy_and_delete->second;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
ret = delete_fn(*cxx_win, keyval, attribute_val, extra_state);
return ret;
}
// For similar reasons as above, we need to intercept calls for the 3
// generalized request callbacks (convert arguments to C++ types and
// invoke the C++ callback signature).

Просмотреть файл

@ -25,6 +25,11 @@ static const int ompi_stdio_seek_end = SEEK_END;
#include "mpicxx.h"
/* Need to include ompi_config.h after mpicxx.h... */
#include "ompi_config.h"
#include "ompi/errhandler/errhandler.h"
#if OMPI_WANT_MPI_CXX_SEEK
const int SEEK_SET = ompi_stdio_seek_set;
@ -93,11 +98,9 @@ const int DISTRIBUTE_NONE = MPI_DISTRIBUTE_NONE;
const int DISTRIBUTE_DFLT_DARG = MPI_DISTRIBUTE_DFLT_DARG;
// error-handling specifiers
const Errhandler ERRORS_ARE_FATAL(MPI_ERRORS_ARE_FATAL);
const Errhandler ERRORS_RETURN(MPI_ERRORS_RETURN);
const Errhandler ERRORS_THROW_EXCEPTIONS(MPI_ERRORS_RETURN);
//JGS: the MPI_ERRORS_RETURN function in ERRORS_THROW_EXCEPTIONS gets replaced
//by the throw_exptn_fctn in Init)
const Errhandler ERRORS_ARE_FATAL(&ompi_mpi_errors_are_fatal);
const Errhandler ERRORS_RETURN(&ompi_mpi_errors_return);
const Errhandler ERRORS_THROW_EXCEPTIONS(&ompi_mpi_errors_throw_exceptions);
// typeclass definitions for MPI_Type_match_size
const int TYPECLASS_INTEGER = MPI_TYPECLASS_INTEGER;

Просмотреть файл

@ -70,26 +70,42 @@ extern "C" void
ompi_mpi_cxx_op_intercept(void *invec, void *outvec, int *len,
MPI_Datatype *datatype, MPI_User_function *fn);
//JGS: this is used as the MPI_Handler_function for
// the mpi_errhandler in ERRORS_THROW_EXCEPTIONS
extern "C" void
ompi_mpi_cxx_throw_excptn_fctn(MPI_Comm* comm, int* errcode, ...);
ompi_mpi_cxx_comm_errhandler_intercept(MPI_Comm * mpi_comm, int * err, ...);
extern "C" void
ompi_mpi_cxx_errhandler_intercept(MPI_Comm * mpi_comm, int * err, ...);
ompi_mpi_cxx_win_errhandler_intercept(MPI_Win * mpi_comm, int * err, ...);
extern "C" void
ompi_mpi_cxx_file_errhandler_intercept(MPI_File * mpi_comm, int * err, ...);
//used for attr intercept functions
enum CommType { eIntracomm, eIntercomm, eCartcomm, eGraphcomm};
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);
ompi_mpi_cxx_comm_copy_attr_intercept(MPI_Comm oldcomm, int keyval,
void *extra_state, void *attribute_val_in,
void *attribute_val_out, int *flag);
extern "C" int
ompi_mpi_cxx_comm_delete_attr_intercept(MPI_Comm comm, int keyval,
void *attribute_val, void *extra_state);
extern "C" int
ompi_mpi_cxx_delete_attr_intercept(MPI_Comm comm, int keyval,
void *attribute_val, void *extra_state);
ompi_mpi_cxx_type_copy_attr_intercept(MPI_Datatype oldtype, int keyval,
void *extra_state, void *attribute_val_in,
void *attribute_val_out, int *flag);
extern "C" int
ompi_mpi_cxx_type_delete_attr_intercept(MPI_Datatype type, int keyval,
void *attribute_val, void *extra_state);
extern "C" int
ompi_mpi_cxx_win_copy_attr_intercept(MPI_Win oldwin, int keyval,
void *extra_state, void *attribute_val_in,
void *attribute_val_out, int *flag);
extern "C" int
ompi_mpi_cxx_win_delete_attr_intercept(MPI_Win win, int keyval,
void *attribute_val, void *extra_state);
//
// MPI generalized request intercepts
@ -155,14 +171,15 @@ namespace MPI {
#include "ompi/mpi/cxx/request.h" //includes class Prequest
#include "ompi/mpi/cxx/group.h"
#include "ompi/mpi/cxx/comm.h"
#include "ompi/mpi/cxx/win.h"
#include "ompi/mpi/cxx/file.h"
#include "ompi/mpi/cxx/errhandler.h"
#include "ompi/mpi/cxx/intracomm.h"
#include "ompi/mpi/cxx/topology.h" //includes Cartcomm and Graphcomm
#include "ompi/mpi/cxx/intercomm.h"
#include "ompi/mpi/cxx/info.h"
#include "ompi/mpi/cxx/win.h"
#include "ompi/mpi/cxx/file.h"
extern opal_mutex_t *mpi_map_mutex;
}
#if 0 /* OMPI_ENABLE_MPI_PROFILING */

77
ompi/mpi/cxx/win.cc Обычный файл
Просмотреть файл

@ -0,0 +1,77 @@
// -*- c++ -*-
//
// Copyright (c) 2006 Los Alamos National Security, LLC. All rights
// reserved.
// $COPYRIGHT$
//
// Additional copyrights may follow
//
// $HEADER$
//
// do not include ompi_config.h because it kills the free/malloc defines
#include "mpi.h"
#include "ompi/mpi/cxx/mpicxx.h"
#include "opal/threads/mutex.h"
void
MPI::Win::Free()
{
MPI_Win save = mpi_win;
(void) MPI_Win_free(&mpi_win);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Win::mpi_win_map.erase(save);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}
void
MPI::Win::Set_errhandler(const MPI::Errhandler& errhandler)
{
my_errhandler = (MPI::Errhandler *)&errhandler;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Win::mpi_win_map[mpi_win] = this;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
(void)MPI_Win_set_errhandler(mpi_win, errhandler);
}
int
MPI::Win::Create_keyval(MPI::Win::Copy_attr_function* win_copy_attr_fn,
MPI::Win::Delete_attr_function* win_delete_attr_fn,
void* extra_state)
{
int keyval;
(void) MPI_Win_create_keyval(ompi_mpi_cxx_win_copy_attr_intercept,
ompi_mpi_cxx_win_delete_attr_intercept,
&keyval, extra_state);
key_pair_t* copy_and_delete =
new key_pair_t(win_copy_attr_fn, win_delete_attr_fn);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Win::mpi_win_key_fn_map[keyval] = copy_and_delete;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
return keyval;
}
void
MPI::Win::Free_keyval(int& win_keyval)
{
int save = win_keyval;
(void) MPI_Win_free_keyval(&win_keyval);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::Win::mpi_win_key_fn_map.erase(save);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}
void
MPI::Win::Set_attr(int win_keyval, const void* attribute_val)
{
(void) MPI_Win_set_attr(mpi_win, win_keyval, const_cast<void *>(attribute_val));
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
if (MPI::Win::mpi_win_map[mpi_win] == 0) {
MPI::Win::mpi_win_map[mpi_win] = (Win*) this;
}
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}

Просмотреть файл

@ -158,6 +158,15 @@ public:
virtual void Set_attr(int win_keyval, const void* attribute_val);
virtual void Set_name(const char* win_name);
Errhandler* my_errhandler;
typedef ::std::map<MPI_Win, Win*> mpi_win_map_t;
static mpi_win_map_t mpi_win_map;
typedef ::std::pair<Win::Copy_attr_function*, Win::Delete_attr_function*> key_pair_t;
typedef ::std::map<int, key_pair_t*> mpi_win_key_fn_map_t;
static mpi_win_key_fn_map_t mpi_win_key_fn_map;
protected:
#if 0 /* OMPI_ENABLE_MPI_PROFILING */

Просмотреть файл

@ -28,25 +28,18 @@ inline MPI::Errhandler
MPI::Win::Create_errhandler(MPI::Win::Errhandler_fn* function)
{
MPI_Errhandler errhandler;
(void) MPI_Win_create_errhandler((MPI_Win_errhandler_fn *)function,
(void) MPI_Win_create_errhandler((MPI_Win_errhandler_fn *) ompi_mpi_cxx_win_errhandler_intercept,
&errhandler);
return errhandler;
MPI::Errhandler temp(errhandler);
temp.win_handler_fn = (void(*)(MPI::Win&, int* , ...)) function;
return temp;
}
inline MPI::Errhandler
MPI::Win:: Get_errhandler() const
{
MPI_Errhandler errhandler;
(void) MPI_Win_get_errhandler(mpi_win, &errhandler);
return errhandler;
}
inline void
MPI::Win::Set_errhandler(const MPI::Errhandler& errhandler)
{
(void) MPI_Win_set_errhandler(mpi_win, errhandler);
return *my_errhandler;
}
@ -94,13 +87,6 @@ MPI::Win::Fence(int assert) const
}
inline void
MPI::Win::Free()
{
(void) MPI_Win_free(&mpi_win);
}
inline void
MPI::Win::Get(const void *origin_addr, int origin_count,
const MPI::Datatype& origin_datatype,
@ -194,19 +180,6 @@ MPI::Win::Call_errhandler(int errorcode) const
}
inline int
MPI::Win::Create_keyval(MPI::Win::Copy_attr_function*
win_copy_attr_fn,
MPI::Win::Delete_attr_function*
win_delete_attr_fn, void* extra_state)
{
int val;
(void) MPI_Win_create_keyval((MPI_Win_copy_attr_function *)win_copy_attr_fn,
(MPI_Win_delete_attr_function *)
win_delete_attr_fn, &val,extra_state);
return val;
}
inline void
MPI::Win::Delete_attr(int win_keyval)
@ -215,13 +188,6 @@ MPI::Win::Delete_attr(int win_keyval)
}
inline void
MPI::Win::Free_keyval(int& win_keyval)
{
(void) MPI_Win_free_keyval(&win_keyval);
}
inline bool
MPI::Win::Get_attr(const Win& win, int win_keyval,
void* attribute_val) const
@ -239,12 +205,6 @@ MPI::Win::Get_name(char* win_name, int& resultlen) const
}
inline void
MPI::Win::Set_attr(int win_keyval, const void* attribute_val)
{
(void) MPI_Win_set_attr(mpi_win, win_keyval, const_cast<void *>(attribute_val));
}
inline void
MPI::Win::Set_name(const char* win_name)
@ -252,24 +212,3 @@ MPI::Win::Set_name(const char* win_name)
(void) MPI_Win_set_name(mpi_win, const_cast<char *>(win_name));
}
#if 0
//
// User defined functions
//
typedef int MPI::Win::Copy_attr_function(const Win& oldwin,
int win_keyval,
void* extra_state,
void* attribute_val_in,
void* attribute_val_out,
bool& flag);
typedef int MPI::Win::Delete_attr_function(&win, int win_keyval,
void* attribute_val,
void* extra_state);
typedef void MPI::Win::Errhandler_fn(Win &, int *, ... );
#endif