18# include <cuda_runtime.h>
22#include <boost/fiber/cuda/waitfor.hpp>
23#include <boost/fiber/mutex.hpp>
24#include <boost/fiber/recursive_mutex.hpp>
36 using Mutex_t = std::recursive_mutex;
40 std::deque<Stream_t> queue;
45 void push(
const Stream_t& s ) {
46 std::unique_lock lck( queue_mtx );
52 bool pop( Stream_t& s ) {
53 std::unique_lock lck( queue_mtx );
54 if ( queue.empty() ) {
return false; }
63 cudaStreamDestroy( s );
68 StreamList available_streams{};
69 std::string err_fmt( cudaError_t err, std::string file,
int line ) {
70 const char* errname = cudaGetErrorName( err );
71 const char* errstr = cudaGetErrorString( err );
73 std::format(
"Encountered CUDA error {} [{}]: {} on {}:{}", errname,
int( err ), errstr, file, line );
86 if ( !available_streams.pop(
m_stream ) ) {
87 cudaError_t err = cudaStreamCreate( &m_stream );
88 if ( err != cudaSuccess ) {
90 throw GaudiException( err_fmt( err, __FILE__, __LINE__ ),
"CUDAStreamException", StatusCode::FAILURE );
92 err = cudaStreamSynchronize(
m_stream );
93 if ( err != cudaSuccess ) {
102 m_parent->error() << std::format(
"Stream destroyed before all its dependents ({} remaining)",
m_dependents )
105 if (
await().isFailure() ) {
m_parent->error() <<
"Error in Stream destructor" <<
endmsg; }
115 auto temp_error = cudaSuccess;
117 auto sc =
m_async_parent->decorateSuspension( [
this, &temp_error]() {
118 auto res = boost::fibers::cuda::waitfor_all(
m_stream );
119 temp_error = std::get<1>( res );
122 if ( !sc.isSuccess() ) {
127 temp_error = cudaStreamSynchronize(
m_stream );
129 if ( ( temp_error ) != cudaSuccess ) {
131 std::string errmsg = err_fmt( temp_error, __FILE__, __LINE__ );
struct CUstream_st * cudaStream_t
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Base class from which all concrete algorithm classes should be derived.
Base class for asynchronous algorithms.
const Gaudi::AsynchronousAlgorithm * m_async_parent
void removeDependency()
INTERNAL: Remove a dependency.
const Gaudi::AsynchronousAlgorithm * asyncParent()
Access the parent AsynchronousAlgorithm.
void registerDependency()
INTERNAL: Register a dependency.
Stream(const Gaudi::Algorithm *parent, cudaStream_t stream)
Wrap an existing cudaStream.
StatusCode await()
Yield fiber until stream is done.
const Gaudi::Algorithm * parent()
Access the parent algorithm.
const Gaudi::Algorithm * m_parent
Define general base for Gaudi exception.
This class is used for returning status codes from appropriate routines.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...