Footprint in jobList as selectable

This commit is contained in:
Christoph Kluge 2023-11-20 17:53:12 +01:00
parent dc86523cce
commit 8d409eed0f
6 changed files with 64 additions and 10 deletions

View File

@ -27,7 +27,7 @@
import TagManagement from "./TagManagement.svelte"; import TagManagement from "./TagManagement.svelte";
import MetricSelection from "./MetricSelection.svelte"; import MetricSelection from "./MetricSelection.svelte";
import StatsTable from "./StatsTable.svelte"; import StatsTable from "./StatsTable.svelte";
import JobFootprint from "./JobFootprint.svelte"; import JobFootprintBars from "./JobFootprintBars.svelte";
import { getContext } from "svelte"; import { getContext } from "svelte";
export let dbid; export let dbid;
@ -135,7 +135,7 @@
jobTags, jobTags,
statsTable, statsTable,
jobFootprint; jobFootprint;
$: document.title = $initq.fetching $: document.title = $initq.fetching
? "Loading..." ? "Loading..."
: $initq.error : $initq.error
@ -206,7 +206,12 @@
{#if $jobMetrics.data} {#if $jobMetrics.data}
{#key $jobMetrics.data} {#key $jobMetrics.data}
<Col> <Col>
<JobFootprint <!-- <JobFootprint
bind:this={jobFootprint}
job={$initq.data.job}
jobMetrics={$jobMetrics.data.jobMetrics}
/> -->
<JobFootprintBars
bind:this={jobFootprint} bind:this={jobFootprint}
job={$initq.data.job} job={$initq.data.job}
jobMetrics={$jobMetrics.data.jobMetrics} jobMetrics={$jobMetrics.data.jobMetrics}

View File

@ -17,18 +17,19 @@
export let job export let job
export let jobMetrics export let jobMetrics
export let view = 'job'
// export let size = 200 // export let size = 200
const footprintMetrics = ['cpu_load', 'flops_any', 'mem_used', 'mem_bw'] // 'acc_utilization' / missing: energy , move to central config before deployment const footprintMetrics = ['cpu_load', 'flops_any', 'mem_used', 'mem_bw'] // 'acc_utilization' / missing: energy , move to central config before deployment
console.log('JMs', jobMetrics.filter((jm) => footprintMetrics.includes(jm.name))) // console.log('JMs', jobMetrics.filter((jm) => footprintMetrics.includes(jm.name)))
const footprintMetricConfigs = footprintMetrics.map((fm) => { const footprintMetricConfigs = footprintMetrics.map((fm) => {
return getContext('metrics')(job.cluster, fm) return getContext('metrics')(job.cluster, fm)
}).filter( Boolean ) // Filter only "truthy" vals, see: https://stackoverflow.com/questions/28607451/removing-undefined-values-from-array }).filter( Boolean ) // Filter only "truthy" vals, see: https://stackoverflow.com/questions/28607451/removing-undefined-values-from-array
console.log("FMCs", footprintMetricConfigs) // console.log("FMCs", footprintMetricConfigs)
// const footprintMetricThresholds = footprintMetricConfigs.map((fmc) => { // Only required if scopes smaller than node required // const footprintMetricThresholds = footprintMetricConfigs.map((fmc) => { // Only required if scopes smaller than node required
// return {name: fmc.name, ...findThresholds(fmc, 'node', job?.subCluster ? job.subCluster : '')} // Merge 2 objects // return {name: fmc.name, ...findThresholds(fmc, 'node', job?.subCluster ? job.subCluster : '')} // Merge 2 objects
@ -149,16 +150,18 @@
} }
}).filter( Boolean ) }).filter( Boolean )
console.log("FPD", footprintData) // console.log("FPD", footprintData)
</script> </script>
<Card class="h-auto mt-1"> <Card class="h-auto mt-1">
{#if view === 'job'}
<CardHeader> <CardHeader>
<CardTitle class="mb-0 d-flex justify-content-center"> <CardTitle class="mb-0 d-flex justify-content-center">
Core Metrics Footprint Core Metrics Footprint
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
{/if}
<CardBody> <CardBody>
{#each footprintData as fpd} {#each footprintData as fpd}
<div class="mb-1 d-flex justify-content-between"> <div class="mb-1 d-flex justify-content-between">

View File

@ -19,7 +19,7 @@
let filterComponent; // see why here: https://stackoverflow.com/questions/58287729/how-can-i-export-a-function-from-a-svelte-component-that-changes-a-value-in-the let filterComponent; // see why here: https://stackoverflow.com/questions/58287729/how-can-i-export-a-function-from-a-svelte-component-that-changes-a-value-in-the
let jobList, matchedJobs = null let jobList, matchedJobs = null
let sorting = { field: 'startTime', order: 'DESC' }, isSortingOpen = false, isMetricsSelectionOpen = false let sorting = { field: 'startTime', order: 'DESC' }, isSortingOpen = false, isMetricsSelectionOpen = false, showFootprint
let metrics = filterPresets.cluster let metrics = filterPresets.cluster
? ccconfig[`plot_list_selectedMetrics:${filterPresets.cluster}`] || ccconfig.plot_list_selectedMetrics ? ccconfig[`plot_list_selectedMetrics:${filterPresets.cluster}`] || ccconfig.plot_list_selectedMetrics
: ccconfig.plot_list_selectedMetrics : ccconfig.plot_list_selectedMetrics
@ -81,7 +81,8 @@
bind:metrics={metrics} bind:metrics={metrics}
bind:sorting={sorting} bind:sorting={sorting}
bind:matchedJobs={matchedJobs} bind:matchedJobs={matchedJobs}
bind:this={jobList} /> bind:this={jobList}
bind:showFootprint={showFootprint} />
</Col> </Col>
</Row> </Row>
@ -93,4 +94,5 @@
bind:cluster={selectedCluster} bind:cluster={selectedCluster}
configName="plot_list_selectedMetrics" configName="plot_list_selectedMetrics"
bind:metrics={metrics} bind:metrics={metrics}
bind:isOpen={isMetricsSelectionOpen} /> bind:isOpen={isMetricsSelectionOpen}
bind:showFootprint={showFootprint}/>

View File

@ -17,12 +17,14 @@
export let configName export let configName
export let allMetrics = null export let allMetrics = null
export let cluster = null export let cluster = null
export let showFootprint
const clusters = getContext('clusters'), const clusters = getContext('clusters'),
onInit = getContext('on-init') onInit = getContext('on-init')
let newMetricsOrder = [] let newMetricsOrder = []
let unorderedMetrics = [...metrics] let unorderedMetrics = [...metrics]
let pendingShowFootprint = showFootprint || false
onInit(() => { onInit(() => {
if (allMetrics == null) allMetrics = new Set() if (allMetrics == null) allMetrics = new Set()
@ -90,6 +92,8 @@
metrics = newMetricsOrder.filter(m => unorderedMetrics.includes(m)) metrics = newMetricsOrder.filter(m => unorderedMetrics.includes(m))
isOpen = false isOpen = false
showFootprint = pendingShowFootprint ? true : false
updateConfigurationMutation({ updateConfigurationMutation({
name: cluster == null ? configName : `${configName}:${cluster}`, name: cluster == null ? configName : `${configName}:${cluster}`,
value: JSON.stringify(metrics) value: JSON.stringify(metrics)
@ -121,6 +125,10 @@
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
<ListGroup> <ListGroup>
<li class="list-group-item">
<input type="checkbox" bind:checked={pendingShowFootprint}> Show Footprint
</li>
<hr/>
{#each newMetricsOrder as metric, index (metric)} {#each newMetricsOrder as metric, index (metric)}
<li class="cc-config-column list-group-item" <li class="cc-config-column list-group-item"
draggable={true} ondragover="return false" draggable={true} ondragover="return false"

View File

@ -28,6 +28,7 @@
export let sorting = { field: "startTime", order: "DESC" }; export let sorting = { field: "startTime", order: "DESC" };
export let matchedJobs = 0; export let matchedJobs = 0;
export let metrics = ccconfig.plot_list_selectedMetrics; export let metrics = ccconfig.plot_list_selectedMetrics;
export let showFootprint;
let itemsPerPage = ccconfig.plot_list_jobsPerPage; let itemsPerPage = ccconfig.plot_list_jobsPerPage;
let page = 1; let page = 1;
@ -160,6 +161,15 @@
> >
Job Info Job Info
</th> </th>
{#if showFootprint}
<th
class="position-sticky top-0"
scope="col"
style="width: {jobInfoColumnWidth}px; padding-top: {headerPaddingTop}px"
>
Job Footprint
</th>
{/if}
{#each metrics as metric (metric)} {#each metrics as metric (metric)}
<th <th
class="position-sticky top-0 text-center" class="position-sticky top-0 text-center"
@ -212,7 +222,7 @@
</tr> </tr>
{:else if $jobs.data && $initialized} {:else if $jobs.data && $initialized}
{#each $jobs.data.jobs.items as job (job)} {#each $jobs.data.jobs.items as job (job)}
<JobListRow {job} {metrics} {plotWidth} /> <JobListRow {job} {metrics} {plotWidth} {showFootprint}/>
{:else} {:else}
<tr> <tr>
<td colspan={metrics.length + 1}> <td colspan={metrics.length + 1}>

View File

@ -14,16 +14,23 @@
import { Card, Spinner } from "sveltestrap"; import { Card, Spinner } from "sveltestrap";
import MetricPlot from "../plots/MetricPlot.svelte"; import MetricPlot from "../plots/MetricPlot.svelte";
import JobInfo from "./JobInfo.svelte"; import JobInfo from "./JobInfo.svelte";
import JobFootprint from "../JobFootprint.svelte";
import JobFootprintBars from "../JobFootprintBars.svelte";
import { maxScope, checkMetricDisabled } from "../utils.js"; import { maxScope, checkMetricDisabled } from "../utils.js";
export let job; export let job;
export let metrics; export let metrics;
export let plotWidth; export let plotWidth;
export let plotHeight = 275; export let plotHeight = 275;
export let showFootprint;
let { id } = job; let { id } = job;
let scopes = [job.numNodes == 1 ? "core" : "node"]; let scopes = [job.numNodes == 1 ? "core" : "node"];
function distinct(value, index, array) {
return array.indexOf(value) === index;
}
const cluster = getContext("clusters").find((c) => c.name == job.cluster); const cluster = getContext("clusters").find((c) => c.name == job.cluster);
const metricConfig = getContext("metrics"); // Get all MetricConfs which include subCluster-specific settings for this job const metricConfig = getContext("metrics"); // Get all MetricConfs which include subCluster-specific settings for this job
const client = getContextClient(); const client = getContextClient();
@ -64,6 +71,10 @@
variables: { id, metrics, scopes } variables: { id, metrics, scopes }
}); });
$: if (showFootprint) {
metrics = ['cpu_load', 'flops_any', 'mem_used', 'mem_bw', ...metrics].filter(distinct)
}
export function refresh() { export function refresh() {
metricsQuery = queryStore({ metricsQuery = queryStore({
client: client, client: client,
@ -122,6 +133,21 @@
</Card> </Card>
</td> </td>
{:else} {:else}
{#if showFootprint}
<!-- <td>
<JobFootprint
job={job}
jobMetrics={$metricsQuery.data.jobMetrics}
/>
</td> -->
<td>
<JobFootprintBars
job={job}
jobMetrics={$metricsQuery.data.jobMetrics}
view="list"
/>
</td>
{/if}
{#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric || i)} {#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric || i)}
<td> <td>
<!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case--> <!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case-->