diff --git a/ChangeLog b/ChangeLog index b3886294..470a588c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2025-11-20 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): RcppArmadillo 15.2.2-0 + * inst/NEWS.Rd: Idem + * configure.ac: Idem + * configure: Idem + + * inst/include/current/: Sync with Armadillo 15.2.2 + + * inst/tinytest/test_Rlapack.R: Skip this test involving complex + algebra if on macOS as the LAPACK switch by R affects it + 2025-11-13 Dirk Eddelbuettel * R/inline.R (inlineCxxPlugin): No longer special-case macOS for diff --git a/DESCRIPTION b/DESCRIPTION index b5367ea2..0bf951d3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: RcppArmadillo Type: Package Title: 'Rcpp' Integration for the 'Armadillo' Templated Linear Algebra Library -Version: 15.2.1-0 -Date: 2025-10-28 +Version: 15.2.2-0 +Date: 2025-11-20 Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org", comment = c(ORCID = "0000-0001-6419-907X")), person("Romain", "Francois", role = "aut", diff --git a/configure b/configure index 7cb920bb..4d7948a7 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for RcppArmadillo 15.2.1-0. +# Generated by GNU Autoconf 2.72 for RcppArmadillo 15.2.2-0. # # Report bugs to . # @@ -603,8 +603,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='RcppArmadillo' PACKAGE_TARNAME='rcpparmadillo' -PACKAGE_VERSION='15.2.1-0' -PACKAGE_STRING='RcppArmadillo 15.2.1-0' +PACKAGE_VERSION='15.2.2-0' +PACKAGE_STRING='RcppArmadillo 15.2.2-0' PACKAGE_BUGREPORT='edd@debian.org' PACKAGE_URL='' @@ -1221,7 +1221,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures RcppArmadillo 15.2.1-0 to adapt to many kinds of systems. +'configure' configures RcppArmadillo 15.2.2-0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1283,7 +1283,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of RcppArmadillo 15.2.1-0:";; + short | recursive ) echo "Configuration of RcppArmadillo 15.2.2-0:";; esac cat <<\_ACEOF @@ -1364,7 +1364,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -RcppArmadillo configure 15.2.1-0 +RcppArmadillo configure 15.2.2-0 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1480,7 +1480,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by RcppArmadillo $as_me 15.2.1-0, which was +It was created by RcppArmadillo $as_me 15.2.2-0, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3862,7 +3862,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by RcppArmadillo $as_me 15.2.1-0, which was +This file was extended by RcppArmadillo $as_me 15.2.2-0, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3917,7 +3917,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -RcppArmadillo config.status 15.2.1-0 +RcppArmadillo config.status 15.2.2-0 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index b19d20c5..27602a50 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ AC_PREREQ([2.69]) ## Process this file with autoconf to produce a configure script. -AC_INIT([RcppArmadillo],[15.2.1-0],[edd@debian.org]) +AC_INIT([RcppArmadillo],[15.2.2-0],[edd@debian.org]) ## Set R_HOME, respecting an environment variable if one is set : ${R_HOME=$(R RHOME)} diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 2de645d6..568646d8 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -3,6 +3,19 @@ \newcommand{\ghpr}{\href{https://github.com/RcppCore/RcppArmadillo/pull/#1}{##1}} \newcommand{\ghit}{\href{https://github.com/RcppCore/RcppArmadillo/issues/#1}{##1}} +\section{Changes in RcppArmadillo version 15.2.2-0 (2025-11-20) (GitHub Only)}{ + \itemize{ + \item Upgraded to Armadillo release 15.2.2 (Medium Roast Deluxe) + \itemize{ + \item Improved reproducibility of random number generation when using OpenMP + } + \item Skip a unit test file under macOS as complex algebra seems to fail + under newer macOS LAPACK setting + \item Further OpenMP detection rework for macOS + \item Define ARMA_CRIPPLED_LAPACK on Windows only if 'LEGACY' Armadillo selected + } +} + \section{Changes in RcppArmadillo version 15.2.1-0 (2025-10-28) (GitHub Only)}{ \itemize{ \item Upgraded to Armadillo release 15.2.1 (Medium Roast Deluxe) diff --git a/inst/include/current/armadillo_bits/arma_rng.hpp b/inst/include/current/armadillo_bits/arma_rng.hpp index 8a2c3fc0..620146c8 100644 --- a/inst/include/current/armadillo_bits/arma_rng.hpp +++ b/inst/include/current/armadillo_bits/arma_rng.hpp @@ -26,6 +26,9 @@ #undef ARMA_USE_THREAD_LOCAL #define ARMA_USE_THREAD_LOCAL +#undef ARMA_USE_THREAD_UNIQUE_RNG_SEED +#define ARMA_USE_THREAD_UNIQUE_RNG_SEED + #if (defined(ARMA_RNG_ALT) || defined(ARMA_DONT_USE_CXX11_RNG)) #undef ARMA_USE_CXX11_RNG #endif @@ -34,6 +37,10 @@ #undef ARMA_USE_THREAD_LOCAL #endif +#if defined(ARMA_DONT_USE_THREAD_UNIQUE_RNG_SEED) + #undef ARMA_USE_THREAD_UNIQUE_RNG_SEED +#endif + // NOTE: ARMA_WARMUP_PRODUCER enables a workaround // NOTE: for thread_local issue on macOS 11 and/or AppleClang 12.0 @@ -129,24 +136,42 @@ arma_rng::get_producer() { #if defined(ARMA_USE_THREAD_LOCAL) - // use a thread-safe RNG, with each thread having its own unique starting seed - - static std::atomic mt19937_64_producer_counter(0); - - static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + mt19937_64_producer_counter++ ); + // thread-safe RNG - arma_rng::warmup_producer(mt19937_64_producer); + #if defined(ARMA_USE_THREAD_UNIQUE_RNG_SEED) + + // each thread has unique starting seed + + #if defined(ARMA_USE_OPENMP) + + static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + arma_rng::seed_type(omp_get_thread_num()) ); + + #else + + static std::atomic mt19937_64_producer_counter(0); + + static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + mt19937_64_producer_counter++ ); + + #endif + + #else + + // each thread has the same starting seed + + static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed ); + + #endif #else - // use a plain RNG in case we don't have thread_local + // plain RNG in case we don't have thread_local static std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed ); - arma_rng::warmup_producer(mt19937_64_producer); - #endif + arma_rng::warmup_producer(mt19937_64_producer); + return mt19937_64_producer; } @@ -226,9 +251,45 @@ arma_rng::set_seed(const arma_rng::seed_type val) } #elif defined(ARMA_USE_CXX11_RNG) { - arma_rng::lock_producer(); - arma_rng::get_producer().seed(val); - arma_rng::unlock_producer(); + #if defined(ARMA_USE_OPENMP) && defined(ARMA_USE_THREAD_LOCAL) + { + arma_rng::lock_producer(); + + #if defined(ARMA_USE_THREAD_UNIQUE_RNG_SEED) + constexpr bool thread_unique_rng_seed = true; + #else + constexpr bool thread_unique_rng_seed = false; + #endif + + // if we're already in a parallel region, assume the user is setting the seed for each thread + + if( (thread_unique_rng_seed == false) || bool(omp_in_parallel()) ) + { + arma_rng::get_producer().seed(val); + } + else + { + const int n_threads = int( (std::max)( int(1), int(omp_get_max_threads()) ) ); + + #pragma omp parallel for ordered schedule(static) num_threads(n_threads) + for(int t=0; t < n_threads; ++t) + { + #pragma omp ordered + { + arma_rng::get_producer().seed(val + arma_rng::seed_type(omp_get_thread_num())); + } + } + } + + arma_rng::unlock_producer(); + } + #else + { + arma_rng::lock_producer(); + arma_rng::get_producer().seed(val); + arma_rng::unlock_producer(); + } + #endif } #else { diff --git a/inst/include/current/armadillo_bits/arma_version.hpp b/inst/include/current/armadillo_bits/arma_version.hpp index 1a6ca870..5e1da9b9 100644 --- a/inst/include/current/armadillo_bits/arma_version.hpp +++ b/inst/include/current/armadillo_bits/arma_version.hpp @@ -23,7 +23,7 @@ #define ARMA_VERSION_MAJOR 15 #define ARMA_VERSION_MINOR 2 -#define ARMA_VERSION_PATCH 1 +#define ARMA_VERSION_PATCH 2 #define ARMA_VERSION_NAME "Medium Roast Deluxe" diff --git a/inst/tinytest/test_Rlapack.R b/inst/tinytest/test_Rlapack.R index fba72ac1..8a0784a8 100644 --- a/inst/tinytest/test_Rlapack.R +++ b/inst/tinytest/test_Rlapack.R @@ -20,6 +20,8 @@ library(RcppArmadillo) +if (Sys.info()['sysname'] == "Darwin") exit_file("Skip on macOS") + if (isFALSE(tryCatch({svd(matrix(complex(1, 1, 1),1,1)); TRUE}, error=function(e) FALSE))) exit_file("Skipping for lack of Fortran complex functions in this R build")