• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com>.
2 
3 // Use, modification and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 /** @file status.hpp
8  *
9  *  This header defines the class @c status, which reports on the
10  *  results of point-to-point communication.
11  */
12 #ifndef BOOST_MPI_STATUS_HPP
13 #define BOOST_MPI_STATUS_HPP
14 
15 #include <boost/mpi/config.hpp>
16 #include <boost/mpi/datatype.hpp>
17 #include <boost/optional.hpp>
18 #include <boost/mpl/bool.hpp>
19 
20 namespace boost { namespace mpi {
21 
22 class request;
23 class communicator;
24 
25 /** @brief Contains information about a message that has been or can
26  *  be received.
27  *
28  *  This structure contains status information about messages that
29  *  have been received (with @c communicator::recv) or can be received
30  *  (returned from @c communicator::probe or @c
31  *  communicator::iprobe). It permits access to the source of the
32  *  message, message tag, error code (rarely used), or the number of
33  *  elements that have been transmitted.
34  */
35 class BOOST_MPI_DECL status
36 {
37  public:
status()38   status() : m_count(-1) { }
39 
status(MPI_Status const & s)40   status(MPI_Status const& s) : m_status(s), m_count(-1) {}
41 
42   /**
43    * Retrieve the source of the message.
44    */
source() const45   int source() const { return m_status.MPI_SOURCE; }
46 
47   /**
48    * Retrieve the message tag.
49    */
tag() const50   int tag() const { return m_status.MPI_TAG; }
51 
52   /**
53    * Retrieve the error code.
54    */
error() const55   int error() const { return m_status.MPI_ERROR; }
56 
57   /**
58    * Determine whether the communication associated with this object
59    * has been successfully cancelled.
60   */
61   bool cancelled() const;
62 
63   /**
64    * Determines the number of elements of type @c T contained in the
65    * message. The type @c T must have an associated data type, i.e.,
66    * @c is_mpi_datatype<T> must derive @c mpl::true_. In cases where
67    * the type @c T does not match the transmitted type, this routine
68    * will return an empty @c optional<int>.
69    *
70    * @returns the number of @c T elements in the message, if it can be
71    * determined.
72    */
count() const73   template<typename T> optional<int> count() const { return count_impl<T>(is_mpi_datatype<T>()); }
74 
75   /**
76    * References the underlying @c MPI_Status
77    */
operator MPI_Status&()78   operator       MPI_Status&()       { return m_status; }
79 
80   /**
81    * References the underlying @c MPI_Status
82    */
operator const MPI_Status&() const83   operator const MPI_Status&() const { return m_status; }
84 
85  private:
86   /**
87    * INTERNAL ONLY
88    */
89   template<typename T> optional<int> count_impl(mpl::true_) const;
90 
91   /**
92    * INTERNAL ONLY
93    */
94   template<typename T> optional<int> count_impl(mpl::false_) const;
95 
96  public: // friend templates are not portable
97 
98   /// INTERNAL ONLY
99   mutable MPI_Status m_status;
100   mutable int m_count;
101 
102   friend class communicator;
103   friend class request;
104 };
105 
106 template<typename T>
count_impl(mpl::true_) const107 inline optional<int> status::count_impl(mpl::true_) const
108 {
109   if (m_count != -1)
110     return m_count;
111 
112   int return_value;
113   BOOST_MPI_CHECK_RESULT(MPI_Get_count,
114                          (&m_status, get_mpi_datatype<T>(T()), &return_value));
115   if (return_value == MPI_UNDEFINED)
116     return optional<int>();
117   else
118     /* Cache the result. */
119     return m_count = return_value;
120 }
121 
122 template<typename T>
count_impl(mpl::false_) const123 inline optional<int> status::count_impl(mpl::false_) const
124 {
125   if (m_count == -1)
126     return optional<int>();
127   else
128     return m_count;
129 }
130 
131 
132 } } // end namespace boost::mpi
133 
134 #endif // BOOST_MPI_STATUS_HPP
135