Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dispatch a builder with backendV1 and backendV2 #10150

Merged
merged 25 commits into from
Jun 12, 2023

Conversation

to24toro
Copy link
Contributor

@to24toro to24toro commented May 24, 2023

Summary

Added some codes of dispatching backends under pulse.builder. The number of the dispatching codes is not so many and we need not to use BackendV2Converter.

Details and comments

  • I have not implemented the tests about TestGates, TestBuilderComposition, and TestSubroutineCall in the version of backendV2 because they are the tests including the process with scheduling with backendV2 and this process don't work well.

  • related with Fix the output macros.measure with backendV2 #10135.

  • related with this issue.

@to24toro to24toro requested review from a team, eggerdj, wshanks and jyu00 as code owners May 24, 2023 03:28
@qiskit-bot
Copy link
Collaborator

One or more of the the following people are requested to review this:

  • @Qiskit/terra-core
  • @nkanazawa1989

self.assertScheduleEqual(schedule, reference)


class TestChannelsV2(TestBuilderV2, TestChannels):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it Ok this implementation ? is it better to split the tests about the builder with backendV2 to another file or not inherit the tests of the builder with backendV1?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good question. Alternatively we can use data driven test (ddt) to test against both V1 and V2 models (and we need a bit of overhaul of the test). At least you can split the file because the file may become too long if you also mirror other tests for V2.

@coveralls
Copy link

coveralls commented May 24, 2023

Pull Request Test Coverage Report for Build 5242207642

  • 37 of 38 (97.37%) changed or added relevant lines in 2 files are covered.
  • 23 unchanged lines in 4 files lost coverage.
  • Overall coverage increased (+0.004%) to 85.908%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/pulse/builder.py 34 35 97.14%
Files with Coverage Reduction New Missed Lines %
qiskit/transpiler/passes/synthesis/unitary_synthesis.py 1 90.39%
crates/qasm2/src/lex.rs 2 90.63%
qiskit/extensions/quantum_initializer/squ.py 2 80.0%
crates/qasm2/src/parse.rs 18 96.65%
Totals Coverage Status
Change from base Build 5199973880: 0.004%
Covered Lines: 71239
Relevant Lines: 82925

💛 - Coveralls

Copy link
Contributor

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @to24toro. This implementation looks better than previous one. Please also add release note with fix. I think this must be backported to 0.24 unless it requires API change, because without this fix pulse users need to use V1 backend which is deprecated.

qubit_mem_slots={qubit: register.index for qubit, register in zip(qubits, registers)},
)
# backendV2
if hasattr(backend, "target"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just pass backend without branching, because macros.measure implicitly dispatches the scheduler logic for backends with different models.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed at a21cc84.

qubit_mem_slots={qubit: qubit for qubit in qubits},
)
# backendV2
if hasattr(backend, "target"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed at a21cc84.

@@ -505,6 +505,26 @@ def qubit_properties(
return self.target.qubit_properties[qubit]
return [self.target.qubit_properties[q] for q in qubit]

def get_qubit_channels(self, qubit: int):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you implement this method as a helper function in the pulse.builder or pulse.utils? I want to backport this PR if possible, but this introduces API change and prevents us from the patch release with this. I also don't think there is demand for this method (i.e. V1 and V2 backend interface doesn't need to be fully compatible).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed at a21cc84.

self.assertScheduleEqual(schedule, reference)


class TestChannelsV2(TestBuilderV2, TestChannels):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good question. Alternatively we can use data driven test (ddt) to test against both V1 and V2 models (and we need a bit of overhaul of the test). At least you can split the file because the file may become too long if you also mirror other tests for V2.

@@ -677,6 +677,9 @@ def get_context(self) -> ScheduleBlock:
@_requires_backend
def num_qubits(self):
"""Get the number of qubits in the backend."""
# backendV2
if hasattr(self.backend, "target"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason not to use isinstance(self.backend, BackendV2), maybe circular import? If required information is stored in the backend.target then it looks reasonable to use this condition. Because we can dynamically add any attribute to the instance, it could have .target that may provide unexpected value. I think instance check is much safer in this sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed at a21cc84.

@nkanazawa1989 nkanazawa1989 self-assigned this May 24, 2023
@nkanazawa1989 nkanazawa1989 added stable backport potential The bug might be minimal and/or import enough to be port to stable mod: pulse Related to the Pulse module labels May 24, 2023
@to24toro
Copy link
Contributor Author

I splited test codes for pulse.builder with backendV2 to test_builder_v2.py.

Copy link
Contributor

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. Seems like the test for V2 backend dependency is not much, so probably we can combine both tests in a single file. Also we should have avoided new API for patch release.

self.assertEqual(target_qobj_transform(program), target_qobj_transform(target))


class TestBuilderBaseV2(TestBuilderV2):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test have V2 backend dependency? You can remove all the tests that builder context is not initialized with self.backend. How must test will remain then? If the number of test is not many, you can just add class TestBuilderBackendV2 to test_builder.py rather than creating new file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. I overlooked it. However the number of test and the code volume of the test are almost same as 93a9262 even if I will delete the test you mention. Is it Ok?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was probably overestimating the number of tests, but when I briefly checked your code I realized that number of test is not really large. For example, test_builder_v2.TestContextsV2 class, only three cases

  • test_transpiler_settings
  • test_scheduler_settings
  • test_phase_compensated_frequency_offset

take backend. I think if you remove other cases without backend dependency you can drastically reduce the amount of code to add. But having separate test file is probably okey.

Copy link
Contributor Author

@to24toro to24toro Jun 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Q] Is there any reason why self.backend is not set in test_default_alignment_right and test_default_alignment_sequential while it is used in test_default_alignment_left?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm good question. I don't think test_default_alignment_left needs backend. Perhaps I just copied it from another test case when I wrote this test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deleted duplicated and unnecesasry test codes at 891c1bd.

@@ -125,3 +130,24 @@ def deprecated_functionality(func):
stacklevel=2,
since="0.22.0",
)(func)


def get_qubit_channels(backend: BackendV2, qubit: int):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry my previous comment was wrong. This is also API change (i.e. new feature) and we should wait for another release. To make this PR a part of patch release, you need to embed this logic in the qubit_channels to avoid adding new public API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed at 9b2b80d.

@to24toro to24toro requested a review from ikkoham as a code owner June 5, 2023 08:52
@nkanazawa1989 nkanazawa1989 added this to the 0.24.2 milestone Jun 7, 2023
Copy link
Contributor

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR now looks good to me as one for patch release. Could you please redundant file changes to keep logical change minimum, because this is a patch to fix backend v2 problem (so unrelated files must not be included).

@@ -20,6 +22,9 @@
from qiskit.pulse.exceptions import UnassignedDurationError, QiskitError
from qiskit.utils.deprecation import deprecate_func, deprecate_function

if TYPE_CHECKING:
from qiskit.providers.backend import BackendV2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is needed? Likely BackendV2 type is not newly introduced in this file with this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to remove it. FIxed at 9fee85e .

@@ -100,7 +100,7 @@ def test_average_data_matrix_observable(self):
self.assertAlmostEqual(mean_iz, 0, places=1)

def test_make_dict_observable(self):
"""Test make_dict_observable."""
"""Test which makes_dict_observable."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary for this PR? Please keep logical change minimum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is my mistake. Fixed at c8d13f5 .

@@ -1163,6 +1178,31 @@ def qubit_channels(qubit: int) -> Set[chans.Channel]:
such as in the case where significant crosstalk exists.

"""

# implement as the inner function to avoid API change in 0.24.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# implement as the inner function to avoid API change in 0.24.
# implement as the inner function to avoid API change for a patch release in 0.24.2.

Do you plan to move this to pulse.utils after this PR? I think it's worth having this in 0.25.

Copy link
Contributor Author

@to24toro to24toro Jun 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider it makes sense to implement it as a method in backendV2.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This qubit channels assume some coupler or CR architecture. For example if one wants to use ControlChannels for flux bias of flux tunable qubits, they don't appear in the coupling map.

if isinstance(active_backend(), BackendV2):
dt = active_backend().dt
else:
dt = active_backend().configuration().dt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this logic to get dt everywhere in this file. This is of course not the scope of this PR, but could you please add new builder command to get backend dt in 0.25 for cleanup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want me to add like below?

def get_dt_from_backend(backend):
  if isinstance(backend. backendV2):
    return backend.dt
  else:
    return backend.configuration().dt

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in the followup PR for 0.25. I think this makes some logic cleaner.

qiskit/pulse/builder.py Show resolved Hide resolved
Copy link
Contributor

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @to24toro . I'm really glad the pulse builder can work with V2 backend now.

@nkanazawa1989 nkanazawa1989 added this pull request to the merge queue Jun 12, 2023
Merged via the queue into Qiskit:main with commit a1615a8 Jun 12, 2023
mergify bot pushed a commit that referenced this pull request Jun 12, 2023
* fix measure_v2

* modify measure_all

* dispatch backend

* add test of the builder with backendV2

* reconfigure test codes and some func

* refactoring

* add reno

* fix _measure_v2

* fix backend.meas_map in measure_v2

* fix reno

* delete get_qubit_channels from utils

* add get_qubits_channels in qubit_channels

* recostruct test about the builder with backendV2

* fix descriptions of test_macros

* fix descriptions of test_macros again

* delete import of backendV2 in utils

* revert no need to modify code

* Update releasenotes/notes/fix-dispatching-backends-28aff96f726ca9c5.yaml

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* Update a commnet in qiskit/pulse/builder.py

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* remove import TYPE_CHECKING

* removed test_builder.py utils.py and test_analyzation.py from pull request

---------

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
(cherry picked from commit a1615a8)
thspreetham98 pushed a commit to thspreetham98/qiskit-terra that referenced this pull request Jun 19, 2023
* fix measure_v2

* modify measure_all

* dispatch backend

* add test of the builder with backendV2

* reconfigure test codes and some func

* refactoring

* add reno

* fix _measure_v2

* fix backend.meas_map in measure_v2

* fix reno

* delete get_qubit_channels from utils

* add get_qubits_channels in qubit_channels

* recostruct test about the builder with backendV2

* fix descriptions of test_macros

* fix descriptions of test_macros again

* delete import of backendV2 in utils

* revert no need to modify code

* Update releasenotes/notes/fix-dispatching-backends-28aff96f726ca9c5.yaml

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* Update a commnet in qiskit/pulse/builder.py

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* remove import TYPE_CHECKING

* removed test_builder.py utils.py and test_analyzation.py from pull request

---------

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
github-merge-queue bot pushed a commit that referenced this pull request Jul 10, 2023
* fix measure_v2

* modify measure_all

* dispatch backend

* add test of the builder with backendV2

* reconfigure test codes and some func

* refactoring

* add reno

* fix _measure_v2

* fix backend.meas_map in measure_v2

* fix reno

* delete get_qubit_channels from utils

* add get_qubits_channels in qubit_channels

* recostruct test about the builder with backendV2

* fix descriptions of test_macros

* fix descriptions of test_macros again

* delete import of backendV2 in utils

* revert no need to modify code

* Update releasenotes/notes/fix-dispatching-backends-28aff96f726ca9c5.yaml

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* Update a commnet in qiskit/pulse/builder.py

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* remove import TYPE_CHECKING

* removed test_builder.py utils.py and test_analyzation.py from pull request

---------

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
(cherry picked from commit a1615a8)

Co-authored-by: Kento Ueda <38037695+to24toro@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mod: pulse Related to the Pulse module stable backport potential The bug might be minimal and/or import enough to be port to stable
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants