Added gpu__time_duration.sum to the Nsight Compute memory preset, so the full preset inherits measured kernel duration without relying on PC-sampling metrics that are gated on Blackwell.
derive_ncu_run_summary() now aggregates total_kernel_duration_us and kernels_with_duration_data across parsed kernels.
diff_ncu_runs now emits a kernel_time block with availability, baseline_us, optimized_us, and speedup_x.
Added the shipped frx_bench_harness.cuh cudaEvent harness. Users can wrap a kernel launch in frx_bench([&]{ ... }) and emit FRX_KERNEL_US without running Nsight Compute.
frx bench --emit-harness now writes the reusable harness, and the wheel includes the header so a bare #include "frx_bench_harness.cuh" works.
Added P0a and P0b regression coverage: NCU comparison, preset gating, run-summary analysis, bench/report behavior, and cudaEvent harness parsing. The suite reached 913 passing tests, with only pre-existing environment gaps remaining.
Compare verdicts now use kernel GPU time when available, apply a 0.95-1.05 neutral noise band, tag their basis as kernel_gpu_time or bottleneck_diff, and keep bottleneck_outcome visible when the signals disagree.
frx bench now times compile per side, records compile_ms, and sets primary_speedup_x plus primary_speedup_basis from cudaEvent timing, NCU kernel duration, or wall clock in that priority order.
CLI bench reports now show compile time, process wall time, and kernel GPU time separately, including a note when kernel speedup is at least 1.10x but wall time stays within 0.9-1.1x because host overhead or CUDA initialization dominates.
Reports now state the NCU honesty caveat inline: absolute kernel duration is profiler-inflated because NCU serializes kernels, but same-tax before/after ratios remain useful.
The verdict now surfaces the kernel-time versus bottleneck-diff gap as a diagnostic signal, so cases like bottleneck resolved but kernel time flat are visible instead of one signal silently winning.
Verified the 02 matmul demo remains fair and measures 1.36x faster with cudaEvent timing.
Reframed the 04 register demo as an honest static-detection example because the current scale is memory-bound and the lower-register version measures 0.70x instead of a real speedup.
cudaEvent timing fails safe by withholding FRX_KERNEL_US on CUDA errors instead of reporting a misleading kernel duration.
Fixed the 01 uncoalesced demo to compare equal work. The optimized version now measures 3.07x faster with uncoalesced_access resolved.
Adjusted the 01 static signal fixture so the column-major subscript multiply uses the width stride keyword, preserving the intended uncoalesced_access finding.
Fixed the 03 excess_sync demo illegal memory access. It now runs clean and measures 2.19x faster.