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
[WIP] Fix doxygen so it compiles with 0 errors and update docs #2745
Conversation
@bob-carpenter I still need to finish some of the edits to the adding new functions documentation but this should be ready to read over by tmrw or so |
Alrighty @bob-carpenter I think I got everything sorted out. Can you try checking out this branch and running |
The branch doesn't build for me in doxygen. Could I have the wrong version of doxygen installed?
Here's the error dump from doxygen:
|
No this is an error when compiling with 1.9.1+, it is trying to document the OpenCL library we use as well which is odd. Let me see if I can tell it to not try to do that. Oddly this doesn't show up for <= 1.9.1 |
Alrighty @bob-carpenter can you give it another shot? |
Awesome. It works now with only some config warnings. Should I go ahead and review and merge?
|
If you can start reviewing the doxygen docs I wrote that would be great, but I need to check out what the error is coming from on Jenkins right now in prim |
It looks like the error may be on Jenkins config. I don't know how to mechanically do the review here. The 400+ files just chokes my web browser and the web page takes forever to scroll (30+ seconds) or to click (60+ seconds). Suggestions? |
Oh wow, so on my desktop its fine but on my laptop it totally crashes. Can you try the link below while also setting the diff to unified view? Both of those things managed to get the docs up and reviewable. I think unified view also works for reviewing the code |
Thanks, @SteveBronder---that works. Now onto the actual reviewing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well that took several hours. I can't imagine how long this took to write. Thanks, it all looks amazing. Almost all of my comments are minor grammatical and formatting things.
But what I don't see is the changed C++ code. Is that coming in a different PR?
doxygen/README.md
Outdated
|
||
int main() { | ||
std::cout << "log normal(1 | 2, 3)=" | ||
<< stan::math::normal_log(1, 2, 3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be _lpdf
---the _log
suffixes are deprecated (or should be, if they're not).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
doxygen/README.md
Outdated
``` | ||
|
||
If this is in the file `/path/to/foo/foo.cpp`, then you can compile | ||
and run this with something like this, with the `/path/to` business |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd just say <path>/foo.cpp
and mention that it's a path.
I'd also prefer to stay away from vague statements like "something like this"---if it's not exactly this, then just say how it differs (e.g., replace <path>
with an actual path).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
it new meta-programs should be added. | ||
|
||
|
||
All of the SFINAE template meta-programs in Math are special to Stan or Math. Documentation can be found in the @ref require_meta docs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no hyphen in metaprogram. don't listen to your spellchecker if it tries to tell you otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ty! I'll look at other places this is done as well
the expression it is used in. | ||
[godbolt example](https://godbolt.org/z/6Te856Mv7) | ||
|
||
When we return back an **eigen expression** containing objects created in the local scope we need a way to store those locally created objects till the expression is evaluated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
capitalize Eigen; return back -> return
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
other.m_data = nullptr; | ||
} | ||
}; | ||
``` | ||
|
||
We can see in the above that the standard style of a move (the constructor taking an rvalue reference) is to copy the pointer and then null out the original pointer. But in Stan, particularly for reverse mode, we need to keep memory around even if it's only a temporary for when we call the gradient calculations in the reverse pass. And since memory for reverse mode is stored in our arena allocator no copying happens in the first place. | ||
|
||
When working with arithmetic types, keep in mind that moving Scalars is often less optimal than simply taking their copy. For instance, Stan's `var` type is a PIMPL implementation, so it simply holds a pointer of size 8 bytes. A `double` is also 8 bytes which just so happens to fit exactly in a [word](https://en.wikipedia.org/wiki/Word_(computer_architecture)) of most modern CPUs. While a reference to a double is also 8 bytes, unless the function is inlined by the compiler, the computer will have to place the reference into cache, then go fetch the value that is being referenced which now takes up two words instead of one! | ||
When working with arithmetic types, keep in mind that moving Scalars is often less optimal than simply taking their copy. For instance, Stan's `var` type is a PIMPL implementation, so it simply holds a pointer of size 8 bytes. A `double` is also 8 bytes which just so happens to fit exactly in a [word](https://en.wikipedia.org/wiki/Word_(computer_architecture)) of most modern CPUs with at least 64 byte cache lines. While a reference to a double is also 8 bytes, unless the function is inlined by the compiler, the computer will have to place the reference into cache, then go fetch the value that is being referenced which now takes up two words instead of one! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should avoid these super long lines.
But the reason I opened this box was to say that "PIMPL impementation" is redundant because the IMPL stands for "implementation. So I'd say "uses the pointer to implementation (PIMPL) pattern" to avoid redundancy.
Plus, thanks for explaining the "why" here---I hadn't realized references would tickle two words instead of one. I would've expected that with a pointer, but I would've thought references would be smarter given that they're immutable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should avoid these super long lines.
Yeah I'll add some returns here to make the markdown easier to read.
But the reason I opened this box was to say that "PIMPL impementation" is redundant because the IMPL stands for "implementation. So I'd say "uses the pointer to implementation (PIMPL) pattern" to avoid redundancy.
Yes thats a much better way to word it, fixed!
Plus, thanks for explaining the "why" here---I hadn't realized references would tickle two words instead of one. I would've expected that with a pointer, but I would've thought references would be smarter given that they're immutable.
Yes, though note that this is one of those weird internal to compiler things that tbh will rarely come up, but with large programs you can have instances where this sort of thing happens.
@ref stan::is_var. | ||
|
||
The `requires` type traits allow Stan to have more generic types so that the | ||
library can forward along Eigen expression and have better move semantics. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forward along -> forward
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
template <typename Mat1, typename Mat2, | ||
require_all_eigen_vt<is_arithmetic, Mat1, Mat2>* = nullptr> | ||
inline auto a_func(Mat1&& m1, Mat2&& m2) { | ||
check_nan(m1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's check_not_nan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
|
||
For a full list of predefined `requires` please see @ref require_meta. | ||
|
||
If you are adding a new type trait that returns has a `bool value` member you can add it to the set of known requires by using the macros @ref stan/math/prim/meta/require_helpers.hpp . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
returns has -> returns
bool value
member -> bool value
(members don't get returned by functions)
macros -> macros defined in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. This should not have been about returns but instead about definint type traits that have a bool
member named value
.
``` | ||
|
||
We can add the associated `requires` for the standard requires of `require_double_only_t` using @ref STAN_ADD_REQUIRE_UNARY macro. | ||
We supply the name to use in the require (`double_only`), The type trait name (`is_double_only`) and which group this type trait is in `require_stan_scalar_real`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using -> using the
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
} catch (err) { | ||
setTimeout(arguments.callee, 10); | ||
} | ||
})(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get what anything in this file is doing or the previous one, but I assume they just come in as boilerplate from elsewhere and don't need thorough review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is a hack of the Eigen hack so that the table of contents in the bottom left part of the docs page is drawn nicely.
Thank you for the thorough review! Yes it took quite a while to write but I think it should help folks in the future. I'll give this a look over the weekend |
Seriously, you can take as much of that feedback as you want. It's great as it is, and I wouldn't want to block it on grammar, formatting, etc. |
Alright I think I got everything! At this point just need to do a find replace to add newlines after each sentence and remove some of the I / we usage. @bob-carpenter I'll ping you when I'm finished with those |
@SteveBronder, I'm trying to resurrect this PR. I merged develop into it to the best of my ability. |
Summary
This cleans up a lot of the doxygen to remove a lot of the warnings we previously had. The biggest warning was about parameters being defined multiple times for different overloads. This was caused by doxygen parsing functions while ignoring non-type template parameters which we use for writing our overloads. For example, doxygen would look at both of these functions signatures as if they were the same
To fix this I just changed the names of the template parameters. When possible I would change the name to reflect, conceptually, what types would go into the overload. But in some cases there are several generic overloads and so for those I just added arbitrary named templates like
T1
,T2
,T3
, etc.Tests
This should only be a cosmetic change so no new tests should be necessary.
The docs should be looked over from a local build of the website using
make doxygen
Side Effects
Yes, doxygen now requires at least version
1.8.13
. This is the default for Ubuntu in 20.04, but I'm not sure what version homebrew has. I also got this to make the docs with doxygen 1.9.1 but there could be errors I'm missing with newer versions like 1.9.4. Bullseye Debian only has version1.8.3
so our docs will not compile on Bullseye debian systems with the basic install unless they install doxygen from backports.Release notes
Update the documentation
Checklist
Math issue #(issue number)
Copyright holder: Steve Bronder
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
./runTests.py test/unit
)make test-headers
)make test-math-dependencies
)make doxygen
)make cpplint
)the code is written in idiomatic C++ and changes are documented in the doxygen
the new changes are tested