Changelog

All notable changes to QUASAR (quasar and its compiled backend quasarcpp). The format follows Keep a Changelog. Entries say what changed for a user; Breaking marks a change that needs user code to change.

[0.9.0]

Added

  • State preparation. GateCompiler.compile_state(target, initial_state=None) compiles a circuit that prepares one target state. compile(circuit, initial_state=...) compiles a circuit for one known start state. Both are usually much shallower than a compile of the full unitary. state_preparation_error gives the error of such a circuit.

  • Pauli readout. A trailing PauliProductMeasurement asks for one or several Pauli strings to be read. The compiled circuit ends with the native readout, and metadata["pauli_readout_products"] maps each delivered string to the requested one. Helpers: append_pauli_readout, remove_pauli_readouts, GateSet.pauli_readouts_native and GateCompiler.build_pauli_readout_circuit.

  • Resets. A reset compiles to the device’s own initialization. Every star gate set takes spam_qubits, the qubits the device resets and reads out together, (0,) by default. Helpers: GateSet.lower_resets and GateSet.reset_circuit.

  • Qiskit order. Every Pauli string QUASAR takes or returns is in Qiskit’s order: its last letter is qubit 0.

  • XeedQ. XeedQBackend.from_cloud_backend reads the calibration of an XeedQ device and compiles FixedCROTGateSet circuits into pulse programs. to_xeedq_circuit and from_xeedq_circuit translate a compiled circuit to and from the XeedQ toolchain’s gate names.

  • Gate errors and durations on the gate set. Every gate set takes single_qubit_gate_error, entangler_gate_error, gate_errors, the matching durations and reserved_qubits_by_gate. with_properties returns a copy with new values. GateCompiler.estimate_errors returns the compilation, physical and overall error of a compiled circuit, as an ErrorEstimate.

  • Layout search. layout_method="diagonal_search" uses one mapping for the input and the output. layout_objective ranks the candidates by "gate_count", "error" or "duration", and metadata["duration"] holds the duration of the result.

  • Rotation rounding. Angles close to 0, and on FixedCROTGateSet close to π/2, are rounded where the result stays within the tolerance. round_single_qubit_rotations names the angles, and () turns rounding off.

  • Error-aware search. The error-aware strategies trade circuit depth against the gate errors. PlateauWarning and plot_error_aware_history report the search.

  • Search settings on every synthesis config: global_search, n_trials_warm, n_trials_cold, warm_start_from_level and refine_best_trial.

  • PulseCompiler.compile warns with LayoutWarning when a circuit carries a qubit relabeling that its pulses do not.

  • quasar.__version__. At import, quasar checks that the installed quasarcpp is the version it was released with.

  • ConvergenceError, ErrorEstimate, LayoutWarning, LicenseError and PlateauWarning are exported from the package root.

  • The plot extra installs what plot_error_aware_history and the tutorials’ drawings need.

  • New tutorials: Qubit Layout and State Preparation and Pauli Readout. The other four tutorials cover the error model.

Changed

  • Breaking. Gate errors come from the gate set. The configs take no error arguments (layer_error).

  • Breaking. Error-aware searches decide by one overall error, which combines the compilation error with the gate errors. No config takes a cost_function.

  • Breaking. metadata["error_aware"] names its errors compilation_error (was decomposition_error), physical_error (was estimated_gate_error) and overall_error (new).

  • Breaking. layout_objective exists only on AdaptiveConfig and TreeSearchConfig. An error-aware config always minimizes the overall error.

  • Breaking. Config names and values: QiskitConfig.seed_transpiler → seed; use_basin_hopping (a number) → global_search (a name); parallel_mode and verbosity take names instead of numbers.

  • Breaking. A synthesis that misses tolerance_error raises ConvergenceError instead of BackendError.

  • Breaking. Pauli readouts: append_pauli_measurement → append_pauli_readout, and remove_pauli_measurement → remove_pauli_readouts, which returns a list of strings. GateCompiler.build_pauli_readout_circuit(pauli_readout, compiled) takes no suffix_permutation.

  • Breaking. A gate set describes its topology by placements (qubit tuples) instead of pairs. EdgeEntanglerGateSet is renamed EntanglerGateSet. TwoQubitNativeGate and SynthesisDescription are no longer part of the documented API.

  • Breaking. CNOTGateSet and CRXGateSet lower single-qubit gates to rz and rx instead of rz and r.

  • Breaking. No gate set has an id gate. GateCompiler.compile drops an id or a delay from its input. In a native circuit given to PulseCompiler, an id plays nothing and a delay raises ValidationError.

  • Breaking. Pulse parameters: one PulseParameters record per device, with DriveParameters, NuclearParameters, DriveStrength and DeviceParameters. A backend is built from it: SimphonyBackend(model, parameters=None), XeedQBackend(parameters). .config and default_config() become .parameters, and pulse_recipe(gate) becomes pulse_template(gate, gateset).

  • AdaptiveConfig.level_min defaults to 0, so a target that needs no entangler gets none.

  • Error-aware configs return at least one entangler by default (level_min / layer_min = 1).

  • Every strategy runs a cold trial by default, and searches to depth 25 instead of 20 (level_max / layer_max).

  • compress defaults to None: the gate set decides, and every gate set of this package compresses.

  • The tolerance is an average gate infidelity, and a state infidelity for a state target.

  • With a seed, a compile returns the same circuit on every run, also when the backend runs on several threads. A seed is a non-negative Python or NumPy integer.

  • A frame change (rz) reserves no qubit when a duration is scheduled.

  • quasar needs NumPy 2 or later, and no longer installs qiskit-aer.

  • The simphony-backend extra installs simphony v0.2.1.

  • The macOS wheels install on macOS 15 and later.

Removed

  • SimphonyConfig, XeedQConfig, SingleQubitDrive, ConditionalTransition and EntanglerCalibration. PulseParameters replaces them.

  • ErrorAwareTreeSearchConfig.scouting_trials. n_trials_warm and n_trials_cold replace it.

  • FixedCROTGateSet.rotation_ansatz_layer_errors.

  • GateSet.readable_qubits. spam_qubits names the qubits the device reads, and pauli_readouts_native() the Pauli strings it reads directly.

Fixed

  • layout_method="full_search" ranked every candidate the same, so it kept the first mapping it tried.

  • Wrong arguments to the compiled backend raise a Python exception instead of ending the process.

  • Three cases where the compiled backend could crash.

  • cu’s fourth parameter survives conversion.

  • compilation_error, estimate_errors, state_preparation_error and compile(..., initial_state=...) raise ValidationError for a circuit that holds a Pauli readout, a reset or a measurement.

  • A state whose norm is not 1 raises ValidationError.

  • A delay compiled on the Qiskit path raised Qiskit’s QiskitError on every gate set but CROTGateSet.

  • An rx or r rotation within rounding of zero is dropped, and plays no pulse.

  • append_pauli_readout refuses an all-I string and an unknown letter with ValidationError. FixedCROTGateSet.rotation_ansatz does the same for an unknown edge.

  • A negative level_min, layer_max or tolerance_error, and an optimization_level outside 0 to 3, raise ConfigError on every config.

[0.5.1]

Added

  • FixedCROTGateSet chooses the rotation each layer and the closing layer put on a qubit.

Changed

  • A u gate lowers to the fewest sx its angle allows.

[0.5.0]

First public release: gate-level compilation for star-topology central-spin devices (CROTGateSet, FixedCROTGateSet, CNOTGateSet, CRXGateSet); adaptive, tree-search and error-aware synthesis strategies; boundary-permutation layout search; the Qiskit-transpiler path; pulse-level compilation through Simphony and XeedQ; licence-checked compiled backend.