Skip to content
This repository has been archived by the owner on Feb 14, 2024. It is now read-only.

Commit

Permalink
Supporting other memory units
Browse files Browse the repository at this point in the history
* MB, MiB, GB, GiB

- Added metric::Common::unit
- Supporting converting metrics to other units
- Added utils::unit
- Ignoring linter errors 'readability/braces'
  • Loading branch information
razrotenberg committed Mar 24, 2022
1 parent b93e98d commit 84f8bcb
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 36 deletions.
3 changes: 2 additions & 1 deletion CPPLINT.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set noparent
# filter out non-relevant messages (documented examples)
# - build/c++11: "<mutex> is an unapproved C++11 header"
# - legal/copyright: "No copyright message found"
# - readability/braces: "If an else has a brace on one side, it should have it on both"
# - runtime/explicit: "Single-parameter constructors should be marked explicit"
# - runtime/int: "Use int16/int64/etc, rather than the C type long"
# - runtime/references: "Is this a non-const reference? If so, make const or use a pointer"
Expand All @@ -12,4 +13,4 @@ set noparent
# - whitespace/line_length: "Lines should be <= 80 characters long"
# - whitespace/newline: "An else should appear on the same line as the preceding }"
#
filter=-build/c++11,-legal/copyright,-runtime/explicit,-runtime/int,-runtime/references,-whitespace/braces,-whitespace/comments,-whitespace/line_length,-whitespace/newline
filter=-build/c++11,-legal/copyright,-readability/braces,-runtime/explicit,-runtime/int,-runtime/references,-whitespace/braces,-whitespace/comments,-whitespace/line_length,-whitespace/newline
5 changes: 4 additions & 1 deletion arguments/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ load("//:rules.bzl", "rntop_cc_auto_library")

rntop_cc_auto_library(
name = "arguments",
deps = ["//agent/type"],
deps = [
"//agent/type",
"//unit",
],
)
23 changes: 13 additions & 10 deletions arguments/arguments.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ Arguments Arguments::parse(int argc, char * argv[])

const auto usage = [=]()
{
std::cerr << "usage: " << argv[0] << " [-i --interval secs] [--color --no-color] [-l -u --username username] [--ssh] [--libssh] ...hostname" << std::endl;
std::cerr << "usage: " << argv[0] << " [-i --interval secs] [-l -u --username username] [--ssh] [--libssh] ...hostname" << std::endl;
std::cerr << "\nSettings:" << std::endl;
std::cerr << " -i --interval Interval in seconds between updates; default: " << arguments.interval << std::endl;
std::cerr << " --color --no-color Use colors; default: " << arguments.color << std::endl;
std::cerr << " -l -u --username Username for login" << std::endl;
std::cerr << " --ssh Use 'ssh' command for remote execution" << std::endl;
std::cerr << " --libssh Use libssh for remote execution (default)" << std::endl;
std::cerr << "\nGUI:" << std::endl;
std::cerr << " --mb --mib --gb --gib Unit for memory metrics" << std::endl;
std::cerr << " --[no-]color Use colors; default: " << arguments.color << std::endl;
std::cerr << "\nInformation about GPU:" << std::endl;
std::cerr << " --[no-]gpu-index Zero based index of the GPU; default: " << arguments.gpu_index << std::endl;
std::cerr << " --[no-]gpu-name The official product name of the GPU; default: " << arguments.gpu_name << std::endl;
Expand Down Expand Up @@ -67,14 +70,6 @@ Arguments Arguments::parse(int argc, char * argv[])
exit(EXIT_FAILURE);
}
}
else if (arg == "--color")
{
arguments.color = true;
}
else if (arg == "--no-color")
{
arguments.color = false;
}
else if (arg == "-l" || arg == "-u" || arg == "--username")
{
arguments.username = shift();
Expand All @@ -87,6 +82,14 @@ Arguments Arguments::parse(int argc, char * argv[])
{
arguments.agent = decltype(arguments.agent)::libssh;
}
else if (arg == "--mb") { arguments.unit = Unit::MB; }
else if (arg == "--mib") { arguments.unit = Unit::MiB; }
else if (arg == "--gb") { arguments.unit = Unit::GB; }
else if (arg == "--gib") { arguments.unit = Unit::GiB; }
else if (arg == "--color" || arg == "--no-color")
{
arguments.color = arg == "--color";
}
else if (arg == "--gpu-index" || arg == "--no-gpu-index")
{
arguments.gpu_index = arg == "--gpu-index";
Expand Down
2 changes: 2 additions & 0 deletions arguments/arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <vector>

#include "agent/type/type.h"
#include "unit/unit.h"

namespace runai
{
Expand All @@ -15,6 +16,7 @@ struct Arguments
agent::Type agent = agent::Type::libssh;
std::string username = "";
bool color = true;
Unit unit = Unit::MiB;

// information to show about GPU
bool gpu_index = true;
Expand Down
9 changes: 4 additions & 5 deletions cluster/cluster.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,15 @@ Cluster::Cluster(const std::vector<std::string> & hostnames, const std::string &

void Cluster::refresh()
{
using Op = utils::Op<size_t, Node>;

_metric.store(
{
// TODO(raz): theoretically, a node metric can change while we are calculating the cluster metric.
// we should consider copying the node metrics for the cluster metric to be coherent.

.utilization = utils::avg(_nodes, (Op)[](const auto & node){ return node.metric().utilization; }),
.used_memory = utils::sum(_nodes, (Op)[](const auto & node){ return node.metric().used_memory; }),
.total_memory = utils::sum(_nodes, (Op)[](const auto & node){ return node.metric().total_memory; }),
.utilization = utils::avg(_nodes, (utils::Op<size_t, Node>)[](const auto & node){ return node.metric().utilization; }),
.used_memory = utils::sum(_nodes, (utils::Op<double, Node>)[](const auto & node){ return node.metric().used_memory; }),
.total_memory = utils::sum(_nodes, (utils::Op<double, Node>)[](const auto & node){ return node.metric().total_memory; }),
.unit = Unit::MiB,
});
}

Expand Down
6 changes: 3 additions & 3 deletions gui/app/app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ void App::refresh(const Cluster & cluster)
_nodes.moveln(0);
_gpus.moveln(0);

_cluster.println(cluster.metric());
_cluster.println(cluster.metric().convert(_arguments.unit));

for (const auto & node : cluster)
{
_nodes.print("%-25s %-11s\t", node.hostname().c_str(), node.driver().c_str());
_nodes.println(node.metric());
_nodes.println(node.metric().convert(_arguments.unit));

for (const auto & device : node)
{
Expand All @@ -55,7 +55,7 @@ void App::refresh(const Cluster & cluster)
}

_gpus.print("\t");
_gpus.println(device.metric());
_gpus.println(device.metric().convert(_arguments.unit));
}
}

Expand Down
2 changes: 2 additions & 0 deletions metric/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ rntop_cc_auto_library(
deps = [
"//gui/window",
"//mutex",
"//unit",
"//utils",
],
)
45 changes: 39 additions & 6 deletions metric/metric.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

#include "gui/window/window.h"

#include "unit/unit.h"

#include "utils/utils.h"

namespace runai
{

Expand Down Expand Up @@ -47,10 +51,11 @@ struct Common : gui::View
{
Common() = default; // empty creation

Common(size_t utilization, size_t used_memory, size_t total_memory) :
Common(size_t utilization, double used_memory, double total_memory, Unit unit) :
utilization(utilization),
used_memory(used_memory),
total_memory(total_memory)
total_memory(total_memory),
unit(unit)
{}

void print(gui::Window & window) const override
Expand All @@ -60,7 +65,7 @@ struct Common : gui::View
utilization >= 80 ? ncurses::Color::Green :
ncurses::Color::Cyan;

const auto used_memory_percentage = static_cast<float>(used_memory) / static_cast<float>(total_memory) * 100.f;
const auto used_memory_percentage = used_memory / total_memory * 100.f;

const auto memory_color = Color == false ? ncurses::Color::None :
used_memory_percentage < 50 ? ncurses::Color::Red :
Expand All @@ -69,12 +74,40 @@ struct Common : gui::View

window.print(utilization_color, "GPU utilization: %3d%%", utilization);
window.print(" ");
window.print(memory_color, "Used GPU memory: %5d MiB / %-5d MiB (%.0f%%)", used_memory, total_memory, used_memory_percentage);

const auto symbol = utils::unit::symbol(unit);

if (unit < Unit::GB)
{
window.print(memory_color, "Used GPU memory: %5d %s / %-5d %s (%.0f%%)",
static_cast<size_t>(used_memory), symbol.c_str(),
static_cast<size_t>(total_memory), symbol.c_str(),
used_memory_percentage);
}
else
{
window.print(memory_color, "Used GPU memory: %.2f %s / %-.2f %s (%.0f%%)",
used_memory, symbol.c_str(),
total_memory, symbol.c_str(),
used_memory_percentage);
}
}

Common convert(Unit to)
{
return Common
{
.utilization = utilization,
.used_memory = utils::unit::convert(used_memory, unit, to),
.total_memory = utils::unit::convert(total_memory, unit, to),
.unit = to,
};
}

size_t utilization = {};
size_t used_memory = {};
size_t total_memory = {};
double used_memory = {};
double total_memory = {};
Unit unit;
};

} // namespace metric
Expand Down
15 changes: 8 additions & 7 deletions node/node.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "node/node.h"

#include <string>
#include <utility>

#include "utils/utils.h"
Expand Down Expand Up @@ -62,8 +63,9 @@ void Node::refresh()
metrics.push_back(
{
.utilization = std::stoull(row.at(0)),
.used_memory = std::stoull(row.at(1)),
.total_memory = std::stoull(row.at(2)),
.used_memory = std::stod(row.at(1)),
.total_memory = std::stod(row.at(2)),
.unit = Unit::MiB,
});
}

Expand All @@ -76,13 +78,12 @@ void Node::refresh()

// calculate and store node metric

using Op = utils::Op<size_t, Device::Metric>;

_metric.store(
{
.utilization = utils::avg(metrics, (Op)[](const auto & metric){ return metric.utilization; }),
.used_memory = utils::sum(metrics, (Op)[](const auto & metric){ return metric.used_memory; }),
.total_memory = utils::sum(metrics, (Op)[](const auto & metric){ return metric.total_memory; }),
.utilization = utils::avg(metrics, (utils::Op<size_t, Device::Metric>)[](const auto & metric){ return metric.utilization; }),
.used_memory = utils::sum(metrics, (utils::Op<double, Device::Metric>)[](const auto & metric){ return metric.used_memory; }),
.total_memory = utils::sum(metrics, (utils::Op<double, Device::Metric>)[](const auto & metric){ return metric.total_memory; }),
.unit = Unit::MiB,
});
}

Expand Down
3 changes: 3 additions & 0 deletions unit/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
load("//:rules.bzl", "rntop_cc_auto_library")

rntop_cc_auto_library(name = "unit")
14 changes: 14 additions & 0 deletions unit/unit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

namespace runai
{

enum class Unit
{
MB,
MiB,
GB,
GiB,
};

} // namespace runai
5 changes: 4 additions & 1 deletion utils/BUILD
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
load("//:rules.bzl", "rntop_cc_auto_library")

rntop_cc_auto_library(name = "utils")
rntop_cc_auto_library(
name = "utils",
deps = ["//unit"],
)
58 changes: 56 additions & 2 deletions utils/utils.cc
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#include "utils/utils.h"

#include <iostream>
#include <sstream>
#include <utility>

namespace runai::utils::string
namespace runai::utils
{

namespace string
{

std::string join(const std::vector<std::string> & elements, char delimiter)
Expand Down Expand Up @@ -54,4 +58,54 @@ std::string strip(std::string && str, const std::set<char> & chars)
return std::move(str);
}

} // namespace runai::utils::string
} // namespace string

namespace unit
{

std::string symbol(Unit unit)
{
if (unit == Unit::MB) { return "MB"; }
else if (unit == Unit::MiB) { return "MiB"; }
else if (unit == Unit::GB) { return "GB"; }
else if (unit == Unit::GiB) { return "GiB"; }

std::cerr << "Invalid unit type (" << static_cast<int>(unit) << ")" << std::endl;
throw std::exception();
}

double convert(double x, Unit from, Unit to)
{
if (from == to)
{
return x;
}

return bytes_to(to_bytes(x, from), to);
}

size_t to_bytes(double x, Unit from)
{
if (from == Unit::MB) { return x * 1000000ull; }
else if (from == Unit::MiB) { return x * 1048576ull; }
else if (from == Unit::GB) { return x * 1000000000ull; }
else if (from == Unit::GiB) { return x * 1073741824ull; }

std::cerr << "Cannot convert " << symbol(from) << " to bytes" << std::endl;
throw std::exception();
}

double bytes_to(size_t x, Unit to)
{
if (to == Unit::MB) { return static_cast<double>(x) / 1000000ull; }
else if (to == Unit::MiB) { return static_cast<double>(x) / 1048576ull; }
else if (to == Unit::GB) { return static_cast<double>(x) / 1000000000ull; }
else if (to == Unit::GiB) { return static_cast<double>(x) / 1073741824ull; }

std::cerr << "Cannot convert bytes to " << symbol(to) << std::endl;
throw std::exception();
}

} // namespace unit

} // namespace runai::utils
12 changes: 12 additions & 0 deletions utils/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <string>
#include <vector>

#include "unit/unit.h"

namespace runai::utils
{

Expand All @@ -18,6 +20,16 @@ std::string strip(std::string && str, const std::set<char> & chars = { ' ', '\r'

} // namespace string

namespace unit
{

std::string symbol(Unit unit);
double convert(double x, Unit from, Unit to);
size_t to_bytes(double x, Unit from);
double bytes_to(size_t x, Unit to);

} // namespace unit

template <typename R, typename T>
using Op = std::function<R(const T &)>;

Expand Down

0 comments on commit 84f8bcb

Please sign in to comment.