10 #ifndef __Tpetra_ComputeGatherMap_hpp
11 #define __Tpetra_ComputeGatherMap_hpp
17 #include "Tpetra_Map.hpp"
22 #if ! defined(TRILINOS_UNUSED_FUNCTION)
23 # if defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
24 # define TRILINOS_UNUSED_FUNCTION __attribute__((__unused__))
25 # elif defined(__clang__)
26 # if __has_attribute(unused)
27 # define TRILINOS_UNUSED_FUNCTION __attribute__((__unused__))
29 # define TRILINOS_UNUSED_FUNCTION
30 # endif // Clang has 'unused' attribute
31 # elif defined(__IBMCPP__)
35 # define TRILINOS_UNUSED_FUNCTION
36 # else // some other compiler
37 # define TRILINOS_UNUSED_FUNCTION
39 #endif // ! defined(TRILINOS_UNUSED_FUNCTION)
50 template<
class IntType> TRILINOS_UNUSED_FUNCTION MPI_Datatype
52 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
53 "Not implemented for IntType != int, long, or long long");
56 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
57 getMpiDatatype<int> () {
return MPI_INT; }
59 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
60 getMpiDatatype<long> () {
return MPI_LONG; }
62 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
63 getMpiDatatype<long long> () {
return MPI_LONG_LONG; }
66 template<
class IntType>
68 gather (
const IntType sendbuf[],
const int sendcnt,
69 IntType recvbuf[],
const int recvcnt,
70 const int root,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
73 using Teuchos::rcp_dynamic_cast;
75 using Teuchos::MpiComm;
78 RCP<const MpiComm<int> > mpiComm = rcp_dynamic_cast<
const MpiComm<int> > (comm);
79 if (! mpiComm.is_null ()) {
80 MPI_Datatype sendtype = getMpiDatatype<IntType> ();
81 MPI_Datatype recvtype = sendtype;
82 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
83 const int err = MPI_Gather (reinterpret_cast<void*> (const_cast<IntType*> (sendbuf)),
86 reinterpret_cast<void*> (recvbuf),
91 TEUCHOS_TEST_FOR_EXCEPTION(
92 err != MPI_SUCCESS, std::runtime_error,
"MPI_Gather failed");
97 TEUCHOS_TEST_FOR_EXCEPTION(
98 recvcnt > sendcnt, std::invalid_argument,
99 "gather: If the input communicator contains only one process, "
100 "then you cannot receive more entries than you send. "
101 "You aim to receive " << recvcnt <<
" entries, "
102 "but to send " << sendcnt <<
".");
105 std::copy (sendbuf, sendbuf + recvcnt, recvbuf);
108 template<
class IntType>
110 gatherv (
const IntType sendbuf[],
const int sendcnt,
111 IntType recvbuf[],
const int recvcnts[],
const int displs[],
112 const int root,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
115 using Teuchos::rcp_dynamic_cast;
117 using Teuchos::MpiComm;
121 RCP<const MpiComm<int> > mpiComm =
122 rcp_dynamic_cast<
const MpiComm<int> > (comm);
123 if (! mpiComm.is_null ()) {
124 MPI_Datatype sendtype = getMpiDatatype<IntType> ();
125 MPI_Datatype recvtype = sendtype;
126 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
127 const int err = MPI_Gatherv (reinterpret_cast<void*> (const_cast<IntType*> (sendbuf)),
130 reinterpret_cast<void*> (recvbuf),
131 const_cast<int*> (recvcnts),
132 const_cast<int*> (displs),
136 TEUCHOS_TEST_FOR_EXCEPTION(
137 err != MPI_SUCCESS, std::runtime_error,
"MPI_Gatherv failed");
141 TEUCHOS_TEST_FOR_EXCEPTION(
142 recvcnts[0] > sendcnt,
143 std::invalid_argument,
144 "gatherv: If the input communicator contains only one process, "
145 "then you cannot receive more entries than you send. "
146 "You aim to receive " << recvcnts[0] <<
" entries, "
147 "but to send " << sendcnt <<
".");
151 std::copy (sendbuf, sendbuf + recvcnts[0], recvbuf + displs[0]);
159 template<
class MapType>
160 Teuchos::RCP<const MapType>
161 computeGatherMap (Teuchos::RCP<const MapType> map,
162 const Teuchos::RCP<Teuchos::FancyOStream>& err,
163 const bool dbg=
false)
167 using Teuchos::Array;
168 using Teuchos::ArrayRCP;
169 using Teuchos::ArrayView;
174 typedef typename MapType::local_ordinal_type LO;
175 typedef typename MapType::global_ordinal_type GO;
176 typedef typename MapType::node_type NT;
178 RCP<const Comm<int> > comm = map->getComm ();
179 const int numProcs = comm->getSize ();
180 const int myRank = comm->getRank ();
182 if (! err.is_null ()) {
186 *err << myRank <<
": computeGatherMap:" << endl;
188 if (! err.is_null ()) {
192 RCP<const MapType> oneToOneMap;
193 if (map->isContiguous ()) {
197 *err << myRank <<
": computeGatherMap: Calling createOneToOne" << endl;
202 oneToOneMap = createOneToOne<LO, GO, NT> (map);
205 RCP<const MapType> gatherMap;
207 gatherMap = oneToOneMap;
210 *err << myRank <<
": computeGatherMap: Gathering Map counts" << endl;
229 const int myEltCount = as<int> (oneToOneMap->getLocalNumElements ());
230 Array<int> recvCounts (numProcs);
231 const int rootProc = 0;
232 gather<int> (&myEltCount, 1, recvCounts.getRawPtr (), 1, rootProc, comm);
234 ArrayView<const GO> myGlobalElts = oneToOneMap->getLocalElementList ();
235 const int numMyGlobalElts = as<int> (myGlobalElts.size ());
238 ArrayRCP<GO> allGlobalElts;
240 allGlobalElts = Teuchos::arcp<GO> (oneToOneMap->getGlobalNumElements ());
241 std::fill (allGlobalElts.begin (), allGlobalElts.end (), 0);
245 *err << myRank <<
": computeGatherMap: Computing MPI_Gatherv "
246 "displacements" << endl;
252 Array<int> displs (numProcs, 0);
253 std::partial_sum (recvCounts.begin (), recvCounts.end () - 1,
254 displs.begin () + 1);
256 *err << myRank <<
": computeGatherMap: Calling MPI_Gatherv" << endl;
258 gatherv<GO> (myGlobalElts.getRawPtr (), numMyGlobalElts,
259 allGlobalElts.getRawPtr (), recvCounts.getRawPtr (),
260 displs.getRawPtr (), rootProc, comm);
263 *err << myRank <<
": computeGatherMap: Creating gather Map" << endl;
267 ArrayView<const GO> allElts (NULL, 0);
269 allElts = allGlobalElts ();
271 const global_size_t INVALID = Teuchos::OrdinalTraits<global_size_t>::invalid ();
272 gatherMap = rcp (
new MapType (INVALID, allElts,
273 oneToOneMap->getIndexBase (),
276 if (! err.is_null ()) {
280 *err << myRank <<
": computeGatherMap: done" << endl;
282 if (! err.is_null ()) {
291 #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.