Hey everyone,
I started building my own plugin, since I want to support a new gate consisting of already existing PennyLane gates, so that if I want to apply this gate I don’t have to always apply all operations one after another and can just call one gate. I had quite some difficulties getting to the point where I am right now, but now I am stuck.
I created my own device and followed the PennyLane documentation[https://pennylane.readthedocs.io/en/user-docs-refactor/introduction/plugins.html] and added it into the setup.py
file. The device installation works fine and I can also import my custom gate. If I try to run it though it just returns a Key Error with the name of my gate. No additional information. Now I am quite confused. What am I doing wrong?
This is the code I have so far:
from pennylane.operation import CVOperation
from pennylane_sf.fock import StrawberryFieldsFock
import pennylane as qml
class CustomDevice(StrawberryFieldsFock):
name = 'My custom device'
short_name = 'example.mydevice'
pennylane_requires = '0.15.0'
version = '0.0.1'
author = 'Noah Wach'
operations = {"FockState", "Beamsplitter", "Test_Gate"}
observables = {"NumberOperator"}
def apply(self, operations, wires, par, **kwargs):
return StrawberryFieldsFock.apply(self, operations, wires, par, **kwargs)
def var(self, operations, wires, par, **kwargs):
return StrawberryFieldsFock.var(self, operations, wires, par, **kwargs)
def expval(self, operations, wires, par, **kwargs):
return StrawberryFieldsFock.expval(self, operations, wires, par, **kwargs)
class Test_Gate(CVOperation):
num_params = 1
num_wires = 2
par_domain = 'R'
grad_method = 'A'
grad_recipe = None
@staticmethod
def decomposition(*params, wires):
return [qml.Kerr(params[0], wires=wires[0]), qml.Kerr(params[0], wires=wires[1]), qml.CrossKerr(-2*params[0], wires=wires[0, 1])]
If I run the circuit I get the following error:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-5-b578624aadda> in <module>
----> 1 result = Kerr_test()
~/Desktop/Uni/HiWi/pennylane_NaLi/pennylane/pennylane/qnode.py in __call__(self, *args, **kwargs)
553
554 # execute the tape
--> 555 res = self.qtape.execute(device=self.device)
556
557 if original_shots is not None:
~/Desktop/Uni/HiWi/pennylane_NaLi/pennylane/pennylane/tape/tape.py in execute(self, device, params)
1187 params = self.get_parameters()
1188
-> 1189 return self._execute(params, device=device)
1190
1191 def execute_device(self, params, device):
~/venvs/HiWi/lib/python3.7/site-packages/autograd/tracer.py in f_wrapped(*args, **kwargs)
46 return new_box(ans, trace, node)
47 else:
---> 48 return f_raw(*args, **kwargs)
49 f_wrapped.fun = f_raw
50 f_wrapped._is_autograd_primitive = True
~/Desktop/Uni/HiWi/pennylane_NaLi/pennylane/pennylane/interfaces/autograd.py in _execute(self, params, device)
163 # evaluate the tape
164 self.set_parameters(self._all_params_unwrapped, trainable_only=False)
--> 165 res = self.execute_device(params, device=device)
166 self.set_parameters(self._all_parameter_values, trainable_only=False)
167
~/Desktop/Uni/HiWi/pennylane_NaLi/pennylane/pennylane/tape/tape.py in execute_device(self, params, device)
1220 res = device.execute(self)
1221 else:
-> 1222 res = device.execute(self.operations, self.observables, {})
1223
1224 # Update output dim if incorrect.
~/Desktop/Uni/HiWi/pennylane_NaLi/pennylane/pennylane/_device.py in execute(self, queue, observables, parameters, **kwargs)
394
395 for operation in queue:
--> 396 self.apply(operation.name, operation.wires, operation.parameters)
397
398 self.post_apply()
~/Desktop/Uni/HiWi/pennylane_NaLi/pennylane/pennylane/devices/NaLi.py in apply(self, operations, wires, par, **kwargs)
21
22 def apply(self, operations, wires, par, **kwargs):
---> 23 return StrawberryFieldsFock.apply(self, operations, wires, par, **kwargs)
24
25
~/venvs/HiWi/lib/python3.7/site-packages/pennylane_sf/simulator.py in apply(self, operation, wires, par)
112 par = [p.unwrap() if hasattr(p, "unwrap") else p for p in par]
113
--> 114 op = self._operation_map[operation](*sf_par)
115 op | [self.q[i] for i in device_wires.labels] # pylint: disable=pointless-statement
116
KeyError: 'Test_Gate'
What is the problem here? Thanks in advance.
Cheers,
Noah