Skip to content

Commit

Permalink
Merge branch 'develop' into feature/leakage-RB
Browse files Browse the repository at this point in the history
  • Loading branch information
BillyKalfus committed Dec 17, 2019
2 parents d60d109 + 2ac324a commit c1488c6
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 29 deletions.
7 changes: 3 additions & 4 deletions .travis.yml
Expand Up @@ -5,8 +5,8 @@ language: python
python:
- 3.6
env:
- CONDA_TYPE=miniconda CONDA_VERS=https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
- CONDA_TYPE=miniconda CONDA_VERS=https://repo.continuum.io/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh
- CONDA_TYPE=miniconda CONDA_VERS=https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh UPDATE_CONDA="true"
- CONDA_TYPE=miniconda CONDA_VERS=https://repo.continuum.io/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh UPDATE_CONDA=""

before_install:
# install git lfs and fetch test data
Expand All @@ -32,8 +32,7 @@ install:
- export PATH="$HOME/miniconda/bin:$PATH"
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda install -c anaconda setuptools
- conda update -q conda
- if [ $UPDATE_CONDA ]; then conda update -q conda; fi
# Useful for debugging any issues with conda
- conda info -a

Expand Down
69 changes: 58 additions & 11 deletions QGL/ChannelLibraries.py
Expand Up @@ -147,17 +147,6 @@ def ls(self):
table_code += f"<tr><td>{id}</td><td>{y}</td><td>{d}</td><td>{t}</td><td>{label}</td><td>{notes}</td></tr>"
display(HTML(f"<table><tr><th>id</th><th>Year</th><th>Date</th><th>Time</th><th>Name</th><th>Notes</th></tr><tr>{table_code}</tr></table>"))

def cal_ls(self):
''' List of auspex.pulse_calibration results '''
caldb = bbndb.calibration.Calibration
c = self.session.query(caldb.sample_id, caldb.name, caldb.value, caldb.date).order_by(-Channels.ChannelDatabase.id).all()
table_code = ""
for i, (id, sample_id, name, value, time) in enumerate(c):
d,t = str(time).split()
sample = self.session.query(bbndb.calibration.Sample).filter_by(id=sample_id).first()
table_code += f"<tr><td>{id}</td><td>{d}</td><td>{t.split('.')[0]}</td><td>{sample.name}</td><td>{name}</td><td>{round(value,9)}</td></tr>"
display(HTML(f"<table><tr><th>id</th><th>Date</th><th>Time</th><th>Sample</th><th>Name</th><th>Value</th></tr><tr>{table_code}</tr></table>"))

def ent_by_type(self, obj_type, show=False):
q = self.session.query(obj_type).filter(obj_type.channel_db.has(label="working")).order_by(obj_type.label).all()
if show:
Expand Down Expand Up @@ -273,6 +262,61 @@ def spike_at(f):
figs.append(Figure(marks=lines+[labels], axes=[ax, ay], title=f"{ss} Frequency Plan"))
return HBox(figs)

def diff(self, name1, name2, index1=1, index2=1):
'''
Compare 2 channel library versions. Print the difference between 2 libraries, including parameter values and channel allocations. It requires both versions to be saved in the same sqlite database.
Args
name1: name of first version to compare
name2: name of second version to compare
index1, index2: by default, loading the most recent instances for the given names. Specifying index1/2 = 2 will select the second most recent instance etc."""
'''
cdb = Channels.ChannelDatabase
db1 = self.session.query(cdb).filter(cdb.label==name1).order_by(cdb.time.desc())[-1*index1]
db2 = self.session.query(cdb).filter(cdb.label==name2).order_by(cdb.time.desc())[-1*index2]
copied_db1 = bbndb.deepcopy_sqla_object(db1)
copied_db2 = bbndb.deepcopy_sqla_object(db2)
dict_1 = {c.label: c for c in copied_db1.channels + copied_db1.all_instruments()}
dict_2 = {c.label: c for c in copied_db2.channels + copied_db2.all_instruments()}
def iter_diff(value_iter1, value_iter2, ct, label=''):
table_code = ''
for key, key2 in zip(value_iter1, value_iter2):
if key in ['_sa_instance_state', 'channel_db']:
continue
if isinstance(value_iter1, dict):
cmp1 = value_iter1[key]
cmp2 = value_iter2[key]
if label in value_iter1:
label = value_iter1['label']
elif isinstance(value_iter1, list):
cmp1 = key
cmp2 = key2
else:
cmp1 = getattr(value_iter1, key)
cmp2 = getattr(value_iter2, key)
if (cmp1 == None) ^ (cmp2 == None):
table_code += f"<tr><td>{label}</td><td>{key}</td><td>{cmp1}</td><td>{cmp2}</td></tr>"
continue
if (cmp1 == None) or (cmp2 == None) or ((isinstance(cmp1, dict) or isinstance(cmp1, list)) and len(cmp1) == 0):
continue
if isinstance(cmp1, (bbndb.qgl.DatabaseItem, bbndb.qgl.Channel, bbndb.qgl.Instrument)):
cmp1 = cmp1.__dict__
cmp2 = cmp2.__dict__
if isinstance(cmp1, (dict, list, bbndb.qgl.DatabaseItem, bbndb.qgl.Channel, bbndb.qgl.Instrument)):
if ct<1: # up to 2 recursion levels for now, to avoid infinite loops for bidirectional relations
ct+=1
table_code += iter_diff(cmp1, cmp2, ct, label=label)
break
if cmp1 != cmp2:
table_code += f"<tr><td>{label}</td><td>{key}</td><td>{cmp1}</td><td>{cmp2}</td></tr>"
return table_code

table_code = ''
for chan, value in dict_1.items():
this_dict = value.__dict__
ct = 0
table_code += iter_diff(this_dict, dict_2[chan].__dict__, ct, chan)
display(HTML(f"<table><tr><th>Object</th><th>Parameter</th><th>{name1}</th><th>{name2}</th></tr><tr>{table_code}</tr></table>"))

def receivers(self):
return self.ent_by_type(Channels.Receiver)

Expand All @@ -285,6 +329,9 @@ def transceivers(self):
def qubits(self):
return self.ent_by_type(Channels.Qubit)

def edges(self):
return self.ent_by_type(Channels.Edge)

def meas(self):
return self.ent_by_type(Channels.Measurement)

Expand Down
6 changes: 5 additions & 1 deletion QGL/PulseSequencer.py
Expand Up @@ -47,7 +47,11 @@ def __new__(cls, label, channel, shapeParams, amp=1.0, phase=0, frameChange=0, i
for param in requiredParams:
if param not in shapeParams.keys():
raise NameError("shapeParams must include {0}".format(param))
isTimeAmp = (shapeParams['shape_fun'] == PulseShapes.constant)
if isinstance(shapeParams['shape_fun'],str):
shape = getattr(PulseShapes, shapeParams['shape_fun'])
else:
shape = shapeParams['shape_fun']
isTimeAmp = (shape == PulseShapes.constant)
isZero = (amp == 0)
return super(cls, Pulse).__new__(cls, label, channel,
shapeParams['length'], amp, phase,
Expand Down
22 changes: 13 additions & 9 deletions QGL/drivers/APS2Pattern.py
Expand Up @@ -47,8 +47,9 @@
MAX_NUM_INSTRUCTIONS = 2**26
MAX_REPEAT_COUNT = 2**16 - 1
MAX_TRIGGER_COUNT = 2**32 - 1

MAX_VRAM_ADDRESS = 2**(12-2)-1
MODULATION_CLOCK = 300e6
NUM_NCO = 4

# instruction encodings
WFM = 0x0
Expand Down Expand Up @@ -581,13 +582,19 @@ def to_instruction(self, write_flag=True, label=None):
MODULATOR_OP_OFFSET = 44
NCO_SELECT_OP_OFFSET = 40

nco_select_bits = {1 : 0b0001,
2 : 0b0010,
3 : 0b0100,
4 : 0b1000,
15: 0b1111}[self.nco_select]

op_code_map = {"MODULATE": 0x0,
"RESET_PHASE": 0x2,
"SET_FREQ": 0x6,
"SET_PHASE": 0xa,
"UPDATE_FRAME": 0xe}
payload = (op_code_map[self.instruction] << MODULATOR_OP_OFFSET) | (
self.nco_select << NCO_SELECT_OP_OFFSET)
(nco_select_bits) << NCO_SELECT_OP_OFFSET)
if self.instruction == "MODULATE":
#zero-indexed quad count
payload |= np.uint32(self.length / ADDRESS_UNIT - 1)
Expand Down Expand Up @@ -615,9 +622,9 @@ def inject_modulation_cmds(seqs):
for ct,seq in enumerate(seqs):
#check whether we have modulation commands
freqs = np.unique([entry.frequency for entry in filter(lambda s: isinstance(s,Compiler.Waveform), seq)])
if len(freqs) > 2:
raise Exception("Max 2 frequencies on the same channel allowed.")
no_freq_cmds = np.all(np.less(np.abs(freqs), 1e-8))
if len(freqs) > NUM_NCO:
raise Exception("Max {} frequencies on the same channel allowed.".format(NUM_NCO))
no_freq_cmds = np.allclose(freqs, 0)
phases = [entry.phase for entry in filter(lambda s: isinstance(s,Compiler.Waveform), seq)]
no_phase_cmds = np.all(np.less(np.abs(phases), 1e-8))
frame_changes = [entry.frameChange for entry in filter(lambda s: isinstance(s,Compiler.Waveform), seq)]
Expand All @@ -641,7 +648,7 @@ def inject_modulation_cmds(seqs):
#heuristic to insert phase reset before trigger if we have modulation commands
if isinstance(entry, ControlFlow.Wait):
if not ( no_modulation_cmds and (cur_freq == 0) and (cur_phase == 0)):
mod_seq.append(ModulationCommand("RESET_PHASE", 0x3))
mod_seq.append(ModulationCommand("RESET_PHASE", 0xF))
for nco_ind, freq in enumerate(freqs):
mod_seq.append( ModulationCommand("SET_FREQ", nco_ind + 1, frequency = -freq) )
elif isinstance(entry, ControlFlow.Return):
Expand Down Expand Up @@ -1139,8 +1146,6 @@ def start_new_seq():
wf_len = struct.unpack('<Q', FID.read(8))[0]
wf_dat = np.frombuffer(FID.read(2*wf_len), dtype=np.int16)
wf_lib[f'ch{i+1}'] = ( 1.0 / MAX_WAVEFORM_VALUE) * wf_dat.flatten()

NUM_NCO = 2
freq = np.zeros(NUM_NCO) #radians per timestep
phase = np.zeros(NUM_NCO)
frame = np.zeros(NUM_NCO)
Expand Down Expand Up @@ -1267,7 +1272,6 @@ def start_new_seq():
seqs['ch2'][ct] = mod_ch2

del seqs['mod_phase']

return seqs


Expand Down
2 changes: 1 addition & 1 deletion QGL/drivers/APSPattern.py
Expand Up @@ -151,7 +151,7 @@ def build_waveforms(seqs, shapeLib):
shape = np.exp(1j * wf.phase) * wf.amp * shapeLib[wf.key]
if wf.frequency != 0 and wf.amp != 0:
shape *= np.exp(
-1j * 2 * np.pi * wf.frequency * np.arange(wf.length) /
-1j * 2 * np.pi * wf.frequency * np.arange(len(shape)) /
SAMPLING_RATE) #minus from negative frequency qubits
wfLib[wf_sig(wf)] = shape
return wfLib
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
@@ -1,4 +1,4 @@
bbndb >= 0.1
bbndb >= 2019.2
numpy >= 1.11.1
scipy >= 0.17.1
networkx >= 1.11
Expand Down
4 changes: 2 additions & 2 deletions setup.py
@@ -1,13 +1,13 @@
from setuptools import setup, find_packages

setup(name='QGL',
version='2019.1',
version='2019.2',
packages=find_packages(exclude=["tests"]),
url='https://github.com/BBN-Q/QGL',
download_url='https://github.com/BBN-Q/QGL',
license="Apache 2.0 License",
install_requires=[
"bbndb >= 2019.1",
"bbndb >= 2019.2",
"numpy >= 1.11.1",
"scipy >= 0.17.1",
"networkx >= 1.11",
Expand Down

0 comments on commit c1488c6

Please sign in to comment.