LCOV - code coverage report
Current view: top level - artdaq/TransferPlugins - TransferInterface.hh (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 26.7 % 15 4
Test Date: 2025-09-04 00:45:34 Functions: 57.1 % 7 4

            Line data    Source code
       1              : #ifndef artdaq_ArtModules_TransferInterface_hh
       2              : #define artdaq_ArtModules_TransferInterface_hh
       3              : 
       4              : #include "TRACE/tracemf.h"  // Pre-empt TRACE/trace.h from Fragment.hh.
       5              : #include "artdaq-core/Data/Fragment.hh"
       6              : 
       7              : #include "artdaq/DAQdata/Globals.hh"  // my_rank
       8              : 
       9              : #include "artdaq-core/Data/detail/RawFragmentHeader.hh"
      10              : 
      11              : #include "fhiclcpp/types/Atom.h"
      12              : #include "fhiclcpp/types/Comment.h"
      13              : #include "fhiclcpp/types/ConfigurationTable.h"
      14              : #include "fhiclcpp/types/Name.h"
      15              : 
      16              : namespace fhicl {
      17              : class ParameterSet;
      18              : }
      19              : 
      20              : #include "cetlib/compiler_macros.h"  // EXTERN_C_FUNC_*
      21              : 
      22              : #include <iostream>
      23              : #include <limits>
      24              : #include <memory>
      25              : #include <sstream>
      26              : #include <string>
      27              : 
      28              : namespace artdaq {
      29              : /**
      30              :  * \brief This interface defines the functions used to transfer data between artdaq applications.
      31              :  */
      32              : class TransferInterface
      33              : {
      34              : public:
      35              :         /// <summary>
      36              :         /// Configuration of the TransferInterface. May be used for parameter validation
      37              :         /// </summary>
      38              :         struct Config
      39              :         {
      40              :                 /// "source_rank" (Default: my_rank) : The rank that data is coming from
      41              :                 fhicl::Atom<int> source_rank{fhicl::Name{"source_rank"}, fhicl::Comment{"The rank that data is coming from"}, my_rank};
      42              :                 /// "destination_rank" (Default: my_rank) : The rank that data is going to
      43              :                 fhicl::Atom<int> destination_rank{fhicl::Name{"destination_rank"}, fhicl::Comment{"The rank that data is going to"}, my_rank};
      44              :                 /// "unique_label" (Default: "transfer_between_[source_rank]_and_[destination_rank]") : A label that uniquely identifies the TransferInterface instance
      45              :                 fhicl::Atom<std::string> unique_label{fhicl::Name{"unique_label"}, fhicl::Comment{"A label that uniquely identifies the TransferInterface instance"}, "transfer_between_[source_rank]_and_[destination_rank]"};
      46              :                 /// "buffer_count" (Default: 10) : How many Fragments can the TransferInterface handle simultaneously
      47              :                 fhicl::Atom<size_t> buffer_count{fhicl::Name{"buffer_count"}, fhicl::Comment{"How many Fragments can the TransferInterface handle simultaneously"}, 10};
      48              :                 /// "max_fragment_size_words" (Default: 1024) : The maximum Fragment size expected.May be used for static memory allocation, and will cause errors if larger Fragments are sent.
      49              :                 fhicl::Atom<size_t> max_fragment_size{fhicl::Name{"max_fragment_size_words"}, fhicl::Comment{"The maximum Fragment size expected.May be used for static memory allocation, and will cause errors if larger Fragments are sent."}, 1024};
      50              :         };
      51              :         /// Used for ParameterSet validation (if desired)
      52              :         using Parameters = fhicl::WrappedTable<Config>;
      53              : 
      54              :         /// <summary>
      55              :         /// Return codes from receive operations
      56              :         /// </summary>
      57              :         enum ReceiveReturnCode : int
      58              :         {
      59              :                 DATA_END = -2222,      ///< Value that is to be returned when a Transfer plugin determines that no more data will be arriving.
      60              :                 RECV_TIMEOUT = -1111,  ///< Value to be returned upon receive timeout.
      61              :                 NO_RANK_INFO = -1,     ///< Will be returned from a successful receive that does not know the source rank (Transfer to OM art process)
      62              :                 RECV_SUCCESS = 0       ///< For code clarity, things checking for successful receive should check retval >= NO_RANK_INFO
      63              :         };
      64              : 
      65              :         /**
      66              :          * \brief Used to determine if a TransferInterface is a Sender or Receiver
      67              :          */
      68              :         enum class Role
      69              :         {
      70              :                 kSend,    ///< This TransferInterface is a Sender
      71              :                 kReceive  ///< This TransferInterface is a Receiver
      72              :         };
      73              : 
      74              :         /**
      75              :          * \brief Returned from the send functions, this enumeration describes the possible return codes.
      76              :          * If an exception occurs, it will be thrown and should be handled normally.
      77              :          */
      78              :         enum class CopyStatus
      79              :         {
      80              :                 kSuccess,                    ///< The send operation completed successfully
      81              :                 kTimeout,                    ///< The send operation timed out
      82              :                 kErrorNotRequiringException  ///< Some error occurred, but no exception was thrown
      83              :         };
      84              : 
      85              :         /// <summary>
      86              :         /// Convert a CopyStatus variable to its string represenatation
      87              :         /// </summary>
      88              :         /// <param name="in">CopyStatus to convert</param>
      89              :         /// <returns>String representation of CopyStatus</returns>
      90            0 :         static std::string CopyStatusToString(CopyStatus in)
      91              :         {
      92            0 :                 switch (in)
      93              :                 {
      94            0 :                         case CopyStatus::kSuccess:
      95            0 :                                 return "Success";
      96            0 :                         case CopyStatus::kTimeout:
      97            0 :                                 return "Timeout";
      98            0 :                         case CopyStatus::kErrorNotRequiringException:
      99            0 :                                 return "Error";
     100            0 :                         default:
     101            0 :                                 return "UNKNOWN";
     102              :                 }
     103              :                 return "SWITCHERROR";
     104              :         }
     105              : 
     106              :         /**
     107              :          * \brief TransferInterface Constructor
     108              :          * \param ps ParameterSet used for configuring the TransferInterface. See artdaq::TransferInterface::Config
     109              :          * \param role Role of the TransferInterface (See TransferInterface::Role)
     110              :          */
     111              :         TransferInterface(const fhicl::ParameterSet& ps, Role role);
     112              : 
     113              :         /**
     114              :          * \brief Copy Constructor is deleted
     115              :          */
     116              :         TransferInterface(const TransferInterface&) = delete;
     117              : 
     118              :         /**
     119              :          * \brief Copy Assignment operator is deleted
     120              :          * \return TransferInterface Copy
     121              :          */
     122              :         TransferInterface& operator=(const TransferInterface&) = delete;
     123              : 
     124              :         /**
     125              :          * \brief Default virtual Destructor
     126              :          */
     127            3 :         virtual ~TransferInterface() = default;
     128              : 
     129              :         /**
     130              :          * \brief Receive a Fragment from the transport mechanism
     131              :          * \param[out] fragment Received Fragment
     132              :          * \param receive_timeout Timeout for receive
     133              :          * \return The rank the Fragment was received from (should be source_rank), or RECV_TIMEOUT
     134              :          */
     135              :         virtual int receiveFragment(artdaq::Fragment& fragment, size_t receive_timeout);
     136              : 
     137              :         /**
     138              :          * \brief Receive a Fragment Header from the transport mechanism
     139              :          * \param[out] header Received Fragment Header
     140              :          * \param receiveTimeout Timeout for receive
     141              :          * \return The rank the Fragment was received from (should be source_rank), or RECV_TIMEOUT
     142              :          */
     143              :         virtual int receiveFragmentHeader(detail::RawFragmentHeader& header, size_t receiveTimeout) = 0;
     144              : 
     145              :         /**
     146              :          * \brief Receive the body of a Fragment to the given destination pointer
     147              :          * \param destination Pointer to memory region where Fragment data should be stored
     148              :          * \param wordCount Number of words of Fragment data to receive
     149              :          * \return The rank the Fragment was received from (should be source_rank), or RECV_TIMEOUT
     150              :          *
     151              :          * The precondition for calling this function is that you have received a valid header, therefore it does
     152              :          * not have a , as the Fragment data should immediately be available.
     153              :          */
     154              :         virtual int receiveFragmentData(RawDataType* destination, size_t wordCount) = 0;
     155              : 
     156              :         /**
     157              :          * \brief Transfer a Fragment to the destination. May not necessarily be reliable, but will not block longer than send_timeout_usec.
     158              :          * \param fragment Fragment to transfer
     159              :          * \param send_timeout_usec Timeout for send, in microseconds
     160              :          * \return CopyStatus detailing result of transfer
     161              :          */
     162              :         virtual CopyStatus transfer_fragment_min_blocking_mode(artdaq::Fragment const& fragment, size_t send_timeout_usec) = 0;
     163              : 
     164              :         /**
     165              :          * \brief Transfer a Fragment to the destination. This should be reliable, if the underlying transport mechanism supports reliable sending
     166              :          * \param fragment Fragment to transfer
     167              :          * \return CopyStatus detailing result of copy
     168              :          */
     169              :         virtual CopyStatus transfer_fragment_reliable_mode(artdaq::Fragment&& fragment) = 0;
     170              : 
     171              :         /**
     172              :          * \brief Get the unique label of this TransferInterface instance
     173              :          * \return The unique label of this TransferInterface instance
     174              :          */
     175              :         std::string uniqueLabel() const { return unique_label_; }
     176              : 
     177              :         /**
     178              :          * \brief Get the source rank for this TransferInterface instance
     179              :          * \return The source rank for this Transferinterface instance
     180              :          */
     181          143 :         virtual int source_rank() const { return source_rank_; }
     182              :         /**
     183              :          * \brief Get the destination rank for this TransferInterface instance
     184              :          * \return The destination rank for this TransferInterface instance
     185              :          */
     186            4 :         virtual int destination_rank() const { return destination_rank_; }
     187              : 
     188              :         /**
     189              :          * \brief Determine whether the TransferInterface plugin is able to send/receive data
     190              :          * \return True if the TransferInterface plugin is currently able to send/receive data
     191              :          */
     192            0 :         virtual bool isRunning() { return false; }
     193              : 
     194              :         /**
     195              :          * \brief Flush any in-flight data. This should be used by the receiver after the receive loop has ended.
     196              :          */
     197              :         virtual void flush_buffers() = 0;
     198              : 
     199              : /** \cond */
     200              : #define GetTraceName() unique_label_ << (role_ == Role::kSend ? std::string("_SEND: ") : std::string("_RECV: "))
     201              :         /** \endcond */
     202              : 
     203              : protected:
     204              :         TransferInterface(TransferInterface&&) = delete;             ///< Move Constructor is deleted
     205              :         TransferInterface& operator=(TransferInterface&&) = delete;  ///< Move Assignment Operator is deleted
     206              : 
     207              :         const Role role_;  ///< Whether this instance of TransferInterface is a sender or receiver
     208              : 
     209              :         const int source_rank_;           ///< Rank of source
     210              :         const int destination_rank_;      ///< Rank of destination
     211              :         const std::string unique_label_;  ///< Unique label of transfer (ideally the same on sender and receiver)
     212              : 
     213              :         size_t buffer_count_;                   ///< The number of Fragment transfers the TransferInterface can handle simultaneously
     214              :         const size_t max_fragment_size_words_;  ///< The maximum size of the transferred Fragment objects, in artdaq::Fragment::RawDataType words
     215              : 
     216              : protected:
     217              :         /**
     218              :          * \brief Get the TransferInterface::Role of this TransferInterface
     219              :          * \return The Role of this TransferInterface
     220              :          */
     221            5 :         Role role() const { return role_; }
     222              : };
     223              : }  // namespace artdaq
     224              : 
     225              : /** \cond */
     226              : 
     227              : #ifndef EXTERN_C_FUNC_DECLARE_START
     228              : #define EXTERN_C_FUNC_DECLARE_START extern "C" {
     229              : #endif
     230              : 
     231              : #define DEFINE_ARTDAQ_TRANSFER(klass)                                                                                    \
     232              :         EXTERN_C_FUNC_DECLARE_START                                                                                          \
     233              :         std::unique_ptr<artdaq::TransferInterface> make(fhicl::ParameterSet const& ps, artdaq::TransferInterface::Role role) \
     234              :         {                                                                                                                    \
     235              :                 return std::unique_ptr<artdaq::TransferInterface>(new klass(ps, role));                                          \
     236              :         }                                                                                                                    \
     237              :         }
     238              : 
     239              : /** \endcond */
     240              : 
     241              : #endif /* artdaq_ArtModules_TransferInterface.hh */
     242              : 
     243              : // Local Variables:
     244              : // mode: c++
     245              : // End:
        

Generated by: LCOV version 2.0-1