Fenix @develop
 
Loading...
Searching...
No Matches
request.hpp
1#ifndef FENIX_MPIXX_REQUEST_HPP
2#define FENIX_MPIXX_REQUEST_HPP
3
4#include <mpi.h>
5
6#include "fenix_opt.hpp"
7#include "fenix/mpixx/status.hpp"
8
9namespace fenix::mpixx {
10
11// Note that this 'takes ownership' of the request - if RequestBase is destroyed
12// before completing, it frees the MPI_Request to ensure proper cleanup if a
13// Task is destroyed before completing.
14class Request {
15 public:
16 Request(MPI_Request* r) : request(r) {};
17
18 Request() = default;
19 Request(const Request&) = delete;
20 Request(Request&& r) { *this = std::move(r); }
21 Request& operator=(MPI_Request* r) { return *this = Request(r); }
22 Request& operator=(Request&& r) {
23 mpi_free();
24 *this = r;
25 Request tmp{};
26 r = tmp;
27 return *this;
28 }
29
30 // TODO: this turned out buggy, figure out why
31 ~Request() { /*mpi_free();*/ }
32
33 bool operator==(const MPI_Request* r) const { return r == request; }
34
35 bool is_complete() {
36 return complete || request == nullptr || *request == MPI_REQUEST_NULL;
37 }
38
39 bool test() {
40 if (!is_complete()) {
41 ret = MPI_Test(request, &complete, ret);
42 if (ret != MPI_SUCCESS) complete = true;
43 }
44 return is_complete();
45 }
46 void wait() {
47 if (!is_complete()) {
48 ret = MPI_Wait(request, ret);
49 complete = true;
50 }
51 }
52 void mpi_free() {
53 if (!is_complete()) MPI_Request_free(request);
54 }
55
56 bool done() { return test(); }
57 void resume() { test(); }
58 auto result() {
59 fenix_assert(is_complete());
60 return ret;
61 }
62
63 private:
64 Request& operator=(const Request& r) {
65 request = r.request;
66 ret = r.ret;
67 complete = r.complete;
68 return *this;
69 }
70
71 MPI_Request* request = nullptr;
72 Status ret;
73 int complete = false;
74};
75
76} // namespace fenix::mpixx
77
78#endif //FENIX_MPIXX_REQUEST_HPP
Definition request.hpp:14
Definition status.hpp:8