quantumlib / Cirq

A Python framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
Apache License 2.0
4.28k stars 1.02k forks source link

Avoid pickling of cached values of `cached_method` decorated functions #6674

Closed pavoljuhas closed 3 months ago

pavoljuhas commented 3 months ago

Description of the issue

For some gates, e.g., cirq.H, the hash(gate) value is stored with cached_method decorator which breaks dictionary lookup if such gate is passed to multiprocessing worker. This seems to be the root cause for dictionary lookup problem in https://github.com/quantumlib/Cirq/issues/6667#issuecomment-2233834127.

How to reproduce the issue

import multiprocessing
import cirq

def compare_hash(gate):
    print(f"{hash(gate)=}  {hash(cirq.H)=}")

if __name__ == "__main__":
    ctx = multiprocessing.get_context("spawn")
    p = ctx.Process(target=compare_hash, args=(cirq.H,))
    p.start()
    p.join()

Output

hash(gate)=4057262618035729319  hash(cirq.H)=-7715581409246145106

Proposed solution

Do not pickle cached values from cached_method calls. Arguments to multiprocessing workers are passed as pickles so the results of cached methods (and of hash(cirq.H)) would be computed on the worker side.

Similar to #3777 and #5738

Cirq version You can get the cirq version by printing cirq.__version__. From the command line:

1.5.0.dev at 8d09a3220962c4e5eeed30ea33b9d120619b585f