Error:unhashable type: 'list'andWires must be hashable; got [[0], [1]]

hello, I have some questions in my code,please tell me how to modify my code.Best wishes to you!

# Put code here
n_wires = 6
G = 23.5
q = 3.0
# unitary operator U_B with parameter beta
def U_B(beta):
    for wire in range(n_wires):
        qml.RX(2 * beta, wires=wire)


# unitary operator U_C with parameter gamma
def U_C(gamma):
    for wire in range(n_wires):
        wire0 = [0]
        wire1 = [1]
        wire2 = [2]
        wire3 = [3]
        wire4 = [4]
        wire5 = [5]

        qml.CNOT(wires=[wire0, wire1])
        qml.RZ(2 * G * gamma, wires=wire1)
        qml.CNOT(wires=[wire0, wire1])

        qml.CNOT(wires=[wire1, wire2])
        qml.RZ(2 * G * gamma, wires=wire2)
        qml.CNOT(wires=[wire1, wire2])

        qml.CNOT(wires=[wire2, wire3])
        qml.RZ(2 * G * gamma, wires=wire3)
        qml.CNOT(wires=[wire2, wire3])

        qml.CNOT(wires=[wire3, wire4])
        qml.RZ(2 * G * gamma, wires=wire4)
        qml.CNOT(wires=[wire3, wire4])

        qml.CNOT(wires=[wire4, wire5])
        qml.RZ(2 * G * gamma, wires=wire5)
        qml.CNOT(wires=[wire4, wire5])

        qml.Barrier()

        qml.CNOT(wires=[wire0, wire2])
        qml.RZ(2 * G * gamma, wires=wire2)
        qml.CNOT(wires=[wire0, wire2])

        qml.CNOT(wires=[wire1, wire3])
        qml.RZ(2 * G * gamma, wires=wire3)
        qml.CNOT(wires=[wire1, wire3])

        qml.CNOT(wires=[wire2, wire4])
        qml.RZ(2 * G * gamma, wires=wire4)
        qml.CNOT(wires=[wire2, wire4])

        qml.CNOT(wires=[wire3, wire5])
        qml.RZ(2 * G * gamma, wires=wire5)
        qml.CNOT(wires=[wire3, wire5])

        qml.Barrier()

        qml.CNOT(wires=[wire0, wire3])
        qml.RZ(2 * G * gamma, wires=wire3)
        qml.CNOT(wires=[wire0, wire3])

        qml.CNOT(wires=[wire1, wire4])
        qml.RZ(2 * G * gamma, wires=wire4)
        qml.CNOT(wires=[wire1, wire4])

        qml.CNOT(wires=[wire2, wire5])
        qml.RZ(2 * G * gamma, wires=wire5)
        qml.CNOT(wires=[wire2, wire5])

        qml.Barrier()

        qml.CNOT(wires=[wire0, wire4])
        qml.RZ(2 * G * gamma, wires=wire4)
        qml.CNOT(wires=[wire0, wire4])

        qml.CNOT(wires=[wire1, wire5])
        qml.RZ(2 * G * gamma, wires=wire5)
        qml.CNOT(wires=[wire1, wire5])

        qml.Barrier()

        qml.CNOT(wires=[wire0, wire5])
        qml.RZ(2 * G * gamma, wires=wire5)
        qml.CNOT(wires=[wire0, wire5])

        qml.Barrier()

        qml.RZ(2 * q * gamma, wires=wire0)
        qml.RZ(2 * q * gamma, wires=wire1)
        qml.RZ(2 * q * gamma, wires=wire2)
        qml.RZ(2 * q * gamma, wires=wire3)
        qml.RZ(2 * q * gamma, wires=wire4)
        qml.RZ(2 * q * gamma, wires=wire5)
        qml.Barrier()
  
def bitstring_to_int(bit_string_sample):
    bit_string = "".join(str(bs) for bs in bit_string_sample)
    return int(bit_string, base=2)
dev = qml.device("lightning.qubit", wires=n_wires, shots=1)
wire0 = [0]
wire1 = [1]
@qml.qnode(dev)
def circuit(gammas, betas, edge=None, n_layers=1):
    # apply Hadamards to get the n qubit |+> state
    for wire in range(n_wires):
        qml.Hadamard(wires=wire)
    # p instances of unitary operators
    for i in range(n_layers):
        U_C(gammas[i])
        U_B(betas[i])
    if edge is None:
       
        return qml.sample()
    # during the optimization phase we are evaluating a term
    # in the objective using expval

    H = qml.PauliZ(wire0) @ qml.PauliZ(wire1) + qml.PauliZ(wire0)
    
    return qml.expval(H) 

def qaoa_1(n_layers=1):
    print("\np={:d}".format(n_layers))

    # initialize the parameters near zero
    init_params = 0.01 * np.random.rand(2, n_layers)

    # minimize the negative of the objective function
    def objective(params):
        gammas = params[0]
        betas = params[1]
        neg_obj = 0

        neg_obj -= circuit(gammas, betas, n_layers=n_layers)
        return neg_obj

    # initialize optimizer: Adagrad works well empirically
    opt = qml.AdagradOptimizer(stepsize=0.5)

    # optimize parameters in objective
    params = init_params
    steps = 30
    for i in range(steps):
        params = opt.step(objective, params)
        if (i + 1) % 5 == 0:
            print("Objective after step {:5d}: {: .7f}".format(i + 1, -objective(params)))

    # sample measured bitstrings 100 times
    bit_strings = []
    n_samples = 100
    for i in range(n_samples):
        bit_strings.append(circuit(params[0], params[1], n_layers=n_layers))

    # print optimal parameters and most frequently sampled bitstring
    counts = np.bincount(np.array(bit_strings))
    most_freq_bit_string = np.argmax(counts)
    print("Optimized (gamma, beta) vectors:\n{}".format(params[:, :n_layers]))
    print("Most frequently sampled bit string is: {:04b}".format(most_freq_bit_string))

    return -objective(params), bit_strings

# perform qaoa on our graph with p=1,2 and
# keep the bitstring sample lists
bitstrings1 = qaoa_1(n_layers=1)[1]
bitstrings2 = qaoa_1(n_layers=2)[1]

If you want help with diagnosing an error, please put the full error message below:


# Put full error message here
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File d:\download\Anaconda\envs\xming\Lib\site-packages\pennylane\wires.py:68, in _process(wires)
     65 try:
     66     # We need the set for the uniqueness check,
     67     # so we can use it for hashability check of iterables.
---> 68     set_of_wires = set(wires)
     69 except TypeError as e:

TypeError: unhashable type: 'list'

The above exception was the direct cause of the following exception:

WireError                                 Traceback (most recent call last)
c:\Users\ming\Desktop\qaoa\try.ipynb 单元格 5 line 4
     42     return -objective(params), bit_strings
     44 # perform qaoa on our graph with p=1,2 and
     45 # keep the bitstring sample lists
---> 46 bitstrings1 = qaoa_1(n_layers=1)[1]
     47 bitstrings2 = qaoa_1(n_layers=2)[1]

c:\Users\ming\Desktop\qaoa\try.ipynb 单元格 5 line 2
     24 steps = 30
     25 for i in range(steps):
---> 26     params = opt.step(objective, params)
...
---> 71         raise WireError(f"Wires must be hashable; got {wires}.") from e
     73 if len(set_of_wires) != len(tuple_of_wires):
     74     raise WireError(f"Wires must be unique; got {wires}.")

WireError: Wires must be hashable; got [[0], [1]].

Hey @ming!

Looks like all you need to change is this chunk of code:

        wire0 = [0]
        wire1 = [1]
        wire2 = [2]
        wire3 = [3]
        wire4 = [4]
        wire5 = [5]

When you have an operator that acts on multiple wires, you must provide the wires to the operator as a list of wire labels / indices. You’re passing it a list of lists — [[0], [1]] — when you really want [0, 1]. So, if you make this change, that should remedy the issue:

        wire0 = 0
        wire1 = 1
        wire2 = 2
        wire3 = 3
        wire4 = 4
        wire5 = 5

Thank you for your reply!And I try your method,get a new error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
c:\Users\ming\Desktop\qaoa\try.ipynb 单元格 5 line 4
     44     return -objective(params), bit_strings
     46 # perform qaoa on our graph with p=1,2 and
     47 # keep the bitstring sample lists
---> 48 bitstrings1 = qaoa_1(n_layers=1)[1]
     49 bitstrings2 = qaoa_1(n_layers=2)[1]

c:\Users\ming\Desktop\qaoa\try.ipynb 单元格 5 line 2
     26     params = opt.step(objective, params)
     27     if (i + 1) % 5 == 0:
---> 28         print("Objective after step {:5d}: {: .7f}".format(i + 1, -objective(params)))
     30 # sample measured bitstrings 100 times
     31 bit_strings = [ ]

TypeError: unsupported format string passed to numpy.ndarray.__format__

it seems like print("Optimized (gamma, beta) vectors:\n{}".format(params[:, :n_layers])) have some problem, is a NumPy array, and the method might not handle it directly. i try to modify as print("Optimized (gamma, beta) vectors:\n{}".format(params[:, :n_layers].tolist())) but have not solved.

could you have a method?please tell me.Best wishes to you!

Hey @ming, thanks! I’m getting a different error message than you are. Can you show me the output of the following?

qml.about()

If your pennylane version is less than 0.33.1, I highly recommend that you update :slight_smile:.

Name: PennyLane
Version: 0.33.1
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/PennyLaneAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: d:\download\Anaconda\envs\xming\Lib\site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane-Lightning, pennylane-qulacs

Platform info:           Windows-11-10.0.22621-SP0
Python version:          3.12.0
Numpy version:           1.26.1
Scipy version:           1.11.3
Installed devices:
- default.gaussian (PennyLane-0.33.0)
- default.mixed (PennyLane-0.33.0)
- default.qubit (PennyLane-0.33.0)
- default.qubit.autograd (PennyLane-0.33.0)
- default.qubit.jax (PennyLane-0.33.0)
- default.qubit.legacy (PennyLane-0.33.0)
- default.qubit.tf (PennyLane-0.33.0)
- default.qubit.torch (PennyLane-0.33.0)
- default.qutrit (PennyLane-0.33.0)
- null.qubit (PennyLane-0.33.0)
- lightning.qubit (PennyLane-Lightning-0.33.1)
- qulacs.simulator (pennylane-qulacs-0.32.0)

Thank you for your reply and your advice! I run the code,and get“Cannot cast array data from dtype(‘float64’) to dtype(‘int64’) according to the rule ‘safe’”,it seem to have some errors,how can i modify it?

Best wishes!

Hey @ming, sorry I didn’t realize this earlier, but QNodes that return qml.sample aren’t generally differentiable. In the documentation for qml.sample it says:

QNodes that return samples cannot, in general, be differentiated, since the derivative with respect to a sample — a stochastic process — is ill-defined. The one exception is if the QNode uses the parameter-shift method (diff_method="parameter-shift"), in which case qml.sample(obs) is interpreted as a single-shot expectation value of the observable obs.

The second half of :point_up: leads me to believe that there should be a workaround to your issue, but I think there’s a bug! I’ve made an issue here: [BUG] QNodes that return `qml.sample(obs)` and use `parameter-shift` are not differentiable · Issue #4840 · PennyLaneAI/pennylane · GitHub

If there are any updates, I’ll let you know :slight_smile:

1 Like