|
11 | 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | | -import numpy as np |
15 | | -import warnings |
16 | 14 |
|
17 | 15 | from inspect import signature |
18 | | -from typing import Callable, List, Sequence, Tuple, Union |
19 | | -from tenacity import retry, stop_after_attempt, stop_after_delay |
| 16 | +from typing import Callable, Sequence, Tuple |
| 17 | +import warnings |
20 | 18 |
|
21 | 19 | from pennylane.devices import ExecutionConfig |
22 | 20 | from pennylane.devices.modifiers import simulator_tracking, single_tape_support |
23 | | - |
24 | | -from pennylane.tape import QuantumScriptOrBatch, QuantumScript, QuantumTape |
| 21 | +from pennylane.tape import QuantumTape |
25 | 22 | from pennylane.transforms import transform |
26 | 23 | from pennylane.transforms.core import TransformProgram |
27 | 24 |
|
28 | | -from qiskit.result import Result |
29 | | - |
30 | 25 | from qiskit_scaleway.backends import AqtBackend, AerBackend |
31 | 26 |
|
32 | | -from pennylane_scaleway.utils import ( |
33 | | - circuit_to_qiskit, |
34 | | -) |
35 | 27 | from pennylane_scaleway.scw_device import ScalewayDevice |
36 | 28 |
|
37 | 29 |
|
@@ -69,14 +61,13 @@ def processing_fn(results: Sequence) -> any: |
69 | 61 | @single_tape_support # add support for device.execute(tape) in addition to device.execute((tape,)) |
70 | 62 | class AqtDevice(ScalewayDevice): |
71 | 63 | """ |
72 | | - This is Scaleway's AQT device. |
73 | | - It allows to run quantum circuits on Scaleway's AQT emulation backends. |
| 64 | + Scaleway's device to run Pennylane circuits on AQT platforms. |
74 | 65 |
|
75 | 66 | This device: |
76 | | - * Follows the same constraints as AerDevice, as it uses qiskit as a common interface with AQT emulators. |
77 | | - * Has 12 wires available. |
| 67 | + * Has 12 qubits available. |
78 | 68 | * Supports up to 2000 shots maximum. |
79 | | - * Does not support more than 2000 operations AFTER decomposition, due to hardware limitation. This translates to roughly 12 wires and ~20 layers deep for a pennylane circuit. |
| 69 | + * Does not support more than 2000 operations AFTER decomposition, due to hardware limitation. This translates to roughly 12 qubits and ~20 layers deep for a pennylane circuit. |
| 70 | + * Follows the same constraints as AerDevice, as it uses qiskit as a common interface with AQT emulators. |
80 | 71 | """ |
81 | 72 |
|
82 | 73 | name = "scaleway.aqt" |
@@ -156,11 +147,6 @@ def circuit(): |
156 | 147 | """ |
157 | 148 |
|
158 | 149 | super().__init__(wires=wires, kwargs=kwargs, shots=shots, seed=seed) |
159 | | - |
160 | | - self._default_shots = None |
161 | | - if isinstance(shots, int): |
162 | | - self._default_shots = shots |
163 | | - |
164 | 150 | self._handle_kwargs(**kwargs) |
165 | 151 |
|
166 | 152 | def _handle_kwargs(self, **kwargs): |
@@ -196,77 +182,3 @@ def preprocess( |
196 | 182 | limit_aqt_shots, default_shots=self._default_shots |
197 | 183 | ) |
198 | 184 | return transform_program, config |
199 | | - |
200 | | - def execute( |
201 | | - self, |
202 | | - circuits: QuantumScriptOrBatch, |
203 | | - execution_config: ExecutionConfig | None = None, |
204 | | - ) -> List: |
205 | | - if not self._session_id: |
206 | | - raise RuntimeError( |
207 | | - "No active session. Please instanciate the device using a context manager, or call start() first. You can also attach to an existing deduplication_id." |
208 | | - ) |
209 | | - |
210 | | - if isinstance(circuits, QuantumScript): |
211 | | - circuits = [circuits] |
212 | | - |
213 | | - qiskit_circuits = [] |
214 | | - for circuit in circuits: |
215 | | - qiskit_circuits.append( |
216 | | - circuit_to_qiskit( |
217 | | - circuit, self.num_wires, diagonalize=True, measure=True |
218 | | - ) |
219 | | - ) |
220 | | - |
221 | | - shots = self._default_shots |
222 | | - if circuits[0].shots and circuits[0].shots.total_shots: |
223 | | - shots = circuits[0].shots.total_shots |
224 | | - |
225 | | - @retry(stop=stop_after_attempt(3) | stop_after_delay(3 * 60), reraise=True) |
226 | | - def run() -> Union[Result, List[Result]]: |
227 | | - return self._platform.run( |
228 | | - qiskit_circuits, |
229 | | - session_id=self._session_id, |
230 | | - shots=shots, |
231 | | - **self._run_options, |
232 | | - ).result() |
233 | | - |
234 | | - results = run() |
235 | | - if isinstance(results, Result): |
236 | | - results = [results] |
237 | | - |
238 | | - counts = [] |
239 | | - for result in results: |
240 | | - if isinstance(result.get_counts(), dict): |
241 | | - counts.append(result.get_counts()) |
242 | | - else: |
243 | | - counts.extend([count for count in result.get_counts()]) |
244 | | - |
245 | | - all_results = [] |
246 | | - for original_circuit, qcirc, count in zip(circuits, qiskit_circuits, counts): |
247 | | - # Reconstruct the list of samples from the counts dictionary |
248 | | - samples_list = [] |
249 | | - for key, value in count.items(): |
250 | | - samples_list.extend([key] * value) |
251 | | - |
252 | | - if not samples_list: |
253 | | - # Handle case with no samples (e.g., 0 shots) |
254 | | - num_clbits = len(qcirc.clbits) |
255 | | - samples = np.empty((0, num_clbits), dtype=int) |
256 | | - else: |
257 | | - # Convert bitstrings to numpy array of ints, reversing for convention |
258 | | - samples = np.vstack( |
259 | | - [np.array([int(i) for i in s[::-1]]) for s in samples_list] |
260 | | - ) |
261 | | - |
262 | | - # Process the samples according to the measurements in the original circuit |
263 | | - res = [ |
264 | | - mp.process_samples(samples, wire_order=self.wires) |
265 | | - for mp in original_circuit.measurements |
266 | | - ] |
267 | | - |
268 | | - single_measurement = len(original_circuit.measurements) == 1 |
269 | | - res_tuple = res[0] if single_measurement else tuple(res) |
270 | | - all_results.append(res_tuple) |
271 | | - |
272 | | - return all_results |
0 commit comments