LINT: Add cpplint, clang-format and pre-commit support
Change-Id: I3cbb787ef27d90486b212dfb1a8c77c460acc2ac Signed-off-by: Galantsev, Dmitrii <dmitrii.galantsev@amd.com>
This commit is contained in:
@@ -20,464 +20,433 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include "rdc_lib/impl/RdcCacheManagerImpl.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
|
||||
#include "rdc_lib/RdcLogger.h"
|
||||
#include "rdc_lib/rdc_common.h"
|
||||
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_field_get_value_since(
|
||||
uint32_t gpu_index, rdc_field_t field_id, uint64_t since_time_stamp,
|
||||
uint64_t *next_since_time_stamp, rdc_field_value* value) {
|
||||
if (!next_since_time_stamp || !value) {
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_field_get_value_since(uint32_t gpu_index,
|
||||
rdc_field_t field_id,
|
||||
uint64_t since_time_stamp,
|
||||
uint64_t* next_since_time_stamp,
|
||||
rdc_field_value* value) {
|
||||
if (!next_since_time_stamp || !value) {
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
RdcFieldKey field{gpu_index, field_id};
|
||||
auto cache_samples_ite = cache_samples_.find(field);
|
||||
if (cache_samples_ite == cache_samples_.end() ||
|
||||
cache_samples_ite->second.size() == 0) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
// TODO(bill_liu): Optimize it using the binary search
|
||||
auto cache_values = cache_samples_ite->second;
|
||||
for (auto cache_value=cache_values.begin();
|
||||
cache_value != cache_values.end(); cache_value++) {
|
||||
if ( cache_value->last_time >= since_time_stamp ) {
|
||||
// move to next potential timestamp
|
||||
auto next_iter = std::next(cache_value);
|
||||
if (next_iter != cache_values.end()) {
|
||||
*next_since_time_stamp = next_iter->last_time;
|
||||
} else { // Last item, set it to the future by adding 1us
|
||||
*next_since_time_stamp = cache_value->last_time + 1;
|
||||
}
|
||||
value->ts = cache_value->last_time;
|
||||
value->type = cache_value->type;
|
||||
|
||||
if (value->type == STRING) {
|
||||
strncpy_with_null(value->value.str, cache_value->value.str,
|
||||
RDC_MAX_STR_LENGTH);
|
||||
} else {
|
||||
value->value.l_int = cache_value->value.l_int;
|
||||
}
|
||||
value->field_id = field_id;
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*next_since_time_stamp = since_time_stamp;
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
RdcFieldKey field{gpu_index, field_id};
|
||||
auto cache_samples_ite = cache_samples_.find(field);
|
||||
if (cache_samples_ite == cache_samples_.end() || cache_samples_ite->second.size() == 0) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
// TODO(bill_liu): Optimize it using the binary search
|
||||
auto cache_values = cache_samples_ite->second;
|
||||
for (auto cache_value = cache_values.begin(); cache_value != cache_values.end(); cache_value++) {
|
||||
if (cache_value->last_time >= since_time_stamp) {
|
||||
// move to next potential timestamp
|
||||
auto next_iter = std::next(cache_value);
|
||||
if (next_iter != cache_values.end()) {
|
||||
*next_since_time_stamp = next_iter->last_time;
|
||||
} else { // Last item, set it to the future by adding 1us
|
||||
*next_since_time_stamp = cache_value->last_time + 1;
|
||||
}
|
||||
value->ts = cache_value->last_time;
|
||||
value->type = cache_value->type;
|
||||
|
||||
if (value->type == STRING) {
|
||||
strncpy_with_null(value->value.str, cache_value->value.str, RDC_MAX_STR_LENGTH);
|
||||
} else {
|
||||
value->value.l_int = cache_value->value.l_int;
|
||||
}
|
||||
value->field_id = field_id;
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*next_since_time_stamp = since_time_stamp;
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::evict_cache(uint32_t gpu_index, rdc_field_t field_id,
|
||||
uint64_t max_keep_samples, double max_keep_age) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::evict_cache(uint32_t gpu_index,
|
||||
rdc_field_t field_id, uint64_t max_keep_samples, double max_keep_age) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
RdcFieldKey field{gpu_index, field_id};
|
||||
auto cache_samples_ite = cache_samples_.find(field);
|
||||
if (cache_samples_ite == cache_samples_.end() || cache_samples_ite->second.size() == 0) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
RdcFieldKey field{gpu_index, field_id};
|
||||
auto cache_samples_ite = cache_samples_.find(field);
|
||||
if (cache_samples_ite == cache_samples_.end() ||
|
||||
cache_samples_ite->second.size() == 0) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
// Check max_keep_samples
|
||||
auto& cache_values = cache_samples_ite->second;
|
||||
int item_remove = cache_values.size() - max_keep_samples;
|
||||
if (item_remove > 0) {
|
||||
cache_values.erase(cache_values.begin(), cache_values.begin() + item_remove);
|
||||
}
|
||||
|
||||
// Check max_keep_age
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
uint64_t now = static_cast<uint64_t>(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
|
||||
|
||||
auto ite = cache_values.begin();
|
||||
while (ite != cache_values.end()) {
|
||||
if (ite->last_time + max_keep_age * 1000 >= now) {
|
||||
break;
|
||||
} else {
|
||||
ite = cache_values.erase(ite);
|
||||
}
|
||||
}
|
||||
|
||||
// Check max_keep_samples
|
||||
auto& cache_values = cache_samples_ite->second;
|
||||
int item_remove = cache_values.size() - max_keep_samples;
|
||||
if (item_remove > 0) {
|
||||
cache_values.erase(cache_values.begin(),
|
||||
cache_values.begin()+item_remove);
|
||||
}
|
||||
|
||||
// Check max_keep_age
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
uint64_t now = static_cast<uint64_t>(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
|
||||
|
||||
auto ite = cache_values.begin();
|
||||
while (ite != cache_values.end()) {
|
||||
if (ite->last_time + max_keep_age*1000 >= now) {
|
||||
break;
|
||||
} else {
|
||||
ite = cache_values.erase(ite);
|
||||
}
|
||||
}
|
||||
|
||||
return RDC_ST_OK;
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_field_get_latest_value(
|
||||
uint32_t gpu_index, rdc_field_t field_id, rdc_field_value* value) {
|
||||
if (!value) {
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_field_get_latest_value(uint32_t gpu_index,
|
||||
rdc_field_t field_id,
|
||||
rdc_field_value* value) {
|
||||
if (!value) {
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
RdcFieldKey field{gpu_index, field_id};
|
||||
auto cache_samples_ite = cache_samples_.find(field);
|
||||
if (cache_samples_ite == cache_samples_.end() ||
|
||||
cache_samples_ite->second.size() == 0) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
RdcFieldKey field{gpu_index, field_id};
|
||||
auto cache_samples_ite = cache_samples_.find(field);
|
||||
if (cache_samples_ite == cache_samples_.end() || cache_samples_ite->second.size() == 0) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
auto& cache_value = cache_samples_ite->second.back();
|
||||
value->ts = cache_value.last_time;
|
||||
value->type = cache_value.type;
|
||||
value->value = cache_value.value;
|
||||
value->field_id = field_id;
|
||||
auto& cache_value = cache_samples_ite->second.back();
|
||||
value->ts = cache_value.last_time;
|
||||
value->type = cache_value.type;
|
||||
value->value = cache_value.value;
|
||||
value->field_id = field_id;
|
||||
|
||||
return RDC_ST_OK;
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
std::string RdcCacheManagerImpl::get_cache_stats() {
|
||||
std::stringstream strstream;
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
std::stringstream strstream;
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
|
||||
strstream << "Cache samples:";
|
||||
auto cache_samples_ite = cache_samples_.begin();
|
||||
for (; cache_samples_ite != cache_samples_.end(); cache_samples_ite++) {
|
||||
strstream << "<" << cache_samples_ite->first.first << ","
|
||||
<< cache_samples_ite->first.second << ":"
|
||||
<< cache_samples_ite->second.size() << "> ";
|
||||
}
|
||||
strstream << "Cache samples:";
|
||||
auto cache_samples_ite = cache_samples_.begin();
|
||||
for (; cache_samples_ite != cache_samples_.end(); cache_samples_ite++) {
|
||||
strstream << "<" << cache_samples_ite->first.first << "," << cache_samples_ite->first.second
|
||||
<< ":" << cache_samples_ite->second.size() << "> ";
|
||||
}
|
||||
|
||||
strstream <<" Job caches:";
|
||||
auto job_ite = cache_jobs_.begin();
|
||||
for ( ; job_ite != cache_jobs_.end(); job_ite++ ) {
|
||||
strstream << "<" << job_ite->first << ":"
|
||||
<< job_ite->second.gpu_stats.size() << "> ";
|
||||
}
|
||||
strstream << " Job caches:";
|
||||
auto job_ite = cache_jobs_.begin();
|
||||
for (; job_ite != cache_jobs_.end(); job_ite++) {
|
||||
strstream << "<" << job_ite->first << ":" << job_ite->second.gpu_stats.size() << "> ";
|
||||
}
|
||||
|
||||
return strstream.str();
|
||||
return strstream.str();
|
||||
}
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_update_cache(uint32_t gpu_index,
|
||||
const rdc_field_value& value) {
|
||||
RdcCacheEntry entry;
|
||||
entry.last_time = value.ts;
|
||||
entry.value = value.value;
|
||||
entry.type = value.type;
|
||||
const rdc_field_value& value) {
|
||||
RdcCacheEntry entry;
|
||||
entry.last_time = value.ts;
|
||||
entry.value = value.value;
|
||||
entry.type = value.type;
|
||||
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
RdcFieldKey field{gpu_index, value.field_id};
|
||||
auto cache_samples_ite = cache_samples_.find(field);
|
||||
if (cache_samples_ite == cache_samples_.end()) {
|
||||
std::vector<RdcCacheEntry> ve;
|
||||
ve.push_back(entry);
|
||||
cache_samples_.insert({field, ve});
|
||||
} else {
|
||||
cache_samples_ite->second.push_back(entry);
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
RdcFieldKey field{gpu_index, value.field_id};
|
||||
auto cache_samples_ite = cache_samples_.find(field);
|
||||
if (cache_samples_ite == cache_samples_.end()) {
|
||||
std::vector<RdcCacheEntry> ve;
|
||||
ve.push_back(entry);
|
||||
cache_samples_.insert({field, ve});
|
||||
} else {
|
||||
cache_samples_ite->second.push_back(entry);
|
||||
}
|
||||
|
||||
return RDC_ST_OK;
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_job_remove(const char job_id[64]) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
cache_jobs_.erase(job_id);
|
||||
return RDC_ST_OK;
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
cache_jobs_.erase(job_id);
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_job_remove_all() {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
cache_jobs_.clear();
|
||||
return RDC_ST_OK;
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
cache_jobs_.clear();
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_update_job_stats(uint32_t gpu_index,
|
||||
const std::string& job_id, const rdc_field_value& value) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
auto job_iter = cache_jobs_.find(job_id);
|
||||
if (job_iter == cache_jobs_.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
const std::string& job_id,
|
||||
const rdc_field_value& value) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
auto job_iter = cache_jobs_.find(job_id);
|
||||
if (job_iter == cache_jobs_.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
auto gpu_iter = job_iter->second.gpu_stats.find(gpu_index);
|
||||
if (gpu_iter == job_iter->second.gpu_stats.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
auto gpu_iter = job_iter->second.gpu_stats.find(gpu_index);
|
||||
if (gpu_iter == job_iter->second.gpu_stats.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
auto fsummary = gpu_iter->second.field_summaries.find(value.field_id);
|
||||
if (fsummary == gpu_iter->second.field_summaries.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
if (fsummary->second.count == 0) { // first item
|
||||
fsummary->second.count = 1;
|
||||
fsummary->second.max_value = value.value.l_int;
|
||||
fsummary->second.min_value = value.value.l_int;
|
||||
fsummary->second.total_value = value.value.l_int;
|
||||
fsummary->second.last_time = value.ts;
|
||||
if (value.field_id == RDC_FI_POWER_USAGE) {
|
||||
gpu_iter->second.energy_last_time = value.ts;
|
||||
}
|
||||
|
||||
// https://www.johndcook.com/blog/standard_deviation/
|
||||
fsummary->second.old_s = 0;
|
||||
fsummary->second.old_m = fsummary->second.new_m = value.value.l_int;
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
if (value.field_id == RDC_FI_POWER_USAGE) {
|
||||
uint64_t time_elapsed = value.ts - gpu_iter->second.energy_last_time;
|
||||
// Stored in cache as microseconds and microwats
|
||||
gpu_iter->second.energy_consumed +=
|
||||
(time_elapsed * value.value.l_int)/(1000.0*1000000);
|
||||
}
|
||||
fsummary->second.max_value = std::max(fsummary->second.max_value,
|
||||
static_cast<int64_t>(value.value.l_int));
|
||||
fsummary->second.min_value = std::min(fsummary->second.min_value,
|
||||
static_cast<int64_t>(value.value.l_int));
|
||||
fsummary->second.total_value += value.value.l_int;
|
||||
auto fsummary = gpu_iter->second.field_summaries.find(value.field_id);
|
||||
if (fsummary == gpu_iter->second.field_summaries.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
if (fsummary->second.count == 0) { // first item
|
||||
fsummary->second.count = 1;
|
||||
fsummary->second.max_value = value.value.l_int;
|
||||
fsummary->second.min_value = value.value.l_int;
|
||||
fsummary->second.total_value = value.value.l_int;
|
||||
fsummary->second.last_time = value.ts;
|
||||
fsummary->second.count++;
|
||||
if (value.field_id == RDC_FI_POWER_USAGE) {
|
||||
gpu_iter->second.energy_last_time = value.ts;
|
||||
}
|
||||
|
||||
// https://www.johndcook.com/blog/standard_deviation/
|
||||
fsummary->second.new_m = fsummary->second.old_m +
|
||||
(value.value.l_int - fsummary->second.old_m)/fsummary->second.count;
|
||||
fsummary->second.new_s = fsummary->second.old_s +
|
||||
(value.value.l_int - fsummary->second.old_m)*
|
||||
(value.value.l_int - fsummary->second.new_m);
|
||||
fsummary->second.old_m = fsummary->second.new_m;
|
||||
fsummary->second.old_s = fsummary->second.new_s;
|
||||
|
||||
fsummary->second.old_s = 0;
|
||||
fsummary->second.old_m = fsummary->second.new_m = value.value.l_int;
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
if (value.field_id == RDC_FI_POWER_USAGE) {
|
||||
uint64_t time_elapsed = value.ts - gpu_iter->second.energy_last_time;
|
||||
// Stored in cache as microseconds and microwats
|
||||
gpu_iter->second.energy_consumed += (time_elapsed * value.value.l_int) / (1000.0 * 1000000);
|
||||
}
|
||||
fsummary->second.max_value =
|
||||
std::max(fsummary->second.max_value, static_cast<int64_t>(value.value.l_int));
|
||||
fsummary->second.min_value =
|
||||
std::min(fsummary->second.min_value, static_cast<int64_t>(value.value.l_int));
|
||||
fsummary->second.total_value += value.value.l_int;
|
||||
fsummary->second.last_time = value.ts;
|
||||
fsummary->second.count++;
|
||||
|
||||
// https://www.johndcook.com/blog/standard_deviation/
|
||||
fsummary->second.new_m = fsummary->second.old_m +
|
||||
(value.value.l_int - fsummary->second.old_m) / fsummary->second.count;
|
||||
fsummary->second.new_s =
|
||||
fsummary->second.old_s +
|
||||
(value.value.l_int - fsummary->second.old_m) * (value.value.l_int - fsummary->second.new_m);
|
||||
fsummary->second.old_m = fsummary->second.new_m;
|
||||
fsummary->second.old_s = fsummary->second.new_s;
|
||||
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
void RdcCacheManagerImpl::set_summary(const FieldSummaryStats & stats,
|
||||
rdc_stats_summary_t & gpu, rdc_stats_summary_t& summary,
|
||||
unsigned int adjuster) {
|
||||
if (stats.count == 0) {
|
||||
gpu.min_value = std::numeric_limits<uint64_t>::max();
|
||||
gpu.max_value = gpu.average = 0;
|
||||
return;
|
||||
}
|
||||
void RdcCacheManagerImpl::set_summary(const FieldSummaryStats& stats, rdc_stats_summary_t& gpu,
|
||||
rdc_stats_summary_t& summary, unsigned int adjuster) {
|
||||
if (stats.count == 0) {
|
||||
gpu.min_value = std::numeric_limits<uint64_t>::max();
|
||||
gpu.max_value = gpu.average = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
gpu.max_value = stats.max_value / adjuster;
|
||||
gpu.min_value = stats.min_value / adjuster;
|
||||
gpu.average = stats.total_value / stats.count / adjuster;
|
||||
summary.max_value = std::max(summary.max_value, gpu.max_value);
|
||||
summary.min_value = std::min(summary.min_value, gpu.min_value);
|
||||
//< save total for future average calculation.
|
||||
summary.average += gpu.average;
|
||||
gpu.max_value = stats.max_value / adjuster;
|
||||
gpu.min_value = stats.min_value / adjuster;
|
||||
gpu.average = stats.total_value / stats.count / adjuster;
|
||||
summary.max_value = std::max(summary.max_value, gpu.max_value);
|
||||
summary.min_value = std::min(summary.min_value, gpu.min_value);
|
||||
//< save total for future average calculation.
|
||||
summary.average += gpu.average;
|
||||
|
||||
//< calculate the sample variance
|
||||
gpu.standard_deviation = std::sqrt((stats.count > 1)
|
||||
? stats.new_s/(stats.count - 1) : 0.0)/adjuster;
|
||||
summary.standard_deviation += gpu.standard_deviation;
|
||||
//< calculate the sample variance
|
||||
gpu.standard_deviation =
|
||||
std::sqrt((stats.count > 1) ? stats.new_s / (stats.count - 1) : 0.0) / adjuster;
|
||||
summary.standard_deviation += gpu.standard_deviation;
|
||||
}
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_job_get_stats(const char jobId[64],
|
||||
const rdc_gpu_gauges_t& gpu_gauges,
|
||||
rdc_job_info_t* p_job_info) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
auto job_stats = cache_jobs_.find(jobId);
|
||||
const rdc_gpu_gauges_t& gpu_gauges,
|
||||
rdc_job_info_t* p_job_info) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
auto job_stats = cache_jobs_.find(jobId);
|
||||
|
||||
if (job_stats == cache_jobs_.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
if (job_stats == cache_jobs_.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
//< Init the summary info
|
||||
bool is_job_stopped = (job_stats->second.end_time != 0);
|
||||
RDC_LOG(RDC_DEBUG, "rdc_job_get_stats for job " << jobId);
|
||||
auto& summary_info = p_job_info->summary;
|
||||
summary_info.start_time = job_stats->second.start_time;
|
||||
if (job_stats->second.end_time == 0) {
|
||||
summary_info.end_time = time(nullptr);
|
||||
//< Init the summary info
|
||||
bool is_job_stopped = (job_stats->second.end_time != 0);
|
||||
RDC_LOG(RDC_DEBUG, "rdc_job_get_stats for job " << jobId);
|
||||
auto& summary_info = p_job_info->summary;
|
||||
summary_info.start_time = job_stats->second.start_time;
|
||||
if (job_stats->second.end_time == 0) {
|
||||
summary_info.end_time = time(nullptr);
|
||||
} else {
|
||||
summary_info.end_time = job_stats->second.end_time;
|
||||
}
|
||||
summary_info.energy_consumed = 0;
|
||||
summary_info.max_gpu_memory_used = 0;
|
||||
summary_info.ecc_correct = 0;
|
||||
summary_info.ecc_uncorrect = 0;
|
||||
summary_info.power_usage = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.pcie_tx = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.pcie_rx = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.gpu_temperature = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.memory_clock = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.gpu_clock = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.gpu_utilization = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.memory_utilization = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
|
||||
p_job_info->num_gpus = job_stats->second.gpu_stats.size();
|
||||
|
||||
//< Populate information for each GPUs
|
||||
|
||||
auto gpus = job_stats->second.gpu_stats.begin();
|
||||
for (; gpus != job_stats->second.gpu_stats.end(); gpus++) {
|
||||
auto& gpu_info = p_job_info->gpus[gpus->first];
|
||||
gpu_info.start_time = summary_info.start_time;
|
||||
gpu_info.end_time = summary_info.end_time;
|
||||
gpu_info.energy_consumed = gpus->second.energy_consumed;
|
||||
summary_info.energy_consumed += gpu_info.energy_consumed;
|
||||
|
||||
if (is_job_stopped) {
|
||||
gpu_info.ecc_correct = gpus->second.ecc_correct_init;
|
||||
summary_info.ecc_correct += gpu_info.ecc_correct;
|
||||
} else if (gpu_gauges.find({gpus->first, RDC_FI_ECC_CORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gpu_info.ecc_correct =
|
||||
gpu_gauges.at({gpus->first, RDC_FI_ECC_CORRECT_TOTAL}) - gpus->second.ecc_correct_init;
|
||||
summary_info.ecc_correct += gpu_info.ecc_correct;
|
||||
} else {
|
||||
summary_info.end_time = job_stats->second.end_time;
|
||||
gpu_info.ecc_correct = 0;
|
||||
}
|
||||
summary_info.energy_consumed = 0;
|
||||
summary_info.max_gpu_memory_used = 0;
|
||||
summary_info.ecc_correct = 0;
|
||||
summary_info.ecc_uncorrect = 0;
|
||||
summary_info.power_usage = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.pcie_tx = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.pcie_rx = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.gpu_temperature =
|
||||
{0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.memory_clock = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.gpu_clock = {0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.gpu_utilization =
|
||||
{0, std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
summary_info.memory_utilization = {0,
|
||||
std::numeric_limits<uint64_t>::max(), 0, 0};
|
||||
|
||||
p_job_info->num_gpus = job_stats->second.gpu_stats.size();
|
||||
|
||||
//< Populate information for each GPUs
|
||||
|
||||
auto gpus = job_stats->second.gpu_stats.begin();
|
||||
for (; gpus != job_stats->second.gpu_stats.end(); gpus++) {
|
||||
auto & gpu_info = p_job_info->gpus[gpus->first];
|
||||
gpu_info.start_time = summary_info.start_time;
|
||||
gpu_info.end_time = summary_info.end_time;
|
||||
gpu_info.energy_consumed = gpus->second.energy_consumed;
|
||||
summary_info.energy_consumed += gpu_info.energy_consumed;
|
||||
|
||||
if (is_job_stopped) {
|
||||
gpu_info.ecc_correct = gpus->second.ecc_correct_init;
|
||||
summary_info.ecc_correct += gpu_info.ecc_correct;
|
||||
} else if (gpu_gauges.find({gpus->first,
|
||||
RDC_FI_ECC_CORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gpu_info.ecc_correct = gpu_gauges.at({
|
||||
gpus->first, RDC_FI_ECC_CORRECT_TOTAL}) -
|
||||
gpus->second.ecc_correct_init;
|
||||
summary_info.ecc_correct += gpu_info.ecc_correct;
|
||||
} else {
|
||||
gpu_info.ecc_correct = 0;
|
||||
}
|
||||
|
||||
if (is_job_stopped) {
|
||||
gpu_info.ecc_uncorrect = gpus->second.ecc_uncorrect_init;
|
||||
summary_info.ecc_uncorrect += gpu_info.ecc_uncorrect;
|
||||
} else if (gpu_gauges.find({gpus->first,
|
||||
RDC_FI_ECC_UNCORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gpu_info.ecc_uncorrect = gpu_gauges.at({
|
||||
gpus->first, RDC_FI_ECC_UNCORRECT_TOTAL}) -
|
||||
gpus->second.ecc_uncorrect_init;
|
||||
summary_info.ecc_uncorrect += gpu_info.ecc_uncorrect;
|
||||
} else {
|
||||
gpu_info.ecc_uncorrect = 0;
|
||||
}
|
||||
|
||||
if (gpu_gauges.find({gpus->first,
|
||||
RDC_FI_GPU_MEMORY_TOTAL}) == gpu_gauges.end()) {
|
||||
RDC_LOG(RDC_ERROR, "Cannot find the total memory");
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
uint64_t tmemory = gpu_gauges.at({gpus->first,
|
||||
RDC_FI_GPU_MEMORY_TOTAL});
|
||||
|
||||
auto ite = gpus->second.field_summaries.begin();
|
||||
for (; ite != gpus->second.field_summaries.end(); ite++) {
|
||||
if (ite->first == RDC_FI_POWER_USAGE) {
|
||||
set_summary(ite->second,
|
||||
gpu_info.power_usage, summary_info.power_usage, 1000000);
|
||||
} else if (ite->first == RDC_FI_GPU_MEMORY_USAGE) {
|
||||
set_summary(ite->second, gpu_info.memory_utilization,
|
||||
summary_info.memory_utilization, tmemory/100);
|
||||
gpu_info.max_gpu_memory_used = ite->second.max_value;
|
||||
summary_info.max_gpu_memory_used = std::max(
|
||||
summary_info.max_gpu_memory_used,
|
||||
gpu_info.max_gpu_memory_used);
|
||||
} else if (ite->first == RDC_FI_GPU_CLOCK) {
|
||||
set_summary(ite->second, gpu_info.gpu_clock,
|
||||
summary_info.gpu_clock, 1000000);
|
||||
} else if (ite->first == RDC_FI_GPU_UTIL) {
|
||||
set_summary(ite->second, gpu_info.gpu_utilization,
|
||||
summary_info.gpu_utilization, 1);
|
||||
} else if (ite->first == RDC_FI_GPU_TEMP) {
|
||||
set_summary(ite->second,
|
||||
gpu_info.gpu_temperature, summary_info.gpu_temperature, 1000);
|
||||
} else if (ite->first == RDC_FI_MEM_CLOCK) {
|
||||
set_summary(ite->second,
|
||||
gpu_info.memory_clock, summary_info.memory_clock, 1000000);
|
||||
} else if (ite->first == RDC_FI_PCIE_TX) {
|
||||
set_summary(ite->second,
|
||||
gpu_info.pcie_tx, summary_info.pcie_tx, 1024*1024);
|
||||
} else if (ite->first == RDC_FI_PCIE_RX) {
|
||||
set_summary(ite->second,
|
||||
gpu_info.pcie_rx, summary_info.pcie_rx, 1024*1024);
|
||||
}
|
||||
}
|
||||
if (is_job_stopped) {
|
||||
gpu_info.ecc_uncorrect = gpus->second.ecc_uncorrect_init;
|
||||
summary_info.ecc_uncorrect += gpu_info.ecc_uncorrect;
|
||||
} else if (gpu_gauges.find({gpus->first, RDC_FI_ECC_UNCORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gpu_info.ecc_uncorrect = gpu_gauges.at({gpus->first, RDC_FI_ECC_UNCORRECT_TOTAL}) -
|
||||
gpus->second.ecc_uncorrect_init;
|
||||
summary_info.ecc_uncorrect += gpu_info.ecc_uncorrect;
|
||||
} else {
|
||||
gpu_info.ecc_uncorrect = 0;
|
||||
}
|
||||
// Set the average of the summary
|
||||
set_average_summary(summary_info.power_usage, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.gpu_clock, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.gpu_utilization, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.memory_utilization, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.pcie_tx, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.pcie_rx, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.gpu_temperature, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.memory_clock, p_job_info->num_gpus);
|
||||
|
||||
return RDC_ST_OK;
|
||||
if (gpu_gauges.find({gpus->first, RDC_FI_GPU_MEMORY_TOTAL}) == gpu_gauges.end()) {
|
||||
RDC_LOG(RDC_ERROR, "Cannot find the total memory");
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
uint64_t tmemory = gpu_gauges.at({gpus->first, RDC_FI_GPU_MEMORY_TOTAL});
|
||||
|
||||
auto ite = gpus->second.field_summaries.begin();
|
||||
for (; ite != gpus->second.field_summaries.end(); ite++) {
|
||||
if (ite->first == RDC_FI_POWER_USAGE) {
|
||||
set_summary(ite->second, gpu_info.power_usage, summary_info.power_usage, 1000000);
|
||||
} else if (ite->first == RDC_FI_GPU_MEMORY_USAGE) {
|
||||
set_summary(ite->second, gpu_info.memory_utilization, summary_info.memory_utilization,
|
||||
tmemory / 100);
|
||||
gpu_info.max_gpu_memory_used = ite->second.max_value;
|
||||
summary_info.max_gpu_memory_used =
|
||||
std::max(summary_info.max_gpu_memory_used, gpu_info.max_gpu_memory_used);
|
||||
} else if (ite->first == RDC_FI_GPU_CLOCK) {
|
||||
set_summary(ite->second, gpu_info.gpu_clock, summary_info.gpu_clock, 1000000);
|
||||
} else if (ite->first == RDC_FI_GPU_UTIL) {
|
||||
set_summary(ite->second, gpu_info.gpu_utilization, summary_info.gpu_utilization, 1);
|
||||
} else if (ite->first == RDC_FI_GPU_TEMP) {
|
||||
set_summary(ite->second, gpu_info.gpu_temperature, summary_info.gpu_temperature, 1000);
|
||||
} else if (ite->first == RDC_FI_MEM_CLOCK) {
|
||||
set_summary(ite->second, gpu_info.memory_clock, summary_info.memory_clock, 1000000);
|
||||
} else if (ite->first == RDC_FI_PCIE_TX) {
|
||||
set_summary(ite->second, gpu_info.pcie_tx, summary_info.pcie_tx, 1024 * 1024);
|
||||
} else if (ite->first == RDC_FI_PCIE_RX) {
|
||||
set_summary(ite->second, gpu_info.pcie_rx, summary_info.pcie_rx, 1024 * 1024);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set the average of the summary
|
||||
set_average_summary(summary_info.power_usage, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.gpu_clock, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.gpu_utilization, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.memory_utilization, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.pcie_tx, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.pcie_rx, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.gpu_temperature, p_job_info->num_gpus);
|
||||
set_average_summary(summary_info.memory_clock, p_job_info->num_gpus);
|
||||
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
void RdcCacheManagerImpl::set_average_summary(
|
||||
rdc_stats_summary_t& summary, uint32_t num_gpus) {
|
||||
summary.average = summary.average/num_gpus;
|
||||
summary.standard_deviation = summary.standard_deviation/num_gpus;
|
||||
void RdcCacheManagerImpl::set_average_summary(rdc_stats_summary_t& summary, uint32_t num_gpus) {
|
||||
summary.average = summary.average / num_gpus;
|
||||
summary.standard_deviation = summary.standard_deviation / num_gpus;
|
||||
}
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_job_start_stats(const char job_id[64],
|
||||
const rdc_group_info_t& ginfo, const rdc_field_group_info_t& finfo,
|
||||
const rdc_gpu_gauges_t& gpu_gauges) {
|
||||
RdcJobStatsCacheEntry cacheEntry;
|
||||
cacheEntry.start_time = std::time(nullptr);
|
||||
cacheEntry.end_time = 0;
|
||||
for (unsigned int i=0 ; i < ginfo.count; i++) { // GPUs
|
||||
GpuSummaryStats gstats;
|
||||
gstats.energy_consumed = 0;
|
||||
gstats.energy_last_time = 0;
|
||||
for (unsigned int j = 0; j < finfo.count; j++) { // init fields
|
||||
FieldSummaryStats s;
|
||||
s.count = 0;
|
||||
s.max_value = s.min_value = s.total_value = 0;
|
||||
gstats.field_summaries.insert({finfo.field_ids[j], s});
|
||||
}
|
||||
const rdc_group_info_t& ginfo,
|
||||
const rdc_field_group_info_t& finfo,
|
||||
const rdc_gpu_gauges_t& gpu_gauges) {
|
||||
RdcJobStatsCacheEntry cacheEntry;
|
||||
cacheEntry.start_time = std::time(nullptr);
|
||||
cacheEntry.end_time = 0;
|
||||
for (unsigned int i = 0; i < ginfo.count; i++) { // GPUs
|
||||
GpuSummaryStats gstats;
|
||||
gstats.energy_consumed = 0;
|
||||
gstats.energy_last_time = 0;
|
||||
for (unsigned int j = 0; j < finfo.count; j++) { // init fields
|
||||
FieldSummaryStats s;
|
||||
s.count = 0;
|
||||
s.max_value = s.min_value = s.total_value = 0;
|
||||
gstats.field_summaries.insert({finfo.field_ids[j], s});
|
||||
}
|
||||
|
||||
gstats.ecc_correct_init = 0;
|
||||
if (gpu_gauges.find({ginfo.entity_ids[i], RDC_FI_ECC_CORRECT_TOTAL}) !=
|
||||
gpu_gauges.end()) {
|
||||
gstats.ecc_correct_init = gpu_gauges.at(
|
||||
{ginfo.entity_ids[i], RDC_FI_ECC_CORRECT_TOTAL});
|
||||
}
|
||||
gstats.ecc_correct_init = 0;
|
||||
if (gpu_gauges.find({ginfo.entity_ids[i], RDC_FI_ECC_CORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gstats.ecc_correct_init = gpu_gauges.at({ginfo.entity_ids[i], RDC_FI_ECC_CORRECT_TOTAL});
|
||||
}
|
||||
|
||||
gstats.ecc_uncorrect_init = 0;
|
||||
if (gpu_gauges.find({ginfo.entity_ids[i], RDC_FI_ECC_UNCORRECT_TOTAL}) !=
|
||||
gpu_gauges.end()) {
|
||||
gstats.ecc_uncorrect_init = gpu_gauges.at(
|
||||
{ginfo.entity_ids[i], RDC_FI_ECC_UNCORRECT_TOTAL});
|
||||
}
|
||||
gstats.ecc_uncorrect_init = 0;
|
||||
if (gpu_gauges.find({ginfo.entity_ids[i], RDC_FI_ECC_UNCORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gstats.ecc_uncorrect_init = gpu_gauges.at({ginfo.entity_ids[i], RDC_FI_ECC_UNCORRECT_TOTAL});
|
||||
}
|
||||
|
||||
cacheEntry.gpu_stats.insert({ginfo.entity_ids[i], gstats});
|
||||
}
|
||||
cacheEntry.gpu_stats.insert({ginfo.entity_ids[i], gstats});
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
// Remove the old stats if it exists
|
||||
cache_jobs_.erase(job_id);
|
||||
cache_jobs_.insert({job_id, cacheEntry});
|
||||
return RDC_ST_OK;
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
// Remove the old stats if it exists
|
||||
cache_jobs_.erase(job_id);
|
||||
cache_jobs_.insert({job_id, cacheEntry});
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
|
||||
rdc_status_t RdcCacheManagerImpl::rdc_job_stop_stats(const char job_id[64],
|
||||
const rdc_gpu_gauges_t& gpu_gauges) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
auto job_stats = cache_jobs_.find(job_id);
|
||||
const rdc_gpu_gauges_t& gpu_gauges) {
|
||||
std::lock_guard<std::mutex> guard(cache_mutex_);
|
||||
auto job_stats = cache_jobs_.find(job_id);
|
||||
|
||||
if (job_stats == cache_jobs_.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
if (job_stats == cache_jobs_.end()) {
|
||||
return RDC_ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
job_stats->second.end_time = std::time(nullptr);
|
||||
|
||||
// update the ecc errors
|
||||
auto gpus = job_stats->second.gpu_stats.begin();
|
||||
for (; gpus != job_stats->second.gpu_stats.end(); gpus++) {
|
||||
if (gpu_gauges.find({gpus->first, RDC_FI_ECC_CORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gpus->second.ecc_correct_init =
|
||||
gpu_gauges.at({gpus->first, RDC_FI_ECC_CORRECT_TOTAL}) - gpus->second.ecc_correct_init;
|
||||
}
|
||||
|
||||
job_stats->second.end_time = std::time(nullptr);
|
||||
|
||||
// update the ecc errors
|
||||
auto gpus = job_stats->second.gpu_stats.begin();
|
||||
for (; gpus != job_stats->second.gpu_stats.end(); gpus++) {
|
||||
if (gpu_gauges.find({gpus->first,
|
||||
RDC_FI_ECC_CORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gpus->second.ecc_correct_init = gpu_gauges.at({
|
||||
gpus->first, RDC_FI_ECC_CORRECT_TOTAL}) -
|
||||
gpus->second.ecc_correct_init;
|
||||
}
|
||||
|
||||
if (gpu_gauges.find({gpus->first,
|
||||
RDC_FI_ECC_UNCORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gpus->second.ecc_uncorrect_init = gpu_gauges.at({
|
||||
gpus->first, RDC_FI_ECC_UNCORRECT_TOTAL}) -
|
||||
gpus->second.ecc_uncorrect_init;
|
||||
}
|
||||
if (gpu_gauges.find({gpus->first, RDC_FI_ECC_UNCORRECT_TOTAL}) != gpu_gauges.end()) {
|
||||
gpus->second.ecc_uncorrect_init = gpu_gauges.at({gpus->first, RDC_FI_ECC_UNCORRECT_TOTAL}) -
|
||||
gpus->second.ecc_uncorrect_init;
|
||||
}
|
||||
}
|
||||
|
||||
return RDC_ST_OK;
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
} // namespace rdc
|
||||
|
||||
Reference in New Issue
Block a user