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
Elementwise pow functions not compiling at the C++ level #661
Comments
Do you understand why removing t If we don't have that, then presumably this comes back. |
I'm not sure yet exactly why:
causes problems now. My suspicion is something with how templates come in to ADL that I wasn't understanding in the previous discussion (https://discourse.mc-stan.org/t/using-std-pow-inside-stan-math-namespace/13975/6). The things that compile are:
in the generated code, or moving all the using declarations (everything except
inside the All three of those should solve both problems. I'm going to have to think about ADL and why this is failing in the first place and why these are fixes cuz I don't really understand. |
What am I saying lol I don't know that anymore. |
There are two ways of fixing this:
I think this line here: https://github.com/stan-dev/math/blob/develop/stan/math/prim/fun/pow.hpp#L44 Just to be safe I am running a test locally that will compile all 850+ models in the tests here, including https://github.com/stan-dev/stanc3/blob/master/test/integration/good/function-signatures/math/functions/pow.stan Gonna take awhile and already uncovered other stuff we need to fix. |
I did some more looking. It looks like the older error was platform dependent. It didn't always trigger in Linux. I think the issue was only the C99 pow (definitions here) + the Stan pows were available for some compiler configurations, and so something like The trick was to expose the later pows with
What other issues are coming up? I think the issue now is that we are defining specializations for Originally (before #1809), we had code like: namespace model {
using namespace stan::math;
double d_double = 0.0;
int d_int = 0;
var d_var = 0.0;
pow(d_int, d_double); // call this statement 'A'
pow(d_var, d_double); // call this statement 'B'
} This caused problems sometimes because the pow signature required by A was ambiguous ( We added namespace model {
using std::pow;
using namespace stan::math;
double d_double = 0.0;
int d_int = 0;
var d_var = 0.0;
pow(d_int, d_double); // call this statement 'A'
pow(d_var, d_double); // call this statement 'B'
} Now what happens is the definitions of The weirdness is happening with statement 'B'. Statement 'B' works not because the Because of this, all the Now the code is this: namespace model {
using std::pow;
using namespace stan::math;
double d_double = 0.0;
int d_int = 0;
var d_var = 0.0;
std::vector<double> d_vector = { 0.0 };
pow(d_int, d_double); // call this statement 'A'
pow(d_var, d_double); // call this statement 'B'
pow(d_vector, d_double); // call this statement 'c'
} 'A' works because 'B' works because there is a 'C' fails because There's another weird fix for this -- if you remove the model namespace in the generated code of a Stan model, the code will also compile. In this case I still think adding |
It would be great if we had a solution that only required touching stanc3 to hotfix this. It makes the hotfix release really simple. Would including both using std::pow and stan::math::pow work if I understand correctly what you are saying? I think the longterm solution would be to just define pow(double, double), pow(int, int) and the rest in Math. Like we do for unary functions: https://github.com/stan-dev/math/blob/develop/stan/math/prim/fun/acos.hpp
Two issues came up. #662 is a longstanding issue, I checked 2.23 and it had the same issue. The other one is that the linspaced_* utility functions should be data only (they work with doubles only in math). I have a fix ready for this, looking at #662 now. |
If you look at the long history, we've gone back and forth on this by either hardcoding |
That is true yeah. Someone adding a global using statement can mess things in a bunch of other files (we should not encourage that but can happen). The problem is that we will always have some stan::math::foo(...) functions that shadow std::foo(...) because we want to differ from std for some of them. We could list the exceptions and hardcode std:: in code-gen for the rest. Not sure what would be ideal :/. Testing does not help catch everything here, as these include are very OS-dependent. |
I think so. For all pows, they get to see all the
This is surprising to me. Do you know an example? |
Yes, that sounds like a good call.
I think its exclusively edge cases (NaN and Inf and such). Example https://github.com/stan-dev/math/blob/develop/stan/math/prim/fun/atanh.hpp |
Unfortunately, this is a bug in the release version which will most likely warrant a hotfix release.
This test model https://github.com/stan-dev/stanc3/blob/master/test/integration/good/function-signatures/math/matrix/elementwise_pow.stan compiles to C++, but the generated C++ does not compile with:
The issue is the
using std::pow
in the generated code model code. Removing that fixes it, but need to double-check that does not corrupt anything else.The text was updated successfully, but these errors were encountered: