Skip to content

Commit f916263

Browse files
authored
Add SingleExcitation and DoubleExcitation to RuntimeCAPI. (#1980)
**Context:** Lightning Devices support `SingleExcitation` and `DoubleExcitation`, and with the corresponding runtime capi functinos we will be able to target it directly in the runtime, without further decomposing. **Description of the Change:** Add SingleExcitation and DoubleExcitation to RuntimeCAPI **Benefits:** Reduce need to decompose SingleExcitation and accelerate XAS benchmark with capture enabled + qjit.
1 parent ef72f61 commit f916263

File tree

6 files changed

+76
-0
lines changed

6 files changed

+76
-0
lines changed

doc/releases/changelog-dev.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676

7777
<h3>Internal changes ⚙️</h3>
7878

79+
* Add `SingleExcitation` and `DoubleExcitation` to native `RUNTIME_OPERATIONS` and `RuntimeCAPI`.
80+
[(#1980)](https://github.com/PennyLaneAI/catalyst/pull/1980)
81+
7982
* Updates use of `qml.transforms.dynamic_one_shot.parse_native_mid_circuit_measurements` to improved signature.
8083
[(#1953)](https://github.com/PennyLaneAI/catalyst/pull/1953)
8184

@@ -173,6 +176,7 @@ Yushao Chen,
173176
Sengthai Heng,
174177
David Ittah,
175178
Christina Lee,
179+
Joseph Lee,
176180
Andrija Paurevic,
177181
Roberto Turrado,
178182
Paul Haochen Wang.

frontend/catalyst/device/qjit_device.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
"IsingXY",
7272
"IsingYY",
7373
"IsingZZ",
74+
"SingleExcitation",
75+
"DoubleExcitation",
7476
"ISWAP",
7577
"MultiRZ",
7678
"PauliX",

frontend/test/lit/test_decomposition.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,48 @@ def decompose_qubit_unitary(U: jax.core.ShapedArray([2, 2], float)):
169169
test_decompose_qubitunitary()
170170

171171

172+
def test_decompose_singleexcitation():
173+
"""
174+
Test that single excitation is not decomposed.
175+
"""
176+
dev = get_custom_device_without(2)
177+
178+
@qjit(target="mlir")
179+
@qml.qnode(dev)
180+
# CHECK-LABEL: public @jit_decompose_singleexcitation
181+
def decompose_singleexcitation(theta: float):
182+
# CHECK: quantum.custom "SingleExcitation"
183+
184+
qml.SingleExcitation(theta, wires=[0, 1])
185+
return measure(wires=0)
186+
187+
print(decompose_singleexcitation.mlir)
188+
189+
190+
test_decompose_singleexcitation()
191+
192+
193+
def test_decompose_doubleexcitation():
194+
"""
195+
Test that Double excitation is not decomposed.
196+
"""
197+
dev = get_custom_device_without(4)
198+
199+
@qjit(target="mlir")
200+
@qml.qnode(dev)
201+
# CHECK-LABEL: public @jit_decompose_doubleexcitation
202+
def decompose_doubleexcitation(theta: float):
203+
# CHECK: quantum.custom "DoubleExcitation"
204+
205+
qml.DoubleExcitation(theta, wires=[0, 1, 2, 3])
206+
return measure(wires=0)
207+
208+
print(decompose_doubleexcitation.mlir)
209+
210+
211+
test_decompose_doubleexcitation()
212+
213+
172214
def test_decompose_singleexcitationplus():
173215
"""
174216
Test decomposition of single excitation plus.

frontend/test/pytest/test_operations.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ def circuit(x: float, y: float):
124124
qml.IsingZZ(x, wires=[0, 1])
125125
qml.IsingZZ(y, wires=[1, 2])
126126

127+
qml.SingleExcitation(x, wires=[0, 1])
128+
qml.SingleExcitation(y, wires=[1, 2])
129+
130+
qml.DoubleExcitation(x, wires=[0, 1, 2, 3])
131+
qml.DoubleExcitation(y, wires=[2, 3, 0, 1])
132+
127133
qml.CRX(x, wires=[0, 1])
128134
qml.CRY(x, wires=[0, 1])
129135
qml.CRZ(x, wires=[0, 1])

runtime/include/RuntimeCAPI.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ void __catalyst__qis__IsingXX(double, QUBIT *, QUBIT *, const Modifiers *);
7070
void __catalyst__qis__IsingYY(double, QUBIT *, QUBIT *, const Modifiers *);
7171
void __catalyst__qis__IsingXY(double, QUBIT *, QUBIT *, const Modifiers *);
7272
void __catalyst__qis__IsingZZ(double, QUBIT *, QUBIT *, const Modifiers *);
73+
void __catalyst__qis__SingleExcitation(double, QUBIT *, QUBIT *, const Modifiers *);
74+
void __catalyst__qis__DoubleExcitation(double, QUBIT *, QUBIT *, QUBIT *, QUBIT *,
75+
const Modifiers *);
7376
void __catalyst__qis__ControlledPhaseShift(double, QUBIT *, QUBIT *, const Modifiers *);
7477
void __catalyst__qis__CRX(double, QUBIT *, QUBIT *, const Modifiers *);
7578
void __catalyst__qis__CRY(double, QUBIT *, QUBIT *, const Modifiers *);

runtime/lib/capi/RuntimeCAPI.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,25 @@ void __catalyst__qis__IsingZZ(double theta, QUBIT *control, QUBIT *target,
678678
/* modifiers */ MODIFIERS_ARGS(modifiers));
679679
}
680680

681+
void __catalyst__qis__SingleExcitation(double phi, QUBIT *wire0, QUBIT *wire1,
682+
const Modifiers *modifiers)
683+
{
684+
getQuantumDevicePtr()->NamedOperation(
685+
"SingleExcitation", {phi},
686+
{reinterpret_cast<QubitIdType>(wire0), reinterpret_cast<QubitIdType>(wire1)},
687+
MODIFIERS_ARGS(modifiers));
688+
}
689+
690+
void __catalyst__qis__DoubleExcitation(double phi, QUBIT *wire0, QUBIT *wire1, QUBIT *wire2,
691+
QUBIT *wire3, const Modifiers *modifiers)
692+
{
693+
getQuantumDevicePtr()->NamedOperation(
694+
"DoubleExcitation", {phi},
695+
{reinterpret_cast<QubitIdType>(wire0), reinterpret_cast<QubitIdType>(wire1),
696+
reinterpret_cast<QubitIdType>(wire2), reinterpret_cast<QubitIdType>(wire3)},
697+
MODIFIERS_ARGS(modifiers));
698+
}
699+
681700
void __catalyst__qis__ControlledPhaseShift(double theta, QUBIT *control, QUBIT *target,
682701
const Modifiers *modifiers)
683702
{

0 commit comments

Comments
 (0)