NVIDIA / cuQuantum

Home for cuQuantum Python & NVIDIA cuQuantum SDK C++ samples
https://docs.nvidia.com/cuda/cuquantum/
BSD 3-Clause "New" or "Revised" License
320 stars 63 forks source link

Issue with using the Cirq frontend simulate(program=...) #75

Closed mtjrider closed 11 months ago

mtjrider commented 11 months ago

Referencing this issue: https://github.com/quantumlib/qsim/issues/618

cc @paaige

mtjrider commented 11 months ago

The code, as posted:

import cirq
import qsimcirq
from cirq.contrib import quantum_volume

options = {"f": 4, "g": True, "gmode": 1}
gpu_options = qsimcirq.QSimOptions(options)
sim = qsimcirq.QSimSimulator(gpu_options)

def qv_circuit_cirq(depth, num_qubits, seed=None):
    if seed is not None:
        state = np.random.RandomState(int(seed, 2))
    else:
        state=None
    return quantum_volume.generate_model_circuit(num_qubits, depth, random_state=state)

qc = qv_circuit_cirq(9, num_qubits=3)
print(sim.simulate(program=qc).final_state_vector)

will not work. It produces this error on cuQuantum Appliance version 23.03:

Traceback (most recent call last):
  File "test3.py", line 17, in <module>
    print(sim.simulate(program=qc).final_state_vector)
  File "/home/cuquantum/conda/envs/cuquantum-23.03/lib/python3.8/site-packages/cirq/sim/simulator.py", line 495, in simulate
    return self.simulate_sweep(
  File "/home/cuquantum/conda/envs/cuquantum-23.03/lib/python3.8/site-packages/cirq/sim/simulator.py", line 510, in simulate_sweep
    return list(self.simulate_sweep_iter(program, params, qubit_order, initial_state))
  File "/home/cuquantum/conda/envs/cuquantum-23.03/lib/python3.8/site-packages/qsimcirq/qsim_simulator.py", line 620, in simulate_sweep_iter
    qsim_state = fullstate_simulator_fn(options, initial_state)
RuntimeError: Unable to cast Python instance to C++ type (compile in debug mode for details)

To avoid this error, you must declare the simulator and use it as follows:

import cirq
import qsimcirq
from cirq.contrib import quantum_volume

options = qsimcirq.QSimOptions(
    max_fused_gate_size=4,
    disable_gpu=False,
    gpu_mode=(0,)  # change to (0,1,...) for multiple GPUs
)

simulator = qsimcirq.QSimSimulator(qsim_options=options)

def qv_circuit_cirq(depth, num_qubits, seed=None):
    if seed is not None:
        state = np.random.RandomState(int(seed, 2))
    else:
        state=None
    return quantum_volume.generate_model_circuit(num_qubits, depth, random_state=state)

qc = qv_circuit_cirq(9, num_qubits=3)
result = simulator.simulate(qc)
print(result.state_vector())  # result.final_state_vector also works

We document this here. If there is any confusion, please let us know.

95-martin-orion commented 11 months ago

To clarify: the issue in the original code was that the options dict was passed to the QSimOptions constructor, which only accepts individual option values, not a dict.

The solution above will work; alternatively, you can pass the {string: value} input format referenced in the docstring to QSimSimulator directly:

options = {"f": 4, "g": True, "gmode": 1}
sim = qsimcirq.QSimSimulator(options)
mtjrider commented 11 months ago

@95-martin-orion thanks. Yes. We added additional GPU modes in the cuQuantum Appliance. I wanted to clarify how to utilize the multi-GPU backend in the aforementioned case.

mtjrider commented 11 months ago

Marking this issue addressed.