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)
49 template <
class IntType>
50 TRILINOS_UNUSED_FUNCTION MPI_Datatype
52 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
53 "Not implemented for IntType != int, long, or long long");
57 TRILINOS_UNUSED_FUNCTION MPI_Datatype
58 getMpiDatatype<int>() {
return MPI_INT; }
61 TRILINOS_UNUSED_FUNCTION MPI_Datatype
62 getMpiDatatype<long>() {
return MPI_LONG; }
65 TRILINOS_UNUSED_FUNCTION MPI_Datatype
66 getMpiDatatype<long long>() {
return MPI_LONG_LONG; }
69 template <
class IntType>
70 void gather(
const IntType sendbuf[],
const int sendcnt,
71 IntType recvbuf[],
const int recvcnt,
72 const int root,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm) {
74 using Teuchos::rcp_dynamic_cast;
76 using Teuchos::MpiComm;
79 RCP<const MpiComm<int> > mpiComm = rcp_dynamic_cast<
const MpiComm<int> >(comm);
80 if (!mpiComm.is_null()) {
81 MPI_Datatype sendtype = getMpiDatatype<IntType>();
82 MPI_Datatype recvtype = sendtype;
83 MPI_Comm rawMpiComm = *(mpiComm->getRawMpiComm());
84 const int err = MPI_Gather(reinterpret_cast<void*>(const_cast<IntType*>(sendbuf)),
87 reinterpret_cast<void*>(recvbuf),
92 TEUCHOS_TEST_FOR_EXCEPTION(
93 err != MPI_SUCCESS, std::runtime_error,
"MPI_Gather failed");
98 TEUCHOS_TEST_FOR_EXCEPTION(
99 recvcnt > sendcnt, std::invalid_argument,
100 "gather: If the input communicator contains only one process, "
101 "then you cannot receive more entries than you send. "
102 "You aim to receive "
103 << recvcnt <<
" entries, "
108 std::copy(sendbuf, sendbuf + recvcnt, recvbuf);
111 template <
class IntType>
112 void gatherv(
const IntType sendbuf[],
const int sendcnt,
113 IntType recvbuf[],
const int recvcnts[],
const int displs[],
114 const int root,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm) {
116 using Teuchos::rcp_dynamic_cast;
118 using Teuchos::MpiComm;
122 RCP<const MpiComm<int> > mpiComm =
123 rcp_dynamic_cast<
const MpiComm<int> >(comm);
124 if (!mpiComm.is_null()) {
125 MPI_Datatype sendtype = getMpiDatatype<IntType>();
126 MPI_Datatype recvtype = sendtype;
127 MPI_Comm rawMpiComm = *(mpiComm->getRawMpiComm());
128 const int err = MPI_Gatherv(reinterpret_cast<void*>(const_cast<IntType*>(sendbuf)),
131 reinterpret_cast<void*>(recvbuf),
132 const_cast<int*>(recvcnts),
133 const_cast<int*>(displs),
137 TEUCHOS_TEST_FOR_EXCEPTION(
138 err != MPI_SUCCESS, std::runtime_error,
"MPI_Gatherv failed");
142 TEUCHOS_TEST_FOR_EXCEPTION(
143 recvcnts[0] > sendcnt,
144 std::invalid_argument,
145 "gatherv: If the input communicator contains only one process, "
146 "then you cannot receive more entries than you send. "
147 "You aim to receive "
148 << recvcnts[0] <<
" entries, "
154 std::copy(sendbuf, sendbuf + recvcnts[0], recvbuf + displs[0]);
161 template <
class MapType>
162 Teuchos::RCP<const MapType>
163 computeGatherMap(Teuchos::RCP<const MapType> map,
164 const Teuchos::RCP<Teuchos::FancyOStream>& err,
165 const bool dbg =
false) {
167 using Teuchos::Array;
168 using Teuchos::ArrayRCP;
169 using Teuchos::ArrayView;
175 typedef typename MapType::local_ordinal_type LO;
176 typedef typename MapType::global_ordinal_type GO;
177 typedef typename MapType::node_type NT;
179 RCP<const Comm<int> > comm = map->getComm();
180 const int numProcs = comm->getSize();
181 const int myRank = comm->getRank();
183 if (!err.is_null()) {
187 *err << myRank <<
": computeGatherMap:" << endl;
189 if (!err.is_null()) {
193 RCP<const MapType> oneToOneMap;
194 if (map->isContiguous()) {
198 *err << myRank <<
": computeGatherMap: Calling createOneToOne" << endl;
203 oneToOneMap = createOneToOne<LO, GO, NT>(map);
206 RCP<const MapType> gatherMap;
208 gatherMap = oneToOneMap;
211 *err << myRank <<
": computeGatherMap: Gathering Map counts" << endl;
230 const int myEltCount = as<int>(oneToOneMap->getLocalNumElements());
231 Array<int> recvCounts(numProcs);
232 const int rootProc = 0;
233 gather<int>(&myEltCount, 1, recvCounts.getRawPtr(), 1, rootProc, comm);
235 ArrayView<const GO> myGlobalElts = oneToOneMap->getLocalElementList();
236 const int numMyGlobalElts = as<int>(myGlobalElts.size());
239 ArrayRCP<GO> allGlobalElts;
241 allGlobalElts = Teuchos::arcp<GO>(oneToOneMap->getGlobalNumElements());
242 std::fill(allGlobalElts.begin(), allGlobalElts.end(), 0);
246 *err << myRank <<
": computeGatherMap: Computing MPI_Gatherv "
254 Array<int> displs(numProcs, 0);
255 std::partial_sum(recvCounts.begin(), recvCounts.end() - 1,
258 *err << myRank <<
": computeGatherMap: Calling MPI_Gatherv" << endl;
260 gatherv<GO>(myGlobalElts.getRawPtr(), numMyGlobalElts,
261 allGlobalElts.getRawPtr(), recvCounts.getRawPtr(),
262 displs.getRawPtr(), rootProc, comm);
265 *err << myRank <<
": computeGatherMap: Creating gather Map" << endl;
269 ArrayView<const GO> allElts(NULL, 0);
271 allElts = allGlobalElts();
273 const global_size_t INVALID = Teuchos::OrdinalTraits<global_size_t>::invalid();
274 gatherMap = rcp(
new MapType(INVALID, allElts,
275 oneToOneMap->getIndexBase(),
278 if (!err.is_null()) {
282 *err << myRank <<
": computeGatherMap: done" << endl;
284 if (!err.is_null()) {
293 #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.