CMS 3D CMS Logo

ProductBase.h
Go to the documentation of this file.
1 #ifndef CUDADataFormats_Common_ProductBase_h
2 #define CUDADataFormats_Common_ProductBase_h
3 
4 #include <atomic>
5 #include <memory>
6 
9 
10 namespace cms {
11  namespace cuda {
12  namespace impl {
13  class ScopedContextBase;
14  }
15 
20  class ProductBase {
21  public:
22  ProductBase() = default; // Needed only for ROOT dictionary generation
23  ~ProductBase();
24 
25  ProductBase(const ProductBase&) = delete;
26  ProductBase& operator=(const ProductBase&) = delete;
28  : stream_{std::move(other.stream_)},
29  event_{std::move(other.event_)},
30  mayReuseStream_{other.mayReuseStream_.load()},
31  device_{other.device_} {}
33  stream_ = std::move(other.stream_);
34  event_ = std::move(other.event_);
35  mayReuseStream_ = other.mayReuseStream_.load();
36  device_ = other.device_;
37  return *this;
38  }
39 
40  bool isValid() const { return stream_.get() != nullptr; }
41  bool isAvailable() const;
42 
43  int device() const { return device_; }
44 
45  // cudaStream_t is a pointer to a thread-safe object, for which a
46  // mutable access is needed even if the cms::cuda::ScopedContext itself
47  // would be const. Therefore it is ok to return a non-const
48  // pointer from a const method here.
49  cudaStream_t stream() const { return stream_.get(); }
50 
51  // cudaEvent_t is a pointer to a thread-safe object, for which a
52  // mutable access is needed even if the cms::cuda::ScopedContext itself
53  // would be const. Therefore it is ok to return a non-const
54  // pointer from a const method here.
55  cudaEvent_t event() const { return event_.get(); }
56 
57  protected:
60 
61  private:
63  friend class ScopedContextProduce;
64 
65  // The following function is intended to be used only from ScopedContext
66  const SharedStreamPtr& streamPtr() const { return stream_; }
67 
68  bool mayReuseStream() const {
69  bool expected = true;
70  bool changed = mayReuseStream_.compare_exchange_strong(expected, false);
71  // If the current thread is the one flipping the flag, it may
72  // reuse the stream.
73  return changed;
74  }
75 
76  // The cudaStream_t is really shared among edm::Event products, so
77  // using shared_ptr also here
79  // shared_ptr because of caching in cms::cuda::EventCache
81 
82  // This flag tells whether the CUDA stream may be reused by a
83  // consumer or not. The goal is to have a "chain" of modules to
84  // queue their work to the same stream.
85  mutable std::atomic<bool> mayReuseStream_ = true;
86 
87  // The CUDA device associated with this product
88  int device_ = -1;
89  };
90  } // namespace cuda
91 } // namespace cms
92 
93 #endif
bool isValid() const
Definition: ProductBase.h:40
bool mayReuseStream() const
Definition: ProductBase.h:68
std::shared_ptr< std::remove_pointer_t< cudaEvent_t > > SharedEventPtr
ProductBase & operator=(const ProductBase &)=delete
ProductBase(ProductBase &&other)
Definition: ProductBase.h:27
std::shared_ptr< std::remove_pointer_t< cudaStream_t > > SharedStreamPtr
ProductBase(int device, SharedStreamPtr stream, SharedEventPtr event)
Definition: ProductBase.h:58
bool isAvailable() const
Definition: ProductBase.cc:5
const SharedStreamPtr & streamPtr() const
Definition: ProductBase.h:66
Namespace of DDCMS conversion namespace.
SharedStreamPtr stream_
Definition: ProductBase.h:78
SharedEventPtr event_
Definition: ProductBase.h:80
ProductBase & operator=(ProductBase &&other)
Definition: ProductBase.h:32
cudaEvent_t event() const
Definition: ProductBase.h:55
std::atomic< bool > mayReuseStream_
Definition: ProductBase.h:85
cudaStream_t stream() const
Definition: ProductBase.h:49
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1