Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set different seed for each sampling in AerStatevector #1663

Merged
merged 5 commits into from
Dec 2, 2022

Conversation

hhorii
Copy link
Collaborator

@hhorii hhorii commented Nov 18, 2022

Summary

Previously seed is not initialized in AerStatevector and then sampled results are always same. With this commit, a seed is initialized for each sampling and sampled results can be vary.

Details and comments

Previously, sampled counts are always same in multiple calls because AerStatevector uses the same seed to generate random values which are used in processing sample_counts(). More specifically, _seed is not initialized in state_controller if seed_simulator is not set. For example, following two sampled values count0 and count1 are the same.

circ = QuantumVolume(5, seed=1111)
state = AerStatevector(circ)

shots = 1024
counts0 = state.sample_counts(shots, qargs=range(5))
counts1 = state.sample_counts(shots, qargs=range(5))

Even if seed_simulator is set, the value is reused to initialize RngEngine and sampled counts become same.

With this PR, _seed is initialized with std::random_device() and renewed seed_simulator for each sampling, and then sampled counts are always different in the same AerStatevector instance.

@hhorii hhorii added the stable-backport-potential The issue or PR might be minimal and/or import enough to backport to stable label Nov 18, 2022
@hhorii hhorii added this to the Aer 0.11.2 milestone Nov 18, 2022
Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

Is it always going to be the case that a user will want the RNG to advance by calling sample_memory? I'm thinking probably yes, but I'm just mentioning it as a question.

Comment on lines 116 to 120
self._aer_state = AerState(**self._aer_state.configuration())

configs = self._aer_state.configuration()
if 'seed_simulator' in configs:
configs['seed_simulator'] = int(configs['seed_simulator']) + 1
self._aer_state = AerState(**configs)
Copy link
Member

Choose a reason for hiding this comment

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

This seems like a slightly odd split in responsibilities. Perhaps it would be more convenient for now, and for future development if AerState gains an advance_rng method or something like that mutates the AerState in place. It'll be easier to re-use between the different Aer quantum_info classes you're planning that way, it gives clearer hints as to what's happening, and modifying it is kind of an AerState internal feature that we don't particularly want client classes to need to know about.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

QuantumState advances RNG. So, AerStatevector also needs to advance it in sample_memory().
https://github.com/Qiskit/qiskit-terra/blob/main/qiskit/quantum_info/states/quantum_state.py#L269

However, instead of manually update of seed_simulator by increasing 1, it is better to succeed the state of mt19937 from the previous AerState.

int seed_;
int seed_ = std::random_device()();
Copy link
Member

Choose a reason for hiding this comment

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

What was happening before this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Depending on environemnt. In my macbook (clang), it was always set 0.

@hhorii
Copy link
Collaborator Author

hhorii commented Dec 1, 2022

@jakelishman With 4b80871, AerStatevector uses a random number generator of mt19937. Also, AerStatevector overrides seed() to enable reproducing same returns from sample_memory() by calling seed() before each sample_memory().

Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

One comment aside, this looks like a much cleaner split of responsibilities to me, thanks!

@@ -661,13 +658,21 @@ void AerState::initialize() {

state_->initialize_qreg(num_of_qubits_);
state_->initialize_creg(num_of_qubits_, num_of_qubits_);
rng_.set_seed(seed_);
Copy link
Member

Choose a reason for hiding this comment

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

Do we still need to track the seed_ member after this change? I see it's still used in clear_ops(), but it's not 100% clear to me why that function should reset the RNG. Admittedly, I'm not exactly clear on the circumstances in which it's called.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

last_result_.seed = buffer_.seed;

This seed_ is to be returned as a member of a result. AerState.last_result() returns it. We may not need to construct a result as AerSimulator does for each call of methods, but it is not expensive to keep seed_, I think.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, sounds good to me then!

@jakelishman jakelishman added Changelog: Bugfix Include in the Fixed section of the changelog automerge This PR will automatically merge once its CI has passed labels Dec 2, 2022
@mergify mergify bot merged commit a71f17f into Qiskit:main Dec 2, 2022
hhorii added a commit to hhorii/qiskit-aer that referenced this pull request Dec 2, 2022
* update seed for multiple calls of sample_memory

* correct seed_simulator update in AerStatevector

* set seed in AerState explicitly and reuse AerState in AerStatevector for sampling

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge This PR will automatically merge once its CI has passed Changelog: Bugfix Include in the Fixed section of the changelog stable-backport-potential The issue or PR might be minimal and/or import enough to backport to stable
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants