Skip to content

Commit

Permalink
Merge pull request oqc-community#115 from oqc-community/wh/changes_fo…
Browse files Browse the repository at this point in the history
…r_weighted_readback

Wh/changes for weighted readback
  • Loading branch information
keriksson-rosenqvist authored Jun 25, 2024
2 parents bc442d1 + bff23aa commit 0278d75
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 17 deletions.
8 changes: 7 additions & 1 deletion src/QAT/qat/purr/backends/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,15 @@ def evaluate_shape(data: Waveform, t, phase_offset=0.0):
f"'{str(data)}' is an unknown pulse type. Can't evaluate shape."
)

amplitude_differential = num_func.derivative(t, amplitude)
buf = scale_factor * amp * np.exp(1.0j * phase_offset) * amplitude
if not drag == 0.0:
amplitude_differential = num_func.derivative(t, amplitude)
if len(amplitude_differential) < len(buf):
amplitude_differential = np.pad(
amplitude_differential,
(0,len(buf)-len(amplitude_differential)),
'edge'
)
buf += (
drag
* 1.0j
Expand Down
2 changes: 2 additions & 0 deletions src/QAT/qat/purr/compiler/builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ def measure(

measure_channel = qubit.get_measure_channel()
acquire_channel = qubit.get_acquire_channel()
weights = qubit.measure_acquire.get('weights', None) if qubit.measure_acquire.get('use_weights', False) else None
acquire_instruction = Acquire(
acquire_channel,
qubit.pulse_measure["width"]
Expand All @@ -581,6 +582,7 @@ def measure(
output_variable,
self.existing_names,
qubit.measure_acquire["delay"],
weights,
)

# If we detect a full measure block before us, merge it together if we're
Expand Down
8 changes: 7 additions & 1 deletion src/QAT/qat/purr/compiler/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,13 @@ def __init__(
"rise": 0.0,
}

self.measure_acquire = {"delay": 180e-9, "sync": True, "width": 1e-6}
self.measure_acquire = {
"delay": 180e-9,
"sync": True,
"width": 1e-6,
'weights': None,
'use_weights': False
}

def add_coupled_qubit(self, qubit: Qubit):
if qubit is None:
Expand Down
29 changes: 14 additions & 15 deletions src/QAT/qat/purr/compiler/instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,28 +337,27 @@ def __init__(
output_variable=None,
existing_names: Set[str] = None,
delay=None,
filter: Pulse = None,
filter: Union[Pulse, CustomPulse] = None
):
super().__init__(channel.full_id())
super(QuantumComponent, self).__init__(channel)
self.time: float = time or 1.0e-6
self.mode: AcquireMode = mode or AcquireMode.RAW
self.delay = delay
self.filter: Pulse = filter
self.output_variable = output_variable or self.generate_name(existing_names)

if filter is not None:
if not isinstance(filter, Pulse):
raise ValueError(
"Filter on an acquire has to be a Pulse. Instead it's a "
f"{type(filter)}"
)

if filter.duration != self.time:
raise ValueError(
f"Filter duration '{filter.duration}' must be equal to Acquire "
f"duration '{self.time}'."
)
self.filter: Union[Pulse, CustomPulse] = self._check_filter(filter)

def _check_filter(self, filter):
if filter:
for target in self.quantum_targets:
if isinstance(target, PulseChannel):
dt = target.physical_channel.sample_time
if not np.isclose(filter.duration, dt * (self.time // dt), atol=1e-12):
raise ValueError(
f"Filter duration '{filter.duration}' must be equal to Acquire "
f"duration '{self.time}'."
)
return filter

def generate_name(self, existing_names=None):
return build_generated_name(existing_names, f"{self.channel.id}")
Expand Down
21 changes: 21 additions & 0 deletions src/tests/test_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from qat.purr.compiler.execution import SweepIterator
from qat.purr.compiler.instructions import (
Acquire,
CustomPulse,
Instruction,
PostProcessType,
Pulse,
Expand Down Expand Up @@ -172,6 +173,26 @@ def test_012_entanglement(self):
qubit2: {qubit0, qubit1, qubit2}
}

def test_acquire_filter(self):
hw = get_default_echo_hardware(1)
measure_ch = hw.get_qubit(0).get_measure_channel()
acquire_ch = hw.get_qubit(0).get_acquire_channel()
width = 1e-6
samples = np.linspace(0, width, int(width//1e-9), dtype=np.complex64)
filter = CustomPulse(measure_ch, samples)
acquire = Acquire(
acquire_ch,
time=width,
filter=filter,
)
assert all(samples == acquire.filter.samples)
with pytest.raises(ValueError):
Acquire(
acquire_ch,
time=0.8e-6,
filter=filter,
)


class TestSweep:

Expand Down
11 changes: 11 additions & 0 deletions src/tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import pytest
from qat.purr.backends.utilities import (
BlackmanFunction,
evaluate_shape,
GaussianFunction,
NumericFunction,
SquareFunction,
)
from qat.purr.compiler.instructions import CustomPulse


@pytest.mark.parametrize("sizes", [1, 2, 5, 7])
Expand Down Expand Up @@ -101,3 +103,12 @@ def eval(self, x):
f = SomeFunction()
d_y = f.derivative(np.arange(start=0, stop=5))
assert np.allclose(d_y, np.ones(5), atol=1e-6)


def test_custom_pulse_evaluate_shape():
samples = np.linspace(0, 1, 100, dtype=np.complex64)
t = np.linspace(0, 1e-6, 100)
pulse = CustomPulse(None, samples)
buffer = evaluate_shape(pulse, t)
assert len(buffer) == len(t)
assert all(buffer == samples)

0 comments on commit 0278d75

Please sign in to comment.