From cd104b55fdeb879585b83c2540422a8598fe2029 Mon Sep 17 00:00:00 2001 From: Bharath Date: Thu, 29 Aug 2024 17:55:04 -0500 Subject: [PATCH 01/13] add support for qubit type validation --- cirq-superstaq/cirq_superstaq/validation.py | 43 ++++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index 5a0e14d35..d47836fbe 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -4,10 +4,46 @@ import cirq +SUPPORTED_QID_TYPES = ( + cirq.LineQubit, + cirq.LineQid, + cirq.GridQubit, + cirq.GridQid, + cirq.NamedQubit, + cirq.NamedQid, +) + + +def validate_qubit_types(circuits: object) -> None: + """Verifies that `circuit` consists of valid qubit types only. + + Args: + circuits: The input circuits to validate. + + Raises: + TypeError: If an invalid qubit type is found in `circuit`. + """ + circuits_to_check = [circuits] if isinstance(circuits, cirq.Circuit) else circuits + assert isinstance(circuits_to_check, Sequence) + + all_qubits_present: set[cirq.Qid] = set() + for circuit in circuits_to_check: + all_qubits_present.update(circuit.all_qubits()) + + if not all(isinstance(q, SUPPORTED_QID_TYPES) for q in all_qubits_present): + raise TypeError( + "Input circuit(s) contain unsupported qubit types. Valid qubit types are: " + "`cirq.LineQubit`, `cirq.LineQid`, `cirq.GridQubit`, `cirq.GridQid`, " + "`cirq.NamedQubit`, and `cirq.NamedQid`." + ) + def validate_cirq_circuits(circuits: object, require_measurements: bool = False) -> None: - """Validates that the input is either a single `cirq.Circuit` or a list of `cirq.Circuit` - instances. + """Validates that the input is an acceptable `cirq` object for `cirq-superstaq`. + + In particular, this function verfies that `circuits` is either a single `cirq.Circuit` + or a list of `cirq.Circuit` instances. Additionally, also validates that `circuits` only + contains valid qubit types. Args: circuits: The circuit(s) to run. @@ -16,6 +52,7 @@ def validate_cirq_circuits(circuits: object, require_measurements: bool = False) Raises: ValueError: If the input is not a `cirq.Circuit` or a list of `cirq.Circuit` instances. + TypeError: If an invalid qubit type is found in `circuits`. """ if not ( @@ -37,3 +74,5 @@ def validate_cirq_circuits(circuits: object, require_measurements: bool = False) # TODO: only raise if the run method actually requires samples (and not for e.g. a # statevector simulation) raise ValueError("Circuit has no measurements to sample.") + + validate_qubit_types(circuits) From 265794c96e267aabe55d94927af9ba1573061097 Mon Sep 17 00:00:00 2001 From: Bharath Date: Thu, 29 Aug 2024 17:55:19 -0500 Subject: [PATCH 02/13] test for invalid qubit type --- .../cirq_superstaq/validation_test.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cirq-superstaq/cirq_superstaq/validation_test.py b/cirq-superstaq/cirq_superstaq/validation_test.py index 9ada51bb2..8f520f4c0 100644 --- a/cirq-superstaq/cirq_superstaq/validation_test.py +++ b/cirq-superstaq/cirq_superstaq/validation_test.py @@ -1,6 +1,9 @@ # pylint: disable=missing-function-docstring,missing-class-docstring from __future__ import annotations +import re +from unittest.mock import MagicMock, create_autospec + import cirq import pytest @@ -27,3 +30,23 @@ def test_validate_cirq_circuits() -> None: with pytest.raises(ValueError, match="Circuit has no measurements to sample"): css.validation.validate_cirq_circuits(circuit, require_measurements=True) + + +def test_validate_qubit_type() -> None: + invalid_qubit_type = MagicMock(spec=str) # E.g., in practice, `cirq_rigetti.AspenQubit` + mock_cirq_circuit = create_autospec(cirq.Circuit, spec_set=True) + mock_cirq_circuit.all_qubits.return_value = frozenset({invalid_qubit_type, cirq.LineQubit(0)}) + q0 = cirq.LineQubit(0) + q1, q2 = cirq.NamedQubit.range(2, prefix="q") + q3 = cirq.GridQubit(0, 0) + q4 = cirq.q(4) + valid_qubits = frozenset({q0, q1, q2, q3, q4}) + valid_circuit = cirq.Circuit(cirq.H(q) for q in valid_qubits) + valid_circuit += cirq.measure(*valid_qubits) + + css.validation.validate_cirq_circuits(valid_circuit, require_measurements=True) + with pytest.raises( + TypeError, + match=re.escape("Input circuit(s) contain unsupported qubit types. Valid"), + ): + css.validation.validate_cirq_circuits([mock_cirq_circuit, valid_circuit]) From a4a8c41bb38dcb0b9858f015f9d20aa11b99fa5c Mon Sep 17 00:00:00 2001 From: Bharath Date: Thu, 29 Aug 2024 18:02:21 -0500 Subject: [PATCH 03/13] docstring nit --- cirq-superstaq/cirq_superstaq/validation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index d47836fbe..71568af10 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -15,13 +15,13 @@ def validate_qubit_types(circuits: object) -> None: - """Verifies that `circuit` consists of valid qubit types only. + """Verifies that `circuits` consists of valid qubit types only. Args: - circuits: The input circuits to validate. + circuits: The input circuit(s) to validate. Raises: - TypeError: If an invalid qubit type is found in `circuit`. + TypeError: If an invalid qubit type is found in `circuits`. """ circuits_to_check = [circuits] if isinstance(circuits, cirq.Circuit) else circuits assert isinstance(circuits_to_check, Sequence) From aa9cbfab1587172700f2f20863333ad152e7e5bb Mon Sep 17 00:00:00 2001 From: Bharath Date: Thu, 29 Aug 2024 19:06:31 -0500 Subject: [PATCH 04/13] typo fix --- cirq-superstaq/cirq_superstaq/validation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index 71568af10..c4d891a65 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -39,9 +39,9 @@ def validate_qubit_types(circuits: object) -> None: def validate_cirq_circuits(circuits: object, require_measurements: bool = False) -> None: - """Validates that the input is an acceptable `cirq` object for `cirq-superstaq`. + """Validates that the input is an acceptable `cirq-core` object for `cirq-superstaq`. - In particular, this function verfies that `circuits` is either a single `cirq.Circuit` + In particular, this function verifies that `circuits` is either a single `cirq.Circuit` or a list of `cirq.Circuit` instances. Additionally, also validates that `circuits` only contains valid qubit types. From 3e04c18ff662916e945a889c844373a6cb349bca Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 30 Aug 2024 09:46:54 -0500 Subject: [PATCH 05/13] better error message --- cirq-superstaq/cirq_superstaq/validation.py | 9 ++++++--- cirq-superstaq/cirq_superstaq/validation_test.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index c4d891a65..866395736 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -31,10 +31,13 @@ def validate_qubit_types(circuits: object) -> None: all_qubits_present.update(circuit.all_qubits()) if not all(isinstance(q, SUPPORTED_QID_TYPES) for q in all_qubits_present): + invalid_qubit_types = ", ".join( + map(str, (set(type(q) for q in all_qubits_present) - set(SUPPORTED_QID_TYPES))) + ) raise TypeError( - "Input circuit(s) contain unsupported qubit types. Valid qubit types are: " - "`cirq.LineQubit`, `cirq.LineQid`, `cirq.GridQubit`, `cirq.GridQid`, " - "`cirq.NamedQubit`, and `cirq.NamedQid`." + f"Input circuit(s) contain unsupported qubit types: {invalid_qubit_types}. " + "Valid qubit types are: `cirq.LineQubit`, `cirq.LineQid`, `cirq.Grid>Qubit`, " + "`cirq.GridQid`, `cirq.NamedQubit`, and `cirq.NamedQid`." ) diff --git a/cirq-superstaq/cirq_superstaq/validation_test.py b/cirq-superstaq/cirq_superstaq/validation_test.py index 8f520f4c0..c6d2514b0 100644 --- a/cirq-superstaq/cirq_superstaq/validation_test.py +++ b/cirq-superstaq/cirq_superstaq/validation_test.py @@ -47,6 +47,6 @@ def test_validate_qubit_type() -> None: css.validation.validate_cirq_circuits(valid_circuit, require_measurements=True) with pytest.raises( TypeError, - match=re.escape("Input circuit(s) contain unsupported qubit types. Valid"), + match=re.escape("Input circuit(s) contain unsupported qubit types:"), ): css.validation.validate_cirq_circuits([mock_cirq_circuit, valid_circuit]) From ca73e9fa55763083188dbb2a551a655e2e0e424d Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 30 Aug 2024 10:48:53 -0500 Subject: [PATCH 06/13] remove assert --- cirq-superstaq/cirq_superstaq/validation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index 866395736..8db2a17d0 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -24,7 +24,6 @@ def validate_qubit_types(circuits: object) -> None: TypeError: If an invalid qubit type is found in `circuits`. """ circuits_to_check = [circuits] if isinstance(circuits, cirq.Circuit) else circuits - assert isinstance(circuits_to_check, Sequence) all_qubits_present: set[cirq.Qid] = set() for circuit in circuits_to_check: From b1cf6220dada2a69f13b5259c1cdecd45ced09a0 Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 30 Aug 2024 10:49:32 -0500 Subject: [PATCH 07/13] check qubit validator is not called when not needed --- .../cirq_superstaq/validation_test.py | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/cirq-superstaq/cirq_superstaq/validation_test.py b/cirq-superstaq/cirq_superstaq/validation_test.py index c6d2514b0..5ea13c828 100644 --- a/cirq-superstaq/cirq_superstaq/validation_test.py +++ b/cirq-superstaq/cirq_superstaq/validation_test.py @@ -2,7 +2,7 @@ from __future__ import annotations import re -from unittest.mock import MagicMock, create_autospec +from unittest.mock import MagicMock, create_autospec, patch import cirq import pytest @@ -14,22 +14,26 @@ def test_validate_cirq_circuits() -> None: qubits = [cirq.LineQubit(i) for i in range(2)] circuit = cirq.Circuit(cirq.H(qubits[0]), cirq.CNOT(qubits[0], qubits[1])) - with pytest.raises( - ValueError, - match="Invalid 'circuits' input. Must be a `cirq.Circuit` or a " - "sequence of `cirq.Circuit` instances.", - ): - css.validation.validate_cirq_circuits("circuit_invalid") + with patch("cirq_superstaq.validation.validate_qubit_types") as mock_qubit_validator: + with pytest.raises( + ValueError, + match="Invalid 'circuits' input. Must be a `cirq.Circuit` or a " + "sequence of `cirq.Circuit` instances.", + ): + css.validation.validate_cirq_circuits("circuit_invalid") + mock_qubit_validator.assert_not_called() - with pytest.raises( - ValueError, - match="Invalid 'circuits' input. Must be a `cirq.Circuit` or a " - "sequence of `cirq.Circuit` instances.", - ): - css.validation.validate_cirq_circuits([circuit, "circuit_invalid"]) + with pytest.raises( + ValueError, + match="Invalid 'circuits' input. Must be a `cirq.Circuit` or a " + "sequence of `cirq.Circuit` instances.", + ): + css.validation.validate_cirq_circuits([circuit, "circuit_invalid"]) + mock_qubit_validator.assert_not_called() - with pytest.raises(ValueError, match="Circuit has no measurements to sample"): - css.validation.validate_cirq_circuits(circuit, require_measurements=True) + with pytest.raises(ValueError, match="Circuit has no measurements to sample"): + css.validation.validate_cirq_circuits(circuit, require_measurements=True) + mock_qubit_validator.assert_not_called() def test_validate_qubit_type() -> None: @@ -44,7 +48,7 @@ def test_validate_qubit_type() -> None: valid_circuit = cirq.Circuit(cirq.H(q) for q in valid_qubits) valid_circuit += cirq.measure(*valid_qubits) - css.validation.validate_cirq_circuits(valid_circuit, require_measurements=True) + css.validation.validate_qubit_types(valid_circuit) with pytest.raises( TypeError, match=re.escape("Input circuit(s) contain unsupported qubit types:"), From 39506fe68c303abcf914a0aeef6f6a5069edbe66 Mon Sep 17 00:00:00 2001 From: Bharath Thotakura <113555655+bharat-thotakura@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:50:05 -0500 Subject: [PATCH 08/13] Type annotation fix Co-authored-by: Cameron Booker <130447455+cdbf1@users.noreply.github.com> --- cirq-superstaq/cirq_superstaq/validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index 8db2a17d0..f60e32499 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -14,7 +14,7 @@ ) -def validate_qubit_types(circuits: object) -> None: +def validate_qubit_types(circuits: cirq.Circuit | Sequence[cirq.Circuit]) -> None: """Verifies that `circuits` consists of valid qubit types only. Args: From 7752a5fba60c19cfc3f1472654c307b46cf2a737 Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 30 Aug 2024 10:57:11 -0500 Subject: [PATCH 09/13] Revert "check qubit validator is not called when not needed" This reverts commit b1cf6220dada2a69f13b5259c1cdecd45ced09a0. --- .../cirq_superstaq/validation_test.py | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/cirq-superstaq/cirq_superstaq/validation_test.py b/cirq-superstaq/cirq_superstaq/validation_test.py index 5ea13c828..c6d2514b0 100644 --- a/cirq-superstaq/cirq_superstaq/validation_test.py +++ b/cirq-superstaq/cirq_superstaq/validation_test.py @@ -2,7 +2,7 @@ from __future__ import annotations import re -from unittest.mock import MagicMock, create_autospec, patch +from unittest.mock import MagicMock, create_autospec import cirq import pytest @@ -14,26 +14,22 @@ def test_validate_cirq_circuits() -> None: qubits = [cirq.LineQubit(i) for i in range(2)] circuit = cirq.Circuit(cirq.H(qubits[0]), cirq.CNOT(qubits[0], qubits[1])) - with patch("cirq_superstaq.validation.validate_qubit_types") as mock_qubit_validator: - with pytest.raises( - ValueError, - match="Invalid 'circuits' input. Must be a `cirq.Circuit` or a " - "sequence of `cirq.Circuit` instances.", - ): - css.validation.validate_cirq_circuits("circuit_invalid") - mock_qubit_validator.assert_not_called() + with pytest.raises( + ValueError, + match="Invalid 'circuits' input. Must be a `cirq.Circuit` or a " + "sequence of `cirq.Circuit` instances.", + ): + css.validation.validate_cirq_circuits("circuit_invalid") - with pytest.raises( - ValueError, - match="Invalid 'circuits' input. Must be a `cirq.Circuit` or a " - "sequence of `cirq.Circuit` instances.", - ): - css.validation.validate_cirq_circuits([circuit, "circuit_invalid"]) - mock_qubit_validator.assert_not_called() + with pytest.raises( + ValueError, + match="Invalid 'circuits' input. Must be a `cirq.Circuit` or a " + "sequence of `cirq.Circuit` instances.", + ): + css.validation.validate_cirq_circuits([circuit, "circuit_invalid"]) - with pytest.raises(ValueError, match="Circuit has no measurements to sample"): - css.validation.validate_cirq_circuits(circuit, require_measurements=True) - mock_qubit_validator.assert_not_called() + with pytest.raises(ValueError, match="Circuit has no measurements to sample"): + css.validation.validate_cirq_circuits(circuit, require_measurements=True) def test_validate_qubit_type() -> None: @@ -48,7 +44,7 @@ def test_validate_qubit_type() -> None: valid_circuit = cirq.Circuit(cirq.H(q) for q in valid_qubits) valid_circuit += cirq.measure(*valid_qubits) - css.validation.validate_qubit_types(valid_circuit) + css.validation.validate_cirq_circuits(valid_circuit, require_measurements=True) with pytest.raises( TypeError, match=re.escape("Input circuit(s) contain unsupported qubit types:"), From 6c84b3e2d890824476a3379618f3b547129767eb Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 30 Aug 2024 11:05:52 -0500 Subject: [PATCH 10/13] explicitly call `validate_qubit_type()` --- cirq-superstaq/cirq_superstaq/validation_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq-superstaq/cirq_superstaq/validation_test.py b/cirq-superstaq/cirq_superstaq/validation_test.py index c6d2514b0..097d518be 100644 --- a/cirq-superstaq/cirq_superstaq/validation_test.py +++ b/cirq-superstaq/cirq_superstaq/validation_test.py @@ -44,7 +44,7 @@ def test_validate_qubit_type() -> None: valid_circuit = cirq.Circuit(cirq.H(q) for q in valid_qubits) valid_circuit += cirq.measure(*valid_qubits) - css.validation.validate_cirq_circuits(valid_circuit, require_measurements=True) + css.validation.validate_qubit_types(valid_circuit) with pytest.raises( TypeError, match=re.escape("Input circuit(s) contain unsupported qubit types:"), From 0f2a467ad67bf4ab4c25c7728a65aac484a2685d Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 30 Aug 2024 11:38:19 -0500 Subject: [PATCH 11/13] typo fix --- cirq-superstaq/cirq_superstaq/validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index f60e32499..7f5ece223 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -35,7 +35,7 @@ def validate_qubit_types(circuits: cirq.Circuit | Sequence[cirq.Circuit]) -> Non ) raise TypeError( f"Input circuit(s) contain unsupported qubit types: {invalid_qubit_types}. " - "Valid qubit types are: `cirq.LineQubit`, `cirq.LineQid`, `cirq.Grid>Qubit`, " + "Valid qubit types are: `cirq.LineQubit`, `cirq.LineQid`, `cirq.GridQubit`, " "`cirq.GridQid`, `cirq.NamedQubit`, and `cirq.NamedQid`." ) From 57380c229fbaedaa0f5861b28dba31fe639ce9f2 Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 30 Aug 2024 13:51:58 -0500 Subject: [PATCH 12/13] nit: grammar --- cirq-superstaq/cirq_superstaq/validation.py | 2 +- cirq-superstaq/cirq_superstaq/validation_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index 7f5ece223..66880fbb1 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -34,7 +34,7 @@ def validate_qubit_types(circuits: cirq.Circuit | Sequence[cirq.Circuit]) -> Non map(str, (set(type(q) for q in all_qubits_present) - set(SUPPORTED_QID_TYPES))) ) raise TypeError( - f"Input circuit(s) contain unsupported qubit types: {invalid_qubit_types}. " + f"Input circuit(s) contains unsupported qubit types: {invalid_qubit_types}. " "Valid qubit types are: `cirq.LineQubit`, `cirq.LineQid`, `cirq.GridQubit`, " "`cirq.GridQid`, `cirq.NamedQubit`, and `cirq.NamedQid`." ) diff --git a/cirq-superstaq/cirq_superstaq/validation_test.py b/cirq-superstaq/cirq_superstaq/validation_test.py index 097d518be..44375578f 100644 --- a/cirq-superstaq/cirq_superstaq/validation_test.py +++ b/cirq-superstaq/cirq_superstaq/validation_test.py @@ -47,6 +47,6 @@ def test_validate_qubit_type() -> None: css.validation.validate_qubit_types(valid_circuit) with pytest.raises( TypeError, - match=re.escape("Input circuit(s) contain unsupported qubit types:"), + match=re.escape("Input circuit(s) contains unsupported qubit types:"), ): css.validation.validate_cirq_circuits([mock_cirq_circuit, valid_circuit]) From d950639f264d3469679ea53c18a09742688d7f82 Mon Sep 17 00:00:00 2001 From: Bharath Date: Tue, 3 Sep 2024 11:02:10 -0500 Subject: [PATCH 13/13] nit: docstring wording --- cirq-superstaq/cirq_superstaq/validation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cirq-superstaq/cirq_superstaq/validation.py b/cirq-superstaq/cirq_superstaq/validation.py index 66880fbb1..5d4d38663 100644 --- a/cirq-superstaq/cirq_superstaq/validation.py +++ b/cirq-superstaq/cirq_superstaq/validation.py @@ -15,13 +15,13 @@ def validate_qubit_types(circuits: cirq.Circuit | Sequence[cirq.Circuit]) -> None: - """Verifies that `circuits` consists of valid qubit types only. + """Verifies that `circuits` consists of valid (`cirq-core`) qubit types only. Args: circuits: The input circuit(s) to validate. Raises: - TypeError: If an invalid qubit type is found in `circuits`. + TypeError: If an unsupported qubit type is found in `circuits`. """ circuits_to_check = [circuits] if isinstance(circuits, cirq.Circuit) else circuits @@ -44,8 +44,8 @@ def validate_cirq_circuits(circuits: object, require_measurements: bool = False) """Validates that the input is an acceptable `cirq-core` object for `cirq-superstaq`. In particular, this function verifies that `circuits` is either a single `cirq.Circuit` - or a list of `cirq.Circuit` instances. Additionally, also validates that `circuits` only - contains valid qubit types. + or a list of `cirq.Circuit` instances. Additionally, also validates that `circuits` + contains supported qubit types only. Args: circuits: The circuit(s) to run. @@ -54,7 +54,7 @@ def validate_cirq_circuits(circuits: object, require_measurements: bool = False) Raises: ValueError: If the input is not a `cirq.Circuit` or a list of `cirq.Circuit` instances. - TypeError: If an invalid qubit type is found in `circuits`. + TypeError: If an unsupported qubit type is found in `circuits`. """ if not (