-
-
Notifications
You must be signed in to change notification settings - Fork 0
WIP: Small Fast Chaotic PRNGs #41
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
Conversation
* BUG: Keep the integers uint32_t, add test
* ENH: Expose and use n_children_spawned * DOC: docstring formatting and cleanups. * TST: more test coverage of SeedSequence.
Some Win64 timings
and Win32
|
I would prefer to add only one of them to numpy. We could add both to the collection of alternative BitGenerators in numpy/bitgenerators |
Certainly, hence the WIP. I wanted both up for comparison purposes. I'd pick |
BTW, I suspect the comment about jump-ahead is a copy-and-paste-o. The same comment is at the bottom of some other PRNGs where it is actually true. FWIW, I reported to Chris that PractRand claimed to find a problem with SFC64 (but not the smaller variant). In version 0.94 of PractRand Chris changed the constants for SFC, which may address/avoid the issue. |
Hmm, no, there's no difference in the |
Oh, sorry, I misread the release notes. You're right, the constants were improved in 0.93. Which is unfortunate because it means that the version that failed
In the interests of making sure the result reproduces, I've set it rerunning on a faster machine. It should be done in about a week. |
I've patched PractRand to let me just run the |
FWIW, here's the full log file from when I tested it. The whole thing is pretty weird. It's super unhappy about it, but then its outrage fades as more data comes in. |
Interesting. In my
And then promptly mis-pressed Ctrl-C to copy that here, so I have to start again. My other run with a different seed is still running at 64 TiB as well and is still going. |
It's all a bit of a PITA. When I tried yesterday to reproduce it with 0.94, I saw early differences from my run with some of the other tests. Rerunning with 0.93, I see the same output for these other tests which gives me more confidence. I looked briefly at backporting your Alas, running the code on my iMac at home (a Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz) was supposed to be faster than my main test machine a (Intel(R) Xeon(R) CPU E7-4830 v3 @ 2.10GHz), but as the test wears on that is proving to not be the case. (It's possible that the whole thing was a glitch related to a race condition in the |
Interesting. I'll do the backporting. If I can provoke the same failure, then I think that'll be confirmation enough. If not, then a full run is still probably warranted. I've pushed an implementation of David Blackman's GJrand as well. It has many of the same desirable properties as |
One issue with all of these chaotic PRNGs is that their authors don't allow you to seed the full state of the generator, just part of it. For JSF, it's merely because the author did some testing on the limited range of allowed seedings (beyond the probabilistic guarantee that would have existed); for the counter-based variants, it's because the guarantees that the counter provides disappear if you let the counter have an arbitrary starting value. Having less random seed data than the state size of the PRNG will typically introduce a kind of bias. This bias is only easily detectable if the space of allowed speeds is very small (e.g., 32 bits), otherwise we're in too big to fail territory. To explore this, I just wrote seeding_bias.cpp, which is a modest tweak on code I wrote to show bias initializing the Mersenne Twister with simple seeds. Here's what happens if we run it on
This also happens for
(These two PRNGs also allow three-word and two-word seeding respectively, which is too large to test, but would also technically have bias as well for the same reasons.) Just to show that it doesn't have to be this way (i.e., if the amount of seed data matches the internal state size):
FWIW, for both |
Thanks. I had to also patch (Clang also warned about various other problems with the overall source.) |
Yeah, I applied a patch for that as well. |
Would it make sense to add GJrand, JSF64 and SFC64 to numpy/bitgenerators and then change this PR to only add SFC64 to numpy.random? I understand then we would remove PCG64 and PCG32 from numpy.random as well. |
I don't think PCG64 is going away, is it? |
As I understood it, the goal is to release 1.17.0 with two BitGenerators: MT19937 and one other. All the rest would live in numpy/bitgenerators. |
I might have missed that thread/comment. |
With the
That leads me to believe it was some kind of strange one-time glitch in the tester and |
No consensus has been reached on that point. I proposed it, but was convinced that including My current proposal is |
I added GJrand, JSF64, SFC64 to numpy/bitgenerators. Could you redo this PR against numpy/numpy to add SFC64, then we can move toward PCG64, MT19937, Philox, and SFC64 only. |
I concur. Possibly-insulting question: on the original machine which you ran the tests, did you have ECC memory? I always enjoy cosmic-ray-corrupted-my-process stories. But a bug in PractRand's multithreading seems more likely. |
I updated the README to describe the bitgenerators, I hope I was accurate. |
FWIW, my main test machine is a Silicon Mechanics Rackform R422.v5 [based on the SuperMicro X10QBL board], with four 12-core Intel(R) Xeon(R) CPU E7-4830 v3 @ 2.10GHz and 32 Samsung M393B2G70QH0-YK0 16GB DDR3 1600 ECC Registered DIMMs, giving me 96 hyperthreaded cores and 512 GB of goodness. (It's a really nice machine!) |
f6e8d21
to
c69f90c
Compare
Replaced by numpy#13838 |
…_assign_subscript Merge in numpy-hpy from ss/array_transpose to labs-hpy-port * commit '801921dd9786794a410e5d193c019930419da168': Port more of array_assign_subscript Slices support in array_assign_subscript Revert "Comment out initialization of the legacy global PyObject variables and weakreflist" Port more of array_assign_subscript Port more of array_assign_subscript Partial port of np.transpose
Here are two more PRNGs to enter the fray. They are each at least as fast as
Xoshiro256
, at least on my 64-bit Linux machine. I expect they'll be about the same on 32-bit machines, but I have not tested that.They are each 256-bit PRNGs architected fairly similarly, based on random invertible mappings. They each have a small number of separate cycles within their state space, but it is exceedingly unlikely that your seeding won't fall on the big ones. You can expect a period of about
2**255
.SFC64
incorporates a 64-bit counter in its state so you have the extra safety that, should you happen to be enormously unlucky, you always have a minimum of2**64
states in your cycle.Both are very well-tested.
JSF64
has been analyzed for a long time.SFC64
seems to be inspired by that work; it was written by the author of PractRand so it too has been pretty thoroughly tested.Their one downside is that they don't have an efficient jumpahead operation. @imneme (whose implementation I referenced) seems to think that it might be doable for
SFC64
, but I don't know where to start with that.