-
Notifications
You must be signed in to change notification settings - Fork 294
Migrating the Python operators to be C++ bindings #2817
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
…tor infrastructure Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Collaborator
Author
Command Bot: Processing... |
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Collaborator
Author
Command Bot: Processing... |
|
CUDA Quantum Docs Bot: A preview of the documentation can be found here. |
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Signed-off-by: Bettina Heim <heimb@outlook.com>
Collaborator
Author
Command Bot: Processing... |
Signed-off-by: Bettina Heim <heimb@outlook.com>
Collaborator
Author
Command Bot: Processing... |
|
CUDA Quantum Docs Bot: A preview of the documentation can be found here. |
bmhowe23
added a commit
to NVIDIA/cudaqx
that referenced
this pull request
May 1, 2025
Upstream changes: NVIDIA/cuda-quantum#2817 --------- Signed-off-by: Ben Howe <bhowe@nvidia.com>
This was referenced May 6, 2025
Merged
annagrin
pushed a commit
to annagrin/cuda-quantum
that referenced
this pull request
Jun 17, 2025
This PR introduces a type distinction between different kinds of operators and migrates the quantum operator infrastructure in Python to be bindings instead of Python code. This fixes previous performance issues after the initial introduction of the general quantum operator API in Python with 0.9.0. --------- Signed-off-by: Bettina Heim <heimb@outlook.com> Signed-off-by: Anna Gringauze <agringauze@nvidia.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR introduces a type distinction between different kinds of operators and migrates the quantum operator infrastructure in Python to be bindings instead of Python code. This fixes previous performance issues after the initial introduction of the general quantum operator API in Python with 0.9.0.
The following types are introduced:
The OperatorSum class is now a union of BosonOperator | FermionOperator | SpinOperator | MatrixOperator.
The ProductOperator class is now a union of BosonOperatorTerm | FermionOperatorTerm | SpinOperatorTerm | MatrixOperatorTerm.
The ElementaryOperator class is now a union of BosonOperatorElement | FermionOperatorElement | SpinOperatorElement | MatrixOperatorElement.
Operators for bosons, fermions and spins leverage a dedicated internal representation that allows for significant performance improvements compared to general matrix operators. When operators of different kinds (types) are combined, the resulting operator will always be a matrix operator.
Breaking changes:
max_degreeare: a constructorSpinOperatorTerm(first_degree, last_degree), the member functionop.canonicalize(Iterable[int]), and of course explicit multiplication with the identity(target).SpinOperator(a sum ofSpinOperatorTerms) and a SpinOperatorTerm (a product of Pauli operators). This requires a couple of breaking changes:SpinOperator()) will no longer create a product term with value 1. Instead, it will create a default instantiated sum, which will take the value of the first operator it is multiplied with or added to. For clarity and robustness, we recommend using an explicitcudaq.spin.empty()to create a sum with no terms, orcudaq.spin.identity()to create a product with value 1 as the previous constructor did.+=other terms, since this requiresopto be aSpinOperatorrather than aSpinOperatorTerm. You can ensureopis of the appropriate type by either starting out with an empty sum (op = spin.empty()), or by explicitly converting it to the correct type (op = SpinOperator(spin.identity())).spin.empty()now creates a spin operator with no terms; to determine whether a variableopof typeSpinOperatoris empty (has no terms), useop.num_terms == 0.SpinOperator(num_qubits: int)no longer exists; the constructorSpinOperatorTerm(first_degree: int, last_degree: int)can be used to create a product term that applies the identity to all targets in the open range [first_degree, last_degree). The constructorSpinOperator(size: int)instantiates a sum without any terms, reserving space for the given size (estimated number of terms).SpinOperators changed;op.serialize()andop.to_json()) are supported on bothSpinOperatorandSpinOperatorTerm, with matching constructors that take anIterable[float]and methodsSpinOperator.from_jsonandSpinOperatorTerm.from_json.SpinOperator(filename: str)expects the file to contain the new serialization format; please useSpinOperator(filename: str, legacy: bool)withlegacy = Trueto load existing files using the format/representationcudaq.operatorhas been restructured;cudaq.operator.operatorsare now available undercudaq.operatorscudaq.operatorscontains the submodulesspin,boson, andfermion(aliased also directly undercudaq)cudaq.dynamicsfolder; this should be largely non-breaking since the public classes and functions were and continue to be aliased directly undercudaqElementaryOperator.defineno longer exists; it is replaced bycudaq.operators.define, which defines aMatrixOperatorElementElementaryOperator(op_id: str, degrees: Iterable[int])no longer exists; it is replaced bycudaq.operators.instantiate(op_id, degrees), which produces aMatrixOperatorTerm(product operator)ElementaryOperator.zeroandElementaryOperator.identityno longer exist; they are replaced byoperators.zeroandoperators.identity, which produce aMatrixOperatorTerm(product operator)operators.identityorboson.identity) will always produce a product operator as well; ElementaryOperators are no longer intended to be constructed directly but merely encountered when iterator over a ProductOperatorDeprecations:
operators.createandoperators.annihilateare deprecated; please useboson.create/annihilateorfermion.create/annihilateinstead.operators.number) continue to be supported, we highly recommend replacing them with the appropriateboson.numberorfermion.numberinstead to greatly improve performance.get_coefficientis deprecated; useevaluate_coefficienton a/eachSpinOperatorTerminstead.get_term_countis deprecated; use the propertyterm_countinstead. Both are only available onSpinOperator, not onSpinOperatorTerm.get_qubit_countis deprecated; use the propertyqubit_countinstead.get_raw_datais deprecated; raw data access will no longer be supported in future releases. Coefficients can be obtained via thecoefficientproperty on aSpinOperatorTerm, and the binary symplectic form via the methodget_binary_symplectic_form()onSpinOperatorTerm.is_identitywill no longer be supported onSpinOperatorin future releases, but will continue to be supported onSpinOperatorTermSpinOperator(data: Iterable[double], num_qubits: int)used to load the old deserialization format will be removed in future releases; it is replaced by the constructorSpinOperator(data: Iterable[double])using the new formatop.to_string(print_coefficient: bool)is deprecated and will be removed in future releases; please usestr(op)instead. The Pauli word representation for aSpinOperatorTermcan be obtained withop.get_pauli_word(pad_identities: int = 0)instead.for_each_termandfor_each_pauliare deprecated and replaced by the standard iteration over the sum, and over each term in the sum instead.See also the description in #2710 to understand the broader changes across the CUDA-Q codebase that are now reflected also in the Python API.
Potential follow ups that are not part of this PR: