qiboteam / qibotn

The tensor-network translation module for Qibo.
https://qibo.science
Apache License 2.0
5 stars 1 forks source link

Error when running circuits #51

Open renatomello opened 7 months ago

renatomello commented 7 months ago

I tried to run the example inside the doc file of this repo and got this error

from qibo import Circuit, gates, set_backend

# Set the quimb backend
set_backend(
    backend="qibotn", platform="qutensornet", runcard=computation_settings
)

# Set the runcard
computation_settings = {
    "MPI_enabled": False,
    "MPS_enabled": False,
    "NCCL_enabled": False,
    "expectation_enabled": False,
}

# Construct the circuit with two qubits
c = Circuit(2)

# Apply Hadamard gates on first and second qubit
c.add(gates.H(0))
c.add(gates.H(1))

# Execute the circuit and obtain the final state
result = c()

# Print the final state
print(result.state())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[12], line 24
     21 c.add(qibo.gates.H(1))
     23 # Execute the circuit and obtain the final state
---> 24 result = c()
     26 # Print the final state
     27 print(result.state())

File ~/.local/lib/python3.10/site-packages/qibo/models/circuit.py:1117, in Circuit.__call__(self, initial_state, nshots)
   1115 def __call__(self, initial_state=None, nshots=1000):
   1116     """Equivalent to ``circuit.execute``."""
-> 1117     return self.execute(initial_state=initial_state, nshots=nshots)

File ~/.local/lib/python3.10/site-packages/qibo/models/circuit.py:1113, in Circuit.execute(self, initial_state, nshots)
   1109     return GlobalBackend().execute_distributed_circuit(
   1110         self, initial_state, nshots
   1111     )
   1112 else:
-> 1113     return GlobalBackend().execute_circuit(self, initial_state, nshots)

File ~/.local/lib/python3.10/site-packages/qibotn/backends/quimb.py:78, in QuimbBackend.execute_circuit(self, circuit, initial_state, nshots, return_array)
     73 if self.expectation_enabled == True:
     74     raise_error(
     75         NotImplementedError, "QiboTN quimb backend cannot support expectation"
     76     )
---> 78 state = eval.dense_vector_tn_qu(
     79     circuit.to_qasm(), initial_state, self.mps_opts, backend="numpy"
     80 )
     82 if return_array:
     83     return state.flatten()

File ~/.local/lib/python3.10/site-packages/qibotn/eval_qu.py:39, in dense_vector_tn_qu(qasm, initial_state, mps_opts, backend)
     36     initial_state = init_state_tn(nqubits, initial_state)
     38 circ_cls = qtn.circuit.CircuitMPS if mps_opts else qtn.circuit.Circuit
---> 39 circ_quimb = circ_cls.from_openqasm2_str(
     40     qasm, psi0=initial_state, gate_opts=mps_opts
     41 )
     43 interim = circ_quimb.psi.full_simplify(seq="DRC")
     44 amplitudes = interim.to_dense(backend=backend)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1499, in Circuit.from_openqasm2_str(cls, contents, **circuit_opts)
   1497 """Generate a ``Circuit`` instance from an OpenQASM 2.0 string."""
   1498 info = parse_openqasm2_str(contents)
-> 1499 qc = cls(info["n"], **circuit_opts)
   1500 qc.apply_gates(info["gates"])
   1501 return qc

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1438, in Circuit.__init__(self, N, psi0, gate_opts, gate_contract, gate_propagate_tags, tags, psi0_dtype, psi0_tag, bra_site_ind_id)
   1435     for tag in tags:
   1436         self._psi.add_tag(tag)
-> 1438 self.gate_opts = ensure_dict(gate_opts)
   1439 self.gate_opts.setdefault("contract", gate_contract)
   1440 self.gate_opts.setdefault("propagate_tags", gate_propagate_tags)

File ~/.local/lib/python3.10/site-packages/quimb/utils.py:189, in ensure_dict(x)
    187 if x is None:
    188     return {}
--> 189 return dict(x)

Moreover, adding a two-qubit gate leads to this error

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[14], line 25
     22 c.add(gates.CNOT(0, 1))
     24 # Execute the circuit and obtain the final state
---> 25 result = c()
     27 # Print the final state
     28 print(result.state())

File ~/.local/lib/python3.10/site-packages/qibo/models/circuit.py:1117, in Circuit.__call__(self, initial_state, nshots)
   1115 def __call__(self, initial_state=None, nshots=1000):
   1116     """Equivalent to ``circuit.execute``."""
-> 1117     return self.execute(initial_state=initial_state, nshots=nshots)

File ~/.local/lib/python3.10/site-packages/qibo/models/circuit.py:1113, in Circuit.execute(self, initial_state, nshots)
   1109     return GlobalBackend().execute_distributed_circuit(
   1110         self, initial_state, nshots
   1111     )
   1112 else:
-> 1113     return GlobalBackend().execute_circuit(self, initial_state, nshots)

File ~/.local/lib/python3.10/site-packages/qibotn/backends/quimb.py:78, in QuimbBackend.execute_circuit(self, circuit, initial_state, nshots, return_array)
     73 if self.expectation_enabled == True:
     74     raise_error(
     75         NotImplementedError, "QiboTN quimb backend cannot support expectation"
     76     )
---> 78 state = eval.dense_vector_tn_qu(
     79     circuit.to_qasm(), initial_state, self.mps_opts, backend="numpy"
     80 )
     82 if return_array:
     83     return state.flatten()

File ~/.local/lib/python3.10/site-packages/qibotn/eval_qu.py:39, in dense_vector_tn_qu(qasm, initial_state, mps_opts, backend)
     36     initial_state = init_state_tn(nqubits, initial_state)
     38 circ_cls = qtn.circuit.CircuitMPS if mps_opts else qtn.circuit.Circuit
---> 39 circ_quimb = circ_cls.from_openqasm2_str(
     40     qasm, psi0=initial_state, gate_opts=mps_opts
     41 )
     43 interim = circ_quimb.psi.full_simplify(seq="DRC")
     44 amplitudes = interim.to_dense(backend=backend)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1500, in Circuit.from_openqasm2_str(cls, contents, **circuit_opts)
   1498 info = parse_openqasm2_str(contents)
   1499 qc = cls(info["n"], **circuit_opts)
-> 1500 qc.apply_gates(info["gates"])
   1501 return qc

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1624, in Circuit.apply_gates(self, gates, **gate_opts)
   1622 for gate in gates:
   1623     if isinstance(gate, Gate):
-> 1624         self._apply_gate(gate, **gate_opts)
   1625     else:
   1626         self.apply_gate(*gate, **gate_opts)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1545, in Circuit._apply_gate(self, gate, tags, **gate_opts)
   1540     SPECIAL_GATES[gate.label](
   1541         self._psi, *gate.params, *gate.qubits, **opts
   1542     )
   1543 else:
   1544     # apply the gate to the TN!
-> 1545     self._psi.gate_(gate.array, gate.qubits, tags=tags, **opts)
   1547 # keep track of the gates applied
   1548 self.gates.append(gate)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_1d.py:557, in TensorNetwork1DVector.gate(self, inplace, *args, **kwargs)
    555 @functools.wraps(gate_TN_1D)
    556 def gate(self, *args, inplace=False, **kwargs):
--> 557     return gate_TN_1D(self, *args, inplace=inplace, **kwargs)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_1d.py:231, in gate_TN_1D(tn, G, where, contract, tags, propagate_tags, info, inplace, cur_orthog, **compress_opts)
    229 if contract == "swap+split":
    230     if ng >= 2:
--> 231         return tn.gate_with_auto_swap(
    232             G,
    233             where,
    234             cur_orthog=cur_orthog,
    235             inplace=inplace,
    236             **compress_opts,
    237         )
    238     else:
    239         contract = True

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_1d.py:1880, in MatrixProductState.gate_with_auto_swap(self, G, where, inplace, cur_orthog, **compress_opts)
   1878 # make sure sites are orthog center, then apply and split
   1879 mps.canonize((i, i + 1), cur_orthog)
-> 1880 mps.gate_split_(
   1881     G, where=(i + 1, i) if need2flip else (i, i + 1), **compress_opts
   1882 )
   1884 if need2swap:
   1885     # move j site back to original position
   1886     mps.swap_site_to(
   1887         i + 1, j, cur_orthog=(i, i + 1), inplace=True, **compress_opts
   1888     )

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_1d.py:1728, in MatrixProductState.gate_split(self, G, where, inplace, **compress_opts)
   1726 ix_i, ix_j = map(self.site_ind, where)
   1727 # note that 'reduce-split' is unecessary: tensors have ndim<=3
-> 1728 return self.gate_inds(
   1729     G, (ix_i, ix_j), contract="split", inplace=inplace, **compress_opts
   1730 )

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_core.py:3848, in tensor_network_gate_inds(self, G, inds, contract, tags, info, inplace, **compress_opts)
   3841         raise ValueError(
   3842             "For a parametrized gate acting on more than one site "
   3843             "``contract`` must be false to preserve the array shape."
   3844         )
   3846 if basic:
   3847     # no gate splitting involved
-> 3848     _tensor_network_gate_inds_basic(
   3849         tn, G, inds, ng, tags, contract, isparam, info, **compress_opts
   3850     )
   3851 else:
   3852     # possible splitting of gate itself involved
   3853     if ng > 2:

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_core.py:3525, in _tensor_network_gate_inds_basic(tn, G, inds, ng, tags, contract, isparam, info, **compress_opts)
   3520     tlGr = tensor_contract(
   3521         tl.reindex(reindex_map), tr.reindex(reindex_map), TG
   3522     )
   3524     # decompose back into two tensors
-> 3525     tln, *maybe_svals, trn = tlGr.split(
   3526         left_inds=bnds_l,
   3527         right_inds=bnds_r,
   3528         bond_ind=bix,
   3529         get="tensors",
   3530         **compress_opts,
   3531     )
   3533 if contract == "reduce-split":
   3534     # move physical inds on reduced tensors
   3535     #
   (...)
   3540     #      ╱   ╱          ╱       ╱
   3541     #
   3542     tmp_bix_l = rand_uuid()

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_core.py:2483, in Tensor.split(self, *args, **kwargs)
   2481 @functools.wraps(tensor_split)
   2482 def split(self, *args, **kwargs):
-> 2483     return tensor_split(self, *args, **kwargs)

TypeError: tensor_split() got an unexpected keyword argument 'cutoff_mod'
liweintu commented 7 months ago

Thanks @renatomello for noting down this error.

From the call stack, it seems the way quimb is invoked has some issue. Particularly, the args provided might not be compatible. @Vinitha-balachandran Can we take a look and prepare a PR for the fix?

Vinitha-balachandran commented 7 months ago

@liweintu Sure, will check.

Vinitha-balachandran commented 7 months ago

@renatomello computation settings has to be given before the set_backend. It was a mistake in doc. And, for your code with the import c= Circuit(2) instead of c = qibo.Circuit(2). There was no error when I run the code with this fix. I will update the doc.

renatomello commented 7 months ago

@renatomello computation settings has to be given before the set_backend. It was a mistake in doc. And, for your code with the import c= Circuit(2) instead of c = qibo.Circuit(2). There was no error when I run the code with this fix. I will update the doc.

The problem was that platform should've been cutensornet instead of qutensornet.

renatomello commented 7 months ago

If I try to print the result object instead of calling the .state() method, another error appears:

In [17]: from qibo import Circuit, gates, set_backend
    ...: 
    ...: computation_settings = {
    ...:     "MPI_enabled": False,
    ...:     "MPS_enabled": False,
    ...:     "NCCL_enabled": False,
    ...:     "expectation_enabled": False,
    ...: }
    ...: 
    ...: # Set the quimb backend
    ...: set_backend(
    ...:     backend="qibotn", platform="cutensornet", runcard=computation_settings
    ...: )
    ...: 
    ...: # Construct the circuit with two qubits
    ...: c = Circuit(2)
    ...: 
    ...: # Apply Hadamard gates on first and second qubit
    ...: c.add(gates.H(0))
    ...: c.add(gates.H(1))
    ...: c.add(gates.CZ(0, 1))
    ...: 
    ...: # Execute the circuit and obtain the final state
    ...: result = c()
    ...: 
    ...: # Print the final state
    ...: print(result)
[Qibo 0.2.7|INFO|2024-03-28 10:44:57]: Using qibotn (cutensornet) backend on /CPU:0
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[17], line 27
     24 result = c()
     26 # Print the final state
---> 27 print(result)

File ~/.local/lib/python3.10/site-packages/qibo/result.py:108, in QuantumState.__str__(self)
    107 def __str__(self):
--> 108     return self.symbolic()

File ~/.local/lib/python3.10/site-packages/qibo/result.py:60, in QuantumState.symbolic(self, decimals, cutoff, max_terms)
     56     terms = self.backend.calculate_symbolic_density_matrix(
     57         self._state, self.nqubits, decimals, cutoff, max_terms
     58     )
     59 else:
---> 60     terms = self.backend.calculate_symbolic(
     61         self._state, self.nqubits, decimals, cutoff, max_terms
     62     )
     63 return " + ".join(terms)

File ~/.local/lib/python3.10/site-packages/qibo/backends/numpy.py:578, in NumpyBackend.calculate_symbolic(self, state, nqubits, decimals, cutoff, max_terms)
    576 terms = []
    577 for i in np.nonzero(state)[0]:
--> 578     b = bin(i)[2:].zfill(nqubits)
    579     if np.abs(state[i]) >= cutoff:
    580         x = np.round(state[i], decimals)

TypeError: 'ndarray' object cannot be interpreted as an integer
renatomello commented 7 months ago

Also, calling the state method kind of defeats the purpose of running circuits as MPS. Is there a way to recover the MPS itself from the Circuit Result object?

Vinitha-balachandran commented 7 months ago

About the last two comments, primarily we were interested to have one to one comparison of state vector and tensor network method. So, at present we are converting the mps (or tensor ) form to dense vector. Sure, we will consider updating it to recover also in the MPS format.

NithyasriVS commented 7 months ago

I tried to run the example inside the doc file of this repo and got this error

from qibo import Circuit, gates, set_backend

# Set the quimb backend
set_backend(
    backend="qibotn", platform="qutensornet", runcard=computation_settings
)

# Set the runcard
computation_settings = {
    "MPI_enabled": False,
    "MPS_enabled": False,
    "NCCL_enabled": False,
    "expectation_enabled": False,
}

# Construct the circuit with two qubits
c = Circuit(2)

# Apply Hadamard gates on first and second qubit
c.add(gates.H(0))
c.add(gates.H(1))

# Execute the circuit and obtain the final state
result = c()

# Print the final state
print(result.state())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[12], line 24
     21 c.add(qibo.gates.H(1))
     23 # Execute the circuit and obtain the final state
---> 24 result = c()
     26 # Print the final state
     27 print(result.state())

File ~/.local/lib/python3.10/site-packages/qibo/models/circuit.py:1117, in Circuit.__call__(self, initial_state, nshots)
   1115 def __call__(self, initial_state=None, nshots=1000):
   1116     """Equivalent to ``circuit.execute``."""
-> 1117     return self.execute(initial_state=initial_state, nshots=nshots)

File ~/.local/lib/python3.10/site-packages/qibo/models/circuit.py:1113, in Circuit.execute(self, initial_state, nshots)
   1109     return GlobalBackend().execute_distributed_circuit(
   1110         self, initial_state, nshots
   1111     )
   1112 else:
-> 1113     return GlobalBackend().execute_circuit(self, initial_state, nshots)

File ~/.local/lib/python3.10/site-packages/qibotn/backends/quimb.py:78, in QuimbBackend.execute_circuit(self, circuit, initial_state, nshots, return_array)
     73 if self.expectation_enabled == True:
     74     raise_error(
     75         NotImplementedError, "QiboTN quimb backend cannot support expectation"
     76     )
---> 78 state = eval.dense_vector_tn_qu(
     79     circuit.to_qasm(), initial_state, self.mps_opts, backend="numpy"
     80 )
     82 if return_array:
     83     return state.flatten()

File ~/.local/lib/python3.10/site-packages/qibotn/eval_qu.py:39, in dense_vector_tn_qu(qasm, initial_state, mps_opts, backend)
     36     initial_state = init_state_tn(nqubits, initial_state)
     38 circ_cls = qtn.circuit.CircuitMPS if mps_opts else qtn.circuit.Circuit
---> 39 circ_quimb = circ_cls.from_openqasm2_str(
     40     qasm, psi0=initial_state, gate_opts=mps_opts
     41 )
     43 interim = circ_quimb.psi.full_simplify(seq="DRC")
     44 amplitudes = interim.to_dense(backend=backend)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1499, in Circuit.from_openqasm2_str(cls, contents, **circuit_opts)
   1497 """Generate a ``Circuit`` instance from an OpenQASM 2.0 string."""
   1498 info = parse_openqasm2_str(contents)
-> 1499 qc = cls(info["n"], **circuit_opts)
   1500 qc.apply_gates(info["gates"])
   1501 return qc

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1438, in Circuit.__init__(self, N, psi0, gate_opts, gate_contract, gate_propagate_tags, tags, psi0_dtype, psi0_tag, bra_site_ind_id)
   1435     for tag in tags:
   1436         self._psi.add_tag(tag)
-> 1438 self.gate_opts = ensure_dict(gate_opts)
   1439 self.gate_opts.setdefault("contract", gate_contract)
   1440 self.gate_opts.setdefault("propagate_tags", gate_propagate_tags)

File ~/.local/lib/python3.10/site-packages/quimb/utils.py:189, in ensure_dict(x)
    187 if x is None:
    188     return {}
--> 189 return dict(x)

Moreover, adding a two-qubit gate leads to this error

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[14], line 25
     22 c.add(gates.CNOT(0, 1))
     24 # Execute the circuit and obtain the final state
---> 25 result = c()
     27 # Print the final state
     28 print(result.state())

File ~/.local/lib/python3.10/site-packages/qibo/models/circuit.py:1117, in Circuit.__call__(self, initial_state, nshots)
   1115 def __call__(self, initial_state=None, nshots=1000):
   1116     """Equivalent to ``circuit.execute``."""
-> 1117     return self.execute(initial_state=initial_state, nshots=nshots)

File ~/.local/lib/python3.10/site-packages/qibo/models/circuit.py:1113, in Circuit.execute(self, initial_state, nshots)
   1109     return GlobalBackend().execute_distributed_circuit(
   1110         self, initial_state, nshots
   1111     )
   1112 else:
-> 1113     return GlobalBackend().execute_circuit(self, initial_state, nshots)

File ~/.local/lib/python3.10/site-packages/qibotn/backends/quimb.py:78, in QuimbBackend.execute_circuit(self, circuit, initial_state, nshots, return_array)
     73 if self.expectation_enabled == True:
     74     raise_error(
     75         NotImplementedError, "QiboTN quimb backend cannot support expectation"
     76     )
---> 78 state = eval.dense_vector_tn_qu(
     79     circuit.to_qasm(), initial_state, self.mps_opts, backend="numpy"
     80 )
     82 if return_array:
     83     return state.flatten()

File ~/.local/lib/python3.10/site-packages/qibotn/eval_qu.py:39, in dense_vector_tn_qu(qasm, initial_state, mps_opts, backend)
     36     initial_state = init_state_tn(nqubits, initial_state)
     38 circ_cls = qtn.circuit.CircuitMPS if mps_opts else qtn.circuit.Circuit
---> 39 circ_quimb = circ_cls.from_openqasm2_str(
     40     qasm, psi0=initial_state, gate_opts=mps_opts
     41 )
     43 interim = circ_quimb.psi.full_simplify(seq="DRC")
     44 amplitudes = interim.to_dense(backend=backend)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1500, in Circuit.from_openqasm2_str(cls, contents, **circuit_opts)
   1498 info = parse_openqasm2_str(contents)
   1499 qc = cls(info["n"], **circuit_opts)
-> 1500 qc.apply_gates(info["gates"])
   1501 return qc

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1624, in Circuit.apply_gates(self, gates, **gate_opts)
   1622 for gate in gates:
   1623     if isinstance(gate, Gate):
-> 1624         self._apply_gate(gate, **gate_opts)
   1625     else:
   1626         self.apply_gate(*gate, **gate_opts)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/circuit.py:1545, in Circuit._apply_gate(self, gate, tags, **gate_opts)
   1540     SPECIAL_GATES[gate.label](
   1541         self._psi, *gate.params, *gate.qubits, **opts
   1542     )
   1543 else:
   1544     # apply the gate to the TN!
-> 1545     self._psi.gate_(gate.array, gate.qubits, tags=tags, **opts)
   1547 # keep track of the gates applied
   1548 self.gates.append(gate)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_1d.py:557, in TensorNetwork1DVector.gate(self, inplace, *args, **kwargs)
    555 @functools.wraps(gate_TN_1D)
    556 def gate(self, *args, inplace=False, **kwargs):
--> 557     return gate_TN_1D(self, *args, inplace=inplace, **kwargs)

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_1d.py:231, in gate_TN_1D(tn, G, where, contract, tags, propagate_tags, info, inplace, cur_orthog, **compress_opts)
    229 if contract == "swap+split":
    230     if ng >= 2:
--> 231         return tn.gate_with_auto_swap(
    232             G,
    233             where,
    234             cur_orthog=cur_orthog,
    235             inplace=inplace,
    236             **compress_opts,
    237         )
    238     else:
    239         contract = True

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_1d.py:1880, in MatrixProductState.gate_with_auto_swap(self, G, where, inplace, cur_orthog, **compress_opts)
   1878 # make sure sites are orthog center, then apply and split
   1879 mps.canonize((i, i + 1), cur_orthog)
-> 1880 mps.gate_split_(
   1881     G, where=(i + 1, i) if need2flip else (i, i + 1), **compress_opts
   1882 )
   1884 if need2swap:
   1885     # move j site back to original position
   1886     mps.swap_site_to(
   1887         i + 1, j, cur_orthog=(i, i + 1), inplace=True, **compress_opts
   1888     )

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_1d.py:1728, in MatrixProductState.gate_split(self, G, where, inplace, **compress_opts)
   1726 ix_i, ix_j = map(self.site_ind, where)
   1727 # note that 'reduce-split' is unecessary: tensors have ndim<=3
-> 1728 return self.gate_inds(
   1729     G, (ix_i, ix_j), contract="split", inplace=inplace, **compress_opts
   1730 )

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_core.py:3848, in tensor_network_gate_inds(self, G, inds, contract, tags, info, inplace, **compress_opts)
   3841         raise ValueError(
   3842             "For a parametrized gate acting on more than one site "
   3843             "``contract`` must be false to preserve the array shape."
   3844         )
   3846 if basic:
   3847     # no gate splitting involved
-> 3848     _tensor_network_gate_inds_basic(
   3849         tn, G, inds, ng, tags, contract, isparam, info, **compress_opts
   3850     )
   3851 else:
   3852     # possible splitting of gate itself involved
   3853     if ng > 2:

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_core.py:3525, in _tensor_network_gate_inds_basic(tn, G, inds, ng, tags, contract, isparam, info, **compress_opts)
   3520     tlGr = tensor_contract(
   3521         tl.reindex(reindex_map), tr.reindex(reindex_map), TG
   3522     )
   3524     # decompose back into two tensors
-> 3525     tln, *maybe_svals, trn = tlGr.split(
   3526         left_inds=bnds_l,
   3527         right_inds=bnds_r,
   3528         bond_ind=bix,
   3529         get="tensors",
   3530         **compress_opts,
   3531     )
   3533 if contract == "reduce-split":
   3534     # move physical inds on reduced tensors
   3535     #
   (...)
   3540     #      ╱   ╱          ╱       ╱
   3541     #
   3542     tmp_bix_l = rand_uuid()

File ~/.local/lib/python3.10/site-packages/quimb/tensor/tensor_core.py:2483, in Tensor.split(self, *args, **kwargs)
   2481 @functools.wraps(tensor_split)
   2482 def split(self, *args, **kwargs):
-> 2483     return tensor_split(self, *args, **kwargs)

TypeError: tensor_split() got an unexpected keyword argument 'cutoff_mod'

This is due to setting every possible computation setting to False. In order to use the quimb backend's dense vector function, MPS_enabled must be True since the function uses mps_opts for its calculation. I've proposed a PR to add a note for the user in the doc to let them know that this would be an invalid configuration for computation settings #57

Additionally, error handling can be introduced under quimb.py as follows:

mps_enabled_value = runcard.get("MPS_enabled") expectation_enabled_value = runcard.get("expectation_enabled") if mps_enabled_value == False and expectation_enabled_value == False: raise TypeError("Please set either MPS_enabled or expectation_enabled to True")

Vinitha-balachandran commented 7 months ago

@NithyasriVS , error encountered by you was due to the computation setting written after set backend. There is no issue when everything is false, I have tried it for the issue mentioned by @renatomello. This was the fix I proposed for the earlier issue. I don't think this statement is true "In order to use the quimb backend's dense vector function, MPS_enabled must be True since the function uses mps_opts for its calculation."

NithyasriVS commented 7 months ago

Irrespective of the programmatical working, I feel my point about the configuration is still valid as setting all computation settings to False may not be a meaningful way to use qibotn as the user no longer knows what their output is a computation of, especially as more features/computations get added to the QuimbBackend in the future. So, it could be useful to restrict the user from wanting to use the configuration where are settings are False.