Query regarding admissible shape of input data

Recently I am trying to construct a code for building RNN model based on quantum circuits. I gave a single dimensional input(time series data) of size=200:

t = np.arange(0, 20, 0.1) # Time from 0 to 200 with step size of 0.1
x_in = torch.tensor(np.cos(t))
The circuit(of 6 qubits) based model consists of:
encoding part: R_y gate applied on each qubit at each time step
evolution part: At each time step, R_x,R_z applied on each qubit followed by Hamiltonian Gate
mid-circuit measurements for 3 out of 6 qubits.

On running the circuit an error message is coming as follows:

ValueError: maximum supported dimension for an ndarray is 32, found 606

How to overcome this problem?
Any suggestion in this context will be helpful.

Please note that: the same model is running without any error for a time series data of size=2.

Hi @Kaushiki_Mukherjee,

It’s hard to know the root of the issue without having a minimal reproducible example and the full error traceback. But from the error I can tell that you’re trying to store an array of size 606, which is not supported. It might be a question of using deferred-measurements. You can see in the docs that these measurements add an auxiliary qubit to the circuit for each mid-circuit measurement, leading to overheads of both memory and simulation time that scale exponentially with the number of measurements.

So my guess is that you’re accidentally creating a 606-qubit circuit without realizing.

Make sure to check our section on dynamic quantum circuits in the docs for other ways of doing mid-circuit measurements.

Again, this is only a hypothesis, it’s impossible to know for sure without the minimal reproducible example and the full error traceback.

Thanks for your response @CatalinaAlbornoz
Part of the code that is giving error is as follows:

t = np.arange(0, 20, 0.1)  # Time from 0 to 200 with step size of 0.1
x_in = torch.tensor(np.cos(t))
print(x_in.shape)
"""
target=x_in+torch.torch.tensor(0.03)
"""
nb=3
na=3
D=3
list1=torch.randn(3,6, requires_grad=True)
print(f" list1 before training:{list1}")
list2=torch.randn(3,6, requires_grad=True)
list3=torch.randn(3,6, requires_grad=True)
evolution_time=torch.randn(1,requires_grad=True)
list_single = [0.52, 0.7, 0.41,0.23, 0.24, 0.4]
list_double=[0.31,0.51,0.42,0.3,0.4,0.5,0.66,0.33,0.22,0.7]#10 elements
#NOTE:list_single,double are not parameters as per the paper


def apply_hamiltonian(H, time):
    # This function applies the Hamiltonian gate (time evolution)
    qml.templates.ApproxTimeEvolution(H, time, 1)

dev = qml.device("default.qubit", wires=6)
s=[]
@qml.qnode(dev,diff_method="backprop")    
def circuit(nb,x_in,D,na,list1,list2,list3,list_single,list_double,evo_time):
    for i in range(len(x_in)):
        s2=[]
        for j in range(nb):
            s2.append(0)
        s.append(s2)

    s1=torch.zeros(len(x_in),nb)
    for i in range(len(x_in)):#loop for every time step
        # Apply gates for encoding
        for j in range(nb):
            qml.RY(np.arccos(x_in[i]),wires=j)
        for turn in range(D):  # no. of layers
            for r in range(na+nb):  # single qubi part of U(theta in paper)
                qml.RX(list1[turn,r],wires=r)    
                qml.RZ(list2[turn,r],wires=r) 
                qml.RX(list3[turn,r],wires=r)  
            coeff_list=list_single+list_double
            obs1=[qml.PauliX(i) for i in range(na+nb)]
            obs2=[qml.PauliZ(k3) @ qml.PauliZ(k4) for k3 in range(1,na+nb) 
            for k4 in range(k3-1)]
            obs=obs1+obs2
        # Construct the Hamiltonian
        H = qml.Hamiltonian(coeff_list, obs)
        #applying time approximate Hamiltonian gate
        apply_hamiltonian(H, evo_time)
        #qml.templates.ApproxTimeEvolution(H, time, 1)
        m=torch.zeros(len(x_in))
        
        for k1 in range(nb):
            s[i][k1]=qml.measure([k1],reset=True)
        #print(f"time step:{i} complete")
       # m[i]=qml.expval(s[i][0])
    k=[]
    for i in range(len(x_in)):
        for j in range(nb):
            k.append(qml.expval(s[i][j]))
    return k
   #return(qml.expval(s[0][0]),qml.expval(s[0][1]),qml.expval(s[0][2]),qml.expval(s[1][0]),qml.expval(s[1][1]),qml.expval(s[1][2]))
    #return(qml.expval(qml.PauliX(0)@qml.PauliX(1)@qml.PauliX(2)))
#w=circuit(3, x_in, 3, 3)
#print(circuit(3, x_in, 3, 3,list1,list2,list3,list_single,list_double,evolution_time)) 
rnn=circuit(3, x_in, 3, 3,list1,list2,list3,list_single,list_double,evolution_time)
time_steps=len(x_in)

How to get rid of the error that I said earlier?
It will be helpful if you please do explain in more details about the way out you pointed out to solve this problem in your earlier post.

Thanks for sharing the code @Kaushiki_Mukherjee .

I can replicate your error and it’s indeed a question of creating a circuit with too many wires.

You can try using our debugging tools to see where in your code your circuit is being created with so many qubits. If you’re struggling with this please post a message in this thread and we’ll do our best to help you.

I can interpret that the number of wires used is exceeding the permissible limit. I was just trying to build the RNN model given in Phys. Rev. A 103, 052414 and check its functionality for interpreting role of quantum gates in building RNN model. But for constructing that model, I need to use the gates as shown in the code and also the length of the synthetic data I have considered for checking is not large enough . Then how to control the number of wires? Also I cannot follow the strategy of using debugging tools.
Being a novice in this field, I am unable to tackle this problem.

Hey @Kaushiki_Mukherjee,

default.qubit doesn’t require that you specify the number of wires in the circuit, which is a nice feature because it lets you create dynamic circuits! Here, it might be useful to switch to a device that needs to know the number of qubits right off the hop: lightning.qubit. Try that device instead, and it might raise errors that are indicative of where you start to access wire numbers that are too big.

The other thing to check is every index that you loop over that is used as a wire label. E.g., your loop over nb: for j in range(nb). How big are the loops? This will tell you how many qubits you’re trying to allocate.

Thanks for your suggestions.