Skip to content
Merged
Changes from 2 commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
09500b5
replacing two macro calls
syclik Oct 20, 2023
18ad3b4
expanding STAN_ADD_REQUIRE_UNARY(...) macro
syclik Oct 20, 2023
1684854
expanding STAN_ADD_REQUIRE_UNARY_INNER(...) macro
syclik Oct 22, 2023
01488a8
expanding STAN_ADD_REQUIRE_BINARY_INNER(...) macro
syclik Oct 22, 2023
56e960e
expanding STAN_ADD_REQUIRE_CONTAINER(...) macro
syclik Oct 22, 2023
1a41603
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Oct 22, 2023
8295f0b
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Oct 22, 2023
940c3b5
fixing a few mistakes in expansion
syclik Oct 23, 2023
5571c5d
removing duplicated macro expansion
syclik Oct 23, 2023
2d032a0
removing unused require_ from stan/math/prim/meta/is_arena_matrix.hpp
syclik Oct 23, 2023
71c5b70
removing unused require_ from stan/math/prim/meta/is_autodiff.hpp
syclik Oct 23, 2023
478f4cb
removing unused require_ from stan/math/prim/meta/is_complex.hpp
syclik Oct 23, 2023
af52c7f
removing unused require_ from stan/math/prim/meta/is_constant.hpp
syclik Oct 23, 2023
4f83ba4
removing unused require_ from stan/math/prim/meta/is_container.hpp
syclik Oct 23, 2023
c5bde61
removing unused require_ from stan/math/prim/meta/is_container_or_var…
syclik Oct 23, 2023
fcdc1ba
removing unused require_ from stan/math/prim/meta/is_dense_dynamic.hpp
syclik Oct 23, 2023
96a972a
removing unused require_ from stan/math/prim/meta/is_double_or_int.hpp
syclik Oct 24, 2023
18c012d
removing unused require_ from stan/math/prim/meta/is_eigen.hpp
syclik Oct 24, 2023
0d19cba
removing unused require_ from stan/math/prim/meta/is_eigen_dense.hpp
syclik Oct 24, 2023
7dcc949
removing unused require_ from stan/math/prim/meta/is_eigen_dense_dyna…
syclik Oct 24, 2023
c00c47c
removing unused require_ from stan/math/prim/meta/is_eigen_matrix.hpp
syclik Oct 24, 2023
a5393bd
removing unused require_ from stan/math/prim/meta/is_eigen_matrix_bas…
syclik Oct 24, 2023
097f77b
removing unused require_ from stan/math/prim/meta/is_eigen_sparse_bas…
syclik Oct 24, 2023
fdb288c
removing unused require_ from stan/math/prim/meta/is_fvar.hpp
syclik Oct 24, 2023
f860153
removing unused require_ from stan/math/prim/meta/is_kernel_expressio…
syclik Oct 24, 2023
2e78376
removing unused require_ from stan/math/prim/meta/is_matrix.hpp
syclik Oct 24, 2023
335938c
removing unused require_ from stan/math/prim/meta/is_matrix_cl.hpp
syclik Oct 24, 2023
e6892e6
removing unused require_ from stan/math/prim/meta/is_plain_type.hpp
syclik Oct 24, 2023
0ee6a19
removing unused require_ from stan/math/prim/meta/is_rev_matrix.hpp
syclik Oct 24, 2023
d442821
removing unused require_ from stan/math/prim/meta/is_stan_scalar.hpp
syclik Oct 24, 2023
4b2b109
removing unused require_ from stan/math/prim/meta/is_stan_scalar_or_e…
syclik Oct 24, 2023
5c1c078
removing unused require_ from stan/math/prim/meta/is_string_convertib…
syclik Oct 24, 2023
b53b8c1
removing unused require_ from stan/math/prim/meta/is_tuple.hpp
syclik Oct 24, 2023
1ce7375
removing unused require_ from stan/math/prim/meta/is_var.hpp
syclik Oct 24, 2023
1c6ab83
removing unused require_ from stan/math/prim/meta/is_var_and_matrix_t…
syclik Oct 24, 2023
47a036b
removing unused require_ from stan/math/prim/meta/is_var_dense_dynami…
syclik Oct 24, 2023
05eb70e
removing unused require_ from stan/math/prim/meta/is_var_eigen.hpp
syclik Oct 24, 2023
ccb73dc
removing unused require_ from stan/math/prim/meta/is_var_matrix.hpp
syclik Oct 24, 2023
e10ec7c
removing unused require_ from stan/math/prim/meta/is_var_or_arithmeti…
syclik Oct 24, 2023
529787a
removing unused require_ from stan/math/prim/meta/is_vari.hpp
syclik Oct 24, 2023
d602663
removing unused require_ from stan/math/prim/meta/is_vector.hpp
syclik Oct 24, 2023
243c067
removing unused require_ from stan/math/prim/meta/is_vector_like.hpp
syclik Oct 24, 2023
c334aed
removing unused require_ from stan/math/prim/meta/require_generics.hpp
syclik Oct 24, 2023
b0a689e
adding back in require_not_same_t
syclik Nov 8, 2023
27cf52b
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
syclik Nov 29, 2023
6dcc5d7
wip: temp files
syclik Nov 1, 2023
291f056
adding back in require_vector_like_vt
syclik Nov 27, 2023
a328a97
adding back in require_all_not_tuple_t
syclik Nov 27, 2023
4cfbdf9
adding back in require_eigen_array_vt
syclik Nov 28, 2023
cc6f6d0
adding back in require_all_st_stan_scalar
syclik Nov 28, 2023
2eb7d88
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Nov 28, 2023
d8d92d6
adding back in require_all_var_t
syclik Nov 28, 2023
3291285
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Nov 28, 2023
a922690
adding back in require_any_not_var_t
syclik Nov 28, 2023
8d103bc
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Nov 28, 2023
5f3a7f2
adding back in some requires traits
syclik Nov 29, 2023
e336f40
removing tmp files
syclik Nov 29, 2023
43dbed7
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Nov 29, 2023
1f37599
adding back in some requires traits
syclik Dec 3, 2023
63baa5f
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Dec 3, 2023
032b135
adding back in a require trait that is used by Stan
syclik Dec 15, 2023
2e1804a
Merge commit 'c491e9b591d1c7fdc5176844c086ade0b13f2466' into HEAD
yashikno Dec 15, 2023
b6967ab
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Dec 15, 2023
7220894
adding back in requires trait
syclik Dec 16, 2023
4a8972e
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Dec 16, 2023
2b10934
added dirichlet_multinomial files and updated prob.hpp
chvandorp Nov 26, 2023
3a66d6c
correction in documentation for dirichlet_multinomial_lpmf
chvandorp Nov 27, 2023
ac7c2d2
added unit test. equivalence of BetaBinom and DirMult when K=2
chvandorp Nov 28, 2023
f4d88cf
cleaned up tests, added cases for lmpf test
chvandorp Nov 28, 2023
82070da
used clang-format to properly format the added files
chvandorp Nov 29, 2023
858057c
added AD test for dirichlet_multinomial_lpmf
chvandorp Dec 5, 2023
24221f4
Update vectorised handling, add analytical gradients
andrjohns Dec 13, 2023
7d7f4dc
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Dec 13, 2023
40151ac
style changes, removed _log file, optimized lpmf
chvandorp Dec 16, 2023
c9df636
Retry headers check and threading tests in case of failure. (#2982)
serban-nicusor-toptal Dec 17, 2023
32b814f
Bump actions/upload-artifact from 3 to 4
dependabot[bot] Dec 18, 2023
e5db7cb
Fix usages of fabs in check_symmetric with llvm17
WardBrian Dec 20, 2023
1ab9bc1
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Dec 20, 2023
eb7c393
removing STAN_ADD_REQUIRE_UNARY macro
syclik Jan 3, 2024
6a00303
removing STAN_ADD_REQUIRE_UNARY_INNER macro
syclik Jan 3, 2024
06763a3
removing STAN_ADD_REQUIRE_BINARY macro
syclik Jan 3, 2024
f83fa6a
removing STAN_ADD_REQUIRE_BINARY_INNER macro
syclik Jan 3, 2024
51c1a39
removing STAN_ADD_REQUIRE_CONTAINER macro
syclik Jan 3, 2024
62533fc
Merge commit 'ae90c3edca5d3b5e5234fdd6cbd1146f1666761d' into HEAD
yashikno Jan 3, 2024
61389e7
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jan 3, 2024
4b19a97
Merge branch 'develop' into feature/simplify-meta
syclik Jan 11, 2024
58cab78
Merge branch 'develop' into feature/simplify-meta
syclik Jan 17, 2024
469f687
Merge branch 'develop' into feature/simplify-meta
syclik Jan 18, 2024
d10a379
updating shebang in python testing scripts to allow for direct execution
syclik Jan 18, 2024
c6ebb2f
correct makefile documentation (within the makefile). We no longer ne…
syclik Jan 18, 2024
ac8a645
updating shebang in python testing scripts to allow for direct execution
syclik Jan 18, 2024
af48cb6
updating shebang in more python scripts
syclik Jan 18, 2024
37d7799
adding checks for cholesky factors; we found problems with user-facin…
syclik Jan 13, 2024
8cd890f
Update wishart_cholesky_rng_test.cpp
spinkney Jan 17, 2024
44920e1
updating test; test was incorrect. It passed in a non-cholesky factor…
syclik Jan 17, 2024
9024040
passing expression tests
syclik Jan 19, 2024
232fd33
passing expression tests
syclik Jan 20, 2024
1f8f3be
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jan 20, 2024
436b48e
release/v4.8.1: updating version numbers
Jan 23, 2024
8de3538
upgrading to boost v1.84.0; removing old boost library
andrjohns Jan 11, 2024
a123652
upgrading to boost v1.84.0; modifying with new version number
andrjohns Jan 11, 2024
07aed11
upgrading to boost v1.84.0; adding unmodified boost library
andrjohns Jan 11, 2024
62fb5de
upgrading to boost v1.84.0; pruning files
andrjohns Jan 11, 2024
f33fd3c
ibeta throw behaviour changed
andrjohns Jan 11, 2024
7ad7377
inv_inc_beta throw behaviour changed
andrjohns Jan 12, 2024
e4f5889
Fix exception in inv_wishart_cholesky test
WardBrian Jan 25, 2024
c1c2960
Re-add missing checks, revert test changes from #3007
WardBrian Jan 26, 2024
16bd832
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jan 26, 2024
af90916
Ensure pointer is 8-byte aligned in stack_alloc::alloc
WardBrian Jan 26, 2024
2576d9e
Update stack_alloc_test
WardBrian Jan 26, 2024
5a534bf
Update doc
WardBrian Jan 26, 2024
9fe464c
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jan 26, 2024
6741f9d
CVODES exceptions converted to domain_error
WardBrian Jan 25, 2024
8939593
Change test
WardBrian Jan 26, 2024
4140057
Use bessel identity to improve grad calc
andrjohns Jan 20, 2024
9aa7975
Update von mises test to use AD framework
andrjohns Jan 20, 2024
4c7c9f8
Patch TBB makefile, add testing workflow
andrjohns Jan 8, 2024
8c6fe65
Remove interim testing workflow
andrjohns Jan 8, 2024
1805449
Document changes
andrjohns Jan 8, 2024
80841b1
Remove additional stray usage
andrjohns Jan 8, 2024
fbc8f84
Move shell setting to makefile
andrjohns Jan 9, 2024
34fc8dd
Using rtools check
andrjohns Jan 9, 2024
1bbec87
mingw32-make compatible override
andrjohns Jan 9, 2024
986c8d8
Update notes
andrjohns Jan 9, 2024
e881b01
Alt sh check
andrjohns Jan 9, 2024
ca70c6e
Remove new unused boost libs, add to boost update script
WardBrian Jan 31, 2024
7a77bcf
Silence unused variable warning in Boost
WardBrian Jan 31, 2024
cba756e
Ensure workdir is clean after step, cat make/local before running run…
Feb 2, 2024
1fa5eb5
Change return type of linspaced_array
WardBrian Feb 6, 2024
9b19654
Update linspaced_array_test to actually test doubles
WardBrian Feb 6, 2024
93cc98e
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Feb 6, 2024
facb259
Fix copy/paste error in tests
WardBrian Feb 6, 2024
1800520
adding doc from @SteveBronder in the PR comments (with code formatting)
syclik Feb 10, 2024
7efb6ae
updating require_meta.md doc
syclik Feb 23, 2024
ca66d39
Merge branch 'develop' into feature/simplify-meta
syclik Feb 23, 2024
a8bb63e
adding code doc from @SteveBronder in the PR comments
syclik Feb 24, 2024
7f9e657
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Feb 24, 2024
4498a87
Merge branch 'develop' into feature/simplify-meta
syclik Mar 20, 2024
cc417ed
updating doxygen documentation about require traits
syclik Mar 24, 2024
cf4fd5e
Merge branch 'develop' into feature/simplify-meta
syclik Mar 24, 2024
7831559
adding require_eigen_matrix_base_t
syclik Mar 24, 2024
8efc7cf
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Mar 24, 2024
62ff9ae
adding require_not_assignable
syclik Mar 24, 2024
aaea3d8
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Mar 24, 2024
182cc29
Update doxygen/contributor_help_pages/require_meta.md
syclik Apr 2, 2024
0f77d06
Apply suggestions from code review
syclik Apr 2, 2024
a1d05d9
fixing meta doc
syclik Apr 2, 2024
b9309e7
updating doc
syclik Apr 2, 2024
2d1cb20
Update doxygen/contributor_help_pages/require_meta.md
syclik Apr 12, 2024
a2a19dc
Update doxygen/contributor_help_pages/require_meta.md
syclik Apr 12, 2024
dd75ad7
updating doc with edits from Steve Bronder
syclik Apr 12, 2024
66b92b5
updating doc
syclik Apr 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 97 additions & 44 deletions doxygen/contributor_help_pages/require_meta.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,100 @@ than overloaded functions for a number of reasons including the sheer
number of implementations we would need to write to handle the
combinations of arguments that are allowed in the Stan language.

In the Stan Math library, all the primary function templates are
declared in `stan/math/prim/`. The role of the primary function
template is to define a generic implementation for all valid argument
types. The definition of the function often restricts the valid
argument types through [substitution failure is not an error
(SFINAE)](https://en.cppreference.com/w/cpp/language/sfinae).

For many functions, we write specializations of the function
templates, usually for readability of code and computationaly
efficiency. To take advantage of generic template types while
limiting the implementation to a subset of valid types, we use
[partial template
specialization](https://en.cppreference.com/w/cpp/language/partial_specialization)
and specifically [SFINAE in partial
specialization](https://en.cppreference.com/w/cpp/language/sfinae#SFINAE_in_partial_specializations)
to enable this behavior. The source code for function specializations are
found in either `stan/math/rev/` for reverse-mode implementations,
`stan/math/fwd/` for forward-mode implementations, or
`stan/math/mix/` for implementations that are for nested
autodiff.

In the partial template specializations, we include a `requires`
template parameter as a pointer [non-type template
Many functions in the Stan Math library have a single function
template defined in the `stan/math/prim` folder that is flexible
enough to accept both primitive and autodiff types. Some of these
functions also have template specializations (usually [partial
template
specializations](https://en.cppreference.com/w/cpp/language/partial_specialization))
that define an implementation where at least one template parameters
is restricted to a specific type. The source code for the function
template specializations are found in either `stan/math/rev/` for
reverse-mode implementations, `stan/math/fwd/` for forward-mode
implementations, or `stan/math/mix/` for implementations that are for
nested autodiff. This pattern of a primary template function
definition with specialization is commonly used in templated C++.

In the Stan Math library, we have also adopted another technique which
allows multiple template function definitions, while restricting the
definition to apply only to when certain criteria are met. Since this
technique is used repeatedly through the Math library and this is not a
common use of template metaprogramming, we'll describe it in the next
subsection.

### Using SFINAE to allow multiple template function definitions

In the Stan Math library, each function exposed through to the Stan
language must have definitions that allow for both primitive and
autodiff types. As the language has grown, we have also added
broadcasting, which allows users to mix scalars arguments with vector
or array arguments.

The typical C++ method of defining a primary function template and a
set of function template specialization is untenable for many
functions in the Math library. For example, a single argument of the
function may take 6 distinct C++ types: `double`, `stan::math::var`,
`std::vector<double>`, `std::vector<stan::math::var>`,
`Eigen::Matrix<double, -1, 1>`, or `Eigen::Matrix<stan::math::var, -1,
1>`. For a 3-argument function, we would need to define 108 different
Comment thread
syclik marked this conversation as resolved.
Outdated
Comment thread
syclik marked this conversation as resolved.
Outdated
function template specializations to handle all the autodiff types.

In the Math library, we use a technique that allows the definition of
multiple template functions where each handles a subset of allowable
types. We add a pointer [non-type template
parameter](https://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter)
with a default value of `nullptr`; any `void*` non-template parameter
with a default of `nullptr` is ignored by the compiler. When we pass a
type that satisfies the `requires`, the `requires` trait evaluates to
`void`, the template parameter evaluates to `void*=nullptr`, and the
template argument is safely ignored by the compiler. When a type that
does not satisfy the `requires` template parameter is passed, the
definition is removed from the set of possible functions via
SFINAE. With this scheme we end up having a very nice pattern for
writing generic templates for functions while also being able to
restrict the set of types that a function can be used for.

For convenience in writing partial template specializations, we have
to the template parameter list with a default value of `nullptr`. Any
`void*` non-type template parameter with a default of `nullptr` is
valid and the non-type template parameter is ignored by the
compiler. Utilizing [substitution failure is not an error
(SFNIAE)](https://en.cppreference.com/w/cpp/language/sfinae), a
substitution failure for the non-type template parameter will result
in that definition being removed from the possible function
definitions. Using this technique we have to be careful not to violate
the [One Definition
Rule](https://en.cppreference.com/w/cpp/language/definition) and only
provide one definition for any set of types.

For convenience in using this technique, the Math library has
implemented a set of [`requires` type traits](@ref require_meta).
When we pass a type that satisfies the `requires` type trait, the
trait evaluates to `void`. When a type that does not satisfy the
`requires` template parameter is passed, there is a substitution
failure. These traits are used in the template functions by adding a
call to a `requires` type trait to the parameter list.

Below is an example to illustrate how this technique is used. After
the example, the rest of this page describes what the requires type
traits are, how to use them, and how to add new ones if necessary.

#### Example

Here's a function that would have two different template functions for
`stan::math::var` and `double`:

```
Comment thread
syclik marked this conversation as resolved.
Outdated
template <typename T, requires_var_t<T>* = nullptr>
T foo(T& t) {
// handles stan::math::var
return t;
}

template <typename T, requires_not_var_t<T>* = nullptr>
T foo(T& t) {
// handles primitives
return t;
}
Comment thread
syclik marked this conversation as resolved.
Outdated
```

When `foo()` is called with a `stan::math::var`, the first template
function matches but not the second. This works because
`requires_var_t<stan::math::var>` evaluates to `void` whereas
`requires_not_var_t<stan::math::var>` is a subsitution error causing
the compiler to omit the second definition for `stan::math::var`.

When `foo()` is called with `double` or `int`, the second template
function matches, but not the first.

The rest of this page describes what the requires type traits are, how
to use them, and how to add new ones if necessary.

### Requires<> type traits

Expand All @@ -61,12 +115,11 @@ are named `is_{condition}` and the struct contains a `value` that is
`true` or `false` at compile time. For example, `is_var<T>::value` is
`true` if and only if the type `T` is `stan::math::var_value`.

For ease of use in partial template specialization, we provide
`requires<>` type traits based on the boolean `is_{condition}` type
traits. When types satisfy the condition, the `requires<>::value` will
evaluate to `void`. When the types do not satisfy the condition,
`requires<>::value` is an invalid subsitution and is not used. (See
@ref requires_impl for more details.)
We provide `requires<>` type traits based on the boolean
`is_{condition}` type traits. When types satisfy the condition, the
`requires<>::value` will evaluate to `void`. When the types do not
satisfy the condition, `requires<>::value` is an invalid subsitution
Comment thread
syclik marked this conversation as resolved.
Outdated
and is not used. (See @ref requires_impl for more details.)

Note: every possible requires<> type trait is not implemented in the
Stan Math library. If one of the missing requires<> type trait is
Expand Down Expand Up @@ -272,7 +325,7 @@ available.
### Adding a new boolean type trait

If you are adding a new boolean type trait, please add the primary
template function to `stan/math/prim/meta/`, then add any autodiff
function template to `stan/math/prim/meta/`, then add any autodiff
specialization to the appropriate `stan/math/{rev, fwd, mix}/meta/`
folder.

Expand Down