From 9c228a28188cf2b26687bee4f0ce34a5a8ab6c84 Mon Sep 17 00:00:00 2001 From: OmarMesqq Date: Sun, 10 Sep 2023 11:44:08 -0300 Subject: [PATCH 1/2] Implement random.seed() --- integration_tests/test_random.py | 10 ++++++++++ src/libasr/runtime/lfortran_intrinsics.c | 9 +++++++++ src/libasr/runtime/lfortran_intrinsics.h | 1 + src/runtime/random.py | 11 +++++++++++ 4 files changed, 31 insertions(+) diff --git a/integration_tests/test_random.py b/integration_tests/test_random.py index db60a16d37..dc54956c54 100644 --- a/integration_tests/test_random.py +++ b/integration_tests/test_random.py @@ -52,6 +52,15 @@ def test_weibullvariate(): r = random.weibullvariate(-5.6, 1.2) print(r) +def test_seed(): + random.seed(123) + t1: f64 + t1 = random.random() + random.seed(321) + t2: f64 + t2 = random.random() + assert t1 != t2 + def check(): test_random() test_randrange() @@ -60,5 +69,6 @@ def check(): test_paretovariate() test_expovariate() test_weibullvariate() + test_seed() check() diff --git a/src/libasr/runtime/lfortran_intrinsics.c b/src/libasr/runtime/lfortran_intrinsics.c index 6548592d5d..3e39fa6640 100644 --- a/src/libasr/runtime/lfortran_intrinsics.c +++ b/src/libasr/runtime/lfortran_intrinsics.c @@ -96,6 +96,15 @@ LFORTRAN_API void _lfortran_random_number(int n, double *v) } } +LFORTRAN_API void _lfortran_init_random(unsigned seed) +{ + if (seed == 0) { + srand((unsigned int)clock()); + } else { + srand(seed); + } +} + LFORTRAN_API double _lfortran_random() { return (rand() / (double) RAND_MAX); diff --git a/src/libasr/runtime/lfortran_intrinsics.h b/src/libasr/runtime/lfortran_intrinsics.h index ab418523df..e009fcb632 100644 --- a/src/libasr/runtime/lfortran_intrinsics.h +++ b/src/libasr/runtime/lfortran_intrinsics.h @@ -67,6 +67,7 @@ typedef double _Complex double_complex_t; LFORTRAN_API double _lfortran_sum(int n, double *v); LFORTRAN_API void _lfortran_random_number(int n, double *v); +LFORTRAN_API void _lfortran_init_random(unsigned seed); LFORTRAN_API double _lfortran_random(); LFORTRAN_API int _lfortran_randrange(int lower, int upper); LFORTRAN_API int _lfortran_random_int(int lower, int upper); diff --git a/src/runtime/random.py b/src/runtime/random.py index 280f5552db..fd0ed6f384 100644 --- a/src/runtime/random.py +++ b/src/runtime/random.py @@ -32,6 +32,17 @@ def random() -> f64: def _lfortran_random() -> f64: pass +def seed(seed: i32) -> None: + """ + Initializes the random number generator. + """ + _lfortran_init_random(seed) + return + +@ccall +def _lfortran_init_random(seed: i32) -> None: + pass + def randrange(lower: i32, upper: i32) -> i32: """ Return a random integer N such that `lower <= N < upper`. From 805b6212cf567689d6a8c1f7a28a5a4f239c2caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Tue, 17 Oct 2023 07:56:57 +0200 Subject: [PATCH 2/2] Proper clock initialization stricter tests --- integration_tests/test_random.py | 18 ++++++++++++++++++ src/libasr/runtime/lfortran_intrinsics.c | 13 +++++++------ src/libasr/runtime/lfortran_intrinsics.h | 3 ++- src/runtime/random.py | 17 +++++++++++++++-- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/integration_tests/test_random.py b/integration_tests/test_random.py index dc54956c54..d20f6286e0 100644 --- a/integration_tests/test_random.py +++ b/integration_tests/test_random.py @@ -53,13 +53,31 @@ def test_weibullvariate(): print(r) def test_seed(): + random.seed() + t6: f64 = random.random() random.seed(123) t1: f64 t1 = random.random() random.seed(321) t2: f64 t2 = random.random() + random.seed(123) + t3: f64 + t3 = random.random() + random.seed(0) + t4: f64 + t4 = random.random() + random.seed(0) + t5: f64 + t5 = random.random() + random.seed() + t7: f64 = random.random() assert t1 != t2 + assert t1 == t3 + assert t1 != t4 + assert t1 != t5 + assert t4 == t5 + assert t6 != t7 def check(): test_random() diff --git a/src/libasr/runtime/lfortran_intrinsics.c b/src/libasr/runtime/lfortran_intrinsics.c index 3e39fa6640..f01cb94550 100644 --- a/src/libasr/runtime/lfortran_intrinsics.c +++ b/src/libasr/runtime/lfortran_intrinsics.c @@ -96,13 +96,14 @@ LFORTRAN_API void _lfortran_random_number(int n, double *v) } } -LFORTRAN_API void _lfortran_init_random(unsigned seed) +LFORTRAN_API void _lfortran_init_random_seed(unsigned seed) { - if (seed == 0) { - srand((unsigned int)clock()); - } else { - srand(seed); - } + srand(seed); +} + +LFORTRAN_API void _lfortran_init_random_clock() +{ + srand((unsigned int)clock()); } LFORTRAN_API double _lfortran_random() diff --git a/src/libasr/runtime/lfortran_intrinsics.h b/src/libasr/runtime/lfortran_intrinsics.h index e009fcb632..3ea56e4991 100644 --- a/src/libasr/runtime/lfortran_intrinsics.h +++ b/src/libasr/runtime/lfortran_intrinsics.h @@ -67,7 +67,8 @@ typedef double _Complex double_complex_t; LFORTRAN_API double _lfortran_sum(int n, double *v); LFORTRAN_API void _lfortran_random_number(int n, double *v); -LFORTRAN_API void _lfortran_init_random(unsigned seed); +LFORTRAN_API void _lfortran_init_random_clock(); +LFORTRAN_API void _lfortran_init_random_seed(unsigned seed); LFORTRAN_API double _lfortran_random(); LFORTRAN_API int _lfortran_randrange(int lower, int upper); LFORTRAN_API int _lfortran_random_int(int lower, int upper); diff --git a/src/runtime/random.py b/src/runtime/random.py index fd0ed6f384..3e7367dc4e 100644 --- a/src/runtime/random.py +++ b/src/runtime/random.py @@ -32,15 +32,28 @@ def random() -> f64: def _lfortran_random() -> f64: pass +@overload +def seed() -> None: + """ + Initializes the random number generator. + """ + _lfortran_init_random_clock() + return + +@overload def seed(seed: i32) -> None: """ Initializes the random number generator. """ - _lfortran_init_random(seed) + _lfortran_init_random_seed(seed) return @ccall -def _lfortran_init_random(seed: i32) -> None: +def _lfortran_init_random_clock() -> None: + pass + +@ccall +def _lfortran_init_random_seed(seed: i32) -> None: pass def randrange(lower: i32, upper: i32) -> i32: