00001 ////////////////////////////////////////////////////////////////////////////////////////////////// 00002 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. 00003 // Produced at the Lawrence Livermore National Laboratory 00004 // LLNL-CODE-433662 00005 // All rights reserved. 00006 // 00007 // This file is part of Muster. For details, see http://github.com/tgamblin/muster. 00008 // Please also read the LICENSE file for further information. 00009 // 00010 // Redistribution and use in source and binary forms, with or without modification, are 00011 // permitted provided that the following conditions are met: 00012 // 00013 // * Redistributions of source code must retain the above copyright notice, this list of 00014 // conditions and the disclaimer below. 00015 // * Redistributions in binary form must reproduce the above copyright notice, this list of 00016 // conditions and the disclaimer (as noted below) in the documentation and/or other materials 00017 // provided with the distribution. 00018 // * Neither the name of the LLNS/LLNL nor the names of its contributors may be used to endorse 00019 // or promote products derived from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 00022 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00023 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00024 // LAWRENCE LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE 00025 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00026 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00027 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00028 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00029 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 ////////////////////////////////////////////////////////////////////////////////////////////////// 00031 00032 /// 00033 /// @file id_pair.h 00034 /// @brief MPI-packable, templated struct for shipping around an MPI-packable 00035 /// object plus the id of the process it came from. 00036 /// 00037 #ifndef ID_PAIR_H 00038 #define ID_PAIR_H 00039 00040 #include <mpi.h> 00041 #include "mpi_bindings.h" 00042 00043 #include <cstdlib> 00044 #include <ostream> 00045 00046 namespace cluster { 00047 00048 /// 00049 /// MPI-packable struct for an MPI-packable type plus its object id. 00050 /// 00051 /// Each id_pair<T> has an element and an id for that element and supports 00052 /// packed_size(), pack(), and unpack() methods for transferring these 00053 /// things with MPI. 00054 /// 00055 /// @tparam T Type of contained element. 00056 /// T Must support MPI pack(), packed_size(), and unpack() methods. 00057 /// 00058 template <class T> 00059 struct id_pair { 00060 T element; ///< The object wrapped by this id_pair. 00061 size_t id; ///< Id of the rank where element came from. 00062 00063 /// Template typedef for declaring vectors of id_pair<T> 00064 typedef std::vector< id_pair<T> > vector; 00065 00066 id_pair() { } 00067 id_pair(const T& elt, size_t _id) : element(elt), id(_id) { } 00068 00069 int packed_size(MPI_Comm comm) const { 00070 return element.packed_size(comm) + cmpi_packed_size(1, MPI_SIZE_T, comm); 00071 } 00072 00073 void pack(void *buf, int bufsize, int *position, MPI_Comm comm) const { 00074 element.pack(buf, bufsize, position, comm); 00075 MPI_Pack(const_cast<size_t*>(&id), 1, MPI_SIZE_T, buf, bufsize, position, comm); 00076 } 00077 00078 static id_pair unpack(void *buf, int bufsize, int *position, MPI_Comm comm) { 00079 T t = T::unpack(buf, bufsize, position, comm); 00080 size_t id; 00081 MPI_Unpack(buf, bufsize, position, &id, 1, MPI_SIZE_T, comm); 00082 return id_pair(t, id); 00083 } 00084 }; 00085 00086 /// 00087 /// Helper function for making arbitrary id_pairs with type inference. 00088 /// 00089 template <class T> 00090 id_pair<T> make_id_pair(const T& elt, int id) { 00091 return id_pair<T>(elt, id); 00092 } 00093 00094 /// 00095 /// Print out an id_pair as a tuple of its element and its source rank. 00096 /// 00097 /// @tparam T inferred from the id_pair<T> this is called on. Must support operator<<. 00098 /// 00099 /// @param out Output stream to write the id_pair p onto 00100 /// @param p An id_pair<T>. T must support operator<<. 00101 /// 00102 template <class T> 00103 std::ostream& operator<<(std::ostream& out, const id_pair<T>& p) { 00104 out << "<" << p.element << ", " << p.id << ">"; 00105 return out; 00106 } 00107 00108 } // namespace cluster 00109 00110 #endif // ID_PAIR_H