request.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 #ifndef LIBMESH_REQUEST_H
20 #define LIBMESH_REQUEST_H
21 
22 // Parallel includes
23 #include "libmesh/status.h"
24 
25 // libMesh Includes
26 #include "libmesh/libmesh_common.h"
27 
28 // C++ includes
29 #include <memory>
30 #include <vector>
31 #include <utility>
32 
33 namespace libMesh
34 {
35 
36 namespace Parallel
37 {
38 
39 // Forward declarations
40 struct PostWaitWork;
41 
42 #ifdef LIBMESH_HAVE_MPI
43 
44 //-------------------------------------------------------------------
48 typedef MPI_Request request;
49 
50 #else
51 
52 // This shouldn't actually be needed, but must be
53 // a unique type for function overloading to work
54 // properly.
55 struct request { /* unsigned int r; */ };
56 #endif // LIBMESH_HAVE_MPI
57 
58 
59 //-------------------------------------------------------------------
63 class Request
64 {
65 public:
66  Request ();
67 
68  Request (const request & r);
69 
70  Request (const Request & other);
71 
72  void cleanup();
73 
74  Request & operator = (const Request & other);
75 
76  Request & operator = (const request & r);
77 
78  ~Request ();
79 
80  request * get() { return &_request; }
81 
82  const request * get() const { return &_request; }
83 
84  Status wait ();
85 
86  bool test ();
87 
88  bool test (status & status);
89 
90  // Breaking non-blocking sends into multiple requests can require
91  // chaining multiple requests into a single Request. After using
92  // add_prior_request, any wait() on this request automatically
93  // begins with a wait() on a copy of the added Request \p req.
94  //
95  // The added request should not already have a prior request of its
96  // own. However, if \p this request already has a prior, it will be
97  // moved to and thus invoked prior to the new prior request \p req.
98  void add_prior_request(const Request & req);
99 
100  // Objects of a PostWaitWork subclass can be added to this request,
101  // and they will automatically be run() after a wait() on this
102  // request completes. The \p work object must be heap allocated,
103  // and will be deleted once \p this Request and any Request copies
104  // made from \p this have been cleaned up.
105  void add_post_wait_work(PostWaitWork * work);
106 
107 private:
109 
110  std::unique_ptr<Request> _prior_request;
111 
112  // post_wait_work->first is a vector of work to do after a wait
113  // finishes; post_wait_work->second is a reference count so that
114  // Request objects will behave roughly like a shared_ptr and be
115  // usable in STL containers
116  //
117  // FIXME - we require C++11 now, so we can be smarter about this.
118  std::pair<std::vector <PostWaitWork * >, unsigned int> * post_wait_work;
119 
120  // waitany() takes a container of Requests, so it can't be a member
121  // function, but it needs access to each Request's _prior_request
122  // and _post_wait_work
123  friend std::size_t waitany (std::vector<Request> &);
124 };
125 
129 inline Status wait (Request & r) { return r.wait(); }
130 
134 void wait (std::vector<Request> & r);
135 
140 std::size_t waitany (std::vector<Request> & r);
141 
142 
143 } // namespace Parallel
144 
145 } // namespace libMesh
146 
147 #endif // LIBMESH_REQUEST_H
void wait(std::vector< Request > &r)
Definition: request.C:213
MPI_Request request
Definition: request.h:40
std::pair< std::vector< PostWaitWork *>, unsigned int > * post_wait_work
Definition: request.h:118
friend std::size_t waitany(std::vector< Request > &)
Definition: request.C:219
void add_prior_request(const Request &req)
Definition: request.C:190
std::size_t waitany(std::vector< Request > &r)
Definition: request.C:219
Request & operator=(const Request &other)
Definition: request.C:92
void add_post_wait_work(PostWaitWork *work)
Definition: request.C:204
std::unique_ptr< Request > _prior_request
Definition: request.h:110