Distribute the input data over several identical 1-qubit circuits

I am training a 1-qubit circuit for classification of 2dim data (x,y) and I want to speed up the training by using several identical 1-qubit wires in a bigger circuit, with the same parameters for all wires, but each wire taking one different (x,y) point from the input data. I am doing this by using the broadcast of the parameters over several wires, but when I check with the qml.specs or I just launch a simulation of the training, I see that the number of parameters to train is seen as my actual number of parameters (4) multiplied by the number of wires. At the end I get again only the 4 values of the optimized parameters, which look quite fine on test data, but so I loose all the speedup I was looking for. Thanks for any idea.

circuit_nq

The parameters are [0.73, 0.95, -0.75, 1.51] and the 3 points for training are [0.1, 0.2], [0.3, 0.4] and [0.5, 0.6].

Hello Bogdan,

If you are comfortable doing so, would you be able to share a code snippet so that we can try to narrow down where the issue is exactly?

Hello,

This is the code:

nqb = 3
dev = qml.device('default.qubit', wires=nqb, shots=1000)

def block(x, pars):
    print("pars[0]= ",pars[0])
    broadcast(unitary=qml.RX, pattern="single", wires=range(nqb), parameters=pars[0])
    broadcast(unitary=qml.RY, pattern="single", wires=range(nqb), parameters=x[0])
    broadcast(unitary=qml.RX, pattern="single", wires=range(nqb), parameters=pars[1])
    broadcast(unitary=qml.RY, pattern="single", wires=range(nqb), parameters=x[1])
    broadcast(unitary=qml.RX, pattern="single", wires=range(nqb), parameters=pars[2])
    broadcast(unitary=qml.RY, pattern="single", wires=range(nqb), parameters=x[0])
    broadcast(unitary=qml.RX, pattern="single", wires=range(nqb), parameters=pars[3])
    broadcast(unitary=qml.RY, pattern="single", wires=range(nqb), parameters=x[1])    

@qml.qnode(dev)
def circuit(x, params):
    block(x, pars=params)
    return [qml.expval(qml.PauliZ(wires=i)) for i in range(nqb)]

x_t = np.array(x_b, requires_grad=False)
print(x_t)

[[0.1 0.3 0.5]
 [0.2 0.4 0.6]]

params_t = np.array(params_b, requires_grad=True)
print(params_t)

[[ 0.7312  0.7312  0.7312]
 [ 0.9535  0.9535  0.9535]
 [-0.7562 -0.7562 -0.7562]
 [ 1.5118  1.5118  1.5118]]

qml.specs(circuit)(x_t, params_t)

{'gate_sizes': defaultdict(int, {1: 24}),
 'gate_types': defaultdict(int, {'RX': 12, 'RY': 12}),
 'num_operations': 24,
 'num_observables': 3,
 'num_diagonalizing_gates': 0,
 'num_used_wires': 3,
 'depth': 8,
 'num_trainable_params': 12,
 'num_device_wires': 3,
 'device_name': 'default.qubit',
 'expansion_strategy': 'gradient',
 'gradient_options': {},
 'interface': 'autograd',
 'diff_method': 'best',
 'gradient_fn': 'pennylane.gradients.parameter_shift.param_shift',
 'num_gradient_executions': 24}

Here the points to classify are (0.1,0.2), (0.3,0.4) and (0.5,0.6), one for each qubit.
Indeed, it seems that I can not use the broadcast method as a kind of linking a reference to a parameter over several wires, as I was hoping, I end up with multiplying them for each wire, instead.
I wonder if there is such a possibility in Pennylane.