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

Add perfect forwarding and constexpr to reverse mode functions #3092

Open
wants to merge 33 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f164443
adds perfect forwarding and uses constexpr in functions
SteveBronder Jul 11, 2024
d70fb0f
fix return for eigenvector_sym
SteveBronder Jul 11, 2024
f08c711
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 12, 2024
ddea3c0
fix bad formatting for clang-format
SteveBronder Jul 15, 2024
d98f4f0
Merge commit '9052db82c3fafce144c355c757a9b7e44b884b66' into HEAD
yashikno Jul 15, 2024
3012408
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 15, 2024
af37cbc
clean up type traits to change \!is_constant with is_autodiffable
SteveBronder Jul 15, 2024
5152942
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 15, 2024
888e2cc
force c++17
SteveBronder Jul 15, 2024
9887597
Merge remote-tracking branch 'refs/remotes/origin/feature/pf-funcs-co…
SteveBronder Jul 15, 2024
d4ebc3d
remove unused type alias
SteveBronder Jul 15, 2024
d7350f2
add check_vari_on_stack for arena matrix
SteveBronder Jul 15, 2024
a54fb01
update type traits for fft, square_dist, and trace funcs
SteveBronder Jul 15, 2024
bf36144
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 15, 2024
5d989a2
adds test framework for cleaning memory after autodiff calls
SteveBronder Jul 16, 2024
fdb5d03
update forward for ref in quad_form_sym
SteveBronder Jul 16, 2024
be242f0
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 16, 2024
aea8afa
Merge remote-tracking branch 'origin/develop' into feature/pf-funcs-c…
SteveBronder Jul 17, 2024
d5bcc83
update wrt review comments
SteveBronder Jul 17, 2024
a3f3cd8
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 17, 2024
c3d8136
update columns dot product for complex types
SteveBronder Jul 18, 2024
ab679fe
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 18, 2024
ad456a1
update columns_dot_product
SteveBronder Jul 18, 2024
bc96704
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 18, 2024
d1fc936
update
SteveBronder Jul 19, 2024
5c8bd28
Merge remote-tracking branch 'refs/remotes/origin/feature/pf-funcs-co…
SteveBronder Jul 19, 2024
17ffd02
start working on the constrain functions
SteveBronder Jul 19, 2024
506fe50
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot Jul 19, 2024
c4c7605
fix move semantics in unit_vector_constrain
SteveBronder Jul 22, 2024
82fc4f6
update ordered constrain
SteveBronder Jul 23, 2024
c826d98
fix use of x after forwarding in ordered_constrain
SteveBronder Jul 25, 2024
d5de333
update
SteveBronder Jul 29, 2024
855546a
Merge remote-tracking branch 'origin/develop' into feature/pf-funcs-c…
SteveBronder Jul 29, 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
28 changes: 2 additions & 26 deletions make/compiler_flags
Original file line number Diff line number Diff line change
Expand Up @@ -120,32 +120,8 @@ INC_GTEST ?= -I $(GTEST)/include -I $(GTEST)
CPPFLAGS_BOOST ?= -DBOOST_DISABLE_ASSERTS
CPPFLAGS_SUNDIALS ?= -DNO_FPRINTF_OUTPUT $(CPPFLAGS_OPTIM_SUNDIALS) $(CXXFLAGS_FLTO_SUNDIALS)
#CPPFLAGS_GTEST ?=
STAN_HAS_CXX17 ?= false
ifeq ($(CXX_TYPE), gcc)
GCC_GE_73 := $(shell [ $(CXX_MAJOR) -gt 7 -o \( $(CXX_MAJOR) -eq 7 -a $(CXX_MINOR) -ge 1 \) ] && echo true)
ifeq ($(GCC_GE_73),true)
STAN_HAS_CXX17 := true
endif
else ifeq ($(CXX_TYPE), clang)
CLANG_GE_5 := $(shell [ $(CXX_MAJOR) -gt 5 -o \( $(CXX_MAJOR) -eq 5 -a $(CXX_MINOR) -ge 0 \) ] && echo true)
ifeq ($(CLANG_GE_5),true)
STAN_HAS_CXX17 := true
endif
else ifeq ($(CXX_TYPE), mingw32-gcc)
MINGW_GE_50 := $(shell [ $(CXX_MAJOR) -gt 5 -o \( $(CXX_MAJOR) -eq 5 -a $(CXX_MINOR) -ge 0 \) ] && echo true)
ifeq ($(MINGW_GE_50),true)
STAN_HAS_CXX17 := true
endif
endif

ifeq ($(STAN_HAS_CXX17), true)
CXXFLAGS_LANG ?= -std=c++17
CXXFLAGS_STANDARD ?= c++17
else
$(warning "Stan cannot detect if your compiler has the C++17 standard. If it does, please set STAN_HAS_CXX17=true in your make/local file. C++17 support is mandatory in the next release of Stan. Defaulting to C++14")
CXXFLAGS_LANG ?= -std=c++1y
CXXFLAGS_STANDARD ?= c++1y
endif
CXXFLAGS_LANG ?= -std=c++17
CXXFLAGS_STANDARD ?= c++17
#CXXFLAGS_BOOST ?=
CXXFLAGS_SUNDIALS ?= -pipe $(CXXFLAGS_OPTIM_SUNDIALS) $(CPPFLAGS_FLTO_SUNDIALS)
#CXXFLAGS_GTEST
Expand Down
62 changes: 44 additions & 18 deletions stan/math/prim/constraint/lb_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,16 @@ inline auto lb_constrain(const T& x, const L& lb, return_type_t<T, L>& lp) {
* @param[in] lb lower bound on output
* @return lower-bound constrained value corresponding to inputs
*/
template <typename T, typename L, require_not_std_vector_t<L>* = nullptr>
inline auto lb_constrain(const std::vector<T>& x, const L& lb) {
template <typename T, typename L, require_std_vector_t<T>* = nullptr,
require_not_std_vector_t<L>* = nullptr>
inline auto lb_constrain(T&& x, L&& lb) {
std::vector<plain_type_t<decltype(lb_constrain(x[0], lb))>> ret(x.size());
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = lb_constrain(x[i], lb);
if constexpr (std::is_rvalue_reference_v<T&&>) {
ret[i] = lb_constrain(std::move(x[i]), lb);
} else {
ret[i] = lb_constrain(x[i], lb);
}
}
return ret;
}
Expand All @@ -169,12 +174,16 @@ inline auto lb_constrain(const std::vector<T>& x, const L& lb) {
* @param[in,out] lp reference to log probability to increment
* @return lower-bound constrained value corresponding to inputs
*/
template <typename T, typename L, require_not_std_vector_t<L>* = nullptr>
inline auto lb_constrain(const std::vector<T>& x, const L& lb,
return_type_t<T, L>& lp) {
template <typename T, typename L, require_std_vector_t<T>* = nullptr,
require_not_std_vector_t<L>* = nullptr>
inline auto lb_constrain(T&& x, L&& lb, return_type_t<T, L>& lp) {
std::vector<plain_type_t<decltype(lb_constrain(x[0], lb))>> ret(x.size());
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = lb_constrain(x[i], lb, lp);
if constexpr (std::is_rvalue_reference_v<T&&>) {
ret[i] = lb_constrain(std::move(x[i]), lb, lp);
} else {
ret[i] = lb_constrain(x[i], lb, lp);
}
}
return ret;
}
Expand All @@ -189,12 +198,21 @@ inline auto lb_constrain(const std::vector<T>& x, const L& lb,
* @param[in] lb lower bound on output
* @return lower-bound constrained value corresponding to inputs
*/
template <typename T, typename L>
inline auto lb_constrain(const std::vector<T>& x, const std::vector<L>& lb) {
template <typename T, typename L, require_all_std_vector_t<T, L>* = nullptr>
inline auto lb_constrain(T&& x, L&& lb) {
check_matching_dims("lb_constrain", "x", x, "lb", lb);
std::vector<plain_type_t<decltype(lb_constrain(x[0], lb[0]))>> ret(x.size());
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = lb_constrain(x[i], lb[i]);
if constexpr (std::is_rvalue_reference_v<
T&&> && std::is_rvalue_reference_v<L&&>) {
ret[i] = lb_constrain(std::move(x[i]), std::move(lb[i]));
} else if constexpr (std::is_rvalue_reference_v<T&&>) {
ret[i] = lb_constrain(std::move(x[i]), lb[i]);
} else if constexpr (std::is_rvalue_reference_v<L&&>) {
ret[i] = lb_constrain(x[i], std::move(lb[i]));
} else {
ret[i] = lb_constrain(x[i], lb[i]);
}
}
return ret;
}
Expand All @@ -210,13 +228,21 @@ inline auto lb_constrain(const std::vector<T>& x, const std::vector<L>& lb) {
* @param[in,out] lp reference to log probability to increment
* @return lower-bound constrained value corresponding to inputs
*/
template <typename T, typename L>
inline auto lb_constrain(const std::vector<T>& x, const std::vector<L>& lb,
return_type_t<T, L>& lp) {
template <typename T, typename L, require_all_std_vector_t<T, L>* = nullptr>
inline auto lb_constrain(T&& x, L&& lb, return_type_t<T, L>& lp) {
check_matching_dims("lb_constrain", "x", x, "lb", lb);
std::vector<plain_type_t<decltype(lb_constrain(x[0], lb[0]))>> ret(x.size());
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = lb_constrain(x[i], lb[i], lp);
if constexpr (std::is_rvalue_reference_v<
T&&> && std::is_rvalue_reference_v<L&&>) {
ret[i] = lb_constrain(std::move(x[i]), std::move(lb[i]), lp);
} else if constexpr (std::is_rvalue_reference_v<T&&>) {
ret[i] = lb_constrain(std::move(x[i]), lb[i], lp);
} else if constexpr (std::is_rvalue_reference_v<L&&>) {
ret[i] = lb_constrain(x[i], std::move(lb[i]), lp);
} else {
ret[i] = lb_constrain(x[i], lb[i], lp);
}
}
return ret;
}
Expand All @@ -240,11 +266,11 @@ inline auto lb_constrain(const std::vector<T>& x, const std::vector<L>& lb,
* @return lower-bound constrained value corresponding to inputs
*/
template <bool Jacobian, typename T, typename L>
inline auto lb_constrain(const T& x, const L& lb, return_type_t<T, L>& lp) {
if (Jacobian) {
return lb_constrain(x, lb, lp);
inline auto lb_constrain(T&& x, L&& lb, return_type_t<T, L>& lp) {
if constexpr (Jacobian) {
return lb_constrain(std::forward<T>(x), std::forward<L>(lb), lp);
} else {
return lb_constrain(x, lb);
return lb_constrain(std::forward<T>(x), std::forward<L>(lb));
}
}

Expand Down
25 changes: 13 additions & 12 deletions stan/math/prim/constraint/ordered_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ inline plain_type_t<EigVec> ordered_constrain(const EigVec& x) {
* @return Positive, increasing ordered vector.
*/
template <typename EigVec, require_eigen_col_vector_t<EigVec>* = nullptr>
inline auto ordered_constrain(const EigVec& x, value_type_t<EigVec>& lp) {
const auto& x_ref = to_ref(x);
if (likely(x.size() > 1)) {
lp += sum(x_ref.tail(x.size() - 1));
inline auto ordered_constrain(EigVec&& x, value_type_t<EigVec>& lp) {
auto&& x_ref = to_ref(std::forward<EigVec>(x));
if (likely(x_ref.size() > 1)) {
lp += sum(x_ref.tail(x_ref.size() - 1));
}
return ordered_constrain(x_ref);
return ordered_constrain(std::forward<decltype(x_ref)>(x_ref));
}

/**
Expand All @@ -78,11 +78,11 @@ inline auto ordered_constrain(const EigVec& x, value_type_t<EigVec>& lp) {
* @return Positive, increasing ordered vector.
*/
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto ordered_constrain(const T& x, return_type_t<T>& lp) {
if (Jacobian) {
return ordered_constrain(x, lp);
inline auto ordered_constrain(T&& x, return_type_t<T>& lp) {
if constexpr (Jacobian) {
return ordered_constrain(std::forward<T>(x), lp);
} else {
return ordered_constrain(x);
return ordered_constrain(std::forward<T>(x));
}
}

Expand All @@ -105,9 +105,10 @@ inline auto ordered_constrain(const T& x, return_type_t<T>& lp) {
* @return Positive, increasing ordered vector.
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto ordered_constrain(const T& x, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(
x, [&lp](auto&& v) { return ordered_constrain<Jacobian>(v, lp); });
inline auto ordered_constrain(T&& x, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(std::forward<T>(x), [&lp](auto&& v) {
return ordered_constrain<Jacobian>(std::forward<decltype(v)>(v), lp);
});
}

} // namespace math
Expand Down
16 changes: 8 additions & 8 deletions stan/math/prim/constraint/simplex_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,11 @@ inline plain_type_t<Vec> simplex_constrain(const Vec& y,
* @return simplex of dimensionality one greater than `y`
*/
template <bool Jacobian, typename Vec, require_not_std_vector_t<Vec>* = nullptr>
inline plain_type_t<Vec> simplex_constrain(const Vec& y,
return_type_t<Vec>& lp) {
if (Jacobian) {
return simplex_constrain(y, lp);
inline auto simplex_constrain(Vec&& y, return_type_t<Vec>& lp) {
if constexpr (Jacobian) {
return simplex_constrain(std::forward<Vec>(y), lp);
} else {
return simplex_constrain(y);
return simplex_constrain(std::forward<Vec>(y));
}
}

Expand All @@ -125,9 +124,10 @@ inline plain_type_t<Vec> simplex_constrain(const Vec& y,
* @return simplex of dimensionality one greater than `y`
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto simplex_constrain(const T& y, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(
y, [&lp](auto&& v) { return simplex_constrain<Jacobian>(v, lp); });
inline auto simplex_constrain(T&& y, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(std::forward<T>(y), [&lp](auto&& v) {
return simplex_constrain<Jacobian>(std::forward<decltype(v)>(v), lp);
});
}

} // namespace math
Expand Down
62 changes: 44 additions & 18 deletions stan/math/prim/constraint/ub_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,16 @@ inline auto ub_constrain(const T& x, const U& ub,
* @param[in] ub upper bound on output
* @return lower-bound constrained value corresponding to inputs
*/
template <typename T, typename U, require_not_std_vector_t<U>* = nullptr>
inline auto ub_constrain(const std::vector<T>& x, const U& ub) {
template <typename T, typename U, require_std_vector_t<T>* = nullptr,
require_not_std_vector_t<U>* = nullptr>
inline auto ub_constrain(T&& x, const U& ub) {
std::vector<plain_type_t<decltype(ub_constrain(x[0], ub))>> ret(x.size());
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = ub_constrain(x[i], ub);
if constexpr (std::is_rvalue_reference_v<T&&>) {
ret[i] = ub_constrain(std::move(x[i]), ub);
} else {
ret[i] = ub_constrain(x[i], ub);
}
}
return ret;
}
Expand All @@ -179,12 +184,16 @@ inline auto ub_constrain(const std::vector<T>& x, const U& ub) {
* @param[in,out] lp reference to log probability to increment
* @return lower-bound constrained value corresponding to inputs
*/
template <typename T, typename U, require_not_std_vector_t<U>* = nullptr>
inline auto ub_constrain(const std::vector<T>& x, const U& ub,
return_type_t<T, U>& lp) {
template <typename T, typename U, require_std_vector_t<T>* = nullptr,
require_not_std_vector_t<U>* = nullptr>
inline auto ub_constrain(T&& x, const U& ub, return_type_t<T, U>& lp) {
std::vector<plain_type_t<decltype(ub_constrain(x[0], ub))>> ret(x.size());
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = ub_constrain(x[i], ub, lp);
if constexpr (std::is_rvalue_reference_v<T&&>) {
ret[i] = ub_constrain(std::move(x[i]), ub, lp);
} else {
ret[i] = ub_constrain(x[i], ub, lp);
}
}
return ret;
}
Expand All @@ -199,12 +208,21 @@ inline auto ub_constrain(const std::vector<T>& x, const U& ub,
* @param[in] ub upper bound on output
* @return lower-bound constrained value corresponding to inputs
*/
template <typename T, typename U>
inline auto ub_constrain(const std::vector<T>& x, const std::vector<U>& ub) {
template <typename T, typename U, require_all_std_vector_t<T, U>* = nullptr>
inline auto ub_constrain(T&& x, U&& ub) {
check_matching_dims("ub_constrain", "x", x, "ub", ub);
std::vector<plain_type_t<decltype(ub_constrain(x[0], ub[0]))>> ret(x.size());
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = ub_constrain(x[i], ub[i]);
if constexpr (std::is_rvalue_reference_v<
T&&> && std::is_rvalue_reference_v<U&&>) {
ret[i] = ub_constrain(std::move(x[i]), std::move(ub[i]));
} else if constexpr (std::is_rvalue_reference_v<T&&>) {
ret[i] = ub_constrain(std::move(x[i]), ub[i]);
} else if constexpr (std::is_rvalue_reference_v<U&&>) {
ret[i] = ub_constrain(x[i], std::move(ub[i]));
} else {
ret[i] = ub_constrain(x[i], ub[i]);
}
}
return ret;
}
Expand All @@ -220,13 +238,21 @@ inline auto ub_constrain(const std::vector<T>& x, const std::vector<U>& ub) {
* @param[in,out] lp reference to log probability to increment
* @return lower-bound constrained value corresponding to inputs
*/
template <typename T, typename U>
inline auto ub_constrain(const std::vector<T>& x, const std::vector<U>& ub,
return_type_t<T, U>& lp) {
template <typename T, typename U, require_all_std_vector_t<T, U>* = nullptr>
inline auto ub_constrain(T&& x, U&& ub, return_type_t<T, U>& lp) {
check_matching_dims("ub_constrain", "x", x, "ub", ub);
std::vector<plain_type_t<decltype(ub_constrain(x[0], ub[0]))>> ret(x.size());
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = ub_constrain(x[i], ub[i], lp);
if constexpr (std::is_rvalue_reference_v<
T&&> && std::is_rvalue_reference_v<U&&>) {
ret[i] = ub_constrain(std::move(x[i]), std::move(ub[i]), lp);
} else if constexpr (std::is_rvalue_reference_v<T&&>) {
ret[i] = ub_constrain(std::move(x[i]), ub[i], lp);
} else if constexpr (std::is_rvalue_reference_v<U&&>) {
ret[i] = ub_constrain(x[i], std::move(ub[i]), lp);
} else {
ret[i] = ub_constrain(x[i], ub[i], lp);
}
}
return ret;
}
Expand All @@ -250,11 +276,11 @@ inline auto ub_constrain(const std::vector<T>& x, const std::vector<U>& ub,
* @return lower-bound constrained value corresponding to inputs
*/
template <bool Jacobian, typename T, typename U>
inline auto ub_constrain(const T& x, const U& ub, return_type_t<T, U>& lp) {
if (Jacobian) {
return ub_constrain(x, ub, lp);
inline auto ub_constrain(T&& x, U&& ub, return_type_t<T, U>& lp) {
if constexpr (Jacobian) {
return ub_constrain(std::forward<T>(x), std::forward<U>(ub), lp);
} else {
return ub_constrain(x, ub);
return ub_constrain(std::forward<T>(x), std::forward<U>(ub));
}
}

Expand Down
15 changes: 8 additions & 7 deletions stan/math/prim/constraint/unit_vector_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ inline plain_type_t<T1> unit_vector_constrain(const T1& y, T2& lp) {
* @return Unit length vector of dimension K
*/
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto unit_vector_constrain(const T& y, return_type_t<T>& lp) {
if (Jacobian) {
return unit_vector_constrain(y, lp);
inline auto unit_vector_constrain(T&& y, return_type_t<T>& lp) {
if constexpr (Jacobian) {
return unit_vector_constrain(std::forward<T>(y), lp);
} else {
return unit_vector_constrain(y);
return unit_vector_constrain(std::forward<T>(y));
}
}

Expand All @@ -98,9 +98,10 @@ inline auto unit_vector_constrain(const T& y, return_type_t<T>& lp) {
* @return Unit length vector of dimension K
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto unit_vector_constrain(const T& y, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(
y, [&lp](auto&& v) { return unit_vector_constrain<Jacobian>(v, lp); });
inline auto unit_vector_constrain(T&& y, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(std::forward<T>(y), [&lp](auto&& v) {
return unit_vector_constrain<Jacobian>(std::forward<decltype(v)>(v), lp);
});
}

} // namespace math
Expand Down
6 changes: 3 additions & 3 deletions stan/math/prim/fun/grad_reg_inc_gamma.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ namespace math {
(a-1)_k\right) \frac{1}{z^k} \end{array} \f]
*/
template <typename T1, typename T2>
return_type_t<T1, T2> grad_reg_inc_gamma(T1 a, T2 z, T1 g, T1 dig,
double precision = 1e-6,
int max_steps = 1e5) {
inline return_type_t<T1, T2> grad_reg_inc_gamma(T1 a, T2 z, T1 g, T1 dig,
double precision = 1e-6,
int max_steps = 1e5) {
using std::exp;
using std::fabs;
using std::log;
Expand Down
8 changes: 8 additions & 0 deletions stan/math/prim/meta/is_autodiff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ struct is_autodiff
: bool_constant<math::disjunction<is_var<std::decay_t<T>>,
is_fvar<std::decay_t<T>>>::value> {};

template <typename... Types>
inline constexpr bool is_autodiff_v
= math::conjunction<is_autodiff<Types>...>::value;

template <typename... Types>
inline constexpr bool is_autodiffable_v
= math::conjunction<is_autodiff<scalar_type_t<Types>>...>::value;

Comment on lines +22 to +29
Copy link
Collaborator

Choose a reason for hiding this comment

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

These two typedefs seem to test the same thing. Also, shouldn't this be is_autodiff_all_v?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

These need better names. is_autodiff_v<> looks to see is the type is a fvar or var and fails otherwise. is_autodiffable_v looks into the scalar type of the type to see if it is autodiffable, so things like eigen matrices and vectors of var or fvar types would be true for is_autodiffable_v.

I left is_autodiff alone to not mess with the other functions that use it (mostly functions that use it in a requires). Maybe the current is_autodiff should be named is_autodiff_scalar?

/*! \ingroup require_stan_scalar_real */
/*! \defgroup autodiff_types autodiff */
/*! \addtogroup autodiff_types */
Expand Down
Loading