2004-07-14 18:11:03 +04:00
|
|
|
// -*- c++ -*-
|
|
|
|
//
|
2005-11-05 22:57:48 +03:00
|
|
|
// Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
|
|
|
// University Research and Technology
|
|
|
|
// Corporation. All rights reserved.
|
|
|
|
// Copyright (c) 2004-2005 The University of Tennessee and The University
|
|
|
|
// of Tennessee Research Foundation. All rights
|
|
|
|
// reserved.
|
2004-11-28 23:09:25 +03:00
|
|
|
// Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
|
|
// University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
// Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
// All rights reserved.
|
Fixes trac:817
The C++ bindings were not tracking keyvals properly -- they were
freeing some internal meta data when Free_keyval() was called, not
when the keyval was actually destroyed (keyvals are refcounted in the
C layer, just like all other MPI objects, because they can live for
long after their corresponding Free call is invoked). This commit
fixes this problem and several other things:
* Add infrastructure on the ompi_attribute_keyval_t for an "extra"
destructor pointer that will be invoked during the "real"
constructor (i.e., when OBJ_RELEASE puts the refcount to 0). This
allows calling back into the C++ layer to release meta data
associated with the keyval.
* Adjust all cases where keyvals are created to pass in relevant
destructors (NULL or the C++ destructor).
* Do essentially the same for MPI::Comm, MPI::Win, and MPI:Datatype:
* Move several functions out of the .cc file into the _inln.h file
since they no longer require locks
* Make the 4 Create_keyval() functions call a common back-end
keyval creation function that does the Right Thing depending on
whether C or C++ function pointers were used for the keyval
functions. The back-end function does not call the corresponding
C MPI_*_create_keyval function, but rather does the work itself
so that it can associate a "destructor" callback for the C++
bindings for when the keyval is actually destroyed.
* Change a few type names to be more indicative of what they are
(mostly dealing with keyvals [not "keys"]).
* Add the 3 missing bindings for MPI::Comm::Create_keyval().
* Remove MPI::Comm::comm_map (and associated types) because it's no
longer necessary in the intercepts -- it was a by-product of being
a portable C++ bindings layer. Now we can just query the C layer
directly to figure out what type a communicator is. This solves
some logistics / callback issues, too.
* Rename several types, variables, and fix many comments in the
back-end C attribute implementation to make the names really
reflect what they are (keyvals vs. attributes). The previous names
heavily overloaded the name "key" and were ''extremely''
confusing.
This commit was SVN r13565.
The following Trac tickets were found above:
Ticket 817 --> https://svn.open-mpi.org/trac/ompi/ticket/817
2007-02-09 02:50:04 +03:00
|
|
|
// Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
// $COPYRIGHT$
|
|
|
|
//
|
|
|
|
// Additional copyrights may follow
|
|
|
|
//
|
2004-07-14 18:11:03 +04:00
|
|
|
// $HEADER$
|
|
|
|
//
|
|
|
|
|
|
|
|
class Comm_Null {
|
|
|
|
#if 0 /* OMPI_ENABLE_MPI_PROFILING */
|
|
|
|
// friend class PMPI::Comm_Null;
|
|
|
|
#endif
|
|
|
|
public:
|
|
|
|
|
|
|
|
#if 0 /* OMPI_ENABLE_MPI_PROFILING */
|
|
|
|
|
|
|
|
// construction
|
|
|
|
inline Comm_Null() { }
|
|
|
|
// copy
|
|
|
|
inline Comm_Null(const Comm_Null& data) : pmpi_comm(data.pmpi_comm) { }
|
|
|
|
// inter-language operability
|
This is a workaround to bug in the Intel C++ compiler, version 9.1
(all versions up to and including 20060925). The issue has been
reported to Intel, along with a small [non-MPI] test program that
reproduces the problem (the test program and the OMPI C++ bindings
work fine with Intel C++ 9.0 and many other C++ compilers).
In short, a static initializer for a global variable (i.e., its
constructor is fired before main()) that takes as an argument a
reference to a typedef'd type will simply get the wrong value in the
argument. Specifically:
{{{
namespace MPI {
Intracomm COMM_WORLD(MPI_COMM_WORLD);
}
}}}
The constructor for MPI::Intracomm should get the value of
&ompi_mpi_comm_world. It does not; it seems to get a random value.
As mandated by MPI-2, annex B.13.4, for C/C++ interoperability, the
prototype for this constructor is:
{{{
class Intracomm {
public:
Intracomm(const MPI_Comm& data);
};
}}}
Experiments with icpc 9.1/20060925 have shown that removing the
reference from the prototype makes it work (!). After lots of
discussions about this issue with a C++ expert (Doug Gregor from IU),
we decided the following (cut-n-paste from an e-mail):
-----
> So here's my question: given that OMPI's MPI_<CLASS> types are all
> pointers, is there any legal MPI program that adheres to the above
> bindings that would fail to compile or work properly if we simply
> removed the "&" from the second binding, above?
I don't know of any way that a program could detect this change. FWIW,
the C++ committee has agreed that implementation of the C++ standard
library are allowed to decide arbitrarily between const& and by-value.
If they don't care, MPI users won't care.
When you remove the '&', I suggest also removing the "const". It is
redundant, but can trigger some strange name mangling in Sun's C++
compiler.
-----
So with this change:
* we now work again with the Intel 9.1 compiler
* our C++ bindings do not exactly conform to the MPI-2 spec, but
valid/legal MPI C++ apps cannot tell the difference (i.e., the
functionality is the same)
This commit was SVN r12514.
2006-11-09 20:34:12 +03:00
|
|
|
inline Comm_Null(MPI_Comm data) : pmpi_comm(data) { }
|
2004-07-14 18:11:03 +04:00
|
|
|
|
|
|
|
inline Comm_Null(const PMPI::Comm_Null& data) : pmpi_comm(data) { }
|
|
|
|
|
|
|
|
// destruction
|
2004-09-28 22:40:24 +04:00
|
|
|
virtual inline ~Comm_Null() { }
|
2004-07-14 18:11:03 +04:00
|
|
|
|
|
|
|
inline Comm_Null& operator=(const Comm_Null& data) {
|
|
|
|
pmpi_comm = data.pmpi_comm;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// comparison
|
|
|
|
inline bool operator==(const Comm_Null& data) const {
|
|
|
|
return (bool) (pmpi_comm == data.pmpi_comm); }
|
|
|
|
|
|
|
|
inline bool operator!=(const Comm_Null& data) const {
|
|
|
|
return (bool) (pmpi_comm != data.pmpi_comm);}
|
|
|
|
|
|
|
|
// inter-language operability (conversion operators)
|
|
|
|
inline operator MPI_Comm() const { return pmpi_comm; }
|
|
|
|
// inline operator MPI_Comm*() /*const JGS*/ { return pmpi_comm; }
|
|
|
|
inline operator const PMPI::Comm_Null&() const { return pmpi_comm; }
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
// construction
|
|
|
|
inline Comm_Null() : mpi_comm(MPI_COMM_NULL) { }
|
|
|
|
// copy
|
|
|
|
inline Comm_Null(const Comm_Null& data) : mpi_comm(data.mpi_comm) { }
|
|
|
|
// inter-language operability
|
This is a workaround to bug in the Intel C++ compiler, version 9.1
(all versions up to and including 20060925). The issue has been
reported to Intel, along with a small [non-MPI] test program that
reproduces the problem (the test program and the OMPI C++ bindings
work fine with Intel C++ 9.0 and many other C++ compilers).
In short, a static initializer for a global variable (i.e., its
constructor is fired before main()) that takes as an argument a
reference to a typedef'd type will simply get the wrong value in the
argument. Specifically:
{{{
namespace MPI {
Intracomm COMM_WORLD(MPI_COMM_WORLD);
}
}}}
The constructor for MPI::Intracomm should get the value of
&ompi_mpi_comm_world. It does not; it seems to get a random value.
As mandated by MPI-2, annex B.13.4, for C/C++ interoperability, the
prototype for this constructor is:
{{{
class Intracomm {
public:
Intracomm(const MPI_Comm& data);
};
}}}
Experiments with icpc 9.1/20060925 have shown that removing the
reference from the prototype makes it work (!). After lots of
discussions about this issue with a C++ expert (Doug Gregor from IU),
we decided the following (cut-n-paste from an e-mail):
-----
> So here's my question: given that OMPI's MPI_<CLASS> types are all
> pointers, is there any legal MPI program that adheres to the above
> bindings that would fail to compile or work properly if we simply
> removed the "&" from the second binding, above?
I don't know of any way that a program could detect this change. FWIW,
the C++ committee has agreed that implementation of the C++ standard
library are allowed to decide arbitrarily between const& and by-value.
If they don't care, MPI users won't care.
When you remove the '&', I suggest also removing the "const". It is
redundant, but can trigger some strange name mangling in Sun's C++
compiler.
-----
So with this change:
* we now work again with the Intel 9.1 compiler
* our C++ bindings do not exactly conform to the MPI-2 spec, but
valid/legal MPI C++ apps cannot tell the difference (i.e., the
functionality is the same)
This commit was SVN r12514.
2006-11-09 20:34:12 +03:00
|
|
|
inline Comm_Null(MPI_Comm data) : mpi_comm(data) { }
|
2004-07-14 18:11:03 +04:00
|
|
|
|
|
|
|
// destruction
|
2005-06-11 01:02:52 +04:00
|
|
|
virtual inline ~Comm_Null() { }
|
2004-07-14 18:11:03 +04:00
|
|
|
|
|
|
|
// comparison
|
|
|
|
// JGS make sure this is right (in other classes too)
|
|
|
|
inline bool operator==(const Comm_Null& data) const {
|
|
|
|
return (bool) (mpi_comm == data.mpi_comm); }
|
|
|
|
|
|
|
|
inline bool operator!=(const Comm_Null& data) const {
|
|
|
|
return (bool) !(*this == data);}
|
|
|
|
|
|
|
|
// inter-language operability (conversion operators)
|
|
|
|
inline operator MPI_Comm() const { return mpi_comm; }
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
#if 0 /* OMPI_ENABLE_MPI_PROFILING */
|
|
|
|
PMPI::Comm_Null pmpi_comm;
|
|
|
|
#else
|
|
|
|
MPI_Comm mpi_comm;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Comm : public Comm_Null {
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef void Errhandler_fn(Comm&, int*, ...);
|
|
|
|
typedef int Copy_attr_function(const Comm& oldcomm, int comm_keyval,
|
|
|
|
void* extra_state, void* attribute_val_in,
|
|
|
|
void* attribute_val_out,
|
|
|
|
bool& flag);
|
|
|
|
typedef int Delete_attr_function(Comm& comm, int comm_keyval,
|
|
|
|
void* attribute_val,
|
|
|
|
void* extra_state);
|
|
|
|
#if !0 /* OMPI_ENABLE_MPI_PROFILING */
|
|
|
|
#define _MPI2CPP_ERRHANDLERFN_ Errhandler_fn
|
|
|
|
#define _MPI2CPP_COPYATTRFN_ Copy_attr_function
|
|
|
|
#define _MPI2CPP_DELETEATTRFN_ Delete_attr_function
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// construction
|
|
|
|
Comm();
|
|
|
|
|
|
|
|
// copy
|
|
|
|
Comm(const Comm_Null& data);
|
|
|
|
|
|
|
|
#if 0 /* OMPI_ENABLE_MPI_PROFILING */
|
|
|
|
Comm(const Comm& data) :
|
|
|
|
Comm_Null(data),
|
|
|
|
pmpi_comm((const PMPI::Comm&) data) { }
|
|
|
|
|
|
|
|
// inter-language operability
|
This is a workaround to bug in the Intel C++ compiler, version 9.1
(all versions up to and including 20060925). The issue has been
reported to Intel, along with a small [non-MPI] test program that
reproduces the problem (the test program and the OMPI C++ bindings
work fine with Intel C++ 9.0 and many other C++ compilers).
In short, a static initializer for a global variable (i.e., its
constructor is fired before main()) that takes as an argument a
reference to a typedef'd type will simply get the wrong value in the
argument. Specifically:
{{{
namespace MPI {
Intracomm COMM_WORLD(MPI_COMM_WORLD);
}
}}}
The constructor for MPI::Intracomm should get the value of
&ompi_mpi_comm_world. It does not; it seems to get a random value.
As mandated by MPI-2, annex B.13.4, for C/C++ interoperability, the
prototype for this constructor is:
{{{
class Intracomm {
public:
Intracomm(const MPI_Comm& data);
};
}}}
Experiments with icpc 9.1/20060925 have shown that removing the
reference from the prototype makes it work (!). After lots of
discussions about this issue with a C++ expert (Doug Gregor from IU),
we decided the following (cut-n-paste from an e-mail):
-----
> So here's my question: given that OMPI's MPI_<CLASS> types are all
> pointers, is there any legal MPI program that adheres to the above
> bindings that would fail to compile or work properly if we simply
> removed the "&" from the second binding, above?
I don't know of any way that a program could detect this change. FWIW,
the C++ committee has agreed that implementation of the C++ standard
library are allowed to decide arbitrarily between const& and by-value.
If they don't care, MPI users won't care.
When you remove the '&', I suggest also removing the "const". It is
redundant, but can trigger some strange name mangling in Sun's C++
compiler.
-----
So with this change:
* we now work again with the Intel 9.1 compiler
* our C++ bindings do not exactly conform to the MPI-2 spec, but
valid/legal MPI C++ apps cannot tell the difference (i.e., the
functionality is the same)
This commit was SVN r12514.
2006-11-09 20:34:12 +03:00
|
|
|
Comm(MPI_Comm data) : Comm_Null(data), pmpi_comm(data) { }
|
2004-07-14 18:11:03 +04:00
|
|
|
|
|
|
|
Comm(const PMPI::Comm& data) :
|
|
|
|
Comm_Null((const PMPI::Comm_Null&)data),
|
|
|
|
pmpi_comm(data) { }
|
|
|
|
|
|
|
|
operator const PMPI::Comm&() const { return pmpi_comm; }
|
|
|
|
|
|
|
|
// assignment
|
|
|
|
Comm& operator=(const Comm& data) {
|
|
|
|
this->Comm_Null::operator=(data);
|
|
|
|
pmpi_comm = data.pmpi_comm;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
Comm& operator=(const Comm_Null& data) {
|
|
|
|
this->Comm_Null::operator=(data);
|
|
|
|
MPI_Comm tmp = data;
|
|
|
|
pmpi_comm = tmp;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
// inter-language operability
|
|
|
|
Comm& operator=(const MPI_Comm& data) {
|
|
|
|
this->Comm_Null::operator=(data);
|
|
|
|
pmpi_comm = data;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
Comm(const Comm& data) : Comm_Null(data.mpi_comm) { }
|
|
|
|
// inter-language operability
|
This is a workaround to bug in the Intel C++ compiler, version 9.1
(all versions up to and including 20060925). The issue has been
reported to Intel, along with a small [non-MPI] test program that
reproduces the problem (the test program and the OMPI C++ bindings
work fine with Intel C++ 9.0 and many other C++ compilers).
In short, a static initializer for a global variable (i.e., its
constructor is fired before main()) that takes as an argument a
reference to a typedef'd type will simply get the wrong value in the
argument. Specifically:
{{{
namespace MPI {
Intracomm COMM_WORLD(MPI_COMM_WORLD);
}
}}}
The constructor for MPI::Intracomm should get the value of
&ompi_mpi_comm_world. It does not; it seems to get a random value.
As mandated by MPI-2, annex B.13.4, for C/C++ interoperability, the
prototype for this constructor is:
{{{
class Intracomm {
public:
Intracomm(const MPI_Comm& data);
};
}}}
Experiments with icpc 9.1/20060925 have shown that removing the
reference from the prototype makes it work (!). After lots of
discussions about this issue with a C++ expert (Doug Gregor from IU),
we decided the following (cut-n-paste from an e-mail):
-----
> So here's my question: given that OMPI's MPI_<CLASS> types are all
> pointers, is there any legal MPI program that adheres to the above
> bindings that would fail to compile or work properly if we simply
> removed the "&" from the second binding, above?
I don't know of any way that a program could detect this change. FWIW,
the C++ committee has agreed that implementation of the C++ standard
library are allowed to decide arbitrarily between const& and by-value.
If they don't care, MPI users won't care.
When you remove the '&', I suggest also removing the "const". It is
redundant, but can trigger some strange name mangling in Sun's C++
compiler.
-----
So with this change:
* we now work again with the Intel 9.1 compiler
* our C++ bindings do not exactly conform to the MPI-2 spec, but
valid/legal MPI C++ apps cannot tell the difference (i.e., the
functionality is the same)
This commit was SVN r12514.
2006-11-09 20:34:12 +03:00
|
|
|
Comm(MPI_Comm data) : Comm_Null(data) { }
|
2004-07-14 18:11:03 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Point-to-Point
|
|
|
|
//
|
|
|
|
|
|
|
|
virtual void Send(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest, int tag) const;
|
|
|
|
|
|
|
|
virtual void Recv(void *buf, int count, const Datatype & datatype,
|
|
|
|
int source, int tag, Status & status) const;
|
|
|
|
|
|
|
|
|
|
|
|
virtual void Recv(void *buf, int count, const Datatype & datatype,
|
|
|
|
int source, int tag) const;
|
|
|
|
|
|
|
|
virtual void Bsend(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest, int tag) const;
|
|
|
|
|
|
|
|
virtual void Ssend(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest, int tag) const ;
|
|
|
|
|
|
|
|
virtual void Rsend(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest, int tag) const;
|
|
|
|
|
|
|
|
virtual Request Isend(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest, int tag) const;
|
|
|
|
|
|
|
|
virtual Request Ibsend(const void *buf, int count, const
|
|
|
|
Datatype & datatype, int dest, int tag) const;
|
|
|
|
|
|
|
|
virtual Request Issend(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest, int tag) const;
|
|
|
|
|
|
|
|
virtual Request Irsend(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest, int tag) const;
|
|
|
|
|
|
|
|
virtual Request Irecv(void *buf, int count,
|
|
|
|
const Datatype & datatype, int source, int tag) const;
|
|
|
|
|
|
|
|
virtual bool Iprobe(int source, int tag, Status & status) const;
|
|
|
|
|
|
|
|
virtual bool Iprobe(int source, int tag) const;
|
|
|
|
|
|
|
|
virtual void Probe(int source, int tag, Status & status) const;
|
|
|
|
|
|
|
|
virtual void Probe(int source, int tag) const;
|
|
|
|
|
|
|
|
virtual Prequest Send_init(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest,
|
|
|
|
int tag) const;
|
|
|
|
|
|
|
|
virtual Prequest Bsend_init(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest,
|
|
|
|
int tag) const;
|
|
|
|
|
|
|
|
virtual Prequest Ssend_init(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest,
|
|
|
|
int tag) const;
|
|
|
|
|
|
|
|
virtual Prequest Rsend_init(const void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest,
|
|
|
|
int tag) const;
|
|
|
|
|
|
|
|
virtual Prequest Recv_init(void *buf, int count,
|
|
|
|
const Datatype & datatype, int source,
|
|
|
|
int tag) const;
|
|
|
|
|
|
|
|
virtual void Sendrecv(const void *sendbuf, int sendcount,
|
|
|
|
const Datatype & sendtype, int dest, int sendtag,
|
|
|
|
void *recvbuf, int recvcount,
|
|
|
|
const Datatype & recvtype, int source,
|
|
|
|
int recvtag, Status & status) const;
|
|
|
|
|
|
|
|
virtual void Sendrecv(const void *sendbuf, int sendcount,
|
|
|
|
const Datatype & sendtype, int dest, int sendtag,
|
|
|
|
void *recvbuf, int recvcount,
|
|
|
|
const Datatype & recvtype, int source,
|
|
|
|
int recvtag) const;
|
|
|
|
|
|
|
|
virtual void Sendrecv_replace(void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest,
|
|
|
|
int sendtag, int source,
|
|
|
|
int recvtag, Status & status) const;
|
|
|
|
|
|
|
|
virtual void Sendrecv_replace(void *buf, int count,
|
|
|
|
const Datatype & datatype, int dest,
|
|
|
|
int sendtag, int source,
|
|
|
|
int recvtag) const;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Groups, Contexts, and Communicators
|
|
|
|
//
|
|
|
|
|
|
|
|
virtual Group Get_group() const;
|
|
|
|
|
|
|
|
virtual int Get_size() const;
|
|
|
|
|
|
|
|
virtual int Get_rank() const;
|
|
|
|
|
|
|
|
static int Compare(const Comm & comm1, const Comm & comm2);
|
|
|
|
|
|
|
|
virtual Comm& Clone() const = 0;
|
|
|
|
|
|
|
|
virtual void Free(void);
|
|
|
|
|
|
|
|
virtual bool Is_inter() const;
|
|
|
|
|
|
|
|
|
2005-12-22 00:12:52 +03:00
|
|
|
//
|
|
|
|
// Collective Communication
|
|
|
|
//
|
|
|
|
// Up in Comm because as of MPI-2, they are common to intracomm and
|
|
|
|
// intercomm -- with the exception of Scan and Exscan, which are not
|
|
|
|
// defined on intercomms.
|
|
|
|
//
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Barrier() const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Bcast(void *buffer, int count,
|
|
|
|
const Datatype& datatype, int root) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Gather(const void *sendbuf, int sendcount,
|
|
|
|
const Datatype & sendtype,
|
|
|
|
void *recvbuf, int recvcount,
|
|
|
|
const Datatype & recvtype, int root) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Gatherv(const void *sendbuf, int sendcount,
|
|
|
|
const Datatype & sendtype, void *recvbuf,
|
|
|
|
const int recvcounts[], const int displs[],
|
|
|
|
const Datatype & recvtype, int root) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Scatter(const void *sendbuf, int sendcount,
|
|
|
|
const Datatype & sendtype,
|
|
|
|
void *recvbuf, int recvcount,
|
|
|
|
const Datatype & recvtype, int root) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Scatterv(const void *sendbuf, const int sendcounts[],
|
|
|
|
const int displs[], const Datatype & sendtype,
|
|
|
|
void *recvbuf, int recvcount,
|
|
|
|
const Datatype & recvtype, int root) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Allgather(const void *sendbuf, int sendcount,
|
|
|
|
const Datatype & sendtype, void *recvbuf,
|
|
|
|
int recvcount, const Datatype & recvtype) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Allgatherv(const void *sendbuf, int sendcount,
|
|
|
|
const Datatype & sendtype, void *recvbuf,
|
|
|
|
const int recvcounts[], const int displs[],
|
|
|
|
const Datatype & recvtype) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Alltoall(const void *sendbuf, int sendcount,
|
|
|
|
const Datatype & sendtype, void *recvbuf,
|
|
|
|
int recvcount, const Datatype & recvtype) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Alltoallv(const void *sendbuf, const int sendcounts[],
|
|
|
|
const int sdispls[], const Datatype & sendtype,
|
|
|
|
void *recvbuf, const int recvcounts[],
|
|
|
|
const int rdispls[], const Datatype & recvtype) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Alltoallw(const void *sendbuf, const int sendcounts[],
|
|
|
|
const int sdispls[], const Datatype sendtypes[],
|
|
|
|
void *recvbuf, const int recvcounts[],
|
|
|
|
const int rdispls[], const Datatype recvtypes[]) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Reduce(const void *sendbuf, void *recvbuf, int count,
|
|
|
|
const Datatype & datatype, const Op & op,
|
|
|
|
int root) const;
|
|
|
|
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Allreduce(const void *sendbuf, void *recvbuf, int count,
|
|
|
|
const Datatype & datatype, const Op & op) const;
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
Reduce_scatter(const void *sendbuf, void *recvbuf,
|
|
|
|
int recvcounts[],
|
|
|
|
const Datatype & datatype,
|
|
|
|
const Op & op) const;
|
|
|
|
|
2004-07-14 18:11:03 +04:00
|
|
|
//
|
|
|
|
// Process Creation
|
|
|
|
//
|
|
|
|
|
|
|
|
virtual void Disconnect();
|
|
|
|
|
|
|
|
static Intercomm Get_parent();
|
|
|
|
|
|
|
|
static Intercomm Join(const int fd);
|
|
|
|
|
|
|
|
//
|
2005-12-22 00:12:52 +03:00
|
|
|
// External Interfaces
|
2004-07-14 18:11:03 +04:00
|
|
|
//
|
|
|
|
|
|
|
|
virtual void Get_name(char * comm_name, int& resultlen) const;
|
|
|
|
|
|
|
|
virtual void Set_name(const char* comm_name);
|
|
|
|
|
|
|
|
//
|
2005-12-22 00:12:52 +03:00
|
|
|
// Process Topologies
|
2004-07-14 18:11:03 +04:00
|
|
|
//
|
|
|
|
|
|
|
|
virtual int Get_topology() const;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Environmental Inquiry
|
|
|
|
//
|
|
|
|
|
|
|
|
virtual void Abort(int errorcode);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Errhandler
|
|
|
|
//
|
|
|
|
|
|
|
|
virtual void Set_errhandler(const Errhandler& errhandler);
|
|
|
|
|
|
|
|
virtual Errhandler Get_errhandler() const;
|
|
|
|
|
|
|
|
//JGS took out const below from fn arg
|
|
|
|
static Errhandler Create_errhandler(Comm::Errhandler_fn* function);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Keys and Attributes
|
|
|
|
//
|
|
|
|
|
Fixes trac:817
The C++ bindings were not tracking keyvals properly -- they were
freeing some internal meta data when Free_keyval() was called, not
when the keyval was actually destroyed (keyvals are refcounted in the
C layer, just like all other MPI objects, because they can live for
long after their corresponding Free call is invoked). This commit
fixes this problem and several other things:
* Add infrastructure on the ompi_attribute_keyval_t for an "extra"
destructor pointer that will be invoked during the "real"
constructor (i.e., when OBJ_RELEASE puts the refcount to 0). This
allows calling back into the C++ layer to release meta data
associated with the keyval.
* Adjust all cases where keyvals are created to pass in relevant
destructors (NULL or the C++ destructor).
* Do essentially the same for MPI::Comm, MPI::Win, and MPI:Datatype:
* Move several functions out of the .cc file into the _inln.h file
since they no longer require locks
* Make the 4 Create_keyval() functions call a common back-end
keyval creation function that does the Right Thing depending on
whether C or C++ function pointers were used for the keyval
functions. The back-end function does not call the corresponding
C MPI_*_create_keyval function, but rather does the work itself
so that it can associate a "destructor" callback for the C++
bindings for when the keyval is actually destroyed.
* Change a few type names to be more indicative of what they are
(mostly dealing with keyvals [not "keys"]).
* Add the 3 missing bindings for MPI::Comm::Create_keyval().
* Remove MPI::Comm::comm_map (and associated types) because it's no
longer necessary in the intercepts -- it was a by-product of being
a portable C++ bindings layer. Now we can just query the C layer
directly to figure out what type a communicator is. This solves
some logistics / callback issues, too.
* Rename several types, variables, and fix many comments in the
back-end C attribute implementation to make the names really
reflect what they are (keyvals vs. attributes). The previous names
heavily overloaded the name "key" and were ''extremely''
confusing.
This commit was SVN r13565.
The following Trac tickets were found above:
Ticket 817 --> https://svn.open-mpi.org/trac/ompi/ticket/817
2007-02-09 02:50:04 +03:00
|
|
|
// Need 4 overloaded versions of this function because per the
|
|
|
|
// MPI-2 spec, you can mix-n-match the C predefined functions with
|
|
|
|
// C++ functions.
|
2004-07-14 18:11:03 +04:00
|
|
|
static int Create_keyval(Copy_attr_function* comm_copy_attr_fn,
|
Fixes trac:817
The C++ bindings were not tracking keyvals properly -- they were
freeing some internal meta data when Free_keyval() was called, not
when the keyval was actually destroyed (keyvals are refcounted in the
C layer, just like all other MPI objects, because they can live for
long after their corresponding Free call is invoked). This commit
fixes this problem and several other things:
* Add infrastructure on the ompi_attribute_keyval_t for an "extra"
destructor pointer that will be invoked during the "real"
constructor (i.e., when OBJ_RELEASE puts the refcount to 0). This
allows calling back into the C++ layer to release meta data
associated with the keyval.
* Adjust all cases where keyvals are created to pass in relevant
destructors (NULL or the C++ destructor).
* Do essentially the same for MPI::Comm, MPI::Win, and MPI:Datatype:
* Move several functions out of the .cc file into the _inln.h file
since they no longer require locks
* Make the 4 Create_keyval() functions call a common back-end
keyval creation function that does the Right Thing depending on
whether C or C++ function pointers were used for the keyval
functions. The back-end function does not call the corresponding
C MPI_*_create_keyval function, but rather does the work itself
so that it can associate a "destructor" callback for the C++
bindings for when the keyval is actually destroyed.
* Change a few type names to be more indicative of what they are
(mostly dealing with keyvals [not "keys"]).
* Add the 3 missing bindings for MPI::Comm::Create_keyval().
* Remove MPI::Comm::comm_map (and associated types) because it's no
longer necessary in the intercepts -- it was a by-product of being
a portable C++ bindings layer. Now we can just query the C layer
directly to figure out what type a communicator is. This solves
some logistics / callback issues, too.
* Rename several types, variables, and fix many comments in the
back-end C attribute implementation to make the names really
reflect what they are (keyvals vs. attributes). The previous names
heavily overloaded the name "key" and were ''extremely''
confusing.
This commit was SVN r13565.
The following Trac tickets were found above:
Ticket 817 --> https://svn.open-mpi.org/trac/ompi/ticket/817
2007-02-09 02:50:04 +03:00
|
|
|
Delete_attr_function* comm_delete_attr_fn,
|
|
|
|
void* extra_state);
|
|
|
|
static int Create_keyval(MPI_Comm_copy_attr_function* comm_copy_attr_fn,
|
|
|
|
MPI_Comm_delete_attr_function* comm_delete_attr_fn,
|
|
|
|
void* extra_state);
|
|
|
|
static int Create_keyval(Copy_attr_function* comm_copy_attr_fn,
|
|
|
|
MPI_Comm_delete_attr_function* comm_delete_attr_fn,
|
|
|
|
void* extra_state);
|
|
|
|
static int Create_keyval(MPI_Comm_copy_attr_function* comm_copy_attr_fn,
|
|
|
|
Delete_attr_function* comm_delete_attr_fn,
|
|
|
|
void* extra_state);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
static int do_create_keyval(MPI_Comm_copy_attr_function* c_copy_fn,
|
|
|
|
MPI_Comm_delete_attr_function* c_delete_fn,
|
|
|
|
Copy_attr_function* cxx_copy_fn,
|
|
|
|
Delete_attr_function* cxx_delete_fn,
|
|
|
|
void* extra_state);
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2004-07-14 18:11:03 +04:00
|
|
|
static void Free_keyval(int& comm_keyval);
|
|
|
|
|
|
|
|
virtual void Set_attr(int comm_keyval, const void* attribute_val) const;
|
|
|
|
|
|
|
|
virtual bool Get_attr(int comm_keyval, void* attribute_val) const;
|
|
|
|
|
|
|
|
virtual void Delete_attr(int comm_keyval);
|
|
|
|
|
|
|
|
static int NULL_COPY_FN(const Comm& oldcomm, int comm_keyval,
|
|
|
|
void* extra_state, void* attribute_val_in,
|
|
|
|
void* attribute_val_out, bool& flag);
|
|
|
|
|
|
|
|
static int DUP_FN(const Comm& oldcomm, int comm_keyval,
|
|
|
|
void* extra_state, void* attribute_val_in,
|
|
|
|
void* attribute_val_out, bool& flag);
|
|
|
|
|
|
|
|
static int NULL_DELETE_FN(Comm& comm, int comm_keyval, void* attribute_val,
|
|
|
|
void* extra_state);
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
#if 0 /* OMPI_ENABLE_MPI_PROFILING */
|
|
|
|
PMPI::Comm pmpi_comm;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if ! 0 /* OMPI_ENABLE_MPI_PROFILING */
|
|
|
|
public: // JGS hmmm, these used by errhandler_intercept
|
|
|
|
// should make it a friend
|
|
|
|
|
|
|
|
Errhandler* my_errhandler;
|
|
|
|
|
2006-12-31 02:41:42 +03:00
|
|
|
typedef ::std::map<MPI_Comm, Comm*> mpi_comm_err_map_t;
|
|
|
|
static mpi_comm_err_map_t mpi_comm_err_map;
|
2004-07-14 18:11:03 +04:00
|
|
|
|
Fixes trac:817
The C++ bindings were not tracking keyvals properly -- they were
freeing some internal meta data when Free_keyval() was called, not
when the keyval was actually destroyed (keyvals are refcounted in the
C layer, just like all other MPI objects, because they can live for
long after their corresponding Free call is invoked). This commit
fixes this problem and several other things:
* Add infrastructure on the ompi_attribute_keyval_t for an "extra"
destructor pointer that will be invoked during the "real"
constructor (i.e., when OBJ_RELEASE puts the refcount to 0). This
allows calling back into the C++ layer to release meta data
associated with the keyval.
* Adjust all cases where keyvals are created to pass in relevant
destructors (NULL or the C++ destructor).
* Do essentially the same for MPI::Comm, MPI::Win, and MPI:Datatype:
* Move several functions out of the .cc file into the _inln.h file
since they no longer require locks
* Make the 4 Create_keyval() functions call a common back-end
keyval creation function that does the Right Thing depending on
whether C or C++ function pointers were used for the keyval
functions. The back-end function does not call the corresponding
C MPI_*_create_keyval function, but rather does the work itself
so that it can associate a "destructor" callback for the C++
bindings for when the keyval is actually destroyed.
* Change a few type names to be more indicative of what they are
(mostly dealing with keyvals [not "keys"]).
* Add the 3 missing bindings for MPI::Comm::Create_keyval().
* Remove MPI::Comm::comm_map (and associated types) because it's no
longer necessary in the intercepts -- it was a by-product of being
a portable C++ bindings layer. Now we can just query the C layer
directly to figure out what type a communicator is. This solves
some logistics / callback issues, too.
* Rename several types, variables, and fix many comments in the
back-end C attribute implementation to make the names really
reflect what they are (keyvals vs. attributes). The previous names
heavily overloaded the name "key" and were ''extremely''
confusing.
This commit was SVN r13565.
The following Trac tickets were found above:
Ticket 817 --> https://svn.open-mpi.org/trac/ompi/ticket/817
2007-02-09 02:50:04 +03:00
|
|
|
typedef ::std::pair<Comm::_MPI2CPP_COPYATTRFN_*, Comm::_MPI2CPP_DELETEATTRFN_*> keyval_pair_t;
|
|
|
|
typedef ::std::map<int, keyval_pair_t*> mpi_comm_keyval_fn_map_t;
|
|
|
|
static mpi_comm_keyval_fn_map_t mpi_comm_keyval_fn_map;
|
2004-07-14 18:11:03 +04:00
|
|
|
|
|
|
|
void init() {
|
|
|
|
my_errhandler = (Errhandler*)0;
|
|
|
|
}
|
2005-12-16 01:07:34 +03:00
|
|
|
|
2004-07-14 18:11:03 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
};
|