#!/usr/bin/env python # coding: utf-8 # # An example of how to run GST on a 2-qubit system # This example gives an overview of the typical steps used to perform an end-to-end (i.e. experimental-data-to-report) Gate Set Tomography analysis on a 2-qubit system. The steps are very similar to the single-qubit case described in the tutorials, but we thought 2Q-GST is an important enough topic to deserve a separate example. # In[1]: from __future__ import print_function import pygsti # ### Step 1: Construct the desired 2-qubit gateset # Since the purpose of this example is to show how to *run* 2Q-GST, we'll just use a built-in "standard" 2-qubit gate set. (Another example covers how to create a custom 2-qubit gate set.) # In[2]: from pygsti.construction import std2Q_XYICNOT gs_target = std2Q_XYICNOT.gs_target.copy() #copying is good practice so we don't inadvertetly mess up std2Q_XYCNOT.gs_target # ### Step 2: Obtain lists of fiducial and germ gate sequences # These are the building blocks of the gate sequences performed in the experiment. Typically, these lists are either provided by pyGSTi because you're using a "standard" gate set (as we are here), or computed using the "fiducial selection" and "germ selection" algorithms which are a part of pyGSTi and covered in the tutorials. Since 2Q-GST with the 71 germs of the complete set would take a while, we'll also create a couple of small germ sets to demonstrate 2Q-GST more quickly (because we know you have important stuff to do). # In[3]: prep_fiducials = std2Q_XYICNOT.prepStrs effect_fiducials = std2Q_XYICNOT.effectStrs # In[4]: germs4 = pygsti.construction.gatestring_list( [ ('Gix',), ('Giy',), ('Gxi',), ('Gyi',) ] ) germs11 = pygsti.construction.gatestring_list( [ ('Gix',), ('Giy',), ('Gxi',), ('Gyi',), ('Gcnot',), ('Gxi','Gyi'), ('Gix','Giy'), ('Gix','Gcnot'), ('Gxi','Gcnot'), ('Giy','Gcnot'), ('Gyi','Gcnot') ] ) germs71 = std2Q_XYICNOT.germs # ### Step 3: Data generation # Now that fiducial and germ strings have been found, we can generate the list of experiments needed to run GST, just like in the 1-qubit case. As an additional input we'll need a list of lengths indicating the maximum length strings to use on each successive GST iteration. # In[5]: #A list of maximum lengths for each GST iteration - typically powers of 2 up to # the longest experiment you can glean information from. Here we just pick 2 so things run quickly. maxLengths = [1,2] # 4,16,32... #Create a list of GST experiments for this gateset, with #the specified fiducials, germs, and maximum lengths. We use #"germs4" here so that the tutorial runs quickly; really, you'd #want to use germs71! listOfExperiments = pygsti.construction.make_lsgst_experiment_list(gs_target.gates.keys(), prep_fiducials, effect_fiducials, germs4, maxLengths) #Create an empty dataset file, which stores the list of experiments # and zerod-out columns where data should be inserted. Note the use of the SPAM # labels in the "Columns" header line. pygsti.io.write_empty_dataset("example_files/My2QDataTemplate.txt", listOfExperiments, "## Columns = 00 count, 01 count, 10 count, 11 count") # In[6]: #Generate some "fake" (simulated) data based on a depolarized version of the target gateset gs_datagen = gs_target.depolarize(gate_noise=0.1, spam_noise=0.001) ds = pygsti.construction.generate_fake_data(gs_datagen, listOfExperiments, nSamples=1000, sampleError="multinomial", seed=2016) #if you have a dataset file with real data in it, load it using something like: #ds = pygsti.io.load_dataset("mydir/My2QDataset.txt") # ### Step 4: Run GST using `do_long_sequence_gst` # Just like for 1-qubit GST, we call the driver routine `do_long_sequence_gst` to compute the GST estimates. Usually for two qubits this could take a long time (hours on a single cpu) based on the number of gate sequences used, and running on multiple processors is a good idea (see the MPI example). However, since we chose an incomplete set of only 4 germs and set our maximum max-length to 2, this will run fairly quickly (~10min). # # Some notes about the options/arguments to `do_long_sequence_gst` that are particularly relevant to 2-qubit GST: # - `memoryLimit` gives an estimate of how much memory is available to use on your system (in bytes). This is currently *not* a hard limit, and pyGSTi may require slightly more memory than this "limit". So you'll need to be conservative in the value you place here: if your machine has 10GB of RAM, set this to 6 or 8 GB initially and increase it as you see how much memory is actually used using a separate OS performance monitor tool. If you're running on multiple processors, this should be the memory available *per processor*. # - `verbosity` tells the routine how much detail to print to stdout. If you don't mind waiting a while without getting any output, you can leave this at its default value (2). If you can't standing wondering whether GST is still running or has locked up, set this to 3. # - `advancedOptions` is a dictionary that accepts various "advanced" settings that aren't typically needed. While we don't require its use below, the `depolarizeStart` key of this dictionary may be useful in certain cases: it gives an amount (in [0,1]) to depolarize the (LGST) estimate that is used as the initial guess for long-sequence GST. In practice, we find that, sometime, in the larger 2-qubit Hilbert space, the LGST estimate may be so poor as to adversely affect the subsequent long-sequence GST (e.g. very slow convergence). Depolarizing the LGST estimate can remedy this. If you're unsure what to put here, either don't specify `depolarizeLGST` at all (the same as using 0.0), or just use 0.1, i.e. `advancedOptions={ 'depolarizeStart' : 0.1 }`. # In[7]: import time start = time.time() results = pygsti.do_long_sequence_gst(ds, gs_target, prep_fiducials, effect_fiducials, germs4, maxLengths, gaugeOptParams={'itemWeights': {'spam':0.1,'gates': 1.0}}, memLimit=3*(1024)**3, verbosity=3 ) end = time.time() print("Total time=%f hours" % ((end - start) / 3600.0)) # ### Step 5: Create report(s) using the returned `Results` object # The `Results` object returned from `do_long_sequence_gst` can be used to generate a "general" HTML report, just as in the 1-qubit case: # In[8]: pygsti.report.create_standard_report(results, filename="example_files/easy_2q_report", title="Example 2Q-GST Report", verbosity=2) # Now open [example_files/easy_2q_report/main.html](example_files/easy_2q_report/main.html) to see the results. You've run 2-qubit GST! # # You can save the `Results` object for later by just pickling it: # In[9]: import pickle with open("example_files/easy_2q_results.pkl","wb") as pklfile: pickle.dump(results, pklfile) # In[ ]: