cuda rng state does NOT change when re-seeding!!! WHY is that?
- Consider 1 GPU only.
- Pytorch 1.0.0. Python 3.7.0
- Related.
Expected behavior:
The rng state change in a deterministic way with respect to the seed.
Reality:
rng state does not care about your seed. It behaves on its own way.
Code:
import copy
import torch
seed = 1
use_cuda = True
l = (torch.cuda.get_rng_state())
# np.savetxt("rng_state_init.txt".format(0), l.numpy())
for i in range(10):
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
lastl = copy.deepcopy(l)
l = (torch.cuda.get_rng_state())
print((l == lastl).all())
a = torch.rand(1, device="cuda") # torch.bernoulli(torch.full((300, 300), 0.5, device='cuda:0'))
print(a)
Issues of the above code:
- The initial state of the rng is random. Each run will start with a different rng state. This is fine. You can check this by storing the rng state on disc to compare the different runs. Reseeding before the loop is not problem since reseeding does not change the rng state.
- The main issue is that after reseeding the rng with the same seed, the rng state will be random!!!. To check this, one can run the above code many times, and check the value of
print((l == lastl).all())
. What we expect is that after the first iteration, we findTrue (0)
ALWAYS because reseeding is expected to reset the rng state to a state that corresponds to the seed. But, you will find from time to timeFalse (1)
. - Yes,
a
is always the same. This is expected.
Now, my question is: why resetting the seed does not change the rng state? (as in Numpy, for instance).
Here are some runs:
run 1:
tensor(0, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor(0.2921, device='cuda:0')
run 2:
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
run 3:
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
run 4:
tensor(0, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
tensor(1, dtype=torch.uint8)
tensor([0.2921], device='cuda:0')
You see how random it is!!!
+++++++++++++++++++++++++++++++++++++++++++++++++
NUMPY
+++++++++++++++++++++++++++++++++++++++++++++++++
Code:
import copy
import numpy as np
seed = 1
use_cuda = True
np.random.seed(0)
l = np.random.get_state()
# np.savetxt("{}.txt".format(0), l[1])
for i in range(10):
np.random.seed(seed)
lastl = copy.deepcopy(l)
l = (np.random.get_state())
print((l[1] == lastl[1]).all())
a = np.random.uniform(1)
print(a)
run 1:
False
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
run 2:
False
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
run 3:
False
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
run 4:
False
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
run 5:
False
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
True
1.0
See how deterministic Numpy is!!!
Thanks!