42 #ifndef __Tpetra_ComputeGatherMap_hpp 43 #define __Tpetra_ComputeGatherMap_hpp 49 #include "Tpetra_Map.hpp" 53 #if ! defined(TRILINOS_UNUSED_FUNCTION) 54 # if defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) 55 # define TRILINOS_UNUSED_FUNCTION __attribute__((__unused__)) 56 # elif defined(__clang__) 57 # if __has_attribute(unused) 58 # define TRILINOS_UNUSED_FUNCTION __attribute__((__unused__)) 60 # define TRILINOS_UNUSED_FUNCTION 61 # endif // Clang has 'unused' attribute 62 # elif defined(__IBMCPP__) 66 # define TRILINOS_UNUSED_FUNCTION 67 # else // some other compiler 68 # define TRILINOS_UNUSED_FUNCTION 70 #endif // ! defined(TRILINOS_UNUSED_FUNCTION) 81 template<
class IntType> TRILINOS_UNUSED_FUNCTION MPI_Datatype
83 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
84 "Not implemented for IntType != int, long, or long long");
87 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
88 getMpiDatatype<int> () {
return MPI_INT; }
90 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
91 getMpiDatatype<long> () {
return MPI_LONG; }
93 template<> TRILINOS_UNUSED_FUNCTION MPI_Datatype
94 getMpiDatatype<long long> () {
return MPI_LONG_LONG; }
97 template<
class IntType>
99 gather (
const IntType sendbuf[],
const int sendcnt,
100 IntType recvbuf[],
const int recvcnt,
101 const int root,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
104 using Teuchos::rcp_dynamic_cast;
106 using Teuchos::MpiComm;
109 RCP<const MpiComm<int> > mpiComm = rcp_dynamic_cast<
const MpiComm<int> > (comm);
110 if (! mpiComm.is_null ()) {
111 MPI_Datatype sendtype = getMpiDatatype<IntType> ();
112 MPI_Datatype recvtype = sendtype;
113 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
114 const int err = MPI_Gather (reinterpret_cast<void*> (const_cast<IntType*> (sendbuf)),
117 reinterpret_cast<void*> (recvbuf),
122 TEUCHOS_TEST_FOR_EXCEPTION(
123 err != MPI_SUCCESS, std::runtime_error,
"MPI_Gather failed");
128 TEUCHOS_TEST_FOR_EXCEPTION(
129 recvcnt > sendcnt, std::invalid_argument,
130 "gather: If the input communicator contains only one process, " 131 "then you cannot receive more entries than you send. " 132 "You aim to receive " << recvcnt <<
" entries, " 133 "but to send " << sendcnt <<
".");
136 std::copy (sendbuf, sendbuf + recvcnt, recvbuf);
139 template<
class IntType>
141 gatherv (
const IntType sendbuf[],
const int sendcnt,
142 IntType recvbuf[],
const int recvcnts[],
const int displs[],
143 const int root,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
146 using Teuchos::rcp_dynamic_cast;
148 using Teuchos::MpiComm;
152 RCP<const MpiComm<int> > mpiComm =
153 rcp_dynamic_cast<
const MpiComm<int> > (comm);
154 if (! mpiComm.is_null ()) {
155 MPI_Datatype sendtype = getMpiDatatype<IntType> ();
156 MPI_Datatype recvtype = sendtype;
157 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
158 const int err = MPI_Gatherv (reinterpret_cast<void*> (const_cast<IntType*> (sendbuf)),
161 reinterpret_cast<void*> (recvbuf),
162 const_cast<int*> (recvcnts),
163 const_cast<int*> (displs),
167 TEUCHOS_TEST_FOR_EXCEPTION(
168 err != MPI_SUCCESS, std::runtime_error,
"MPI_Gatherv failed");
172 TEUCHOS_TEST_FOR_EXCEPTION(
173 recvcnts[0] > sendcnt,
174 std::invalid_argument,
175 "gatherv: If the input communicator contains only one process, " 176 "then you cannot receive more entries than you send. " 177 "You aim to receive " << recvcnts[0] <<
" entries, " 178 "but to send " << sendcnt <<
".");
182 std::copy (sendbuf, sendbuf + recvcnts[0], recvbuf + displs[0]);
190 template<
class MapType>
191 Teuchos::RCP<const MapType>
192 computeGatherMap (Teuchos::RCP<const MapType> map,
193 const Teuchos::RCP<Teuchos::FancyOStream>& err,
194 const bool dbg=
false)
198 using Teuchos::Array;
199 using Teuchos::ArrayRCP;
200 using Teuchos::ArrayView;
205 typedef typename MapType::local_ordinal_type LO;
206 typedef typename MapType::global_ordinal_type GO;
207 typedef typename MapType::node_type NT;
209 RCP<const Comm<int> > comm = map->getComm ();
210 const int numProcs = comm->getSize ();
211 const int myRank = comm->getRank ();
213 if (! err.is_null ()) {
217 *err << myRank <<
": computeGatherMap:" << endl;
219 if (! err.is_null ()) {
223 RCP<const MapType> oneToOneMap;
224 if (map->isContiguous ()) {
228 *err << myRank <<
": computeGatherMap: Calling createOneToOne" << endl;
233 oneToOneMap = createOneToOne<LO, GO, NT> (map);
236 RCP<const MapType> gatherMap;
238 gatherMap = oneToOneMap;
241 *err << myRank <<
": computeGatherMap: Gathering Map counts" << endl;
260 const int myEltCount = as<int> (oneToOneMap->getNodeNumElements ());
261 Array<int> recvCounts (numProcs);
262 const int rootProc = 0;
263 gather<int> (&myEltCount, 1, recvCounts.getRawPtr (), 1, rootProc, comm);
265 ArrayView<const GO> myGlobalElts = oneToOneMap->getNodeElementList ();
266 const int numMyGlobalElts = as<int> (myGlobalElts.size ());
269 ArrayRCP<GO> allGlobalElts;
271 allGlobalElts = arcp<GO> (oneToOneMap->getGlobalNumElements ());
272 std::fill (allGlobalElts.begin (), allGlobalElts.end (), 0);
276 *err << myRank <<
": computeGatherMap: Computing MPI_Gatherv " 277 "displacements" << endl;
283 Array<int> displs (numProcs, 0);
284 std::partial_sum (recvCounts.begin (), recvCounts.end () - 1,
285 displs.begin () + 1);
287 *err << myRank <<
": computeGatherMap: Calling MPI_Gatherv" << endl;
289 gatherv<GO> (myGlobalElts.getRawPtr (), numMyGlobalElts,
290 allGlobalElts.getRawPtr (), recvCounts.getRawPtr (),
291 displs.getRawPtr (), rootProc, comm);
294 *err << myRank <<
": computeGatherMap: Creating gather Map" << endl;
298 ArrayView<const GO> allElts (NULL, 0);
300 allElts = allGlobalElts ();
302 const global_size_t INVALID = Teuchos::OrdinalTraits<global_size_t>::invalid ();
303 gatherMap = rcp (
new MapType (INVALID, allElts,
304 oneToOneMap->getIndexBase (),
305 comm, map->getNode ()));
307 if (! err.is_null ()) {
311 *err << myRank <<
": computeGatherMap: done" << endl;
313 if (! err.is_null ()) {
322 #endif // __Tpetra_ComputeGatherMap_hpp Namespace Tpetra contains the class and methods constituting the Tpetra library.
Implementation details of Tpetra.
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)
Creates a one-to-one version of the given Map where each GID is owned by only one process...