qnetbench.metrics
The standard report, computed purely from a trace.
Narrative guide: Metrics and reports.
qnetbench.metrics.report
Standard metrics, computed only from a trace. Any third-party tool can produce
the same numbers from the JSONL without importing this module; we are just the
first consumer.
RoleResult
Bases: BaseModel
success
instance-attribute
utility
instance-attribute
Report
Bases: BaseModel
app
class-attribute
instance-attribute
backend
class-attribute
instance-attribute
arbitration
class-attribute
instance-attribute
topology
class-attribute
instance-attribute
seed
class-attribute
instance-attribute
sim_duration
class-attribute
instance-attribute
sim_duration: float = 0.0
n_requests
class-attribute
instance-attribute
n_delivered
class-attribute
instance-attribute
qubits_sent
class-attribute
instance-attribute
delivered_rate
class-attribute
instance-attribute
delivered_rate: float = 0.0
mean_fidelity
class-attribute
instance-attribute
mean_fidelity: float = 0.0
fidelity_throughput
class-attribute
instance-attribute
fidelity_throughput: float = 0.0
violations
class-attribute
instance-attribute
violations: dict[str, int] = Field(default_factory=dict)
violation_rate
class-attribute
instance-attribute
violation_rate: float = 0.0
latency_mean
class-attribute
instance-attribute
latency_mean: float = 0.0
latency_p50
class-attribute
instance-attribute
latency_p95
class-attribute
instance-attribute
latency_p99
class-attribute
instance-attribute
classical_msgs
class-attribute
instance-attribute
classical_bytes
class-attribute
instance-attribute
bytes_per_pair
class-attribute
instance-attribute
bytes_per_pair: float = 0.0
msgs_per_pair
class-attribute
instance-attribute
msgs_per_pair: float = 0.0
app_success
class-attribute
instance-attribute
app_success: bool = False
app_utility
class-attribute
instance-attribute
roles
class-attribute
instance-attribute
roles: list[RoleResult] = Field(default_factory=list)
compute_report
Source code in qnetbench/metrics/report.py
| def compute_report(events: Iterable[Event]) -> Report:
events = list(events)
report = Report()
fidelities: list[float] = []
latencies: list[float] = []
times: list[float] = []
roles: list[RoleResult] = []
for ev in events:
times.append(ev.t)
if isinstance(ev, RunHeader):
report.app = ev.app
report.backend = ev.backend
report.arbitration = ev.arbitration
report.topology = ev.topology
report.seed = ev.seed
elif isinstance(ev, EntanglementRequested):
report.n_requests += 1
elif isinstance(ev, EntanglementDelivered):
report.n_delivered += 1
fidelities.append(ev.actual_fidelity)
latencies.append(ev.latency)
elif isinstance(ev, ContractViolation):
report.violations[ev.violation] = report.violations.get(ev.violation, 0) + 1
elif isinstance(ev, QubitSent):
report.qubits_sent += 1
fidelities.append(ev.fidelity) # transmission fidelity (prepare-and-measure)
elif isinstance(ev, ClassicalMessage):
report.classical_msgs += 1
report.classical_bytes += ev.n_bytes
elif isinstance(ev, AppOutcomeEvent):
roles.append(
RoleResult(role=ev.role, node=ev.node, success=ev.success, utility=ev.utility)
)
duration = (max(times) - min(times)) if times else 0.0
report.sim_duration = duration
report.mean_fidelity = float(np.mean(fidelities)) if fidelities else 0.0
if duration > 0:
report.delivered_rate = report.n_delivered / duration
report.fidelity_throughput = float(np.sum(fidelities)) / duration
total_violations = sum(report.violations.values())
report.violation_rate = total_violations / report.n_delivered if report.n_delivered else 0.0
report.latency_mean = float(np.mean(latencies)) if latencies else 0.0
report.latency_p50 = _percentile(latencies, 50)
report.latency_p95 = _percentile(latencies, 95)
report.latency_p99 = _percentile(latencies, 99)
if report.n_delivered:
report.bytes_per_pair = report.classical_bytes / report.n_delivered
report.msgs_per_pair = report.classical_msgs / report.n_delivered
report.roles = roles
report.app_success = bool(roles) and all(r.success for r in roles)
report.app_utility = float(np.mean([r.utility for r in roles])) if roles else 0.0
return report
|
render
Source code in qnetbench/metrics/report.py
| def render(report: Report) -> str:
v = ", ".join(f"{k}={n}" for k, n in sorted(report.violations.items())) or "none"
return "\n".join(
[
f"app={report.app} backend={report.backend} "
f"arbitration={report.arbitration} seed={report.seed}",
f" app_success={report.app_success} app_utility={report.app_utility:.3f}",
f" pairs: requested={report.n_requests} delivered={report.n_delivered} "
f"rate={report.delivered_rate:.1f}/s mean_fidelity={report.mean_fidelity:.3f}",
f" fidelity_throughput={report.fidelity_throughput:.1f}/s "
f"violations: {v} violation_rate={report.violation_rate:.3f}",
f" latency(s): mean={report.latency_mean:.4f} p50={report.latency_p50:.4f} "
f"p95={report.latency_p95:.4f} p99={report.latency_p99:.4f}",
f" classical: msgs={report.classical_msgs} bytes={report.classical_bytes} "
f"bytes/pair={report.bytes_per_pair:.1f} msgs/pair={report.msgs_per_pair:.2f}",
]
)
|