Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QIR submission generating incorrect results #550

Open
sjdilkes opened this issue Dec 3, 2024 · 1 comment
Open

QIR submission generating incorrect results #550

sjdilkes opened this issue Dec 3, 2024 · 1 comment
Assignees

Comments

@sjdilkes
Copy link
Contributor

sjdilkes commented Dec 3, 2024

This circuit is designed to detect for leakage errors on Qubit(0), writing 1 to leakage_detection_bit if leakage has occurred:

{'bits': [['experiment_bit', [0]], ['leakage_detection_bit', [0]]], 'commands': [{'args': [['q', [0]]], 'op': {'params': ['1', '0'], 'type': 'PhasedX'}}, {'args': [['q', [1]]], 'op': {'type': 'Reset'}}, {'args': [['q', [1]]], 'op': {'params': ['1', '0'], 'type': 'PhasedX'}}, {'args': [['q', [0]], ['q', [1]]], 'op': {'data': '', 'signature': ['Q', 'Q'], 'type': 'Barrier'}}, {'args': [['q', [1]]], 'op': {'params': ['1'], 'type': 'Rz'}}, {'args': [['q', [1]]], 'op': {'params': ['1/2', '1/2'], 'type': 'PhasedX'}}, {'args': [['q', [0]], ['q', [1]]], 'op': {'params': ['0.5'], 'type': 'ZZPhase'}}, {'args': [['q', [0]], ['q', [1]]], 'op': {'data': '', 'signature': ['Q', 'Q'], 'type': 'Barrier'}}, {'args': [['q', [0]], ['q', [1]]], 'op': {'params': ['0.5'], 'type': 'ZZPhase'}}, {'args': [['q', [0]], ['q', [1]]], 'op': {'data': '', 'signature': ['Q', 'Q'], 'type': 'Barrier'}}, {'args': [['q', [0]]], 'op': {'params': ['1'], 'type': 'Rz'}}, {'args': [['q', [1]]], 'op': {'params': ['1'], 'type': 'Rz'}}, {'args': [['q', [1]]], 'op': {'params': ['1/2', '1/2'], 'type': 'PhasedX'}}, {'args': [['q', [0]], ['q', [1]]], 'op': {'data': '', 'signature': ['Q', 'Q'], 'type': 'Barrier'}}, {'args': [['q', [0]], ['experiment_bit', [0]]], 'op': {'type': 'Measure'}}, {'args': [['q', [1]], ['leakage_detection_bit', [0]]], 'op': {'type': 'Measure'}}], 'created_qubits': [], 'discarded_qubits': [], 'implicit_permutation': [[['q', [0]], ['q', [0]]], [['q', [1]], ['q', [1]]]], 'phase': '0.5', 'qubits': [['q', [0]], ['q', [1]]]}

Running on "H1-1E", we expect little leakage. Submitting with Language.QASM has the expected behaviour, showing no/very few leaked results, while submitting with Language.QIR returns ~half leaked result, incorrect behaviour. We can see how much leakage has occurred by counting the number of shots that has leakage_detection_bit = 1.

@cqc-alec cqc-alec self-assigned this Dec 3, 2024
@cqc-alec
Copy link
Collaborator

cqc-alec commented Dec 3, 2024

This seems to be a problem with the QIR compiler or simulator at the other end. Here is a minimal test case:

from pytket.circuit import Bit, Circuit, Qubit
from pytket.extensions.quantinuum import Language, QuantinuumBackend

c = Circuit(2)
c.add_c_register("a", 1)
c.add_c_register("b", 1)

c.PhasedX(0.5, 0.5, 1)
c.Measure(Qubit(0), Bit("a", 0))
c.Measure(Qubit(1), Bit("b", 0))

b = QuantinuumBackend("H1-1E")

h = b.process_circuit(c, n_shots=100, language=Language.QIR)
r = b.get_result(h)
print(r.get_counts())

Unexpectedly we get a 50-50 split between (0,0) and (1,1) results.

The QIR we generate for this looks correct:

; ModuleID = 'circuit generated by pytket-qir'
source_filename = "circuit generated by pytket-qir"

%Qubit = type opaque
%Result = type opaque

@0 = internal constant [2 x i8] c"a\00"
@1 = internal constant [2 x i8] c"b\00"

define void @main() #0 {
entry:
  %0 = call i1* @create_creg(i64 1)
  %1 = call i1* @create_creg(i64 1)
  call void @mz_to_creg_bit(%Qubit* null, i1* %0, i64 0)
  call void @__quantum__qis__phasedx__body(double 0x3FF921FB54442D18, double 0x3FF921FB54442D18, %Qubit* inttoptr (i64 1 to %Qubit*))
  call void @mz_to_creg_bit(%Qubit* inttoptr (i64 1 to %Qubit*), i1* %1, i64 0)
  %2 = call i64 @get_int_from_creg(i1* %0)
  call void @__quantum__rt__int_record_output(i64 %2, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @0, i32 0, i32 0))
  %3 = call i64 @get_int_from_creg(i1* %1)
  call void @__quantum__rt__int_record_output(i64 %3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @1, i32 0, i32 0))
  ret void
}

declare i1 @__quantum__qis__read_result__body(%Result*)

declare void @__quantum__rt__int_record_output(i64, i8*)

declare i1 @get_creg_bit(i1*, i64)

declare void @set_creg_bit(i1*, i64, i1)

declare void @set_creg_to_int(i1*, i64)

declare i1* @create_creg(i64)

declare i64 @get_int_from_creg(i1*)

declare void @mz_to_creg_bit(%Qubit*, i1*, i64)

declare void @__quantum__qis__phasedx__body(double, double, %Qubit*)

attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="custom" "required_num_qubits"="2" "required_num_results"="2" }

!llvm.module.flags = !{!0, !1, !2, !3}

!0 = !{i32 1, !"qir_major_version", i32 1}
!1 = !{i32 7, !"qir_minor_version", i32 0}
!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
!3 = !{i32 1, !"dynamic_result_management", i1 false}

However, the results returned do not:

{'a': ['0', '0', '0', '1', '1', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '0', '0', '0', '1', '0', '1', '1', '1', '0', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '1', '1', '0', '1', '0', '0', '0', '0', '1', '0', '0', '1', '0', '0', '1', '1', '0', '0', '0', '0', '1', '1', '0', '1', '1', '0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '1', '0', '0', '0', '1', '1', '0', '0', '1', '0', '1', '1', '1', '1', '1', '0', '0', '1', '0', '0', '1'], 'b': ['0', '0', '0', '1', '1', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '0', '0', '0', '1', '0', '1', '1', '1', '0', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '1', '1', '0', '1', '0', '0', '0', '0', '1', '0', '0', '1', '0', '0', '1', '1', '0', '0', '0', '0', '1', '1', '0', '1', '1', '0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '1', '0', '0', '0', '1', '1', '0', '0', '1', '0', '1', '1', '1', '1', '1', '0', '0', '1', '0', '0', '1']}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants