mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 13:29:05 +01:00
Finish direct data render roofplot demo
This commit is contained in:
parent
8d7f942de4
commit
b2b4beaeaa
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
export let flopsAny = null
|
export let flopsAny = null
|
||||||
export let memBw = null
|
export let memBw = null
|
||||||
|
export let maxY = null
|
||||||
export let cluster = null
|
export let cluster = null
|
||||||
export let defaultMaxY = null
|
|
||||||
export let width = 500
|
export let width = 500
|
||||||
export let height = 300
|
export let height = 300
|
||||||
export let tiles = null
|
export let tiles = null
|
||||||
@ -19,11 +19,6 @@
|
|||||||
let uplot = null
|
let uplot = null
|
||||||
let timeoutId = null
|
let timeoutId = null
|
||||||
|
|
||||||
const paddingLeft = 40,
|
|
||||||
paddingRight = 10,
|
|
||||||
paddingTop = 10,
|
|
||||||
paddingBottom = 50
|
|
||||||
|
|
||||||
// Three Render-Cases:
|
// Three Render-Cases:
|
||||||
// #1 Single-Job Roofline -> Has Time-Information: Use data, allow colorDots && showTime
|
// #1 Single-Job Roofline -> Has Time-Information: Use data, allow colorDots && showTime
|
||||||
// #2 MultiNode Roofline - > Has No Time-Information: Transform from nodeData, only "IST"-state of nodes, no timeInfo
|
// #2 MultiNode Roofline - > Has No Time-Information: Transform from nodeData, only "IST"-state of nodes, no timeInfo
|
||||||
@ -65,35 +60,10 @@
|
|||||||
data[1][1] = filledArr(points, i => randFloat(1,5000)) // Performance
|
data[1][1] = filledArr(points, i => randFloat(1,5000)) // Performance
|
||||||
data[2] = filledArr(points, i => 0) // Time Information (Optional)
|
data[2] = filledArr(points, i => 0) // Time Information (Optional)
|
||||||
|
|
||||||
console.log("Subcluster: ", cluster);
|
|
||||||
console.log("Data: ", data);
|
|
||||||
|
|
||||||
// End Demo Data
|
// End Demo Data
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
const [minX, maxX, minY, maxY] = [0.01, 1000, 1., cluster?.flopRateSimd?.value || defaultMaxY]
|
|
||||||
|
|
||||||
const w = width - paddingLeft - paddingRight
|
|
||||||
|
|
||||||
const h = height - paddingTop - paddingBottom
|
|
||||||
|
|
||||||
const [log10minX, log10maxX, log10minY, log10maxY] =
|
|
||||||
[Math.log10(minX), Math.log10(maxX), Math.log10(minY), Math.log10(maxY)]
|
|
||||||
|
|
||||||
const getCanvasX = (x) => {
|
|
||||||
x = Math.log10(x)
|
|
||||||
x -= log10minX; x /= (log10maxX - log10minX)
|
|
||||||
return Math.round((x * w) + paddingLeft)
|
|
||||||
}
|
|
||||||
|
|
||||||
const getCanvasY = (y) => {
|
|
||||||
y = Math.log10(y)
|
|
||||||
y -= log10minY
|
|
||||||
y /= (log10maxY - log10minY)
|
|
||||||
return Math.round((h - y * h) + paddingTop)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getGradientR(x) {
|
function getGradientR(x) {
|
||||||
if (x < 0.5) return 0
|
if (x < 0.5) return 0
|
||||||
if (x > 0.75) return 255
|
if (x > 0.75) return 255
|
||||||
@ -119,6 +89,10 @@
|
|||||||
return `rgb(${getGradientR(c)}, ${getGradientG(c)}, ${getGradientB(c)})`
|
return `rgb(${getGradientR(c)}, ${getGradientG(c)}, ${getGradientB(c)})`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function nearestThousand (num) {
|
||||||
|
return Math.ceil(num/1000) * 1000
|
||||||
|
}
|
||||||
|
|
||||||
function lineIntersect(x1, y1, x2, y2, x3, y3, x4, y4) {
|
function lineIntersect(x1, y1, x2, y2, x3, y3, x4, y4) {
|
||||||
let l = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
|
let l = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
|
||||||
let a = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / l
|
let a = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / l
|
||||||
@ -233,6 +207,7 @@
|
|||||||
legend: {
|
legend: {
|
||||||
show: false
|
show: false
|
||||||
},
|
},
|
||||||
|
cursor: { drag: { x: false, y: false } },
|
||||||
axes: [
|
axes: [
|
||||||
{
|
{
|
||||||
label: 'Intensity [FLOPS/Byte]'
|
label: 'Intensity [FLOPS/Byte]'
|
||||||
@ -244,12 +219,14 @@
|
|||||||
scales: {
|
scales: {
|
||||||
x: {
|
x: {
|
||||||
time: false,
|
time: false,
|
||||||
distr: 3,
|
range: [0.01, 1000],
|
||||||
log: 10,
|
distr: 3, // Render as log
|
||||||
|
log: 10, // log exp
|
||||||
},
|
},
|
||||||
y: {
|
y: {
|
||||||
distr: 3,
|
range: [1.0, nearestThousand(cluster.flopRateSimd.value || maxY)],
|
||||||
log: 10,
|
distr: 3, // Render as log
|
||||||
|
log: 10, // log exp
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
@ -274,47 +251,58 @@
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
draw: [
|
draw: [
|
||||||
u => { // draw roofs
|
u => { // draw roofs when cluster set
|
||||||
u.ctx.strokeStyle = 'black'
|
|
||||||
u.ctx.lineWidth = 2
|
|
||||||
u.ctx.beginPath()
|
|
||||||
if (cluster != null) {
|
if (cluster != null) {
|
||||||
|
const padding = u._padding // [top, right, bottom, left]
|
||||||
|
|
||||||
|
u.ctx.strokeStyle = 'black'
|
||||||
|
u.ctx.lineWidth = 2
|
||||||
|
u.ctx.beginPath()
|
||||||
|
|
||||||
const ycut = 0.01 * cluster.memoryBandwidth.value
|
const ycut = 0.01 * cluster.memoryBandwidth.value
|
||||||
const scalarKnee = (cluster.flopRateScalar.value - ycut) / cluster.memoryBandwidth.value
|
const scalarKnee = (cluster.flopRateScalar.value - ycut) / cluster.memoryBandwidth.value
|
||||||
const simdKnee = (cluster.flopRateSimd.value - ycut) / cluster.memoryBandwidth.value
|
const simdKnee = (cluster.flopRateSimd.value - ycut) / cluster.memoryBandwidth.value
|
||||||
const scalarKneeX = getCanvasX(scalarKnee),
|
const scalarKneeX = u.valToPos(scalarKnee, 'x', true), // Value, axis, toCanvasPixels
|
||||||
simdKneeX = getCanvasX(simdKnee),
|
simdKneeX = u.valToPos(simdKnee, 'x', true),
|
||||||
flopRateScalarY = getCanvasY(cluster.flopRateScalar.value),
|
flopRateScalarY = u.valToPos(cluster.flopRateScalar.value, 'y', true),
|
||||||
flopRateSimdY = getCanvasY(cluster.flopRateSimd.value)
|
flopRateSimdY = u.valToPos(cluster.flopRateSimd.value, 'y', true)
|
||||||
|
|
||||||
if (scalarKneeX < width - paddingRight) {
|
if (scalarKneeX < width - padding[1]) { // Top horizontal roofline
|
||||||
u.ctx.moveTo(scalarKneeX, flopRateScalarY)
|
u.ctx.moveTo(scalarKneeX, flopRateScalarY)
|
||||||
u.ctx.lineTo(width - paddingRight, flopRateScalarY)
|
u.ctx.lineTo(width - padding[1], flopRateScalarY)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simdKneeX < width - paddingRight) {
|
if (simdKneeX < width - padding[1]) { // Lower horitontal roofline
|
||||||
u.ctx.moveTo(simdKneeX, flopRateSimdY)
|
u.ctx.moveTo(simdKneeX, flopRateSimdY)
|
||||||
u.ctx.lineTo(width - paddingRight, flopRateSimdY)
|
u.ctx.lineTo(width - padding[1], flopRateSimdY)
|
||||||
}
|
}
|
||||||
|
|
||||||
let x1 = getCanvasX(0.01),
|
let x1 = u.valToPos(0.01, 'x', true),
|
||||||
y1 = getCanvasY(ycut),
|
y1 = u.valToPos(ycut, 'y', true)
|
||||||
x2 = getCanvasX(simdKnee),
|
|
||||||
|
let x2 = u.valToPos(simdKnee, 'x', true),
|
||||||
y2 = flopRateSimdY
|
y2 = flopRateSimdY
|
||||||
|
|
||||||
let xAxisIntersect = lineIntersect(
|
let xAxisIntersect = lineIntersect(
|
||||||
x1, y1, x2, y2,
|
x1, y1, x2, y2,
|
||||||
0, height - paddingBottom, width, height - paddingBottom)
|
u.valToPos(0.01, 'x', true), u.valToPos(1.0, 'y', true),
|
||||||
|
u.valToPos(1000, 'x', true), u.valToPos(1.0, 'y', true) // X-Axis Coords
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if (xAxisIntersect.x > x1) {
|
if (xAxisIntersect.x > x1) {
|
||||||
x1 = xAxisIntersect.x
|
x1 = xAxisIntersect.x
|
||||||
y1 = xAxisIntersect.y
|
y1 = xAxisIntersect.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Diagonal
|
||||||
u.ctx.moveTo(x1, y1)
|
u.ctx.moveTo(x1, y1)
|
||||||
u.ctx.lineTo(x2, y2)
|
u.ctx.lineTo(x2, y2)
|
||||||
|
|
||||||
|
u.ctx.stroke()
|
||||||
|
// Reset lineWidth
|
||||||
|
u.ctx.lineWidth = 0.15
|
||||||
}
|
}
|
||||||
u.ctx.stroke()
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user