diff --git a/src/code/rand-xoroshiro.lisp b/src/code/rand-xoroshiro.lisp index 549cbbac700e9d982635dcd278ea799a1b08d35f..5cfd7021a9d2fe95a875079ff014a0f0728d2e68 100644 --- a/src/code/rand-xoroshiro.lisp +++ b/src/code/rand-xoroshiro.lisp @@ -18,7 +18,8 @@ make-random-state)) (in-package "KERNEL") -(export '(%random-single-float %random-double-float random-chunk init-random-state)) +(export '(%random-single-float %random-double-float random-chunk init-random-state + random-state-jump)) (sys:register-lisp-feature :random-xoroshiro) @@ -470,7 +471,12 @@ :format-control (intl:gettext "Argument is not a positive integer or a positive float: ~S") :format-arguments (list arg))))) -(defun xoroshiro-jump (rng-state) +;; Jump function for the generator. See the jump function in +;; http://xoroshiro.di.unimi.it/xoroshiro128plus.c +(defun random-state-jump (&optional (rng-state *random-state*)) + "Jump the RNG-STATE. This is equivalent to 2^64 calls to the + xoroshiro128+ generator. It can be used to generate 2^64 + non-overlapping subsequences for parallel computations." (declare (type random-state rng-state)) (let ((state (random-state-state rng-state)) (s0-0 0) @@ -493,7 +499,6 @@ (kernel:double-float-bits (aref state 1)) (setf s1-1 (logxor s1-1 (ldb (byte 32 0) x1)) s1-0 (logxor s1-0 x0)))) - (format t "jump: ~D s0, s1 = ~X~8,'0X ~X~8,'0X~%" b s0-1 s0-0 s1-1 s1-0) (xoroshiro-gen state))) (flet ((convert (x1 x0) @@ -504,4 +509,3 @@ (setf (aref state 0) (convert s0-1 s0-0)) (setf (aref state 1) (convert s1-1 s1-0))) rng-state)) - diff --git a/tests/rng.lisp b/tests/rng.lisp index e48dc4519b8f7b830e4a3b2f3d1c2c3ac903c9fd..1b5dcbcaf52852a18f0db42c58de9820b730341e 100644 --- a/tests/rng.lisp +++ b/tests/rng.lisp @@ -55,3 +55,16 @@ item (assert-equal value (64-bit-value *test-state*)) (assert-equal state (multiple-value-list (64-bit-rng-state *test-state*)))))) + +(define-test rng.jump + (setf *test-state* + (kernel::make-random-object :state (kernel::init-random-state #x12345678) + :rand 0 + :cached-p nil)) + (dolist (result '((#x291ddf8e6f6a7b67 #x1f9018a12f9e031f) + (#x88a7aa12158558d0 #xe264d785ab1472d9) + (#x207e16f73c51e7ba #x999c8a0a9a8d87c0) + (#x28f8959d3bcf5ff1 #x38091e563ab6eb98))) + (kernel:random-state-jump *test-state*) + (assert-equal result (multiple-value-list + (64-bit-rng-state *test-state*)))))