Now my question is, how do I perform the necessary CSWAP operations between my different registers/devices. Is there a way of concatenating the devices such that a swap test could be implemented, i.e generating a device in the state “|anc> @ |inp1> @ |inp2>”?

Welcome to the forum and thank you so much for your question!

There is no way, unfortunately, to perform operations between quantum functions that are being executed on separate devices. The concept of a QNode necessitates that it takes classical inputs and provides classical outputs, so every quantum operation is applied within the QNode itself. Therefore the best approach might be to use a single device and a single QNode.

The following could be an approach for performing the swap test using a single device and a single QNode:

import pennylane as qml
from pennylane import numpy as np
from pennylane.templates import AmplitudeEmbedding
# define two random input vectors
inp1 = np.array([1,2,0,0])
inp2 = np.array([0,1,0,0])
qubit_number = int(np.ceil(np.log2(len(inp1))))
dev = qml.device('default.qubit', wires=3 * qubit_number)
@qml.qnode(dev)
def prepare_reg1(inp):
AmplitudeEmbedding(features=inp, wires=range(qubit_number, 3 * qubit_number), normalize=True, pad_with=0.)
ancillea = []
for i in range(qubit_number):
anc = i
ancillea.append(anc)
first_state = i+qubit_number
second_state = i+ 2*qubit_number
qml.CSWAP(wires=[anc, first_state, second_state])
return qml.expval(qml.operation.Tensor(*[qml.PauliZ(i) for i in ancillea]))
input_state = np.concatenate([inp1, inp2])
prepare_reg1(input_state)
print(prepare_reg1.draw())

Hey, thanks a lot! This looks already close to what I’m looking for. Actually, I’m trying to implement the swap test code on Wikipedia (https://en.wikipedia.org/wiki/Swap_test) to estimate the inner product of two vectors, thus, I guess I only need one ancilla qubit. However, I don’t quite get how you initialized the two input states. Is there a reason that you expanded the vectors with zeros so that they have length 4? Also, after concatenation and using an amplitude embedding, how can we be sure, that the two input vectors are stored in two different qubit registers? Right now I feel like this is not the case, or am I wrong?

You’ll need one ancilla qubit for every pair of qubits that you would like to compare. So taking your original example, correct, you will only need one ancilla qubit.

Is there a reason that you expanded the vectors with zeros so that they have length 4?

Not at all, the expansion was done only so that we’d have a multiqubit basis state preparation. Just made that to generalize the idea for multiple ancillae.

Also, after concatenation and using an amplitude embedding, how can we be sure, that the two input vectors are stored in two different qubit registers? Right now I feel like this is not the case, or am I wrong?

This is guaranteed because of how amplitude embedding works. We provision a vector of features which will be encoded into the amplitudes of the qubits that we’ve specified. We are required to provide different wires and every feature is encoded into a separate qubit.

When we concatenate the two vector of features (each containing 2^n features), we shift to a higher-order feature space with dimension 2n. The concatenated vector will contain 2^{2n} features. When we then embed the concatenated features into a quantum circuit, the number of qubits needed for the encoding also increases (and will be 2n, equal to the dimension of the feature space).

In the n=1 case this will mean that we can concatenate two input vectors of length 2, to create a single feature vector of length 4. These features are then embedded into log_2 4=2 qubits. We can then compare the state of these two qubits by introducing an ancilla qubit and performing the SWAP test.