diff --git a/content/_data/constants.yml b/content/_data/constants.yml index 2d4f4d550504..38b8a55ee87c 100644 --- a/content/_data/constants.yml +++ b/content/_data/constants.yml @@ -136,6 +136,20 @@ cookie_consent: - link: "https://qx.vtt.fi/docs/devices/q50.html" teaser: "Read more about VTT Q50 (VTT website)" icon: mdiOpenInNew + + - name: EuroHPC VLQ + desc: |- + EuroHPC VLQ is a superconducting IQM quantum computer with 24 qubits in a star topology. It is operated by IT4I. + image: "/assets/images/vlq-images/vlq-image.jpg" + links: + - link: "/resource-call" + teaser: "Apply for access to EuroHPC VLQ" + - link: "https://docs.csc.fi/computing/quantum-computing/running-quantum-jobs/" + teaser: "How to access EuroHPC VLQ, instructions" + icon: mdiArrowRight + - link: "https://docs.it4i.cz/en/docs/clusters/vlq/introduction" + teaser: "Read more about EuroHPC VLQ (IT4I website)" + icon: mdiOpenInNew - name: VTT Q5 (Helmi) - End of life desc: |- @@ -256,6 +270,9 @@ cookie_consent: Aalto Q20 access is currently being rolled out! See the CSC Quantum Computing docs for more info. link: "https://docs.csc.fi/computing/quantum-computing/overview/" type: info + - text: |- + Access to EuroHPC VLQ is coming soon! + type: info quantum-computers: - name: VTT Q50 qubits: 53 @@ -271,6 +288,13 @@ cookie_consent: pulse: "True" device_id: "Q20" + - name: VLQ + qubits: 24 + basis: "PRX, CZ, MOVE" + topology: "Star" + pulse: "True" + device_id: "VLQ" + "/cookies/": title: Cookie Policy desc: |- diff --git a/content/assets/images/vlq-images/vlq-image.jpg b/content/assets/images/vlq-images/vlq-image.jpg new file mode 100644 index 000000000000..65a78709ead2 Binary files /dev/null and b/content/assets/images/vlq-images/vlq-image.jpg differ diff --git a/src/components/Loading.jsx b/src/components/Loading.jsx new file mode 100644 index 000000000000..3b76b2e2cf3b --- /dev/null +++ b/src/components/Loading.jsx @@ -0,0 +1,27 @@ +import React from 'react' +import { CSpinner } from '@cscfi/csc-ui-react' + +/** + * Stand-in for the Online/Offline status pill. Keeps the pill's height so the + * card doesn't jump when the healthcheck resolves. + */ +export const StatusPillLoading = () => ( +
Loading...
+{props.label || 'Loading…'}
+{props.label || 'Data is currently unavailable.'}
+Online
Qubits: {deviceData.qubits}
Basis gates: {deviceData.basis}
Topology: {deviceData.topology}
+Pulse access: {deviceData.pulse === "True" ? "Yes" : "No"}
Online
Last calibrated: {lastCalibrated.toLocaleString()}
++ Last calibrated:{' '} + {calibrationLoading ? 'Loading…' : lastCalibrated || 'Not available'} +
{props.title}
+ {props.children} + ++ {metric.title}: + {metric.value} + {metric.unit === 's' ? <> μs> : metric.unit ? metric.unit : '%'} + +
+Not available
+ export const Overview = (props) => { const calibrationData = props.calibrationData; const deviceInfoData = props.deviceInfoData; const limitationsData = deviceInfoData?.job_policy || {}; - const deviceName = deviceInfoData?.name || ''; + const deviceName = deviceInfoData?.name || props.device_id || ''; const { overview } = getDeviceMetricsConfig(deviceName); - const limitations = { - "Max circuits per batch": limitationsData?.max_number_circuits_per_batch || "-", - "Max shots per job": limitationsData?.max_number_shots_per_job || "-", - "Max jobs in queue": limitationsData?.max_queue_length || "-" - } + // Distinguishes "the fetch gave us nothing" from "this device doesn't track + // that metric" — the former gets a message, the latter is simply omitted. + const calibrationUnavailable = !!props.calibrationError + || !calibrationData + || Object.keys(calibrationData).length === 0; + const limitationsUnavailable = !!props.infoError || !deviceInfoData; - const buildMetric = (title, keys) => { + const buildMetric = (key, title, keys) => { const entry = pickMetricData(calibrationData, keys); const unit = getMetricUnit(entry?.data) || '%'; return { + key, title, value: parseResultMedian(entry?.data?.statistics, unit), unit, }; }; - const qualityMetricsSingle = { - "median-prx": buildMetric('Median single-qubit gate fidelity', overview?.single?.singleGateFidelity), - "median-readout-fidelity": buildMetric('Median readout fidelity', overview?.single?.readoutFidelity), - "median-t1": buildMetric('Median T1 time', overview?.single?.t1), - "median-t2": buildMetric('Median T2 time', overview?.single?.t2), - }; + const qubitMetrics = [ + buildMetric('median-prx', 'Median single-qubit gate fidelity', overview?.single?.singleGateFidelity), + buildMetric('median-readout-fidelity', 'Median readout fidelity', overview?.single?.readoutFidelity), + buildMetric('median-t1', 'Median T1 time', overview?.single?.t1), + buildMetric('median-t2', 'Median T2 time', overview?.single?.t2), + ].filter(metric => metric.value !== null); - const qualityMetricsTwo = { - "median-2-qubit": buildMetric('Median 2-qubit gate fidelity', overview?.coupler?.twoQubitFidelity), - "median-clifford": buildMetric('Median Clifford gate fidelity', overview?.coupler?.cliffordFidelity), - }; + const couplerMetrics = [ + buildMetric('median-2-qubit', 'Median 2-qubit gate fidelity', overview?.coupler?.twoQubitFidelity), + buildMetric('median-clifford', 'Median Clifford gate fidelity', overview?.coupler?.cliffordFidelity), + ].filter(metric => metric.value !== null); - return ( -Qubit Metrics:
- {Object.entries(qualityMetricsSingle).filter(([key, metric]) => metric.value !== null).map(([key, metric]) => ( -- {metric.title}: - {metric.value} - {metric.unit === 's' ? <> μs> : metric.unit ? metric.unit : '%'} - -
-Coupler Metrics:
- {Object.entries(qualityMetricsTwo).map(([key, metric]) => ( -- {metric.title}: - {metric.value} - {metric.unit === 's' ? <> μs> : metric.unit ? metric.unit : '%'} - -
-Limitations:
- {Object.entries(limitations).map(([key, value]) => ( -{key}:
-{value}
+ if (calibrationUnavailable) { + sections.push( +{limitation.title}:
+{limitation.value}
No device data is currently available.