Skip to content

Added optional prng parameter to sampler and simulator methods - #8289

Open
AamindMandragora wants to merge 6 commits into
quantumlib:mainfrom
AamindMandragora:issue-6567
Open

Added optional prng parameter to sampler and simulator methods#8289
AamindMandragora wants to merge 6 commits into
quantumlib:mainfrom
AamindMandragora:issue-6567

Conversation

@AamindMandragora

Copy link
Copy Markdown
Contributor

Should complete #6567

Threaded an optional prng: np.random.Generator | None through sampler and simulator APIs, defaults to None, all run_batch and run_batch_async call prng.spawn(len(programs)) to give each circuit its own child generator, making batched runs independent, added helpers that are agnostic to Generator vs RandomState, still backwards-compatible with simulators and samplers that don't have prng.

@github-actions github-actions Bot added the size: XL lines changed >1000 label Aug 29, 2026

@mhucka mhucka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this work. Here are some initial review comments.


def get_random_array(
rng: np.random.RandomState | np.random.Generator, shape: Sequence[int] | None = None
):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and the other new functions in this file lack return type annotations. Could you please add them? (I won't flag every case; they're easy enough to find.)

rng: np.random.RandomState | np.random.Generator,
low: int,
high: int | None = None,
size: Sequence[int] | None = None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The size parameter is passed to np.random.Generator.integers and np.random.RandomState.randint, but those methods accept both ints and sequences of ints. Can you adjust the type declaration?

return list(self.run_sweep_iter(program, params, repetitions))
if prng is None:
return list(self.run_sweep_iter(program, params, repetitions))
return list(self.run_sweep_iter(program, params, repetitions, prng))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some cases in the new code, prng is passed as a keyword argument, while in other cases like here, it's passed as a positional argument. It would be better to make them all consistent. Preferably, the keyword argument approach should be used (i.e., typically prng=prng).

Comment on lines +68 to +70
theta = np.arcsin(np.sqrt(random_state.get_random_array(real_rng, shape)))
phi_d = random_state.get_random_array(real_rng, shape) * np.pi * 2
phi_o = random_state.get_random_array(real_rng, shape) * np.pi * 2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what will happen here if shape = (). Could you add a test case for that (if there isn't already one)?

initial_state: Any,
qubits: Sequence[cirq.Qid],
classical_data: cirq.ClassicalDataStore,
prng: np.random.Generator | None = None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter is not used. This behavior should be documented, or (better) the parameter should be forwarded if the self.state_type method accepts it (e.g., if it's a custom state type that accepts prng).

@mhucka mhucka self-assigned this Sep 4, 2026

@arettig arettig left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this! I think a lot of these changes can be removed with some design changes. Ideally, we should leave the RandomState architecture untouched and add separate support for generators, so that we can deprecate RandomState and transition to generators over time.

My suggestions:

  • Leave parse_random_state alone.
  • Leave samplers alone.
  • Change SimulatorBase._prng to accept either a RandomState or a Generator
  • Change SimulationState to accept either a RandomState or a Generator

There will be a couple other places you have to clean up where RandomState specific methods are used, but probably not that many. Just these couple changes should get us the functionality necessary while being minimally invasive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: XL lines changed >1000

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants