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

Instruction API: Calibrations #155

Conversation

MarquessV
Copy link
Contributor

@MarquessV MarquessV commented Mar 7, 2023

Closes #154

This PR includes type hints for Calibration and MeasureCalibrationDefinition, I also added type hints for a lot of what was already existing, so that future MRs only contain type hints that are relevant to whatever that MR is touching.

@MarquessV MarquessV marked this pull request as ready for review March 7, 2023 19:44
Copy link
Contributor

@jselig-rigetti jselig-rigetti left a comment

Choose a reason for hiding this comment

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

Should the quil-py/quil/quil.cpython-310-darwin.so build artifact be gitignored?

quil-py/quil/instructions/__init__.pyi Outdated Show resolved Hide resolved
quil-py/quil/instructions/_expression.pyi Outdated Show resolved Hide resolved
quil-py/quil/instructions/_gate.pyi Outdated Show resolved Hide resolved
quil-py/quil/instructions/_qubit.pyi Outdated Show resolved Hide resolved
- is_*: Returns ``True`` if the inner type is of that variant.
- as_*: Returns the inner data if it is the given variant, ``None`` otherwise.
- to_*: Returns the inner data if it is the given variant, raises ``ValueError`` otherwise.
- from_*: Creates a new ``GateSpecification`` using an instance of the inner type for the variant.
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
- from_*: Creates a new ``GateSpecification`` using an instance of the inner type for the variant.
- from_*: Creates a new ``Qubit`` using an instance of the inner type for the variant.

MarquessV and others added 7 commits March 7, 2023 13:08
Co-authored-by: jselig-rigetti <97701976+jselig-rigetti@users.noreply.github.com>
Co-authored-by: jselig-rigetti <97701976+jselig-rigetti@users.noreply.github.com>
Co-authored-by: jselig-rigetti <97701976+jselig-rigetti@users.noreply.github.com>
Co-authored-by: jselig-rigetti <97701976+jselig-rigetti@users.noreply.github.com>
@MarquessV
Copy link
Contributor Author

@jselig-rigetti Nice catches! Fixed.

quil-py/quil/instructions/__init__.pyi Outdated Show resolved Hide resolved
quil-py/quil/instructions/_expression.pyi Show resolved Hide resolved
quil-py/quil/instructions/_expression.pyi Outdated Show resolved Hide resolved
quil-py/src/instruction/calibration.rs Show resolved Hide resolved
Comment on lines +68 to +76
impl MeasureCalibrationDefinition {
pub fn new(qubit: Option<Qubit>, parameter: String, instructions: Vec<Instruction>) -> Self {
Self {
qubit,
parameter,
instructions,
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't seem necessary if all of the fields are public.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe not necessary, but it makes the API more consistent if all the instruction types have new methods. Making the members of the instructions private is up for consideration as well since manual manipulation of the fields could easily malform an instruction. That would be a big change, but having and using constructors allows us to make it much easier in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, this approach is definitely a change in philosophy here. Previously/until now, these were really just data objects, which assert the type of the data held within but otherwise not its validity in any scope. So a parameter could be an invalid identifier and that was just fine, until the program was written to string and then read again. Both ways are valid, but this newer approach does make sense as the library matures away from being parser-focused.

This approach, with new, does add some boilerplate to the library, and I wonder if derive_builder would be more flexible and future proof without significantly more work. In fact, it might be less work since it's a derive rather than a hand-written new method for each instruction. If something internal to the struct changes, a builder is less likely to break than new. It also neatly supports validation.

More importantly, users do need to be able to mutate these instructions; that's a common pattern for users of pyQuil. So no matter what, we need to support the ability to do that from pyQuil and likely for Rust users as well.

  • Today, that could be operating directly on the public struct fields via pyO3;
  • if we added new here and made the fields private, we'd need at a minimum some way to read the fields and then send back to new for an updated copy;
  • if we use the the builder pattern, the user would turn a Calibration back into a CalibrationBuilder, update the field, and re-build()

Overall though I don't want to bike shed over it - I'll defer to @MarquessV 's judgment here.

Copy link
Contributor Author

@MarquessV MarquessV Mar 8, 2023

Choose a reason for hiding this comment

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

To follow up here after further discussion with @kalzoo.

We are going to continue with the new pattern used here. It is fast and allows us to do everything we need to do to support the next pyQuil RC. Long term we'll look at something like derive_builder as we agree that is closer to an ideal solution, but would take much longer to port the builders and associated methods to Python.

Comment on lines +68 to +76
impl MeasureCalibrationDefinition {
pub fn new(qubit: Option<Qubit>, parameter: String, instructions: Vec<Instruction>) -> Self {
Self {
qubit,
parameter,
instructions,
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, this approach is definitely a change in philosophy here. Previously/until now, these were really just data objects, which assert the type of the data held within but otherwise not its validity in any scope. So a parameter could be an invalid identifier and that was just fine, until the program was written to string and then read again. Both ways are valid, but this newer approach does make sense as the library matures away from being parser-focused.

This approach, with new, does add some boilerplate to the library, and I wonder if derive_builder would be more flexible and future proof without significantly more work. In fact, it might be less work since it's a derive rather than a hand-written new method for each instruction. If something internal to the struct changes, a builder is less likely to break than new. It also neatly supports validation.

More importantly, users do need to be able to mutate these instructions; that's a common pattern for users of pyQuil. So no matter what, we need to support the ability to do that from pyQuil and likely for Rust users as well.

  • Today, that could be operating directly on the public struct fields via pyO3;
  • if we added new here and made the fields private, we'd need at a minimum some way to read the fields and then send back to new for an updated copy;
  • if we use the the builder pattern, the user would turn a Calibration back into a CalibrationBuilder, update the field, and re-build()

Overall though I don't want to bike shed over it - I'll defer to @MarquessV 's judgment here.

quil-rs/src/parser/command.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@Shadow53 Shadow53 left a comment

Choose a reason for hiding this comment

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

The new changes LGTM

@MarquessV MarquessV merged commit eaf049f into 1455-python-support-for-program-and-beyond Mar 9, 2023
@MarquessV MarquessV deleted the 154-instruction-api-calibrations branch March 9, 2023 00:22
@MarquessV MarquessV linked an issue Apr 10, 2023 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Instruction API: Calibrations
4 participants