From 045c0609b5c059974104f29dad91bcc3828e91ac Mon Sep 17 00:00:00 2001 From: Antonio Sanchez Date: Wed, 21 Apr 2021 11:03:23 -0700 Subject: Check existence of BSD random before use. `TensorRandom` currently relies on BSD `random()`, which is not always available. The [linux manpage](https://man7.org/linux/man-pages/man3/srandom.3.html) gives the glibc condition: ``` _XOPEN_SOURCE >= 500 || /* Glibc since 2.19: */ _DEFAULT_SOURCE || /* Glibc <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE ``` In particular, this was failing to compile for MinGW via msys2. If not available, we fall back to using `rand()`. --- unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h | 34 +++++++++++++---------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'unsupported') diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h b/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h index 13450e1a7..9a20b53bb 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h @@ -34,9 +34,9 @@ EIGEN_DEVICE_FUNC uint64_t get_random_seed() { // we try to generate seeds faster than the clock resolution. // We need 2 random values since the generator only generate 16 bits at // a time (https://msdn.microsoft.com/en-us/library/398ax69y.aspx) - int rnd1 = ::rand(); - int rnd2 = ::rand(); - uint64_t rnd = (rnd1 | rnd2 << 16) ^ time; + unsigned rnd1 = static_cast(::rand()); + unsigned rnd2 = static_cast(::rand()); + uint64_t rnd = (rnd1 ^ (rnd2 << 16)) ^ time; return rnd; #elif defined __APPLE__ @@ -45,23 +45,29 @@ EIGEN_DEVICE_FUNC uint64_t get_random_seed() { uint64_t rnd = ::random() ^ mach_absolute_time(); return rnd; -#elif defined __native_client__ - // Same approach as for win32, except using clock_gettime - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - int rnd1 = ::rand(); - int rnd2 = ::rand(); - uint64_t rnd = (rnd1 | rnd2 << 16) ^ ts.tv_nsec; - return rnd; - #else // Augment the current time with pseudo random number generation // to ensure that we get different seeds if we try to generate seeds // faster than the clock resolution. timespec ts; clock_gettime(CLOCK_REALTIME, &ts); - uint64_t rnd = ::random() ^ ts.tv_nsec; - return rnd; + + + // Check for BSD random(). +#if EIGEN_COMP_GNUC && (\ + defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500 \ + || /* Glibc since 2.19: */ (defined(_DEFAULT_SOURCE) && _DEFAULT_SOURCE) \ + || /* Glibc <= 2.19: */ (defined(_SVID_SOURCE) && _SVID_SOURCE) \ + || (defined(_BSD_SOURCE) && _BSD_SOURCE) \ + ) + uint64_t rnd = ::random(); +#else + // Build random from rand() + unsigned rnd1 = static_cast(::rand()); + unsigned rnd2 = static_cast(::rand()); + uint64_t rnd = (rnd1 ^ (rnd2 << 16)); +#endif + return rnd ^ ts.tv_nsec; #endif } -- cgit v1.2.3