-
Notifications
You must be signed in to change notification settings - Fork 6
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
Clifford simultaneous filtered rb #412
Conversation
Codecov Report
@@ Coverage Diff @@
## main #412 +/- ##
==========================================
+ Coverage 95.90% 96.02% +0.12%
==========================================
Files 83 85 +2
Lines 5740 5994 +254
==========================================
+ Hits 5505 5756 +251
- Misses 235 238 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
|
@vodovozovaliza @wilkensJ what is the status of this PR? |
@ingoroth is someone going to work on this? |
At the moment nobody is actively working on this anymore. @vodovozovaliza might find some time to push this again at some point in the future. Maybe @Jacfomg has capacities to take over. |
We can talk about it next week if it's ok |
…bocal into clifford_filtered_rb
for more information, see https://pre-commit.ci
I think those tests should pass once we merge #499 that has the coupler changes needed. |
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.
Thanks for the updates @Jacfomg.
A few more comments.
I tried to run the protocol using simulation
Perhaps it is better to move the legend under the plot with a horizontal layout.
Moreover, I'm seeing that in the matrix a color is shown as nan
is it normal or am I doing something wrong?
src/qibocal/protocols/characterization/randomized_benchmarking/clifford_filtered_rb.py
Outdated
Show resolved
Hide resolved
src/qibocal/protocols/characterization/randomized_benchmarking/clifford_filtered_rb.py
Show resolved
Hide resolved
@Jacfomg I believe that if we manage to run at least once on hardware without errors we should be ready to merge this PR. |
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.
Just a quick comment here.
Even if the parameters/data/results are the same as the StandardRB
could you please add a separate class for each just for readability?
Executed on hardware: http://login.qrccluster.com:9000/JdmSqP64RrG-t4WRSd9zhw==/ |
Could you also fix conflicts? |
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.
Documentation is missing for some functions; it would be great to add it.
if isinstance(new_layer, Gate): | ||
nqubits = max(new_layer.qubits) + 1 | ||
elif all(isinstance(gate, Gate) for gate in new_layer): | ||
nqubits = max(max(gate.qubits) for gate in new_layer) + 1 |
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.
If new_layer
is always an iterable, you can reduce it to one if
.
elif isinstance(new_layer, Circuit): | ||
nqubits = new_layer.nqubits | ||
else: |
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.
Why does layer_gen
return list of Gates
or Circuit
? A list of Gates
can be seen as a circuit and vice versa.
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.
I agree. I think the original functionality of passing either a single Gate
or a Circuit
is sufficient. I guess the motivation was to be able to pass a layer of parallel single qubit gates. But this can also be cast to Circuit
when passed.
else: | ||
raise_error( | ||
TypeError, | ||
f"layer_gen must return type Circuit or Gate, but it is type {type(new_layer)}.", | ||
) | ||
|
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.
else: | |
raise_error( | |
TypeError, | |
f"layer_gen must return type Circuit or Gate, but it is type {type(new_layer)}.", | |
) |
Is there a particular reason for raising this error? We're all adults here; I'm guessing the code will crash if the wrong type is used.
if not isinstance(depth, int) or depth < 0: | ||
raise_error(ValueError, f"Depth: {depth}, must be type int and >= 0.") | ||
|
||
# Generate a layer to get nqubits. |
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.
I don't understand the first part of this function, if you need to know the number of qubits, you can add it as an input.
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.
In principle there is no need to pass nqubits as it is implicit in the output of layer_gen.__call__()
. But I don't like that now the first call of the generator is not added to the circuit. This makes it harder when one actually has to reproduce the result of a generator, say by restoring the rng state.
if platform and platform.name != "dummy": | ||
raise_error( | ||
NotImplementedError, | ||
f"Backend qibolab ({platform}) does not perform noise models simulation.", | ||
) |
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.
Can we skip this if
and set directly the numpy backend?
# Compute fitting uncertainties | ||
if len(popt_estimates): | ||
perr = data_uncertainties(popt_estimates, uncertainties, data_median=popt) | ||
perr = perr.T if perr is not None else (0,) * len(popt) |
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.
perr = perr.T if perr is not None else (0,) * len(popt) | |
perr = perr.T if perr else (0,) * len(popt) |
# TODO: If fit is None: loop to separate plotting for fitting in qq | ||
|
||
# TODO: fit doesn't get loaded on acquisition tests |
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.
There are a lot of TODOS, I suggest to collect them in an issue.
# TODO: This mess as well ... | ||
# meta_data = deepcopy(data.attrs) | ||
# meta_data.pop("depths", None) | ||
# if not meta_data["noise_model"]: | ||
# meta_data.pop("noise_model") | ||
# meta_data.pop("noise_params") | ||
# elif meta_data.get("noise_params", None) is not None: | ||
# meta_data["noise_params"] = np.round(meta_data["noise_params"], 3) | ||
|
||
# table_str = "".join( | ||
# [f" | {key}: {value}<br>" for key, value in {**meta_data, **rb_params}.items()] | ||
# ) | ||
|
||
# table_str = table_html(table_dict("Something")) |
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.
Dead code, delete it
if gate["name"] == "rz": | ||
gatelist.append( | ||
gates.RZ(gate["_target_qubits"][0], gate["init_kwargs"]["theta"]) | ||
) | ||
if gate["name"] == "rx": | ||
gatelist.append( | ||
gates.RX(gate["_target_qubits"][0], gate["init_kwargs"]["theta"]) | ||
) | ||
if gate["name"] == "ry": | ||
gatelist.append( | ||
gates.RY(gate["_target_qubits"][0], gate["init_kwargs"]["theta"]) | ||
) |
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 lines can be collected in a for loop using getattr
if gate["name"] == "z": | ||
gatelist.append(gates.Z(gate["_target_qubits"][0])) | ||
if gate["name"] == "x": | ||
gatelist.append(gates.X(gate["_target_qubits"][0])) | ||
if gate["name"] == "y": | ||
gatelist.append(gates.Y(gate["_target_qubits"][0])) |
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.
also this one
This PR is outdated, and it seems it will not be concluded, btw the protocol is interesting so I have opened #779 |
(Juan): This will need qiboteam/qibo#1015 to save and load circuits properly
Checklist: