|
||||
File indexing completed on 2025-01-18 09:54:50
0001 //----------------------------------*-C++-*----------------------------------// 0002 // Copyright 2022-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/KernelRegistry.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <atomic> 0011 #include <cstdint> 0012 #include <iosfwd> // IWYU pragma: keep 0013 #include <memory> 0014 #include <mutex> 0015 #include <string> 0016 #include <string_view> 0017 #include <vector> 0018 0019 #include "corecel/Assert.hh" 0020 #include "corecel/OpaqueId.hh" 0021 0022 #include "KernelAttributes.hh" 0023 0024 namespace celeritas 0025 { 0026 //---------------------------------------------------------------------------// 0027 struct KernelProfiling 0028 { 0029 using value_type = std::uint_least64_t; 0030 0031 //!< Number of times launched 0032 std::atomic<value_type> num_launches{0}; 0033 //!< Number of threads integrated over all launches 0034 std::atomic<value_type> accum_threads{0}; 0035 0036 // Increment atomic counters given the number of threads 0037 inline void log_launch(value_type num_threads); 0038 }; 0039 0040 //---------------------------------------------------------------------------// 0041 struct KernelMetadata 0042 { 0043 std::string name; 0044 KernelAttributes attributes; 0045 KernelProfiling profiling; 0046 }; 0047 0048 //! Ordered identifiers for registered kernels 0049 using KernelId = OpaqueId<KernelMetadata>; 0050 0051 //---------------------------------------------------------------------------// 0052 /*! 0053 * Keep track of kernels and launches. 0054 * 0055 * Every "insert" creates a unique \c KernelMetadata entry in a thread-safe 0056 * fashion (in case multiple threads are launching kernels for the first time). 0057 * Thus every kernel added to the registry needs a \c static local data (i.e., 0058 * \c KernelParamCalculator) to track whether the kernel has been added and to 0059 * keep a reference to the returned profiling data counter. Kernels are always 0060 * added sequentially and can never be removed from the registry once added. 0061 * Kernels that share the same name will create independent entries! 0062 * 0063 * This class has a thread-safe methods because it's meant to be shared 0064 * across multiple threads when running. Generally \c insert is the only method 0065 * expected to have contention across threads. 0066 */ 0067 class KernelRegistry 0068 { 0069 public: 0070 // Whether profiling metrics (launch count, max threads) are collected 0071 static bool profiling(); 0072 0073 // Construct without any data 0074 KernelRegistry() = default; 0075 0076 //// CONSTRUCTION //// 0077 0078 // Register a kernel and return optional reference to profiling info 0079 KernelProfiling* insert(std::string_view name, KernelAttributes&& attrs); 0080 0081 //// ACCESSORS //// 0082 0083 //! \todo rename to size 0084 // Number of kernel diagnostics available 0085 KernelId::size_type num_kernels() const; 0086 0087 //! \todo rename to get 0088 // Access kernel data for a single kernel 0089 KernelMetadata const& kernel(KernelId id) const; 0090 0091 private: 0092 using UPKM = std::unique_ptr<KernelMetadata>; 0093 0094 mutable std::mutex kernels_mutex_; 0095 std::vector<UPKM> kernels_; 0096 }; 0097 0098 //---------------------------------------------------------------------------// 0099 // FREE FUNCTIONS 0100 //---------------------------------------------------------------------------// 0101 // Globally shared registry of kernels for end-of-program diagnostics 0102 KernelRegistry& kernel_registry(); 0103 0104 // Write kernel statistics to a stream 0105 std::ostream& operator<<(std::ostream& os, KernelMetadata const& md); 0106 0107 //---------------------------------------------------------------------------// 0108 // INLINE DEFINITIONS 0109 //---------------------------------------------------------------------------// 0110 /*! 0111 * Accumulate counters for a kernel launch. 0112 */ 0113 void KernelProfiling::log_launch(value_type num_threads) 0114 { 0115 CELER_EXPECT(num_threads > 0); 0116 0117 // Increment launches by 1 and thread count by num_threads. 0118 // We don't care in what order these values are written. 0119 this->num_launches.fetch_add(1, std::memory_order_relaxed); 0120 this->accum_threads.fetch_add(num_threads, std::memory_order_relaxed); 0121 } 0122 0123 //---------------------------------------------------------------------------// 0124 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |