@@ -378,31 +378,56 @@ def _input_basis_gates(circuit: QuantumCircuit) -> list[str]:
378378
379379
380380def _translate_to_basis (circuit : QuantumCircuit , basis_gates : list [str ]) -> QuantumCircuit :
381- """Re-express ``circuit`` in ``basis_gates`` via basis translation only.
382-
383- No coupling map or target is supplied, so this performs a local gate-set
384- translation without any routing or relayout -- qubit placement (and any ISA
385- layout) is preserved. Registers and measurements pass through unchanged.
381+ """Re-express ``circuit`` in ``basis_gates`` while **preserving gate order**.
382+
383+ Running ``BasisTranslator`` on the whole circuit round-trips through a DAG and
384+ re-emits gates in a topological order that reshuffles independent (parallel)
385+ gates -- which would smear the entangling-layer structure the check picker
386+ carefully preserved. Instead each instruction is translated on its own and
387+ appended in the circuit's original order, so that structure survives. No
388+ coupling map or target is supplied, so there is no routing or relayout; qubit
389+ placement (and any ISA layout) is preserved, and measurements pass through.
386390 """
387391 pm = PassManager (
388392 [
389393 UnrollCustomDefinitions (_SEL , basis_gates ),
390394 BasisTranslator (_SEL , basis_gates ),
391395 ]
392396 )
393- try :
394- return pm .run (circuit )
395- except TranspilerError :
396- # The input basis can't express the checks the picker inserted -- it is
397- # not universal (e.g. {h, cx}, with no phase gate, as for a virtual GHZ).
398- # Leave the circuit in the package's internal Clifford basis.
399- warnings .warn (
400- f"Could not re-express the output in the input gate set { sorted (basis_gates )} ; "
401- "it is not universal for the inserted checks. Returning the circuit in the "
402- "internal Clifford basis instead." ,
403- stacklevel = 2 ,
404- )
405- return circuit
397+ keep = set (basis_gates ) | {"measure" , "barrier" }
398+ # Translate each unique gate once (Clifford gates carry no parameters, so the name
399+ # is a complete key); ``None`` marks a gate the basis cannot express.
400+ translated_block : dict [str , QuantumCircuit | None ] = {}
401+ out = circuit .copy_empty_like ()
402+ for instruction in circuit .data :
403+ op = instruction .operation
404+ if op .name in keep :
405+ out .append (instruction )
406+ continue
407+ if op .name not in translated_block :
408+ block = QuantumCircuit (op .num_qubits )
409+ block .append (op , range (op .num_qubits ))
410+ try :
411+ translated_block [op .name ] = pm .run (block )
412+ except TranspilerError :
413+ translated_block [op .name ] = None
414+ block = translated_block [op .name ]
415+ if block is None :
416+ # The input basis can't express the checks the picker inserted -- it is not
417+ # universal (e.g. {h, cx}, with no phase gate, as for a virtual GHZ). Leave
418+ # the circuit in the package's internal Clifford basis (already order-preserved).
419+ warnings .warn (
420+ f"Could not re-express the output in the input gate set { sorted (basis_gates )} ; "
421+ "it is not universal for the inserted checks. Returning the circuit in the "
422+ "internal Clifford basis instead." ,
423+ stacklevel = 2 ,
424+ )
425+ return circuit
426+ for sub in block .data :
427+ out .append (
428+ sub .operation , [instruction .qubits [block .find_bit (q ).index ] for q in sub .qubits ]
429+ )
430+ return out
406431
407432
408433def _strip_measurements_cregs_barriers (circuit : QuantumCircuit ):
0 commit comments