Tpetra parallel linear algebra  Version of the Day
Tpetra_Details_iallreduce.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_DETAILS_IALLREDUCE_HPP
43 #define TPETRA_DETAILS_IALLREDUCE_HPP
44 
60 
61 #include "TpetraCore_config.h"
62 #include "Teuchos_EReductionType.hpp"
63 #ifdef HAVE_TPETRACORE_MPI
66 #endif // HAVE_TPETRACORE_MPI
67 #include "Kokkos_Core.hpp"
68 #include <memory>
69 #include <stdexcept>
70 #include <type_traits>
71 #include <functional>
72 
73 #ifndef DOXYGEN_SHOULD_SKIP_THIS
74 namespace Teuchos {
75  // forward declaration of Comm
76  template<class OrdinalType> class Comm;
77 } // namespace Teuchos
78 #endif // NOT DOXYGEN_SHOULD_SKIP_THIS
79 
80 namespace Tpetra {
81 namespace Details {
82 
85 class CommRequest {
86 public:
88  virtual ~CommRequest () {}
89 
94  virtual void wait () = 0;
95 
99  virtual void cancel () = 0;
100 };
101 
102 // Don't rely on anything in this namespace. You shouldn't be relying
103 // on anything in Tpetra::Details anyway. You _especially_ shouldn't
104 // be relying on anything in Tpetra::Details::Impl. Consider
105 // yourselves warned!
106 namespace Impl {
107 
109 std::shared_ptr<CommRequest>
110 emptyCommRequest ();
111 
112 #ifdef HAVE_TPETRACORE_MPI
113 
127 class MpiCommRequest : public CommRequest {
128 public:
130  MpiCommRequest ();
131 
133  MpiCommRequest (const MPI_Request req);
134 
136  virtual ~MpiCommRequest ();
137 
143  virtual void wait ();
144 
151  virtual void waitWithStatus (MPI_Status& status);
152 
154  virtual void cancel ();
155 
156 private:
157  MPI_Request req_;
158 };
159 #endif // HAVE_TPETRACORE_MPI
160 
166 public:
169 
176  DeferredActionCommRequest (std::function<void () > action);
177 
179  void wait ();
180 
185  void cancel ();
186 
187 private:
189  std::function<void(void) > action_;
191  bool actionTaken_;
192 };
193 
220 template<class PacketType,
221  class SendLayoutType,
222  class SendDeviceType,
223  class RecvLayoutType,
224  class RecvDeviceType,
225  const int rank>
227 
229 template<class PacketType,
230  class SendLayoutType,
231  class SendDeviceType,
232  class RecvLayoutType,
233  class RecvDeviceType>
234 class IallreduceCommRequest<PacketType,
235  SendLayoutType,
236  SendDeviceType,
237  RecvLayoutType,
238  RecvDeviceType,
239  1> :
240  public CommRequest {
241 public:
244  {}
245 
247  typedef ::Kokkos::View<const PacketType*, SendLayoutType,
248  SendDeviceType> send_buffer_type;
250  typedef ::Kokkos::View<PacketType*, RecvLayoutType,
251  RecvDeviceType> recv_buffer_type;
252 
256  IallreduceCommRequest (const std::shared_ptr<CommRequest>& req,
257  const send_buffer_type& sendbuf,
258  const recv_buffer_type& recvbuf) :
259  req_ (req),
260  sendbuf_ (sendbuf),
261  recvbuf_ (recvbuf)
262  {
263  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
264  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
265  "SendLayoutType must be either Kokkos::LayoutLeft or "
266  "Kokkos::LayoutRight.");
267  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
268  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
269  "RecvLayoutType must be either Kokkos::LayoutLeft or "
270  "Kokkos::LayoutRight.");
271  }
272 
275  if (req_.get () != NULL) {
276  // We're in a destructor, so don't throw. We'll just try our best
277  // to handle whatever happens here without throwing.
278  try {
279  req_->cancel ();
280  }
281  catch (...) {}
282 
283  try {
284  req_ = std::shared_ptr<CommRequest> ();
285  }
286  catch (...) {}
287  }
288  }
289 
294  void
295  wait ()
296  {
297  if (req_.get () != NULL) {
298  req_->wait ();
299  // Relinquish request handle.
300  req_ = std::shared_ptr<CommRequest> ();
301  }
302  // Relinquish references to saved buffers, if we have not already
303  // done so. This operation is idempotent.
304  sendbuf_ = send_buffer_type ();
305  recvbuf_ = recv_buffer_type ();
306  }
307 
311  void
313  {
314  if (req_.get () != NULL) {
315  req_->cancel ();
316  // Relinquish request handle.
317  req_ = std::shared_ptr<CommRequest> ();
318  }
319  // Relinquish references to saved buffers, if we have not already
320  // done so. This operation is idempotent.
321  sendbuf_ = send_buffer_type ();
322  recvbuf_ = recv_buffer_type ();
323  }
324 
325 private:
327  std::shared_ptr<CommRequest> req_;
328 
330  send_buffer_type sendbuf_;
331 
333  recv_buffer_type recvbuf_;
334 };
335 
337 template<class PacketType,
338  class SendLayoutType,
339  class SendDeviceType,
340  class RecvLayoutType,
341  class RecvDeviceType>
342 class IallreduceCommRequest<PacketType,
343  SendLayoutType,
344  SendDeviceType,
345  RecvLayoutType,
346  RecvDeviceType,
347  0> :
348  public CommRequest {
349 public:
352  {}
353 
355  typedef ::Kokkos::View<const PacketType, SendLayoutType,
356  SendDeviceType> send_buffer_type;
358  typedef ::Kokkos::View<PacketType, RecvLayoutType,
359  RecvDeviceType> recv_buffer_type;
360 
364  IallreduceCommRequest (const std::shared_ptr<CommRequest>& req,
365  const send_buffer_type& sendbuf,
366  const recv_buffer_type& recvbuf) :
367  req_ (req),
368  sendbuf_ (sendbuf),
369  recvbuf_ (recvbuf)
370  {
371  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
372  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
373  "SendLayoutType must be either Kokkos::LayoutLeft or "
374  "Kokkos::LayoutRight.");
375  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
376  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
377  "RecvLayoutType must be either Kokkos::LayoutLeft or "
378  "Kokkos::LayoutRight.");
379  }
380 
383  if (req_.get () != NULL) {
384  // We're in a destructor, so don't throw. We'll just try our best
385  // to handle whatever happens here without throwing.
386  try {
387  req_->cancel ();
388  }
389  catch (...) {}
390 
391  try {
392  req_ = std::shared_ptr<CommRequest> ();
393  }
394  catch (...) {}
395  }
396  }
397 
402  void
403  wait ()
404  {
405  if (req_.get () != NULL) {
406  req_->wait ();
407  // Relinquish request handle.
408  req_ = std::shared_ptr<CommRequest> ();
409  }
410  // Relinquish references to saved buffers, if we have not already
411  // done so. This operation is idempotent.
412  sendbuf_ = send_buffer_type ();
413  recvbuf_ = recv_buffer_type ();
414  }
415 
419  void
421  {
422  if (req_.get () != NULL) {
423  req_->cancel ();
424  // Relinquish request handle.
425  req_ = std::shared_ptr<CommRequest> ();
426  }
427  // Relinquish references to saved buffers, if we have not already
428  // done so. This operation is idempotent.
429  sendbuf_ = send_buffer_type ();
430  recvbuf_ = recv_buffer_type ();
431  }
432 
433 private:
435  std::shared_ptr<CommRequest> req_;
436 
438  send_buffer_type sendbuf_;
439 
441  recv_buffer_type recvbuf_;
442 };
443 
476 template<class PacketType,
477  class SendLayoutType,
478  class SendDeviceType,
479  class RecvLayoutType,
480  class RecvDeviceType>
481 std::shared_ptr<CommRequest>
482 wrapIallreduceCommRequest (const std::shared_ptr<CommRequest>& req,
483  const ::Kokkos::View<const PacketType*,
484  SendLayoutType,
485  SendDeviceType>& sendbuf,
486  const ::Kokkos::View<PacketType*,
487  RecvLayoutType,
488  RecvDeviceType>& recvbuf)
489 {
490  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
491  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
492  "SendLayoutType must be either Kokkos::LayoutLeft or "
493  "Kokkos::LayoutRight.");
494  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
495  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
496  "RecvLayoutType must be either Kokkos::LayoutLeft or "
497  "Kokkos::LayoutRight.");
498  typedef IallreduceCommRequest<PacketType, SendLayoutType, SendDeviceType,
499  RecvLayoutType, RecvDeviceType, 1> req_type;
500  return std::shared_ptr<CommRequest> (new req_type (req, sendbuf, recvbuf));
501 }
502 
535 template<class PacketType,
536  class SendLayoutType,
537  class SendDeviceType,
538  class RecvLayoutType,
539  class RecvDeviceType>
540 std::shared_ptr<CommRequest>
541 wrapIallreduceCommRequest (const std::shared_ptr<CommRequest>& req,
542  const ::Kokkos::View<const PacketType,
543  SendLayoutType,
544  SendDeviceType>& sendbuf,
545  const ::Kokkos::View<PacketType,
546  RecvLayoutType,
547  RecvDeviceType>& recvbuf)
548 {
549  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
550  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
551  "SendLayoutType must be either Kokkos::LayoutLeft or "
552  "Kokkos::LayoutRight.");
553  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
554  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
555  "RecvLayoutType must be either Kokkos::LayoutLeft or "
556  "Kokkos::LayoutRight.");
557  typedef IallreduceCommRequest<PacketType, SendLayoutType, SendDeviceType,
558  RecvLayoutType, RecvDeviceType, 0> req_type;
559  return std::shared_ptr<CommRequest> (new req_type (req, sendbuf, recvbuf));
560 }
561 
562 #ifdef HAVE_TPETRACORE_MPI
563 
574 std::shared_ptr<CommRequest>
575 iallreduceRawVoid (const void* sendbuf,
576  void* recvbuf,
577  const int count,
578  MPI_Datatype mpiDatatype,
579  const bool mpiDatatypeNeedsFree,
580  const Teuchos::EReductionType op,
581  MPI_Comm comm);
582 
583 #endif // HAVE_TPETRACORE_MPI
584 
593 template<class Packet>
594 std::shared_ptr<CommRequest>
595 iallreduceRaw (const Packet sendbuf[],
596  Packet recvbuf[],
597  const int count,
598  const ::Teuchos::EReductionType op,
599  const ::Teuchos::Comm<int>& comm)
600 {
601 #ifdef HAVE_TPETRACORE_MPI
602  using ::Tpetra::Details::MpiTypeTraits;
603 
604  // mfh 12 Nov 2016: It's reasonable to assume that if users call
605  // this function with count > 1, then users should expect that all
606  // sent and received data have the same MPI_Datatype. If count is
607  // zero, then it doesn't matter what datatype we use, as long as
608  // it's not MPI_DATATYPE_NULL. For the latter, see e.g., the
609  // discussion here:
610  //
611  // http://lists.mpi-forum.org/pipermail/mpi-forum/2016-January/003159.html
612 
613  // FIXME (mfh 14 Nov 2016) For derived MPI_Datatype, it may make
614  // sense for us to cache them somewhere for later reuse, rather than
615  // constructing and freeing a new one each time.
616 
617  MPI_Datatype mpiDatatype = (count > 0) ?
618  MpiTypeTraits<Packet>::getType (sendbuf[0]) :
619  MPI_BYTE;
620  MPI_Comm rawComm = ::Tpetra::Details::extractMpiCommFromTeuchos (comm);
621  return iallreduceRawVoid (sendbuf, recvbuf, count, mpiDatatype,
622  MpiTypeTraits<Packet>::needsFree, op, rawComm);
623 #else // NOT HAVE_TPETRACORE_MPI
624  throw std::logic_error ("Tpetra::Details::Impl::iallreduceRaw: This function "
625  "should never be called if MPI is not enabled. "
626  "Please report this bug to the Tpetra developers.");
627 #endif // HAVE_TPETRACORE_MPI
628 }
629 
652 template<class PacketType,
653  class SendLayoutType,
654  class SendDeviceType,
655  class RecvLayoutType,
656  class RecvDeviceType,
657  const int rank>
658 struct Iallreduce {};
659 
661 template<class PacketType,
662  class SendLayoutType,
663  class SendDeviceType,
664  class RecvLayoutType,
665  class RecvDeviceType>
666 struct Iallreduce<PacketType,
667  SendLayoutType,
668  SendDeviceType,
669  RecvLayoutType,
670  RecvDeviceType,
671  1> {
672  typedef ::Kokkos::View<const PacketType*,
673  SendLayoutType,
674  SendDeviceType> send_buffer_type;
675  typedef ::Kokkos::View<PacketType*,
676  RecvLayoutType,
677  RecvDeviceType> recv_buffer_type;
678 
679  static std::shared_ptr<CommRequest>
680  iallreduce (const send_buffer_type& sendbuf,
681  const recv_buffer_type& recvbuf,
682  const ::Teuchos::EReductionType op,
683  const ::Teuchos::Comm<int>& comm)
684  {
685  static_assert (! std::is_const<PacketType>::value,
686  "PacketType must be a nonconst type.");
687  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
688  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
689  "SendLayoutType must be either Kokkos::LayoutLeft or "
690  "Kokkos::LayoutRight.");
691  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
692  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
693  "RecvLayoutType must be either Kokkos::LayoutLeft or "
694  "Kokkos::LayoutRight.");
695 #ifdef HAVE_TPETRACORE_MPI
696  // Avoid instantiating Impl::iallreduceRaw for both T and const T,
697  // by canonicalizing to the non-const version of T.
698  typedef typename std::remove_const<PacketType>::type packet_type;
699 
700  std::shared_ptr<CommRequest> req =
701  Impl::iallreduceRaw<packet_type> (sendbuf.ptr_on_device (),
702  recvbuf.ptr_on_device (),
703  static_cast<int> (sendbuf.dimension_0 ()),
704  op, comm);
705  return Impl::wrapIallreduceCommRequest (req, sendbuf, recvbuf);
706 #else // NOT HAVE_TPETRACORE_MPI
707 
708  // MPI is disabled, so comm is a SerialComm.
709  // Avoid needing to check the SerialComm case in Impl::iallreduce.
710  // That lets Impl::iallreduce not need to know about DeviceType.
711  ::Kokkos::deep_copy (recvbuf, sendbuf);
712  // This request has already finished. There's nothing more to do.
713  return Impl::emptyCommRequest ();
714 #endif // HAVE_TPETRACORE_MPI
715  }
716 };
717 
719 template<class PacketType,
720  class SendLayoutType,
721  class SendDeviceType,
722  class RecvLayoutType,
723  class RecvDeviceType>
724 struct Iallreduce<PacketType,
725  SendLayoutType,
726  SendDeviceType,
727  RecvLayoutType,
728  RecvDeviceType,
729  0> {
730  // mfh 02 Jan 2017: For rank-0 Views, LayoutLeft and LayoutRight are
731  // unfortunately NOT mutually assignable, even though it would make
732  // sense for this to be the case. That's why we have to template on
733  // the layout types.
734  typedef ::Kokkos::View<const PacketType,
735  SendLayoutType,
736  SendDeviceType> send_buffer_type;
737  typedef ::Kokkos::View<PacketType,
738  RecvLayoutType,
739  RecvDeviceType> recv_buffer_type;
740 
741  static std::shared_ptr<CommRequest>
742  iallreduce (const send_buffer_type& sendbuf,
743  const recv_buffer_type& recvbuf,
744  const ::Teuchos::EReductionType op,
745  const ::Teuchos::Comm<int>& comm)
746  {
747  static_assert (! std::is_const<PacketType>::value,
748  "PacketType must be a nonconst type.");
749  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
750  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
751  "SendLayoutType must be either Kokkos::LayoutLeft or "
752  "Kokkos::LayoutRight.");
753  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
754  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
755  "RecvLayoutType must be either Kokkos::LayoutLeft or "
756  "Kokkos::LayoutRight.");
757 #ifdef HAVE_TPETRACORE_MPI
758  // Avoid instantiating Impl::iallreduceRaw for both T and const T,
759  // by canonicalizing to the non-const version of T.
760  typedef typename std::remove_const<PacketType>::type packet_type;
761 
762  std::shared_ptr<CommRequest> req =
763  Impl::iallreduceRaw<packet_type> (sendbuf.ptr_on_device (),
764  recvbuf.ptr_on_device (),
765  static_cast<int> (1),
766  op, comm);
767  return Impl::wrapIallreduceCommRequest (req, sendbuf, recvbuf);
768 #else // NOT HAVE_TPETRACORE_MPI
769 
770  // MPI is disabled, so comm is a SerialComm.
771  // Avoid needing to check the SerialComm case in Impl::iallreduce.
772  // That lets Impl::iallreduce not need to know about DeviceType.
773  ::Kokkos::deep_copy (recvbuf, sendbuf);
774  // This request has already finished. There's nothing more to do.
775  return Impl::emptyCommRequest ();
776 #endif // HAVE_TPETRACORE_MPI
777  }
778 };
779 
780 } // namespace Impl
781 
782 //
783 // SKIP DOWN TO HERE
784 //
785 
811 template<class InputViewType, class OutputViewType>
812 std::shared_ptr<CommRequest>
813 iallreduce (const InputViewType& sendbuf,
814  const OutputViewType& recvbuf,
815  const ::Teuchos::EReductionType op,
816  const ::Teuchos::Comm<int>& comm)
817 {
818  static_assert (Kokkos::Impl::is_view<InputViewType>::value,
819  "InputViewType must be a Kokkos::View specialization.");
820  static_assert (Kokkos::Impl::is_view<OutputViewType>::value,
821  "OutputViewType must be a Kokkos::View specialization.");
822  constexpr int rank = static_cast<int> (OutputViewType::rank);
823  static_assert (static_cast<int> (InputViewType::rank) == rank,
824  "InputViewType and OutputViewType must have the same rank.");
825  static_assert (rank == 0 || rank == 1,
826  "InputViewType and OutputViewType must both have "
827  "rank 0 or rank 1.");
828  typedef typename OutputViewType::non_const_value_type packet_type;
829  static_assert (std::is_same<typename OutputViewType::value_type,
830  packet_type>::value,
831  "OutputViewType must be a nonconst Kokkos::View.");
832  static_assert (std::is_same<typename InputViewType::non_const_value_type,
833  packet_type>::value,
834  "InputViewType and OutputViewType must be Views "
835  "whose entries have the same type.");
836  typedef typename InputViewType::array_layout send_layout_type;
837  typedef typename OutputViewType::array_layout recv_layout_type;
838  typedef typename InputViewType::device_type send_device_type;
839  typedef typename OutputViewType::device_type recv_device_type;
840 
841  typedef Impl::Iallreduce<packet_type, send_layout_type, send_device_type,
842  recv_layout_type, recv_device_type, rank> impl_type;
843  return impl_type::iallreduce (sendbuf, recvbuf, op, comm);
844 }
845 
846 } // namespace Details
847 } // namespace Tpetra
848 
849 #endif // TPETRA_DETAILS_IALLREDUCE_HPP
IallreduceCommRequest(const std::shared_ptr< CommRequest > &req, const send_buffer_type &sendbuf, const recv_buffer_type &recvbuf)
Constructor that takes a wrapped request (representing the pending MPI_Iallreduce operation itself)...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
std::shared_ptr< CommRequest > wrapIallreduceCommRequest(const std::shared_ptr< CommRequest > &req, const ::Kokkos::View< const PacketType *, SendLayoutType, SendDeviceType > &sendbuf, const ::Kokkos::View< PacketType *, RecvLayoutType, RecvDeviceType > &recvbuf)
Function for wrapping the CommRequest to be returned from Tpetra::Details::iallreduce; overload for r...
Declaration of Tpetra::Details::extractMpiCommFromTeuchos.
Add specializations of Teuchos::Details::MpiTypeTraits for Kokkos::complex<float> and Kokkos::complex...
::Kokkos::View< const PacketType, SendLayoutType, SendDeviceType > send_buffer_type
Type of the send buffer.
void deep_copy(MultiVector< DS, DL, DG, DN, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
Object representing a pending Tpetra::Details::iallreduce operation.
::Kokkos::View< const PacketType *, SendLayoutType, SendDeviceType > send_buffer_type
Type of the send buffer.
Implementation details of Tpetra.
::Kokkos::View< PacketType *, RecvLayoutType, RecvDeviceType > recv_buffer_type
Type of the receive buffer.
Implementation of Tpetra::Details::iallreduce.
Part of the Work-around for not having MPI >= 3.
IallreduceCommRequest(const std::shared_ptr< CommRequest > &req, const send_buffer_type &sendbuf, const recv_buffer_type &recvbuf)
Constructor that takes a wrapped request (representing the pending MPI_Iallreduce operation itself)...
Base class for the request (more or less a future) representing a pending nonblocking MPI operation...
std::shared_ptr< CommRequest > iallreduce(const InputViewType &sendbuf, const OutputViewType &recvbuf, const ::Teuchos::EReductionType op, const ::Teuchos::Comm< int > &comm)
Nonblocking all-reduce, for either rank-1 or rank-0 Kokkos::View objects.
std::shared_ptr< CommRequest > iallreduceRaw(const Packet sendbuf[], Packet recvbuf[], const int count, const ::Teuchos::EReductionType op, const ::Teuchos::Comm< int > &comm)
Second lowest-level implementation of Tpetra::Details::iallreduce (see bottom of this header file)...
virtual ~CommRequest()
Destructor (virtual for memory safety of derived classes).