Skip to content

Commit 939ac5f

Browse files
CPU/Memory logging working
1 parent f75cc4b commit 939ac5f

File tree

5 files changed

+155
-61
lines changed

5 files changed

+155
-61
lines changed

src/components/cylc/analysis/AnalysisTable.vue

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
5656

5757
<script>
5858
import { upperFirst } from 'lodash'
59-
import { formatDuration } from '@/utils/tasks'
59+
import {
60+
formatDuration,
61+
formatHeader
62+
} from '@/utils/tasks'
6063
import {
6164
initialOptions,
6265
updateInitialOptionsEvent,
@@ -130,48 +133,64 @@ export default {
130133
const times = upperFirst(this.timingOption)
131134
const timingHeaders = [
132135
{
133-
title: `Mean T-${times}`,
134-
key: `mean${times}Time`,
136+
title: `Mean ${times}`,
137+
key: `${formatHeader('mean', times)}`,
135138
formatter: formatDuration,
136-
allowZeros: false
139+
allowZeros: false,
140+
timingOption: this.timingOption
137141
},
138142
{
139-
title: `Std Dev T-${times}`,
140-
key: `stdDev${times}Time`,
143+
title: `Std Dev ${times}`,
144+
key: `${formatHeader('stdDev', times)}`,
141145
formatter: formatDuration,
142-
allowZeros: true
146+
allowZeros: true,
147+
timingOption: this.timingOption
143148
},
144149
{
145-
title: `Min T-${times}`,
146-
key: `min${times}Time`,
150+
title: `Min ${times}`,
151+
key: `${formatHeader('min', times)}`,
147152
formatter: formatDuration,
148-
allowZeros: false
153+
allowZeros: false,
154+
timingOption: this.timingOption
149155
},
150156
{
151-
title: `Q1 T-${times}`,
152-
key: `${times.toLowerCase()}Quartiles.0`,
157+
title: `Q1 ${times}`,
158+
key: `${formatHeader('quartiles', times)}Quartiles.0`,
153159
formatter: formatDuration,
154-
allowZeros: false
160+
allowZeros: false,
161+
timingOption: this.timingOption
155162
},
156163
{
157-
title: `Median T-${times}`,
158-
key: `${times.toLowerCase()}Quartiles.1`,
164+
title: `Median ${times}`,
165+
key: `${formatHeader('quartiles', times)}Quartiles.1`,
159166
formatter: formatDuration,
160-
allowZeros: false
167+
allowZeros: false,
168+
timingOption: this.timingOption
161169
},
162170
{
163-
title: `Q3 T-${times}`,
164-
key: `${times.toLowerCase()}Quartiles.2`,
171+
title: `Q3 ${times}`,
172+
key: `${formatHeader('quartiles', times)}Quartiles.2`,
165173
formatter: formatDuration,
166-
allowZeros: false
174+
allowZeros: false,
175+
timingOption: this.timingOption
167176
},
168177
{
169-
title: `Max T-${times}`,
170-
key: `max${times}Time`,
178+
title: `Max ${times}`,
179+
key: `${formatHeader('max', times)}`,
171180
formatter: formatDuration,
172-
allowZeros: false
181+
allowZeros: false,
182+
timingOption: this.timingOption
173183
}
174184
]
185+
if (this.timingOption === 'cpuTime') {
186+
timingHeaders.push({
187+
title: 'Total CPU Time',
188+
key: 'totalCpuTime',
189+
formatter: formatDuration,
190+
allowZeros: false,
191+
timingOption: this.timingOption
192+
})
193+
}
175194
return this.headers.concat(timingHeaders)
176195
}
177196
},
@@ -186,7 +205,7 @@ export default {
186205
value = value[index]
187206
}
188207
if (header.formatter) {
189-
return header.formatter(value, header.allowZeros)
208+
return header.formatter(value, header.allowZeros, this.timingOption)
190209
}
191210
return value
192211
}

src/components/cylc/analysis/BoxPlot.vue

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ import {
6565
mdiSortVariant,
6666
} from '@mdi/js'
6767
import { upperFirst } from 'lodash'
68-
import { formatDuration } from '@/utils/tasks'
68+
import {
69+
formatDuration,
70+
getTimingOption,
71+
formatChartLabels
72+
} from '@/utils/tasks'
6973
import { useReducedAnimation } from '@/composables/localStorage'
7074
import {
7175
initialOptions,
@@ -165,11 +169,11 @@ export default {
165169
},
166170
tooltip: {
167171
custom ({ seriesIndex, dataPointIndex, w }) {
168-
const max = formatDuration(w.globals.seriesCandleC[seriesIndex][dataPointIndex], true)
169-
const q3 = formatDuration(w.globals.seriesCandleL[seriesIndex][dataPointIndex], true)
170-
const med = formatDuration(w.globals.seriesCandleM[seriesIndex][dataPointIndex], true)
171-
const q1 = formatDuration(w.globals.seriesCandleH[seriesIndex][dataPointIndex], true)
172-
const min = formatDuration(w.globals.seriesCandleO[seriesIndex][dataPointIndex], true)
172+
const max = formatDuration(w.globals.seriesCandleC[seriesIndex][dataPointIndex], true, props.timingOption)
173+
const q3 = formatDuration(w.globals.seriesCandleL[seriesIndex][dataPointIndex], true, props.timingOption)
174+
const med = formatDuration(w.globals.seriesCandleM[seriesIndex][dataPointIndex], true, props.timingOption)
175+
const q1 = formatDuration(w.globals.seriesCandleH[seriesIndex][dataPointIndex], true, props.timingOption)
176+
const min = formatDuration(w.globals.seriesCandleO[seriesIndex][dataPointIndex], true, props.timingOption)
173177
return `
174178
<div class="pa-2">
175179
<div>Maximum: ${max}</div>
@@ -194,10 +198,10 @@ export default {
194198
},
195199
xaxis: {
196200
title: {
197-
text: `${upperFirst(props.timingOption)} time`,
201+
text: `${upperFirst(getTimingOption(props.timingOption))}`,
198202
},
199203
labels: {
200-
formatter: (value) => formatDuration(value, true)
204+
formatter: (value) => formatDuration(value, true, props.timingOption)
201205
},
202206
},
203207
}))
@@ -221,11 +225,11 @@ export default {
221225
data.push({
222226
x: sortedTasks[i].name,
223227
y: [
224-
sortedTasks[i][`min${upperFirst(this.timingOption)}Time`],
228+
sortedTasks[i][`min${upperFirst(getTimingOption(this.timingOption))}`],
225229
sortedTasks[i][`${this.timingOption}Quartiles`][0],
226230
sortedTasks[i][`${this.timingOption}Quartiles`][1],
227231
sortedTasks[i][`${this.timingOption}Quartiles`][2],
228-
sortedTasks[i][`max${upperFirst(this.timingOption)}Time`],
232+
sortedTasks[i][`max${upperFirst(getTimingOption(this.timingOption))}`],
229233
],
230234
})
231235
}
@@ -241,10 +245,10 @@ export default {
241245
{ title: 'Task name', value: 'name' },
242246
{ title: 'Platform', value: 'platform' },
243247
{ title: 'Count', value: 'count' },
244-
{ title: `Mean ${this.timingOption} time`, value: `mean${upperFirst(this.timingOption)}Time` },
245-
{ title: `Median ${this.timingOption} time`, value: `median${upperFirst(this.timingOption)}Time` },
246-
{ title: `Min ${this.timingOption} time`, value: `min${upperFirst(this.timingOption)}Time` },
247-
{ title: `Max ${this.timingOption} time`, value: `max${upperFirst(this.timingOption)}Time` },
248+
{ title: `Mean ${formatChartLabels(this.timingOption)}`, value: `mean${upperFirst(getTimingOption(this.timingOption))}` },
249+
{ title: `Median ${formatChartLabels(this.timingOption)}`, value: `median${upperFirst(getTimingOption(this.timingOption))}` },
250+
{ title: `Min ${formatChartLabels(this.timingOption)}`, value: `min${upperFirst(getTimingOption(this.timingOption))}` },
251+
{ title: `Max ${formatChartLabels(this.timingOption)}`, value: `max${upperFirst(getTimingOption(this.timingOption))}` },
248252
]
249253
},
250254
},

src/components/cylc/analysis/TimeSeries.vue

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,14 @@ import {
9393
difference,
9494
pick,
9595
union,
96-
uniq,
97-
upperFirst
96+
uniq
9897
} from 'lodash'
9998
import gql from 'graphql-tag'
100-
import { formatDuration } from '@/utils/tasks'
99+
import {
100+
getTimingOption,
101+
formatDuration,
102+
formatChartLabels
103+
} from '@/utils/tasks'
101104
import {
102105
mdiDownload,
103106
mdiRefresh,
@@ -119,7 +122,8 @@ const jobFields = [
119122
'totalTime',
120123
'queueTime',
121124
'runTime',
122-
'startedTime'
125+
'startedTime',
126+
'maxRss'
123127
]
124128
125129
/** The one-off query which retrieves historical job timing statistics */
@@ -284,7 +288,7 @@ export default {
284288
const currentStartedTime = seriesData[job.name].data[job.cyclePoint].startedTime
285289
// Only add data if this job was run more recently than any existing data
286290
if (currentStartedTime === undefined || job.startedTime.localeCompare(currentStartedTime) === 1) {
287-
time = job[`${this.timingOption}Time`]
291+
time = job[getTimingOption(this.timingOption)]
288292
Object.assign(seriesData[job.name].data[job.cyclePoint], {
289293
x: job.cyclePoint,
290294
y: time,
@@ -384,7 +388,7 @@ export default {
384388
forceNiceScale: true,
385389
min: this.showOrigin ? 0 : undefined,
386390
title: {
387-
text: upperFirst(this.timingOption) + ' time',
391+
text: formatChartLabels(this.timingOption),
388392
},
389393
labels: {
390394
formatter: function (value) {
@@ -445,7 +449,7 @@ export default {
445449
yaxis: {
446450
tickAmount: 3,
447451
title: {
448-
text: upperFirst(this.timingOption) + ' time',
452+
text: formatChartLabels(this.timingOption),
449453
},
450454
labels: {
451455
formatter: function (value) {

src/utils/tasks.js

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717

1818
import TaskState from '@/model/TaskState.model'
1919
import { TASK_OUTPUT_NAMES } from '@/model/TaskOutput.model'
20-
20+
import {
21+
upperFirst
22+
} from 'lodash'
2123
/**
2224
* States used when the parent is stopped.
2325
* @type {TaskState[]}
@@ -96,28 +98,80 @@ export function jobMessageOutputs (jobNode) {
9698
* 00:00:00, rather than undefined
9799
* @return {string=} Formatted duration
98100
*/
99-
export function formatDuration (dur, allowZeros = false) {
100-
if (dur || (dur === 0 && allowZeros === true)) {
101-
const seconds = dur % 60
102-
const minutes = ((dur - seconds) / 60) % 60
103-
const hours = ((dur - minutes * 60 - seconds) / 3600) % 24
104-
const days = (dur - hours * 3600 - minutes * 60 - seconds) / 86400
101+
export function formatDuration (value, allowZeros = false, timingOption = false) {
102+
// Smaller number of seconds are formatted as HH:MM:SS
103+
if (timingOption === 'queue' || timingOption === 'total' || timingOption === 'run' || timingOption === 'cpuTime') {
104+
if (value || (value === 0 && allowZeros === true)) {
105+
if (timingOption === 'cpuTime') {
106+
value = value / 1000
107+
}
108+
const seconds = value % 60
109+
const minutes = ((value - seconds) / 60) % 60
110+
const hours = ((value - minutes * 60 - seconds) / 3600) % 24
111+
const days = (value - hours * 3600 - minutes * 60 - seconds) / 86400
105112

106-
let dayss = ''
107-
if (days > 0) {
108-
dayss = days.toString() + 'd '
109-
}
113+
let dayss = ''
114+
if (days > 0) {
115+
dayss = days.toString() + 'd '
116+
}
110117

111-
return dayss +
112-
hours.toString().padStart(2, '0') +
113-
':' + minutes.toString().padStart(2, '0') +
114-
':' + Math.round(seconds).toString().padStart(2, '0')
118+
return dayss +
119+
hours.toString().padStart(2, '0') +
120+
':' + minutes.toString().padStart(2, '0') +
121+
':' + Math.round(seconds).toString().padStart(2, '0')
122+
}
123+
// Larger number means it's memory
124+
} else if (timingOption === 'maxRss') {
125+
if (value / 1024 < 5000) {
126+
const kilobytes = value / 1024
127+
return kilobytes.toPrecision(3) + ' KB'
128+
} else if (value / 1048576 < 1000) {
129+
const megabytes = value / 1048576
130+
return megabytes.toPrecision(3) + ' MB'
131+
} else {
132+
const gigabytes = value / 1073741824
133+
return gigabytes.toPrecision(3) + ' GB'
134+
}
115135
}
116136
// the meanElapsedTime can be 0/undefined (i.e. task has not run before)
117137
// return "undefined" rather than a number for these cases
118138
return undefined
119139
}
120140

141+
export function formatChartLabels (timingOption) {
142+
// Create correct labels for the charts
143+
if (timingOption === 'maxRss') {
144+
return 'Max RSS'
145+
} else {
146+
return upperFirst(timingOption) + ' time'
147+
}
148+
}
149+
150+
export function getTimingOption (timingOption) {
151+
// Create correct timing option for the charts
152+
if (timingOption === 'maxRss' || timingOption === 'cpuTime') {
153+
return timingOption
154+
} else {
155+
return timingOption + 'Time'
156+
}
157+
}
158+
159+
export function formatHeader (statistic, timingOption) {
160+
if (timingOption === 'MaxRss' || timingOption === 'CpuTime' || timingOption === 'totalCpuTime') {
161+
if (statistic === 'quartiles') {
162+
return timingOption.charAt(0).toLowerCase() + timingOption.slice(1)
163+
} else {
164+
return statistic + timingOption
165+
}
166+
} else {
167+
if (statistic === 'quartiles') {
168+
return timingOption.toLowerCase()
169+
} else {
170+
return statistic + timingOption + 'Time'
171+
}
172+
}
173+
}
174+
121175
export function dtMean (taskNode) {
122176
// Convert to an easily read duration format:
123177
const dur = taskNode.node?.task?.meanElapsedTime
@@ -140,4 +194,4 @@ export function formatFlowNums (flowNums) {
140194
*/
141195
export function isFlowNone (flowNums) {
142196
return Boolean(flowNums && !JSON.parse(flowNums).length)
143-
}
197+
}

src/views/Analysis.vue

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,18 @@ const taskFields = [
184184
'stdDevQueueTime',
185185
'minQueueTime',
186186
'queueQuartiles',
187-
'maxQueueTime'
187+
'maxQueueTime',
188+
'maxMaxRss',
189+
'meanMaxRss',
190+
'stdDevMaxRss',
191+
'minMaxRss',
192+
'maxRssQuartiles',
193+
'maxCpuTime',
194+
'meanCpuTime',
195+
'stdDevCpuTime',
196+
'minCpuTime',
197+
'totalCpuTime',
198+
'cpuTimeQuartiles',
188199
]
189200
190201
/** The one-off query which retrieves historical task timing statistics */
@@ -359,6 +370,8 @@ export default {
359370
{ value: 'totalTimes', title: 'Total times' },
360371
{ value: 'runTimes', title: 'Run times' },
361372
{ value: 'queueTimes', title: 'Queue times' },
373+
{ value: 'maxRss', title: 'Max RSS' },
374+
{ value: 'cpuTime', title: 'CPU Time' },
362375
],
363376
}
364377
</script>

0 commit comments

Comments
 (0)