Get current random seed for reproducibility

fepegar: <p>Hi all,</p>
<p>I would like to write an object that generates a deterministic output given a seed. Without the given seed, I’d like it to return <em>the seed that would generate the same output</em>. Furthermore, it should be aware of any manual seed set before its creation. I think I’m close, but I’m not quite there yet. Context: <a href="https://github.com/fepegar/torchio/issues/208" rel="nofollow noopener">reproducibility of random transforms in TorchIO</a>.</p>
<p>I’ve read the docs on <a href="https://pytorch.org/docs/stable/notes/randomness.html" rel="nofollow noopener">reproducibility</a>, <a href="https://pytorch.org/docs/master/generated/torch.Generator.html" rel="nofollow noopener"><code>torch.Generator</code></a>, <a href="https://pytorch.org/docs/stable/_modules/torch/random.html#fork_rng" rel="nofollow noopener"><code>fork_rng</code></a>, etc., but I might have missed something.</p>
<p>This is some code I’m playing with, called <code>script.py</code>:</p>
<pre><code class="lang-python">import sys
import torch

if len(sys.argv) &gt; 1:
    seed = int(sys.argv[1])
    torch.manual_seed(seed)
    print('Initial seed:', seed)
else:
    print('No initial seed')

def random_stuff(seed=None):
    with torch.random.fork_rng():
        if seed is None:
            seed = torch.seed()
        else:
            torch.manual_seed(seed &amp; (2**63 - 1))
        number = int(1000 * torch.rand(1).item())
    return number, seed

print('random_stuff(seed=None):', random_stuff(seed=None))
nice_number, nice_seed = random_stuff(seed=None)
print('random_stuff(seed=None) to reproduce:', nice_number, nice_seed)
print('random_stuff(seed=42):', random_stuff(seed=42))
print('random_stuff(seed=42):', random_stuff(seed=42))
print('1000 * int(torch.rand(1).item()):', int(1000 * torch.rand(1).item()))
print('Reproduced result:', random_stuff(seed=nice_seed)[0])
print('1000 * int(torch.rand(1).item()):', int(1000 * torch.rand(1).item()))
print()
</code></pre>
<p>I call this command:</p>
<pre><code class="lang-auto">$ for i in {,,99,99}; do python script.py $i; done      
</code></pre>
<p>And get this output, that I have commented:</p>
<pre><code class="lang-python">No initial seed
random_stuff(seed=None): (233, 1238635228448488131)
random_stuff(seed=None) to reproduce: 270 16876508215961374208
random_stuff(seed=42): (882, 42)
random_stuff(seed=42): (882, 42)
1000 * int(torch.rand(1).item()): 154
Reproduced result: 270
1000 * int(torch.rand(1).item()): 771

No initial seed
random_stuff(seed=None): (873, 6207067658288732991)
random_stuff(seed=None) to reproduce: 83 9352679628244516342
random_stuff(seed=42): (882, 42)
random_stuff(seed=42): (882, 42)
1000 * int(torch.rand(1).item()): 591
Reproduced result: 83
1000 * int(torch.rand(1).item()): 20

Initial seed: 99
random_stuff(seed=None): (442, 4463515504174338291)
random_stuff(seed=None) to reproduce: 919 5178903995377210757
random_stuff(seed=42): (882, 42)
random_stuff(seed=42): (882, 42)
1000 * int(torch.rand(1).item()): 103
Reproduced result: 919
1000 * int(torch.rand(1).item()): 970

Initial seed: 99
random_stuff(seed=None): (95, 3538104565691272705)
random_stuff(seed=None) to reproduce: 24 12991252712705207801
random_stuff(seed=42): (882, 42)
random_stuff(seed=42): (882, 42)
1000 * int(torch.rand(1).item()): 103
Reproduced result: 24
1000 * int(torch.rand(1).item()): 970
</code></pre>
<p>I would like the first two (and second to last) lines of the 4th block to be the same as the ones in the 3rd block.</p>
<p>Do you know which direction I should follow here? I feel like I should somehow get the “current seed” instead of calling <code>torch.seed()</code>. I’ve tried different things involving e.g. <code>torch.default_generator</code>, with no luck.</p>