-
Notifications
You must be signed in to change notification settings - Fork 67
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
Simplify the structure of CircuitSimulator
#225
Conversation
Only expand the propagators when it is applied to the states.
- Remove it from the input parameters, it makes little sense to provide them to the circuit and then do the simulation. If the unitaries are known. it can be trivally multiplied. - Remove U_list from the properties of CircuitSimulator. It is generated during the process and the dimensions of the unitaries are not determined. It should not be exposed to the the user.
- The method `_process_ops` was executed during the construction, which could be expensive. This is moved to the first execution of the circuit. - Remove some global members from the class to increase the clearity.
The parameters that will be updated during the circuit simulation are changed to private.
Move all the calculation related to unitary-state multiplication to _evolve_state.
Provide qeye as the input states.
This option computes the full unitary of all the gates, and caches it. It is beneficial if the circuit has a small number of qubits but a very large depth. This is a rare use case. At the same time, this feature makes the migration to the new efficient circuit evaluation very hard. If the unitary for the circuit is desired, one can just call QubitCircuit.compute_unitary to get the circuit and then apply it to different states.
Use np.einsum to apply the gate matrix directly on the state vector, instead of expanding it first to the full dimension. - The private member self._state will remain a numpy array during the sequential application of gates. - If a measurement occurs, the state has to be transformed to a Qobj. - Returning the state after each step is removed as it inevitably creates Qobj and creates a copy in v4.
Remove the support of precompute_unitary Use np.einsum for gate-state multiplication
Some benchmarking for the circuit simulator after the improvement, with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we also add tests (or maybe just parameterize some existing ones) for both the einsum and non-einsum modes?
for j, k in enumerate(targets_indices): | ||
new_index_list[k] = j + num_site | ||
state = np.einsum( | ||
gate_array, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question for the future -- could one in theory provide multiple gates at once here? Would that potentially be better / faster? Possibly with or without use of np.einsum_path
to select an optimal contraction path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that could be faster if those gates are mostly local. Then it is not that easy to decide unless one first builds the directed graph of the circuit, because gates can be commuting. So instead of this, we should rather try to get tensor network to work and let it does the heavy lifting.
…lator_refactor.py
@simon there is no non-einsum mode anymore. There is no need to keep that option. Measurement is not yet compatible with einsum, so in that case it just fails back to normal Qobj. |
Refactor the gate level
CircuitSimulator
einsum
).