Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_Details_iallreduce.cpp
1// @HEADER
2// *****************************************************************************
3// Tpetra: Templated Linear Algebra Services Package
4//
5// Copyright 2008 NTESS and the Tpetra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Tpetra_ConfigDefs.hpp"
12
13#ifdef HAVE_TPETRACORE_MPI
14#include "Teuchos_DefaultMpiComm.hpp" // only needs to be in .cpp file
15#endif // HAVE_TPETRACORE_MPI
16#include "Teuchos_DefaultSerialComm.hpp" // only needs to be in .cpp file
17
18namespace Tpetra {
19namespace Details {
20
21#ifdef HAVE_TPETRACORE_MPI
22std::string getMpiErrorString(const int errCode) {
23 // Space for storing the error string returned by MPI.
24 // Leave room for null termination, since I don't know if MPI does this.
25 char errString[MPI_MAX_ERROR_STRING + 1];
26 int errStringLen = MPI_MAX_ERROR_STRING; // output argument
27 (void)MPI_Error_string(errCode, errString, &errStringLen);
28 // errStringLen on output is the number of characters written.
29 // I'm not sure (the MPI 3.0 Standard doesn't say) if this
30 // includes the '\0', so I'll make sure. We reserved space for
31 // the extra '\0' if needed.
32 if (errString[errStringLen - 1] != '\0') {
33 errString[errStringLen] = '\0';
34 }
35 return std::string(errString); // This copies the original string.
36}
37#endif // HAVE_TPETRACORE_MPI
38
39namespace Impl {
40
41std::shared_ptr<CommRequest>
42emptyCommRequest() {
43 return std::shared_ptr<CommRequest>(new CommRequest());
44}
45
46#ifdef HAVE_TPETRACORE_MPI
47
48#if MPI_VERSION >= 3
49MPI_Request
50iallreduceRaw(const void* sendbuf,
51 void* recvbuf,
52 const int count,
53 MPI_Datatype mpiDatatype,
54 const Teuchos::EReductionType op,
55 MPI_Comm comm) {
56 MPI_Op rawOp = ::Teuchos::Details::getMpiOpForEReductionType(op);
57 MPI_Request req = MPI_REQUEST_NULL;
58 int err = MPI_SUCCESS;
59 if (sendbuf == recvbuf) {
60 // Fix for #850. This only works if rawComm is an
61 // intracommunicator. Intercommunicators don't have an in-place
62 // option for collectives.
63 err = MPI_Iallreduce(MPI_IN_PLACE, recvbuf, count, mpiDatatype,
64 rawOp, comm, &req);
65 } else {
66 err = MPI_Iallreduce(sendbuf, recvbuf, count, mpiDatatype,
67 rawOp, comm, &req);
68 }
69 TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error,
70 "MPI_Iallreduce failed with the following error: "
71 << getMpiErrorString(err));
72 return req;
73}
74#endif // MPI >= 3
75
76void allreduceRaw(const void* sendbuf,
77 void* recvbuf,
78 const int count,
79 MPI_Datatype mpiDatatype,
80 const Teuchos::EReductionType op,
81 MPI_Comm comm) {
82 MPI_Op rawOp = ::Teuchos::Details::getMpiOpForEReductionType(op);
83 int err = MPI_SUCCESS;
84 if (sendbuf == recvbuf) {
85 err = MPI_Allreduce(MPI_IN_PLACE, recvbuf,
86 count, mpiDatatype, rawOp, comm);
87 } else {
88 // OpenMPI 1.6.5 insists on void*, not const void*, for sendbuf.
89 (void)MPI_Allreduce(const_cast<void*>(sendbuf), recvbuf,
90 count, mpiDatatype, rawOp, comm);
91 }
92 TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error,
93 "MPI_Allreduce failed with the following error: "
94 << getMpiErrorString(err));
95}
96
97#endif // HAVE_TPETRACORE_MPI
98
99} // namespace Impl
100
101template <class ValueType>
102std::shared_ptr<CommRequest>
103iallreduce(const ValueType localValue,
104 ValueType& globalValue,
105 const ::Teuchos::EReductionType op,
106 const ::Teuchos::Comm<int>& comm) {
107 // Input: needs to be an owning view containing localValue
108 Kokkos::View<ValueType*, Kokkos::HostSpace> localView(
109 Kokkos::ViewAllocateWithoutInitializing("localValue"), 1);
110 localView(0) = localValue;
111 Kokkos::View<ValueType*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>>
112 globalView(&globalValue, 1);
113 return ::Tpetra::Details::iallreduce<decltype(localView), decltype(globalView)>(localView, globalView, op, comm);
114}
115
116} // namespace Details
117} // namespace Tpetra
118
119template std::shared_ptr<Tpetra::Details::CommRequest> Tpetra::Details::iallreduce(const int,
120 int&,
121 const ::Teuchos::EReductionType,
122 const ::Teuchos::Comm<int>&);
123template std::shared_ptr<Tpetra::Details::CommRequest> Tpetra::Details::iallreduce(const Tpetra::global_size_t,
125 const ::Teuchos::EReductionType,
126 const ::Teuchos::Comm<int>&);
Declaration of Tpetra::Details::iallreduce.
Struct that holds views of the contents of a CrsMatrix.
Implementation details of Tpetra.
Namespace Tpetra contains the class and methods constituting the Tpetra library.