Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:03:45

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2023-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file corecel/sys/MemRegistry.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <cstddef>
0011 #include <string>
0012 #include <vector>
0013 
0014 #include "corecel/OpaqueId.hh"
0015 #include "corecel/Types.hh"
0016 #include "corecel/math/Quantity.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 //! SI prefix for multiples of 1024
0022 struct Kibi
0023 {
0024     using value_type = std::size_t;
0025 
0026     static CELER_CONSTEXPR_FUNCTION value_type value() { return 1024u; }
0027     static char const* label() { return "kibi"; }
0028 };
0029 
0030 //! 1024 bytes
0031 using KibiBytes = Quantity<Kibi>;
0032 //! Ordered identifiers for memory allocation segments
0033 using MemUsageId = OpaqueId<struct MemUsageEntry>;
0034 
0035 //! Statistics about a block of memory usage
0036 struct MemUsageEntry
0037 {
0038     //! Name of this entry
0039     std::string label;
0040     //! Index of the umbrella entry
0041     MemUsageId parent_index{};
0042     //! Difference in CPU memory usage from beginning to end
0043     KibiBytes cpu_delta{};
0044     //! Reported CPU "high water mark" at the end the block
0045     KibiBytes cpu_hwm{};
0046     //! Difference in GPU memory usage from beginning to end
0047     KibiBytes gpu_delta{};
0048     //! Reported GPU "high water mark" at the end the block
0049     KibiBytes gpu_usage{};
0050 };
0051 
0052 //---------------------------------------------------------------------------//
0053 /*!
0054  * Track memory usage across the application.
0055  *
0056  * This class is \em not thread-safe and should generally be used during setup.
0057  * The memory usage entries are a tree. Pushing and popping should be done with
0058  * \c ScopedMem .
0059  */
0060 class MemRegistry
0061 {
0062   public:
0063     // Construct with no entries
0064     MemRegistry() = default;
0065 
0066     //// ACCESSORS ////
0067 
0068     //! Number of entries
0069     MemUsageId::size_type size() const { return entries_.size(); }
0070 
0071     // Get the entry for an ID
0072     inline MemUsageEntry& get(MemUsageId id);
0073 
0074     // Get the entry for an ID
0075     inline MemUsageEntry const& get(MemUsageId id) const;
0076 
0077     //! Number of memory entries deep
0078     size_type depth() const { return stack_.size(); }
0079 
0080     //// MUTATORS ////
0081 
0082     // Create a new entry and push it onto the stack, returning the new ID
0083     MemUsageId push();
0084 
0085     // Pop the last entry
0086     void pop();
0087 
0088   private:
0089     std::vector<MemUsageEntry> entries_;
0090     std::vector<MemUsageId> stack_;
0091 };
0092 
0093 //---------------------------------------------------------------------------//
0094 // FREE FUNCTIONS
0095 //---------------------------------------------------------------------------//
0096 // Globally shared registry of memory usage
0097 MemRegistry& mem_registry();
0098 
0099 //---------------------------------------------------------------------------//
0100 // INLINE DEFINITIONS
0101 //---------------------------------------------------------------------------//
0102 /*!
0103  * Get the entry for an ID.
0104  */
0105 MemUsageEntry const& MemRegistry::get(MemUsageId id) const
0106 {
0107     CELER_EXPECT(id < this->size());
0108     return entries_[id.unchecked_get()];
0109 }
0110 
0111 //---------------------------------------------------------------------------//
0112 /*!
0113  * Get the entry for an ID.
0114  */
0115 MemUsageEntry& MemRegistry::get(MemUsageId id)
0116 {
0117     CELER_EXPECT(id < this->size());
0118     return entries_[id.unchecked_get()];
0119 }
0120 
0121 //---------------------------------------------------------------------------//
0122 }  // namespace celeritas