<div dir="ltr"><div dir="ltr">On Mon, Dec 14, 2020 at 3:27 PM Evgeni Burovski <<a href="mailto:evgeny.burovskiy@gmail.com" target="_blank">evgeny.burovskiy@gmail.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><snip><br>
<br>
> I also think that the lock only matters for Multithreaded code not Multiprocess. I believe the latter pickles and unpickles any Generator object (and the underying BitGenerator) and so each process has its own version. Note that when multiprocessing the recommended procedure is to use spawn() to generate a sequence of BitGenerators and to use a distinct BitGenerator in each process. If you do this then you are free from the lock.<br>
<br>
Thanks. Just to confirm: does using SeedSequence spawn_key arg<br>
generate distinct BitGenerators? As in<br>
<br>
cdef class Wrapper():<br>
def __init__(self, seed):<br>
entropy, num = seed<br>
py_gen = PCG64(SeedSequence(entropy, spawn_key=(spawn_key,)))<br>
self.rng = <bitgen_t *><br>
py_gen.capsule.PyCapsule_GetPointer(capsule, "BitGenerator") # <---<br>
this<br>
<br>
cdef Wrapper rng_0 = Wrapper(seed=(123, 0))<br>
cdef Wrapper rng_1 = Wrapper(seed=(123, 1))<br>
<br>
And then,of these two objects, do they have distinct BitGenerators?<br></blockquote><div><br></div><div>The code you wrote doesn't work (`spawn_key` is never assigned). I can guess what you meant to write, though, and yes, you would get distinct `BitGenerator`s. However, I do not recommend using `spawn_key` explicitly. The `SeedSequence.spawn()` method internally keeps track of how many children it has spawned and uses that to construct the `spawn_key`s for its subsequent children. If you play around with making your own `spawn_key`s, then the parent `SeedSequence(entropy)` might spawn identical `SeedSequence`s to the ones you constructed.</div><div><br></div><div>If you don't want to use the `spawn()` API to construct the separate `SeedSequence`s but still want to incorporate some per-process information into the seeds (e.g. the 0 and 1 in your example), then note that a tuple of integers is a valid value for the `entropy` argument. You can have the first item be the same (i.e. per-run information) and the second item be a per-process ID or counter.</div><div><br></div><div>cdef class Wrapper():<br>
def __init__(self, seed):<br>
py_gen = PCG64(SeedSequence(seed))<br>
self.rng = <bitgen_t *>py_gen.capsule.PyCapsule_GetPointer(capsule, "BitGenerator")<br>
<br>
cdef Wrapper rng_0 = Wrapper(seed=(123, 0))<br>
cdef Wrapper rng_1 = Wrapper(seed=(123, 1))<br></div></div><div><br></div>-- <br><div dir="ltr">Robert Kern</div></div>