TIMPI
request.h
Go to the documentation of this file.
1 // The TIMPI Message-Passing Parallelism Library.
2 // Copyright (C) 2002-2025 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 TIMPI_REQUEST_H
20 #define TIMPI_REQUEST_H
21 
22 // TIMPI includes
23 #include "timpi/timpi_config.h"
24 #include "timpi/status.h"
25 
26 // C/C++ includes
27 #ifdef TIMPI_HAVE_MPI
28 # include "timpi/ignore_warnings.h"
29 # include "mpi.h"
30 # include "timpi/restore_warnings.h"
31 #endif // TIMPI_HAVE_MPI
32 
33 #include <memory>
34 #include <vector>
35 #include <utility>
36 
37 namespace TIMPI
38 {
39 
40 // Forward declarations
41 struct PostWaitWork;
42 
43 #ifdef TIMPI_HAVE_MPI
44 
45 //-------------------------------------------------------------------
49 typedef MPI_Request request;
50 
51 #else
52 
53 // This shouldn't actually be needed, but must be
54 // a unique type for function overloading to work
55 // properly.
56 //
57 // We'll want some actual data in here, to make it possible for
58 // waitany() to be used in loops that degrade cleanly.
59 typedef unsigned int request;
60 #endif // TIMPI_HAVE_MPI
61 
62 
63 //-------------------------------------------------------------------
67 class Request
68 {
69 public:
70  Request ();
71 
72  Request (const request & r);
73 
74  Request (const Request & other);
75 
76  void cleanup();
77 
78  Request & operator = (const Request & other);
79 
80  Request & operator = (const request & r);
81 
82  ~Request ();
83 
84  request * get() { return &_request; }
85 
86  const request * get() const { return &_request; }
87 
88  Status wait ();
89 
90  bool test ();
91 
92  bool test (status & status);
93 
94  // Breaking non-blocking sends into multiple requests can require
95  // chaining multiple requests into a single Request. After using
96  // add_prior_request, any wait() on this request automatically
97  // begins with a wait() on a copy of the added Request \p req.
98  //
99  // The added request should not already have a prior request of its
100  // own. However, if \p this request already has a prior, it will be
101  // moved to and thus invoked prior to the new prior request \p req.
102  void add_prior_request(const Request & req);
103 
104  // Objects of a PostWaitWork subclass can be added to this request,
105  // and they will automatically be run() after a wait() on this
106  // request completes. The \p work object must be heap allocated,
107  // and will be deleted once \p this Request and any Request copies
108  // made from \p this have been cleaned up.
109  void add_post_wait_work(PostWaitWork * work);
110 
111  static const request null_request;
112 
113 private:
115 
116  std::unique_ptr<Request> _prior_request;
117 
118  // post_wait_work->first is a vector of work to do after a wait
119  // finishes; post_wait_work->second is a reference count so that
120  // Request objects will behave roughly like a shared_ptr and be
121  // usable in STL containers
122  //
123  // FIXME - we require C++11 now, so we can be smarter about this.
124  std::pair<std::vector <PostWaitWork * >, unsigned int> * post_wait_work;
125 
126  // waitany() takes a container of Requests, so it can't be a member
127  // function, but it needs access to each Request's _prior_request
128  // and _post_wait_work
129  friend std::size_t waitany (std::vector<Request> &);
130 };
131 
135 inline Status wait (Request & r) { return r.wait(); }
136 
140 void wait (std::vector<Request> & r);
141 
146 std::size_t waitany (std::vector<Request> & r);
147 
148 
149 } // namespace TIMPI
150 
151 #endif // TIMPI_REQUEST_H
void add_prior_request(const Request &req)
Definition: request.C:190
MPI_Request request
Request object for non-blocking I/O.
Definition: request.h:41
static const request null_request
Definition: request.h:111
std::unique_ptr< Request > _prior_request
Definition: request.h:116
void cleanup()
Definition: request.C:71
request _request
Definition: request.h:114
friend std::size_t waitany(std::vector< Request > &)
Wait for at least one non-blocking operation to finish.
Definition: request.C:219
An abstract base class that can be subclassed to allow other code to perform work after a MPI_Wait su...
Status wait()
Definition: request.C:121
void add_post_wait_work(PostWaitWork *work)
Definition: request.C:204
Encapsulates the MPI_Request.
Definition: request.h:67
std::size_t waitany(std::vector< Request > &r)
Wait for at least one non-blocking operation to finish.
Definition: request.C:219
Status wait(Request &r)
Wait for a non-blocking send or receive to finish.
Definition: request.h:135
Encapsulates the MPI_Status struct.
Definition: status.h:75
std::pair< std::vector< PostWaitWork *>, unsigned int > * post_wait_work
Definition: request.h:124
bool test()
Definition: request.C:153
Request & operator=(const Request &other)
Definition: request.C:92