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

Added arithmetic version of pow (Fixes: #1809) #1810

Merged
merged 12 commits into from
Apr 5, 2020
Merged

Conversation

bbbales2
Copy link
Member

@bbbales2 bbbales2 commented Mar 30, 2020

This should fix #1809

Checklist

  • Math issue Ambiguities with between C/C++/stan pow implementations #1809

  • Copyright holder: Columbia University
    The copyright holder is typically you or your assignee, such as a university or company. By submitting this pull request, the copyright holder is agreeing to the license the submitted work under the following licenses:
    - Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)
    - Documentation: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

  • the basic tests are passing

    • unit tests pass (to run, use: ./runTests.py test/unit)
    • header checks pass, (make test-headers)
    • dependencies checks pass, (make test-math-dependencies)
    • docs build, (make doxygen)
    • code passes the built in C++ standards checks (make cpplint)
  • the code is written in idiomatic C++ and changes are documented in the doxygen

  • the new changes are tested

@SteveBronder
Copy link
Collaborator

@bob-carpenter are both of these candidates through implicit conversion?

lib/stan_math/stan/math/rev/fun/pow.hpp:305:26: note: candidate function [with T = double, $1 = void]
inline std::complex<var> pow(T x, const std::complex<var>& y) {
                         ^
lib/stan_math/stan/math/rev/fun/pow.hpp:320:26: note: candidate function
inline std::complex<var> pow(const std::complex<var>& x, int y) {

@bbbales2
Copy link
Member Author

bbbales2 commented Mar 31, 2020

@bob-carpenter Looks like it's blowing up on a Mac in the downstream tests (I'm guessing it's a Mac cause of the use of /usr/local/Cellar which is a brew thing): https://jenkins.mc-stan.org/blue/organizations/jenkins/Stan/detail/downstream_tests/1438/pipeline

I swapped in explicitly the only overloads we need that C99 doesn't provide and to see what happens (pow(double, int), pow(int, double), pow(int, int)). On Ubuntu 16.04/clang++-6.0/gcc-5, the rosenbrock stuff compiles (as part of the Stan tests), but the compiler gave me errors about not having a pow(double, double) implementation:

test/unit/math/mix/fun/pow_test.cpp:37:12), double, double>' requested here
  stan::test::expect_ad(f, -0.4, 0.5);
              ^
./stan/math/prim/fun/pow.hpp:32:15: note: candidate function
inline double pow(double x, int y) {
              ^
./stan/math/prim/fun/pow.hpp:44:15: note: candidate function
inline double pow(int x, double y) {
...

So in this case it's not finding the C99 pow definitions.

I think this is because there's a difference in what:

using namespace stan::math;

and

using stan::math::pow;

mean. Because Rosenbrock uses the first, it works, and the tests use the second, they fail. If I modify the tests to use using namespace stan::math, they work (and find the C99 pow definitions).

Check the difference in rule 6 & 7 here: https://en.cppreference.com/w/cpp/language/namespace

using namespace expands the scope where ADL will look.


Okay so backing up a bit, what we want is:

  1. Any time someone calls a standard function with Stan math autodiff types, they'll get the Stan math types

  2. If someone calls the C math functions with Stan math autodiff types, undefined behavior (things probably fail)

  3. Any time someone calls pow in the stan::math namespace, there will be no ambiguities between the standard C++ definitions, the Stan definitions, and the C definitions

I think what we need to do is inside stan/math/prim/fun/pow.hpp is:

namespace stan {
  namespace math {
    using std::pow;
  }
}

This gets rid of any ambiguities between Stan and std::math and in the case where we're operating in the stan::math namespace we'll hit the std::pow definition with ADL before we find the C version so there won't be ambiguities there.


Edit: Aah, I don't think this explanation is quite right. If we have the code:

namespace rosenbrock_model_namespace {
  using namespace stan::math;
  ...
}

Then the symbols for stan::math get absorbed as if they are in the nearest enclosing namespace that contains stan::math and rosenbrock_model_namespace (which is the global namespace). I'm not sure why then there wouldn't be ambiguities between the C++ pow and the C pow. Presumably there's a rule somewhere for this though.

@bbbales2
Copy link
Member Author

I switched the implementation to:

namespace stan {
  namespace math {
    using std::pow;
  }
}

And added a bunch of tests that I think should help catch problems during the math tests. I'm not sure I got everything though honestly. Can discuss further later if these tests pass.

@bob-carpenter
Copy link
Contributor

From @SteveBronder

are both of these candidates through implicit conversion

Yes. It requires promoting an int to std::complex<double> or a double to var. But keep in mind that we absolutely need the implicit constructors for everything else in the interface to work. It's part of the spec for std::complex that the constructors are implicit.

@bob-carpenter
Copy link
Contributor

From @bbbales2

I switched the implementation to:

namespace stan {
  namespace math {
    using std::pow;
  }
}

We absolutely cannot have a namespace-level using statement.

@bob-carpenter
Copy link
Contributor

We would like this to work idiomatically using argument-dependent lookup, no matter what T1 and T2 are:

using std::pow;
T1 x;
T2 y;
pow(x, y);

That means the solution may need to be having using std::pow in our model code.

@bbbales2
Copy link
Member Author

We absolutely cannot have a namespace-level using statement.

Well I get that this is given out as advice, but why? I think this is the behavior we want.

@bbbales2
Copy link
Member Author

I think this is the behavior we want.

Modulo we kinda define the behavior we want cause we can just change the code generation.

@bob-carpenter
Copy link
Contributor

I acutally meant more in the sense of wanting to work with argument-dependent lookup (ADL). That's the way to ensure that generic written code will work with Stan types dropped in. Let me repeat. The pattern we need to work to support an idiomatic ADL is:

using stan::math::var;
using std::pow;  
auto w = pow(3.1., 2.5);  // resolves to std::pow
auto x = pow(var(3.1), 2);  // next three bring in stan::math::pow
auto y = pow(3.1, var(2));
auto z = pow(var(3.1, var(2));

In words, an idiomatic usage has a using XXX statement to bring in definitions for primitives, then definitions for other types are brought in by argument-dependent lookup. That's why I was suggesting the using std::pow in the math library.

But, that's not going to work for us in models. The reason is that the following using statement in our models will mess us up.

using namespace stan::math;

With both using statements, as in

using namespace stan::math;  // brings in stan::math::pow
using std::pow;

auto x = pow(3.1, 2.5);  // ambiguous between std::pow and stan::math::pow

we have the problem that the pow call is ambiguous.

then we ran into was that mingw32 didn't implement pow(double, int) as the C++11 spec requires, so we were getting ambiguities with 1 promotion between pow(double, double) and pow(var, int). We couldn't just write pow(T, int) with a qualifier that T be a var, because then it wouldn't be specific enough to beat the library function when the library function is defined by a compiler/library combo. Remember that gcc, clang, mingw, and now apparently some 5.5 version of clang on Linux all have different behaviors around which pow overloads they define.

To summaize, I see two options:

  1. The generic solution we're testing now, which should be OK as long as we make sure never to have using statements for std::pow and stan::math::pow in the same scope.

  2. A model that
    (a) has using std::pow; and similarly for all standard library functions that can be used as Stan functions,
    (b) has using statements for all the Stan math functions that won't be brought in by ADL, and
    (c) does not have a generic using namespace stan::math; statement.

From a math library client perspective, (2) is far superior. But that's going to be a huge pain for us on the model side. I think we should target getting there eventually. That would also allow us to clean up all those stan::math::exp(...) examples in the generated code and replace them with exp(...).

The ideal long-term goal for generated model code would be completely generic in that users could drop in their own types as long as they supported the basic C++ built-in arithmetic and standard library functions. That'd also require us to implement all Stan functions generically down to basic arithmetic; as is, we have lots of functions with a double, var and fvar<V> implementation, but not a generic one for type T.

@stan-buildbot
Copy link
Contributor


Name Old Result New Result Ratio Performance change( 1 - new / old )
gp_pois_regr/gp_pois_regr.stan 4.8 4.85 0.99 -0.97% slower
low_dim_corr_gauss/low_dim_corr_gauss.stan 0.02 0.02 0.98 -2.41% slower
eight_schools/eight_schools.stan 0.09 0.09 1.01 1.2% faster
gp_regr/gp_regr.stan 0.22 0.22 0.98 -1.72% slower
irt_2pl/irt_2pl.stan 6.46 6.59 0.98 -1.96% slower
performance.compilation 88.12 87.0 1.01 1.27% faster
low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan 7.53 7.55 1.0 -0.21% slower
pkpd/one_comp_mm_elim_abs.stan 22.04 19.94 1.11 9.5% faster
sir/sir.stan 93.03 91.23 1.02 1.93% faster
gp_regr/gen_gp_data.stan 0.05 0.05 1.02 1.62% faster
low_dim_gauss_mix/low_dim_gauss_mix.stan 2.95 3.0 0.98 -1.9% slower
pkpd/sim_one_comp_mm_elim_abs.stan 0.31 0.31 1.01 1.28% faster
arK/arK.stan 1.73 1.73 1.0 0.34% faster
arma/arma.stan 0.66 0.66 1.0 0.34% faster
garch/garch.stan 0.51 0.52 0.99 -1.35% slower
Mean result: 1.00551534547

Jenkins Console Log
Blue Ocean
Commit hash: b92f149


Machine information ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010

CPU:
Intel(R) Xeon(R) CPU E5-1680 v2 @ 3.00GHz

G++:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

Clang:
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

@bob-carpenter
Copy link
Contributor

Looks like a Jenkins problem:

make: mkdir: Exec format error
make -j6 test/performance/logistic_test failed

I restarted the performance tests.

@bob-carpenter
Copy link
Contributor

bob-carpenter commented Mar 31, 2020

@serban-nicusor-toptal : No idea what's going wrong, but it appears to be a Jenkins test config issue (or general test config issue). After restarting, it failed in exactly the same place. This is confusing, too, because we got the email with results of the performance tests, but there's not a simple file with "logistic" in the name among them.

At least it's progress in that I could find the error in the performance tests on my own.

@serban-nicusor-toptal
Copy link
Contributor

Hey, it looks like the machine that ran the tests went down.
Cannot contact old-imac: java.lang.InterruptedException it is right above the mkdir error.
I've rebooted the build from the failing step, may be just a network error or the machine dies while running the build. We'll see after this run.

@stan-buildbot
Copy link
Contributor


Name Old Result New Result Ratio Performance change( 1 - new / old )
gp_pois_regr/gp_pois_regr.stan 4.92 4.97 0.99 -0.89% slower
low_dim_corr_gauss/low_dim_corr_gauss.stan 0.02 0.02 0.96 -3.84% slower
eight_schools/eight_schools.stan 0.09 0.09 1.03 2.98% faster
gp_regr/gp_regr.stan 0.22 0.22 0.98 -1.54% slower
irt_2pl/irt_2pl.stan 6.45 6.47 1.0 -0.23% slower
performance.compilation 88.45 86.89 1.02 1.76% faster
low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan 7.53 7.53 1.0 -0.04% slower
pkpd/one_comp_mm_elim_abs.stan 20.71 20.77 1.0 -0.28% slower
sir/sir.stan 92.43 91.45 1.01 1.07% faster
gp_regr/gen_gp_data.stan 0.05 0.05 0.98 -1.55% slower
low_dim_gauss_mix/low_dim_gauss_mix.stan 2.96 2.95 1.01 0.51% faster
pkpd/sim_one_comp_mm_elim_abs.stan 0.31 0.32 0.98 -2.46% slower
arK/arK.stan 1.75 1.75 1.0 -0.02% slower
arma/arma.stan 0.65 0.66 0.98 -1.56% slower
garch/garch.stan 0.51 0.52 1.0 -0.49% slower
Mean result: 0.995890388337

Jenkins Console Log
Blue Ocean
Commit hash: b92f149


Machine information ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010

CPU:
Intel(R) Xeon(R) CPU E5-1680 v2 @ 3.00GHz

G++:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

Clang:
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

@bob-carpenter
Copy link
Contributor

Thanks! Looks like it worked. I'll review and merge.

@bbbales2
Copy link
Member Author

bbbales2 commented Apr 1, 2020

Since it's working, I made a post about the using declaration: https://discourse.mc-stan.org/t/using-std-pow-inside-stan-math-namespace/13975 like we discussed. So we can get comments there hopefully and get this merged by the weekend if nobody finds big problems.

@SteveBronder
Copy link
Collaborator

SteveBronder commented Apr 1, 2020

So looking at all the candidate functions

                                            ^
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:153:17: note: candidate function
__MATHCALL_VEC (pow,, (_Mdouble_ __x, _Mdouble_ __y));
                ^

^ That's the one we want right?

What if for all the ones here we just change the signatures to use SFINAE to kick them out? So for instance the first below here would just be

template <typename Complex, typename Arith,
  require_complex_t<Complex>* = nullptr,
  require_arithmetic_t<Arith>* = nullptr>
inline std::complex<var> pow(const Complex& x, Arith y) {

I think that avoids namespace issues and preserves just using the standard lookup rules

lib/stan_math/stan/math/rev/fun/pow.hpp:320:26: note: candidate function
inline std::complex<var> pow(const std::complex<var>& x, int y) {
                         ^
lib/stan_math/stan/math/rev/fun/pow.hpp:140:12: note: candidate function [with T = int, $1 = void]
inline var pow(const var& base, T exponent) {
           ^
lib/stan_math/stan/math/rev/fun/pow.hpp:180:12: note: candidate function [with T = double, $1 = void]
inline var pow(T base, const var& exponent) {
           ^
lib/stan_math/stan/math/rev/fun/pow.hpp:242:26: note: candidate function [with T = int, $1 = void]
inline std::complex<var> pow(const std::complex<var>& x, T y) {
                         ^
lib/stan_math/stan/math/rev/fun/pow.hpp:305:26: note: candidate function [with T = double, $1 = void]
inline std::complex<var> pow(T x, const std::complex<var>& y) {
                         ^
lib/stan_math/stan/math/rev/fun/pow.hpp:119:12: note: candidate function
inline var pow(const var& base, const var& exponent) {
           ^
lib/stan_math/stan/math/rev/fun/pow.hpp:203:26: note: candidate function
inline std::complex<var> pow(const std::complex<var>& x,
                         ^
lib/stan_math/stan/math/rev/fun/pow.hpp:229:26: note: candidate function
inline std::complex<var> pow(const std::complex<var>& x, const var& y) {
                         ^
lib/stan_math/stan/math/rev/fun/pow.hpp:279:26: note: candidate function
inline std::complex<var> pow(const var& x, const std::complex<var>& y) {

@bbbales2
Copy link
Member Author

bbbales2 commented Apr 1, 2020

What if for all the ones here we just change the signatures to use SFINAE to kick them out? So for instance the first below here would just be

So basically this signature won't allow for promotions from (double, int)?

@SteveBronder
Copy link
Collaborator

idt int to double is the issue is it? It looks like because var and complex are implicitly convertible from arithmetic types they are candidates when we don't want them to be. Otherwise we could

  1. Replace the second template with double
  2. do require_t<std::is_same<double, T2>> for the sample template

Though 2 feels gross. I think the one I have above would work

@bbbales2
Copy link
Member Author

bbbales2 commented Apr 1, 2020

I'd have to try this out, I think.

I mean, it's true we don't want doubles/ints promoting to vars through argument calls like that for efficiency, but that doesn't mean we aren't leaning on it somewhere I'm not thinking about.

By (double, int) I meant the first argument is double, second is int.

@SteveBronder
Copy link
Collaborator

I mean, it's true we don't want doubles/ints promoting to vars through argument calls like that for efficiency, but that doesn't mean we aren't leaning on it somewhere I'm not thinking about.

I'm not sure where this would be true and I'm like 90% sure it's actually where the error comes from. @bob-carpenter thoughts? I could be missing something here

@SteveBronder
Copy link
Collaborator

By (double, int) I meant the first argument is double, second is int.

I think just by doing the above thing the double double version is the only possible candidate

@bob-carpenter
Copy link
Contributor

The discussion's now half on Discourse and half here, so I'll follow up here to comments posted on GitHub.

I believe @bbbales2 figured out the right solution to this problem---have a using std::pow; in the stan::math namespace. I have one final question, though---will that introduce an ambiguity between std::pow and stan::math::pow if they're both in scope or does the compiler know they're the same function?

As I keep trying to emphasize, the pure type traits version isn't workable in general because it's not specific enough and won't get chosen over library versions in cases where we need it. We might be able to come up with some hybrid solution that type traits out some of them and has other more specialized versions.

We want to allow double and int to promote to any of our scalar types (complex, var, complex-var, etc.). Promoting never causes an error, just a loss of efficiency compared to a direct primitive implementation. It's never a mistake in Stan to call a lower type function if available.

@bbbales2
Copy link
Member Author

bbbales2 commented Apr 1, 2020

std::pow and stan::math::pow if they're both in scope

Should be tested here: https://github.com/stan-dev/math/pull/1810/files#diff-acb4663890da3d3806032f1554bea099R37

@SteveBronder
Copy link
Collaborator

As I keep trying to emphasize, the pure type traits version isn't workable in general because it's not specific enough and won't get chosen over library versions in cases where we need it. We might be able to come up with some hybrid solution that type traits out some of them and has other more specialized versions.

Can you show me an example where this would fail to do what we want using type traits?

We want to allow double and int to promote to any of our scalar types (complex, var, complex-var, etc.). Promoting never causes an error, just a loss of efficiency compared to a direct primitive implementation. It's never a mistake in Stan to call a lower type function if available.

I think there's some confusion on my end here. Yes i agree we want to allow promotion, but if someone does

double x = 1.0;
int y = 2;
auto v = exp(x, y);

I don't see why we would ever want to allow that auto to resolve to complex etc. My worry is that if someone does something in stan math and doesn't do the right include order for usings then that's going to be possible.

If I can get a version of this working with type traits would that be an acceptable answer?

@bbbales2
Copy link
Member Author

bbbales2 commented Apr 2, 2020

If I can get a version of this working with type traits would that be an acceptable answer?

The solution over here is probably the simpler stopgap to getting this to work if we don't want using std::pow in math: stan-dev/stan#2906 .

I'm happy with just putting using std::pow in math or the generated code for now and bringing this issue up again after the release.

Getting rid of implicit casts in pow might work, but I don't think we'd want to do this generally just cuz it means writing tons and tons of functions.

@SteveBronder
Copy link
Collaborator

Actually nvm I think there is more manutia then I thought. Messing around I had some weird with the namespaces that idk how to work with atm

@bob-carpenter
Copy link
Contributor

There's a pow(T, int) and pow(T, T) built into the standard library definitions (but keep in mind which specific templates are available depends on library implementation---it's the wild west once you get to Windows and std::complex). If you implement pow(T, U) with traits, it won't match better than these library definitions. All of the unary functions are implemented as, e.g., exp(T), so there's an issue with these if you just try to traits them out.

I would suggest you try it for yourself. Maybe there's something I'm missing here.

@bob-carpenter
Copy link
Contributor

My worry is that if someone does something in stan math and doesn't do the right include order for usings then that's going to be possible.

When is overpromotion going to be a problem? Each of the autodiff files should be including the primitive version, so I don't even see how it'll be a problem if we have the instantiations covered properly.

We've decided that end users should be using our top-level includes, which take care of this all at once. Math library developers need to understand C++ include order.

@stan-buildbot
Copy link
Contributor


Name Old Result New Result Ratio Performance change( 1 - new / old )
gp_pois_regr/gp_pois_regr.stan 4.86 4.87 1.0 -0.23% slower
low_dim_corr_gauss/low_dim_corr_gauss.stan 0.02 0.02 1.0 -0.46% slower
eight_schools/eight_schools.stan 0.09 0.09 0.98 -2.01% slower
gp_regr/gp_regr.stan 0.22 0.22 0.98 -1.73% slower
irt_2pl/irt_2pl.stan 6.45 6.44 1.0 0.19% faster
performance.compilation 89.38 86.97 1.03 2.69% faster
low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan 7.51 7.52 1.0 -0.07% slower
pkpd/one_comp_mm_elim_abs.stan 20.53 21.02 0.98 -2.43% slower
sir/sir.stan 97.22 95.71 1.02 1.55% faster
gp_regr/gen_gp_data.stan 0.05 0.05 0.98 -1.95% slower
low_dim_gauss_mix/low_dim_gauss_mix.stan 2.96 2.95 1.0 0.36% faster
pkpd/sim_one_comp_mm_elim_abs.stan 0.31 0.32 0.98 -2.3% slower
arK/arK.stan 1.74 1.74 1.0 -0.07% slower
arma/arma.stan 0.66 0.66 1.0 0.23% faster
garch/garch.stan 0.51 0.51 1.0 0.43% faster
Mean result: 0.996352892995

Jenkins Console Log
Blue Ocean
Commit hash: 087a584


Machine information ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010

CPU:
Intel(R) Xeon(R) CPU E5-1680 v2 @ 3.00GHz

G++:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

Clang:
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

@bbbales2
Copy link
Member Author

bbbales2 commented Apr 4, 2020

@rok-cesnovar, @SteveBronder, @bob-carpenter, anyone want to get this?

This removes the mingw pow(double, int) implementation. Including std::pow in the code generation should make this unnecessary (stan-dev/stan#2906 (comment)).

Copy link
Contributor

@bob-carpenter bob-carpenter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There wa a stray space fix in opencl that probably shouldn't be in this PR.

Otherwise this is fine, but how do we stage the testing?

@@ -49,7 +49,7 @@ class load_
* Creates a deep copy of this expression.
* @return copy of \c *this
*/
inline load_<T&> deep_copy() const & { return load_<T&>(a_); }
inline load_<T&> deep_copy() const& { return load_<T&>(a_); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a stray change that shouldn't be in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was the autoformatter, but I dunno why it looked at this file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the commit: d539b58#diff-e92a842ba1a127d7587a635913cb4ce3 . Since this is the autoformatter I'm not going to bother with trying to revert it. Presumably it'd just put it back again.

Copy link
Member

@rok-cesnovar rok-cesnovar Apr 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is related to #1822

The styling on develop was forced by an older version of clang-format. So one PR would eventually have to fix it.

@bbbales2
Copy link
Member Author

bbbales2 commented Apr 4, 2020

Otherwise this is fine, but how do we stage the testing?

The stan and stanc3 code is already in (stan-dev/stan#2906 (comment), stan-dev/stanc3#492). This is the last one.

Presumably the stan stuff didn't get tested on Windows with mingw so it passed (got tested with g++).

@rok-cesnovar
Copy link
Member

Stanc3 had failures on master since the complex stuff was added. Adding using std::pow fixed that so I think we can proceed here.

@bbbales2
Copy link
Member Author

bbbales2 commented Apr 5, 2020

@bob-carpenter this needs merged so that there aren't ambiguities between using std::pow and the pow(double, int) implementation currently in stan-dev/math/develop. I suspect cmdstan on mingw would fail now.

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

Successfully merging this pull request may close these issues.

Ambiguities with between C/C++/stan pow implementations
7 participants