Guide: Tracking quantum experiments¶
In this guide we will show you how to keep track of your quantum experiments.
First we introduce glossary: - Trial
is a tracking class which wraps a single execution of your quantum experiment - Storage
is a class responsible for storing trial data
We will show simple example of measuring expectation value of an observable and how to track all information about this experiment.
Let’s start with importing necessary modules.
[1]:
import os
from qiskit.circuit.random import random_circuit
from qiskit.quantum_info.random import random_pauli
from qiskit.primitives import Estimator
from purplecaffeine.core import Trial, LocalStorage
Next we need to define some variables, circuit and observable
[2]:
n_qubits = 4
depth = 3
shots = 2000
circuit = random_circuit(n_qubits, depth)
circuit.draw(fold=-1)
[2]:
┌────┐ q_0: ────────────────────────────■────────────────────┤ √X ├──────■──────── ┌────────────┐ │ ├───┬┘ │ ┌─────┐ q_1: ┤ Rz(4.2568) ├──────────────┼────────────────────┤ S ├───────┼─┤ Tdg ├ ├────────────┤ │ ┌────┴───┴─────┐ │ └─────┘ q_2: ┤ Rz(3.9296) ├──────────────┼───────────────┤0 ├─■──────── └────────────┘┌─────────────┴──────────────┐│ Ryy(5.7992) │ │ q_3: ──────────────┤ U3(0.057242,4.0814,3.8183) ├┤1 ├─■──────── └────────────────────────────┘└──────────────┘
[3]:
obs = random_pauli(n_qubits)
obs
[3]:
Pauli('YIIZ')
We also need a place where we will store data about our trials. In this example we will be using LocalStorage
which stores information locally in a folder that you configured. We will set our folder for trials to be ./trials
.
[4]:
local_storage = LocalStorage("./trials")
#You could also set the API storage or S3 storage by calling :
#api_storage = ApiStorage(host="http://localhost:8000", username="MY_USERNAME", password="MY_PASS")
#s3_storage = S3Storage("bucket", access_key="MY_KEY", secret_access_key="MY_SECRET")
In order to track our actions we need to work with Trial
class, give it a name Example trial
, pass our local_storage
as storage option and start context (python with
statement).
Within this context we can call list of different methods on trial
object. Some of them are: - add_parameter
adds parameters to the trial, which can be storage names, depth, number of qubits, etc. - add_metric
adds metric to the trial, which can represent measurable outcome of this trial. Ex: history of vqe iterations, results of measurement, etc. - add_circuit
adds circuit to the trial to understand what circuits where used in your work - add_operator
adds operator to the
trial to understand what observables/operators where used in your work
[5]:
with Trial("Example trial", storage=local_storage) as trial:
# track some parameters
trial.add_parameter("estimator", "qiskit.primitives.Estimator")
trial.add_parameter("depth", depth)
trial.add_parameter("n_qubits", n_qubits)
trial.add_parameter("shots", shots)
# track objects of interest
trial.add_circuit("circuit", circuit)
trial.add_operator("obs", obs)
# run
exp_value = Estimator().run(circuit, obs, shots=shots).result().values.item()
# track results of run
trial.add_metric("exp_value", exp_value)
We can get list of all experiments by calling list
method on storage object.
[6]:
local_storage.list()
[6]:
[<Trial [Example trial] 88b5ef54-a66b-45e1-aed8-c7db7ad82594>,
<Trial [Example trial] b418c1d2-11d7-424a-bef8-8c5c8d9976aa>,
<Trial [Example trial] b47737a7-deac-46ae-af11-5bd587c0b688>,
<Trial [Example trial] 2ef8eaca-0fd5-4e21-9257-1e080ed85ed2>]
We can quiery existing experiments by name by calling get
method on storage object and passing name of your example
[7]:
trials = local_storage.list()
random_trial = trials[0]
trial_uuid = random_trial.uuid
local_storage.get(trial_uuid)
[7]:
<Trial [Example trial] 88b5ef54-a66b-45e1-aed8-c7db7ad82594>