Muster
 All Classes Namespaces Files Functions Variables Typedefs Macros
par_partition.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2010, Lawrence Livermore National Security, LLC.
3 // Produced at the Lawrence Livermore National Laboratory
4 // LLNL-CODE-433662
5 // All rights reserved.
6 //
7 // This file is part of Muster. For details, see http://github.com/tgamblin/muster.
8 // Please also read the LICENSE file for further information.
9 //
10 // Redistribution and use in source and binary forms, with or without modification, are
11 // permitted provided that the following conditions are met:
12 //
13 // * Redistributions of source code must retain the above copyright notice, this list of
14 // conditions and the disclaimer below.
15 // * Redistributions in binary form must reproduce the above copyright notice, this list of
16 // conditions and the disclaimer (as noted below) in the documentation and/or other materials
17 // provided with the distribution.
18 // * Neither the name of the LLNS/LLNL nor the names of its contributors may be used to endorse
19 // or promote products derived from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
22 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24 // LAWRENCE LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 //////////////////////////////////////////////////////////////////////////////////////////////////
31 
32 ///
33 /// @file par_partition.cpp
34 /// @author Todd Gamblin tgamblin@llnl.gov
35 ///
36 #include "par_partition.h"
37 
38 #include <iostream>
39 
40 #include "mpi_utils.h"
41 #include "partition.h"
42 #include "mpi_bindings.h"
43 
44 //#define DEBUG
45 
46 using namespace std;
47 
48 namespace cluster {
49 
50  par_partition::par_partition(MPI_Comm _comm) : comm(_comm) { }
51 
53 
54 
55  void par_partition::gather(partition& destination, int root) {
56  int rank, size;
57  CMPI_Comm_rank(comm, &rank);
58  CMPI_Comm_size(comm, &size);
59 
60 #ifdef DEBUG
61  size_t count = medoid_ids.size();
62  CMPI_Bcast(&count, 1, MPI_SIZE_T, root, comm);
63  if (count != medoid_ids.size()) {
64  cerr << "Error: incorrect number of medoids on " << rank << ": " << medoid_ids.size()
65  << ", expected " << count << endl;
66  exit(1);
67  }
68 
69  size_t object_count = cluster_ids.size();
70  CMPI_Bcast(&object_count, 1, MPI_SIZE_T, root, comm);
71  if (object_count != cluster_ids.size()) {
72  cerr << "Error: incorrect number of objects on " << rank << ": " << cluster_ids.size()
73  << ", expected " << object_count << endl;
74  exit(1);
75  }
76 
77  std::vector<object_id> bcast_medoid_ids = medoid_ids;
78  CMPI_Bcast(&bcast_medoid_ids[0], bcast_medoid_ids.size(), MPI_SIZE_T, root, comm);
79  for (size_t i=0; i < medoid_ids.size(); i++) {
80  if (medoid_ids[i] != bcast_medoid_ids[i]) {
81  cerr << "Error: medoids do not match on " << rank << endl;
82  exit(1);
83  }
84  }
85 #endif // DEBUG
86 
87  if (rank == root) {
88  destination.medoid_ids = medoid_ids;
89  destination.cluster_ids.resize(cluster_ids.size() * size);
90  }
91 
93  &destination.cluster_ids[0], cluster_ids.size(), MPI_SIZE_T,
94  root, comm);
95  }
96 
97 
98  void par_partition::get_sizes(std::vector<size_t>& sizes) {
99  vector<size_t> local_sizes(medoid_ids.size(), 0);
100  for (size_t i=0; i < cluster_ids.size(); i++) {
101  local_sizes[cluster_ids[i]]++;
102  }
103 
104  sizes.resize(medoid_ids.size());
105  CMPI_Allreduce(&local_sizes[0], &sizes[0], medoid_ids.size(), MPI_SIZE_T, MPI_SUM, comm);
106  }
107 
108 
109 
110  std::ostream& operator<<(std::ostream& out, const par_partition& par) {
112  p.medoid_ids = par.medoid_ids;
113  p.cluster_ids = par.cluster_ids;
114  out << p;
115  return out;
116  }
117 
118 
119 } // namespace cluster
#define MPI_SIZE_T
Definition: mpi_utils.h:39
std::vector< object_id > medoid_ids
Gives the index of the object that is the ith medoid.
Definition: partition.h:79
#define CMPI_Allreduce
Definition: mpi_bindings.h:79
Class to represent a partitioning of a data set.
MPI_Comm comm
Communicator, the processes of which this partition divides.
Definition: par_partition.h:79
#define CMPI_Comm_rank
Definition: mpi_bindings.h:81
void get_sizes(std::vector< size_t > &sizes)
Scalably get the sizes of all the clusters in this partition.
std::ostream & operator<<(std::ostream &out, const id_pair< T > &p)
Print out an id_pair as a tuple of its element and its source rank.
Definition: id_pair.h:103
par_partition represents a partitioning of a distributed data set.
Definition: par_partition.h:70
Overloaded utility functions to convert between arbitrary C/C++ types and MPI types, custom typedefs for cstdlib types like size_t, and a wrapper for MPI_Pack_Size.
Distributed representation of a partitioning of a data set.
std::vector< object_id > cluster_ids
Global cluster ids for local objects.
Definition: par_partition.h:76
#define CMPI_Gather
Definition: mpi_bindings.h:83
std::vector< object_id > medoid_ids
Gives the object id for the ith medoid. This object may not be local.
Definition: par_partition.h:72
#define CMPI_Bcast
Definition: mpi_bindings.h:80
virtual ~par_partition()
Virtual destructor for inheritance.
std::vector< medoid_id > cluster_ids
Gives cluster id (index in medoids) for the ith object.
Definition: partition.h:84
#defines for switching between MPI and PMPI bindings.
void gather(partition &local, int root=0)
Collective operation.
This represents a partitioning of a data set.
Definition: partition.h:76
#define CMPI_Comm_size
Definition: mpi_bindings.h:82
Muster. Copyright © 2010, Lawrence Livermore National Laboratory, LLNL-CODE-433662.
Distribution of Muster and its documentation is subject to terms of the Muster LICENSE.
Generated on Thu Sep 1 2016 using Doxygen 1.8.5