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

Measurement fixes #325

Merged
merged 94 commits into from
Mar 6, 2021
Merged

Measurement fixes #325

merged 94 commits into from
Mar 6, 2021

Conversation

stavros11
Copy link
Member

@stavros11 stavros11 commented Feb 13, 2021

Implements the following:

  1. Mirgrates tests/test_measurements.py to tests_new/test_measurement_gate.py, test_measurement_gate_probabilistic.py and test_measurement_gate_registers.py. Now these tests are also done using the numpy backends (fixes measurements for numpy backend #321?).

I have not made any changes in the code in order to support numpy, however the following script works both when only numpy is installed (no Tensorflow) and when both numpy and Tensorflow are installed:

import qibo
from qibo import models, gates
qibo.set_backend("numpy_defaulteinsum")

circuit = models.Circuit(2)
circuit.add([gates.H(0), gates.H(1)])
circuit.add(gates.M(0, 1))

result = circuit(nshots=1000)
print(result.state()) # prints [0.5, 0.5, 0.5, 0.5]
print(type(result.state())) # prints <class 'numpy.ndarray'>
print(result.samples()) # prints a (1000, 2) binary array with shots
print(type(result.samples())) # prints <class 'numpy.ndarray'>
print(result.frequencies()) # prints Counter({'11': 264, '01': 263, '00': 251, '10': 222})

Note that your results may be difference due to randomness. @scarrazza, if you have spotted a different issue with measurements in numpy that still exists, please let me know.

  1. Disables the shot evaluation when the measurement gate is called or the circuit is executed, which fixes Errors when using a large number of shots #322. Now frequencies and/or shots are only calculated when the user asks for it. Now the example:
import qibo
from qibo import models, gates

circuit = models.Circuit(2)
circuit.add([gates.H(0), gates.H(1)])
circuit.add(gates.M(0, 1))

result = circuit(nshots=10 ** 10)
print(result.frequencies())

will work and return Counter({'00': 2500000000, '01': 2500000000, '10': 2500000000, '11': 2500000000}), while result.samples() will fail with OOM as before.

TODO:

  • The frequencies calculated without shots are currently exact (no statistical noise), as I mentioned in Errors when using a large number of shots #322. This can be seen in the above example. It may be good to find an efficient way to add proper noise without calculating samples.
  • I believe the GateResult, CircuitResult in core.measurements are a bit obscure in terms of code readability and I would rename them to something else, such as MeasurementResult and MeasurementRegisterResult.
  • Complete test_core_measurements.py

@codecov
Copy link

codecov bot commented Feb 13, 2021

Codecov Report

Merging #325 (837fc31) into master (1b2383e) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##            master      #325    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files           74        76     +2     
  Lines        12082     12292   +210     
==========================================
+ Hits         12082     12292   +210     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/qibo/tests_new/test_core_gates.py 100.00% <ø> (ø)
src/qibo/__init__.py 100.00% <100.00%> (ø)
src/qibo/backends/abstract.py 100.00% <100.00%> (ø)
src/qibo/backends/numpy.py 100.00% <100.00%> (ø)
src/qibo/backends/tensorflow.py 100.00% <100.00%> (ø)
src/qibo/config.py 100.00% <100.00%> (ø)
src/qibo/core/cgates.py 100.00% <100.00%> (ø)
src/qibo/core/measurements.py 100.00% <100.00%> (ø)
src/qibo/core/states.py 100.00% <100.00%> (ø)
src/qibo/tensorflow/custom_operators/__init__.py 100.00% <100.00%> (ø)
... and 14 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1b2383e...837fc31. Read the comment docs.

@scarrazza
Copy link
Member

Thanks for this, looks good. Seems to fix the numpy issues I have observed with master. However, for my example (carlos code) on CPU, I observe that the numpy_defaulteinsum backend seems 2x faster than tf custom. Did you observe something similar?

@stavros11
Copy link
Member Author

stavros11 commented Feb 14, 2021

Thanks for this, looks good. Seems to fix the numpy issues I have observed with master. However, for my example (carlos code) on CPU, I observe that the numpy_defaulteinsum backend seems 2x faster than tf custom. Did you observe something similar?

Thanks for checking. I believe there is an issue with performance due to the way the tensor of frequencies is transformed to a dictionary, especially with Tensorflow where this line contains exponentially many castings to Python int. This is more visible if you try more qubits, eg. for 20 in my notebook numpy works but tf actually fails.

The current frequency calculation is more like a placeholder though, I will try to implement something close to what Carlos suggested in #322 which should also include the noise, so I would check again the final performance once we have this version.

@scarrazza
Copy link
Member

Great, thanks for the checks.

@scarrazza scarrazza merged commit e3d24dd into master Mar 6, 2021
@delete-merged-branch delete-merged-branch bot deleted the measurements branch March 6, 2021 18:04
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.

Errors when using a large number of shots measurements for numpy backend
3 participants