@@ -91,337 +91,4 @@ def circuit():
9191 ```
9292 """
9393
94- # if isinstance(seed, int):
95- # kwargs.update({"seed_simulator": seed})
96-
9794 super ().__init__ (wires = wires , kwargs = kwargs , shots = shots )
98-
99- # self._handle_kwargs(**kwargs)
100-
101- # def _handle_kwargs(self, **kwargs):
102- # ### Extract Estimator/Sampler-specific options
103- # self._sampler_options = {
104- # k: v
105- # for k, v in kwargs.items()
106- # if k in (field.name for field in fields(SamplerOptions))
107- # }
108- # self._estimator_options = {
109- # k: v
110- # for k, v in kwargs.items()
111- # if k in (field.name for field in fields(EstimatorOptions))
112- # }
113- # [
114- # kwargs.pop(k)
115- # for k in (self._sampler_options.keys() | self._estimator_options.keys())
116- # ]
117-
118- # if len(kwargs) > 0:
119- # warnings.warn(
120- # f"The following keyword arguments are not supported by '{self.name}' device: {list(kwargs.keys())}",
121- # UserWarning,
122- # )
123-
124- # def _handle_kwargs(self, **kwargs):
125- # ### Extract runner-specific arguments
126- # self._run_options = {
127- # k: v
128- # for k, v in kwargs.items()
129- # if k in signature(self._platform.run).parameters.keys()
130- # }
131- # [kwargs.pop(k) for k in self._run_options.keys()]
132- # self._run_options.update(
133- # {
134- # "session_name": self._session_options.get("name"),
135- # "session_max_duration": self._session_options.get("max_duration"),
136- # "session_max_idle_duration": self._session_options.get(
137- # "max_idle_duration"
138- # ),
139- # }
140- # )
141-
142- # if len(kwargs) > 0:
143- # warnings.warn(
144- # f"The following keyword arguments are not supported by '{self.name}' device: {list(kwargs.keys())}",
145- # UserWarning,
146- # )
147-
148- # def preprocess(
149- # self,
150- # execution_config: ExecutionConfig | None = None,
151- # ) -> tuple[TransformProgram, ExecutionConfig]:
152- # transform_program, config = super().preprocess(execution_config)
153- # transform_program.add_transform(split_execution_types)
154- # return transform_program, config
155-
156- # def execute(
157- # self,
158- # circuits: QuantumScriptOrBatch,
159- # execution_config: ExecutionConfig | None = None,
160- # ) -> List:
161-
162- # if not self._session_id:
163- # raise RuntimeError(
164- # "No active session. Please instanciate the device using a context manager, or call start() first. You can also attach to an existing deduplication_id."
165- # )
166-
167- # if isinstance(circuits, QuantumScript):
168- # circuits = [circuits]
169-
170- # estimator_indices = []
171- # estimator_circuits = []
172- # sampler_circuits = []
173-
174- # for i, circuit in enumerate(circuits):
175- # if circuit.shots and len(circuit.shots.shot_vector) > 1:
176- # raise ValueError(
177- # f"Setting shot vector {circuit.shots.shot_vector} is not supported for {self.name}."
178- # "Please use a single integer instead when specifying the number of shots."
179- # )
180-
181- # if isinstance(
182- # circuit.measurements[0], (ExpectationMP, VarianceMP)
183- # ) and getattr(circuit.measurements[0].obs, "pauli_rep", None):
184- # estimator_indices.append(i)
185- # estimator_circuits.append(circuit)
186- # else:
187- # sampler_circuits.append(circuit)
188-
189- # if sampler_circuits:
190- # sampler_results = self._run_sampler(sampler_circuits)
191- # if estimator_circuits:
192- # estimator_results = self._run_estimator(estimator_circuits)
193- # results = []
194- # s, e = 0, 0
195-
196- # for i, circuit in enumerate(circuits):
197- # if i in estimator_indices:
198- # results.append(estimator_results[e])
199- # e += 1
200- # else:
201- # results.append(sampler_results[s])
202- # s += 1
203-
204- # return results
205-
206- # def _run_estimator(self, circuits: Iterable[QuantumScript]) -> List[Tuple]:
207- # qcircs = [
208- # circuit_to_qiskit(circuit, self.num_wires, diagonalize=False, measure=False)
209- # for circuit in circuits
210- # ]
211-
212- # estimator = Estimator(
213- # backend=self._platform,
214- # session_id=self._session_id,
215- # options=self._estimator_options,
216- # )
217-
218- # circ_and_obs = []
219- # for qcirc, circuit in zip(qcircs, circuits):
220- # pauli_observables = [self.mp_to_pauli(mp) for mp in circuit.measurements]
221- # compiled_observables = [
222- # op.apply_layout(qcirc.layout) for op in pauli_observables
223- # ]
224- # circ_and_obs.append((qcirc, compiled_observables))
225-
226- # precision = (
227- # np.sqrt(1 / circuits[0].shots.total_shots)
228- # if circuits[0].shots.total_shots
229- # else None
230- # )
231-
232- # @retry(stop=stop_after_attempt(3) | stop_after_delay(3 * 60), reraise=True)
233- # def run():
234- # return estimator.run(circ_and_obs, precision=precision).result()
235-
236- # results = run()
237-
238- # processed_results = []
239- # for i, circuit in enumerate(circuits):
240- # processed_result = self._process_estimator_job(
241- # circuit.measurements, results[i]
242- # )
243- # processed_results.append(processed_result)
244-
245- # return processed_results
246-
247- # def _run_sampler(self, circuits: Iterable[QuantumScript]) -> List[Tuple]:
248- # qcircs = [
249- # circuit_to_qiskit(circuit, self.num_wires, diagonalize=True, measure=True)
250- # for circuit in circuits
251- # ]
252-
253- # sampler = Sampler(self._platform, self._session_id, self._sampler_options)
254-
255- # @retry(stop=stop_after_attempt(3) | stop_after_delay(3 * 60), reraise=True)
256- # def run():
257- # return sampler.run(
258- # qcircs,
259- # shots=(
260- # circuits[0].shots.total_shots
261- # if circuits[0].shots.total_shots
262- # else None
263- # ),
264- # ).result()
265-
266- # results = run()
267-
268- # all_results = []
269-
270- # for original_circuit, qcirc, result in zip(circuits, qcircs, results):
271- # # Extract counts from the classical register
272- # # Assumes one classical register per circuit, which circuit_to_qiskit sets up
273- # c = getattr(result.data, qcirc.cregs[0].name)
274- # counts = c.get_counts()
275- # if not isinstance(counts, dict):
276- # # Handle cases where get_counts() might return a list
277- # counts = c.get_counts()[0]
278-
279- # # Reconstruct the list of samples from the counts dictionary
280- # samples_list = []
281- # for key, value in counts.items():
282- # samples_list.extend([key] * value)
283-
284- # if not samples_list:
285- # # Handle case with no samples (e.g., 0 shots)
286- # # Create an empty array with the correct number of columns
287- # num_clbits = len(qcirc.clbits)
288- # samples = np.empty((0, num_clbits), dtype=int)
289- # else:
290- # # Convert bitstrings to numpy array of ints, reversing for convention
291- # samples = np.vstack(
292- # [np.array([int(i) for i in s[::-1]]) for s in samples_list]
293- # )
294-
295- # # Process the samples according to the measurements in the original circuit
296- # res = [
297- # mp.process_samples(samples, wire_order=self.wires)
298- # for mp in original_circuit.measurements
299- # ]
300-
301- # # Format the final result tuple for this circuit
302- # single_measurement = len(original_circuit.measurements) == 1
303- # res_tuple = (res[0],) if single_measurement else tuple(res)
304- # all_results.append(res_tuple)
305-
306- # return all_results
307-
308- # @staticmethod
309- # def _process_estimator_job(
310- # measurements: List[MeasurementProcess], job_result: PrimitiveResult[PubResult]
311- # ):
312- # expvals = job_result.data.evs
313- # variances = (
314- # job_result.data.stds / job_result.metadata["target_precision"]
315- # ) ** 2
316-
317- # result = []
318- # for i, mp in enumerate(measurements):
319- # if isinstance(mp, ExpectationMP):
320- # result.append(expvals[i])
321- # elif isinstance(mp, VarianceMP):
322- # result.append(variances[i])
323-
324- # single_measurement = len(measurements) == 1
325- # result = (result[0],) if single_measurement else tuple(result)
326-
327- # return result
328-
329- # def mp_to_pauli(self, mp):
330- # """Convert a Pauli observable to a SparsePauliOp for measurement via Estimator
331-
332- # Args:
333- # mp(Union[ExpectationMP, VarianceMP]): MeasurementProcess to be converted to a SparsePauliOp
334-
335- # Returns:
336- # SparsePauliOp: the ``SparsePauliOp`` of the given Pauli observable
337- # """
338- # op = mp.obs
339-
340- # if op.pauli_rep:
341- # pauli_strings = [
342- # "".join(
343- # [
344- # "I" if i not in pauli_term.wires else pauli_term[i]
345- # for i in range(self.num_wires)
346- # ][
347- # ::-1
348- # ] ## Qiskit follows opposite wire order convention
349- # )
350- # for pauli_term in op.pauli_rep.keys()
351- # ]
352- # coeffs = list(op.pauli_rep.values())
353- # else:
354- # raise ValueError(
355- # f"The operator {op} does not have a representation for SparsePauliOp"
356- # )
357-
358- # return SparsePauliOp(data=pauli_strings, coeffs=coeffs).simplify()
359-
360-
361- # @transform
362- # def split_execution_types(
363- # tape: qml.tape.QuantumTape,
364- # ) -> tuple[Sequence[qml.tape.QuantumTape], Callable]:
365- # """Split into separate tapes based on measurement type. Counts and sample-based measurements
366- # will use the Qiskit Sampler. ExpectationValue and Variance will use the Estimator, except
367- # when the measured observable does not have a `pauli_rep`. In that case, the Sampler will be
368- # used, and the raw samples will be processed to give an expectation value."""
369- # estimator = []
370- # sampler = []
371-
372- # for i, mp in enumerate(tape.measurements):
373- # if isinstance(mp, (ExpectationMP, VarianceMP)):
374- # if mp.obs.pauli_rep:
375- # estimator.append((mp, i))
376- # else:
377- # warnings.warn(
378- # f"The observable measured {mp.obs} does not have a `pauli_rep` "
379- # "and will be run without using the Estimator primitive. Instead, "
380- # "raw samples from the Sampler will be used."
381- # )
382- # sampler.append((mp, i))
383- # else:
384- # sampler.append((mp, i))
385-
386- # order_indices = [[i for mp, i in group] for group in [estimator, sampler]]
387-
388- # tapes = []
389- # if estimator:
390- # tapes.extend(
391- # [
392- # qml.tape.QuantumScript(
393- # tape.operations,
394- # measurements=[mp for mp, i in estimator],
395- # shots=tape.shots,
396- # )
397- # ]
398- # )
399- # if sampler:
400- # tapes.extend(
401- # [
402- # qml.tape.QuantumScript(
403- # tape.operations,
404- # measurements=[mp for mp, i in sampler],
405- # shots=tape.shots,
406- # )
407- # ]
408- # )
409-
410- # def reorder_fn(res):
411- # """re-order the output to the original shape and order"""
412-
413- # flattened_indices = [i for group in order_indices for i in group]
414- # flattened_results = [r for group in res for r in group]
415-
416- # if len(flattened_indices) != len(flattened_results):
417- # raise ValueError(
418- # "The lengths of flattened_indices and flattened_results do not match."
419- # ) # pragma: no cover
420-
421- # result = dict(zip(flattened_indices, flattened_results))
422-
423- # result = tuple(result[i] for i in sorted(result.keys()))
424-
425- # return result[0] if len(result) == 1 else result
426-
427- # return tapes, reorder_fn
0 commit comments