diff --git a/qiskit_ibm_transpiler/utils.py b/qiskit_ibm_transpiler/utils.py index e334aa9..360a36d 100644 --- a/qiskit_ibm_transpiler/utils.py +++ b/qiskit_ibm_transpiler/utils.py @@ -37,6 +37,7 @@ from qiskit import QuantumCircuit, qasm2, qasm3, qpy from qiskit.circuit.library import LinearFunction +from qiskit.qpy import common from qiskit.quantum_info import Clifford from qiskit.synthesis.linear.linear_matrix_utils import random_invertible_binary_matrix from qiskit.circuit import QuantumCircuit, library @@ -44,6 +45,11 @@ logger = logging.getLogger(__name__) +QPY_QISKIT_VERSION_MAPPING = { + "1.3.0": 13, + "1.2.4": 12, +} + def get_metrics(qc: QuantumCircuit) -> Dict[str, int]: """Returns a dict with metrics from a QuantumCircuit""" @@ -232,11 +238,16 @@ def check_topology_synthesized_circuit( def get_qpy_from_circuit( - input_circ: Union[QuantumCircuit, List[QuantumCircuit]] + input_circ: Union[QuantumCircuit, List[QuantumCircuit]], + qiskit_version: Union[str, None] = None, ) -> str: if isinstance(input_circ, QuantumCircuit) or isinstance(input_circ, list): output_b = io.BytesIO() - qpy.dump(input_circ, output_b) + qpy.dump( + input_circ, + output_b, + version=QPY_QISKIT_VERSION_MAPPING.get(qiskit_version, common.QPY_VERSION), + ) qpy_string = base64.b64encode(output_b.getvalue()).decode("utf-8") else: raise TypeError( @@ -255,11 +266,12 @@ def get_circuits_from_qpy(qpy_string: str) -> List[QuantumCircuit]: def serialize_circuit_to_qpy_or_qasm( input_circuit: QuantumCircuit, + qiskit_version: Union[str, None] = None, ) -> Tuple[Union[str, None], Union[str, None]]: qpy_result = None qasm_result = None try: - qpy_result = get_qpy_from_circuit(input_circuit) + qpy_result = get_qpy_from_circuit(input_circuit, qiskit_version) except struct.error: qasm_result = input_to_qasm(input_circuit).replace("\n", " ") @@ -267,12 +279,12 @@ def serialize_circuit_to_qpy_or_qasm( def serialize_circuits_to_qpy_or_qasm( - input_circuits: List[QuantumCircuit], + input_circuits: List[QuantumCircuit], qiskit_version: Union[str, None] = None ) -> Tuple[Union[str, None], Union[List[str], None]]: qpy_result = None qasm_result = None try: - qpy_result = get_qpy_from_circuit(input_circuits) + qpy_result = get_qpy_from_circuit(input_circuits, qiskit_version) except struct.error: qasm_result = [ input_to_qasm(the_circ).replace("\n", " ") for the_circ in input_circuits diff --git a/qiskit_ibm_transpiler/wrappers/ai_api_routing.py b/qiskit_ibm_transpiler/wrappers/ai_api_routing.py index f40d112..821dd84 100644 --- a/qiskit_ibm_transpiler/wrappers/ai_api_routing.py +++ b/qiskit_ibm_transpiler/wrappers/ai_api_routing.py @@ -43,7 +43,7 @@ def routing( OptimizationOptions, List[OptimizationOptions], None ] = None, ): - qpy, qasm = serialize_circuit_to_qpy_or_qasm(circuit) + qpy, qasm = serialize_circuit_to_qpy_or_qasm(circuit, self.get_qiskit_version()) body_params = { "qasm": qasm, "qpy": qpy, diff --git a/qiskit_ibm_transpiler/wrappers/ai_api_synthesis.py b/qiskit_ibm_transpiler/wrappers/ai_api_synthesis.py index ef52ddc..bb1746e 100644 --- a/qiskit_ibm_transpiler/wrappers/ai_api_synthesis.py +++ b/qiskit_ibm_transpiler/wrappers/ai_api_synthesis.py @@ -224,7 +224,9 @@ def transpile( # backend is not used yet, but probably it will replace backend_name backend: Union[Backend, None] = None, ): - qpy, qasm = serialize_circuits_to_qpy_or_qasm(circuits) + qpy, qasm = serialize_circuits_to_qpy_or_qasm( + circuits, self.get_qiskit_version() + ) if coupling_map is not None: logger.info("Running synthesis against the Qiskit Transpiler Service") transpile_resps = self.request_and_wait( diff --git a/qiskit_ibm_transpiler/wrappers/base.py b/qiskit_ibm_transpiler/wrappers/base.py index ca0a5c9..aae401f 100644 --- a/qiskit_ibm_transpiler/wrappers/base.py +++ b/qiskit_ibm_transpiler/wrappers/base.py @@ -101,6 +101,13 @@ def get_versions(self): return resp + def get_qiskit_version(self): + try: + return self.get_versions().get("qiskit") + except Exception as exc: + logger.warning(f"Exception requesting qiskit version: {exc}") + return None + def get_supported_backends(self): url = f"{self.url}/backends" resp = requests.get( diff --git a/qiskit_ibm_transpiler/wrappers/transpile.py b/qiskit_ibm_transpiler/wrappers/transpile.py index 76e63e4..bc227a1 100644 --- a/qiskit_ibm_transpiler/wrappers/transpile.py +++ b/qiskit_ibm_transpiler/wrappers/transpile.py @@ -56,7 +56,9 @@ def transpile( use_fractional_gates: bool = False, ): circuits = [circuits] if isinstance(circuits, QuantumCircuit) else circuits - qpy_circuits, qasm_circuits = serialize_circuits_to_qpy_or_qasm(circuits) + qpy_circuits, qasm_circuits = serialize_circuits_to_qpy_or_qasm( + circuits, self.get_qiskit_version() + ) body_params = { "qasm_circuits": qasm_circuits, diff --git a/release-notes/unreleased/136.bug.rst b/release-notes/unreleased/136.bug.rst new file mode 100644 index 0000000..f22ee6b --- /dev/null +++ b/release-notes/unreleased/136.bug.rst @@ -0,0 +1 @@ +Align QPY version with service.