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

Add Qiskit native QPY ParameterExpression serialization #13356

Merged
merged 18 commits into from
Nov 6, 2024

Commits on Oct 22, 2024

  1. Add Qiskit native QPY ParameterExpression serialization

    With the release of symengine 0.13.0 we discovered a version dependence
    on the payload format used for serializing symengine expressions. This
    was worked around in Qiskit#13251 but this is not a sustainable solution and
    only works for symengine 0.11.0 and 0.13.0 (there was no 0.12.0). While
    there was always the option to use sympy to serialize the underlying
    symbolic expression (there is a `use_symengine` flag on `qpy.dumps` you
    can set to `False` to do this) the sympy serialzation has several
    tradeoffs most importantly is much higher runtime overhead. To solve
    the issue moving forward a qiskit native representation of the parameter
    expression object is necessary for serialization.
    
    This commit bumps the QPY format version to 13 and adds a new
    serialization format for ParameterExpression objects. This new format
    is a serialization of the API calls made to ParameterExpression that
    resulted in the creation of the underlying object. To facilitate this
    the ParameterExpression class is expanded to store an internal "replay"
    record of the API calls used to construct the ParameterExpression
    object. This internal list is what gets serialized by QPY and then on
    deserialization the "replay" is replayed to reconstruct the expression
    object. This is a different approach to the previous QPY representations
    of the ParameterExpression objects which instead represented the internal
    state stored in the ParameterExpression object with the symbolic
    expression from symengine (or a sympy copy of the expression). Doing
    this directly in Qiskit isn't viable though because symengine's internal
    expression tree is not exposed to Python directly. There isn't any
    method (private or public) to walk the expression tree to construct
    a serialization format based off of it. Converting symengine to a sympy
    expression and then using sympy's API to walk the expression tree is a
    possibility but that would tie us to sympy which would be problematic
    for Qiskit#13267 and Qiskit#13131, have significant runtime overhead, and it would
    be just easier to rely on sympy's native serialization tools.
    
    The tradeoff with this approach is that it does increase the memory
    overhead of the `ParameterExpression` class because for each element
    in the expression we have to store a record of it. Depending on the
    depth of the expression tree this also could be a lot larger than
    symengine's internal representation as we store the raw api calls made
    to create the ParameterExpression but symengine is likely simplifying
    it's internal representation as it builds it out. But I personally think
    this tradeoff is worthwhile as it ties the serialization format to the
    Qiskit objects instead of relying on a 3rd party library. This also
    gives us the flexibility of changing the internal symbolic expression
    library internally in the future if we decide to stop using symengine
    at any point.
    
    Fixes Qiskit#13252
    mtreinish committed Oct 22, 2024
    Configuration menu
    Copy the full SHA
    87e2a93 View commit details
    Browse the repository at this point in the history

Commits on Oct 23, 2024

  1. Remove stray comment

    mtreinish authored Oct 23, 2024
    Configuration menu
    Copy the full SHA
    0f84dba View commit details
    Browse the repository at this point in the history

Commits on Oct 24, 2024

  1. Add format documentation

    mtreinish committed Oct 24, 2024
    Configuration menu
    Copy the full SHA
    969e471 View commit details
    Browse the repository at this point in the history
  2. Add release note

    mtreinish committed Oct 24, 2024
    Configuration menu
    Copy the full SHA
    54ef86e View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    7d1fbfe View commit details
    Browse the repository at this point in the history

Commits on Oct 31, 2024

  1. Configuration menu
    Copy the full SHA
    2b352d7 View commit details
    Browse the repository at this point in the history
  2. Add int type for operands

    mtreinish committed Oct 31, 2024
    Configuration menu
    Copy the full SHA
    5d7b79a View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    2df6582 View commit details
    Browse the repository at this point in the history
  4. Add dedicated subs test

    mtreinish committed Oct 31, 2024
    Configuration menu
    Copy the full SHA
    60a2172 View commit details
    Browse the repository at this point in the history

Commits on Nov 5, 2024

  1. Pivot to stack based postfix/rpn deserialization

    This commit changes how the deserialization works to use a postfix
    stack based approach. Operands are push on the stack and then popped off
    based on the operation being run. The result of the operation is then
    pushed on the stack. This handles nested objects much more cleanly than
    the recursion based approach because we just keep pushing on the stack
    instead of recursing, making the accounting much simpler. After the
    expression payload is finished being processed there will be a single
    value on the stack and that is returned as the final expression.
    mtreinish committed Nov 5, 2024
    Configuration menu
    Copy the full SHA
    a903387 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    90e2c3b View commit details
    Browse the repository at this point in the history

Commits on Nov 6, 2024

  1. Apply suggestions from code review

    Co-authored-by: Elena Peña Tapia <[email protected]>
    mtreinish and ElePT authored Nov 6, 2024
    Configuration menu
    Copy the full SHA
    b72856d View commit details
    Browse the repository at this point in the history
  2. Change DERIV to GRAD

    mtreinish committed Nov 6, 2024
    Configuration menu
    Copy the full SHA
    8ae6589 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    11f65ad View commit details
    Browse the repository at this point in the history
  4. Change all the v4s to v13s

    mtreinish committed Nov 6, 2024
    Configuration menu
    Copy the full SHA
    6e75ea5 View commit details
    Browse the repository at this point in the history
  5. Correctly handle non-commutative operations

    This commit fixes a bug with handling the operand order of subtraction,
    division, and exponentiation. These operations are not commutative but
    the qpy deserialization code was treating them as such. So in cases
    where the argument order was reversed qpy was trying to flip the
    operands around for code simplicity and this would result in incorrect
    behavior. This commit fixes this by adding explicit op codes for the
    reversed sub, div, and pow and preserving the operand order correctly
    in these cases.
    mtreinish committed Nov 6, 2024
    Configuration menu
    Copy the full SHA
    8c2205f View commit details
    Browse the repository at this point in the history
  6. Fix lint

    mtreinish committed Nov 6, 2024
    Configuration menu
    Copy the full SHA
    33953fe View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    34479e3 View commit details
    Browse the repository at this point in the history