Function multi_normal_log causing compiler issues

stan-math

#1

I would like to use the function multi_normal_log in my C++ code.

The following simple program does not compile for me,

#include <stan/math.hpp>
#include <iostream>

int main() {
  Eigen::Matrix<double, Eigen::Dynamic, 1> y(3, 1);
  y << 2.0, -2.0, 11.0;
  Eigen::Matrix<double, Eigen::Dynamic, 1> mu(3, 1);
  mu << 1.0, -1.0, 3.0;
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> Sigma(3, 3);
  Sigma << 9.0, -3.0, 0.0, -3.0, 4.0, 0.0, 0.0, 0.0, 5.0;

  std::cout << stan::math::multi_normal_log(y, mu, Sigma);
  return 0;
}

I have tried compiling from the command-line with,

icl -I[...include dirs...] stan-multi_normal_log-test.cpp

which gives the following error message,

error LNK2019: unresolved external symbol "void __cdecl boost::throw_exception(class std::exception const &)" (?throw_exception@boost@@YAXAEBVexception@std@@@Z) referenced in function "double __cdecl stan::math::multi_normal_lpdf<0,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,-1,0,-1,-1> >(class Eigen::Matrix<double,-1,1,0,-1,1> const &,class Eigen::Matrix<double,-1,1,0,-1,1> const &,class Eigen::Matrix<double,-1,-1,0,-1,-1> const &)" (??$multi_normal_lpdf@$0A@V?$Matrix@N$0?0$00$0A@$0?0$00@Eigen@@V12@V?$Matrix@N$0?0$0?0$0A@$0?0$0?0@2@@math@stan@@YANAEBV?$Matrix@N$0?0$00$0A@$0?0$00@Eigen@@0AEBV?$Matrix@N$0?0$0?0$0A@$0?0$0?0@3@@Z)
stan-multi_normal_log-test.exe : fatal error LNK1120: 1 unresolved externals

And from Visual Studio, which gives the following error messages,

Error	C2672	'trace_inv_quad_form_ldlt': no matching overloaded function found	npm-inference	c:\cygwin64\home\philip\stan-dev\math\stan\math\prim\mat\prob\multi_normal_lpdf.hpp	107	
Error	C2782	'boost::enable_if_c<stan::is_var<T>::value||stan::is_var<T3>::value,stan::math::var>::type stan::math::trace_inv_quad_form_ldlt(const stan::math::LDLT_factor<T,R,C> &,const Eigen::Matrix<T2,R2,C2,|_Rows==&&_Cols!=?:_Cols==&&_Rows!=?:,_Rows,_Cols> &)': template parameter '_Cols' is ambiguous	npm-inference	c:\cygwin64\home\philip\stan-dev\math\stan\math\prim\mat\prob\multi_normal_lpdf.hpp	107	
Error	C2784	'boost::enable_if_c<stan::is_var<T>::value||stan::is_var<T3>::value,stan::math::var>::type stan::math::trace_inv_quad_form_ldlt(const stan::math::LDLT_factor<T,R,C> &,const Eigen::Matrix<T2,R2,C2,|_Rows==&&_Cols!=?:_Cols==&&_Rows!=?:,_Rows,_Cols> &)': could not deduce template argument for 'const Eigen::Matrix<T2,R2,C2,|_Rows==&&_Cols!=?:_Cols==&&_Rows!=?:,_Rows,_Cols> &' from 'Eigen::Matrix<double,-1,1,0,-1,1>'	npm-inference	c:\cygwin64\home\philip\stan-dev\math\stan\math\prim\mat\prob\multi_normal_lpdf.hpp	107	
Error	C2784	'boost::enable_if_c<!stan::is_var<T>::value&&!stan::is_var<T2>::value,boost::math::tools::promote_args<RT1,RT2,float,float,float,float>::type>::type stan::math::trace_inv_quad_form_ldlt(const stan::math::LDLT_factor<T1,R2,C2> &,const Eigen::Matrix<T2,R2,C2,|_Rows==&&_Cols!=?:_Cols==&&_Rows!=?:,_Rows,_Cols> &)': could not deduce template argument for 'const Eigen::Matrix<T2,R2,C2,|_Rows==&&_Cols!=?:_Cols==&&_Rows!=?:,_Rows,_Cols> &' from 'Eigen::Matrix<double,-1,1,0,-1,1>'	npm-inference	c:\cygwin64\home\philip\stan-dev\math\stan\math\prim\mat\prob\multi_normal_lpdf.hpp	107	


#2

This probably isn’t that helpful, but:

clang++ -Wall -I . -isystem lib/eigen_3.3.3 -isystem lib/boost_1.65.1 -isystem lib/cvodes_2.9.0/include -std=c++1y test.cpp

Works on Ubuntu 16.04, and the program runs (returning -11.7391), so I’d assume your code is alright.

I don’t really understand how boost, or the Intel compilers, or things in Windows work so I don’t believe I can be of any use beyond that, but it sure looks like it might be a boost thing. Are you using the boost included with Stan math? Or using a different system one?


#3

We’ve had lots of trouble with MSVC.

Are you in an environment where you can use g++? The whole toolchain’s available as part of Rtools with a binary installer and verified to work with Stan’s code.


#4

Yes, I was using the boost included with Stan math.

Yes, I have now installed g++. This fixes the problem - my code compiles and runs with g++.

Has anyone else tried using an Intel compiler (e.g. icl) for compiling Stan math code?


#5

Yes, that should work, but if you turn the optimizations on, you get poorer arithmetic precision—we had to lower tolerances on many of our tests to get them to pass with Intel’s compiler. I’m also not sure if the Eigen and Boost libs are up to taking advantage of it as is without the MKL.


#6

I am still having difficulty with this. Here is my call to the intel c++ compiler,

 icl -I$HOMEDIR/stan-dev/math  -I$HOMEDIR/stan-dev/math/lib/eigen_3.3.3 -I$HOMEDIR/stan-dev/math/lib/boost_1.65.1 -I$HOMEDIR/stan-dev/math/lib/cvodes_2.9.0/include ../npm-inference/tests/stan-multi_normal_log-test.cpp

And here is what gets printed in my terminal,

Intel(R) C++ Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 18.0.1.156 Build 20171018
Copyright (C) 1985-2017 Intel Corporation.  All rights reserved.

stan-multi_normal_log-test.cpp
Unknown compiler version - please run the configure tests and report the results
Microsoft (R) Incremental Linker Version 14.12.25830.2
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:stan-multi_normal_log-test.exe
stan-multi_normal_log-test.obj
stan-multi_normal_log-test.obj : error LNK2019: unresolved external symbol "void __cdecl boost::throw_exception(class std::exception const &)" (?throw_exception@boost@@YAXAEBVexception@std@@@Z) referenced in function "double __cdecl stan::math::multi_normal_lpdf<0,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,-1,0,-1,-1> >(class Eigen::Matrix<double,-1,1,0,-1,1> const &,class Eigen::Matrix<double,-1,1,0,-1,1> const &,class Eigen::Matrix<double,-1,-1,0,-1,-1> const &)" (??$multi_normal_lpdf@$0A@V?$Matrix@N$0?0$00$0A@$0?0$00@Eigen@@V12@V?$Matrix@N$0?0$0?0$0A@$0?0$0?0@2@@math@stan@@YANAEBV?$Matrix@N$0?0$00$0A@$0?0$00@Eigen@@0AEBV?$Matrix@N$0?0$0?0$0A@$0?0$0?0@3@@Z)
stan-multi_normal_log-test.exe : fatal error LNK1120: 1 unresolved externals

#7

I know @wds15 has gotten it to work before. We don’t actively test for the Intel compilers, so there may be something that no longer works. It looks like it’s not finding Boost.


#8

I have now managed to fix the intel compiler issue by adding this code to my program,

namespace boost
{
#ifdef BOOST_NO_EXCEPTIONS
  template<class E> void throw_exception(E const & e){
    exit(0);
  };
#endif

There is some helpful info here - https://stackoverflow.com/questions/6832666/lnk2019-when-including-asio-headers-solution-generated-with-cmake


#9

Thanks for reporting back. The answer buried in there is that when that flag’s on for Boost, it delegates exceptions to a user-defined boost::throw_exception function.

That exit(0) takes the no exceptions business seriously and just takes down the whole process. Something else would work here, such as throw e or logging.