From 939ac5f29b85d2d325f6001b0fc6c7d0627956c6 Mon Sep 17 00:00:00 2001 From: "christopher.bennett" Date: Mon, 24 Feb 2025 10:41:33 +0000 Subject: [PATCH 01/16] CPU/Memory logging working --- .../cylc/analysis/AnalysisTable.vue | 65 +++++++++----- src/components/cylc/analysis/BoxPlot.vue | 32 ++++--- src/components/cylc/analysis/TimeSeries.vue | 18 ++-- src/utils/tasks.js | 86 +++++++++++++++---- src/views/Analysis.vue | 15 +++- 5 files changed, 155 insertions(+), 61 deletions(-) diff --git a/src/components/cylc/analysis/AnalysisTable.vue b/src/components/cylc/analysis/AnalysisTable.vue index d122f3ccd..60bd3ef8f 100644 --- a/src/components/cylc/analysis/AnalysisTable.vue +++ b/src/components/cylc/analysis/AnalysisTable.vue @@ -56,7 +56,10 @@ along with this program. If not, see . From 0bdd49ae013c82a5567fb57e83c8a4790f3e88b4 Mon Sep 17 00:00:00 2001 From: "christopher.bennett" Date: Mon, 3 Mar 2025 16:29:53 +0000 Subject: [PATCH 02/16] Time series now working --- src/components/cylc/analysis/AnalysisTable.vue | 17 ++++++++++------- src/components/cylc/analysis/TimeSeries.vue | 5 +++-- src/utils/tasks.js | 7 ++++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/components/cylc/analysis/AnalysisTable.vue b/src/components/cylc/analysis/AnalysisTable.vue index 60bd3ef8f..6d948f171 100644 --- a/src/components/cylc/analysis/AnalysisTable.vue +++ b/src/components/cylc/analysis/AnalysisTable.vue @@ -139,13 +139,6 @@ export default { allowZeros: false, timingOption: this.timingOption }, - { - title: `Std Dev ${times}`, - key: `${formatHeader('stdDev', times)}`, - formatter: formatDuration, - allowZeros: true, - timingOption: this.timingOption - }, { title: `Min ${times}`, key: `${formatHeader('min', times)}`, @@ -191,6 +184,16 @@ export default { timingOption: this.timingOption }) } + // Don't show std dev for cpuTime or maxRss + if (this.timingOption !== 'cpuTime' && this.timingOption !== 'maxRss') { + timingHeaders.push({ + title: `Std Dev ${times}`, + key: `${formatHeader('stdDev', times)}`, + formatter: formatDuration, + allowZeros: true, + timingOption: this.timingOption + }) + } return this.headers.concat(timingHeaders) } }, diff --git a/src/components/cylc/analysis/TimeSeries.vue b/src/components/cylc/analysis/TimeSeries.vue index 2c62ae7c0..529aa6e97 100644 --- a/src/components/cylc/analysis/TimeSeries.vue +++ b/src/components/cylc/analysis/TimeSeries.vue @@ -123,7 +123,8 @@ const jobFields = [ 'queueTime', 'runTime', 'startedTime', - 'maxRss' + 'maxRss', + 'cpuTime' ] /** The one-off query which retrieves historical job timing statistics */ @@ -370,7 +371,7 @@ export default { if (!value) { return null } - const y = formatDuration(value, true) + const y = formatDuration(value, true, this.timingOption) const platform = this.series[seriesIndex].data[dataPointIndex].platform return `${y} (${platform})` } diff --git a/src/utils/tasks.js b/src/utils/tasks.js index 8fbd4d883..a7b0d9b33 100644 --- a/src/utils/tasks.js +++ b/src/utils/tasks.js @@ -98,10 +98,11 @@ export function jobMessageOutputs (jobNode) { * 00:00:00, rather than undefined * @return {string=} Formatted duration */ - export function formatDuration (value, allowZeros = false, timingOption = false) { - // Smaller number of seconds are formatted as HH:MM:SS +export function formatDuration (value, allowZeros = false, timingOption = false) { + // Times are formatted as HH:MM:SS if (timingOption === 'queue' || timingOption === 'total' || timingOption === 'run' || timingOption === 'cpuTime') { if (value || (value === 0 && allowZeros === true)) { + // Convert CPU time to seconds if (timingOption === 'cpuTime') { value = value / 1000 } @@ -120,7 +121,7 @@ export function jobMessageOutputs (jobNode) { ':' + minutes.toString().padStart(2, '0') + ':' + Math.round(seconds).toString().padStart(2, '0') } - // Larger number means it's memory + // If memory value passed } else if (timingOption === 'maxRss') { if (value / 1024 < 5000) { const kilobytes = value / 1024 From f49aa126b5fc0bbf45ceca96b62022a14f4302ee Mon Sep 17 00:00:00 2001 From: "christopher.bennett" Date: Tue, 4 Mar 2025 10:49:35 +0000 Subject: [PATCH 03/16] Fixed Chart Labels --- src/components/cylc/analysis/BoxPlot.vue | 2 +- src/utils/tasks.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/cylc/analysis/BoxPlot.vue b/src/components/cylc/analysis/BoxPlot.vue index 5ec31b326..de805328c 100644 --- a/src/components/cylc/analysis/BoxPlot.vue +++ b/src/components/cylc/analysis/BoxPlot.vue @@ -198,7 +198,7 @@ export default { }, xaxis: { title: { - text: `${upperFirst(getTimingOption(props.timingOption))}`, + text: `${formatChartLabels(props.timingOption)}`, }, labels: { formatter: (value) => formatDuration(value, true, props.timingOption) diff --git a/src/utils/tasks.js b/src/utils/tasks.js index a7b0d9b33..4590de79e 100644 --- a/src/utils/tasks.js +++ b/src/utils/tasks.js @@ -143,8 +143,10 @@ export function formatChartLabels (timingOption) { // Create correct labels for the charts if (timingOption === 'maxRss') { return 'Max RSS' + } else if (timingOption === 'cpuTime') { + return 'CPU Time' } else { - return upperFirst(timingOption) + ' time' + return upperFirst(timingOption) + ' Time' } } From 75b9adde86949e5d467433932d423735835f2b4d Mon Sep 17 00:00:00 2001 From: "christopher.bennett" Date: Mon, 10 Mar 2025 15:27:37 +0000 Subject: [PATCH 04/16] Added "Total of Totals" for CPU time. Fixed bug memory values --- .../cylc/analysis/AnalysisTable.vue | 120 ++++++++++-------- src/utils/tasks.js | 14 +- src/views/Analysis.vue | 16 ++- 3 files changed, 89 insertions(+), 61 deletions(-) diff --git a/src/components/cylc/analysis/AnalysisTable.vue b/src/components/cylc/analysis/AnalysisTable.vue index 6d948f171..d68d717e4 100644 --- a/src/components/cylc/analysis/AnalysisTable.vue +++ b/src/components/cylc/analysis/AnalysisTable.vue @@ -58,7 +58,8 @@ along with this program. If not, see . import { upperFirst } from 'lodash' import { formatDuration, - formatHeader + formatHeader, + formatChartLabels, } from '@/utils/tasks' import { initialOptions, @@ -131,61 +132,74 @@ export default { computed: { shownHeaders () { const times = upperFirst(this.timingOption) - const timingHeaders = [ - { - title: `Mean ${times}`, - key: `${formatHeader('mean', times)}`, - formatter: formatDuration, - allowZeros: false, - timingOption: this.timingOption - }, - { - title: `Min ${times}`, - key: `${formatHeader('min', times)}`, - formatter: formatDuration, - allowZeros: false, - timingOption: this.timingOption - }, - { - title: `Q1 ${times}`, - key: `${formatHeader('quartiles', times)}Quartiles.0`, - formatter: formatDuration, - allowZeros: false, - timingOption: this.timingOption - }, - { - title: `Median ${times}`, - key: `${formatHeader('quartiles', times)}Quartiles.1`, - formatter: formatDuration, - allowZeros: false, - timingOption: this.timingOption - }, - { - title: `Q3 ${times}`, - key: `${formatHeader('quartiles', times)}Quartiles.2`, - formatter: formatDuration, - allowZeros: false, - timingOption: this.timingOption - }, - { - title: `Max ${times}`, - key: `${formatHeader('max', times)}`, - formatter: formatDuration, - allowZeros: false, - timingOption: this.timingOption + const timingHeaders = [] + // Check if there are any stats to show + let stats = false + for (let i = 0; i < this.tasks.length; i++) { + if (this.tasks[i].count > 1) { + stats = true + break } - ] - if (this.timingOption === 'cpuTime') { - timingHeaders.push({ - title: 'Total CPU Time', - key: 'totalCpuTime', - formatter: formatDuration, - allowZeros: false, - timingOption: this.timingOption - }) } + if (stats) { + timingHeaders.push( + { + title: `Mean ${formatChartLabels(times)}`, + key: `${formatHeader('mean', times)}`, + formatter: formatDuration, + allowZeros: false, + timingOption: this.timingOption + }, + { + title: `Min ${formatChartLabels(times)}`, + key: `${formatHeader('min', times)}`, + formatter: formatDuration, + allowZeros: false, + timingOption: this.timingOption + }, + { + title: `Q1 ${formatChartLabels(times)}`, + key: `${formatHeader('quartiles', times)}Quartiles.0`, + formatter: formatDuration, + allowZeros: false, + timingOption: this.timingOption + }, + { + title: `Median ${formatChartLabels(times)}`, + key: `${formatHeader('quartiles', times)}Quartiles.1`, + formatter: formatDuration, + allowZeros: false, + timingOption: this.timingOption + }, + { + title: `Q3 ${formatChartLabels(times)}`, + key: `${formatHeader('quartiles', times)}Quartiles.2`, + formatter: formatDuration, + allowZeros: false, + timingOption: this.timingOption + }, + { + title: `Max ${formatChartLabels(times)}`, + key: `${formatHeader('max', times)}`, + formatter: formatDuration, + allowZeros: false, + timingOption: this.timingOption + } + ) + } else { + timingHeaders.push( + { + title: `${formatChartLabels(times)}`, + key: `${formatHeader('mean', times)}`, + formatter: formatDuration, + allowZeros: false, + timingOption: this.timingOption + } + ) + } + // Don't show std dev for cpuTime or maxRss - if (this.timingOption !== 'cpuTime' && this.timingOption !== 'maxRss') { + if (this.timingOption !== 'cpuTime' && this.timingOption !== 'maxRss' && stats) { timingHeaders.push({ title: `Std Dev ${times}`, key: `${formatHeader('stdDev', times)}`, diff --git a/src/utils/tasks.js b/src/utils/tasks.js index 4590de79e..782532ab7 100644 --- a/src/utils/tasks.js +++ b/src/utils/tasks.js @@ -123,14 +123,14 @@ export function formatDuration (value, allowZeros = false, timingOption = false) } // If memory value passed } else if (timingOption === 'maxRss') { - if (value / 1024 < 5000) { - const kilobytes = value / 1024 + if (value < 5000) { + const kilobytes = value return kilobytes.toPrecision(3) + ' KB' - } else if (value / 1048576 < 1000) { - const megabytes = value / 1048576 + } else if (value / 1024 < 1000) { + const megabytes = value / 1024 return megabytes.toPrecision(3) + ' MB' } else { - const gigabytes = value / 1073741824 + const gigabytes = value / 1048576 return gigabytes.toPrecision(3) + ' GB' } } @@ -141,9 +141,9 @@ export function formatDuration (value, allowZeros = false, timingOption = false) export function formatChartLabels (timingOption) { // Create correct labels for the charts - if (timingOption === 'maxRss') { + if (timingOption === 'maxRss' || timingOption === 'MaxRss') { return 'Max RSS' - } else if (timingOption === 'cpuTime') { + } else if (timingOption === 'cpuTime' || timingOption === 'CpuTime') { return 'CPU Time' } else { return upperFirst(timingOption) + ' Time' diff --git a/src/views/Analysis.vue b/src/views/Analysis.vue index 65308bd04..65e3b6fcb 100644 --- a/src/views/Analysis.vue +++ b/src/views/Analysis.vue @@ -17,6 +17,11 @@ along with this program. If not, see .