OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
AsyncSendBuffers.h
Go to the documentation of this file.
1 //
2 // Class AsyncSendBuffer and AsyncSendBuffers
3 //
4 // Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
5 // All rights reserved
6 //
7 // Implemented as part of the PhD thesis
8 // "Toward massively parallel multi-objective optimization with application to
9 // particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
10 //
11 // This file is part of OPAL.
12 //
13 // OPAL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
20 //
21 #include <vector>
22 #include <algorithm>
23 #include <string.h>
24 #include "mpi.h"
25 #include "boost/smart_ptr.hpp"
26 #include "boost/bind.hpp"
27 
29 
30 public:
31 
32  AsyncSendBuffer(std::ostringstream &os) {
33  this->size_req = new MPI_Request();
34  this->buffer_req = new MPI_Request();
35  this->buf_size = os.str().length();
36  buffer = new char[buf_size];
37  memcpy(buffer, os.str().c_str(), buf_size);
38  }
39 
41  delete size_req;
42  delete buffer_req;
43  delete[] buffer;
44  }
45 
46  bool hasCompleted() {
47  int bufferflag = 0;
48  MPI_Test(this->buffer_req, &bufferflag, MPI_STATUS_IGNORE);
49  if(bufferflag) {
50  int sizeflag = 0;
51  MPI_Test(this->buffer_req, &sizeflag, MPI_STATUS_IGNORE);
52  if(sizeflag) {
53  return true;
54  }
55  }
56  return false;
57  }
58 
59  void send(int recv_rank, int size_tag, int data_tag, MPI_Comm comm) {
60  MPI_Isend(&buf_size, 1, MPI_LONG, recv_rank, size_tag, comm, size_req);
61  MPI_Isend(buffer, buf_size, MPI_CHAR, recv_rank, data_tag, comm, buffer_req);
62  }
63 
64 
65 private:
66 
67  // can't use smart pointers because MPI will hold last valid reference to
68  // pointer
69  MPI_Request *size_req;
70  MPI_Request *buffer_req;
71  char *buffer;
72 
73  size_t buf_size;
74 
75 };
76 
77 
79 
80 public:
82 
83  void insert(boost::shared_ptr<AsyncSendBuffer> buf) {
84  collection_.push_back(buf);
85  }
86 
87  void cleanup() {
88  collection_.erase(std::remove_if(
89  collection_.begin(), collection_.end(), boost::bind(&AsyncSendBuffer::hasCompleted, _1)),
90  collection_.end());
91  }
92 
93  size_t size() {
94  return collection_.size();
95  }
96 
97 private:
98  std::vector< boost::shared_ptr<AsyncSendBuffer> > collection_;
99 };
100 
MPI_Request * buffer_req
MPI_Request * size_req
AsyncSendBuffer(std::ostringstream &os)
void send(int recv_rank, int size_tag, int data_tag, MPI_Comm comm)
void insert(boost::shared_ptr< AsyncSendBuffer > buf)
std::vector< boost::shared_ptr< AsyncSendBuffer > > collection_