00001 #ifndef ARTDAQ_TRANSFERPLUGINS_MPITRANSFER_HH
00002 #define ARTDAQ_TRANSFERPLUGINS_MPITRANSFER_HH
00003
00004 #include <vector>
00005
00006 #include "artdaq/DAQrate/quiet_mpi.hh"
00007 #include "artdaq-core/Data/Fragment.hh"
00008 #include "artdaq/TransferPlugins/TransferInterface.hh"
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 namespace artdaq
00020 {
00024 class MPITransfer : public TransferInterface
00025 {
00026 public:
00038 MPITransfer(fhicl::ParameterSet pset, Role role);
00039
00043 virtual ~MPITransfer();
00044
00051 CopyStatus copyFragment(Fragment& frag, size_t timeout_usec) override;
00052
00059 CopyStatus moveFragment(Fragment&& frag, size_t timeout_usec) override;
00060
00067 int receiveFragment(Fragment& frag, size_t timeout_usec) override;
00068
00069 private:
00070 enum class status_t
00071 {
00072 SENDING,
00073 PENDING,
00074 DONE
00075 };
00076
00077 void cancelReq_(size_t buf, bool blocking_wait = true);
00078
00079 void post_(size_t buf);
00080
00081
00082 int findAvailable();
00083
00084 TransferInterface::CopyStatus sendFragment(Fragment&& frag, size_t timeout_usec, bool force_async);
00085
00086 int nextSource_();
00087
00088 status_t src_status_;
00089 size_t recvd_count_;
00090 size_t expected_count_;
00091
00092 Fragments payload_;
00093
00094 #if USE_TESTSOME
00095 int saved_wait_result_;
00096 std::vector<int> ready_indices_;
00097 std::vector<MPI_Status> ready_statuses_;
00098 #endif
00099 static std::mutex mpi_mutex_;
00100 bool synchronous_sends_;
00101
00102 std::vector<MPI_Request> reqs_;
00103 int pos_;
00104 };
00105 }
00106
00107 #endif //define ARTDAQ_TRANSFERPLUGINS_MPITRANSFER_HH