-
Notifications
You must be signed in to change notification settings - Fork 126
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
New algorithm for RB building Cliffords by layers #892
New algorithm for RB building Cliffords by layers #892
Conversation
…enerate once all 24 transpiled Cliffords. Then, for every rb_circuit, select Cliffords at random and compose them to a circuit
…. Added parameter to all calls to compose to use inplace=True. Removed redundant method generate_all_transpiled_clifford_circuits
…use front=True, because I assume front=False when creating the circuits
… the previous version of rb_experiment.
New algorithm for generating Clifford circuits for single qubit.
…cuits, generate_1q_transpiled_clifford_circuits
…ling_single_qubit
… otherwise randomization is not identical in the two experiments
…ing called by the child class CurveAnalaysis. Added parameter to rb_experiment to determine whether to use the old algorithm or new one
…s change regarding _format_data
…eters for test_full_sampling_single_qubit
…lse, so that all tests will pass
…ding support for interleave
…cuits. Transformed interleaved element into a transpiled clifford circuit. Added relevant tests
…s PR and I missed it
…nges to the surrounding code
This PR is now ready for review - @nkanazawa1989 , @ShellyGarion , @gadial . |
A question to the reviewers – @itoko (in his recent PR) and I each took a different approach in the split to <2 and >2 qubits. I made the split on the level of circuits (see point (9) above, because my entire algorithm is different than the existing one. @itoko made the split inside the low-level methods, assuming the main flow for the two cases would remain the same. As a result, in the current implementation, in all such methods (for example,
I welcome your inputs on this. |
Thanks @merav-aharoni . My main concerns are the (1) Here are my comments:
Since 1q Clifford contains small number of elements, perhaps it could be faster to generate them on the fly with cache. Please confirm in your PR @itoko
This is really nice technique to reduce cache data size. Great job!
This is also reasonable.
The file size is about 1.4 MB and this is quite heavy. You should switch to another compressed data format, otherwise you could include script to generate this data and run the script at the time of setup. Please do some followup @itoko
Dict is O(1) lookup and sounds like fast enough and I'm curious how it's further boosted. I'm fine with your implementation as long as performance is guaranteed.
This is also nice. We need to write user/developer guide at some point to describe this data structure for future reviewers.
User should be able to run RB experiment with new basis gates without regenerating file (i.e. try-except) as long as they don't care about the speed. They may want to choose to wait for another dozens of seconds with conventional approach, rather than spending time for learning how to use of this generator function and waiting another minutes to regenerate full Clifford table. This is why I prefer a single interface @itoko designed, and we can hide actual logic behind the interface as a black box. For example, forest benchmarking has a dedicated generator class that takes RB configuration with basis gates (likely they generates sequence through Cloud service). With this, users and casual developers don't need to know actual implementation. Proposed implementation exposes everything to the main class and researchers may need to read handles of lines of code to figure out how to make small update. Personally I prefer the implementation of forest benchmarking. I'm fine with promoting
I feel this is no longer util. I was thinking to remove this class since its usage is just a name space. You can still explicitly add basis gates to the arguments of methods/functions that requires the basis information. On the other hand, I think we can promote this class to a generator as I mentioned above.
This design may increases maintenance overhead. I feel we need extra abstraction layer for circuit generation. Please do followup @itoko Overall the performance improvement is really nice and I'm happy with your awesome work! I'll just merge this PR now, and I hope @itoko will address my comments above with his rework without performance regression. |
Great job, @merav-aharoni ! This PR has dramatically improved the performance of the RB experiments. Note: The benchmark measures run time without "setup time" (import time and caching time in |
main: Before this PR (0359f4c) method = time_transpiled_circuits for both settings Standard RB 1Q:
Standard RB 2Q:
Interleaved RB 1Q:
Interleaved RB 2Q:
|
* New algorithm for generating Clifford circuits for single qubit. We generate once all 24 transpiled Cliffords. Then, for every rb_circuit, select Cliffords at random and compose them to a circuit * Changed basis for transpilation to match the one in single_qubit_test. Added parameter to all calls to compose to use inplace=True. Removed redundant method generate_all_transpiled_clifford_circuits * Modified the methods in create_clifford_map so that compose does not use front=True, because I assume front=False when creating the circuits * Changed generation of generation of random numbers to be identical to the previous version of rb_experiment. * Test to run on device * added methods for new algorithm to generate rb circuits: build_rb_circuits, generate_1q_transpiled_clifford_circuits * Added the method _layout_for_rb_single_qubit and added test_full_sampling_single_qubit * In test_full_sampling_single_qubit fixed num_samples to be 1, because otherwise randomization is not identical in the two experiments * Tidied up build_rb_circuits * Added documentation and moved methods * Added test_single_qubit_parallel * Changed name _format_data to format_data because the method wasn't being called by the child class CurveAnalaysis. Added parameter to rb_experiment to determine whether to use the old algorithm or new one * Fixed handling of num_samples>1. Cleaned out prints. Reverted previous change regarding _format_data * Added assertExperimentDone to test_single-qubit_parallel. Fixed parameters for test_full_sampling_single_qubit * Modified assertAllIdentity to support circuits with rz gates * Changed name _new_rb to _transpiled_rb. Also changed default to be False, so that all tests will pass * removed fast_rb.py * removed rb_on_device.py * Removed temporary 'import time' * Added support for interleaved rb single qubit * Fixed handling of interleaved element * Fixed bug caused by change of interface of _buil_rb_circuits after adding support for interleave * added test_number_to_clifford_mapping and fixed the method num_from_1_qubit_clifford * Added support for computation of the Clifford to number mapping of a circuit * Moved setting of interleaved metadata to be under 'if is_interleaved' * Added transpilation of interleaved element before creating the rb circuits. Transformed interleaved element into a transpiled clifford circuit. Added relevant tests * Fixed incorrect parameter 'qubits' in test_non_clifford_interleaved_element * Added support for 'delay' as interleaved element * Moved setting of basis gates to circuits(), because in __init__ the transpile_options are not available yet * Cleaned up setting of tranpile_options in the test. Added call to generate_1q_transpiled_clifford_circuits in InterleavedRB.circuits() * Changed the clifford compose mapping so that the rhs includes only single-gate cliffords. The purpose is to reduce the size of the mapping table * Changed all methods in CliffordUtils to be classmethod * Fixes following changes in CliffordUtils * Changed structure of CLIFF_COMPOSE_DATA to be an array instead of a dict, for performance reasons. The index in the array is computed in compose_num_with_clifford * Improved _layout_for_rb_single_qubit to be more robust * Documentation, black, pylint * black * Removed the parameter transpiled_rb used for choosing whether to use old algorithm or new one. * Cleaning up * Generated transpiled clifford circuits for 2 qubits, and stored in a file. Adding load from this file in circuits() * re-generated transpiled circuits * Added support for compose_num_with_clifford_2q. Added suitable test - test_number_to_clifford_mapping_2q. * Created method load_transpiled_cliff_circuits * Added support for two sets of basis gates and their corresponding transpiled clifford files * United the two class variables _transpiled_cliff_circuits_1q and _transpiled_cliff_circuits_2q to a single dict * Added setting of transpile_options to all tests * Fixed error messages * United methods compose_num_with_clifford and num_from_clifford_single_gate for 1 and 2 qubits. Interface changes in StandardRB towards uniting functionality for 1 and 2 qubits * Unified the format for CLIFF_SINGLE_GATE_MAP_1Q and CLIFF_SINGLE_GATE_MAP_2Q * Added method clifford_inverse_by_num to unite handling of 1 and 2 qubit-rb * Fixes to support 1 and 2 qubits in _build_rb_circuits * Fixed more places where the code assumed 1 qubit rb * Fix for handling of delay. Changed test_interleaving_circuit_with_delay to suit transpiled circuits * changed basis gates in test, because rz is not supported in conversion to Clifford * Extended lenths for test, because test was failing for statistical reasons * changed name of method after addition of 2q * black and lint * black, lint and documentation * black, lint, cleaning * Removed legacy code. Additional cleaning * Removed more legacy code. More cleaning * Removed pylint messages for the data file * pylint, and use method CliffordUtils.file_name * Removed additional legacy code * Release notes * Added missing () * Fixed error message * Added QiskitError to documentation * black * Fixed error message * Changed varible name * attempt to fix documentation failure in CI * pylint * Added transpile options to every experiment * Made setting transpile_options mandatory, because if basis_gates are taken from backend, then the names of the transpiled clifford files don't match * Split test_rb_utils into itself and test_clifford_utils * Added tests for composing a clifford with a number * Added test for inverse clifford by num * Changed random to rng because of failure on Windows * Removed dependency on Aer for transpile. Removed the method transpile_single_clifford and use transpile() directly instead * Changed parameter backend to be optional, as it was before * Improved format for CLIFF_SINGLE_GATE_MAP, CLIFF_COMPOSE_DATA, CLIFF_INVERSE_DATA * Changed usage from cliff.__repr__ to repr(cliff) * Fixed a bug where transpiled_circuits were loaded multiple times * New algorithm that constructs the Cliffords by layers * Added support for 1 qubits, for full sampling and for interleaved rb * Removed unused files. Black * Added 2 parameters to CliffordUtils.__init__: num_qubits and basis_gates * Removed all parameters num_qubits and use self.num-qubits instead * Removed usage of specific gate sets * moved interleaved element out of StandardRB * Split _build_rb_circuits into small methods to make it more modular * Added tests for CliffordUtils * Added support for cz * Added backend to CliffordInit.__init__. Added transpile to initial circuit created in _build methods * Modified test_correct_1q_depolarization for it to pass * black and pylint * Fixed bug with cz - since it is a symmetrical operation, we store only (cz, [0,1]) in all the Clifford lists. * Fixed the parameters in cliffordUtils methods. Since num_qubits was added as a class member, no need to pass it as a parameter. * Data updated by changes in create_clifford_map.py from previous commit * Fixed two tests. test_correct_1q_depolarization was failing due to too strict assertion. test_interleaving_circuit_with_delay needed to be changed because now returns transpiled circuits. * Changed usage of VGate and WGate to their component gates: s, h, sdg. * Moved transpiled clifford structures outside init to make them static in the class * Added test for two qubit rb in parallel * Moved structures back inside __init__ because the previous change caused a bug * Added back the old code to create RB circuits for more than 2 qubits * Changed InterleavedRB.circuits to call its super() when number of qubits > 2. Added default set of basis gates * Added test for three qubit RB * Documentation * black and pylint * Disabled black and pylint errors on clifford_data.py * Changed _clifford_utils to be a static class member. Added a couple of short methods to reduce code duplication * Updated release notes * Fixed failing test * Fixed bug: _transpile_cliff_layer_0 was ignoring the backend * Documentation * Reverted changes in tutorial as it is not mandatory to supply basis_gates any more * Cleaning up * Cleaning up * black and doc * Fixed bug found in tutorial - added transpile at the beginning of building an interleaved circuit * Added header * black * Cleaning up temporary comments * documentation * Changed order of several methods * Removed -interleave(). It was previously removed in main, but I forgot it in the code * Removed method _set_interleaved_element that was removed in a previous PR and I missed it * Name changed and spaces * Removed empty spaces * typo * Fixed transpilation of interleaved element. Made a few structural changes to the surrounding code
* New algorithm for generating Clifford circuits for single qubit. We generate once all 24 transpiled Cliffords. Then, for every rb_circuit, select Cliffords at random and compose them to a circuit * Changed basis for transpilation to match the one in single_qubit_test. Added parameter to all calls to compose to use inplace=True. Removed redundant method generate_all_transpiled_clifford_circuits * Modified the methods in create_clifford_map so that compose does not use front=True, because I assume front=False when creating the circuits * Changed generation of generation of random numbers to be identical to the previous version of rb_experiment. * Test to run on device * added methods for new algorithm to generate rb circuits: build_rb_circuits, generate_1q_transpiled_clifford_circuits * Added the method _layout_for_rb_single_qubit and added test_full_sampling_single_qubit * In test_full_sampling_single_qubit fixed num_samples to be 1, because otherwise randomization is not identical in the two experiments * Tidied up build_rb_circuits * Added documentation and moved methods * Added test_single_qubit_parallel * Changed name _format_data to format_data because the method wasn't being called by the child class CurveAnalaysis. Added parameter to rb_experiment to determine whether to use the old algorithm or new one * Fixed handling of num_samples>1. Cleaned out prints. Reverted previous change regarding _format_data * Added assertExperimentDone to test_single-qubit_parallel. Fixed parameters for test_full_sampling_single_qubit * Modified assertAllIdentity to support circuits with rz gates * Changed name _new_rb to _transpiled_rb. Also changed default to be False, so that all tests will pass * removed fast_rb.py * removed rb_on_device.py * Removed temporary 'import time' * Added support for interleaved rb single qubit * Fixed handling of interleaved element * Fixed bug caused by change of interface of _buil_rb_circuits after adding support for interleave * added test_number_to_clifford_mapping and fixed the method num_from_1_qubit_clifford * Added support for computation of the Clifford to number mapping of a circuit * Moved setting of interleaved metadata to be under 'if is_interleaved' * Added transpilation of interleaved element before creating the rb circuits. Transformed interleaved element into a transpiled clifford circuit. Added relevant tests * Fixed incorrect parameter 'qubits' in test_non_clifford_interleaved_element * Added support for 'delay' as interleaved element * Moved setting of basis gates to circuits(), because in __init__ the transpile_options are not available yet * Cleaned up setting of tranpile_options in the test. Added call to generate_1q_transpiled_clifford_circuits in InterleavedRB.circuits() * Changed the clifford compose mapping so that the rhs includes only single-gate cliffords. The purpose is to reduce the size of the mapping table * Changed all methods in CliffordUtils to be classmethod * Fixes following changes in CliffordUtils * Changed structure of CLIFF_COMPOSE_DATA to be an array instead of a dict, for performance reasons. The index in the array is computed in compose_num_with_clifford * Improved _layout_for_rb_single_qubit to be more robust * Documentation, black, pylint * black * Removed the parameter transpiled_rb used for choosing whether to use old algorithm or new one. * Cleaning up * Generated transpiled clifford circuits for 2 qubits, and stored in a file. Adding load from this file in circuits() * re-generated transpiled circuits * Added support for compose_num_with_clifford_2q. Added suitable test - test_number_to_clifford_mapping_2q. * Created method load_transpiled_cliff_circuits * Added support for two sets of basis gates and their corresponding transpiled clifford files * United the two class variables _transpiled_cliff_circuits_1q and _transpiled_cliff_circuits_2q to a single dict * Added setting of transpile_options to all tests * Fixed error messages * United methods compose_num_with_clifford and num_from_clifford_single_gate for 1 and 2 qubits. Interface changes in StandardRB towards uniting functionality for 1 and 2 qubits * Unified the format for CLIFF_SINGLE_GATE_MAP_1Q and CLIFF_SINGLE_GATE_MAP_2Q * Added method clifford_inverse_by_num to unite handling of 1 and 2 qubit-rb * Fixes to support 1 and 2 qubits in _build_rb_circuits * Fixed more places where the code assumed 1 qubit rb * Fix for handling of delay. Changed test_interleaving_circuit_with_delay to suit transpiled circuits * changed basis gates in test, because rz is not supported in conversion to Clifford * Extended lenths for test, because test was failing for statistical reasons * changed name of method after addition of 2q * black and lint * black, lint and documentation * black, lint, cleaning * Removed legacy code. Additional cleaning * Removed more legacy code. More cleaning * Removed pylint messages for the data file * pylint, and use method CliffordUtils.file_name * Removed additional legacy code * Release notes * Added missing () * Fixed error message * Added QiskitError to documentation * black * Fixed error message * Changed varible name * attempt to fix documentation failure in CI * pylint * Added transpile options to every experiment * Made setting transpile_options mandatory, because if basis_gates are taken from backend, then the names of the transpiled clifford files don't match * Split test_rb_utils into itself and test_clifford_utils * Added tests for composing a clifford with a number * Added test for inverse clifford by num * Changed random to rng because of failure on Windows * Removed dependency on Aer for transpile. Removed the method transpile_single_clifford and use transpile() directly instead * Changed parameter backend to be optional, as it was before * Improved format for CLIFF_SINGLE_GATE_MAP, CLIFF_COMPOSE_DATA, CLIFF_INVERSE_DATA * Changed usage from cliff.__repr__ to repr(cliff) * Fixed a bug where transpiled_circuits were loaded multiple times * New algorithm that constructs the Cliffords by layers * Added support for 1 qubits, for full sampling and for interleaved rb * Removed unused files. Black * Added 2 parameters to CliffordUtils.__init__: num_qubits and basis_gates * Removed all parameters num_qubits and use self.num-qubits instead * Removed usage of specific gate sets * moved interleaved element out of StandardRB * Split _build_rb_circuits into small methods to make it more modular * Added tests for CliffordUtils * Added support for cz * Added backend to CliffordInit.__init__. Added transpile to initial circuit created in _build methods * Modified test_correct_1q_depolarization for it to pass * black and pylint * Fixed bug with cz - since it is a symmetrical operation, we store only (cz, [0,1]) in all the Clifford lists. * Fixed the parameters in cliffordUtils methods. Since num_qubits was added as a class member, no need to pass it as a parameter. * Data updated by changes in create_clifford_map.py from previous commit * Fixed two tests. test_correct_1q_depolarization was failing due to too strict assertion. test_interleaving_circuit_with_delay needed to be changed because now returns transpiled circuits. * Changed usage of VGate and WGate to their component gates: s, h, sdg. * Moved transpiled clifford structures outside init to make them static in the class * Added test for two qubit rb in parallel * Moved structures back inside __init__ because the previous change caused a bug * Added back the old code to create RB circuits for more than 2 qubits * Changed InterleavedRB.circuits to call its super() when number of qubits > 2. Added default set of basis gates * Added test for three qubit RB * Documentation * black and pylint * Disabled black and pylint errors on clifford_data.py * Changed _clifford_utils to be a static class member. Added a couple of short methods to reduce code duplication * Updated release notes * Fixed failing test * Fixed bug: _transpile_cliff_layer_0 was ignoring the backend * Documentation * Reverted changes in tutorial as it is not mandatory to supply basis_gates any more * Cleaning up * Cleaning up * black and doc * Fixed bug found in tutorial - added transpile at the beginning of building an interleaved circuit * Added header * black * Cleaning up temporary comments * documentation * Changed order of several methods * Removed -interleave(). It was previously removed in main, but I forgot it in the code * Removed method _set_interleaved_element that was removed in a previous PR and I missed it * Name changed and spaces * Removed empty spaces * typo * Fixed transpilation of interleaved element. Made a few structural changes to the surrounding code
* New algorithm for generating Clifford circuits for single qubit. We generate once all 24 transpiled Cliffords. Then, for every rb_circuit, select Cliffords at random and compose them to a circuit * Changed basis for transpilation to match the one in single_qubit_test. Added parameter to all calls to compose to use inplace=True. Removed redundant method generate_all_transpiled_clifford_circuits * Modified the methods in create_clifford_map so that compose does not use front=True, because I assume front=False when creating the circuits * Changed generation of generation of random numbers to be identical to the previous version of rb_experiment. * Test to run on device * added methods for new algorithm to generate rb circuits: build_rb_circuits, generate_1q_transpiled_clifford_circuits * Added the method _layout_for_rb_single_qubit and added test_full_sampling_single_qubit * In test_full_sampling_single_qubit fixed num_samples to be 1, because otherwise randomization is not identical in the two experiments * Tidied up build_rb_circuits * Added documentation and moved methods * Added test_single_qubit_parallel * Changed name _format_data to format_data because the method wasn't being called by the child class CurveAnalaysis. Added parameter to rb_experiment to determine whether to use the old algorithm or new one * Fixed handling of num_samples>1. Cleaned out prints. Reverted previous change regarding _format_data * Added assertExperimentDone to test_single-qubit_parallel. Fixed parameters for test_full_sampling_single_qubit * Modified assertAllIdentity to support circuits with rz gates * Changed name _new_rb to _transpiled_rb. Also changed default to be False, so that all tests will pass * removed fast_rb.py * removed rb_on_device.py * Removed temporary 'import time' * Added support for interleaved rb single qubit * Fixed handling of interleaved element * Fixed bug caused by change of interface of _buil_rb_circuits after adding support for interleave * added test_number_to_clifford_mapping and fixed the method num_from_1_qubit_clifford * Added support for computation of the Clifford to number mapping of a circuit * Moved setting of interleaved metadata to be under 'if is_interleaved' * Added transpilation of interleaved element before creating the rb circuits. Transformed interleaved element into a transpiled clifford circuit. Added relevant tests * Fixed incorrect parameter 'qubits' in test_non_clifford_interleaved_element * Added support for 'delay' as interleaved element * Moved setting of basis gates to circuits(), because in __init__ the transpile_options are not available yet * Cleaned up setting of tranpile_options in the test. Added call to generate_1q_transpiled_clifford_circuits in InterleavedRB.circuits() * Changed the clifford compose mapping so that the rhs includes only single-gate cliffords. The purpose is to reduce the size of the mapping table * Changed all methods in CliffordUtils to be classmethod * Fixes following changes in CliffordUtils * Changed structure of CLIFF_COMPOSE_DATA to be an array instead of a dict, for performance reasons. The index in the array is computed in compose_num_with_clifford * Improved _layout_for_rb_single_qubit to be more robust * Documentation, black, pylint * black * Removed the parameter transpiled_rb used for choosing whether to use old algorithm or new one. * Cleaning up * Generated transpiled clifford circuits for 2 qubits, and stored in a file. Adding load from this file in circuits() * re-generated transpiled circuits * Added support for compose_num_with_clifford_2q. Added suitable test - test_number_to_clifford_mapping_2q. * Created method load_transpiled_cliff_circuits * Added support for two sets of basis gates and their corresponding transpiled clifford files * United the two class variables _transpiled_cliff_circuits_1q and _transpiled_cliff_circuits_2q to a single dict * Added setting of transpile_options to all tests * Fixed error messages * United methods compose_num_with_clifford and num_from_clifford_single_gate for 1 and 2 qubits. Interface changes in StandardRB towards uniting functionality for 1 and 2 qubits * Unified the format for CLIFF_SINGLE_GATE_MAP_1Q and CLIFF_SINGLE_GATE_MAP_2Q * Added method clifford_inverse_by_num to unite handling of 1 and 2 qubit-rb * Fixes to support 1 and 2 qubits in _build_rb_circuits * Fixed more places where the code assumed 1 qubit rb * Fix for handling of delay. Changed test_interleaving_circuit_with_delay to suit transpiled circuits * changed basis gates in test, because rz is not supported in conversion to Clifford * Extended lenths for test, because test was failing for statistical reasons * changed name of method after addition of 2q * black and lint * black, lint and documentation * black, lint, cleaning * Removed legacy code. Additional cleaning * Removed more legacy code. More cleaning * Removed pylint messages for the data file * pylint, and use method CliffordUtils.file_name * Removed additional legacy code * Release notes * Added missing () * Fixed error message * Added QiskitError to documentation * black * Fixed error message * Changed varible name * attempt to fix documentation failure in CI * pylint * Added transpile options to every experiment * Made setting transpile_options mandatory, because if basis_gates are taken from backend, then the names of the transpiled clifford files don't match * Split test_rb_utils into itself and test_clifford_utils * Added tests for composing a clifford with a number * Added test for inverse clifford by num * Changed random to rng because of failure on Windows * Removed dependency on Aer for transpile. Removed the method transpile_single_clifford and use transpile() directly instead * Changed parameter backend to be optional, as it was before * Improved format for CLIFF_SINGLE_GATE_MAP, CLIFF_COMPOSE_DATA, CLIFF_INVERSE_DATA * Changed usage from cliff.__repr__ to repr(cliff) * Fixed a bug where transpiled_circuits were loaded multiple times * New algorithm that constructs the Cliffords by layers * Added support for 1 qubits, for full sampling and for interleaved rb * Removed unused files. Black * Added 2 parameters to CliffordUtils.__init__: num_qubits and basis_gates * Removed all parameters num_qubits and use self.num-qubits instead * Removed usage of specific gate sets * moved interleaved element out of StandardRB * Split _build_rb_circuits into small methods to make it more modular * Added tests for CliffordUtils * Added support for cz * Added backend to CliffordInit.__init__. Added transpile to initial circuit created in _build methods * Modified test_correct_1q_depolarization for it to pass * black and pylint * Fixed bug with cz - since it is a symmetrical operation, we store only (cz, [0,1]) in all the Clifford lists. * Fixed the parameters in cliffordUtils methods. Since num_qubits was added as a class member, no need to pass it as a parameter. * Data updated by changes in create_clifford_map.py from previous commit * Fixed two tests. test_correct_1q_depolarization was failing due to too strict assertion. test_interleaving_circuit_with_delay needed to be changed because now returns transpiled circuits. * Changed usage of VGate and WGate to their component gates: s, h, sdg. * Moved transpiled clifford structures outside init to make them static in the class * Added test for two qubit rb in parallel * Moved structures back inside __init__ because the previous change caused a bug * Added back the old code to create RB circuits for more than 2 qubits * Changed InterleavedRB.circuits to call its super() when number of qubits > 2. Added default set of basis gates * Added test for three qubit RB * Documentation * black and pylint * Disabled black and pylint errors on clifford_data.py * Changed _clifford_utils to be a static class member. Added a couple of short methods to reduce code duplication * Updated release notes * Fixed failing test * Fixed bug: _transpile_cliff_layer_0 was ignoring the backend * Documentation * Reverted changes in tutorial as it is not mandatory to supply basis_gates any more * Cleaning up * Cleaning up * black and doc * Fixed bug found in tutorial - added transpile at the beginning of building an interleaved circuit * Added header * black * Cleaning up temporary comments * documentation * Changed order of several methods * Removed -interleave(). It was previously removed in main, but I forgot it in the code * Removed method _set_interleaved_element that was removed in a previous PR and I missed it * Name changed and spaces * Removed empty spaces * typo * Fixed transpilation of interleaved element. Made a few structural changes to the surrounding code
* New algorithm for generating Clifford circuits for single qubit. We generate once all 24 transpiled Cliffords. Then, for every rb_circuit, select Cliffords at random and compose them to a circuit * Changed basis for transpilation to match the one in single_qubit_test. Added parameter to all calls to compose to use inplace=True. Removed redundant method generate_all_transpiled_clifford_circuits * Modified the methods in create_clifford_map so that compose does not use front=True, because I assume front=False when creating the circuits * Changed generation of generation of random numbers to be identical to the previous version of rb_experiment. * Test to run on device * added methods for new algorithm to generate rb circuits: build_rb_circuits, generate_1q_transpiled_clifford_circuits * Added the method _layout_for_rb_single_qubit and added test_full_sampling_single_qubit * In test_full_sampling_single_qubit fixed num_samples to be 1, because otherwise randomization is not identical in the two experiments * Tidied up build_rb_circuits * Added documentation and moved methods * Added test_single_qubit_parallel * Changed name _format_data to format_data because the method wasn't being called by the child class CurveAnalaysis. Added parameter to rb_experiment to determine whether to use the old algorithm or new one * Fixed handling of num_samples>1. Cleaned out prints. Reverted previous change regarding _format_data * Added assertExperimentDone to test_single-qubit_parallel. Fixed parameters for test_full_sampling_single_qubit * Modified assertAllIdentity to support circuits with rz gates * Changed name _new_rb to _transpiled_rb. Also changed default to be False, so that all tests will pass * removed fast_rb.py * removed rb_on_device.py * Removed temporary 'import time' * Added support for interleaved rb single qubit * Fixed handling of interleaved element * Fixed bug caused by change of interface of _buil_rb_circuits after adding support for interleave * added test_number_to_clifford_mapping and fixed the method num_from_1_qubit_clifford * Added support for computation of the Clifford to number mapping of a circuit * Moved setting of interleaved metadata to be under 'if is_interleaved' * Added transpilation of interleaved element before creating the rb circuits. Transformed interleaved element into a transpiled clifford circuit. Added relevant tests * Fixed incorrect parameter 'qubits' in test_non_clifford_interleaved_element * Added support for 'delay' as interleaved element * Moved setting of basis gates to circuits(), because in __init__ the transpile_options are not available yet * Cleaned up setting of tranpile_options in the test. Added call to generate_1q_transpiled_clifford_circuits in InterleavedRB.circuits() * Changed the clifford compose mapping so that the rhs includes only single-gate cliffords. The purpose is to reduce the size of the mapping table * Changed all methods in CliffordUtils to be classmethod * Fixes following changes in CliffordUtils * Changed structure of CLIFF_COMPOSE_DATA to be an array instead of a dict, for performance reasons. The index in the array is computed in compose_num_with_clifford * Improved _layout_for_rb_single_qubit to be more robust * Documentation, black, pylint * black * Removed the parameter transpiled_rb used for choosing whether to use old algorithm or new one. * Cleaning up * Generated transpiled clifford circuits for 2 qubits, and stored in a file. Adding load from this file in circuits() * re-generated transpiled circuits * Added support for compose_num_with_clifford_2q. Added suitable test - test_number_to_clifford_mapping_2q. * Created method load_transpiled_cliff_circuits * Added support for two sets of basis gates and their corresponding transpiled clifford files * United the two class variables _transpiled_cliff_circuits_1q and _transpiled_cliff_circuits_2q to a single dict * Added setting of transpile_options to all tests * Fixed error messages * United methods compose_num_with_clifford and num_from_clifford_single_gate for 1 and 2 qubits. Interface changes in StandardRB towards uniting functionality for 1 and 2 qubits * Unified the format for CLIFF_SINGLE_GATE_MAP_1Q and CLIFF_SINGLE_GATE_MAP_2Q * Added method clifford_inverse_by_num to unite handling of 1 and 2 qubit-rb * Fixes to support 1 and 2 qubits in _build_rb_circuits * Fixed more places where the code assumed 1 qubit rb * Fix for handling of delay. Changed test_interleaving_circuit_with_delay to suit transpiled circuits * changed basis gates in test, because rz is not supported in conversion to Clifford * Extended lenths for test, because test was failing for statistical reasons * changed name of method after addition of 2q * black and lint * black, lint and documentation * black, lint, cleaning * Removed legacy code. Additional cleaning * Removed more legacy code. More cleaning * Removed pylint messages for the data file * pylint, and use method CliffordUtils.file_name * Removed additional legacy code * Release notes * Added missing () * Fixed error message * Added QiskitError to documentation * black * Fixed error message * Changed varible name * attempt to fix documentation failure in CI * pylint * Added transpile options to every experiment * Made setting transpile_options mandatory, because if basis_gates are taken from backend, then the names of the transpiled clifford files don't match * Split test_rb_utils into itself and test_clifford_utils * Added tests for composing a clifford with a number * Added test for inverse clifford by num * Changed random to rng because of failure on Windows * Removed dependency on Aer for transpile. Removed the method transpile_single_clifford and use transpile() directly instead * Changed parameter backend to be optional, as it was before * Improved format for CLIFF_SINGLE_GATE_MAP, CLIFF_COMPOSE_DATA, CLIFF_INVERSE_DATA * Changed usage from cliff.__repr__ to repr(cliff) * Fixed a bug where transpiled_circuits were loaded multiple times * New algorithm that constructs the Cliffords by layers * Added support for 1 qubits, for full sampling and for interleaved rb * Removed unused files. Black * Added 2 parameters to CliffordUtils.__init__: num_qubits and basis_gates * Removed all parameters num_qubits and use self.num-qubits instead * Removed usage of specific gate sets * moved interleaved element out of StandardRB * Split _build_rb_circuits into small methods to make it more modular * Added tests for CliffordUtils * Added support for cz * Added backend to CliffordInit.__init__. Added transpile to initial circuit created in _build methods * Modified test_correct_1q_depolarization for it to pass * black and pylint * Fixed bug with cz - since it is a symmetrical operation, we store only (cz, [0,1]) in all the Clifford lists. * Fixed the parameters in cliffordUtils methods. Since num_qubits was added as a class member, no need to pass it as a parameter. * Data updated by changes in create_clifford_map.py from previous commit * Fixed two tests. test_correct_1q_depolarization was failing due to too strict assertion. test_interleaving_circuit_with_delay needed to be changed because now returns transpiled circuits. * Changed usage of VGate and WGate to their component gates: s, h, sdg. * Moved transpiled clifford structures outside init to make them static in the class * Added test for two qubit rb in parallel * Moved structures back inside __init__ because the previous change caused a bug * Added back the old code to create RB circuits for more than 2 qubits * Changed InterleavedRB.circuits to call its super() when number of qubits > 2. Added default set of basis gates * Added test for three qubit RB * Documentation * black and pylint * Disabled black and pylint errors on clifford_data.py * Changed _clifford_utils to be a static class member. Added a couple of short methods to reduce code duplication * Updated release notes * Fixed failing test * Fixed bug: _transpile_cliff_layer_0 was ignoring the backend * Documentation * Reverted changes in tutorial as it is not mandatory to supply basis_gates any more * Cleaning up * Cleaning up * black and doc * Fixed bug found in tutorial - added transpile at the beginning of building an interleaved circuit * Added header * black * Cleaning up temporary comments * documentation * Changed order of several methods * Removed -interleave(). It was previously removed in main, but I forgot it in the code * Removed method _set_interleaved_element that was removed in a previous PR and I missed it * Name changed and spaces * Removed empty spaces * typo * Fixed transpilation of interleaved element. Made a few structural changes to the surrounding code
* New algorithm for generating Clifford circuits for single qubit. We generate once all 24 transpiled Cliffords. Then, for every rb_circuit, select Cliffords at random and compose them to a circuit * Changed basis for transpilation to match the one in single_qubit_test. Added parameter to all calls to compose to use inplace=True. Removed redundant method generate_all_transpiled_clifford_circuits * Modified the methods in create_clifford_map so that compose does not use front=True, because I assume front=False when creating the circuits * Changed generation of generation of random numbers to be identical to the previous version of rb_experiment. * Test to run on device * added methods for new algorithm to generate rb circuits: build_rb_circuits, generate_1q_transpiled_clifford_circuits * Added the method _layout_for_rb_single_qubit and added test_full_sampling_single_qubit * In test_full_sampling_single_qubit fixed num_samples to be 1, because otherwise randomization is not identical in the two experiments * Tidied up build_rb_circuits * Added documentation and moved methods * Added test_single_qubit_parallel * Changed name _format_data to format_data because the method wasn't being called by the child class CurveAnalaysis. Added parameter to rb_experiment to determine whether to use the old algorithm or new one * Fixed handling of num_samples>1. Cleaned out prints. Reverted previous change regarding _format_data * Added assertExperimentDone to test_single-qubit_parallel. Fixed parameters for test_full_sampling_single_qubit * Modified assertAllIdentity to support circuits with rz gates * Changed name _new_rb to _transpiled_rb. Also changed default to be False, so that all tests will pass * removed fast_rb.py * removed rb_on_device.py * Removed temporary 'import time' * Added support for interleaved rb single qubit * Fixed handling of interleaved element * Fixed bug caused by change of interface of _buil_rb_circuits after adding support for interleave * added test_number_to_clifford_mapping and fixed the method num_from_1_qubit_clifford * Added support for computation of the Clifford to number mapping of a circuit * Moved setting of interleaved metadata to be under 'if is_interleaved' * Added transpilation of interleaved element before creating the rb circuits. Transformed interleaved element into a transpiled clifford circuit. Added relevant tests * Fixed incorrect parameter 'qubits' in test_non_clifford_interleaved_element * Added support for 'delay' as interleaved element * Moved setting of basis gates to circuits(), because in __init__ the transpile_options are not available yet * Cleaned up setting of tranpile_options in the test. Added call to generate_1q_transpiled_clifford_circuits in InterleavedRB.circuits() * Changed the clifford compose mapping so that the rhs includes only single-gate cliffords. The purpose is to reduce the size of the mapping table * Changed all methods in CliffordUtils to be classmethod * Fixes following changes in CliffordUtils * Changed structure of CLIFF_COMPOSE_DATA to be an array instead of a dict, for performance reasons. The index in the array is computed in compose_num_with_clifford * Improved _layout_for_rb_single_qubit to be more robust * Documentation, black, pylint * black * Removed the parameter transpiled_rb used for choosing whether to use old algorithm or new one. * Cleaning up * Generated transpiled clifford circuits for 2 qubits, and stored in a file. Adding load from this file in circuits() * re-generated transpiled circuits * Added support for compose_num_with_clifford_2q. Added suitable test - test_number_to_clifford_mapping_2q. * Created method load_transpiled_cliff_circuits * Added support for two sets of basis gates and their corresponding transpiled clifford files * United the two class variables _transpiled_cliff_circuits_1q and _transpiled_cliff_circuits_2q to a single dict * Added setting of transpile_options to all tests * Fixed error messages * United methods compose_num_with_clifford and num_from_clifford_single_gate for 1 and 2 qubits. Interface changes in StandardRB towards uniting functionality for 1 and 2 qubits * Unified the format for CLIFF_SINGLE_GATE_MAP_1Q and CLIFF_SINGLE_GATE_MAP_2Q * Added method clifford_inverse_by_num to unite handling of 1 and 2 qubit-rb * Fixes to support 1 and 2 qubits in _build_rb_circuits * Fixed more places where the code assumed 1 qubit rb * Fix for handling of delay. Changed test_interleaving_circuit_with_delay to suit transpiled circuits * changed basis gates in test, because rz is not supported in conversion to Clifford * Extended lenths for test, because test was failing for statistical reasons * changed name of method after addition of 2q * black and lint * black, lint and documentation * black, lint, cleaning * Removed legacy code. Additional cleaning * Removed more legacy code. More cleaning * Removed pylint messages for the data file * pylint, and use method CliffordUtils.file_name * Removed additional legacy code * Release notes * Added missing () * Fixed error message * Added QiskitError to documentation * black * Fixed error message * Changed varible name * attempt to fix documentation failure in CI * pylint * Added transpile options to every experiment * Made setting transpile_options mandatory, because if basis_gates are taken from backend, then the names of the transpiled clifford files don't match * Split test_rb_utils into itself and test_clifford_utils * Added tests for composing a clifford with a number * Added test for inverse clifford by num * Changed random to rng because of failure on Windows * Removed dependency on Aer for transpile. Removed the method transpile_single_clifford and use transpile() directly instead * Changed parameter backend to be optional, as it was before * Improved format for CLIFF_SINGLE_GATE_MAP, CLIFF_COMPOSE_DATA, CLIFF_INVERSE_DATA * Changed usage from cliff.__repr__ to repr(cliff) * Fixed a bug where transpiled_circuits were loaded multiple times * New algorithm that constructs the Cliffords by layers * Added support for 1 qubits, for full sampling and for interleaved rb * Removed unused files. Black * Added 2 parameters to CliffordUtils.__init__: num_qubits and basis_gates * Removed all parameters num_qubits and use self.num-qubits instead * Removed usage of specific gate sets * moved interleaved element out of StandardRB * Split _build_rb_circuits into small methods to make it more modular * Added tests for CliffordUtils * Added support for cz * Added backend to CliffordInit.__init__. Added transpile to initial circuit created in _build methods * Modified test_correct_1q_depolarization for it to pass * black and pylint * Fixed bug with cz - since it is a symmetrical operation, we store only (cz, [0,1]) in all the Clifford lists. * Fixed the parameters in cliffordUtils methods. Since num_qubits was added as a class member, no need to pass it as a parameter. * Data updated by changes in create_clifford_map.py from previous commit * Fixed two tests. test_correct_1q_depolarization was failing due to too strict assertion. test_interleaving_circuit_with_delay needed to be changed because now returns transpiled circuits. * Changed usage of VGate and WGate to their component gates: s, h, sdg. * Moved transpiled clifford structures outside init to make them static in the class * Added test for two qubit rb in parallel * Moved structures back inside __init__ because the previous change caused a bug * Added back the old code to create RB circuits for more than 2 qubits * Changed InterleavedRB.circuits to call its super() when number of qubits > 2. Added default set of basis gates * Added test for three qubit RB * Documentation * black and pylint * Disabled black and pylint errors on clifford_data.py * Changed _clifford_utils to be a static class member. Added a couple of short methods to reduce code duplication * Updated release notes * Fixed failing test * Fixed bug: _transpile_cliff_layer_0 was ignoring the backend * Documentation * Reverted changes in tutorial as it is not mandatory to supply basis_gates any more * Cleaning up * Cleaning up * black and doc * Fixed bug found in tutorial - added transpile at the beginning of building an interleaved circuit * Added header * black * Cleaning up temporary comments * documentation * Changed order of several methods * Removed -interleave(). It was previously removed in main, but I forgot it in the code * Removed method _set_interleaved_element that was removed in a previous PR and I missed it * Name changed and spaces * Removed empty spaces * typo * Fixed transpilation of interleaved element. Made a few structural changes to the surrounding code
Improve the performance of transpiled circuit generation in 1Q/2Q StandardRB/InterleavedRB (about 10x speedup in 1Q SRB/IRB and 5x speedup in 2Q SRB/IRB in most cases). Including following feature pull-requests: * New algorithm for RB building Cliffords by layers (#892) * Improve custom transpilation for faster 1Q/2Q RB (#922) * Improve integer-based Clifford operations for 1Q/2Q RB (#940) * Readd support for backends with directed basis gates to RB experiments (#960) Features other than speedup: * Fix performance regression in 3 or more qubits RB (embedded at Refactor RB module for future extensions #898) * Improve validation of interleave_element in InterleavedRB * Restructure tests for RB module * Remove the barriers in front of the first Cliffords in RB circuits Co-authored-by: merav-aharoni <[email protected]> Co-authored-by: Naoki Kanazawa <[email protected]>
Summary
We implement a new algorithm for RB, 1 and 2 qubits.
Details and comments
Here are the main ideas behind the implementation:
qiskit_experiments/library/randomized_benchmarking/clifford_data.py
. The data is generated by the file, in the same directory,create_clifford_map.py
.clifford_data.py
is constant. As a rule,create_clifford_map.py
does not need to be executed unless some overall change is needed.clifford_data.py
as well. There are 9 such Cliffords for 1-qubit, and 21 such Cliffords for 2 qubits. It is sufficient to store the compose table of all-cliffords X single-gate-cliffords, since for every Clifford on the right hand side, we can break it down into single gate Cliffords, and do the composition one at a time. This greatly reduces the storage space for the array of composition results (from O(n^2) to O(n)).clifford_data.py
is if they wish to add a new single-gate Clifford, which is not equivalent to any of the already supported gates. In this case, one needs to add the gate to one of the gate lists increate_clifford_map.py
.CliffordUtils
, so that it now has members fornum_qubits
,basis_gates
and 'backend`. If several RB experiments are run in sequence, e.g., parallel, the class will be updated only if these parameters have changed. This improved performance for cases where the parameters have not changed.circuits()
. The reason for this is that in addition to the changes listed above, I made a change in the high level flow. In the existing code -_sample_circuits
(now for 3+ qubits), first we created sequences of Cliffords and then create circuits out of the sequences. In the code for 1,2 qubits -_build_circuits
, I do not create the sequences. I immediately create the circuits, skipping the sequences step.