mirror of
https://github.com/boostorg/mpi.git
synced 2026-02-25 04:22:17 +00:00
Merge Boost.MPI datatype fixes from the trunk
[SVN r44414]
This commit is contained in:
@@ -181,7 +181,7 @@ struct is_mpi_datatype
|
||||
template<typename T> MPI_Datatype get_mpi_datatype(const T& x)
|
||||
{
|
||||
BOOST_MPL_ASSERT((is_mpi_datatype<T>));
|
||||
return detail::mpi_datatype_cache.datatype(x);
|
||||
return detail::mpi_datatype_cache().datatype(x);
|
||||
}
|
||||
|
||||
// Don't parse this part when we're generating Doxygen documentation.
|
||||
@@ -252,15 +252,34 @@ BOOST_MPI_DATATYPE(std::pair<BOOST_MPI_LIST2(short, int>), MPI_SHORT_INT,
|
||||
BOOST_MPI_DATATYPE(std::pair<BOOST_MPI_LIST2(int, int>), MPI_2INT, builtin);
|
||||
#undef BOOST_MPI_LIST2
|
||||
|
||||
#if 0
|
||||
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
||||
// Define wchar_t specialization of is_mpi_datatype, if possible.
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && \
|
||||
(defined(MPI_WCHAR) || (defined(MPI_VERSION) && MPI_VERSION >= 2))
|
||||
BOOST_MPI_DATATYPE(wchar_t, MPI_WCHAR, builtin);
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
// Define long long or __int64 specialization of is_mpi_datatype, if possible.
|
||||
#if defined(BOOST_HAS_LONG_LONG) && \
|
||||
(defined(MPI_LONG_LONG_INT) || (defined(MPI_VERSION) && MPI_VERSION >= 2))
|
||||
BOOST_MPI_DATATYPE(long long, MPI_LONG_LONG_INT, builtin);
|
||||
BOOST_MPI_DATATYPE(unsigned long long, MPI_UNSIGNED_LONG_LONG, builtin);
|
||||
#elif defined(BOOST_HAS_MS_INT64) && \
|
||||
(defined(MPI_LONG_LONG_INT) || (defined(MPI_VERSION) && MPI_VERSION >= 2))
|
||||
BOOST_MPI_DATATYPE(__int64, MPI_LONG_LONG_INT, builtin);
|
||||
#endif
|
||||
|
||||
// Define unsigned long long or unsigned __int64 specialization of
|
||||
// is_mpi_datatype, if possible. We separate this from the check for
|
||||
// the (signed) long long/__int64 because some MPI implementations
|
||||
// (e.g., MPICH-MX) have MPI_LONG_LONG_INT but not
|
||||
// MPI_UNSIGNED_LONG_LONG.
|
||||
#if defined(BOOST_HAS_LONG_LONG) && \
|
||||
(defined(MPI_UNSIGNED_LONG_LONG) \
|
||||
|| (defined(MPI_VERSION) && MPI_VERSION >= 2))
|
||||
BOOST_MPI_DATATYPE(unsigned long long, MPI_UNSIGNED_LONG_LONG, builtin);
|
||||
#elif defined(BOOST_HAS_MS_INT64) && \
|
||||
(defined(MPI_UNSIGNED_LONG_LONG) \
|
||||
|| (defined(MPI_VERSION) && MPI_VERSION >= 2))
|
||||
BOOST_MPI_DATATYPE(unsigned __int64, MPI_UNSIGNED_LONG_LONG, builtin);
|
||||
#endif
|
||||
|
||||
#endif // Doxygen
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <map>
|
||||
#include <typeinfo>
|
||||
|
||||
// The std::type_info::before function in Visual C++ 8.0 (and probably earlier)
|
||||
@@ -47,21 +46,15 @@ struct type_info_compare
|
||||
///
|
||||
///
|
||||
class BOOST_MPI_DECL mpi_datatype_map
|
||||
: private std::map<std::type_info const*,MPI_Datatype,type_info_compare>,
|
||||
public boost::noncopyable
|
||||
: public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
mpi_datatype_map()
|
||||
{}
|
||||
struct implementation;
|
||||
|
||||
~mpi_datatype_map()
|
||||
{
|
||||
// do not free after call to MPI_FInalize
|
||||
int finalized=0;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Finalized,(&finalized));
|
||||
if (!finalized)
|
||||
free();
|
||||
}
|
||||
implementation *impl;
|
||||
|
||||
public:
|
||||
mpi_datatype_map();
|
||||
~mpi_datatype_map();
|
||||
|
||||
template <class T>
|
||||
MPI_Datatype datatype(const T& x = T(), typename boost::enable_if<is_mpi_builtin_datatype<T> >::type* =0)
|
||||
@@ -76,30 +69,24 @@ public:
|
||||
|
||||
// check whether the type already exists
|
||||
std::type_info const* t = &typeid(T);
|
||||
const_iterator it = find(t);
|
||||
if(it ==end())
|
||||
{
|
||||
MPI_Datatype datatype = get(t);
|
||||
if (datatype == MPI_DATATYPE_NULL) {
|
||||
// need to create a type
|
||||
mpi_datatype_oarchive ar(x);
|
||||
insert(std::make_pair(t,ar.get_mpi_datatype()));
|
||||
it = find(t);
|
||||
datatype = ar.get_mpi_datatype();
|
||||
set(t, datatype);
|
||||
}
|
||||
|
||||
return it->second;
|
||||
return datatype;
|
||||
}
|
||||
|
||||
private:
|
||||
// free all MPI data types
|
||||
void free()
|
||||
{
|
||||
// ignore errors in the destructor
|
||||
for (iterator it=begin(); it !=end(); ++it)
|
||||
MPI_Type_free(&(it->second));
|
||||
}
|
||||
|
||||
MPI_Datatype get(const std::type_info* t);
|
||||
void set(const std::type_info* t, MPI_Datatype datatype);
|
||||
};
|
||||
|
||||
extern mpi_datatype_map mpi_datatype_cache;
|
||||
/// Retrieve the MPI datatype cache
|
||||
mpi_datatype_map& mpi_datatype_cache();
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
|
||||
@@ -8,9 +8,54 @@
|
||||
|
||||
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
|
||||
#include <boost/mpi/detail/mpi_datatype_cache.hpp>
|
||||
#include <map>
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
mpi_datatype_map mpi_datatype_cache;
|
||||
|
||||
typedef std::map<std::type_info const*,MPI_Datatype,type_info_compare>
|
||||
stored_map_type;
|
||||
|
||||
struct mpi_datatype_map::implementation
|
||||
{
|
||||
stored_map_type map;
|
||||
};
|
||||
|
||||
mpi_datatype_map::mpi_datatype_map()
|
||||
{
|
||||
impl = new implementation();
|
||||
}
|
||||
|
||||
mpi_datatype_map::~mpi_datatype_map()
|
||||
{
|
||||
// do not free after call to MPI_FInalize
|
||||
int finalized=0;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Finalized,(&finalized));
|
||||
if (!finalized) {
|
||||
// ignore errors in the destructor
|
||||
for (stored_map_type::iterator it=impl->map.begin(); it != impl->map.end(); ++it) {
|
||||
MPI_Type_free(&(it->second));
|
||||
}
|
||||
}
|
||||
delete impl;
|
||||
}
|
||||
|
||||
MPI_Datatype mpi_datatype_map::get(const std::type_info* t)
|
||||
{
|
||||
stored_map_type::iterator pos = impl->map.find(t);
|
||||
if (pos != impl->map.end())
|
||||
return pos->second;
|
||||
else
|
||||
return MPI_DATATYPE_NULL;
|
||||
}
|
||||
|
||||
void mpi_datatype_map::set(const std::type_info* t, MPI_Datatype datatype)
|
||||
{
|
||||
impl->map[t] = datatype;
|
||||
}
|
||||
|
||||
mpi_datatype_map& mpi_datatype_cache()
|
||||
{
|
||||
static mpi_datatype_map cache;
|
||||
return cache;
|
||||
}
|
||||
} } }
|
||||
|
||||
Reference in New Issue
Block a user