Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-30 10:07:01

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file corecel/sys/ScopedProfiling.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cstdint>
0010 #include <string>
0011 
0012 #include "corecel/Config.hh"
0013 
0014 #include "corecel/Macros.hh"
0015 #include "corecel/io/Logger.hh"
0016 
0017 #include "Environment.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 // Whether profiling is enabled
0023 bool use_profiling();
0024 
0025 //---------------------------------------------------------------------------//
0026 /*!
0027  * Input arguments for the most richly annotated implementation (NVTX).
0028  */
0029 struct ScopedProfilingInput
0030 {
0031     std::string_view name;  //!< Name of the range
0032     uint32_t color{};  //!< ARGB
0033     int32_t payload{};  //!< User data
0034     uint32_t category{};  //!< Category, used to group ranges together
0035 
0036     ScopedProfilingInput(std::string_view n) : name{n} {}
0037 };
0038 
0039 //---------------------------------------------------------------------------//
0040 /*!
0041  * Enable and annotate performance profiling during the lifetime of this class.
0042  *
0043  * This RAII class annotates the profiling output so that, during its scope,
0044  * events and timing are associated with the given name. For use cases inside
0045  * separate begin/end functions of a class (often seen in Geant4), use
0046  * \c std::optional to start and end the class lifetime.
0047  *
0048  * This is useful for wrapping specific code fragment in a range for profiling,
0049  * e.g., ignoring of VecGeom instantiation kernels, or profiling a specific
0050  * action.  It is very similar to the [NVTX
0051  * `scoped_range`](https://nvidia.github.io/NVTX/doxygen-cpp/#scoped_range).
0052  *
0053  * Example: \code
0054  * void do_program()
0055  * {
0056  *     do_setup()
0057  *     ScopedProfiling profile_this{"run"};
0058  *     do_run();
0059  * }
0060  * \endcode
0061  *
0062  * Caveats:
0063  * - The Nvidia/CUDA implementation of \c ScopedProfiling only does something
0064  *   when the application using Celeritas is run through a tool that supports
0065  *   NVTX, e.g., nsight compute with the --nvtx argument. If this is not the
0066  *   case, API calls to nvtx are no-ops.
0067  * - The HIP/AMD ROCTX implementation requires the roctx library, which may not
0068  *   be available on all systems.
0069  * - The CPU implementation requires Perfetto. It is not available when
0070  *   Celeritas is built with device support (CUDA/HIP).
0071  *
0072  * \internal All profiling library implementations must support multithreaded
0073  * contexts since each thread may have one or more active instances of this
0074  * class.
0075  */
0076 class ScopedProfiling
0077 {
0078   public:
0079     //!@{
0080     //! \name Type aliases
0081     using Input = ScopedProfilingInput;
0082     //!@}
0083 
0084   public:
0085     // Activate profiling with options
0086     explicit inline ScopedProfiling(Input const& input);
0087     // Activate profiling with just a name
0088     explicit inline ScopedProfiling(std::string_view name);
0089 
0090     // Deactivate profiling
0091     inline ~ScopedProfiling();
0092 
0093     //!@{
0094     //! Prevent copying and moving for RAII class
0095     CELER_DELETE_COPY_MOVE(ScopedProfiling);
0096     //!@}
0097 
0098   private:
0099     bool activated_;
0100 
0101     void activate(Input const& input) noexcept;
0102     void deactivate() noexcept;
0103 };
0104 
0105 //---------------------------------------------------------------------------//
0106 // INLINE DEFINITIONS
0107 //---------------------------------------------------------------------------//
0108 /*!
0109  * Activate device profiling with options.
0110  */
0111 ScopedProfiling::ScopedProfiling(Input const& input)
0112     : activated_{use_profiling()}
0113 {
0114     if (activated_)
0115     {
0116         this->activate(input);
0117     }
0118 }
0119 
0120 //---------------------------------------------------------------------------//
0121 /*!
0122  * Activate device profiling with just a name.
0123  */
0124 ScopedProfiling::ScopedProfiling(std::string_view name)
0125     : ScopedProfiling{Input{name}}
0126 {
0127 }
0128 
0129 //---------------------------------------------------------------------------//
0130 /*!
0131  * Deactivate a profiling scope.
0132  */
0133 ScopedProfiling::~ScopedProfiling()
0134 {
0135     if (activated_)
0136     {
0137         this->deactivate();
0138     }
0139 }
0140 
0141 #if !CELER_USE_DEVICE && !CELERITAS_USE_PERFETTO
0142 inline void ScopedProfiling::activate(Input const&) noexcept
0143 {
0144     CELER_UNREACHABLE;
0145 }
0146 inline void ScopedProfiling::deactivate() noexcept
0147 {
0148     CELER_UNREACHABLE;
0149 }
0150 #endif
0151 //---------------------------------------------------------------------------//
0152 }  // namespace celeritas