diff --git a/internal/routerConfig/routes.go b/internal/routerConfig/routes.go index 8e943a0a..2267efb4 100644 --- a/internal/routerConfig/routes.go +++ b/internal/routerConfig/routes.go @@ -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") != "" { parts := strings.Split(query.Get("numAccelerators"), "-") 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 } diff --git a/web/frontend/src/generic/Filters.svelte b/web/frontend/src/generic/Filters.svelte index 9580f175..312135aa 100644 --- a/web/frontend/src/generic/Filters.svelte +++ b/web/frontend/src/generic/Filters.svelte @@ -76,7 +76,7 @@ numHWThreads: filterPresets.numHWThreads || { from: null, to: null }, numAccelerators: filterPresets.numAccelerators || { from: null, to: null }, - stats: [], + stats: filterPresets.stats || [], }; let isClusterOpen = false, @@ -127,27 +127,30 @@ items.push({ jobId: { [filters.jobIdMatch]: filters.jobId } }); if (filters.arrayJobId != null) 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({ 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({ numHWThreads: { from: filters.numHWThreads.from, to: filters.numHWThreads.to, }, }); - if ( - filters.numAccelerators.from != null || - filters.numAccelerators.to != null - ) + isHwthreadsModified = true; + } + if (filters.numAccelerators.from != null || filters.numAccelerators.to != null) { items.push({ numAccelerators: { from: filters.numAccelerators.from, to: filters.numAccelerators.to, }, }); + isAccsModified = true; + } if (filters.user) items.push({ user: { [filters.userMatch]: filters.user } }); if (filters.project) @@ -197,10 +200,10 @@ opts.push(`energy=${filters.energy.from}-${filters.energy.to}`); if (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) - opts.push( - `numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`, - ); + opts.push(`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`); if (filters.user.length != 0) if (filters.userMatch != "in") { opts.push(`user=${filters.user}`); @@ -214,7 +217,10 @@ if (filters.arrayJobId) opts.push(`arrayJobId=${filters.arrayJobId}`); if (filters.project && filters.projectMatch != "contains") 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; let newurl = `${window.location.pathname}?${opts.join("&")}`; @@ -364,8 +370,7 @@ {#if (isNodesModified || isHwthreadsModified) && isAccsModified}, {/if} {#if isAccsModified} - Accelerators: {filters.numAccelerators.from} - {filters - .numAccelerators.to} + Accelerators: {filters.numAccelerators.from} - {filters.numAccelerators.to} {/if} {/if} @@ -385,7 +390,7 @@ {#if filters.stats.length > 0} (isStatsOpen = true)}> {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(", ")} {/if} diff --git a/web/frontend/src/generic/filters/Resources.svelte b/web/frontend/src/generic/filters/Resources.svelte index 23eb9b70..750c4a62 100644 --- a/web/frontend/src/generic/filters/Resources.svelte +++ b/web/frontend/src/generic/filters/Resources.svelte @@ -5,10 +5,10 @@ - `cluster Object?`: The currently selected cluster config [Default: null] - `isOpen Bool?`: Is this filter component opened [Default: false] - `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}] - `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] - `namedNode String?`: The currently selected single named node (= hostname) [Default: null] @@ -60,7 +60,7 @@ ); // Limited to Single-Node Thread Count - const findMaxNumHWTreadsPerNode = (clusters) => + const findMaxNumHWThreadsPerNode = (clusters) => clusters.reduce( (max, cluster) => Math.max( @@ -91,13 +91,13 @@ minNumNodes = filterRanges.numNodes.from; maxNumNodes = filterRanges.numNodes.to; maxNumAccelerators = findMaxNumAccels([{ subClusters }]); - maxNumHWThreads = findMaxNumHWTreadsPerNode([{ subClusters }]); + maxNumHWThreads = findMaxNumHWThreadsPerNode([{ subClusters }]); } else if (clusters.length > 0) { const { filterRanges } = header.clusters[0]; minNumNodes = filterRanges.numNodes.from; maxNumNodes = filterRanges.numNodes.to; maxNumAccelerators = findMaxNumAccels(clusters); - maxNumHWThreads = findMaxNumHWTreadsPerNode(clusters); + maxNumHWThreads = findMaxNumHWThreadsPerNode(clusters); for (let cluster of header.clusters) { const { filterRanges } = cluster; minNumNodes = Math.min(minNumNodes, filterRanges.numNodes.from); diff --git a/web/frontend/src/generic/filters/Stats.svelte b/web/frontend/src/generic/filters/Stats.svelte index 5b804a7e..3252d390 100644 --- a/web/frontend/src/generic/filters/Stats.svelte +++ b/web/frontend/src/generic/filters/Stats.svelte @@ -29,10 +29,11 @@ export let isOpen = false; export let stats = []; - let statistics = [] + let statistics = []; + function loadRanges(isInitialized) { if (!isInitialized) return; - statistics = getStatsItems(); + statistics = getStatsItems(stats); } function resetRanges() { diff --git a/web/frontend/src/generic/utils.js b/web/frontend/src/generic/utils.js index 57248fcf..fa357eb3 100644 --- a/web/frontend/src/generic/utils.js +++ b/web/frontend/src/generic/utils.js @@ -307,23 +307,34 @@ export function checkMetricDisabled(m, c, s) { // [m]etric, [c]luster, [s]ubclus return !result } -export function getStatsItems() { +export function getStatsItems(presetStats = []) { // console.time('stats') const globalMetrics = getContext("globalMetrics") const result = globalMetrics.map((gm) => { if (gm?.footprint) { - // console.time('deep') const mc = getMetricConfigDeep(gm.name, null, null) - // console.timeEnd('deep') if (mc) { - return { - field: gm.name + '_' + gm.footprint, - text: gm.name + ' (' + gm.footprint + ')', - metric: gm.name, - from: 0, - to: mc.peak, - peak: mc.peak, - enabled: false + const presetEntry = presetStats.find((s) => s?.field === (gm.name + '_' + gm.footprint)) + if (presetEntry) { + return { + field: gm.name + '_' + gm.footprint, + text: gm.name + ' (' + gm.footprint + ')', + metric: gm.name, + from: presetEntry.from, + 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 + } } } }