]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 request.hpp | |
8 | * | |
9 | * This header defines the class @c request, which contains a request | |
10 | * for non-blocking communication. | |
11 | */ | |
12 | #ifndef BOOST_MPI_REQUEST_HPP | |
13 | #define BOOST_MPI_REQUEST_HPP | |
14 | ||
15 | #include <boost/mpi/config.hpp> | |
92f5a8d4 | 16 | #include <boost/mpi/status.hpp> |
7c673cae FG |
17 | #include <boost/optional.hpp> |
18 | #include <boost/shared_ptr.hpp> | |
19 | #include <boost/mpi/packed_iarchive.hpp> | |
20 | ||
21 | namespace boost { namespace mpi { | |
22 | ||
23 | class status; | |
24 | class communicator; | |
25 | ||
26 | /** | |
27 | * @brief A request for a non-blocking send or receive. | |
28 | * | |
29 | * This structure contains information about a non-blocking send or | |
30 | * receive and will be returned from @c isend or @c irecv, | |
31 | * respectively. | |
32 | */ | |
33 | class BOOST_MPI_DECL request | |
34 | { | |
35 | public: | |
36 | /** | |
37 | * Constructs a NULL request. | |
38 | */ | |
39 | request(); | |
40 | ||
92f5a8d4 TL |
41 | /** |
42 | * Send a known number of primitive objects in one MPI request. | |
43 | */ | |
44 | template<typename T> | |
45 | static request make_trivial_send(communicator const& comm, int dest, int tag, T const& value); | |
46 | template<typename T> | |
47 | static request make_trivial_send(communicator const& comm, int dest, int tag, T const* values, int n); | |
48 | static request make_packed_send(communicator const& comm, int dest, int tag, void const* values, std::size_t n); | |
49 | ||
50 | static request make_bottom_send(communicator const& comm, int dest, int tag, MPI_Datatype tp); | |
51 | static request make_empty_send(communicator const& comm, int dest, int tag); | |
52 | /** | |
53 | * Receive a known number of primitive objects in one MPI request. | |
54 | */ | |
55 | template<typename T> | |
56 | static request make_trivial_recv(communicator const& comm, int dest, int tag, T& value); | |
57 | template<typename T> | |
58 | static request make_trivial_recv(communicator const& comm, int dest, int tag, T* values, int n); | |
59 | ||
60 | static request make_bottom_recv(communicator const& comm, int dest, int tag, MPI_Datatype tp); | |
61 | static request make_empty_recv(communicator const& comm, int dest, int tag); | |
62 | /** | |
63 | * Construct request for simple data of unknown size. | |
64 | */ | |
65 | static request make_dynamic(); | |
66 | /** | |
67 | * Constructs request for serialized data. | |
68 | */ | |
69 | template<typename T> | |
70 | static request make_serialized(communicator const& comm, int source, int tag, T& value); | |
71 | /** | |
72 | * Constructs request for array of complex data. | |
73 | */ | |
74 | template<typename T> | |
75 | static request make_serialized_array(communicator const& comm, int source, int tag, T* values, int n); | |
76 | /** | |
77 | * Request to recv array of primitive data. | |
78 | */ | |
79 | template<typename T, class A> | |
80 | static request | |
81 | make_dynamic_primitive_array_recv(communicator const& comm, int source, int tag, | |
82 | std::vector<T,A>& values); | |
83 | /** | |
84 | * Request to send array of primitive data. | |
85 | */ | |
86 | template<typename T, class A> | |
87 | static request | |
88 | make_dynamic_primitive_array_send(communicator const& comm, int source, int tag, | |
89 | std::vector<T,A> const& values); | |
7c673cae FG |
90 | /** |
91 | * Wait until the communication associated with this request has | |
92 | * completed, then return a @c status object describing the | |
93 | * communication. | |
94 | */ | |
92f5a8d4 | 95 | status wait() { return m_handler ? m_handler->wait() : status(); } |
7c673cae FG |
96 | |
97 | /** | |
98 | * Determine whether the communication associated with this request | |
99 | * has completed successfully. If so, returns the @c status object | |
100 | * describing the communication. Otherwise, returns an empty @c | |
101 | * optional<> to indicate that the communication has not completed | |
102 | * yet. Note that once @c test() returns a @c status object, the | |
103 | * request has completed and @c wait() should not be called. | |
104 | */ | |
92f5a8d4 | 105 | optional<status> test() { return active() ? m_handler->test() : optional<status>(); } |
7c673cae FG |
106 | |
107 | /** | |
108 | * Cancel a pending communication, assuming it has not already been | |
109 | * completed. | |
110 | */ | |
92f5a8d4 TL |
111 | void cancel() { if (m_handler) { m_handler->cancel(); } m_preserved.reset(); } |
112 | ||
7c673cae | 113 | /** |
92f5a8d4 TL |
114 | * The trivial MPI requet implenting this request, provided it's trivial. |
115 | * Probably irrelevant to most users. | |
7c673cae | 116 | */ |
92f5a8d4 TL |
117 | optional<MPI_Request&> trivial() { return (m_handler |
118 | ? m_handler->trivial() | |
119 | : optional<MPI_Request&>()); } | |
7c673cae FG |
120 | |
121 | /** | |
92f5a8d4 | 122 | * Is this request potentialy pending ? |
7c673cae | 123 | */ |
92f5a8d4 TL |
124 | bool active() const { return bool(m_handler) && m_handler->active(); } |
125 | ||
126 | // Some data might need protection while the reqest is processed. | |
127 | void preserve(boost::shared_ptr<void> d); | |
128 | ||
129 | class handler { | |
130 | public: | |
131 | virtual BOOST_MPI_DECL ~handler() = 0; | |
132 | virtual status wait() = 0; | |
133 | virtual optional<status> test() = 0; | |
134 | virtual void cancel() = 0; | |
135 | ||
136 | virtual bool active() const = 0; | |
137 | virtual optional<MPI_Request&> trivial() = 0; | |
138 | }; | |
139 | ||
140 | private: | |
141 | ||
142 | request(handler *h) : m_handler(h) {}; | |
143 | ||
144 | // specific implementations | |
145 | class legacy_handler; | |
146 | class trivial_handler; | |
147 | class dynamic_handler; | |
148 | template<typename T> class legacy_serialized_handler; | |
149 | template<typename T> class legacy_serialized_array_handler; | |
150 | template<typename T, class A> class legacy_dynamic_primitive_array_handler; | |
151 | #if BOOST_MPI_VERSION >= 3 | |
152 | template<class Data> class probe_handler; | |
153 | #endif | |
154 | private: | |
155 | shared_ptr<handler> m_handler; | |
156 | shared_ptr<void> m_preserved; | |
7c673cae FG |
157 | }; |
158 | ||
159 | } } // end namespace boost::mpi | |
160 | ||
161 | #endif // BOOST_MPI_REQUEST_HPP |