Skip to content

Commit 9c70ca7

Browse files
committed
[ESI][Runtime] Add JSON output for esiquery telemetry
1 parent 8691798 commit 9c70ca7

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

lib/Dialect/ESI/runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ add_executable(esiquery
244244
target_link_libraries(esiquery PRIVATE
245245
ESICppRuntime
246246
CLI11::CLI11
247+
nlohmann_json::nlohmann_json
247248
)
248249
add_dependencies(ESIRuntime esiquery)
249250
install(TARGETS esiquery

lib/Dialect/ESI/runtime/cpp/tools/esiquery.cpp

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@
2222
#include <iostream>
2323
#include <map>
2424
#include <stdexcept>
25+
#include <string>
26+
#include <nlohmann/json.hpp>
2527

2628
using namespace esi;
2729

2830
void printInfo(std::ostream &os, AcceleratorConnection &acc, bool details);
2931
void printHier(std::ostream &os, AcceleratorConnection &acc, bool details);
3032
void printTelemetry(std::ostream &os, AcceleratorConnection &acc);
33+
void printTelemetryJson(std::ostream &os, AcceleratorConnection &acc);
3134

3235
int main(int argc, const char *argv[]) {
3336
CliParser cli("esiquery");
@@ -44,8 +47,11 @@ int main(int argc, const char *argv[]) {
4447
CLI::App *hierSub = cli.add_subcommand("hier", "Print ESI system hierarchy");
4548
hierSub->add_flag("--details", hierDetails,
4649
"Print detailed information about the system");
47-
CLI::App *telemetrySub =
50+
bool telemetryJson = false;
51+
CLI::App *telemetrySub =
4852
cli.add_subcommand("telemetry", "Print ESI system telemetry information");
53+
telemetrySub->add_flag("--json", telemetryJson,
54+
"Dump telemetry information as JSON");
4955

5056
if (int rc = cli.esiParse(argc, argv))
5157
return rc;
@@ -63,8 +69,12 @@ int main(int argc, const char *argv[]) {
6369
printInfo(std::cout, *acc, infoDetails);
6470
else if (*hierSub)
6571
printHier(std::cout, *acc, hierDetails);
66-
else if (*telemetrySub)
67-
printTelemetry(std::cout, *acc);
72+
else if (*telemetrySub) {
73+
if (telemetryJson)
74+
printTelemetryJson(std::cout, *acc);
75+
else
76+
printTelemetry(std::cout, *acc);
77+
}
6878
return 0;
6979
} catch (std::exception &e) {
7080
ctxt.getLogger().error("esiquery", e.what());
@@ -159,6 +169,74 @@ void printHier(std::ostream &os, AcceleratorConnection &acc, bool details) {
159169
printInstance(os, design, /*indent=*/"", details);
160170
}
161171

172+
static void insertTelemetryValue(nlohmann::json &root, const AppIDPath &path,
173+
uint64_t value) {
174+
if (path.empty()) {
175+
root["__value"] = value;
176+
return;
177+
}
178+
179+
nlohmann::json *current = &root;
180+
for (size_t i = 0; i < path.size(); ++i) {
181+
const std::string key = path[i].toString();
182+
nlohmann::json &next = (*current)[key];
183+
if (i == path.size() - 1) {
184+
if (next.is_object())
185+
next["__value"] = value;
186+
else
187+
next = value;
188+
} else {
189+
if (!next.is_object()) {
190+
nlohmann::json previous = next;
191+
next = nlohmann::json::object();
192+
if (!previous.is_null())
193+
next["__value"] = previous;
194+
}
195+
current = &next;
196+
}
197+
}
198+
}
199+
200+
static void collapseTelemetryJson(nlohmann::json &node) {
201+
if (!node.is_object())
202+
return;
203+
204+
for (auto it = node.begin(); it != node.end(); ++it)
205+
collapseTelemetryJson(it.value());
206+
207+
if (node.size() == 1 && node.contains("__value")) {
208+
nlohmann::json value = node["__value"];
209+
node = value;
210+
}
211+
}
212+
213+
void printTelemetryJson(std::ostream &os, AcceleratorConnection &acc) {
214+
Manifest manifest(acc.getCtxt(),
215+
acc.getService<services::SysInfo>()->getJsonManifest());
216+
auto accel = manifest.buildAccelerator(acc);
217+
acc.getServiceThread()->addPoll(*accel);
218+
219+
auto *telemetry = acc.getService<services::TelemetryService>();
220+
if (!telemetry) {
221+
os << nlohmann::json{{"error", "No telemetry service found"}}.dump(2)
222+
<< std::endl;
223+
return;
224+
}
225+
226+
const std::map<AppIDPath, services::TelemetryService::Metric *>
227+
&telemetryPorts = telemetry->getTelemetryPorts();
228+
229+
nlohmann::json root = nlohmann::json::object();
230+
for (const auto &[id, port] : telemetryPorts) {
231+
port->connect();
232+
uint64_t value = *port->read().get().as<uint64_t>();
233+
insertTelemetryValue(root, id, value);
234+
}
235+
236+
collapseTelemetryJson(root);
237+
os << root.dump(2) << std::endl;
238+
}
239+
162240
void printTelemetry(std::ostream &os, AcceleratorConnection &acc) {
163241
Manifest manifest(acc.getCtxt(),
164242
acc.getService<services::SysInfo>()->getJsonManifest());

0 commit comments

Comments
 (0)