Re-use profiler visualization for extra networks

This commit is contained in:
catboxanon 2024-03-04 18:33:22 -05:00
parent eee46a5094
commit 801461eea2
3 changed files with 177 additions and 92 deletions

View File

@ -78,6 +78,8 @@ module.exports = {
//extraNetworks.js //extraNetworks.js
requestGet: "readonly", requestGet: "readonly",
popup: "readonly", popup: "readonly",
// profilerVisualization.js
createVisualizationTable: "readonly",
// from python // from python
localization: "readonly", localization: "readonly",
// progrssbar.js // progrssbar.js

View File

@ -528,12 +528,74 @@ function popupId(id) {
popup(storedPopupIds[id]); popup(storedPopupIds[id]);
} }
function extraNetworksFlattenMetadata(obj) {
const result = {};
// Convert any stringified JSON objects to actual objects
for (const key of Object.keys(obj)) {
if (typeof obj[key] === 'string') {
try {
const parsed = JSON.parse(obj[key]);
if (parsed && typeof parsed === 'object') {
obj[key] = parsed;
}
} catch (error) {
continue;
}
}
}
// Flatten the object
for (const key of Object.keys(obj)) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
const nested = extraNetworksFlattenMetadata(obj[key]);
for (const nestedKey of Object.keys(nested)) {
result[`${key}/${nestedKey}`] = nested[nestedKey];
}
} else {
result[key] = obj[key];
}
}
// Special case for handling modelspec keys
for (const key of Object.keys(result)) {
if (key.startsWith("modelspec.")) {
result[key.replaceAll(".", "/")] = result[key];
delete result[key];
}
}
// Add empty keys to designate hierarchy
for (const key of Object.keys(result)) {
const parts = key.split("/");
for (let i = 1; i < parts.length; i++) {
const parent = parts.slice(0, i).join("/");
if (!result[parent]) {
result[parent] = "";
}
}
}
return result;
}
function extraNetworksShowMetadata(text) { function extraNetworksShowMetadata(text) {
try {
let parsed = JSON.parse(text);
if (parsed && typeof parsed === 'object') {
parsed = extraNetworksFlattenMetadata(parsed);
const table = createVisualizationTable(parsed, 0);
popup(table);
return;
}
} catch (error) { console.debug(error); }
var elem = document.createElement('pre'); var elem = document.createElement('pre');
elem.classList.add('popup-metadata'); elem.classList.add('popup-metadata');
elem.textContent = text; elem.textContent = text;
popup(elem); popup(elem);
return;
} }
function requestGet(url, data, handler, errorHandler) { function requestGet(url, data, handler, errorHandler) {

View File

@ -33,23 +33,33 @@ function createRow(table, cellName, items) {
return res; return res;
} }
function showProfile(path, cutoff = 0.05) { function createVisualizationTable(data, cutoff = 0, sort = "") {
requestGet(path, {}, function(data) {
var table = document.createElement('table'); var table = document.createElement('table');
table.className = 'popup-table'; table.className = 'popup-table';
data.records['total'] = data.total; var keys = Object.keys(data);
var keys = Object.keys(data.records).sort(function(a, b) { if (sort === "number") {
return data.records[b] - data.records[a]; keys = keys.sort(function(a, b) {
return data[b] - data[a];
}); });
} else {
keys = keys.sort();
}
var items = keys.map(function(x) { var items = keys.map(function(x) {
return {key: x, parts: x.split('/'), time: data.records[x]}; return {key: x, parts: x.split('/'), value: data[x]};
}); });
var maxLength = items.reduce(function(a, b) { var maxLength = items.reduce(function(a, b) {
return Math.max(a, b.parts.length); return Math.max(a, b.parts.length);
}, 0); }, 0);
var cols = createRow(table, 'th', ['record', 'seconds']); var cols = createRow(
table,
'th',
[
cutoff === 0 ? 'key' : 'record',
cutoff === 0 ? 'value' : 'seconds'
]
);
cols[0].colSpan = maxLength; cols[0].colSpan = maxLength;
function arraysEqual(a, b) { function arraysEqual(a, b) {
@ -60,21 +70,25 @@ function showProfile(path, cutoff = 0.05) {
var matching = items.filter(function(x) { var matching = items.filter(function(x) {
return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent); return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent);
}); });
var sorted = matching.sort(function(a, b) { if (sort === "number") {
return b.time - a.time; matching = matching.sort(function(a, b) {
return b.value - a.value;
}); });
} else {
matching = matching.sort();
}
var othersTime = 0; var othersTime = 0;
var othersList = []; var othersList = [];
var othersRows = []; var othersRows = [];
var childrenRows = []; var childrenRows = [];
sorted.forEach(function(x) { matching.forEach(function(x) {
var visible = x.time >= cutoff && !hide; var visible = (cutoff === 0 && !hide) || (x.value >= cutoff && !hide);
var cells = []; var cells = [];
for (var i = 0; i < maxLength; i++) { for (var i = 0; i < maxLength; i++) {
cells.push(x.parts[i]); cells.push(x.parts[i]);
} }
cells.push(x.time.toFixed(3)); cells.push(cutoff === 0 ? x.value : x.value.toFixed(3));
var cols = createRow(table, 'td', cells); var cols = createRow(table, 'td', cells);
for (i = 0; i < level; i++) { for (i = 0; i < level; i++) {
cols[i].className = 'muted'; cols[i].className = 'muted';
@ -85,10 +99,10 @@ function showProfile(path, cutoff = 0.05) {
tr.classList.add("hidden"); tr.classList.add("hidden");
} }
if (x.time >= cutoff) { if (cutoff === 0 || x.value >= cutoff) {
childrenRows.push(tr); childrenRows.push(tr);
} else { } else {
othersTime += x.time; othersTime += x.value;
othersList.push(x.parts[level]); othersList.push(x.parts[level]);
othersRows.push(tr); othersRows.push(tr);
} }
@ -147,6 +161,13 @@ function showProfile(path, cutoff = 0.05) {
addLevel(0, []); addLevel(0, []);
return table;
}
function showProfile(path, cutoff = 0.05) {
requestGet(path, {}, function(data) {
data.records['total'] = data.total;
const table = createVisualizationTable(data.records, cutoff, "number");
popup(table); popup(table);
}); });
} }