You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Paddle/paddle/fluid/platform/monitor.h

190 lines
5.5 KiB

// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdio.h>
#include <atomic>
#include <memory>
#include <mutex> // NOLINT
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "glog/logging.h"
namespace paddle {
namespace platform {
template <typename T>
class StatRegistry;
class MonitorRegistrar {
public:
// The design is followed by OperatorRegistrar: To avoid the removal of global
// name by the linkerr, we add Touch to all StatValue classes and make
// USE_STAT macros to call this method. So, as long as the callee code calls
// USE_STAT, the global registrar variable won't be removed by the linker.
void Touch() {}
};
template <typename T>
class StatValue : public MonitorRegistrar {
T v_{0};
std::mutex mu_;
// We use lock rather than atomic for generic values
public:
explicit StatValue(const std::string& n) {
StatRegistry<T>::Instance().add(n, this);
}
T increase(T inc) {
std::lock_guard<std::mutex> lock(mu_);
return v_ += inc;
}
T decrease(T inc) {
std::lock_guard<std::mutex> lock(mu_);
return v_ -= inc;
}
T reset(T value = 0) {
std::lock_guard<std::mutex> lock(mu_);
return v_ = value;
}
T get() {
std::lock_guard<std::mutex> lock(mu_);
return v_;
}
};
template <typename T>
struct ExportedStatValue {
std::string key;
T value;
};
template <typename T>
class StatRegistry {
public:
~StatRegistry<T>() {}
static StatRegistry<T>& Instance() {
static StatRegistry<T> r;
return r;
}
StatValue<T>* get(const std::string& name) {
std::lock_guard<std::mutex> lg(mutex_);
auto it = stats_.find(name);
if (it != stats_.end()) {
return it->second;
} else {
return nullptr;
}
}
int add(const std::string& name, StatValue<T>* stat) {
std::lock_guard<std::mutex> lg(mutex_);
auto it = stats_.find(name);
if (it != stats_.end()) {
return -1;
}
stats_.insert(std::make_pair(name, stat));
return 0;
}
void publish(std::vector<ExportedStatValue<T>>& exported, // NOLINT
bool reset = false) {
std::lock_guard<std::mutex> lg(mutex_);
exported.resize(stats_.size());
int i = 0;
for (const auto& kv : stats_) {
auto& out = exported.at(i++);
out.key = kv.first;
out.value = reset ? kv.second->reset() : kv.second->get();
}
}
std::vector<ExportedStatValue<T>> publish(bool reset = false) {
std::vector<ExportedStatValue<T>> stats;
publish(stats, reset);
return stats;
}
private:
std::mutex mutex_;
std::unordered_map<std::string, StatValue<T>*> stats_;
};
} // namespace platform
} // namespace paddle
#define STAT_ADD(item, t) _##item.increase(t)
#define STAT_SUB(item, t) _##item.decrease(t)
// Support add stat value by string
#define STAT_INT_ADD(item, t) \
paddle::platform::StatRegistry<int64_t>::Instance().get(item)->increase(t)
#define STAT_INT_SUB(item, t) \
paddle::platform::StatRegistry<int64_t>::Instance().get(item)->decrease(t)
#define STAT_FLOAT_ADD(item, t) \
paddle::platform::StatRegistry<float>::Instance().get(item)->increase(t)
#define STAT_FLOAT_SUB(item, t) \
paddle::platform::StatRegistry<float>::Instance().get(item)->decrease(t)
#define STAT_RESET(item, t) _##item.reset(t)
#define STAT_GET(item) _##item.get()
#define DEFINE_FLOAT_STATUS(item) \
paddle::platform::StatValue<float> _##item(#item); \
int TouchStatRegistrar_##item() { \
_##item.Touch(); \
return 0; \
}
#define DEFINE_INT_STATUS(item) \
paddle::platform::StatValue<int64_t> _##item(#item); \
int TouchStatRegistrar_##item() { \
_##item.Touch(); \
return 0; \
}
#define USE_STAT(item) \
extern int TouchStatRegistrar_##item(); \
UNUSED static int use_stat_##item = TouchStatRegistrar_##item()
#define USE_INT_STAT(item) \
extern paddle::platform::StatValue<int64_t> _##item; \
USE_STAT(item)
#define USE_FLOAT_STAT(item) \
extern paddle::platform::StatValue<float> _##item; \
USE_STAT(item)
#define USE_GPU_MEM_STAT \
USE_INT_STAT(STAT_gpu0_mem_size); \
USE_INT_STAT(STAT_gpu1_mem_size); \
USE_INT_STAT(STAT_gpu2_mem_size); \
USE_INT_STAT(STAT_gpu3_mem_size); \
USE_INT_STAT(STAT_gpu4_mem_size); \
USE_INT_STAT(STAT_gpu5_mem_size); \
USE_INT_STAT(STAT_gpu6_mem_size); \
USE_INT_STAT(STAT_gpu7_mem_size); \
USE_INT_STAT(STAT_gpu8_mem_size); \
USE_INT_STAT(STAT_gpu9_mem_size); \
USE_INT_STAT(STAT_gpu10_mem_size); \
USE_INT_STAT(STAT_gpu11_mem_size); \
USE_INT_STAT(STAT_gpu12_mem_size); \
USE_INT_STAT(STAT_gpu13_mem_size); \
USE_INT_STAT(STAT_gpu14_mem_size); \
USE_INT_STAT(STAT_gpu15_mem_size)