0.1 WavesExecuter#
Basic Usage#
This QurriumInstance
does not any post-processing feature but provides a workdlow that can execute multiple at once.
a. Import the instances#
from qurry import WavesExecuter
experiment_workflow = WavesExecuter()
b. Preparing quantum circuit#
Remember for any quantum circuit, you need to make sure that they all contain classical registers.
Otherwise, WavesExecuter
will raise an ValueError
when you try to execute the circuit.
from qiskit import QuantumCircuit
from qurry.recipe import TrivialParamagnet, GHZ
def make_neel_circuit(n):
qc = QuantumCircuit(n)
for i in range(0, n, 2):
qc.x(i)
return qc
circuits_dict = {}
for i in range(2, 13, 2):
circuits_dict[f"trivial_paramagnet_{i}_ms"] = TrivialParamagnet(i)
circuits_dict[f"ghz_{i}_ms"] = GHZ(i)
circuits_dict[f"neel_{i}_ms"] = make_neel_circuit(i)
for name, circuit in circuits_dict.items():
circuit.measure_all()
no_creq = TrivialParamagnet(2)
print(no_creq.draw())
try:
experiment_workflow.measure([no_creq], shots=1024)
except ValueError as e:
print(f"Error: {e}")
┌───┐
q_0: ┤ H ├
├───┤
q_1: ┤ H ├
└───┘
Error: | No classical register in ALL circuits, counts will be empty. Please add classical register to the circuit. (Don't be frustrated, I did the same thing on unit test. It made me confused and thought what's wrong for a while before ('_').)
c. Execute the circuit#
i. Directly input the circuit#
After executing, it will return a uuid of experiment. You can use this uuid to get the result of the experiment.
exp1 = experiment_workflow.measure(list(circuits_dict.values()), shots=1024)
exp1
'f7fb93b4-d567-4038-87fb-655a906f0c1a'
Each experiment result will be stored in a container .exps
.
experiment_workflow.exps[exp1]
<WavesExecuterExperiment(exp_id=f7fb93b4-d567-4038-87fb-655a906f0c1a,
WavesExecuterArguments(exp_name='experiment.waves_executer'),
Commonparams(exp_id='f7fb93b4-d567-4038-87fb-655a906f0c1a', target_keys=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], shots=1024, backend=<AerSimulator('aer_simulator')>, run_args={}, transpile_args={}, tags=(), save_location=PosixPath('.'), serial=None, summoner_id=None, summoner_name=None, datetimes=DatetimeDict({'build': '2025-06-26 11:47:19', 'run.001': '2025-06-26 11:47:19'})),
unused_args_num=0,
analysis_num=0))>
WavesExecuter
does not provide any post-processing feature.
So .analyze()
will not provide any useful information, but
The Answer to the Ultimate Question of Life, The Universe, and Everything
report01 = experiment_workflow.exps[exp1].analyze()
report01
| ultimate_question:
<WavesQurryAnalysis(
serial=0,
WEAnalysisInput(ultimate_question=''),
WEAnalysisContent(ultimate_answer=42, dummy=-100)),
unused_args_num=0
)>
main01, side_product01 = report01.export()
main01
{'ultimate_answer': 42,
'dummy': -100,
'input': {'ultimate_question': ''},
'header': {'serial': 0, 'datetime': '2025-06-26 11:47:19', 'log': {}}}
ii. Add the circuits to container .waves
, then call them later.#
Since we have executed an experiment, the circuit we input in exp1
is stored in the container .waves
with serial number 0
.
experiment_workflow.waves
WaveContainer({
0: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c95f27a0>,
1: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94bc6e0>,
2: <qurry.recipe.simple.cat.GHZ object at 0x7632c94bc830>,
3: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b97f0>,
4: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9752c10>,
5: <qurry.recipe.simple.cat.GHZ object at 0x7632c9752d50>,
6: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b99b0>,
7: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9752e90>,
8: <qurry.recipe.simple.cat.GHZ object at 0x7632c9752fd0>,
9: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b98d0>,
10: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94715b0>,
11: <qurry.recipe.simple.cat.GHZ object at 0x7632c94716e0>,
12: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9a90>,
13: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9471a70>,
14: <qurry.recipe.simple.cat.GHZ object at 0x7632c9471ba0>,
15: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9e10>,
16: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94c43b0>,
17: <qurry.recipe.simple.cat.GHZ object at 0x7632c94c4050>,
18: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9c50>})
But we can also add the circuit to the container .waves
with a custom name.
The name should be unique, otherwise it will be overwritten.
The method add
will return the actual name of the circuit in the container.
for k, v in circuits_dict.items():
print("| Circuit:", experiment_workflow.add(v, k), "added.")
| Circuit: trivial_paramagnet_2_ms added.
| Circuit: ghz_2_ms added.
| Circuit: neel_2_ms added.
| Circuit: trivial_paramagnet_4_ms added.
| Circuit: ghz_4_ms added.
| Circuit: neel_4_ms added.
| Circuit: trivial_paramagnet_6_ms added.
| Circuit: ghz_6_ms added.
| Circuit: neel_6_ms added.
| Circuit: trivial_paramagnet_8_ms added.
| Circuit: ghz_8_ms added.
| Circuit: neel_8_ms added.
| Circuit: trivial_paramagnet_10_ms added.
| Circuit: ghz_10_ms added.
| Circuit: neel_10_ms added.
| Circuit: trivial_paramagnet_12_ms added.
| Circuit: ghz_12_ms added.
| Circuit: neel_12_ms added.
If there is a circuit with the same name, it will be replaced by the new one.
print(experiment_workflow.add(circuits_dict["trivial_paramagnet_2_ms"], "ghz_8_ms"))
print(experiment_workflow.waves["ghz_8_ms"])
ghz_8_ms
┌───┐ ░ ┌─┐
q_0: ┤ H ├─░─┤M├───
├───┤ ░ └╥┘┌─┐
q_1: ┤ H ├─░──╫─┤M├
└───┘ ░ ║ └╥┘
meas: 2/═════════╩══╩═
0 1
Otherwise, you will need to use replace="duplicate"
to prevent it from being replaced.
duplicated_case01 = experiment_workflow.add(
circuits_dict["trivial_paramagnet_2_ms"], "ghz_8_ms", replace="duplicate"
)
print(duplicated_case01)
print(experiment_workflow.waves[duplicated_case01])
ghz_8_ms.37
┌───┐ ░ ┌─┐
q_0: ┤ H ├─░─┤M├───
├───┤ ░ └╥┘┌─┐
q_1: ┤ H ├─░──╫─┤M├
└───┘ ░ ║ └╥┘
meas: 2/═════════╩══╩═
0 1
Now we have prepared the circuit and stored it in the container .waves
.
experiment_workflow.waves
WaveContainer({
0: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c95f27a0>,
1: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94bc6e0>,
2: <qurry.recipe.simple.cat.GHZ object at 0x7632c94bc830>,
3: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b97f0>,
4: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9752c10>,
5: <qurry.recipe.simple.cat.GHZ object at 0x7632c9752d50>,
6: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b99b0>,
7: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9752e90>,
8: <qurry.recipe.simple.cat.GHZ object at 0x7632c9752fd0>,
9: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b98d0>,
10: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94715b0>,
11: <qurry.recipe.simple.cat.GHZ object at 0x7632c94716e0>,
12: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9a90>,
13: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9471a70>,
14: <qurry.recipe.simple.cat.GHZ object at 0x7632c9471ba0>,
15: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9e10>,
16: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94c43b0>,
17: <qurry.recipe.simple.cat.GHZ object at 0x7632c94c4050>,
18: <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9c50>,
'trivial_paramagnet_2_ms': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94bc6e0>,
'ghz_2_ms': <qurry.recipe.simple.cat.GHZ object at 0x7632c94bc830>,
'neel_2_ms': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b97f0>,
'trivial_paramagnet_4_ms': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9752c10>,
'ghz_4_ms': <qurry.recipe.simple.cat.GHZ object at 0x7632c9752d50>,
'neel_4_ms': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b99b0>,
'trivial_paramagnet_6_ms': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9752e90>,
'ghz_6_ms': <qurry.recipe.simple.cat.GHZ object at 0x7632c9752fd0>,
'neel_6_ms': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b98d0>,
'trivial_paramagnet_8_ms': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94715b0>,
'ghz_8_ms': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94bc6e0>,
'neel_8_ms': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9a90>,
'trivial_paramagnet_10_ms': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c9471a70>,
'ghz_10_ms': <qurry.recipe.simple.cat.GHZ object at 0x7632c9471ba0>,
'neel_10_ms': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9e10>,
'trivial_paramagnet_12_ms': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94c43b0>,
'ghz_12_ms': <qurry.recipe.simple.cat.GHZ object at 0x7632c94c4050>,
'neel_12_ms': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7632c94b9c50>,
'ghz_8_ms.37': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x7632c94bc6e0>})
Finally, we can execute the circuit and get the result.
exp2 = experiment_workflow.measure(list(circuits_dict.keys()), shots=1024)
exp2
'd0bb1e3c-b586-49ba-8c35-e8c49ad25c0f'
experiment_workflow.exps[exp2]
<WavesExecuterExperiment(exp_id=d0bb1e3c-b586-49ba-8c35-e8c49ad25c0f,
WavesExecuterArguments(exp_name='experiment.waves_executer'),
Commonparams(exp_id='d0bb1e3c-b586-49ba-8c35-e8c49ad25c0f', target_keys=['trivial_paramagnet_2_ms', 'ghz_2_ms', 'neel_2_ms', 'trivial_paramagnet_4_ms', 'ghz_4_ms', 'neel_4_ms', 'trivial_paramagnet_6_ms', 'ghz_6_ms', 'neel_6_ms', 'trivial_paramagnet_8_ms', 'ghz_8_ms', 'neel_8_ms', 'trivial_paramagnet_10_ms', 'ghz_10_ms', 'neel_10_ms', 'trivial_paramagnet_12_ms', 'ghz_12_ms', 'neel_12_ms'], shots=1024, backend=<AerSimulator('aer_simulator')>, run_args={}, transpile_args={}, tags=(), save_location=PosixPath('.'), serial=None, summoner_id=None, summoner_name=None, datetimes=DatetimeDict({'build': '2025-06-26 11:47:25', 'run.001': '2025-06-26 11:47:25'})),
unused_args_num=0,
analysis_num=0))>
report02 = experiment_workflow.exps[exp2].analyze(
"What is the answer to the ultimate question of life, the universe, and everything"
)
report02
| ultimate_question: What is the answer to the ultimate question of life, the universe, and everything
<WavesQurryAnalysis(
serial=0,
WEAnalysisInput(ultimate_question='What is the answer to the ultimate question of life, the universe, and everything'),
WEAnalysisContent(ultimate_answer=42, dummy=-100)),
unused_args_num=0
)>
d. take counts
#
print("| First 2 counts of the second experiment:")
experiment_workflow.exps[exp2].afterwards.counts[:2]
| First 2 counts of the second experiment:
[{'11': 274, '10': 251, '00': 239, '01': 260}, {'00': 515, '11': 509}]
e. Export them after all#
exp1_id, exp1_files_info = experiment_workflow.exps[exp1].write(
save_location=".", # where to save files
)
exp1_files_info
{'folder': 'experiment.waves_executer.001',
'qurryinfo': 'experiment.waves_executer.001/qurryinfo.json',
'args': 'experiment.waves_executer.001/args/experiment.waves_executer.001.id=f7fb93b4-d567-4038-87fb-655a906f0c1a.args.json',
'advent': 'experiment.waves_executer.001/advent/experiment.waves_executer.001.id=f7fb93b4-d567-4038-87fb-655a906f0c1a.advent.json',
'legacy': 'experiment.waves_executer.001/legacy/experiment.waves_executer.001.id=f7fb93b4-d567-4038-87fb-655a906f0c1a.legacy.json',
'reports': 'experiment.waves_executer.001/reports/experiment.waves_executer.001.id=f7fb93b4-d567-4038-87fb-655a906f0c1a.reports.json'}
Post-Process Availablities and Version Info#
from qurry.process import AVAIBILITY_STATESHEET
AVAIBILITY_STATESHEET
| Qurrium version: 0.13.0
---------------------------------------------------------------------------
### Qurrium Post-Processing
- Backend Availability ................... Python Cython Rust JAX
- randomized_measure
- entangled_entropy.entropy_core_2 ....... Yes Depr. Yes No
- entangle_entropy.purity_cell_2 ......... Yes Depr. Yes No
- entangled_entropy_v1.entropy_core ...... Yes Depr. Yes No
- entangle_entropy_v1.purity_cell ........ Yes Depr. Yes No
- wavefunction_overlap.echo_core_2 ....... Yes Depr. Yes No
- wavefunction_overlap.echo_cell_2 ....... Yes Depr. Yes No
- wavefunction_overlap_v1.echo_core ...... Yes Depr. Yes No
- wavefunction_overlap_v1.echo_cell ...... Yes Depr. Yes No
- hadamard_test
- purity_echo_core ....................... Yes No Yes No
- magnet_square
- magnsq_core ............................ Yes No Yes No
- string_operator
- strop_core ............................. Yes No Yes No
- classical_shadow
- rho_m_core ............................. Yes No No Yes
- utils
- randomized ............................. Yes Depr. Yes No
- counts_process ......................... Yes No Yes No
- bit_slice .............................. Yes No Yes No
- dummy .................................. Yes No Yes No
- test ................................... Yes No Yes No
---------------------------------------------------------------------------
+ Yes ...... Working normally.
+ Error .... Exception occurred.
+ No ....... Not supported.
+ Depr. .... Deprecated.
---------------------------------------------------------------------------
by <Hoshi>