HavoqGT
edge_partitioner.hpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright (c) 2013, Lawrence Livermore National Security, LLC.
4  * Produced at the Lawrence Livermore National Laboratory.
5  * Written by Steven Feldman <feldman12@llnl.gov>.
6  * LLNL-CODE-644630.
7  * All rights reserved.
8  *
9  * This file is part of HavoqGT, Version 0.1.
10  * For details, see https://computation.llnl.gov/casc/dcca-pub/dcca/Downloads.html
11  *
12  * Please also read this link – Our Notice and GNU Lesser General Public License.
13  * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
14  *
15  * This program is free software; you can redistribute it and/or modify it under
16  * the terms of the GNU Lesser General Public License (as published by the Free
17  * Software Foundation) version 2.1 dated February 1999.
18  *
19  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
20  * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A
21  * PARTICULAR PURPOSE. See the terms and conditions of the GNU General Public
22  * License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License along
25  * with this program; if not, write to the Free Software Foundation, Inc.,
26  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27  *
28  * OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE
29  *
30  * Our Preamble Notice
31  *
32  * A. This notice is required to be provided under our contract with the
33  * U.S. Department of Energy (DOE). This work was produced at the Lawrence
34  * Livermore National Laboratory under Contract No. DE-AC52-07NA27344 with the DOE.
35  *
36  * B. Neither the United States Government nor Lawrence Livermore National
37  * Security, LLC nor any of their employees, makes any warranty, express or
38  * implied, or assumes any liability or responsibility for the accuracy,
39  * completeness, or usefulness of any information, apparatus, product, or process
40  * disclosed, or represents that its use would not infringe privately-owned rights.
41  *
42  * C. Also, reference herein to any specific commercial products, process, or
43  * services by trade name, trademark, manufacturer or otherwise does not
44  * necessarily constitute or imply its endorsement, recommendation, or favoring by
45  * the United States Government or Lawrence Livermore National Security, LLC. The
46  * views and opinions of authors expressed herein do not necessarily state or
47  * reflect those of the United States Government or Lawrence Livermore National
48  * Security, LLC, and shall not be used for advertising or product endorsement
49  * purposes.
50  *
51  */
52 
53 #ifndef __HAVOQGT_IMP_EDGE_PARTITIONER_HPP__
54 #define __HAVOQGT_IMP_EDGE_PARTITIONER_HPP__
55 #include <map>
56 #include <deque>
57 
58 namespace havoqgt {
59 namespace mpi {
60 
67  public:
68  explicit source_partitioner(int p):m_mpi_size(p) { }
69  int operator()(uint64_t i) const { return i % m_mpi_size; }
70 
71  private:
73 };
74 
76  public:
77  explicit edge_source_partitioner(int p):m_mpi_size(p) { }
78  int operator()(std::pair<uint64_t, uint64_t> i, bool is_counting) const {
79  return i.first % m_mpi_size;
80  }
81 
82  private:
84 };
85 
87  public:
88  explicit edge_target_partitioner(int p):m_mpi_size(p) { }
89  int operator()(std::pair<uint64_t, uint64_t> i) const {
90  return i.second % m_mpi_size;
91  }
92 
93  private:
95 };
96 
108  typedef struct OverflowSendInfo{
109  OverflowSendInfo(int sid, int count)
110  : to_send_id(sid)
111  , to_send_count(count)
112  , temp_to_send_count(0) {}
113 
115  int32_t to_send_count;
118 
120  public:
121  explicit high_edge_partitioner(int s, int r,
122  std::map<uint64_t, std::deque<OverflowSendInfo>> *transfer_info)
123  : m_mpi_size(s)
124  , m_mpi_rank(r)
125  , m_transfer_info(transfer_info)
126  /*, m_dof(dof)*/ { }
127 
136  int operator()(std::pair<uint64_t, uint64_t> i, bool is_counting = true) {
137 
138 
139  int dest = int(i.second % m_mpi_size);
140  if (dest == m_mpi_rank) {
141  // If the current node is the destination, then determine the destination
142  // by examing the transfer_info object
143  const uint64_t delegate_id = i.first;
144  if (m_transfer_info->count(delegate_id) == 0) {
145  return m_mpi_rank;
146  }
147 
148  assert(m_transfer_info->at(delegate_id).size() > 0);
149 
150  if (is_counting) {
151  // If it is counting then use the temp_to_send_count, which is reset
152  // the next time this called with an edge with the same delegate_id and
153  // is_counting is set to false.
154  for (size_t j = 0; j < m_transfer_info->at(delegate_id).size(); j++) {
155  if (m_transfer_info->at(delegate_id)[j].temp_to_send_count <
156  m_transfer_info->at(delegate_id)[j].to_send_count) {
157  (m_transfer_info->at(delegate_id)[j].temp_to_send_count)++;
158 
159  // If this has an edge to send, return the send_id
160  return m_transfer_info->at(delegate_id)[j].to_send_id;
161  }
162  }
163  return m_mpi_rank;
164  } else {
165  // Not counting, so update the edge counts
166  dest = m_transfer_info->at(delegate_id).front().to_send_id;
167  //m_dof->send_of_delegate(delegate_id, dest);
168 
169  const int to_send_count =
170  m_transfer_info->at(delegate_id).front().to_send_count--;
171  assert(m_transfer_info->at(delegate_id).front().to_send_count >= 0);
172 
173  // Cleanup, if no more edges for this destination then remove it.
174  // If no more edges for this delaget remove it!
175  if (m_transfer_info->at(delegate_id).front().to_send_count == 0) {
176  m_transfer_info->at(delegate_id).pop_front();
177  if (m_transfer_info->at(delegate_id).size() == 0) {
178  m_transfer_info->erase(delegate_id);
179  }
180  } else {
181  // Otherwise reset the temp variable
182  m_transfer_info->at(delegate_id).front().temp_to_send_count = 0;
183  }
184  } // else not counting
185 
186  } else { // if dest == rank
187  // m_dof->send_delegate(delegate_id, dest);
188  }
189 
190  assert(dest >= 0);
191  assert(dest != m_mpi_rank);
192  return dest;
193  } // operator()
194 
195  private:
196  const int m_mpi_size;
197  const int m_mpi_rank;
198  std::map<uint64_t, std::deque<OverflowSendInfo>> * m_transfer_info;
199 }; // class high_edge_partitioner
200 
201 
203  public:
204  template<typename T>
205  int operator()(std::pair<int, T> i) const { return i.first; }
206 };
207 
208 
209 
210 } // namespace mpi
211 } // namespace havoqgt
212  //
213 #endif // __HAVOQGT_IMP_EDGE_PARTITIONER_HPP__
int operator()(std::pair< uint64_t, uint64_t > i, bool is_counting) const
int operator()(std::pair< uint64_t, uint64_t > i) const
OverflowSendInfo(int sid, int count)
int operator()(uint64_t i) const
std::map< uint64_t, std::deque< OverflowSendInfo > > * m_transfer_info
int operator()(std::pair< uint64_t, uint64_t > i, bool is_counting=true)
int operator()(std::pair< int, T > i) const
high_edge_partitioner(int s, int r, std::map< uint64_t, std::deque< OverflowSendInfo >> *transfer_info)
struct havoqgt::mpi::OverflowSendInfo OverflowSendInfo