42 #ifndef __Tpetra_ComputeGatherMap_hpp
43 #define __Tpetra_ComputeGatherMap_hpp
49 #include "Tpetra_Map.hpp"
54 #if ! defined(TRILINOS_UNUSED_FUNCTION)
55 # if defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
56 # define TRILINOS_UNUSED_FUNCTION __attribute__((__unused__))
57 # elif defined(__clang__)
58 # if __has_attribute(unused)
59 # define TRILINOS_UNUSED_FUNCTION __attribute__((__unused__))
61 # define TRILINOS_UNUSED_FUNCTION
62 # endif // Clang has 'unused' attribute
63 # elif defined(__IBMCPP__)
67 # define TRILINOS_UNUSED_FUNCTION
68 # else // some other compiler
69 # define TRILINOS_UNUSED_FUNCTION
71 #endif // ! defined(TRILINOS_UNUSED_FUNCTION)
82 template<
class IntType> TRILINOS_UNUSED_FUNCTION MPI_Datatype
84 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
85 "Not implemented for IntType != int, long, or long long");
88 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
89 getMpiDatatype<int> () {
return MPI_INT; }
91 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
92 getMpiDatatype<long> () {
return MPI_LONG; }
94 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
95 getMpiDatatype<long long> () {
return MPI_LONG_LONG; }
98 template<
class IntType>
100 gather (
const IntType sendbuf[],
const int sendcnt,
101 IntType recvbuf[],
const int recvcnt,
102 const int root,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
105 using Teuchos::rcp_dynamic_cast;
107 using Teuchos::MpiComm;
110 RCP<const MpiComm<int> > mpiComm = rcp_dynamic_cast<
const MpiComm<int> > (comm);
111 if (! mpiComm.is_null ()) {
112 MPI_Datatype sendtype = getMpiDatatype<IntType> ();
113 MPI_Datatype recvtype = sendtype;
114 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
115 const int err = MPI_Gather (reinterpret_cast<void*> (const_cast<IntType*> (sendbuf)),
118 reinterpret_cast<void*> (recvbuf),
123 TEUCHOS_TEST_FOR_EXCEPTION(
124 err != MPI_SUCCESS, std::runtime_error,
"MPI_Gather failed");
129 TEUCHOS_TEST_FOR_EXCEPTION(
130 recvcnt > sendcnt, std::invalid_argument,
131 "gather: If the input communicator contains only one process, "
132 "then you cannot receive more entries than you send. "
133 "You aim to receive " << recvcnt <<
" entries, "
134 "but to send " << sendcnt <<
".");
137 std::copy (sendbuf, sendbuf + recvcnt, recvbuf);
140 template<
class IntType>
142 gatherv (
const IntType sendbuf[],
const int sendcnt,
143 IntType recvbuf[],
const int recvcnts[],
const int displs[],
144 const int root,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
147 using Teuchos::rcp_dynamic_cast;
149 using Teuchos::MpiComm;
153 RCP<const MpiComm<int> > mpiComm =
154 rcp_dynamic_cast<
const MpiComm<int> > (comm);
155 if (! mpiComm.is_null ()) {
156 MPI_Datatype sendtype = getMpiDatatype<IntType> ();
157 MPI_Datatype recvtype = sendtype;
158 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
159 const int err = MPI_Gatherv (reinterpret_cast<void*> (const_cast<IntType*> (sendbuf)),
162 reinterpret_cast<void*> (recvbuf),
163 const_cast<int*> (recvcnts),
164 const_cast<int*> (displs),
168 TEUCHOS_TEST_FOR_EXCEPTION(
169 err != MPI_SUCCESS, std::runtime_error,
"MPI_Gatherv failed");
173 TEUCHOS_TEST_FOR_EXCEPTION(
174 recvcnts[0] > sendcnt,
175 std::invalid_argument,
176 "gatherv: If the input communicator contains only one process, "
177 "then you cannot receive more entries than you send. "
178 "You aim to receive " << recvcnts[0] <<
" entries, "
179 "but to send " << sendcnt <<
".");
183 std::copy (sendbuf, sendbuf + recvcnts[0], recvbuf + displs[0]);
191 template<
class MapType>
192 Teuchos::RCP<const MapType>
193 computeGatherMap (Teuchos::RCP<const MapType> map,
194 const Teuchos::RCP<Teuchos::FancyOStream>& err,
195 const bool dbg=
false)
199 using Teuchos::Array;
200 using Teuchos::ArrayRCP;
201 using Teuchos::ArrayView;
206 typedef typename MapType::local_ordinal_type LO;
207 typedef typename MapType::global_ordinal_type GO;
208 typedef typename MapType::node_type NT;
210 RCP<const Comm<int> > comm = map->getComm ();
211 const int numProcs = comm->getSize ();
212 const int myRank = comm->getRank ();
214 if (! err.is_null ()) {
218 *err << myRank <<
": computeGatherMap:" << endl;
220 if (! err.is_null ()) {
224 RCP<const MapType> oneToOneMap;
225 if (map->isContiguous ()) {
229 *err << myRank <<
": computeGatherMap: Calling createOneToOne" << endl;
234 oneToOneMap = createOneToOne<LO, GO, NT> (map);
237 RCP<const MapType> gatherMap;
239 gatherMap = oneToOneMap;
242 *err << myRank <<
": computeGatherMap: Gathering Map counts" << endl;
261 const int myEltCount = as<int> (oneToOneMap->getNodeNumElements ());
262 Array<int> recvCounts (numProcs);
263 const int rootProc = 0;
264 gather<int> (&myEltCount, 1, recvCounts.getRawPtr (), 1, rootProc, comm);
266 ArrayView<const GO> myGlobalElts = oneToOneMap->getNodeElementList ();
267 const int numMyGlobalElts = as<int> (myGlobalElts.size ());
270 ArrayRCP<GO> allGlobalElts;
272 allGlobalElts = Teuchos::arcp<GO> (oneToOneMap->getGlobalNumElements ());
273 std::fill (allGlobalElts.begin (), allGlobalElts.end (), 0);
277 *err << myRank <<
": computeGatherMap: Computing MPI_Gatherv "
278 "displacements" << endl;
284 Array<int> displs (numProcs, 0);
285 std::partial_sum (recvCounts.begin (), recvCounts.end () - 1,
286 displs.begin () + 1);
288 *err << myRank <<
": computeGatherMap: Calling MPI_Gatherv" << endl;
290 gatherv<GO> (myGlobalElts.getRawPtr (), numMyGlobalElts,
291 allGlobalElts.getRawPtr (), recvCounts.getRawPtr (),
292 displs.getRawPtr (), rootProc, comm);
295 *err << myRank <<
": computeGatherMap: Creating gather Map" << endl;
299 ArrayView<const GO> allElts (NULL, 0);
301 allElts = allGlobalElts ();
303 const global_size_t INVALID = Teuchos::OrdinalTraits<global_size_t>::invalid ();
304 gatherMap = rcp (
new MapType (INVALID, allElts,
305 oneToOneMap->getIndexBase (),
308 if (! err.is_null ()) {
312 *err << myRank <<
": computeGatherMap: done" << endl;
314 if (! err.is_null ()) {
323 #endif // __Tpetra_ComputeGatherMap_hpp
size_t global_size_t
Global size_t object.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createOneToOne(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &M)
Nonmember constructor for a contiguous Map with user-defined weights and a user-specified, possibly nondefault Kokkos Node type.