fix: solve inconsistencies with filters, fixes #280

This commit is contained in:
Christoph Kluge 2024-11-27 18:43:56 +01:00
parent 00a578657c
commit f89b5cd2ec
5 changed files with 88 additions and 33 deletions

View File

@ -244,6 +244,16 @@ func buildFilterPresets(query url.Values) map[string]interface{} {
} }
} }
} }
if query.Get("numHWThreads") != "" {
parts := strings.Split(query.Get("numHWThreads"), "-")
if len(parts) == 2 {
a, e1 := strconv.Atoi(parts[0])
b, e2 := strconv.Atoi(parts[1])
if e1 == nil && e2 == nil {
filterPresets["numHWThreads"] = map[string]int{"from": a, "to": b}
}
}
}
if query.Get("numAccelerators") != "" { if query.Get("numAccelerators") != "" {
parts := strings.Split(query.Get("numAccelerators"), "-") parts := strings.Split(query.Get("numAccelerators"), "-")
if len(parts) == 2 { if len(parts) == 2 {
@ -285,7 +295,35 @@ func buildFilterPresets(query url.Values) map[string]interface{} {
} }
} }
} }
if query.Get("energy") != "" {
parts := strings.Split(query.Get("energy"), "-")
if len(parts) == 2 {
a, e1 := strconv.Atoi(parts[0])
b, e2 := strconv.Atoi(parts[1])
if e1 == nil && e2 == nil {
filterPresets["energy"] = map[string]int{"from": a, "to": b}
}
}
}
if len(query["stat"]) != 0 {
statList := make([]map[string]interface{}, 0)
for _, statEntry := range query["stat"] {
parts := strings.Split(statEntry, "-")
if len(parts) == 3 { // Metric Footprint Stat Field, from - to
a, e1 := strconv.ParseInt(parts[1], 10, 64)
b, e2 := strconv.ParseInt(parts[2], 10, 64)
if e1 == nil && e2 == nil {
statEntry := map[string]interface{}{
"field": parts[0],
"from": a,
"to": b,
}
statList = append(statList, statEntry)
}
}
}
filterPresets["stats"] = statList
}
return filterPresets return filterPresets
} }

View File

@ -76,7 +76,7 @@
numHWThreads: filterPresets.numHWThreads || { from: null, to: null }, numHWThreads: filterPresets.numHWThreads || { from: null, to: null },
numAccelerators: filterPresets.numAccelerators || { from: null, to: null }, numAccelerators: filterPresets.numAccelerators || { from: null, to: null },
stats: [], stats: filterPresets.stats || [],
}; };
let isClusterOpen = false, let isClusterOpen = false,
@ -127,27 +127,30 @@
items.push({ jobId: { [filters.jobIdMatch]: filters.jobId } }); items.push({ jobId: { [filters.jobIdMatch]: filters.jobId } });
if (filters.arrayJobId != null) if (filters.arrayJobId != null)
items.push({ arrayJobId: filters.arrayJobId }); items.push({ arrayJobId: filters.arrayJobId });
if (filters.numNodes.from != null || filters.numNodes.to != null) if (filters.numNodes.from != null || filters.numNodes.to != null) {
items.push({ items.push({
numNodes: { from: filters.numNodes.from, to: filters.numNodes.to }, numNodes: { from: filters.numNodes.from, to: filters.numNodes.to },
}); });
if (filters.numHWThreads.from != null || filters.numHWThreads.to != null) isNodesModified = true;
}
if (filters.numHWThreads.from != null || filters.numHWThreads.to != null) {
items.push({ items.push({
numHWThreads: { numHWThreads: {
from: filters.numHWThreads.from, from: filters.numHWThreads.from,
to: filters.numHWThreads.to, to: filters.numHWThreads.to,
}, },
}); });
if ( isHwthreadsModified = true;
filters.numAccelerators.from != null || }
filters.numAccelerators.to != null if (filters.numAccelerators.from != null || filters.numAccelerators.to != null) {
)
items.push({ items.push({
numAccelerators: { numAccelerators: {
from: filters.numAccelerators.from, from: filters.numAccelerators.from,
to: filters.numAccelerators.to, to: filters.numAccelerators.to,
}, },
}); });
isAccsModified = true;
}
if (filters.user) if (filters.user)
items.push({ user: { [filters.userMatch]: filters.user } }); items.push({ user: { [filters.userMatch]: filters.user } });
if (filters.project) if (filters.project)
@ -197,10 +200,10 @@
opts.push(`energy=${filters.energy.from}-${filters.energy.to}`); opts.push(`energy=${filters.energy.from}-${filters.energy.to}`);
if (filters.numNodes.from && filters.numNodes.to) if (filters.numNodes.from && filters.numNodes.to)
opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`); opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`);
if (filters.numHWThreads.from && filters.numHWThreads.to)
opts.push(`numHWThreads=${filters.numHWThreads.from}-${filters.numHWThreads.to}`);
if (filters.numAccelerators.from && filters.numAccelerators.to) if (filters.numAccelerators.from && filters.numAccelerators.to)
opts.push( opts.push(`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`);
`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`,
);
if (filters.user.length != 0) if (filters.user.length != 0)
if (filters.userMatch != "in") { if (filters.userMatch != "in") {
opts.push(`user=${filters.user}`); opts.push(`user=${filters.user}`);
@ -214,7 +217,10 @@
if (filters.arrayJobId) opts.push(`arrayJobId=${filters.arrayJobId}`); if (filters.arrayJobId) opts.push(`arrayJobId=${filters.arrayJobId}`);
if (filters.project && filters.projectMatch != "contains") if (filters.project && filters.projectMatch != "contains")
opts.push(`projectMatch=${filters.projectMatch}`); opts.push(`projectMatch=${filters.projectMatch}`);
if (filters.stats.length != 0)
for (let stat of filters.stats) {
opts.push(`stat=${stat?.field ? stat.field : stat.metricName}-${stat?.from ? stat.from : stat.range.from}-${stat?.to ? stat.to : stat.range.to}`);
}
if (opts.length == 0 && window.location.search.length <= 1) return; if (opts.length == 0 && window.location.search.length <= 1) return;
let newurl = `${window.location.pathname}?${opts.join("&")}`; let newurl = `${window.location.pathname}?${opts.join("&")}`;
@ -364,8 +370,7 @@
{#if (isNodesModified || isHwthreadsModified) && isAccsModified}, {#if (isNodesModified || isHwthreadsModified) && isAccsModified},
{/if} {/if}
{#if isAccsModified} {#if isAccsModified}
Accelerators: {filters.numAccelerators.from} - {filters Accelerators: {filters.numAccelerators.from} - {filters.numAccelerators.to}
.numAccelerators.to}
{/if} {/if}
</Info> </Info>
{/if} {/if}
@ -385,7 +390,7 @@
{#if filters.stats.length > 0} {#if filters.stats.length > 0}
<Info icon="bar-chart" on:click={() => (isStatsOpen = true)}> <Info icon="bar-chart" on:click={() => (isStatsOpen = true)}>
{filters.stats {filters.stats
.map((stat) => `${stat.text}: ${stat.from} - ${stat.to}`) .map((stat) => `${stat?.text ? stat.text : stat.field}: ${stat?.from ? stat.from : stat.range.from} - ${stat?.to ? stat.to : stat.range.to}`)
.join(", ")} .join(", ")}
</Info> </Info>
{/if} {/if}

View File

@ -5,10 +5,10 @@
- `cluster Object?`: The currently selected cluster config [Default: null] - `cluster Object?`: The currently selected cluster config [Default: null]
- `isOpen Bool?`: Is this filter component opened [Default: false] - `isOpen Bool?`: Is this filter component opened [Default: false]
- `numNodes Object?`: The currently selected numNodes filter [Default: {from:null, to:null}] - `numNodes Object?`: The currently selected numNodes filter [Default: {from:null, to:null}]
- `numHWThreads Object?`: The currently selected numHWTreads filter [Default: {from:null, to:null}] - `numHWThreads Object?`: The currently selected numHWThreads filter [Default: {from:null, to:null}]
- `numAccelerators Object?`: The currently selected numAccelerators filter [Default: {from:null, to:null}] - `numAccelerators Object?`: The currently selected numAccelerators filter [Default: {from:null, to:null}]
- `isNodesModified Bool?`: Is the node filter modified [Default: false] - `isNodesModified Bool?`: Is the node filter modified [Default: false]
- `isHwtreadsModified Bool?`: Is the Hwthreads filter modified [Default: false] - `isHwthreadsModified Bool?`: Is the Hwthreads filter modified [Default: false]
- `isAccsModified Bool?`: Is the Accelerator filter modified [Default: false] - `isAccsModified Bool?`: Is the Accelerator filter modified [Default: false]
- `namedNode String?`: The currently selected single named node (= hostname) [Default: null] - `namedNode String?`: The currently selected single named node (= hostname) [Default: null]
@ -60,7 +60,7 @@
); );
// Limited to Single-Node Thread Count // Limited to Single-Node Thread Count
const findMaxNumHWTreadsPerNode = (clusters) => const findMaxNumHWThreadsPerNode = (clusters) =>
clusters.reduce( clusters.reduce(
(max, cluster) => (max, cluster) =>
Math.max( Math.max(
@ -91,13 +91,13 @@
minNumNodes = filterRanges.numNodes.from; minNumNodes = filterRanges.numNodes.from;
maxNumNodes = filterRanges.numNodes.to; maxNumNodes = filterRanges.numNodes.to;
maxNumAccelerators = findMaxNumAccels([{ subClusters }]); maxNumAccelerators = findMaxNumAccels([{ subClusters }]);
maxNumHWThreads = findMaxNumHWTreadsPerNode([{ subClusters }]); maxNumHWThreads = findMaxNumHWThreadsPerNode([{ subClusters }]);
} else if (clusters.length > 0) { } else if (clusters.length > 0) {
const { filterRanges } = header.clusters[0]; const { filterRanges } = header.clusters[0];
minNumNodes = filterRanges.numNodes.from; minNumNodes = filterRanges.numNodes.from;
maxNumNodes = filterRanges.numNodes.to; maxNumNodes = filterRanges.numNodes.to;
maxNumAccelerators = findMaxNumAccels(clusters); maxNumAccelerators = findMaxNumAccels(clusters);
maxNumHWThreads = findMaxNumHWTreadsPerNode(clusters); maxNumHWThreads = findMaxNumHWThreadsPerNode(clusters);
for (let cluster of header.clusters) { for (let cluster of header.clusters) {
const { filterRanges } = cluster; const { filterRanges } = cluster;
minNumNodes = Math.min(minNumNodes, filterRanges.numNodes.from); minNumNodes = Math.min(minNumNodes, filterRanges.numNodes.from);

View File

@ -29,10 +29,11 @@
export let isOpen = false; export let isOpen = false;
export let stats = []; export let stats = [];
let statistics = [] let statistics = [];
function loadRanges(isInitialized) { function loadRanges(isInitialized) {
if (!isInitialized) return; if (!isInitialized) return;
statistics = getStatsItems(); statistics = getStatsItems(stats);
} }
function resetRanges() { function resetRanges() {

View File

@ -307,23 +307,34 @@ export function checkMetricDisabled(m, c, s) { // [m]etric, [c]luster, [s]ubclus
return !result return !result
} }
export function getStatsItems() { export function getStatsItems(presetStats = []) {
// console.time('stats') // console.time('stats')
const globalMetrics = getContext("globalMetrics") const globalMetrics = getContext("globalMetrics")
const result = globalMetrics.map((gm) => { const result = globalMetrics.map((gm) => {
if (gm?.footprint) { if (gm?.footprint) {
// console.time('deep')
const mc = getMetricConfigDeep(gm.name, null, null) const mc = getMetricConfigDeep(gm.name, null, null)
// console.timeEnd('deep')
if (mc) { if (mc) {
return { const presetEntry = presetStats.find((s) => s?.field === (gm.name + '_' + gm.footprint))
field: gm.name + '_' + gm.footprint, if (presetEntry) {
text: gm.name + ' (' + gm.footprint + ')', return {
metric: gm.name, field: gm.name + '_' + gm.footprint,
from: 0, text: gm.name + ' (' + gm.footprint + ')',
to: mc.peak, metric: gm.name,
peak: mc.peak, from: presetEntry.from,
enabled: false to: presetEntry.to,
peak: mc.peak,
enabled: true
}
} else {
return {
field: gm.name + '_' + gm.footprint,
text: gm.name + ' (' + gm.footprint + ')',
metric: gm.name,
from: 0,
to: mc.peak,
peak: mc.peak,
enabled: false
}
} }
} }
} }