xref: /aosp_15_r20/external/pytorch/c10/util/Gauge.cpp (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Gauge.h>
2*da0073e9SAndroid Build Coastguard Worker 
3*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Synchronized.h>
4*da0073e9SAndroid Build Coastguard Worker 
5*da0073e9SAndroid Build Coastguard Worker #include <memory>
6*da0073e9SAndroid Build Coastguard Worker #include <string>
7*da0073e9SAndroid Build Coastguard Worker #include <string_view>
8*da0073e9SAndroid Build Coastguard Worker #include <unordered_map>
9*da0073e9SAndroid Build Coastguard Worker #include <vector>
10*da0073e9SAndroid Build Coastguard Worker 
11*da0073e9SAndroid Build Coastguard Worker namespace c10::monitor {
12*da0073e9SAndroid Build Coastguard Worker 
13*da0073e9SAndroid Build Coastguard Worker namespace detail {
14*da0073e9SAndroid Build Coastguard Worker namespace {
15*da0073e9SAndroid Build Coastguard Worker using GaugeBackendFactories =
16*da0073e9SAndroid Build Coastguard Worker     std::vector<std::shared_ptr<GaugeBackendFactoryIf>>;
17*da0073e9SAndroid Build Coastguard Worker 
gaugeBackendFactories()18*da0073e9SAndroid Build Coastguard Worker Synchronized<GaugeBackendFactories>& gaugeBackendFactories() {
19*da0073e9SAndroid Build Coastguard Worker   static auto instance = new Synchronized<GaugeBackendFactories>();
20*da0073e9SAndroid Build Coastguard Worker   return *instance;
21*da0073e9SAndroid Build Coastguard Worker }
22*da0073e9SAndroid Build Coastguard Worker } // namespace
23*da0073e9SAndroid Build Coastguard Worker 
24*da0073e9SAndroid Build Coastguard Worker class GaugeImpl {
25*da0073e9SAndroid Build Coastguard Worker  public:
getInstance(std::string_view key)26*da0073e9SAndroid Build Coastguard Worker   static GaugeImpl& getInstance(std::string_view key) {
27*da0073e9SAndroid Build Coastguard Worker     static auto& implMapSynchronized = *new Synchronized<
28*da0073e9SAndroid Build Coastguard Worker         std::unordered_map<std::string, std::unique_ptr<GaugeImpl>>>();
29*da0073e9SAndroid Build Coastguard Worker 
30*da0073e9SAndroid Build Coastguard Worker     return *implMapSynchronized.withLock([&](auto& implMap) {
31*da0073e9SAndroid Build Coastguard Worker       if (auto implIt = implMap.find(std::string(key));
32*da0073e9SAndroid Build Coastguard Worker           implIt != implMap.end()) {
33*da0073e9SAndroid Build Coastguard Worker         return implIt->second.get();
34*da0073e9SAndroid Build Coastguard Worker       }
35*da0073e9SAndroid Build Coastguard Worker 
36*da0073e9SAndroid Build Coastguard Worker       auto [implIt, emplaceSuccess] = implMap.emplace(
37*da0073e9SAndroid Build Coastguard Worker           std::string{key}, std::unique_ptr<GaugeImpl>(new GaugeImpl(key)));
38*da0073e9SAndroid Build Coastguard Worker 
39*da0073e9SAndroid Build Coastguard Worker       assert(emplaceSuccess);
40*da0073e9SAndroid Build Coastguard Worker 
41*da0073e9SAndroid Build Coastguard Worker       return implIt->second.get();
42*da0073e9SAndroid Build Coastguard Worker     });
43*da0073e9SAndroid Build Coastguard Worker   }
44*da0073e9SAndroid Build Coastguard Worker 
record(int64_t value)45*da0073e9SAndroid Build Coastguard Worker   void record(int64_t value) {
46*da0073e9SAndroid Build Coastguard Worker     for (auto& backend : backends_) {
47*da0073e9SAndroid Build Coastguard Worker       backend->record(value);
48*da0073e9SAndroid Build Coastguard Worker     }
49*da0073e9SAndroid Build Coastguard Worker   }
50*da0073e9SAndroid Build Coastguard Worker 
51*da0073e9SAndroid Build Coastguard Worker  private:
GaugeImpl(std::string_view key)52*da0073e9SAndroid Build Coastguard Worker   explicit GaugeImpl(std::string_view key) {
53*da0073e9SAndroid Build Coastguard Worker     auto factoriesCopy = gaugeBackendFactories().withLock(
54*da0073e9SAndroid Build Coastguard Worker         [](auto& factories) { return factories; });
55*da0073e9SAndroid Build Coastguard Worker     for (const auto& factory : factoriesCopy) {
56*da0073e9SAndroid Build Coastguard Worker       if (auto backend = factory->create(key)) {
57*da0073e9SAndroid Build Coastguard Worker         backends_.push_back(std::move(backend));
58*da0073e9SAndroid Build Coastguard Worker       }
59*da0073e9SAndroid Build Coastguard Worker     }
60*da0073e9SAndroid Build Coastguard Worker   }
61*da0073e9SAndroid Build Coastguard Worker 
62*da0073e9SAndroid Build Coastguard Worker   SmallVector<std::unique_ptr<GaugeBackendIf>> backends_;
63*da0073e9SAndroid Build Coastguard Worker };
64*da0073e9SAndroid Build Coastguard Worker 
registerGaugeBackend(std::unique_ptr<GaugeBackendFactoryIf> backend)65*da0073e9SAndroid Build Coastguard Worker void registerGaugeBackend(std::unique_ptr<GaugeBackendFactoryIf> backend) {
66*da0073e9SAndroid Build Coastguard Worker   gaugeBackendFactories().withLock(
67*da0073e9SAndroid Build Coastguard Worker       [&](auto& backends) { backends.push_back(std::move(backend)); });
68*da0073e9SAndroid Build Coastguard Worker }
69*da0073e9SAndroid Build Coastguard Worker 
70*da0073e9SAndroid Build Coastguard Worker } // namespace detail
71*da0073e9SAndroid Build Coastguard Worker 
GaugeHandle(std::string_view key)72*da0073e9SAndroid Build Coastguard Worker GaugeHandle::GaugeHandle(std::string_view key)
73*da0073e9SAndroid Build Coastguard Worker     : impl_(detail::GaugeImpl::getInstance(key)) {}
74*da0073e9SAndroid Build Coastguard Worker 
record(int64_t value)75*da0073e9SAndroid Build Coastguard Worker void GaugeHandle::record(int64_t value) {
76*da0073e9SAndroid Build Coastguard Worker   impl_.record(value);
77*da0073e9SAndroid Build Coastguard Worker }
78*da0073e9SAndroid Build Coastguard Worker 
79*da0073e9SAndroid Build Coastguard Worker } // namespace c10::monitor
80