Skip to content

Commit

Permalink
Merge pull request #290 from pyGSTio/feature-padded-lines-edesigns
Browse files Browse the repository at this point in the history
Adds edesign padding and tests.
  • Loading branch information
sserita committed Jan 24, 2023
2 parents e0df4f7 + 91bdc3f commit 92ab1df
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 2 deletions.
33 changes: 32 additions & 1 deletion pygsti/tools/edesigntools.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

import numpy as _np


def calculate_edesign_estimated_runtime(edesign, gate_time_dict=None, gate_time_1Q=None,
gate_time_2Q=None, measure_reset_time=0.0,
interbatch_latency=0.0, total_shots_per_circuit=1000,
Expand Down Expand Up @@ -331,3 +330,35 @@ def calculate_fisher_information_matrices_by_L(model, circuits, num_shots=1, ter
prev_L = L

return fisher_information_by_L

def pad_edesign_with_idle_lines(edesign, line_labels):
"""Utility to explicitly pad out ExperimentDesigns with idle lines.
Parameters
----------
edesign: ExperimentDesign
The edesign to be padded.
line_labels: tuple of int or str
Full line labels for the padded edesign.
Returns
-------
ExperimentDesign
An edesign where all circuits have been padded out with missing idle lines
"""
from pygsti.protocols import CombinedExperimentDesign as _CombinedDesign
from pygsti.protocols import SimultaneousExperimentDesign as _SimulDesign

if set(edesign.qubit_labels) == set(line_labels):
return edesign

if isinstance(edesign, _CombinedDesign):
new_designs = {}
for subkey, subdesign in edesign.items():
new_designs[subkey] = pad_edesign_with_idle_lines(subdesign, line_labels)

return _CombinedDesign(new_designs, qubit_labels=line_labels)

# SimultaneousDesign with single design + full qubit labels tensors out the circuits with idle lines
return _SimulDesign([edesign], qubit_labels=line_labels)
98 changes: 97 additions & 1 deletion test/unit/tools/test_edesigntools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from pygsti.baseobjs import Label
from pygsti.modelpacks import smq2Q_XYICNOT, smq1Q_XYI
from pygsti.tools import edesigntools as et
from pygsti.protocols import CircuitListsDesign, SimultaneousExperimentDesign, CombinedExperimentDesign
from pygsti.circuits import Circuit as C

from ..util import BaseCase

Expand Down Expand Up @@ -144,4 +146,98 @@ def test_fisher_information(self):
self.assertArraysAlmostEqual(v, fim_by_L[k])
self.assertLess(10*fim_by_L2_time, fim1_time) # Cached version should be very fast compared to uncached



def test_generic_design_padding(self):
# Create a series of designs with some overlap when they will be padded out
design_124 = CircuitListsDesign([[
C.cast('Gx:Q1Gy:Q1@(Q1,Q2,Q4)'),
C.cast('Gx:Q2Gy:Q2@(Q1,Q2,Q4)'), # Will be repeat with design_2
C.cast('Gx:Q4Gy:Q4@(Q1,Q2,Q4)'), # Will be repeat with design_14 (but only on Q4)
C.cast('Gx:Q1Gy:Q4@(Q1,Q2,Q4)'), # Will be repeat with design_14 (on both Q1 and Q4)
C.cast('[Gx:Q1Gy:Q2][Gy:Q1Gx:Q2]@(Q1,Q2,Q4)') # Will be repeat with sim_design_12
]], qubit_labels=('Q1', 'Q2', 'Q4'))

design_2 = CircuitListsDesign([[
C.cast('Gx:Q2Gy:Q2@(Q2)'), # Repeat from design_124 after padding
C.cast('Gy:Q2@(Q2)')
]], qubit_labels=('Q2',))

design_14 = CircuitListsDesign([[
C.cast('Gx:Q4Gy:Q4@(Q1,Q4)'), # Repeat from design_124 after padding
C.cast('Gx:Q1Gy:Q4@(Q1,Q4)'), # Repeat from design_124 after padding
C.cast('Gx:Q1@(Q1,Q4)')
]], qubit_labels=('Q1', 'Q4'))

sim_design_1 = CircuitListsDesign([[
C.cast('Gx:Q1Gy:Q1@(Q1)'), # Q1 part of repeat from design_124 after padding
C.cast('Gx:Q1Gx:Q1')
]], qubit_labels=('Q1',))

sim_design_2 = CircuitListsDesign([[
C.cast('Gy:Q2Gx:Q2@(Q2)'), # Q2 part of repeat from design_124 after padding
C.cast('Gx:Q2Gx:Q2')
]], qubit_labels=('Q2',))

sim_design_12 = SimultaneousExperimentDesign([sim_design_1, sim_design_2], qubit_labels=('Q1', 'Q2'))

# The expected deduplicated experiment
expected_design_012345 = CircuitListsDesign([[
C.cast('Gx:Q1Gy:Q1@(Q0,Q1,Q2,Q3,Q4,Q5)'), # design_124
C.cast('Gx:Q2Gy:Q2@(Q0,Q1,Q2,Q3,Q4,Q5)'), # design_124 and design_2
C.cast('Gx:Q4Gy:Q4@(Q0,Q1,Q2,Q3,Q4,Q5)'), # design_124 and design_14
C.cast('Gx:Q1Gy:Q4@(Q0,Q1,Q2,Q3,Q4,Q5)'), # design_124 and design_14
C.cast('Gy:Q2@(Q0,Q1,Q2,Q3,Q4,Q5)'), # design_2
C.cast('Gx:Q1@(Q0,Q1,Q2,Q3,Q4,Q5)'), # design_14
C.cast('[Gx:Q1Gy:Q2][Gy:Q1Gx:Q2]@(Q0,Q1,Q2,Q3,Q4,Q5)'), # design_124 and sim_design_12
C.cast('[Gx:Q1Gx:Q2][Gx:Q1Gx:Q2]@(Q0,Q1,Q2,Q3,Q4,Q5)') # sim_design_12
]], qubit_labels=('Q0', 'Q1', 'Q2', 'Q3', 'Q4', 'Q5'))


# Create nested combined designs and test padding
nested_design = CombinedExperimentDesign({
'2': design_2,
'14': design_14
})

full_design = CombinedExperimentDesign({
'124': design_124,
'2+14': nested_design,
'sim_12': sim_design_12
})

# Padding should dedup "repeats" and add qubits before/during/after the current lines
padded_design = et.pad_edesign_with_idle_lines(full_design, ('Q0', 'Q1', 'Q2', 'Q3', 'Q4', 'Q5'))

self.assertTrue(set(padded_design.all_circuits_needing_data) == set(expected_design_012345.all_circuits_needing_data),
"Padded experiment circuits did not match expected experiment circuits")

def test_gst_design_padding(self):
# Get GST designs
gst_1 = smq1Q_XYI.create_gst_experiment_design(8, ('Q1',))
gst_2 = smq1Q_XYI.create_gst_experiment_design(8, ('Q2',))
gst_12 = smq2Q_XYICNOT.create_gst_experiment_design(8, ('Q1', 'Q2'))

# Get nested combined design
nested_12 = CombinedExperimentDesign({
'1': gst_1,
'2': gst_2,
})

full_gst = CombinedExperimentDesign({
'1+2': nested_12,
'12': gst_12
})

# Pad and test
padded_gst_design = et.pad_edesign_with_idle_lines(full_gst, ('Q1', 'Q2'))

padded_circs_1 = [circ.insert_idling_lines(None, ('Q2',)) for circ in gst_1.all_circuits_needing_data]
self.assertTrue(set(padded_gst_design.all_circuits_needing_data).issuperset(set(padded_circs_1)),
"GST on qubit 1 was not a subset of padded experiment design")

padded_circs_2 = [circ.insert_idling_lines('Q2', ('Q1',)) for circ in gst_2.all_circuits_needing_data]
self.assertTrue(set(padded_gst_design.all_circuits_needing_data).issuperset(set(padded_circs_2)),
"GST on qubit 2 was not a subset of the padded experiment design")

self.assertTrue(set(padded_gst_design.all_circuits_needing_data).issuperset(set(gst_12.all_circuits_needing_data)),
"2Q GST was not a subset of the padded experiment design")

0 comments on commit 92ab1df

Please sign in to comment.