Skip to content
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

Nested max(int, int) expressions cause compiler error in RStan / StanHeaders 2.32.5 #1116

Open
ebuhle opened this issue Feb 14, 2024 · 2 comments

Comments

@ebuhle
Copy link

ebuhle commented Feb 14, 2024

Summary:

Compilation fails with rstan 2.32.5 and StanHeaders 2.32.5 under R 4.3.x if the model code contains an expression of the form max(max(int, int), int), i.e. nested calls to max() with integer arguments.

Description:

After recently updating from rstan 2.32.2 and StanHeaders 2.26.28 to the current 2.32.5 versions of both packages in R 4.3.2, I was unable to compile some previously working Stan models. Through a lot of trial and error, removing code blocks until compilation succeeded and then adding them back until it failed again, I managed to isolate the issue to nested integer-max calls. If a model contains an expression like max(max(int, int), int), the compiler throws an error. If the inner max(int, int) is replaced by a constant integer or a previously defined int variable, or if the arguments to max() are real instead of int, compilation works.

A colleague and I have reproduced this in R 4.3.0 and 4.3.2 on two machines running different versions of Windows.

Reproducible Steps:

test1.stan <- "transformed data {
  int test = max(max(1, 1), 1);
}
"

test1 <- rstan::stan_model(model_code = test1.stan)  # error

test2.stan <- "transformed data {
  int test = max(1, 1);
}
"

test2 <- rstan::stan_model(model_code = test2.stan)  # no error

Current Output:

The first example produces the following compiler output followed by an error:

make cmd is
  make -f "C:/R/R-43~1.2/etc/x64/Makeconf" -f "C:/R/R-43~1.2/share/make/winshlib.mk" -f "C:/~/.R/Makevars.win" CXX='$(CXX17) $(CXX17STD)' CXXFLAGS='$(CXX17FLAGS)' CXXPICFLAGS='$(CXX17PICFLAGS)' SHLIB_LDFLAGS='$(SHLIB_CXX17LDFLAGS)' SHLIB_LD='$(SHLIB_CXX17LD)' SHLIB="file7fc28f11320.dll" WIN=64 TCLBIN= OBJECTS="file7fc28f11320.o"

make would use
g++  -std=gnu++17 -I"C:/R/R-43~1.2/include" -DNDEBUG   -I"C:/R/R-4.3.2/library/Rcpp/include/"  -I"C:/R/R-4.3.2/library/RcppEigen/include/"  -I"C:/R/R-4.3.2/library/RcppEigen/include/unsupported"  -I"C:/R/R-4.3.2/library/BH/include" -I"C:/R/R-4.3.2/library/StanHeaders/include/src/"  -I"C:/R/R-4.3.2/library/StanHeaders/include/"  -I"C:/R/R-4.3.2/library/RcppParallel/include/" -DRCPP_PARALLEL_USE_TBB=1 -I"C:/R/R-4.3.2/library/rstan/include" -DEIGEN_NO_DEBUG  -DBOOST_DISABLE_ASSERTS  -DBOOST_PENDING_INTEGER_LOG2_HPP  -DSTAN_THREADS  -DUSE_STANC3 -DSTRICT_R_HEADERS  -DBOOST_PHOENIX_NO_VARIADIC_EXPRESSION  -D_HAS_AUTO_PTR_ETC=0  -include "C:/R/R-4.3.2/library/StanHeaders/include/stan/math/prim/fun/Eigen.hpp"  -std=c++1y    -I"C:/rtools43/x86_64-w64-mingw32.static.posix/include"     -O2 -Wall  -mfpmath=sse -msse2 -mstackrealign  -c file7fc28f11320.cpp -o file7fc28f11320.o
if test "zfile7fc28f11320.o" != "z"; then \
  if test -e "file7fc28f11320-win.def"; then \
    echo g++  -shared -s -static-libgcc -o file7fc28f11320.dll file7fc28f11320-win.def file7fc28f11320.o  "C:/R/R-4.3.2/library/rstan/lib/x64/libStanServices.a" -L"C:/R/R-4.3.2/library/StanHeaders/libs/x64" -lStanHeaders -L"C:/R/R-4.3.2/library/RcppParallel/lib/x64" -ltbb -LC:/R/R-4.3.2/library/RcppParallel/lib/x64 -ltbb -ltbbmalloc -L"C:/rtools43/x86_64-w64-mingw32.static.posix/lib/x64" -L"C:/rtools43/x86_64-w64-mingw32.static.posix/lib"  -L"C:/R/R-43~1.2/bin/x64" -lR ; \
    g++  -shared -s -static-libgcc -o file7fc28f11320.dll file7fc28f11320-win.def file7fc28f11320.o  "C:/R/R-4.3.2/library/rstan/lib/x64/libStanServices.a" -L"C:/R/R-4.3.2/library/StanHeaders/libs/x64" -lStanHeaders -L"C:/R/R-4.3.2/library/RcppParallel/lib/x64" -ltbb -LC:/R/R-4.3.2/library/RcppParallel/lib/x64 -ltbb -ltbbmalloc -L"C:/rtools43/x86_64-w64-mingw32.static.posix/lib/x64" -L"C:/rtools43/x86_64-w64-mingw32.static.posix/lib"  -L"C:/R/R-43~1.2/bin/x64" -lR ; \
  else \
    echo EXPORTS > tmp.def; \
    nm file7fc28f11320.o | sed -n 's/^.* [BCDRT] / /p' | sed -e '/[.]refptr[.]/d' -e '/[.]weak[.]/d' | sed 's/[^ ][^ ]*/"&"/g'  >> tmp.def; \
    echo g++  -shared -s -static-libgcc -o file7fc28f11320.dll tmp.def file7fc28f11320.o  "C:/R/R-4.3.2/library/rstan/lib/x64/libStanServices.a" -L"C:/R/R-4.3.2/library/StanHeaders/libs/x64" -lStanHeaders -L"C:/R/R-4.3.2/library/RcppParallel/lib/x64" -ltbb -LC:/R/R-4.3.2/library/RcppParallel/lib/x64 -ltbb -ltbbmalloc -L"C:/rtools43/x86_64-w64-mingw32.static.posix/lib/x64" -L"C:/rtools43/x86_64-w64-mingw32.static.posix/lib"  -L"C:/R/R-43~1.2/bin/x64" -lR ; \
    g++  -shared -s -static-libgcc -o file7fc28f11320.dll tmp.def file7fc28f11320.o  "C:/R/R-4.3.2/library/rstan/lib/x64/libStanServices.a" -L"C:/R/R-4.3.2/library/StanHeaders/libs/x64" -lStanHeaders -L"C:/R/R-4.3.2/library/RcppParallel/lib/x64" -ltbb -LC:/R/R-4.3.2/library/RcppParallel/lib/x64 -ltbb -ltbbmalloc -L"C:/rtools43/x86_64-w64-mingw32.static.posix/lib/x64" -L"C:/rtools43/x86_64-w64-mingw32.static.posix/lib"  -L"C:/R/R-43~1.2/bin/x64" -lR ; \
    rm -f tmp.def; \
  fi \
fi

Error in compileCode(f, code, language = language, verbose = verbose) :
C:/R/R-4.3.2/library/RcppEigen/include/Eigen/src/Core/ProductEvaluators.h:35:90: required from 'Eigen::internal::evaluator<Eigen::Product<Lhs, Rhs, Option> >::evaluator(const XprType&) [with Lhs = Eigen::Product<Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<double, double>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, const Eigen::Matrix<double, 1, -1> >, const Eigen::Transpose<Eigen::Matrix<double, -1, 1> > >, Eigen::Matrix<double, -1, -1>, 0>; Rhs = Eigen::Matrix<double, -1, 1>; int Options = 0; XprType = Eigen::Product<Eigen::Product<Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<double, double>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, const Eigen::Matrix<double, 1, -1> >, const Eigen::Transpose<Eigen::Matrix<double, -1, 1> > >, Eigen::Matrix<double, -1, -1>, 0>, Eigen::Matrix<double, -1, 1>, 0>]'C:/R/R-4.3.2/library/RcppEigen/include/Eigen/src/Core/Product.h:132:22: required from 'Eigen::in

Error in sink(type = "output") : invalid connection

Expected Output:

Successful compilation producing a stanmodel object.

RStan Version:

rstan 2.32.5 and StanHeaders 2.32.5

R Version:

R 4.3.0 or 4.3.2

Operating System:

Windows

@WardBrian
Copy link
Member

Thanks for reporting, this was a bug in our math library.

@bgoodri this is another really easy backport: replace return_type_t<T1, T2> with auto for the prim overload of max (and min, too, which has the same issue)

@bgoodri
Copy link
Contributor

bgoodri commented Feb 15, 2024

Will do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants