215 std::vector<MetricIndex>& visibleMetricsIndex,
216 std::vector<MetricDisplayState>& metricDisplayStates,
219 static bool locked =
false;
220 ImGui::Checkbox(
"Lock scrolling", &locked);
221 ImGui::BeginTable(
"##sparks table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY, ImVec2{-1, -1});
222 ImGui::TableSetupColumn(
"##close button", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed, 25);
223 ImGui::TableSetupColumn(
"##plot name", ImGuiTableColumnFlags_WidthFixed, 200);
224 ImGui::TableSetupColumn(
"##plot", ImGuiTableColumnFlags_WidthFixed, 0);
225 ImGui::TableSetupScrollFreeze(2, 0);
226 for (
size_t i = 0;
i < visibleMetricsIndex.size(); ++
i) {
227 auto&
index = visibleMetricsIndex[
i];
228 auto& metricsInfos = metricStore.
metrics[
index.storeIndex];
229 auto& metricsInfo = metricsInfos[
index.deviceIndex];
230 auto& metric = metricsInfo.metrics[
index.metricIndex];
231 auto&
state = metricDisplayStates[
index.stateIndex];
233 ImGui::TableNextColumn();
234 ImGui::PushID(
index.stateIndex);
235 state.visible = !ImGui::Button(
"-");
237 ImGui::TableNextColumn();
238 ImGui::TextUnformatted(
state.legend.c_str());
239 ImGui::TableNextColumn();
240 static ImPlotAxisFlags rtx_axis = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickMarks;
241 static ImPlotAxisFlags rty_axis = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickMarks;
242 ImGui::PushID(
index.stateIndex);
246 data.size = metric.filledMetrics;
250 ImPlot::SetNextAxisLimits(ImAxis_X1, (startTime + ImGui::GetTime() - 100) * 1000, (startTime + ImGui::GetTime()) * 1000, ImGuiCond_Always);
251 ImPlot::SetNextAxisLimits(ImAxis_Y1, metricsInfo.min[
index.metricIndex], metricsInfo.max[
index.metricIndex] * 1.1, ImGuiCond_Always);
252 rty_axis |= ImPlotAxisFlags_LockMin;
254 if (ImPlot::BeginPlot(
"##sparks", ImVec2(700, 100), 0)) {
255 ImPlot::SetupAxes(
"time",
"value", rtx_axis, rty_axis);
256 ImPlot::SetAxis(
state.axis);
257 switch (metric.type) {
258 case MetricType::Enum: {
259 data.points = (
void*)metricsInfo.enumMetrics[metric.storeIdx].data();
260 data.time = metricsInfo.enumTimestamps[metric.storeIdx].data();
262 auto getter = [](
int idx,
void* hData) -> ImPlotPoint {
263 auto histoData =
reinterpret_cast<HistoData*
>(hData);
264 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
266 return ImPlotPoint(histoData->time[
pos], ((int8_t*)(histoData->points))[
pos]);
268 ImPlot::PlotLineG(
"##plot", getter, &
data,
data.mod);
270 case MetricType::Int: {
271 data.points = (
void*)metricsInfo.intMetrics[metric.storeIdx].data();
272 data.time = metricsInfo.intTimestamps[metric.storeIdx].data();
274 auto getter = [](
int idx,
void* hData) -> ImPlotPoint {
275 auto histoData =
reinterpret_cast<HistoData*
>(hData);
276 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
278 return ImPlotPoint(histoData->time[
pos], ((
int*)(histoData->points))[
pos]);
280 ImPlot::PlotLineG(
"##plot", getter, &
data,
data.mod);
282 case MetricType::Uint64: {
283 data.points = (
void*)metricsInfo.uint64Metrics[metric.storeIdx].data();
284 data.time = metricsInfo.uint64Timestamps[metric.storeIdx].data();
286 auto getter = [](
int idx,
void* hData) -> ImPlotPoint {
287 auto histoData =
reinterpret_cast<HistoData*
>(hData);
288 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
290 return ImPlotPoint(histoData->time[
pos], ((uint64_t*)histoData->points)[
pos]);
292 ImPlot::PlotLineG(
"##plot", getter, &
data,
data.mod, 0);
294 case MetricType::Float: {
295 data.points = (
void*)metricsInfo.floatMetrics[metric.storeIdx].data();
296 data.time = metricsInfo.floatTimestamps[metric.storeIdx].data();
298 auto getter = [](
int idx,
void* hData) -> ImPlotPoint {
299 auto histoData =
reinterpret_cast<HistoData*
>(hData);
300 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
302 return ImPlotPoint(histoData->time[
pos], ((
float*)histoData->points)[
pos]);
304 ImPlot::PlotLineG(
"##plot", getter, &
data,
data.mod, 0);
354 std::vector<MetricDisplayState>& state,
356 DriverInfo
const& driverInfo)
358 std::vector<void*> metricsToDisplay;
359 std::vector<const char*> deviceNames;
360 std::vector<MultiplotData> userData;
363 assert(metricsStore.metrics[si].size() == metricStore.
specs[si].size());
366 float maxValue[3] = {std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest()};
367 float minValue[3] = {0, 0, 0};
368 size_t maxDomain = std::numeric_limits<size_t>::lowest();
369 size_t minDomain = std::numeric_limits<size_t>::max();
372 ImPlotAxisFlags axisFlags = 0;
375 gsl::span<DeviceMetricsInfo const> metricsInfos = metricStore.
metrics[si];
376 gsl::span<TopologyNodeInfo const> specs = metricStore.
specs[si];
377 for (
int di = 0;
di < metricsInfos.size(); ++
di) {
378 for (
size_t mi = 0; mi < metricsInfos[
di].metrics.size(); ++mi) {
379 if (
state[gmi].visible ==
false) {
383 auto& metric = metricsInfos[
di].metrics[mi];
384 deviceNames.push_back(specs[
di].
label.c_str());
388 data.type = metric.type;
390 minValue[
data.axis] = std::min(minValue[
data.axis], metricsInfos[
di].min[mi]);
391 maxValue[
data.axis] = std::max(maxValue[
data.axis], metricsInfos[
di].max[mi]);
392 minDomain = std::min(minDomain, metricsInfos[
di].minDomain[mi]);
393 maxDomain = std::max(maxDomain, metricsInfos[
di].maxDomain[mi]);
394 axisFlags |=
data.axis == 1 ? (ImPlotFlags_)ImPlotFlags_YAxis2 : ImPlotFlags_None;
395 axisFlags |=
data.axis == 2 ? (ImPlotFlags_)ImPlotFlags_YAxis3 : ImPlotFlags_None;
396 switch (metric.type) {
397 case MetricType::Int: {
398 data.Y = metricsInfos[
di].intMetrics[metric.storeIdx].data();
399 auto& timestamps = metricsInfos[
di].intTimestamps[metric.storeIdx];
400 data.mod = std::min(metric.filledMetrics, timestamps.size());
402 data.X = timestamps.data();
404 case MetricType::Enum: {
405 data.Y = metricsInfos[
di].enumMetrics[metric.storeIdx].data();
406 auto& timestamps = metricsInfos[
di].enumTimestamps[metric.storeIdx];
407 data.mod = std::min(metric.filledMetrics, timestamps.size());
409 data.X = timestamps.data();
411 case MetricType::Uint64: {
412 data.Y = metricsInfos[
di].uint64Metrics[metric.storeIdx].data();
413 auto& timestamps = metricsInfos[
di].uint64Timestamps[metric.storeIdx];
414 data.mod = std::min(metric.filledMetrics, timestamps.size());
416 data.X = timestamps.data();
418 case MetricType::Float: {
419 data.Y = metricsInfos[
di].floatMetrics[metric.storeIdx].data();
420 auto& timestamps = metricsInfos[
di].floatTimestamps[metric.storeIdx];
421 data.mod = std::min(metric.filledMetrics, timestamps.size());
423 data.X = timestamps.data();
425 case MetricType::Unknown:
426 case MetricType::String: {
428 data.type = MetricType::String;
432 userData.emplace_back(
data);
438 maxDomain = std::max(minDomain + 1024, maxDomain);
439 for (
size_t ai = 0; ai < 3; ++ai) {
440 maxValue[ai] = std::max(minValue[ai] + 1.f, maxValue[ai]);
444 if (userData.empty()) {
447 for (
size_t ui = 0; ui < userData.size(); ++ui) {
448 metricsToDisplay.push_back(&(userData[ui]));
451 auto getterXY = [](
int idx,
void* hData) -> ImPlotPoint {
452 auto histoData =
reinterpret_cast<const MultiplotData*
>(hData);
453 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
454 double x =
static_cast<const size_t*
>(histoData->X)[
pos];
456 if (histoData->type == MetricType::Int) {
457 y =
static_cast<const int*
>(histoData->Y)[
pos];
458 }
else if (histoData->type == MetricType::Uint64) {
459 y =
static_cast<const uint64_t*
>(histoData->Y)[
pos];
460 }
else if (histoData->type == MetricType::Float) {
461 y =
static_cast<const float*
>(histoData->Y)[
pos];
462 }
else if (histoData->type == MetricType::Enum) {
463 y =
static_cast<const int8_t*
>(histoData->Y)[
pos];
465 auto point = ImPlotPoint{
x,
y};
468 static bool logScale =
false;
469 ImGui::Checkbox(
"Log scale", &logScale);
471 ImPlot::SetNextAxisLimits(ImAxis_X1, minDomain, maxDomain, ImGuiCond_Once);
473 auto axisPadding = 0.;
474 if (displayType == MetricsDisplayStyle::Lines) {
478 ImPlot::SetNextAxisLimits(ImAxis_Y1, minValue[0] - (maxValue[0] - minValue[0]) * axisPadding,
479 maxValue[0] * (1. + axisPadding), ImGuiCond_Always);
480 ImPlot::SetNextAxisLimits(ImAxis_Y2, minValue[1] - (maxValue[1] - minValue[1]) * axisPadding,
481 maxValue[1] * (1. + axisPadding), ImGuiCond_Always);
482 ImPlot::SetNextAxisLimits(ImAxis_Y3, minValue[2] - (maxValue[2] - minValue[2]) * axisPadding,
483 maxValue[2] * (1. + axisPadding), ImGuiCond_Always);
485 switch (displayType) {
486 case MetricsDisplayStyle::Histos:
487 if (ImPlot::BeginPlot(
"##Some plot")) {
488 ImPlot::SetupAxes(
"time",
"value");
489 ImPlot::SetupAxisFormat(ImAxis_Y1,
formatSI,
nullptr);
490 ImPlot::SetupAxisFormat(ImAxis_Y2,
formatSI,
nullptr);
491 ImPlot::SetupAxisFormat(ImAxis_Y3,
formatSI,
nullptr);
492 ImPlot::SetupAxisFormat(ImAxis_X1,
formatTimeSinceStart, (
void*)&driverInfo.startTimeMsFromEpoch);
493 for (
size_t pi = 0; pi < metricsToDisplay.size(); ++pi) {
497 ImPlot::PlotBarsG(
label, getterXY, metricsToDisplay[pi],
data->mod, 1, 0);
504 case MetricsDisplayStyle::Lines: {
505 auto xAxisFlags = ImPlotAxisFlags_None;
506 auto yAxisFlags = ImPlotAxisFlags_LockMin;
508 if (ImPlot::BeginPlot(
"##Some plot", {-1, -1}, axisFlags)) {
509 ImPlot::SetupAxes(
"time",
"value", xAxisFlags, yAxisFlags);
510 ImPlot::SetupAxisFormat(ImAxis_Y1,
formatSI,
nullptr);
511 ImPlot::SetupAxisFormat(ImAxis_Y2,
formatSI,
nullptr);
512 ImPlot::SetupAxisFormat(ImAxis_Y3,
formatSI,
nullptr);
513 ImPlot::SetupAxisFormat(ImAxis_X1,
formatTimeSinceStart, (
void*)&driverInfo.startTimeMsFromEpoch);
514 for (
size_t pi = 0; pi < metricsToDisplay.size(); ++pi) {
517 ImPlot::SetAxis(
data->axis);
518 ImPlot::PlotLineG(
data->legend, getterXY, metricsToDisplay[pi],
data->mod, 0);
524 case MetricsDisplayStyle::Stems:
525 if (ImPlot::BeginPlot(
"##Some plot")) {
526 ImPlot::SetupAxes(
"time",
"value");
527 for (
size_t pi = 0; pi < userData.size(); ++pi) {
530 if (
data->type == MetricType::Uint64) {
532 ImPlot::PlotScatterG(((
MultiplotData*)metricsToDisplay[pi])->legend, getterXY, metricsToDisplay[pi],
data->mod, 0);
622 DriverInfo
const& driverInfo,
623 std::vector<DeviceInfo>
const& infos,
624 std::vector<DataProcessorInfo>
const& metadata,
625 std::vector<DeviceControl>& controls,
628 if (
state.bottomPaneVisible ==
false) {
631 auto metricDisplayPos = 0;
632 static bool metricSelectorVisible =
true;
633 static std::vector<MetricDisplayState> metricDisplayState;
638 constexpr size_t MAX_QUERY_SIZE = 256;
639 static char query[MAX_QUERY_SIZE];
640 static char lastSelectedQuery[MAX_QUERY_SIZE];
642 size_t totalMetrics = 0;
643 for (
auto& metricsInfos : metricsStore.
metrics) {
644 for (
auto& metricInfo : metricsInfos) {
645 totalMetrics += metricInfo.metrics.size();
649 if (totalMetrics != metricDisplayState.size() || strcmp(lastSelectedQuery, query)) {
651 std::vector<MetricDisplayState> newMetricDisplayStates;
652 newMetricDisplayStates.resize(totalMetrics);
653 static std::vector<int> order;
654 order.resize(metricDisplayState.size());
655 std::iota(order.begin(), order.end(), 0);
656 std::sort(order.begin(), order.end(), [](
int a,
int b) {
657 return metricDisplayState[a].legend < metricDisplayState[b].legend;
661 auto& metricsInfos = metricsStore.
metrics[si];
662 auto& specs = metricsStore.
specs[si];
663 for (
size_t di = 0;
di < metricsInfos.size(); ++
di) {
664 auto& metricInfo = metricsInfos[
di];
665 auto& spec = specs[
di];
666 for (
size_t li = 0; li != metricInfo.metricLabels.size(); ++li) {
667 char const* metricLabel = metricInfo.metricLabels[li].label;
669 auto low = std::lower_bound(order.begin(), order.end(), spec.label, [](
int a, std::string
const&
b) {
670 return metricDisplayState[a].legend < b;
672 auto up = std::upper_bound(low, order.end(), spec.label, [](std::string
const&
a,
int b) {
673 return a < metricDisplayState[b].legend;
675 std::string legend = fmt::format(
"{}/{}", spec.label, metricLabel);
676 auto old = std::lower_bound(low, up, legend, [](
int a, std::string
const&
b) {
677 return metricDisplayState[
a].legend <
b;
679 if (old != order.end() && metricDisplayState[*old].legend == legend) {
680 newMetricDisplayStates[gmi].visible = metricDisplayState[*old].visible;
681 newMetricDisplayStates[gmi].axis = metricDisplayState[*old].axis;
683 newMetricDisplayStates[gmi].visible =
false;
686 newMetricDisplayStates[gmi].selected =
hasAll(metricLabel, query);
687 newMetricDisplayStates[gmi].legend = legend;
692 metricDisplayState.swap(newMetricDisplayStates);
693 strcpy(lastSelectedQuery, query);
696 static std::vector<MetricIndex> selectedMetricIndex;
698 if (metricSelectorVisible) {
699 selectedMetricIndex.clear();
702 auto& metricsInfos = metricsStore.
metrics[si];
704 for (
size_t di = 0;
di < metricsInfos.size(); ++
di) {
705 auto& metricInfo = metricsInfos[
di];
706 for (
size_t li = 0; li != metricInfo.metricLabels.size(); ++li) {
707 auto&
state = metricDisplayState[gmi];
708 if (
state.selected) {
709 selectedMetricIndex.emplace_back(
MetricIndex{si,
di, li, gmi});
716 metricDisplayPos = ImGui::GetIO().DisplaySize.x / 4;
717 ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y -
state.bottomPaneSize), 0);
718 ImGui::SetNextWindowSize(ImVec2(metricDisplayPos,
state.bottomPaneSize), 0);
719 ImGui::Begin(
"Available metrics",
nullptr, ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
721 ImGui::Text(ICON_FA_FILTER);
723 ImGui::InputText(
"##query-metrics", query, MAX_QUERY_SIZE);
724 size_t metricSize = 0;
725 for (
auto deviceMetrics : metricsStore.
metrics) {
726 metricSize += DeviceMetricsInfoHelpers::metricsStorageSize(deviceMetrics);
729 ImGui::Text(
"%zu/%zu matching", selectedMetricIndex.size(), totalMetrics);
731 static const char* possibleAxis[] = {
736 if (ImGui::BeginTable(
"##metrics-table", 3, ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY, ImVec2{-1, -1})) {
737 ImGui::TableSetupColumn(
"##close button", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed, 20);
738 ImGui::TableSetupColumn(
"##axis kind", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed, 30);
739 ImGui::TableSetupScrollFreeze(1, 0);
740 ImGuiListClipper clipper;
741 clipper.Begin(selectedMetricIndex.size());
742 while (clipper.Step()) {
743 for (
size_t i = clipper.DisplayStart;
i < clipper.DisplayEnd; ++
i) {
744 auto&
index = selectedMetricIndex[
i];
745 auto& metricsInfos = metricsStore.
metrics[
index.storeIndex];
747 auto& metricInfo = metricsInfos[
index.deviceIndex];
749 auto&
label = metricInfo.metricLabels[
index.metricIndex];
750 ImGui::PushID(
index.stateIndex);
751 ImGui::TableNextRow();
752 ImGui::TableNextColumn();
753 ImGui::Checkbox(
"##checkbox", &metricDisplayState[
index.stateIndex].visible);
754 ImGui::TableNextColumn();
755 if (metricDisplayState[
index.stateIndex].visible) {
756 if (ImGui::BeginCombo(
"##Select style", possibleAxis[metricDisplayState[
index.stateIndex].axis], ImGuiComboFlags_NoArrowButton)) {
757 for (
int n = 0;
n < IM_ARRAYSIZE(possibleAxis);
n++) {
758 bool is_selected = (metricDisplayState[
index.stateIndex].axis ==
n);
759 if (ImGui::Selectable(possibleAxis[
n], is_selected)) {
760 metricDisplayState[
index.stateIndex].axis =
n;
763 ImGui::SetItemDefaultFocus();
769 ImGui::TableNextColumn();
770 ImGui::Text(
"%s/%s", node.label.c_str(),
label.label);
778 ImGui::SetNextWindowPos(ImVec2(metricDisplayPos, ImGui::GetIO().DisplaySize.y -
state.bottomPaneSize), 0);
779 ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x - metricDisplayPos,
state.bottomPaneSize), 0);
781 ImGui::Begin(
"Devices",
nullptr, ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
783 if (!metricSelectorVisible) {
784 metricSelectorVisible = ImGui::Button(ICON_FA_CHEVRON_RIGHT
"Show metric selector");
786 metricSelectorVisible = !ImGui::Button(ICON_FA_CHEVRON_LEFT
"Hide metric selector");
788 static char const* plotStyles[] = {
796 static char const* currentStyleStr = plotStyles[0];
797 ImGui::TextUnformatted(
"Metric display style:");
799 ImGui::PushItemWidth(100);
800 if (ImGui::BeginCombo(
"##Select style", currentStyleStr)) {
801 for (
int n = 0;
n < IM_ARRAYSIZE(plotStyles);
n++) {
802 bool is_selected = (currentStyleStr == plotStyles[
n]);
803 if (ImGui::Selectable(plotStyles[
n], is_selected)) {
804 currentStyleStr = plotStyles[
n];
808 ImGui::SetItemDefaultFocus();
813 ImGui::PopItemWidth();
816 int visibleMetrics = 0;
817 static std::vector<int> visibleDevicesIndex;
818 static std::vector<MetricIndex> visibleMetricsIndex;
820 visibleDevicesIndex.reserve(totalMetrics);
821 visibleDevicesIndex.clear();
822 visibleMetricsIndex.clear();
825 auto& metricsInfos = metricsStore.
metrics[si];
826 for (
size_t di = 0;
di < metricsInfos.size(); ++
di) {
827 auto& metricInfo = metricsInfos[
di];
828 bool deviceVisible =
false;
829 for (
size_t mi = 0; mi < metricInfo.metrics.size(); ++mi) {
830 auto&
state = metricDisplayState[gmi];
832 deviceVisible =
true;
834 auto& metric = metricInfo.metrics[mi];
835 size_t const* timestamps =
nullptr;
836 switch (metric.type) {
837 case MetricType::Int:
838 timestamps = metricInfo.intTimestamps[metric.storeIdx].data();
840 case MetricType::Float:
841 timestamps = metricInfo.floatTimestamps[metric.storeIdx].data();
843 case MetricType::String:
844 timestamps = metricInfo.stringTimestamps[metric.storeIdx].data();
846 case MetricType::Uint64:
847 timestamps = metricInfo.uint64Timestamps[metric.storeIdx].data();
849 case MetricType::Enum:
850 timestamps = metricInfo.enumTimestamps[metric.storeIdx].data();
853 throw std::runtime_error(
"Unknown metric type");
858 size_t curMinTime = timestamps[minRangePos];
859 if (curMinTime == 0) {
862 minTime = minTime < curMinTime ? minTime : curMinTime;
863 if (minTime != 0 && minTime != -1) {
868 size_t curMaxTime = timestamps[maxRangePos];
869 maxTime = std::max(maxTime, curMaxTime);
875 visibleDevicesIndex.push_back(
di);
879 if (visibleMetricsIndex.empty()) {
885 switch (currentStyle) {
886 case MetricsDisplayStyle::Stems:
887 case MetricsDisplayStyle::Histos:
888 case MetricsDisplayStyle::Lines: {
890 minTime, maxTime, 1024,
891 currentStyle, metricDisplayState, metricsStore, driverInfo);
893 case MetricsDisplayStyle::Sparks: {
894 displaySparks(
state.startTime, visibleMetricsIndex, metricDisplayState, metricsStore);
896 case MetricsDisplayStyle::Table: {
897 static std::vector<float> visibleDevicesOffsets;
898 visibleDevicesOffsets.clear();
899 visibleDevicesOffsets.resize(visibleDevicesIndex.size());
901 size_t lastDevice = -1;
902 int visibleDeviceCount = -1;
904 for (
auto index : visibleMetricsIndex) {
905 auto& metricsInfos = metricsStore.
metrics[
index.storeIndex];
906 if (lastDevice !=
index.deviceIndex) {
907 visibleDeviceCount++;
908 lastDevice =
index.deviceIndex;
910 auto label = metricsInfos[
index.deviceIndex].metricLabels[
index.metricIndex].label;
911 visibleDevicesOffsets[visibleDeviceCount] += ImGui::CalcTextSize(
label,
nullptr,
true).x;
914 if (ImGui::BeginTable(
"##metrics-table", visibleMetricsIndex.size() + 1, ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX, ImVec2{-1, -1})) {
915 ImGui::TableSetupColumn(
"##close button", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed, 20);
916 for (
int i = 0;
i < visibleMetricsIndex.size(); ++
i) {
917 ImGui::TableSetupColumn(
"##device-header", ImGuiTableColumnFlags_WidthFixed, 100);
919 ImGui::TableSetupScrollFreeze(1, 2);
920 ImGui::TableNextRow();
921 ImGui::TableNextColumn();
922 ImGui::TextUnformatted(
"");
923 visibleDeviceCount = -1;
925 for (
auto index : visibleMetricsIndex) {
926 ImGui::TableNextColumn();
927 auto& devices = metricsStore.
specs[
index.storeIndex];
928 if (lastDevice ==
index.deviceIndex) {
931 visibleDeviceCount++;
932 lastDevice =
index.deviceIndex;
933 auto& spec = devices[
index.deviceIndex];
935 ImGui::TextUnformatted(spec.label.c_str());
939 ImGui::TableNextRow();
940 ImGui::TableNextColumn();
941 ImGui::TextUnformatted(
"#");
943 for (
auto index : visibleMetricsIndex) {
944 ImGui::TableNextColumn();
945 auto& metricsInfos = metricsStore.
metrics[
index.storeIndex];
946 auto& metric = metricsInfos[
index.deviceIndex];
947 auto label = metricsInfos[
index.deviceIndex].metricLabels[
index.metricIndex].label;
948 ImGui::Text(
"%s (%" PRIu64
")",
label, (uint64_t)metric.metrics[
index.metricIndex].filledMetrics);
952 ImGuiListClipper clipper;
956 while (clipper.Step()) {
957 for (
size_t i = clipper.DisplayStart;
i < clipper.DisplayEnd; ++
i) {
958 ImGui::TableNextRow();
1116 std::vector<DeviceSpec>
const& devices,
1117 std::vector<DataProcessingStates>
const& allStates,
1118 std::vector<DataProcessorInfo>
const& metadata,
1119 std::vector<DeviceMetricsInfo>
const& metricsInfos,
1120 DriverInfo
const& driverInfo,
1121 std::vector<DeviceControl>& controls,
1130 guiState.
devices.resize(infos.size());
1131 for (
size_t i = 0;
i < guiState.
devices.size(); ++
i) {
1144 clock_gettime(CLOCK_REALTIME, &now);
1145 guiState.
startTime = now.tv_sec - ImGui::GetTime();
1146 std::vector<TopologyNodeInfo> deviceNodesInfos;
1147 for (
auto& device : devices) {
1150 std::vector<TopologyNodeInfo> driverNodesInfos;
1153 return [&infos, &devices, &allStates, &metadata, &controls, &metricsInfos, &driverInfo, &driverControl, deviceNodesInfos, driverNodesInfos]() {
1154 ImGuiStyle& style = ImGui::GetStyle();
1155 style.FrameRounding = 0.;
1156 style.WindowRounding = 0.;
1157 style.Colors[ImGuiCol_WindowBg] = ImVec4(0x1b / 255.f, 0x1b / 255.f, 0x1b / 255.f, 1.00f);
1158 style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0x1b / 255.f, 0x1b / 255.f, 0x1b / 255.f, 1.00f);
1168 displayMetrics(guiState, driverInfo, infos, metadata, controls, metricsStore);
1171 int windowPosStepping = (ImGui::GetIO().DisplaySize.y - 500) / guiState.
devices.size();
1173 for (
size_t i = 0;
i < guiState.
devices.size(); ++
i) {
1175 assert(
i < infos.size());
1176 assert(
i < devices.size());
1179 assert(controls.size() == devices.size());
1184 ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x / 3 * 2,
i * windowPosStepping), ImGuiCond_Once);
1185 ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x / 3, ImGui::GetIO().DisplaySize.y - 300),
1192 ImGui::Checkbox(
"Stop logging", &control.
quiet);
1195 control.
logLevel = LogParsingHelpers::LogLevel::Debug;
1197 ImGui::Combo(
"Log level",
reinterpret_cast<int*
>(&control.
logLevel), LogParsingHelpers::LOG_LEVELS,
1198 (
int)LogParsingHelpers::LogLevel::Size, 5);
1201 ImGui::BeginChild(
"ScrollingRegion", ImVec2(0, -ImGui::GetTextLineHeightWithSpacing()),
false,
1202 ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NoMove);