Skip to content

Commit

Permalink
Create a new method to return the final state vector array instead of…
Browse files Browse the repository at this point in the history
… wrapping it

This is to avoid the numpy limit on the number of dimensions quantumlib/Cirq#6031

The 1D representation should only be used when the number of qubits is greater than the numpy limit on the number of dimensions (currently set to 32) numpy/numpy#5744.

```py3
_, state_vector, _ = s.simulate_into_1d_array(c)
```
fixes quantumlib/Cirq#6031
  • Loading branch information
NoureldinYosri committed Oct 18, 2023
2 parents 148a9c6 + a1025aa commit 90d2707
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/bazeltest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
- name: Upgrade libc
# An LLVM update broke this test, fix per is https://bugs.llvm.org/show_bug.cgi?id=27310.
run: |
sudo apt-get upgrade libc-bin=2.31-0ubuntu9.9
sudo apt-get upgrade libc-bin
- name: Run C++ tests
run: |
bazel test --config=avx --config=openmp \
Expand Down
95 changes: 63 additions & 32 deletions qsimcirq/qsim_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,42 +435,13 @@ def compute_amplitudes_sweep_iter(
options["s"] = self.get_seed()
yield simulator_fn(options)

def simulate_sweep_iter(
def _simulate_impl(
self,
program: cirq.Circuit,
params: cirq.Sweepable,
qubit_order: cirq.QubitOrderOrList = cirq.QubitOrder.DEFAULT,
initial_state: Optional[Union[int, np.ndarray]] = None,
) -> Iterator[cirq.StateVectorTrialResult]:
"""Simulates the supplied Circuit.
This method returns a result which allows access to the entire
wave function. In contrast to simulate, this allows for sweeping
over different parameter values.
Avoid using this method with `use_gpu=True` in the simulator options;
when used with GPU this method must copy state from device to host memory
multiple times, which can be very slow. This issue is not present in
`simulate_expectation_values_sweep`.
Args:
program: The circuit to simulate.
params: Parameters to run with the program.
qubit_order: Determines the canonical ordering of the qubits. This is
often used in specifying the initial state, i.e. the ordering of the
computational basis states.
initial_state: The initial state for the simulation. This can either
be an integer representing a pure state (e.g. 11010) or a numpy
array containing the full state vector. If none is provided, this
is assumed to be the all-zeros state.
Returns:
List of SimulationTrialResults for this run, one for each
possible parameter resolver.
Raises:
TypeError: if an invalid initial_state is provided.
"""
) -> Iterator[Tuple[cirq.ParamResolver, np.ndarray, Sequence[int]]]:
if initial_state is None:
initial_state = 0
if not isinstance(initial_state, (int, np.ndarray)):
Expand Down Expand Up @@ -526,8 +497,68 @@ def simulate_sweep_iter(
assert qsim_state.dtype == np.float32
assert qsim_state.ndim == 1

yield prs, qsim_state.view(np.complex64), cirq_order

def simulate_into_1d_array(
self,
program: cirq.AbstractCircuit,
param_resolver: cirq.ParamResolverOrSimilarType = None,
qubit_order: cirq.QubitOrderOrList = cirq.ops.QubitOrder.DEFAULT,
initial_state: Any = None,
) -> Tuple[cirq.ParamResolver, np.ndarray, Sequence[int]]:
"""Same as simulate() but returns raw simulation result without wrapping it.
The returned result is not wrapped in a StateVectorTrialResult but can be used
to create a StateVectorTrialResult.
Returns:
Tuple of (param resolver, final state, qubit order)
"""
params = cirq.study.ParamResolver(param_resolver)
return next(self._simulate_impl(program, params, qubit_order, initial_state))

def simulate_sweep_iter(
self,
program: cirq.Circuit,
params: cirq.Sweepable,
qubit_order: cirq.QubitOrderOrList = cirq.QubitOrder.DEFAULT,
initial_state: Optional[Union[int, np.ndarray]] = None,
) -> Iterator[cirq.StateVectorTrialResult]:
"""Simulates the supplied Circuit.
This method returns a result which allows access to the entire
wave function. In contrast to simulate, this allows for sweeping
over different parameter values.
Avoid using this method with `use_gpu=True` in the simulator options;
when used with GPU this method must copy state from device to host memory
multiple times, which can be very slow. This issue is not present in
`simulate_expectation_values_sweep`.
Args:
program: The circuit to simulate.
params: Parameters to run with the program.
qubit_order: Determines the canonical ordering of the qubits. This is
often used in specifying the initial state, i.e. the ordering of the
computational basis states.
initial_state: The initial state for the simulation. This can either
be an integer representing a pure state (e.g. 11010) or a numpy
array containing the full state vector. If none is provided, this
is assumed to be the all-zeros state.
Returns:
Iterator over SimulationTrialResults for this run, one for each
possible parameter resolver.
Raises:
TypeError: if an invalid initial_state is provided.
"""

for prs, state_vector, cirq_order in self._simulate_impl(
program, params, qubit_order, initial_state
):
final_state = cirq.StateVectorSimulationState(
initial_state=qsim_state.view(np.complex64), qubits=cirq_order
initial_state=state_vector, qubits=cirq_order
)
# create result for this parameter
# TODO: We need to support measurements.
Expand Down
10 changes: 10 additions & 0 deletions qsimcirq_tests/qsimcirq_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2058,3 +2058,13 @@ def test_cirq_global_phase_gate():
assert cirq.approx_eq(
qsim_result.state_vector(), cirq_result.state_vector(), atol=1e-6
)


def test_1d_representation():
qsim_sim = qsimcirq.QSimSimulator()
qs = cirq.LineQubit.range(2)
c = cirq.Circuit(cirq.H.on_each(qs), cirq.X(qs[0]), cirq.Y(qs[1]))

want = np.array([0.0 - 0.5j, 0.0 + 0.5j, 0.0 - 0.5j, 0.0 + 0.5j])
_, res, _ = qsim_sim.simulate_into_1d_array(c)
np.testing.assert_allclose(res, np.array(want, dtype=np.complex64))

0 comments on commit 90d2707

Please sign in to comment.