Skip to content

Conversation

Abhiraj-Shrotriya
Copy link
Contributor

@Abhiraj-Shrotriya Abhiraj-Shrotriya commented Aug 31, 2023

Summary

Implemented a way of writing and reading duration and unit data of instructions in qpy.
closes #10662

Details and comments

Backward compatible

@Abhiraj-Shrotriya Abhiraj-Shrotriya requested a review from a team as a code owner August 31, 2023 14:22
@qiskit-bot qiskit-bot added the Community PR PRs from contributors that are not 'members' of the Qiskit repo label Aug 31, 2023
@qiskit-bot
Copy link
Collaborator

Thank you for opening a new pull request.

Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient.

While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone.

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

  • @Qiskit/terra-core
  • @mtreinish
  • @nkanazawa1989

@Abhiraj-Shrotriya Abhiraj-Shrotriya changed the title implemented writing and reading of instruction duration and unit in qpy Implemented writing and reading of instruction duration and unit in qpy Aug 31, 2023
@coveralls
Copy link

Pull Request Test Coverage Report for Build 6038628513

  • 25 of 26 (96.15%) changed or added relevant lines in 4 files are covered.
  • 25 unchanged lines in 3 files lost coverage.
  • Overall coverage decreased (-0.02%) to 87.273%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/qpy/binary_io/circuits.py 17 18 94.44%
Files with Coverage Reduction New Missed Lines %
qiskit/qpy/binary_io/circuits.py 1 92.93%
crates/qasm2/src/lex.rs 6 90.63%
crates/qasm2/src/parse.rs 18 96.67%
Totals Coverage Status
Change from base Build 6037904724: -0.02%
Covered Lines: 74407
Relevant Lines: 85258

💛 - Coveralls

@mtreinish mtreinish self-assigned this Aug 31, 2023
@mtreinish mtreinish added Changelog: New Feature Include in the "Added" section of the changelog Changelog: API Change Include in the "Changed" section of the changelog mod: qpy Related to QPY serialization labels Aug 31, 2023
@mtreinish mtreinish added this to the 0.45.0 milestone Aug 31, 2023
@Abhiraj-Shrotriya
Copy link
Contributor Author

@mtreinish @jakelishman
Hi,
I am having problems making this qpy version backwards compatible since the qpy_version is now increased to Integer 10 (2-digit) up from Integer 9 ( 1-digit).

The qpy FILE_HEADER_PACK needs to be changed from "!6sBBBBQ"(Allowing only 1-digit int) to "!6sHBBBQ"(Allowing 2-digit int, hence allowing to have qpy_version values upto integer 99).

Changing this would break the qpy files created in past versions because then it will have a different structure.

Suggestion-

Create a FILE_HEADER_V2?

But then still the problem will persist.

Please help.

Thank you

@jakelishman
Copy link
Member

There's no need to encode an integer as its ASCII character representation - the current one-byte integer encoding of the QISKIT_VERSION can hold versions up to 256 without issue.

@jakelishman
Copy link
Member

jakelishman commented Sep 1, 2023

I haven't looked through the PR completely, but on a very quick scan, it looks like you're converting a lot of things to strings that shouldn't be strings; QPY is a binary format, and we should prefer to use denser type-code / numeric encodings wherever possible. For the most part, only things that were already strings should be written as strings, and not even all of those - for example, the unit of Instruction is actually enum-like, and we could encode the possible values in a single-byte type code.

@Abhiraj-Shrotriya
Copy link
Contributor Author

@jakelishman Thank you so much for clearing my confusion. Also can you please elaborate a little on the idea concerning unit of instruction .

@Abhiraj-Shrotriya
Copy link
Contributor Author

@mtreinish I think this pull request is now ready for a review. Thank you

Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

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

Overall this looks good, this is the basic framework of what's needed thanks for doing this. I left a couple inline comments on some improvements we can make to the actual struct format used to encode the duration and unit so that it's a bit more compact.

Besides those comments the only thing missing are tests and format documentation. It'd be good to have tests for the use of unit and duration in https://github.com/Qiskit/qiskit/blob/main/test/python/qpy/test_circuit_load_from_qpy.py to verify we can round trip serialize and deserialize these circuits (to ensure we don't regress). It'll also be good to add backwards compatibility tests to https://github.com/Qiskit/qiskit/blob/main/test/qpy_compat/test_qpy.py to ensure that moving forward we're able to load qpy files from old versions of qiskit that have unit and duration set.

Besides that the format documentation it would just be adding something to: https://github.com/Qiskit/qiskit/blob/main/qiskit/qpy/__init__.py#L148 to describe the new struct format and how it's read.

if duration == 0:
duration = None
# Load Unit
unit = file_obj.read(instruction.unit_size).decode(common.ENCODE)
Copy link
Member

Choose a reason for hiding this comment

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

Instead of using a string like this we can probably get by with a char. The only supported units can all be represented by single characters:

        "f": -15,
        "p": -12,
        "n": -9,
        "u": -6,
        "µ": -6,
        "m": -3,
        "k": 3,
        "M": 6,
        "G": 9,
        "T": 12,
        "P": 15,

Then we can just assign a special character for None probably just use bytes(0) and d for "dt". This will save us some space as we can tightly pack the unit and also it will be faster.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mtreinish Can you please elaborate on why the above map that you have given contains the integers as values since you are saying that these units can be stored as characters. Correct me if I am wrong but did you want to store the integer ( making the qpy file numerically dense) and read these numbers to retrieve character units? If yes then the struct pack should not have a 'c' at the end.

Thank you

Copy link
Member

Choose a reason for hiding this comment

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

Sorry for the delay this fell through the cracks at the end of last year and I missed replying here until now. What I meant is that right now you've got an arbitrary width encoding for the unit field. But instead of doing this you can do a fixed single character encoding of the unit in the actual QPY payload. So you would replace unit_size and the string decoding by putting a single character at the end of the struct packing. This will be the most efficient representation because it's just a single byte and then it's just about mapping that to the units that go in the instruction object's unit field.

Comment on lines +256 to +257
else:
pass
Copy link
Member

Choose a reason for hiding this comment

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

This is unnecessary as it's implicit if you don't have an else statement:

Suggested change
else:
pass

"unit_size",
],
)
CIRCUIT_INSTRUCTION_V3_PACK = "!HHHIIBHqIIII"
Copy link
Member

Choose a reason for hiding this comment

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

Isn't duration normally a float, especially if it has an SI unit? If so I would make this:

Suggested change
CIRCUIT_INSTRUCTION_V3_PACK = "!HHHIIBHqIIII"
CIRCUIT_INSTRUCTION_V3_PACK = "!HHHIIBHqIIdI"

to have duration be a double.

Comment on lines +122 to +125
"unit_size",
],
)
CIRCUIT_INSTRUCTION_V3_PACK = "!HHHIIBHqIIII"
Copy link
Member

Choose a reason for hiding this comment

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

Per my comment in circuits.py I'd probably change this to:

Suggested change
"unit_size",
],
)
CIRCUIT_INSTRUCTION_V3_PACK = "!HHHIIBHqIIII"
"unit",
],
)
CIRCUIT_INSTRUCTION_V3_PACK = "!HHHIIBHqIIIc"

and then handle the static mapping from single characters to value in the reader and writer.

@mtreinish mtreinish modified the milestones: 0.45.0, 1.0.0 Oct 18, 2023
@vtomole
Copy link

vtomole commented Nov 2, 2023

Thanks for working on this @Abhiraj-Shrotriya. Are you going to respond to the requested changes soon or is it okay if I take over this PR?

@Abhiraj-Shrotriya
Copy link
Contributor Author

Abhiraj-Shrotriya commented Nov 2, 2023

Thanks for working on this @Abhiraj-Shrotriya. Are you going to respond to the requested changes soon or is it okay if I take over this PR?

@vtomole
Hello,

Yes do intend to fix this issue. Thank you for your interest in helping. If I do however require help, I will contact you here :)

I intend to fix this soon.

Thank you again

@mtreinish mtreinish modified the milestones: 1.0.0, 1.1.0 Jan 23, 2024
@vtomole
Copy link

vtomole commented Feb 23, 2024

Hey @Abhiraj-Shrotriya , how's this going?

@Abhiraj-Shrotriya
Copy link
Contributor Author

@vtomole I asked a question to @mtreinish but did not get a reply in time. So I was not able to know what is expected of the code. That is why this PR is delayed. I am not blaming anyone since it is no one's fault.

If you know what is required of the code for this PR, please feel free to take over it.

I am sorry for the inconvenience and delay.

@vtomole
Copy link

vtomole commented Feb 26, 2024

@Abhiraj-Shrotriya Ah, i see. No worries then! Let's wait for @mtreinish. Thanks.

@Abhiraj-Shrotriya
Copy link
Contributor Author

@vtomole as I said earlier, if you know what is needed of this PR, please go ahead. @mtreinish maybe busy and is not getting time to respond to the queries raised, which is fine. It is of course not a good thing to keep this PR delayed for long. It would be best to resolve it as soon as possible no matter who does it. That is the spirit of open source development and I would like to to keep that spirit alive.

I am quite confident that you will be able to fix it :)

If, however, you are busy but do understand the work that needs to be done here, you can contact me with the guidance and I will work on it.

I would recommend you to just check the latest comments on my code as I think that will help you to have a clear understanding of my situation here.

Looking forward to progress :)

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: API Change Include in the "Changed" section of the changelog Changelog: New Feature Include in the "Added" section of the changelog Community PR PRs from contributors that are not 'members' of the Qiskit repo mod: qpy Related to QPY serialization
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

qpy doesn't percolate delay gate's units
6 participants