Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
89 class CommRequest {
90 public:
92  virtual ~CommRequest () {}
93 
98  virtual void wait () = 0;
99 
103  virtual void cancel () = 0;
104 };
105 
106 // Don't rely on anything in this namespace. You shouldn't be relying
107 // on anything in Tpetra::Details anyway. You _especially_ shouldn't
108 // be relying on anything in Tpetra::Details::Impl. Consider
109 // yourselves warned!
110 namespace Impl {
111 
113 std::shared_ptr<CommRequest>
114 emptyCommRequest ();
115 
116 #ifdef HAVE_TPETRACORE_MPI
117 
131 class MpiCommRequest : public CommRequest {
132 public:
134  MpiCommRequest ();
135 
137  MpiCommRequest (const MPI_Request req);
138 
140  virtual ~MpiCommRequest ();
141 
147  virtual void wait ();
148 
155  virtual void waitWithStatus (MPI_Status& status);
156 
158  virtual void cancel ();
159 
160 private:
161  MPI_Request req_;
162 };
163 #endif // HAVE_TPETRACORE_MPI
164 
170 public:
173 
180  DeferredActionCommRequest (std::function<void () > action);
181 
183  void wait ();
184 
189  void cancel ();
190 
191 private:
193  std::function<void(void) > action_;
195  bool actionTaken_;
196 };
197 
224 template<class PacketType,
225  class SendLayoutType,
226  class SendDeviceType,
227  class RecvLayoutType,
228  class RecvDeviceType,
229  const int rank>
231 
233 template<class PacketType,
234  class SendLayoutType,
235  class SendDeviceType,
236  class RecvLayoutType,
237  class RecvDeviceType>
238 class IallreduceCommRequest<PacketType,
239  SendLayoutType,
240  SendDeviceType,
241  RecvLayoutType,
242  RecvDeviceType,
243  1> :
244  public CommRequest {
245 public:
248  {}
249 
251  typedef ::Kokkos::View<const PacketType*, SendLayoutType,
252  SendDeviceType> send_buffer_type;
254  typedef ::Kokkos::View<PacketType*, RecvLayoutType,
255  RecvDeviceType> recv_buffer_type;
256 
260  IallreduceCommRequest (const std::shared_ptr<CommRequest>& req,
261  const send_buffer_type& sendbuf,
262  const recv_buffer_type& recvbuf) :
263  req_ (req),
264  sendbuf_ (sendbuf),
265  recvbuf_ (recvbuf)
266  {
267  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
268  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
269  "SendLayoutType must be either Kokkos::LayoutLeft or "
270  "Kokkos::LayoutRight.");
271  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
272  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
273  "RecvLayoutType must be either Kokkos::LayoutLeft or "
274  "Kokkos::LayoutRight.");
275  }
276 
279  if (req_.get () != NULL) {
280  // We're in a destructor, so don't throw. We'll just try our best
281  // to handle whatever happens here without throwing.
282  try {
283  req_->cancel ();
284  }
285  catch (...) {}
286 
287  try {
288  req_ = std::shared_ptr<CommRequest> ();
289  }
290  catch (...) {}
291  }
292  }
293 
298  void
299  wait ()
300  {
301  if (req_.get () != NULL) {
302  req_->wait ();
303  // Relinquish request handle.
304  req_ = std::shared_ptr<CommRequest> ();
305  }
306  // Relinquish references to saved buffers, if we have not already
307  // done so. This operation is idempotent.
308  sendbuf_ = send_buffer_type ();
309  recvbuf_ = recv_buffer_type ();
310  }
311 
315  void
317  {
318  if (req_.get () != NULL) {
319  req_->cancel ();
320  // Relinquish request handle.
321  req_ = std::shared_ptr<CommRequest> ();
322  }
323  // Relinquish references to saved buffers, if we have not already
324  // done so. This operation is idempotent.
325  sendbuf_ = send_buffer_type ();
326  recvbuf_ = recv_buffer_type ();
327  }
328 
329 private:
331  std::shared_ptr<CommRequest> req_;
332 
334  send_buffer_type sendbuf_;
335 
337  recv_buffer_type recvbuf_;
338 };
339 
341 template<class PacketType,
342  class SendLayoutType,
343  class SendDeviceType,
344  class RecvLayoutType,
345  class RecvDeviceType>
346 class IallreduceCommRequest<PacketType,
347  SendLayoutType,
348  SendDeviceType,
349  RecvLayoutType,
350  RecvDeviceType,
351  0> :
352  public CommRequest {
353 public:
356  {}
357 
359  typedef ::Kokkos::View<const PacketType, SendLayoutType,
360  SendDeviceType> send_buffer_type;
362  typedef ::Kokkos::View<PacketType, RecvLayoutType,
363  RecvDeviceType> recv_buffer_type;
364 
368  IallreduceCommRequest (const std::shared_ptr<CommRequest>& req,
369  const send_buffer_type& sendbuf,
370  const recv_buffer_type& recvbuf) :
371  req_ (req),
372  sendbuf_ (sendbuf),
373  recvbuf_ (recvbuf)
374  {
375  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
376  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
377  "SendLayoutType must be either Kokkos::LayoutLeft or "
378  "Kokkos::LayoutRight.");
379  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
380  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
381  "RecvLayoutType must be either Kokkos::LayoutLeft or "
382  "Kokkos::LayoutRight.");
383  }
384 
387  if (req_.get () != NULL) {
388  // We're in a destructor, so don't throw. We'll just try our best
389  // to handle whatever happens here without throwing.
390  try {
391  req_->cancel ();
392  }
393  catch (...) {}
394 
395  try {
396  req_ = std::shared_ptr<CommRequest> ();
397  }
398  catch (...) {}
399  }
400  }
401 
406  void
407  wait ()
408  {
409  if (req_.get () != NULL) {
410  req_->wait ();
411  // Relinquish request handle.
412  req_ = std::shared_ptr<CommRequest> ();
413  }
414  // Relinquish references to saved buffers, if we have not already
415  // done so. This operation is idempotent.
416  sendbuf_ = send_buffer_type ();
417  recvbuf_ = recv_buffer_type ();
418  }
419 
423  void
425  {
426  if (req_.get () != NULL) {
427  req_->cancel ();
428  // Relinquish request handle.
429  req_ = std::shared_ptr<CommRequest> ();
430  }
431  // Relinquish references to saved buffers, if we have not already
432  // done so. This operation is idempotent.
433  sendbuf_ = send_buffer_type ();
434  recvbuf_ = recv_buffer_type ();
435  }
436 
437 private:
439  std::shared_ptr<CommRequest> req_;
440 
442  send_buffer_type sendbuf_;
443 
445  recv_buffer_type recvbuf_;
446 };
447 
480 template<class PacketType,
481  class SendLayoutType,
482  class SendDeviceType,
483  class RecvLayoutType,
484  class RecvDeviceType>
485 std::shared_ptr<CommRequest>
486 wrapIallreduceCommRequest (const std::shared_ptr<CommRequest>& req,
487  const ::Kokkos::View<const PacketType*,
488  SendLayoutType,
489  SendDeviceType>& sendbuf,
490  const ::Kokkos::View<PacketType*,
491  RecvLayoutType,
492  RecvDeviceType>& recvbuf)
493 {
494  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
495  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
496  "SendLayoutType must be either Kokkos::LayoutLeft or "
497  "Kokkos::LayoutRight.");
498  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
499  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
500  "RecvLayoutType must be either Kokkos::LayoutLeft or "
501  "Kokkos::LayoutRight.");
502  typedef IallreduceCommRequest<PacketType, SendLayoutType, SendDeviceType,
503  RecvLayoutType, RecvDeviceType, 1> req_type;
504  return std::shared_ptr<CommRequest> (new req_type (req, sendbuf, recvbuf));
505 }
506 
539 template<class PacketType,
540  class SendLayoutType,
541  class SendDeviceType,
542  class RecvLayoutType,
543  class RecvDeviceType>
544 std::shared_ptr<CommRequest>
545 wrapIallreduceCommRequest (const std::shared_ptr<CommRequest>& req,
546  const ::Kokkos::View<const PacketType,
547  SendLayoutType,
548  SendDeviceType>& sendbuf,
549  const ::Kokkos::View<PacketType,
550  RecvLayoutType,
551  RecvDeviceType>& recvbuf)
552 {
553  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
554  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
555  "SendLayoutType must be either Kokkos::LayoutLeft or "
556  "Kokkos::LayoutRight.");
557  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
558  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
559  "RecvLayoutType must be either Kokkos::LayoutLeft or "
560  "Kokkos::LayoutRight.");
561  typedef IallreduceCommRequest<PacketType, SendLayoutType, SendDeviceType,
562  RecvLayoutType, RecvDeviceType, 0> req_type;
563  return std::shared_ptr<CommRequest> (new req_type (req, sendbuf, recvbuf));
564 }
565 
566 #ifdef HAVE_TPETRACORE_MPI
567 
578 std::shared_ptr<CommRequest>
579 iallreduceRawVoid (const void* sendbuf,
580  void* recvbuf,
581  const int count,
582  MPI_Datatype mpiDatatype,
583  const bool mpiDatatypeNeedsFree,
584  const Teuchos::EReductionType op,
585  MPI_Comm comm);
586 
587 #endif // HAVE_TPETRACORE_MPI
588 
597 template<class Packet>
598 std::shared_ptr<CommRequest>
599 iallreduceRaw (const Packet sendbuf[],
600  Packet recvbuf[],
601  const int count,
602  const ::Teuchos::EReductionType op,
603  const ::Teuchos::Comm<int>& comm)
604 {
605 #ifdef HAVE_TPETRACORE_MPI
606  using ::Tpetra::Details::MpiTypeTraits;
607 
608  // mfh 12 Nov 2016: It's reasonable to assume that if users call
609  // this function with count > 1, then users should expect that all
610  // sent and received data have the same MPI_Datatype. If count is
611  // zero, then it doesn't matter what datatype we use, as long as
612  // it's not MPI_DATATYPE_NULL. For the latter, see e.g., the
613  // discussion here:
614  //
615  // http://lists.mpi-forum.org/pipermail/mpi-forum/2016-January/003159.html
616 
617  // FIXME (mfh 14 Nov 2016) For derived MPI_Datatype, it may make
618  // sense for us to cache them somewhere for later reuse, rather than
619  // constructing and freeing a new one each time.
620 
621  MPI_Datatype mpiDatatype = (count > 0) ?
622  MpiTypeTraits<Packet>::getType (sendbuf[0]) :
623  MPI_BYTE;
624  MPI_Comm rawComm = ::Tpetra::Details::extractMpiCommFromTeuchos (comm);
625  return iallreduceRawVoid (sendbuf, recvbuf, count, mpiDatatype,
626  MpiTypeTraits<Packet>::needsFree, op, rawComm);
627 #else // NOT HAVE_TPETRACORE_MPI
628  throw std::logic_error ("Tpetra::Details::Impl::iallreduceRaw: This function "
629  "should never be called if MPI is not enabled. "
630  "Please report this bug to the Tpetra developers.");
631 #endif // HAVE_TPETRACORE_MPI
632 }
633 
656 template<class PacketType,
657  class SendLayoutType,
658  class SendDeviceType,
659  class RecvLayoutType,
660  class RecvDeviceType,
661  const int rank>
662 struct Iallreduce {};
663 
665 template<class PacketType,
666  class SendLayoutType,
667  class SendDeviceType,
668  class RecvLayoutType,
669  class RecvDeviceType>
670 struct Iallreduce<PacketType,
671  SendLayoutType,
672  SendDeviceType,
673  RecvLayoutType,
674  RecvDeviceType,
675  1> {
676  typedef ::Kokkos::View<const PacketType*,
677  SendLayoutType,
678  SendDeviceType> send_buffer_type;
679  typedef ::Kokkos::View<PacketType*,
680  RecvLayoutType,
681  RecvDeviceType> recv_buffer_type;
682 
683  static std::shared_ptr<CommRequest>
684  iallreduce (const send_buffer_type& sendbuf,
685  const recv_buffer_type& recvbuf,
686  const ::Teuchos::EReductionType op,
687  const ::Teuchos::Comm<int>& comm)
688  {
689  static_assert (! std::is_const<PacketType>::value,
690  "PacketType must be a nonconst type.");
691  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
692  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
693  "SendLayoutType must be either Kokkos::LayoutLeft or "
694  "Kokkos::LayoutRight.");
695  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
696  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
697  "RecvLayoutType must be either Kokkos::LayoutLeft or "
698  "Kokkos::LayoutRight.");
699 #ifdef HAVE_TPETRACORE_MPI
700  // Avoid instantiating Impl::iallreduceRaw for both T and const T,
701  // by canonicalizing to the non-const version of T.
702  typedef typename std::remove_const<PacketType>::type packet_type;
703 
704  std::shared_ptr<CommRequest> req =
705  Impl::iallreduceRaw<packet_type> (sendbuf.data (),
706  recvbuf.data (),
707  static_cast<int> (sendbuf.extent (0)),
708  op, comm);
709  return Impl::wrapIallreduceCommRequest (req, sendbuf, recvbuf);
710 #else // NOT HAVE_TPETRACORE_MPI
711 
712  // MPI is disabled, so comm is a SerialComm.
713  // Avoid needing to check the SerialComm case in Impl::iallreduce.
714  // That lets Impl::iallreduce not need to know about DeviceType.
715  ::Kokkos::deep_copy (recvbuf, sendbuf);
716  // This request has already finished. There's nothing more to do.
717  return Impl::emptyCommRequest ();
718 #endif // HAVE_TPETRACORE_MPI
719  }
720 };
721 
723 template<class PacketType,
724  class SendLayoutType,
725  class SendDeviceType,
726  class RecvLayoutType,
727  class RecvDeviceType>
728 struct Iallreduce<PacketType,
729  SendLayoutType,
730  SendDeviceType,
731  RecvLayoutType,
732  RecvDeviceType,
733  0> {
734  // mfh 02 Jan 2017: For rank-0 Views, LayoutLeft and LayoutRight are
735  // unfortunately NOT mutually assignable, even though it would make
736  // sense for this to be the case. That's why we have to template on
737  // the layout types.
738  typedef ::Kokkos::View<const PacketType,
739  SendLayoutType,
740  SendDeviceType> send_buffer_type;
741  typedef ::Kokkos::View<PacketType,
742  RecvLayoutType,
743  RecvDeviceType> recv_buffer_type;
744 
745  static std::shared_ptr<CommRequest>
746  iallreduce (const send_buffer_type& sendbuf,
747  const recv_buffer_type& recvbuf,
748  const ::Teuchos::EReductionType op,
749  const ::Teuchos::Comm<int>& comm)
750  {
751  static_assert (! std::is_const<PacketType>::value,
752  "PacketType must be a nonconst type.");
753  static_assert (std::is_same<SendLayoutType, ::Kokkos::LayoutLeft>::value ||
754  std::is_same<SendLayoutType, ::Kokkos::LayoutRight>::value,
755  "SendLayoutType must be either Kokkos::LayoutLeft or "
756  "Kokkos::LayoutRight.");
757  static_assert (std::is_same<RecvLayoutType, ::Kokkos::LayoutLeft>::value ||
758  std::is_same<RecvLayoutType, ::Kokkos::LayoutRight>::value,
759  "RecvLayoutType must be either Kokkos::LayoutLeft or "
760  "Kokkos::LayoutRight.");
761 #ifdef HAVE_TPETRACORE_MPI
762  // Avoid instantiating Impl::iallreduceRaw for both T and const T,
763  // by canonicalizing to the non-const version of T.
764  typedef typename std::remove_const<PacketType>::type packet_type;
765 
766  std::shared_ptr<CommRequest> req =
767  Impl::iallreduceRaw<packet_type> (sendbuf.data (),
768  recvbuf.data (),
769  static_cast<int> (1),
770  op, comm);
771  return Impl::wrapIallreduceCommRequest (req, sendbuf, recvbuf);
772 #else // NOT HAVE_TPETRACORE_MPI
773 
774  // MPI is disabled, so comm is a SerialComm.
775  // Avoid needing to check the SerialComm case in Impl::iallreduce.
776  // That lets Impl::iallreduce not need to know about DeviceType.
777  ::Kokkos::deep_copy (recvbuf, sendbuf);
778  // This request has already finished. There's nothing more to do.
779  return Impl::emptyCommRequest ();
780 #endif // HAVE_TPETRACORE_MPI
781  }
782 };
783 
784 } // namespace Impl
785 
786 //
787 // SKIP DOWN TO HERE
788 //
789 
815 template<class InputViewType, class OutputViewType>
816 std::shared_ptr<CommRequest>
817 iallreduce (const InputViewType& sendbuf,
818  const OutputViewType& recvbuf,
819  const ::Teuchos::EReductionType op,
820  const ::Teuchos::Comm<int>& comm)
821 {
822  static_assert (Kokkos::Impl::is_view<InputViewType>::value,
823  "InputViewType must be a Kokkos::View specialization.");
824  static_assert (Kokkos::Impl::is_view<OutputViewType>::value,
825  "OutputViewType must be a Kokkos::View specialization.");
826  constexpr int rank = static_cast<int> (OutputViewType::rank);
827  static_assert (static_cast<int> (InputViewType::rank) == rank,
828  "InputViewType and OutputViewType must have the same rank.");
829  static_assert (rank == 0 || rank == 1,
830  "InputViewType and OutputViewType must both have "
831  "rank 0 or rank 1.");
832  typedef typename OutputViewType::non_const_value_type packet_type;
833  static_assert (std::is_same<typename OutputViewType::value_type,
834  packet_type>::value,
835  "OutputViewType must be a nonconst Kokkos::View.");
836  static_assert (std::is_same<typename InputViewType::non_const_value_type,
837  packet_type>::value,
838  "InputViewType and OutputViewType must be Views "
839  "whose entries have the same type.");
840  typedef typename InputViewType::array_layout send_layout_type;
841  typedef typename OutputViewType::array_layout recv_layout_type;
842  typedef typename InputViewType::device_type send_device_type;
843  typedef typename OutputViewType::device_type recv_device_type;
844 
845  typedef Impl::Iallreduce<packet_type, send_layout_type, send_device_type,
846  recv_layout_type, recv_device_type, rank> impl_type;
847  return impl_type::iallreduce (sendbuf, recvbuf, op, comm);
848 }
849 
850 std::shared_ptr<CommRequest>
851 iallreduce (const int localValue,
852  int& globalValue,
853  const ::Teuchos::EReductionType op,
854  const ::Teuchos::Comm<int>& comm);
855 
856 } // namespace Details
857 } // namespace Tpetra
858 
859 #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)...
Declaration of Tpetra::Details::extractMpiCommFromTeuchos.
Add specializations of Teuchos::Details::MpiTypeTraits for Kokkos::complex&lt;float&gt; and Kokkos::complex...
void wait()
Wait on this communication request to complete.
::Kokkos::View< const PacketType, SendLayoutType, SendDeviceType > send_buffer_type
Type of the send buffer.
Object representing a pending ::Tpetra::Details::iallreduce operation.
DeferredActionCommRequest()
Default constructor (take no action on wait).
::Kokkos::View< const PacketType *, SendLayoutType, SendDeviceType > send_buffer_type
Type of the send buffer.
void cancel()
Cancel the pending communication request, without taking the specified action.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
::Kokkos::View< PacketType *, RecvLayoutType, RecvDeviceType > recv_buffer_type
Type of the receive buffer.
virtual void wait()=0
Wait on this communication request to complete.
Implementation of ::Tpetra::Details::iallreduce.
Part of the Work-around for not having MPI &gt;= 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.
virtual void cancel()=0
Cancel the pending communication request.
virtual ~CommRequest()
Destructor (virtual for memory safety of derived classes).