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

Feature/issue 202 vectorize all #399

Merged
merged 6 commits into from
Oct 13, 2016

Conversation

rayleigh
Copy link
Contributor

@rayleigh rayleigh commented Sep 28, 2016

Submisison Checklist

  • [x ] Run unit tests: ./runTests.py test/unit
  • [ x] Run cpplint: make cpplint
  • [ x] Declare copyright holder and open-source license: see below

Summary:

This pull request is to add the headers for the functions vectorized in #202 to stan/math/prim/mat.hpp so that the vectorized functions can be exposed in Stan.

Intended Effect:

None to users. Internally, I added the headers to stan/math/prim/mat.hpp.

How to Verify:

Check that vectorized functions are added correctly and tests still pass.

Side Effects:

None.

Documentation:

None needed.

Reviewer Suggestions:

Copyright and Licensing

Per Michigan's copyright laws, Rayleigh Lei is the copyright holder.
Please list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company):

By submitting this pull request, the copyright holder is agreeing to license the submitted work under the following licenses:

@rayleigh
Copy link
Contributor Author

I couldn't add lgamma or fabs because there are other template functions using those functions and unit tests fail when adding them to stan/math/prim/scal/fun/mat.hpp. Specifically, stan/math/prim/scal/fun/lbeta.hpp is templated and uses lgamma whereas stan/math/prim/scal/fun/grad_2F1.hpp is templated and uses fabs.

@bob-carpenter
Copy link
Contributor

I'm working on this in #370 starting by eliminating math.h branch and then will add vectorization for what's left in #347. #370 already has a pull request and #347 has already added a few more functions that weren't in the original request, but I'm going to stage #347 after #370.

@bob-carpenter
Copy link
Contributor

I wasn't sure how this pull request was supposed to help with only defining a mat.hpp header file.

@syclik
Copy link
Member

syclik commented Sep 28, 2016

I'm confused too. Do those headers all exist?

@rayleigh
Copy link
Contributor Author

rayleigh commented Sep 28, 2016

I'll change the description, but I was adding the functions already vectorized in #202. In that huge pull request, I forgot to add those functions to stan/math/prim/mat.hpp. As a result, I think only log and exp can be vectorized in Stan currently even though we have more vectorized functions in stan/math.

@rayleigh
Copy link
Contributor Author

I was looking at this and realized that I hadn't added the headers to stan/math/prim/mat.hpp in the last pull request. My other comment was about functions that are vectorized in stan/math, but couldn't be added to stan/math/prim/mat.hpp without the unit tests failing. I did some investigation and my comment is my guess at why I couldn't add them without the tests failing.

@rayleigh
Copy link
Contributor Author

rayleigh commented Oct 4, 2016

When I tried adding the function signature test for the matrix form of abs in Stan, I get make error 252. However, the test is a copy of the exp matrix test that passes, only with abs replacing the exp calls. Based on this, I think the cause of the make error is because I hadn't added the appropriate headers to stan/math/prim/mat.hpp in the last vectorize-all pull request in stan-math. Hence, I created this pull request to fix that problem by adding the headers to stan/math/prim/mat.hpp.

Indeed, I just tried adding the function signature test for the matrix form of log in Stan because the header file is in stan/math/prim/mat.hpp. The log matrix test is a copy of the exp matrix test, again with log replacing the exp calls. The log test did not error out.

So, if I can get this pull request in, minus the two functions I have had trouble adding to stan/math/prim/mat.hpp, I should be able to push the vectorized functions up to Stan.

@bob-carpenter
Copy link
Contributor

  1. When my pull request for remving math.h is merged (should be soon), then we will have stan::math::round we can use instead of ::round from math.h, which isn't portable to Windows compilers.
  2. Why are you removing includes like cov_exp_quad.hpp?

@bob-carpenter
Copy link
Contributor

Actually, that's already merged, so you should update and use stan::math::round.

@rayleigh
Copy link
Contributor Author

rayleigh commented Oct 4, 2016

  1. I'll switch it. I'm using ::round because the integration tests were failing due to std::round last week.

  2. No functions were removed. I essentially took out all functions in stan/math/prim/mat/fun/, added vectorized function headers, sorted all functions alphabetically using bash's sort, and then put it back in stan/math/prim/mat.hpp. As a result, some existing functions got moved around.

@bob-carpenter
Copy link
Contributor

(1) Thanks.

You only get std::round in C++11. But it's built into some
of the g++ and clang++ implementations. Overall, the libraries
are a mess before C++11 but get standardized properly in C++11.

(2) I see. That's OK. They should go in the alphabetical
order you rearranged them into.

  • Bob

On Oct 4, 2016, at 12:32 PM, rayleigh [email protected] wrote:

  1. I'll switch it. I'm using ::round because the integration tests were failing due to std::round last week.

  2. No functions were removed. I essentially took out all functions in stan/math/prim/mat/fun/, added vectorized function headers, sorted all functions alphabetically using bash's sort, and then put it back in stan/math/prim/mat.hpp. As a result, some existing functions got moved around.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

@rayleigh
Copy link
Contributor Author

rayleigh commented Oct 7, 2016

I updated round to use stan::math::round. Is this good to merge? Or, do I need to also add lgamma and fabs to stan/math/prim/mat.hpp as well? Or, is there something else as well?

@bob-carpenter
Copy link
Contributor

I'm OK with this merging---I can fix the merge conflict it'll
cause on my existing branch that vectorizes the remaining
functions. I'm stuck on translation unit tests failing.

But what I don't see is how you can get away with putting
the code in stan/math/prim/mat.hpp---I wound up needing to
put it in stan/math/mix/mat.hpp to make sure it went after
all the core fwd and rev stuff so it could get instantiated
properly.

  • Bob

@rayleigh
Copy link
Contributor Author

rayleigh commented Oct 11, 2016

I'm curious what you mean by that.

If I include the vectorized version of lgamma.hpp in prim/math/mat.hpp and run test/unit/math/mix/scal/meta/child_type_test.cpp, I get the following error messages:

In file included from test/unit/math/mix/scal/meta/child_type_test.cpp:3:
In file included from ./test/unit/math/prim/scal/fun/promote_type_test_util.hpp:4:
In file included from ./stan/math/prim/mat.hpp:48:
In file included from ./stan/math/prim/mat/fun/abs.hpp:4:
./stan/math/prim/mat/vectorize/apply_scalar_unary.hpp:39:41: error: implicit
      instantiation of undefined template
      'Eigen::internal::traits<unsigned int>'
      typedef typename Eigen::internal::traits<T>::Scalar scalar_t;
                                        ^
./stan/math/prim/mat/fun/lgamma.hpp:33:21: note: in instantiation of template
      class 'stan::math::apply_scalar_unary<stan::math::lgamma_fun, unsigned
      int>' requested here
    inline typename apply_scalar_unary<lgamma_fun, T>::return_t
                    ^
./stan/math/prim/mat/prob/lkj_corr_log.hpp:65:52: note: while substituting
      deduced template arguments into function template 'lgamma'
      [with T = unsigned int]
            - 0.25 * (Km1 * Km1) * LOG_TWO - Km1 * lgamma((K + 1) / 2);
                                                   ^
lib/eigen_3.2.9/Eigen/src/Core/util/ForwardDeclarations.h:17:29: note: template
      is declared here
template<typename T> struct traits;
                            ^
In file included from test/unit/math/mix/scal/meta/child_type_test.cpp:3:
In file included from ./test/unit/math/prim/scal/fun/promote_type_test_util.hpp:4:
In file included from ./stan/math/prim/mat.hpp:48:
In file included from ./stan/math/prim/mat/fun/abs.hpp:4:
./stan/math/prim/mat/vectorize/apply_scalar_unary.hpp:45:39: error: type
      'unsigned int' cannot be used prior to '::' because it has no members
      typedef Eigen::Matrix<scalar_t, T::RowsAtCompileTime,
                                      ^
./stan/math/prim/mat/vectorize/apply_scalar_unary.hpp:39:41: error: implicit
      instantiation of undefined template
      'Eigen::internal::traits<stan::math::var>'
      typedef typename Eigen::internal::traits<T>::Scalar scalar_t;
                                        ^
./stan/math/prim/mat/fun/lgamma.hpp:33:21: note: in instantiation of template
      class 'stan::math::apply_scalar_unary<stan::math::lgamma_fun,
      stan::math::var>' requested here
    inline typename apply_scalar_unary<lgamma_fun, T>::return_t
                    ^
./stan/math/prim/scal/fun/lbeta.hpp:61:14: note: while substituting deduced
      template arguments into function template 'lgamma' [with T =
      stan::math::var]
      return lgamma(a)
             ^
./stan/math/rev/scal/fun/grad_inc_beta.hpp:37:20: note: in instantiation of
      function template specialization 'stan::math::lbeta<stan::math::var,
      stan::math::var>' requested here
      var c3 = exp(lbeta(a, b)) * inc_beta(a, b, z);
                   ^
lib/eigen_3.2.9/Eigen/src/Core/util/ForwardDeclarations.h:17:29: note: template
      is declared here
template<typename T> struct traits;
                            ^
In file included from test/unit/math/mix/scal/meta/child_type_test.cpp:3:
In file included from ./test/unit/math/prim/scal/fun/promote_type_test_util.hpp:4:
In file included from ./stan/math/prim/mat.hpp:48:
In file included from ./stan/math/prim/mat/fun/abs.hpp:4:
./stan/math/prim/mat/vectorize/apply_scalar_unary.hpp:45:42: error: no member
      named 'RowsAtCompileTime' in 'stan::math::var'
      typedef Eigen::Matrix<scalar_t, T::RowsAtCompileTime,
                                      ~~~^
4 errors generated.
make: *** [test/unit/math/mix/scal/meta/child_type_test.o] Error 1
make test/unit/math/mix/scal/meta/child_type_test failed
exit now (10/11/16 13:34:36 EDT)

If I go into stan/math/prim/mat/prob/lkj_corr_log.hpp and add using stan::math::lgamma to the function do_lkj_constant, the only function that uses lgamma, I get the following error message from running the same test:

In file included from test/unit/math/mix/scal/meta/child_type_test.cpp:3:
In file included from ./test/unit/math/prim/scal/fun/promote_type_test_util.hpp:4:
In file included from ./stan/math/prim/mat.hpp:48:
In file included from ./stan/math/prim/mat/fun/abs.hpp:4:
./stan/math/prim/mat/vectorize/apply_scalar_unary.hpp:39:41: error: implicit
      instantiation of undefined template
      'Eigen::internal::traits<stan::math::var>'
      typedef typename Eigen::internal::traits<T>::Scalar scalar_t;
                                        ^
./stan/math/prim/mat/fun/lgamma.hpp:33:21: note: in instantiation of template
      class 'stan::math::apply_scalar_unary<stan::math::lgamma_fun,
      stan::math::var>' requested here
    inline typename apply_scalar_unary<lgamma_fun, T>::return_t
                    ^
./stan/math/prim/scal/fun/lbeta.hpp:61:14: note: while substituting deduced
      template arguments into function template 'lgamma' [with T =
      stan::math::var]
      return lgamma(a)
             ^
./stan/math/rev/scal/fun/grad_inc_beta.hpp:37:20: note: in instantiation of
      function template specialization 'stan::math::lbeta<stan::math::var,
      stan::math::var>' requested here
      var c3 = exp(lbeta(a, b)) * inc_beta(a, b, z);
                   ^
lib/eigen_3.2.9/Eigen/src/Core/util/ForwardDeclarations.h:17:29: note: template
      is declared here
template<typename T> struct traits;
                            ^
In file included from test/unit/math/mix/scal/meta/child_type_test.cpp:3:
In file included from ./test/unit/math/prim/scal/fun/promote_type_test_util.hpp:4:
In file included from ./stan/math/prim/mat.hpp:48:
In file included from ./stan/math/prim/mat/fun/abs.hpp:4:
./stan/math/prim/mat/vectorize/apply_scalar_unary.hpp:45:42: error: no member
      named 'RowsAtCompileTime' in 'stan::math::var'
      typedef Eigen::Matrix<scalar_t, T::RowsAtCompileTime,
                                      ~~~^
2 errors generated.
make: *** [test/unit/math/mix/scal/meta/child_type_test.o] Error 1
make test/unit/math/mix/scal/meta/child_type_test failed
exit now (10/11/16 13:36:48 EDT)

If I look at stan/math/prim/scal/fun/lbeta.hpp, I see that the function is templated. My guess is that it's pulling in the unary vectorize code out of order.

@bob-carpenter
Copy link
Contributor

The fundamental problems are:

  1. Bringing in a template definition before all
    the classes needed to instantiate it. That's why I couldn't
    figure out how to include in prim/mat.hpp. But I see
    what you did and am going to try following that pattern right now.
  2. Ambiguities due to not having a most specific
    implementation. For example, providing an int
    argument to a function defined only for double and
    var --- int can be promoted to either one. That's why I've
    added explicit int definitions where necessary.

I have the basic functions all sorted in a pull request that's
just awaiting Daniel's help for the multiple translation units.
And I vectorized the rest of the functions in a pull request waiting
on the first pull request.

I'd suggest just working on a pull request to get the rest of
the functions you wrote vectorized in Stan and by the time you're
done, I should have the math library sorted.

@syclik
Copy link
Member

syclik commented Oct 11, 2016

Yup. I need to work on that multiple translation unit thing.

On Oct 11, 2016, at 2:30 PM, Bob Carpenter [email protected] wrote:

The fundamental problems are:

  1. Bringing in a template definition before all
    the classes needed to instantiate it. That's why I couldn't
    figure out how to include in prim/mat.hpp. But I see
    what you did and am going to try following that pattern right now.
  2. Ambiguities due to not having a most specific
    implementation. For example, providing an int
    argument to a function defined only for double and
    var --- int can be promoted to either one. That's why I've
    added explicit int definitions where necessary.

I have the basic functions all sorted in a pull request that's
just awaiting Daniel's help for the multiple translation units.
And I vectorized the rest of the functions in a pull request waiting
on the first pull request.

I'd suggest just working on a pull request to get the rest of
the functions you wrote vectorized in Stan and by the time you're
done, I should have the math library sorted.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

@rayleigh
Copy link
Contributor Author

rayleigh commented Oct 11, 2016

I see. Thanks for letting me know.

I'd suggest just working on a pull request to get the rest of the functions you wrote vectorized in Stan and by the time you're done, I should have the math library sorted.

That sounds good. Could I get this pull request merged then? I currently get a make error 252 when I try to vectorize in Stan the functions that are vectorized in stan/math. This pull request is to add the functions to stan/math/prim/mat.hpp with the exception of lgamma and fabs for reasons we've discussed above. Doing so will allow me to vectorize them in Stan because I've only been able to vectorize in Stan log and exp, functions that are in stan/math/prim/mat.hpp.

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.

Looks good to me.

@bob-carpenter bob-carpenter merged commit 1efa66c into develop Oct 13, 2016
@syclik syclik modified the milestone: v2.13.0 Nov 25, 2016
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.

3 participants