microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
iadavis/pipeline-issue-debugging

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/pip/tests-integration/interop_qiskit/test_run_sim.py

170lines · modecode

1# Copyright (c) Microsoft Corporation.
2# Licensed under the MIT License.
3
4from concurrent.futures import ThreadPoolExecutor
5import pytest
6from qsharp import QSharpError, TargetProfile
7
8from interop_qiskit import QISKIT_AVAILABLE, SKIP_REASON
9
10if QISKIT_AVAILABLE:
11 from .test_circuits import (
12 generate_repro_information,
13 )
14 from qiskit.circuit import QuantumCircuit, Parameter
15 from qiskit_aer import AerSimulator
16 from qiskit.qasm3 import loads as from_qasm3
17 from qiskit.providers import JobStatus
18 from qiskit import ClassicalRegister
19 from qsharp.interop.qiskit import QSharpBackend
20 from .test_circuits import (
21 generate_repro_information,
22 )
23
24
25# Convert the circuit to QASM3 and back to a backend.
26# Then load the QASM3 and convert it back to a circuit.
27# This is to ensure that the QASM3 conversion is semantically correct.
28def round_trip_circuit(circuit, backend):
29 qasm = backend._qasm(circuit)
30 circuit = from_qasm3(qasm)
31 return circuit
32
33
34@pytest.mark.skipif(not QISKIT_AVAILABLE, reason=SKIP_REASON)
35def test_run_smoke() -> None:
36 circuit = QuantumCircuit(2, 2)
37 circuit.x(0)
38 circuit.cx(0, 1)
39 circuit.measure_all(add_bits=False)
40 backend = QSharpBackend()
41 res = backend.run(circuit, shots=1).result()
42 assert res is not None
43
44
45@pytest.mark.skipif(not QISKIT_AVAILABLE, reason=SKIP_REASON)
46def test_run_state_prep_smoke() -> None:
47 circuit = QuantumCircuit(1)
48 circuit.initialize([0.6, 0.8])
49 circuit.measure_all()
50 backend = QSharpBackend()
51 res = backend.run(circuit, shots=1).result()
52 assert res is not None
53
54
55@pytest.mark.skipif(not QISKIT_AVAILABLE, reason=SKIP_REASON)
56def test_get_counts_matches_qiskit_simulator():
57 target_profile = TargetProfile.Base
58 circuit = create_deterministic_test_circuit()
59 backend = QSharpBackend(target_profile=target_profile)
60
61 try:
62 circuit = round_trip_circuit(circuit, backend)
63
64 aersim = AerSimulator()
65 job = aersim.run(circuit, shots=5)
66 qsjob = backend.run(circuit, shots=5)
67 qscounts = qsjob.result().get_counts()
68 assert qscounts == job.result().get_counts()
69 except AssertionError:
70 raise
71 except Exception as ex:
72 additional_info = generate_repro_information(circuit, backend)
73 raise RuntimeError(additional_info) from ex
74
75
76@pytest.mark.skipif(not QISKIT_AVAILABLE, reason=SKIP_REASON)
77def create_deterministic_test_circuit():
78 cr0 = ClassicalRegister(2, "first")
79 cr1 = ClassicalRegister(3, "second")
80 circuit = QuantumCircuit(5)
81 circuit.add_register(cr0)
82 circuit.add_register(cr1)
83 circuit.x(0)
84 circuit.id(1)
85 circuit.id(2)
86 circuit.x(3)
87 circuit.x(4)
88 circuit.measure_all(add_bits=False)
89 return circuit
90
91
92@pytest.mark.skipif(not QISKIT_AVAILABLE, reason=SKIP_REASON)
93def test_execution_works_with_threadpool_set_on_backend():
94 target_profile = TargetProfile.Base
95 circuit = create_deterministic_test_circuit()
96 executor = ThreadPoolExecutor(max_workers=4)
97 backend = QSharpBackend(target_profile=target_profile, executor=executor, shots=5)
98
99 try:
100 job = backend.run(circuit)
101 qscounts = job.result().get_counts()
102 assert str(qscounts) == "{'110 01': 5}"
103 except AssertionError:
104 raise
105 except Exception as ex:
106 additional_info = generate_repro_information(circuit, backend)
107 raise RuntimeError(additional_info) from ex
108
109
110@pytest.mark.skipif(not QISKIT_AVAILABLE, reason=SKIP_REASON)
111def test_execution_works_with_threadpool_set_on_run():
112 target_profile = TargetProfile.Base
113 circuit = create_deterministic_test_circuit()
114
115 backend = QSharpBackend(target_profile=target_profile, shots=5)
116 try:
117 executor = ThreadPoolExecutor(max_workers=1)
118 job = backend.run(circuit, executor=executor)
119 qscounts = job.result().get_counts()
120 assert str(qscounts) == "{'110 01': 5}"
121 except AssertionError:
122 raise
123 except Exception as ex:
124 additional_info = generate_repro_information(circuit, backend)
125 raise RuntimeError(additional_info) from ex
126
127
128@pytest.mark.skipif(not QISKIT_AVAILABLE, reason=SKIP_REASON)
129def test_get_counts_matches_qiskit_simulator_multiple_circuits():
130 target_profile = TargetProfile.Base
131 circuit = create_deterministic_test_circuit()
132 circuit2 = create_deterministic_test_circuit()
133 backend = QSharpBackend(target_profile=target_profile)
134
135 try:
136 circuit = round_trip_circuit(circuit, backend)
137
138 aersim = AerSimulator()
139 job = aersim.run([circuit, circuit2], shots=5)
140 qsjob = backend.run([circuit, circuit2], shots=5)
141 qscounts = qsjob.result().get_counts()
142 assert qscounts == job.result().get_counts()
143 except AssertionError:
144 raise
145 except Exception as ex:
146 additional_info = generate_repro_information(circuit, backend)
147 raise RuntimeError(additional_info) from ex
148
149
150@pytest.mark.skipif(not QISKIT_AVAILABLE, reason=SKIP_REASON)
151def test_simulting_with_unbound_param_raises():
152 theta = Parameter("theta")
153
154 circuit = QuantumCircuit(1)
155 circuit.name = "test"
156 circuit.rx(theta, 0)
157 circuit.measure_all()
158
159 backend = QSharpBackend()
160 try:
161 with pytest.raises(QSharpError) as ex:
162 _ = backend.run(circuit).result()
163 message = str(ex.value)
164 assert "Circuit has unbound input parameters" in message
165 assert "help: Parameters: theta: Double" in message
166 except AssertionError:
167 raise
168 except Exception as ex:
169 additional_info = generate_repro_information(circuit, backend)
170 raise RuntimeError(additional_info) from ex