-
Notifications
You must be signed in to change notification settings - Fork 1k
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 support for > 32 qudits to cirq.sample_state_vector. Fix for #6031 #6090
Add support for > 32 qudits to cirq.sample_state_vector. Fix for #6031 #6090
Conversation
cirq-core/cirq/sim/state_vector.py
Outdated
# If we can't use numpy due to numpy/numpy#5744, use a slower method. | ||
probs = linalg.transpose_flattened_array(probs, qid_shape, list(indices) + not_measured) | ||
|
||
if len(not_measured): |
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.
This is simpler than the old code. I suppose it is also faster?
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. the main difference is what happens in the case of not measuring all qudits. In the old way it did
cirq-core/cirq/sim/state_vector.py
Outdated
if linalg.can_numpy_support_shape(qid_shape): | ||
# Use numpy transpose if we can since it's more efficient. | ||
probs = probs.reshape(qid_shape) | ||
probs = np.transpose(probs, list(indices) + not_measured) |
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.
Looking at the usage of np.transpose
elsewhere in the codebase, it looks like there is another place with similar usage:
Cirq/cirq-core/cirq/sim/density_matrix_utils.py
Lines 195 to 213 in a95f009
if len(indices) == len(qid_shape): | |
# We're measuring every qudit, so no need for fancy indexing | |
probs = np.abs(tensor) | |
probs = np.transpose(probs, indices) | |
probs = probs.reshape(-1) | |
else: | |
# Fancy indexing required | |
meas_shape = tuple(qid_shape[i] for i in indices) | |
probs = np.abs( | |
[ | |
tensor[ | |
linalg.slice_for_qubits_equal_to( | |
indices, big_endian_qureg_value=b, qid_shape=qid_shape | |
) | |
] | |
for b in range(np.prod(meas_shape, dtype=np.int64)) | |
] | |
) | |
probs = np.sum(probs, axis=tuple(range(1, len(probs.shape)))) |
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.
this is an exact copy of the code I'm modifying 😞 I refactored this part into a seprate method which I call from both locations
@rht I refactored the code so that both locations call the method. I don't know why
|
@rht this is now ready for merging |
Nit: I searched for the files named *_util.py; there are 2 occurrences. While *_utils.py has 7 occurrences. As such, I think it should be simulation_utils.py? |
this is ready for another look |
The 32 qubit dimension constraint for numpy is more annoying that I initially thought. Another example: In [1]: import cirq
In [2]: q = cirq.LineQubit.range(17)
In [3]: circuit = cirq.Circuit(cirq.Z.on_each(*q))
In [4]: cirq.unitary(circuit) |
@tanujkhattar wouldn't computing such a unitary generally (when the unitary is not a tensor product) take a couple of hours/days? ... a single multiplication of two a anyway lets keep track of all the places suffering from this problem in the original issue. can we merge this PR? |
@tanujkhattar ping |
…tumlib#6031 (quantumlib#6090) * Add support for > 32 qudits to cirq.sample_state_vector. Fix for quantumlib#6031 * refactor the method into a seprate util module * fix lint * accept only probabilities not complex numbers * added tests
np.transpose(tensor, axes)
so I'm keeping the use ofnp.transpose
when we can._prob
in a more efficient way. The old way did a lot of extra work when reordering the axes is all that is needed.Fix for #6031.