From f49dd02cd00018b7c6321735efe4ba373a3e10d6 Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Tue, 24 Mar 2020 16:45:23 -0400 Subject: [PATCH 01/11] Adds auxilary functions needed for reduce_sum --- stan/math/rev/core.hpp | 4 + stan/math/rev/core/accumulate_adjoints.hpp | 154 ++++++++ stan/math/rev/core/count_vars.hpp | 151 +++++++ stan/math/rev/core/deep_copy_vars.hpp | 87 ++++ stan/math/rev/core/save_varis.hpp | 150 +++++++ .../rev/core/accumulate_adjoints_test.cpp | 374 ++++++++++++++++++ test/unit/math/rev/core/count_vars_test.cpp | 157 ++++++++ .../math/rev/core/deep_copy_vars_test.cpp | 245 ++++++++++++ test/unit/math/rev/core/save_varis_test.cpp | 245 ++++++++++++ 9 files changed, 1567 insertions(+) create mode 100644 stan/math/rev/core/accumulate_adjoints.hpp create mode 100644 stan/math/rev/core/count_vars.hpp create mode 100644 stan/math/rev/core/deep_copy_vars.hpp create mode 100644 stan/math/rev/core/save_varis.hpp create mode 100644 test/unit/math/rev/core/accumulate_adjoints_test.cpp create mode 100644 test/unit/math/rev/core/count_vars_test.cpp create mode 100644 test/unit/math/rev/core/deep_copy_vars_test.cpp create mode 100644 test/unit/math/rev/core/save_varis_test.cpp diff --git a/stan/math/rev/core.hpp b/stan/math/rev/core.hpp index 5d3c91f423b..33eb934c08e 100644 --- a/stan/math/rev/core.hpp +++ b/stan/math/rev/core.hpp @@ -1,13 +1,16 @@ #ifndef STAN_MATH_REV_CORE_HPP #define STAN_MATH_REV_CORE_HPP +#include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -63,5 +66,6 @@ #include #include #include +#include #endif diff --git a/stan/math/rev/core/accumulate_adjoints.hpp b/stan/math/rev/core/accumulate_adjoints.hpp new file mode 100644 index 00000000000..98f0899119d --- /dev/null +++ b/stan/math/rev/core/accumulate_adjoints.hpp @@ -0,0 +1,154 @@ +#ifndef STAN_MATH_REV_CORE_ACCUMULATE_ADJOINTS_HPP +#define STAN_MATH_REV_CORE_ACCUMULATE_ADJOINTS_HPP + +#include +#include +#include + +#include +#include + +namespace stan { +namespace math { + +template +inline double* accumulate_adjoints(double* dest, const var& x, Pargs&&... args); + +template * = nullptr, + typename... Pargs> +inline double* accumulate_adjoints(double* dest, VarVec&& x, Pargs&&... args); + +template * = nullptr, + require_std_vector_vt* = nullptr, + typename... Pargs> +inline double* accumulate_adjoints(double* dest, VecContainer&& x, + Pargs&&... args); + +template * = nullptr, + typename... Pargs> +inline double* accumulate_adjoints(double* dest, EigT&& x, Pargs&&... args); + +template >* = nullptr, + typename... Pargs> +inline double* accumulate_adjoints(double* dest, Arith&& x, Pargs&&... args); + +inline double* accumulate_adjoints(double* dest); + +/** + * Accumulate adjoints from x into storage pointed to by dest, + * increment the adjoint storage pointer, + * recursively accumulate the adjoints of the rest of the arguments, + * and return final position of storage pointer. + * + * @tparam Pargs Types of remaining arguments + * @param dest Pointer to where adjoints are to be accumulated + * @param x A var + * @param args Further args to accumulate over + * @return Final position of adjoint storage pointer + */ +template +inline double* accumulate_adjoints(double* dest, const var& x, + Pargs&&... args) { + *dest += x.adj(); + return accumulate_adjoints(dest + 1, std::forward(args)...); +} + +/** + * Accumulate adjoints from std::vector x into storage pointed to by dest, + * increment the adjoint storage pointer, + * recursively accumulate the adjoints of the rest of the arguments, + * and return final position of storage pointer. + * + * @tparam Pargs Types of remaining arguments + * @param dest Pointer to where adjoints are to be accumulated + * @param x A std::vector of vars + * @param args Further args to accumulate over + * @return Final position of adjoint storage pointer + */ +template *, + typename... Pargs> +inline double* accumulate_adjoints(double* dest, VarVec&& x, Pargs&&... args) { + for (auto&& x_iter : x) { + *dest += x_iter.adj(); + ++dest; + } + return accumulate_adjoints(dest, std::forward(args)...); +} + +/** + * Accumulate adjoints from x (a std::vector of containers containing vars) + * into storage pointed to by dest, + * increment the adjoint storage pointer, + * recursively accumulate the adjoints of the rest of the arguments, + * and return final position of storage pointer. + * + * @tparam VecContainer the type of a standard container holding var + * containers. + * @tparam Pargs Types of remaining arguments + * @param dest Pointer to where adjoints are to be accumulated + * @param x A std::vector of containers holding vars + * @param args Further args to accumulate over + * @return Final position of adjoint storage pointer + */ +template *, + require_std_vector_vt*, typename... Pargs> +inline double* accumulate_adjoints(double* dest, VecContainer&& x, + Pargs&&... args) { + for (auto&& x_iter : x) { + dest = accumulate_adjoints(dest, x_iter); + } + return accumulate_adjoints(dest, std::forward(args)...); +} + +/** + * Accumulate adjoints from x (an Eigen type containing vars) + * into storage pointed to by dest, + * increment the adjoint storage pointer, + * recursively accumulate the adjoints of the rest of the arguments, + * and return final position of storage pointer. + * + * @tparam EigT Type derived from `EigenBase` containing vars. + * @tparam Pargs Types of remaining arguments + * @param dest Pointer to where adjoints are to be accumulated + * @param x An eigen type holding vars to accumulate over + * @param args Further args to accumulate over + * @return Final position of adjoint storage pointer + */ +template *, typename... Pargs> +inline double* accumulate_adjoints(double* dest, EigT&& x, Pargs&&... args) { + Eigen::Map(dest, x.rows(), x.cols()) += x.adj(); + return accumulate_adjoints(dest + x.size(), std::forward(args)...); +} + +/** + * Ignore arithmetic types. + * + * Recursively accumulate the adjoints of the rest of the arguments + * and return final position of adjoint storage pointer. + * + * @tparam Arith A type satisfying `std::is_arithmetic`. + * @tparam Pargs Types of remaining arguments + * @param dest Pointer to where adjoints are to be accumulated + * @param x An object that is either arithmetic or a container of Arithmetic + * types + * @param args Further args to accumulate over + * @return Final position of adjoint storage pointer + */ +template >*, + typename... Pargs> +inline double* accumulate_adjoints(double* dest, Arith&& x, Pargs&&... args) { + return accumulate_adjoints(dest, std::forward(args)...); +} + +/** + * End accumulate_adjoints recursion and return pointer + * + * @param dest Pointer + */ +inline double* accumulate_adjoints(double* dest) { return dest; } + +} // namespace math +} // namespace stan + +#endif diff --git a/stan/math/rev/core/count_vars.hpp b/stan/math/rev/core/count_vars.hpp new file mode 100644 index 00000000000..fbd7557bcf5 --- /dev/null +++ b/stan/math/rev/core/count_vars.hpp @@ -0,0 +1,151 @@ +#ifndef STAN_MATH_REV_CORE_COUNT_VARS_HPP +#define STAN_MATH_REV_CORE_COUNT_VARS_HPP + +#include +#include +#include + +#include +#include + +namespace stan { +namespace math { + +template * = nullptr, + typename... Pargs> +inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args); + +template * = nullptr, + require_std_vector_vt* = nullptr, + typename... Pargs> +inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args); + +template * = nullptr, + typename... Pargs> +inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args); + +template +inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args); + +template >* = nullptr, + typename... Pargs> +inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args); + +inline size_t count_vars_impl(size_t count); + +/** + * Count the number of vars in x (a std::vector of vars), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam VecVar type of standard container holding vars + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A std::vector holding vars. + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template *, + typename... Pargs> +inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args) { + return count_vars_impl(count + x.size(), std::forward(args)...); +} + +/** + * Count the number of vars in x (a std::vector holding other containers), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam VecContainer std::vector holding arguments which contain Vars + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A vector holding containers of vars + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template *, + require_std_vector_vt*, typename... Pargs> +inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args) { + for (auto&& x_iter : x) { + count = count_vars_impl(count, x_iter); + } + return count_vars_impl(count, std::forward(args)...); +} + +/** + * Count the number of vars in x (an eigen container), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam EigT A type derived from `EigenBase` + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x An Eigen container holding vars + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template *, typename... Pargs> +inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args) { + return count_vars_impl(count + x.size(), std::forward(args)...); +} + +/** + * Add one to the running total number of vars, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A var + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template +inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args) { + return count_vars_impl(count + 1, std::forward(args)...); +} + +/** + * Arguments without vars contribute zero to the total number of vars. + * + * Return the running total number of vars plus the number of + * vars in the remaining aruments. + * + * @tparam Arith An object that is either arithmetic or holds arithmetic + * types + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x An arithmetic value or container + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template >*, + typename... Pargs> +inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args) { + return count_vars_impl(count, std::forward(args)...); +} + +/** + * End count_vars_impl recursion and return total number of counted vars + */ +inline size_t count_vars_impl(size_t count) { return count; } + +/** + * Count the number of vars in the input argument list + * + * @tparam Pargs Types of input arguments + * @return Number of vars in input + */ +template +inline size_t count_vars(Pargs&&... args) { + return count_vars_impl(0, std::forward(args)...); +} + +} // namespace math +} // namespace stan + +#endif diff --git a/stan/math/rev/core/deep_copy_vars.hpp b/stan/math/rev/core/deep_copy_vars.hpp new file mode 100644 index 00000000000..5eb1b3d8542 --- /dev/null +++ b/stan/math/rev/core/deep_copy_vars.hpp @@ -0,0 +1,87 @@ +#ifndef STAN_MATH_REV_CORE_DEEP_COPY_VARS_HPP +#define STAN_MATH_REV_CORE_DEEP_COPY_VARS_HPP + +#include +#include +#include + +#include +#include + +namespace stan { +namespace math { + +/** + * Forward arguments that do not contain vars. There + * is no copying to be done. + * + * @tparam Arith an arithmetic type. + * @param arg For lvalue references this will be passed by reference. + * Otherwise it will be moved. + */ +template >> +inline decltype(auto) deep_copy_vars(Arith&& arg) { + return std::forward(arg); +} + +/** + * Copy the value of a var but reallocate a new vari + * + * @param arg A var + * @return A new var + */ +inline auto deep_copy_vars(const var& arg) { + return var(new vari(arg.val(), false)); +} + +/** + * Copy the vars in arg but reallocate new varis for them + * + * @tparam VarVec A variant of std::vector + * @param arg A std::vector of vars + * @return A new std::vector of vars + */ +template * = nullptr> +inline auto deep_copy_vars(VarVec&& arg) { + std::vector copy_vec(arg.size()); + for (size_t i = 0; i < arg.size(); ++i) { + copy_vec[i] = new vari(arg[i].val(), false); + } + return copy_vec; +} + +/** + * Copy the vars in arg but reallocate new varis for them + * + * @tparam VecContainer std::vector where T is another type containing vars + * @param arg A std::vector of containers containing vars + * @return A new std::vector of containers containing vars + */ +template * = nullptr, + require_std_vector_vt* = nullptr> +inline auto deep_copy_vars(VecContainer&& arg) { + std::vector> copy_vec(arg.size()); + for (size_t i = 0; i < arg.size(); ++i) { + copy_vec[i] = deep_copy_vars(arg[i]); + } + return copy_vec; +} + +/** + * Copy the vars in arg but reallocate new varis for them + * + * @tparam EigT An Eigen type with var value type + * @param arg An Eigen container of vars + * @return A new Eigen container of vars + */ +template * = nullptr> +inline auto deep_copy_vars(EigT&& arg) { + return arg.unaryExpr([](auto&& x) { return var(new vari(x.val(), false)); }) + .eval(); +} + +} // namespace math +} // namespace stan + +#endif diff --git a/stan/math/rev/core/save_varis.hpp b/stan/math/rev/core/save_varis.hpp new file mode 100644 index 00000000000..e118d534e98 --- /dev/null +++ b/stan/math/rev/core/save_varis.hpp @@ -0,0 +1,150 @@ +#ifndef STAN_MATH_REV_CORE_SAVE_VARIS_HPP +#define STAN_MATH_REV_CORE_SAVE_VARIS_HPP + +#include +#include +#include +#include + +#include +#include + +namespace stan { +namespace math { + +template +inline vari** save_varis(vari** dest, const var& x, Pargs&&... args); + +template * = nullptr, + typename... Pargs> +inline vari** save_varis(vari** dest, VarVec&& x, Pargs&&... args); + +template * = nullptr, + require_std_vector_vt* = nullptr, + typename... Pargs> +inline vari** save_varis(vari** dest, VecContainer&& x, Pargs&&... args); + +template * = nullptr, + typename... Pargs> +inline vari** save_varis(vari** dest, EigT&& x, Pargs&&... args); + +template >* = nullptr, + typename... Pargs> +inline vari** save_varis(vari** dest, Arith&& x, Pargs&&... args); + +inline vari** save_varis(vari** dest); + +/** + * Save the vari pointer in x into the memory pointed to by dest, + * increment the dest storage pointer, + * recursively call save_varis on the rest of the arguments, + * and return the final value of the dest storage pointer. + * + * @tparam Pargs Types of remaining arguments + * @param[in, out] dest Pointer to where vari pointers are saved + * @param[in] x A var + * @param[in] args Additional arguments to have their varis saved + * @return Final position of dest pointer + */ +template +inline vari** save_varis(vari** dest, const var& x, Pargs&&... args) { + *dest = x.vi_; + return save_varis(dest + 1, std::forward(args)...); +} + +/** + * Save the vari pointers in x into the memory pointed to by dest, + * increment the dest storage pointer, + * recursively call save_varis on the rest of the arguments, + * and return the final value of the dest storage pointer. + * + * @tparam VarVec A variant of std::vector + * @tparam Pargs Types of remaining arguments + * @param[in, out] dest Pointer to where vari pointers are saved + * @param[in] x A std::vector of vars + * @param[in] args Additional arguments to have their varis saved + * @return Final position of dest pointer + */ +template *, + typename... Pargs> +inline vari** save_varis(vari** dest, VarVec&& x, Pargs&&... args) { + for (int i = 0; i < x.size(); ++i) { + dest[i] = x(i).vi_; + } + return save_varis(dest + x.size(), std::forward(args)...); +} + +/** + * Save the vari pointers in x into the memory pointed to by dest, + * increment the dest storage pointer, + * recursively call save_varis on the rest of the arguments, + * and return the final value of the dest storage pointer. + * + * @tparam VecContainer std::vector where T is another type containing vars + * @tparam Pargs Types of remaining arguments + * @param[in, out] dest Pointer to where vari pointers are saved + * @param[in] x A std::vector of containers containing of vars + * @param[in] args Additional arguments to have their varis saved + * @return Final position of dest pointer + */ +template *, + require_std_vector_vt*, typename... Pargs> +inline vari** save_varis(vari** dest, VecContainer&& x, Pargs&&... args) { + for (size_t i = 0; i < x.size(); ++i) { + dest = save_varis(dest, x[i]); + } + return save_varis(dest, std::forward(args)...); +} + +/** + * Save the vari pointers in x into the memory pointed to by dest, + * increment the dest storage pointer, + * recursively call save_varis on the rest of the arguments, + * and return the final value of the dest storage pointer. + * + * @tparam EigT An Eigen type with var value type + * @tparam Pargs Types of remaining arguments + * @param[in, out] dest Pointer to where vari pointers are saved + * @param[in] x An Eigen container of vars + * @param[in] args Additional arguments to have their varis saved + * @return Final position of dest pointer + */ +template *, typename... Pargs> +inline vari** save_varis(vari** dest, EigT&& x, Pargs&&... args) { + for (int i = 0; i < x.size(); ++i) { + dest[i] = x(i).vi_; + } + return save_varis(dest + x.size(), std::forward(args)...); +} + +/** + * Ignore arithmetic types. + * + * Recursively call save_varis on the rest of the arguments + * and return the final value of the dest storage pointer. + * + * @tparam Arith An arithmetic type + * @tparam Pargs Types of remaining arguments + * @param[in, out] dest Pointer to where vari pointers are saved + * @param[in] x An argument not containing vars + * @param[in] args Additional arguments to have their varis saved + * @return Final position of dest pointer + */ +template >*, + typename... Pargs> +inline vari** save_varis(vari** dest, Arith&& x, Pargs&&... args) { + return save_varis(dest, std::forward(args)...); +} + +/** + * End save_varis recursion and return pointer + * + * @param dest Pointer + */ +inline vari** save_varis(vari** dest) { return dest; } + +} // namespace math +} // namespace stan + +#endif diff --git a/test/unit/math/rev/core/accumulate_adjoints_test.cpp b/test/unit/math/rev/core/accumulate_adjoints_test.cpp new file mode 100644 index 00000000000..dfbb95729c5 --- /dev/null +++ b/test/unit/math/rev/core/accumulate_adjoints_test.cpp @@ -0,0 +1,374 @@ +#include +#include +#include +#include + +using stan::math::var; +using stan::math::vari; + +Eigen::VectorXd storage(1000); + +TEST(AgradRev_accumulate_adjoints, int_arg) { + int arg = 5; + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, double_arg) { + double arg = 5.0; + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_int_arg) { + std::vector arg(5, 10); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_double_arg) { + std::vector arg(5, 10.0); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, eigen_vector_arg) { + Eigen::VectorXd arg = Eigen::VectorXd::Ones(5); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, eigen_row_vector_arg) { + Eigen::RowVectorXd arg = Eigen::RowVectorXd::Ones(5); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, eigen_matrix_arg) { + Eigen::MatrixXd arg = Eigen::MatrixXd::Ones(5, 5); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_std_vector_double_arg) { + std::vector> arg(5, std::vector(5, 10.0)); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_eigen_vector_arg) { + std::vector arg(2, Eigen::VectorXd::Ones(5)); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_eigen_row_vector_arg) { + std::vector arg(2, Eigen::VectorXd::Ones(5)); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_eigen_matrix_arg) { + std::vector arg(2, Eigen::MatrixXd::Ones(5, 3)); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data()); +} + +TEST(AgradRev_accumulate_adjoints, var_arg) { + var arg(5.0); + arg.vi_->adj_ = 1.0; + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), i + 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_var_arg) { + std::vector arg(5); + for (size_t i = 0; i < arg.size(); ++i) { + arg[i] = 5.0; + arg[i].vi_->adj_ = i + 1.0; + } + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), i + 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, eigen_vector_var_arg) { + Eigen::Matrix arg(5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = 5.0; + arg(i).vi_->adj_ = i + 1.0; + } + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), i + 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, eigen_row_vector_var_arg) { + Eigen::Matrix arg(5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = 5.0; + arg(i).vi_->adj_ = i + 1.0; + } + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), i + 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, eigen_matrix_var_arg) { + Eigen::Matrix arg(5, 5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = 5.0; + arg(i).vi_->adj_ = i + 1.0; + } + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), i + 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_std_vector_var_arg) { + std::vector arg_(5, var(5.0)); + for (size_t i = 0; i < arg_.size(); ++i) + arg_[i].vi_->adj_ = 1.0; + std::vector> arg(5, arg_); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_eigen_vector_var_arg) { + Eigen::Matrix arg_(5); + for (size_t i = 0; i < arg_.size(); ++i) { + arg_(i) = 5.0; + arg_(i).vi_->adj_ = 1.0; + } + std::vector> arg(2, arg_); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_eigen_row_vector_var_arg) { + Eigen::Matrix arg_(5); + for (size_t i = 0; i < arg_.size(); ++i) { + arg_(i) = 5.0; + arg_(i).vi_->adj_ = 1.0; + } + std::vector> arg(2, arg_); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, std_vector_eigen_matrix_var_arg) { + Eigen::Matrix arg_(5, 3); + for (size_t i = 0; i < arg_.size(); ++i) { + arg_(i) = 5.0; + arg_(i).vi_->adj_ = 1.0; + } + std::vector> arg(2, arg_); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} + +TEST(AgradRev_accumulate_adjoints, sum) { + int arg1 = 1; + double arg2 = 1.0; + std::vector arg3(5, 1); + std::vector arg4(5, 1.0); + Eigen::VectorXd arg5 = Eigen::VectorXd::Ones(5); + Eigen::RowVectorXd arg6 = Eigen::RowVectorXd::Ones(5); + Eigen::MatrixXd arg7 = Eigen::MatrixXd::Ones(5, 5); + std::vector> arg8(2, arg4); + std::vector arg9(2, arg5); + + var arg10(new vari(5.0)); + arg10.vi_->adj_ = 1.0; + std::vector arg11(5, new vari(5.0, 1.0)); + for (size_t i = 0; i < arg11.size(); ++i) + arg11[i].vi_->adj_ = 1.0; + Eigen::Matrix arg12(3); + for (size_t i = 0; i < arg12.size(); ++i) { + arg12(i) = 5.0; + arg12(i).vi_->adj_ = 1.0; + } + Eigen::Matrix arg13(4); + for (size_t i = 0; i < arg13.size(); ++i) { + arg13(i) = 5.0; + arg13(i).vi_->adj_ = 1.0; + } + Eigen::Matrix arg14(5, 3); + for (size_t i = 0; i < arg14.size(); ++i) { + arg14(i) = 5.0; + arg14(i).vi_->adj_ = 1.0; + } + std::vector> arg15(2, arg11); + std::vector> arg16(2, arg12); + std::vector> arg17(2, arg13); + std::vector> arg18(2, + arg14); + + storage.setZero(); + double* ptr = stan::math::accumulate_adjoints( + storage.data(), arg1, arg18, arg17, arg2, arg16, arg3, arg15, arg4, arg14, + arg5, arg13, arg12, arg6, arg11, arg7, arg10, arg8, arg9); + + size_t num_vars = stan::math::count_vars( + arg1, arg18, arg17, arg2, arg16, arg3, arg15, arg4, arg14, arg5, arg13, + arg12, arg6, arg11, arg7, arg10, arg8, arg9); + + for (int i = 0; i < num_vars; ++i) + EXPECT_FLOAT_EQ(storage(i), 1.0); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_FLOAT_EQ(storage(i), 0.0); + + EXPECT_EQ(ptr, storage.data() + num_vars); +} diff --git a/test/unit/math/rev/core/count_vars_test.cpp b/test/unit/math/rev/core/count_vars_test.cpp new file mode 100644 index 00000000000..1ec25c53121 --- /dev/null +++ b/test/unit/math/rev/core/count_vars_test.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#include + +using stan::math::var; + +TEST(AgradRev_count_vars, int_arg) { + int arg = 5; + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, double_arg) { + double arg = 5.0; + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_int_arg) { + std::vector arg(5, 10); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_double_arg) { + std::vector arg(5, 10.0); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, eigen_vector_arg) { + Eigen::VectorXd arg = Eigen::VectorXd::Ones(5); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, eigen_row_vector_arg) { + Eigen::RowVectorXd arg = Eigen::RowVectorXd::Ones(5); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, eigen_matrix_arg) { + Eigen::MatrixXd arg = Eigen::MatrixXd::Ones(5, 5); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_std_vector_double_arg) { + std::vector> arg(5, std::vector(5, 10.0)); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_eigen_vector_arg) { + std::vector arg(2, Eigen::VectorXd::Ones(5)); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_eigen_row_vector_arg) { + std::vector arg(2, Eigen::VectorXd::Ones(5)); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_eigen_matrix_arg) { + std::vector arg(2, Eigen::MatrixXd::Ones(5, 3)); + + EXPECT_EQ(0, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, var_arg) { + var arg = 5.0; + + EXPECT_EQ(1, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_var_arg) { + std::vector arg(5); + + EXPECT_EQ(5, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, eigen_vector_var_arg) { + Eigen::Matrix arg(5); + + EXPECT_EQ(5, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, eigen_row_vector_var_arg) { + Eigen::Matrix arg(5); + + EXPECT_EQ(5, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, eigen_matrix_var_arg) { + Eigen::Matrix arg(5, 5); + + EXPECT_EQ(25, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_std_vector_var_arg) { + std::vector> arg(5, std::vector(5)); + + EXPECT_EQ(25, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_eigen_vector_var_arg) { + std::vector> arg( + 2, Eigen::Matrix(5)); + + EXPECT_EQ(10, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_eigen_row_vector_var_arg) { + std::vector> arg( + 2, Eigen::Matrix(5)); + + EXPECT_EQ(10, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, std_vector_eigen_matrix_var_arg) { + std::vector> arg( + 2, Eigen::Matrix(5, 3)); + + EXPECT_EQ(30, stan::math::count_vars(arg)); +} + +TEST(AgradRev_count_vars, sum) { + int arg1 = 1; + double arg2 = 1.0; + std::vector arg3(5, 1); + std::vector arg4(5, 1.0); + Eigen::VectorXd arg5 = Eigen::VectorXd::Ones(5); + Eigen::RowVectorXd arg6 = Eigen::RowVectorXd::Ones(5); + Eigen::MatrixXd arg7 = Eigen::MatrixXd::Ones(5, 5); + std::vector> arg8(2, arg4); + std::vector arg9(2, arg5); + + var arg10 = 1.0; + std::vector arg11(5, 1.0); + Eigen::Matrix arg12(3); + Eigen::Matrix arg13(4); + Eigen::Matrix arg14(5, 3); + std::vector> arg15(2, arg11); + std::vector> arg16(2, arg12); + std::vector> arg17(2, arg13); + std::vector> arg18(2, + arg14); + + EXPECT_EQ( + 1 + 5 + 3 + 4 + 15 + 2 * 5 + 2 * 3 + 2 * 4 + 30, + count_vars(arg1, arg18, arg17, arg2, arg16, arg3, arg15, arg4, arg14, + arg5, arg13, arg12, arg6, arg11, arg7, arg10, arg8, arg9)); +} diff --git a/test/unit/math/rev/core/deep_copy_vars_test.cpp b/test/unit/math/rev/core/deep_copy_vars_test.cpp new file mode 100644 index 00000000000..3b687d15a22 --- /dev/null +++ b/test/unit/math/rev/core/deep_copy_vars_test.cpp @@ -0,0 +1,245 @@ +#include +#include +#include +#include + +using stan::math::var; +using stan::math::vari; + +TEST(AgradRev_deep_copy_vars, int_arg) { + int arg = 5; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, double_arg) { + double arg = 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_int_arg) { + std::vector arg(5, 10); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_double_arg) { + std::vector arg(5, 10.0); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, eigen_vector_arg) { + Eigen::VectorXd arg = Eigen::VectorXd::Ones(5); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, eigen_row_vector_arg) { + Eigen::RowVectorXd arg = Eigen::RowVectorXd::Ones(5); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, eigen_matrix_arg) { + Eigen::MatrixXd arg = Eigen::MatrixXd::Ones(5, 5); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_std_vector_double_arg) { + std::vector> arg(5, std::vector(5, 10.0)); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_arg) { + std::vector arg(2, Eigen::VectorXd::Ones(5)); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_arg) { + std::vector arg(2, Eigen::VectorXd::Ones(5)); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_arg) { + std::vector arg(2, Eigen::MatrixXd::Ones(5, 3)); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, var_arg) { + var arg(5.0); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_NE(out.vi_, arg.vi_); +} + +TEST(AgradRev_deep_copy_vars, std_vector_var_arg) { + std::vector arg(5); + for (size_t i = 0; i < arg.size(); ++i) + arg[i] = i + 1.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) { + EXPECT_EQ(out[i], arg[i]); + EXPECT_NE(out[i].vi_, arg[i].vi_); + } +} + +TEST(AgradRev_deep_copy_vars, eigen_vector_var_arg) { + Eigen::Matrix arg(5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = i + 1.0; + arg(i).vi_->adj_ = i + 1.0; + } + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) { + EXPECT_EQ(out(i), arg(i)); + EXPECT_NE(out(i).vi_, arg(i).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, eigen_row_vector_var_arg) { + Eigen::Matrix arg(5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = i + 1.0; + arg(i).vi_->adj_ = i + 1.0; + } + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) { + EXPECT_EQ(out(i), arg(i)); + EXPECT_NE(out(i).vi_, arg(i).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, eigen_matrix_var_arg) { + Eigen::Matrix arg(5, 5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = i + 1.0; + arg(i).vi_->adj_ = i + 1.0; + } + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) { + EXPECT_EQ(out(i), arg(i)); + EXPECT_NE(out(i).vi_, arg(i).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, std_vector_std_vector_var_arg) { + std::vector arg_(5); + std::vector> arg(5, arg_); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + arg[i][j] = i * arg[i].size() + j + 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) + for (int j = 0; j < arg[i].size(); ++j) { + EXPECT_EQ(out[i][j], arg[i][j]); + EXPECT_NE(out[i][j].vi_, arg[i][j].vi_); + } +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_var_arg) { + Eigen::Matrix arg_(5); + std::vector> arg(2, arg_); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + arg[i](j) = i * arg[i].size() + j + 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) + for (int j = 0; j < arg[i].size(); ++j) { + EXPECT_EQ(out[i](j), arg[i](j)); + EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_var_arg) { + Eigen::Matrix arg_(5); + std::vector> arg(2, arg_); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + arg[i](j) = i * arg[i].size() + j + 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) + for (int j = 0; j < arg[i].size(); ++j) { + EXPECT_EQ(out[i](j), arg[i](j)); + EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_var_arg) { + Eigen::Matrix arg_(5, 3); + std::vector> arg(2, arg_); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + arg[i](j) = i * arg[i].size() + j + 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) + for (int j = 0; j < arg[i].size(); ++j) { + EXPECT_EQ(out[i](j), arg[i](j)); + EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); + } +} diff --git a/test/unit/math/rev/core/save_varis_test.cpp b/test/unit/math/rev/core/save_varis_test.cpp new file mode 100644 index 00000000000..3b687d15a22 --- /dev/null +++ b/test/unit/math/rev/core/save_varis_test.cpp @@ -0,0 +1,245 @@ +#include +#include +#include +#include + +using stan::math::var; +using stan::math::vari; + +TEST(AgradRev_deep_copy_vars, int_arg) { + int arg = 5; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, double_arg) { + double arg = 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_int_arg) { + std::vector arg(5, 10); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_double_arg) { + std::vector arg(5, 10.0); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, eigen_vector_arg) { + Eigen::VectorXd arg = Eigen::VectorXd::Ones(5); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, eigen_row_vector_arg) { + Eigen::RowVectorXd arg = Eigen::RowVectorXd::Ones(5); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, eigen_matrix_arg) { + Eigen::MatrixXd arg = Eigen::MatrixXd::Ones(5, 5); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_std_vector_double_arg) { + std::vector> arg(5, std::vector(5, 10.0)); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_arg) { + std::vector arg(2, Eigen::VectorXd::Ones(5)); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_arg) { + std::vector arg(2, Eigen::VectorXd::Ones(5)); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_arg) { + std::vector arg(2, Eigen::MatrixXd::Ones(5, 3)); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_EQ(&out, &arg); +} + +TEST(AgradRev_deep_copy_vars, var_arg) { + var arg(5.0); + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + EXPECT_NE(out.vi_, arg.vi_); +} + +TEST(AgradRev_deep_copy_vars, std_vector_var_arg) { + std::vector arg(5); + for (size_t i = 0; i < arg.size(); ++i) + arg[i] = i + 1.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) { + EXPECT_EQ(out[i], arg[i]); + EXPECT_NE(out[i].vi_, arg[i].vi_); + } +} + +TEST(AgradRev_deep_copy_vars, eigen_vector_var_arg) { + Eigen::Matrix arg(5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = i + 1.0; + arg(i).vi_->adj_ = i + 1.0; + } + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) { + EXPECT_EQ(out(i), arg(i)); + EXPECT_NE(out(i).vi_, arg(i).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, eigen_row_vector_var_arg) { + Eigen::Matrix arg(5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = i + 1.0; + arg(i).vi_->adj_ = i + 1.0; + } + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) { + EXPECT_EQ(out(i), arg(i)); + EXPECT_NE(out(i).vi_, arg(i).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, eigen_matrix_var_arg) { + Eigen::Matrix arg(5, 5); + for (size_t i = 0; i < arg.size(); ++i) { + arg(i) = i + 1.0; + arg(i).vi_->adj_ = i + 1.0; + } + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) { + EXPECT_EQ(out(i), arg(i)); + EXPECT_NE(out(i).vi_, arg(i).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, std_vector_std_vector_var_arg) { + std::vector arg_(5); + std::vector> arg(5, arg_); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + arg[i][j] = i * arg[i].size() + j + 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) + for (int j = 0; j < arg[i].size(); ++j) { + EXPECT_EQ(out[i][j], arg[i][j]); + EXPECT_NE(out[i][j].vi_, arg[i][j].vi_); + } +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_var_arg) { + Eigen::Matrix arg_(5); + std::vector> arg(2, arg_); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + arg[i](j) = i * arg[i].size() + j + 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) + for (int j = 0; j < arg[i].size(); ++j) { + EXPECT_EQ(out[i](j), arg[i](j)); + EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_var_arg) { + Eigen::Matrix arg_(5); + std::vector> arg(2, arg_); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + arg[i](j) = i * arg[i].size() + j + 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) + for (int j = 0; j < arg[i].size(); ++j) { + EXPECT_EQ(out[i](j), arg[i](j)); + EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); + } +} + +TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_var_arg) { + Eigen::Matrix arg_(5, 3); + std::vector> arg(2, arg_); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + arg[i](j) = i * arg[i].size() + j + 5.0; + + decltype(stan::math::deep_copy_vars(arg)) out + = stan::math::deep_copy_vars(arg); + + for (int i = 0; i < arg.size(); ++i) + for (int j = 0; j < arg[i].size(); ++j) { + EXPECT_EQ(out[i](j), arg[i](j)); + EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); + } +} From 6dedcf9a7728a7c4908f9a51982c5b5a09edf98d Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Tue, 24 Mar 2020 23:33:17 -0400 Subject: [PATCH 02/11] change test names for save_vari --- test/unit/math/rev/core/save_varis_test.cpp | 40 ++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/test/unit/math/rev/core/save_varis_test.cpp b/test/unit/math/rev/core/save_varis_test.cpp index 3b687d15a22..ab34516d698 100644 --- a/test/unit/math/rev/core/save_varis_test.cpp +++ b/test/unit/math/rev/core/save_varis_test.cpp @@ -6,7 +6,7 @@ using stan::math::var; using stan::math::vari; -TEST(AgradRev_deep_copy_vars, int_arg) { +TEST(AgradRev_save_vari, int_arg) { int arg = 5; decltype(stan::math::deep_copy_vars(arg)) out @@ -15,7 +15,7 @@ TEST(AgradRev_deep_copy_vars, int_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, double_arg) { +TEST(AgradRev_save_vari, double_arg) { double arg = 5.0; decltype(stan::math::deep_copy_vars(arg)) out @@ -24,7 +24,7 @@ TEST(AgradRev_deep_copy_vars, double_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, std_vector_int_arg) { +TEST(AgradRev_save_vari, std_vector_int_arg) { std::vector arg(5, 10); decltype(stan::math::deep_copy_vars(arg)) out @@ -33,7 +33,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_int_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, std_vector_double_arg) { +TEST(AgradRev_save_vari, std_vector_double_arg) { std::vector arg(5, 10.0); decltype(stan::math::deep_copy_vars(arg)) out @@ -42,7 +42,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_double_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, eigen_vector_arg) { +TEST(AgradRev_save_vari, eigen_vector_arg) { Eigen::VectorXd arg = Eigen::VectorXd::Ones(5); decltype(stan::math::deep_copy_vars(arg)) out @@ -51,7 +51,7 @@ TEST(AgradRev_deep_copy_vars, eigen_vector_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, eigen_row_vector_arg) { +TEST(AgradRev_save_vari, eigen_row_vector_arg) { Eigen::RowVectorXd arg = Eigen::RowVectorXd::Ones(5); decltype(stan::math::deep_copy_vars(arg)) out @@ -60,7 +60,7 @@ TEST(AgradRev_deep_copy_vars, eigen_row_vector_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, eigen_matrix_arg) { +TEST(AgradRev_save_vari, eigen_matrix_arg) { Eigen::MatrixXd arg = Eigen::MatrixXd::Ones(5, 5); decltype(stan::math::deep_copy_vars(arg)) out @@ -69,7 +69,7 @@ TEST(AgradRev_deep_copy_vars, eigen_matrix_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, std_vector_std_vector_double_arg) { +TEST(AgradRev_save_vari, std_vector_std_vector_double_arg) { std::vector> arg(5, std::vector(5, 10.0)); decltype(stan::math::deep_copy_vars(arg)) out @@ -78,7 +78,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_std_vector_double_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_arg) { +TEST(AgradRev_save_vari, std_vector_eigen_vector_arg) { std::vector arg(2, Eigen::VectorXd::Ones(5)); decltype(stan::math::deep_copy_vars(arg)) out @@ -87,7 +87,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_arg) { +TEST(AgradRev_save_vari, std_vector_eigen_row_vector_arg) { std::vector arg(2, Eigen::VectorXd::Ones(5)); decltype(stan::math::deep_copy_vars(arg)) out @@ -96,7 +96,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_arg) { +TEST(AgradRev_save_vari, std_vector_eigen_matrix_arg) { std::vector arg(2, Eigen::MatrixXd::Ones(5, 3)); decltype(stan::math::deep_copy_vars(arg)) out @@ -105,7 +105,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_arg) { EXPECT_EQ(&out, &arg); } -TEST(AgradRev_deep_copy_vars, var_arg) { +TEST(AgradRev_save_vari, var_arg) { var arg(5.0); decltype(stan::math::deep_copy_vars(arg)) out @@ -114,7 +114,7 @@ TEST(AgradRev_deep_copy_vars, var_arg) { EXPECT_NE(out.vi_, arg.vi_); } -TEST(AgradRev_deep_copy_vars, std_vector_var_arg) { +TEST(AgradRev_save_vari, std_vector_var_arg) { std::vector arg(5); for (size_t i = 0; i < arg.size(); ++i) arg[i] = i + 1.0; @@ -128,7 +128,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_var_arg) { } } -TEST(AgradRev_deep_copy_vars, eigen_vector_var_arg) { +TEST(AgradRev_save_vari, eigen_vector_var_arg) { Eigen::Matrix arg(5); for (size_t i = 0; i < arg.size(); ++i) { arg(i) = i + 1.0; @@ -144,7 +144,7 @@ TEST(AgradRev_deep_copy_vars, eigen_vector_var_arg) { } } -TEST(AgradRev_deep_copy_vars, eigen_row_vector_var_arg) { +TEST(AgradRev_save_vari, eigen_row_vector_var_arg) { Eigen::Matrix arg(5); for (size_t i = 0; i < arg.size(); ++i) { arg(i) = i + 1.0; @@ -160,7 +160,7 @@ TEST(AgradRev_deep_copy_vars, eigen_row_vector_var_arg) { } } -TEST(AgradRev_deep_copy_vars, eigen_matrix_var_arg) { +TEST(AgradRev_save_vari, eigen_matrix_var_arg) { Eigen::Matrix arg(5, 5); for (size_t i = 0; i < arg.size(); ++i) { arg(i) = i + 1.0; @@ -176,7 +176,7 @@ TEST(AgradRev_deep_copy_vars, eigen_matrix_var_arg) { } } -TEST(AgradRev_deep_copy_vars, std_vector_std_vector_var_arg) { +TEST(AgradRev_save_vari, std_vector_std_vector_var_arg) { std::vector arg_(5); std::vector> arg(5, arg_); for (size_t i = 0; i < arg.size(); ++i) @@ -193,7 +193,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_std_vector_var_arg) { } } -TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_var_arg) { +TEST(AgradRev_save_vari, std_vector_eigen_vector_var_arg) { Eigen::Matrix arg_(5); std::vector> arg(2, arg_); for (size_t i = 0; i < arg.size(); ++i) @@ -210,7 +210,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_var_arg) { } } -TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_var_arg) { +TEST(AgradRev_save_vari, std_vector_eigen_row_vector_var_arg) { Eigen::Matrix arg_(5); std::vector> arg(2, arg_); for (size_t i = 0; i < arg.size(); ++i) @@ -227,7 +227,7 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_var_arg) { } } -TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_var_arg) { +TEST(AgradRev_save_vari, std_vector_eigen_matrix_var_arg) { Eigen::Matrix arg_(5, 3); std::vector> arg(2, arg_); for (size_t i = 0; i < arg.size(); ++i) From fc6701fd7c92ca30fda9c512848082f2dd1e5c2d Mon Sep 17 00:00:00 2001 From: Steve Bronder Date: Fri, 27 Mar 2020 16:31:45 -0400 Subject: [PATCH 03/11] fixup accumulate_adjoint and save_vari tests --- stan/math/rev/core/save_varis.hpp | 2 +- .../rev/core/accumulate_adjoints_test.cpp | 203 ++++++--- test/unit/math/rev/core/count_vars_test.cpp | 4 + test/unit/math/rev/core/save_varis_test.cpp | 403 +++++++++++++----- 4 files changed, 425 insertions(+), 187 deletions(-) diff --git a/stan/math/rev/core/save_varis.hpp b/stan/math/rev/core/save_varis.hpp index e118d534e98..d97e8a1a474 100644 --- a/stan/math/rev/core/save_varis.hpp +++ b/stan/math/rev/core/save_varis.hpp @@ -70,7 +70,7 @@ template *, typename... Pargs> inline vari** save_varis(vari** dest, VarVec&& x, Pargs&&... args) { for (int i = 0; i < x.size(); ++i) { - dest[i] = x(i).vi_; + dest[i] = x[i].vi_; } return save_varis(dest + x.size(), std::forward(args)...); } diff --git a/test/unit/math/rev/core/accumulate_adjoints_test.cpp b/test/unit/math/rev/core/accumulate_adjoints_test.cpp index dfbb95729c5..23e6fb61fd4 100644 --- a/test/unit/math/rev/core/accumulate_adjoints_test.cpp +++ b/test/unit/math/rev/core/accumulate_adjoints_test.cpp @@ -3,19 +3,27 @@ #include #include -using stan::math::var; -using stan::math::vari; -Eigen::VectorXd storage(1000); +TEST(AgradRev_accumulate_adjoints, zero_args) { + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); + double* ptr = stan::math::accumulate_adjoints(storage.data()); + + for (int i = 0; i < storage.size(); ++i) { + EXPECT_FLOAT_EQ(storage(i), 0.0); + } + + EXPECT_EQ(ptr, storage.data()); +} TEST(AgradRev_accumulate_adjoints, int_arg) { int arg = 5; + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); - storage.setZero(); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -23,11 +31,12 @@ TEST(AgradRev_accumulate_adjoints, int_arg) { TEST(AgradRev_accumulate_adjoints, double_arg) { double arg = 5.0; - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -35,11 +44,12 @@ TEST(AgradRev_accumulate_adjoints, double_arg) { TEST(AgradRev_accumulate_adjoints, std_vector_int_arg) { std::vector arg(5, 10); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -47,11 +57,12 @@ TEST(AgradRev_accumulate_adjoints, std_vector_int_arg) { TEST(AgradRev_accumulate_adjoints, std_vector_double_arg) { std::vector arg(5, 10.0); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -59,7 +70,7 @@ TEST(AgradRev_accumulate_adjoints, std_vector_double_arg) { TEST(AgradRev_accumulate_adjoints, eigen_vector_arg) { Eigen::VectorXd arg = Eigen::VectorXd::Ones(5); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); for (int i = 0; i < storage.size(); ++i) @@ -71,11 +82,12 @@ TEST(AgradRev_accumulate_adjoints, eigen_vector_arg) { TEST(AgradRev_accumulate_adjoints, eigen_row_vector_arg) { Eigen::RowVectorXd arg = Eigen::RowVectorXd::Ones(5); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -83,11 +95,12 @@ TEST(AgradRev_accumulate_adjoints, eigen_row_vector_arg) { TEST(AgradRev_accumulate_adjoints, eigen_matrix_arg) { Eigen::MatrixXd arg = Eigen::MatrixXd::Ones(5, 5); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -95,11 +108,12 @@ TEST(AgradRev_accumulate_adjoints, eigen_matrix_arg) { TEST(AgradRev_accumulate_adjoints, std_vector_std_vector_double_arg) { std::vector> arg(5, std::vector(5, 10.0)); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -107,11 +121,12 @@ TEST(AgradRev_accumulate_adjoints, std_vector_std_vector_double_arg) { TEST(AgradRev_accumulate_adjoints, std_vector_eigen_vector_arg) { std::vector arg(2, Eigen::VectorXd::Ones(5)); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -119,11 +134,12 @@ TEST(AgradRev_accumulate_adjoints, std_vector_eigen_vector_arg) { TEST(AgradRev_accumulate_adjoints, std_vector_eigen_row_vector_arg) { std::vector arg(2, Eigen::VectorXd::Ones(5)); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } @@ -131,132 +147,165 @@ TEST(AgradRev_accumulate_adjoints, std_vector_eigen_row_vector_arg) { TEST(AgradRev_accumulate_adjoints, std_vector_eigen_matrix_arg) { std::vector arg(2, Eigen::MatrixXd::Ones(5, 3)); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - for (int i = 0; i < storage.size(); ++i) + for (int i = 0; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data()); } TEST(AgradRev_accumulate_adjoints, var_arg) { + using stan::math::var; + using stan::math::vari; var arg(5.0); arg.vi_->adj_ = 1.0; - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 1; - for (int i = 0; i < num_vars; ++i) - EXPECT_FLOAT_EQ(storage(i), i + 1.0); - for (int i = num_vars; i < storage.size(); ++i) + for (int i = 0; i < num_vars; ++i) { + EXPECT_FLOAT_EQ(storage(i), 1.0); + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, std_vector_var_arg) { + using stan::math::var; + using stan::math::vari; std::vector arg(5); for (size_t i = 0; i < arg.size(); ++i) { arg[i] = 5.0; arg[i].vi_->adj_ = i + 1.0; } - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 5; - for (int i = 0; i < num_vars; ++i) + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), i + 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, eigen_vector_var_arg) { + using stan::math::var; + using stan::math::vari; Eigen::Matrix arg(5); for (size_t i = 0; i < arg.size(); ++i) { arg(i) = 5.0; arg(i).vi_->adj_ = i + 1.0; } - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 5; - for (int i = 0; i < num_vars; ++i) + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), i + 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, eigen_row_vector_var_arg) { + using stan::math::var; + using stan::math::vari; Eigen::Matrix arg(5); for (size_t i = 0; i < arg.size(); ++i) { arg(i) = 5.0; arg(i).vi_->adj_ = i + 1.0; } - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 5; - for (int i = 0; i < num_vars; ++i) + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), i + 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, eigen_matrix_var_arg) { + using stan::math::var; + using stan::math::vari; Eigen::Matrix arg(5, 5); for (size_t i = 0; i < arg.size(); ++i) { arg(i) = 5.0; arg(i).vi_->adj_ = i + 1.0; } - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 25; - for (int i = 0; i < num_vars; ++i) + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), i + 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, std_vector_std_vector_var_arg) { + using stan::math::var; + using stan::math::vari; std::vector arg_(5, var(5.0)); for (size_t i = 0; i < arg_.size(); ++i) arg_[i].vi_->adj_ = 1.0; std::vector> arg(5, arg_); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 25; - for (int i = 0; i < num_vars; ++i) + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, std_vector_eigen_vector_var_arg) { + using stan::math::var; + using stan::math::vari; Eigen::Matrix arg_(5); for (size_t i = 0; i < arg_.size(); ++i) { arg_(i) = 5.0; @@ -264,20 +313,25 @@ TEST(AgradRev_accumulate_adjoints, std_vector_eigen_vector_var_arg) { } std::vector> arg(2, arg_); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 10; - for (int i = 0; i < num_vars; ++i) + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, std_vector_eigen_row_vector_var_arg) { + using stan::math::var; + using stan::math::vari; Eigen::Matrix arg_(5); for (size_t i = 0; i < arg_.size(); ++i) { arg_(i) = 5.0; @@ -285,20 +339,25 @@ TEST(AgradRev_accumulate_adjoints, std_vector_eigen_row_vector_var_arg) { } std::vector> arg(2, arg_); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 10; - for (int i = 0; i < num_vars; ++i) + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, std_vector_eigen_matrix_var_arg) { + using stan::math::var; + using stan::math::vari; Eigen::Matrix arg_(5, 3); for (size_t i = 0; i < arg_.size(); ++i) { arg_(i) = 5.0; @@ -306,20 +365,25 @@ TEST(AgradRev_accumulate_adjoints, std_vector_eigen_matrix_var_arg) { } std::vector> arg(2, arg_); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data(), arg); - size_t num_vars = stan::math::count_vars(arg); + const size_t num_vars = 30; - for (int i = 0; i < num_vars; ++i) + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } TEST(AgradRev_accumulate_adjoints, sum) { + using stan::math::var; + using stan::math::vari; int arg1 = 1; double arg2 = 1.0; std::vector arg3(5, 1); @@ -333,8 +397,9 @@ TEST(AgradRev_accumulate_adjoints, sum) { var arg10(new vari(5.0)); arg10.vi_->adj_ = 1.0; std::vector arg11(5, new vari(5.0, 1.0)); - for (size_t i = 0; i < arg11.size(); ++i) + for (size_t i = 0; i < arg11.size(); ++i) { arg11[i].vi_->adj_ = 1.0; + } Eigen::Matrix arg12(3); for (size_t i = 0; i < arg12.size(); ++i) { arg12(i) = 5.0; @@ -356,19 +421,19 @@ TEST(AgradRev_accumulate_adjoints, sum) { std::vector> arg18(2, arg14); - storage.setZero(); + Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints( storage.data(), arg1, arg18, arg17, arg2, arg16, arg3, arg15, arg4, arg14, arg5, arg13, arg12, arg6, arg11, arg7, arg10, arg8, arg9); - size_t num_vars = stan::math::count_vars( - arg1, arg18, arg17, arg2, arg16, arg3, arg15, arg4, arg14, arg5, arg13, - arg12, arg6, arg11, arg7, arg10, arg8, arg9); - - for (int i = 0; i < num_vars; ++i) + const size_t num_vars = 82; + for (int i = 0; i < num_vars; ++i) { EXPECT_FLOAT_EQ(storage(i), 1.0); - for (int i = num_vars; i < storage.size(); ++i) + } + for (int i = num_vars; i < storage.size(); ++i) { EXPECT_FLOAT_EQ(storage(i), 0.0); + } EXPECT_EQ(ptr, storage.data() + num_vars); + stan::math::recover_memory(); } diff --git a/test/unit/math/rev/core/count_vars_test.cpp b/test/unit/math/rev/core/count_vars_test.cpp index 1ec25c53121..23f4c6d2d2d 100644 --- a/test/unit/math/rev/core/count_vars_test.cpp +++ b/test/unit/math/rev/core/count_vars_test.cpp @@ -128,6 +128,10 @@ TEST(AgradRev_count_vars, std_vector_eigen_matrix_var_arg) { EXPECT_EQ(30, stan::math::count_vars(arg)); } +TEST(AgradRev_count_vars, zero_args) { + EXPECT_EQ(0, stan::math::count_vars()); +} + TEST(AgradRev_count_vars, sum) { int arg1 = 1; double arg2 = 1.0; diff --git a/test/unit/math/rev/core/save_varis_test.cpp b/test/unit/math/rev/core/save_varis_test.cpp index ab34516d698..95decf54868 100644 --- a/test/unit/math/rev/core/save_varis_test.cpp +++ b/test/unit/math/rev/core/save_varis_test.cpp @@ -1,245 +1,414 @@ -#include -#include #include +#include #include using stan::math::var; using stan::math::vari; -TEST(AgradRev_save_vari, int_arg) { +TEST(AgradRev_save_varis, int_arg) { int arg = 5; - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - EXPECT_EQ(&out, &arg); + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data()); + stan::math::recover_memory(); } -TEST(AgradRev_save_vari, double_arg) { +TEST(AgradRev_save_varis, double_arg) { double arg = 5.0; - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); - EXPECT_EQ(&out, &arg); + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, std_vector_int_arg) { +TEST(AgradRev_save_varis, std_vector_int_arg) { std::vector arg(5, 10); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - EXPECT_EQ(&out, &arg); + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, std_vector_double_arg) { +TEST(AgradRev_save_varis, std_vector_double_arg) { std::vector arg(5, 10.0); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); - EXPECT_EQ(&out, &arg); + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, eigen_vector_arg) { +TEST(AgradRev_save_varis, eigen_vector_arg) { Eigen::VectorXd arg = Eigen::VectorXd::Ones(5); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - EXPECT_EQ(&out, &arg); + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, eigen_row_vector_arg) { +TEST(AgradRev_save_varis, eigen_row_vector_arg) { Eigen::RowVectorXd arg = Eigen::RowVectorXd::Ones(5); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); - EXPECT_EQ(&out, &arg); + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, eigen_matrix_arg) { +TEST(AgradRev_save_varis, eigen_matrix_arg) { Eigen::MatrixXd arg = Eigen::MatrixXd::Ones(5, 5); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - EXPECT_EQ(&out, &arg); + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, std_vector_std_vector_double_arg) { +TEST(AgradRev_save_varis, std_vector_std_vector_double_arg) { std::vector> arg(5, std::vector(5, 10.0)); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); - EXPECT_EQ(&out, &arg); + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, std_vector_eigen_vector_arg) { +TEST(AgradRev_save_varis, std_vector_eigen_vector_arg) { std::vector arg(2, Eigen::VectorXd::Ones(5)); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - EXPECT_EQ(&out, &arg); + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, std_vector_eigen_row_vector_arg) { +TEST(AgradRev_save_varis, std_vector_eigen_row_vector_arg) { std::vector arg(2, Eigen::VectorXd::Ones(5)); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); - EXPECT_EQ(&out, &arg); + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, std_vector_eigen_matrix_arg) { +TEST(AgradRev_save_varis, std_vector_eigen_matrix_arg) { std::vector arg(2, Eigen::MatrixXd::Ones(5, 3)); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - EXPECT_EQ(&out, &arg); + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data()); } -TEST(AgradRev_save_vari, var_arg) { +TEST(AgradRev_save_varis, var_arg) { var arg(5.0); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_EQ(storage[i], arg.vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); - EXPECT_NE(out.vi_, arg.vi_); + EXPECT_EQ(ptr, storage.data() + num_vars); } -TEST(AgradRev_save_vari, std_vector_var_arg) { +TEST(AgradRev_save_varis, std_vector_var_arg) { std::vector arg(5); for (size_t i = 0; i < arg.size(); ++i) - arg[i] = i + 1.0; + arg[i] = 5.0; - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - for (int i = 0; i < arg.size(); ++i) { - EXPECT_EQ(out[i], arg[i]); - EXPECT_NE(out[i].vi_, arg[i].vi_); - } + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_EQ(storage[i], arg[i].vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data() + num_vars); } -TEST(AgradRev_save_vari, eigen_vector_var_arg) { +TEST(AgradRev_save_varis, eigen_vector_var_arg) { Eigen::Matrix arg(5); for (size_t i = 0; i < arg.size(); ++i) { - arg(i) = i + 1.0; + arg(i) = 5.0; arg(i).vi_->adj_ = i + 1.0; } - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - for (int i = 0; i < arg.size(); ++i) { - EXPECT_EQ(out(i), arg(i)); - EXPECT_NE(out(i).vi_, arg(i).vi_); - } + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_EQ(storage[i], arg(i).vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data() + num_vars); } -TEST(AgradRev_save_vari, eigen_row_vector_var_arg) { +TEST(AgradRev_save_varis, eigen_row_vector_var_arg) { Eigen::Matrix arg(5); for (size_t i = 0; i < arg.size(); ++i) { - arg(i) = i + 1.0; + arg(i) = 5.0; arg(i).vi_->adj_ = i + 1.0; } - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - for (int i = 0; i < arg.size(); ++i) { - EXPECT_EQ(out(i), arg(i)); - EXPECT_NE(out(i).vi_, arg(i).vi_); - } + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_EQ(storage[i], arg(i).vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data() + num_vars); } -TEST(AgradRev_save_vari, eigen_matrix_var_arg) { +TEST(AgradRev_save_varis, eigen_matrix_var_arg) { Eigen::Matrix arg(5, 5); for (size_t i = 0; i < arg.size(); ++i) { - arg(i) = i + 1.0; + arg(i) = 5.0; arg(i).vi_->adj_ = i + 1.0; } - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - for (int i = 0; i < arg.size(); ++i) { - EXPECT_EQ(out(i), arg(i)); - EXPECT_NE(out(i).vi_, arg(i).vi_); - } + size_t num_vars = stan::math::count_vars(arg); + + for (int i = 0; i < num_vars; ++i) + EXPECT_EQ(storage[i], arg(i).vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data() + num_vars); } -TEST(AgradRev_save_vari, std_vector_std_vector_var_arg) { +TEST(AgradRev_save_varis, std_vector_std_vector_var_arg) { std::vector arg_(5); std::vector> arg(5, arg_); for (size_t i = 0; i < arg.size(); ++i) for (size_t j = 0; j < arg[i].size(); ++j) - arg[i][j] = i * arg[i].size() + j + 5.0; + arg[i][j] = 5.0; - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - for (int i = 0; i < arg.size(); ++i) - for (int j = 0; j < arg[i].size(); ++j) { - EXPECT_EQ(out[i][j], arg[i][j]); - EXPECT_NE(out[i][j].vi_, arg[i][j].vi_); - } + size_t num_vars = stan::math::count_vars(arg); + + EXPECT_EQ(arg.size() * arg[0].size(), num_vars); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + EXPECT_EQ(storage[i * arg[0].size() + j], arg[i][j].vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data() + num_vars); } -TEST(AgradRev_save_vari, std_vector_eigen_vector_var_arg) { +TEST(AgradRev_save_varis, std_vector_eigen_vector_var_arg) { Eigen::Matrix arg_(5); std::vector> arg(2, arg_); for (size_t i = 0; i < arg.size(); ++i) for (size_t j = 0; j < arg[i].size(); ++j) - arg[i](j) = i * arg[i].size() + j + 5.0; + arg[i](j) = 5.0; - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - for (int i = 0; i < arg.size(); ++i) - for (int j = 0; j < arg[i].size(); ++j) { - EXPECT_EQ(out[i](j), arg[i](j)); - EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); - } + size_t num_vars = stan::math::count_vars(arg); + + EXPECT_EQ(arg.size() * arg[0].size(), num_vars); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + EXPECT_EQ(storage[i * arg[0].size() + j], arg[i](j).vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data() + num_vars); } -TEST(AgradRev_save_vari, std_vector_eigen_row_vector_var_arg) { +TEST(AgradRev_save_varis, std_vector_eigen_row_vector_var_arg) { Eigen::Matrix arg_(5); std::vector> arg(2, arg_); for (size_t i = 0; i < arg.size(); ++i) for (size_t j = 0; j < arg[i].size(); ++j) - arg[i](j) = i * arg[i].size() + j + 5.0; + arg[i](j) = 5.0; - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); - for (int i = 0; i < arg.size(); ++i) - for (int j = 0; j < arg[i].size(); ++j) { - EXPECT_EQ(out[i](j), arg[i](j)); - EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); - } + size_t num_vars = stan::math::count_vars(arg); + + EXPECT_EQ(arg.size() * arg[0].size(), num_vars); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + EXPECT_EQ(storage[i * arg[0].size() + j], arg[i](j).vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data() + num_vars); } -TEST(AgradRev_save_vari, std_vector_eigen_matrix_var_arg) { +TEST(AgradRev_save_varis, std_vector_eigen_matrix_var_arg) { Eigen::Matrix arg_(5, 3); std::vector> arg(2, arg_); for (size_t i = 0; i < arg.size(); ++i) for (size_t j = 0; j < arg[i].size(); ++j) - arg[i](j) = i * arg[i].size() + j + 5.0; + arg[i](j) = 5.0; + + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data(), arg); + + size_t num_vars = stan::math::count_vars(arg); + + EXPECT_EQ(arg.size() * arg[0].size(), num_vars); + for (size_t i = 0; i < arg.size(); ++i) + for (size_t j = 0; j < arg[i].size(); ++j) + EXPECT_EQ(storage[i * arg[0].size() + j], arg[i](j).vi_); + for (int i = num_vars; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); - decltype(stan::math::deep_copy_vars(arg)) out - = stan::math::deep_copy_vars(arg); + EXPECT_EQ(ptr, storage.data() + num_vars); +} - for (int i = 0; i < arg.size(); ++i) - for (int j = 0; j < arg[i].size(); ++j) { - EXPECT_EQ(out[i](j), arg[i](j)); - EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); +TEST(AgradRev_save_varis, sum) { + int arg1 = 1; + double arg2 = 1.0; + std::vector arg3(5, 1); + std::vector arg4(5, 1.0); + Eigen::VectorXd arg5 = Eigen::VectorXd::Ones(5); + Eigen::RowVectorXd arg6 = Eigen::RowVectorXd::Ones(5); + Eigen::MatrixXd arg7 = Eigen::MatrixXd::Ones(5, 5); + std::vector> arg8(2, arg4); + std::vector arg9(2, arg5); + + var arg10(new vari(5.0)); + arg10.vi_->adj_ = 1.0; + std::vector arg11(5, new vari(5.0, 1.0)); + for (size_t i = 0; i < arg11.size(); ++i) + arg11[i].vi_->adj_ = 1.0; + Eigen::Matrix arg12(3); + for (size_t i = 0; i < arg12.size(); ++i) { + arg12(i) = 5.0; + arg12(i).vi_->adj_ = 1.0; + } + Eigen::Matrix arg13(4); + for (size_t i = 0; i < arg13.size(); ++i) { + arg13(i) = 5.0; + arg13(i).vi_->adj_ = 1.0; + } + Eigen::Matrix arg14(5, 3); + for (size_t i = 0; i < arg14.size(); ++i) { + arg14(i) = 5.0; + arg14(i).vi_->adj_ = 1.0; + } + std::vector> arg15(2, arg11); + std::vector> arg16(2, arg12); + std::vector> arg17(2, arg13); + std::vector> arg18(2, + arg14); + + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis( + storage.data(), arg1, arg18, arg17, arg2, arg16, arg3, arg15, arg4, arg14, + arg5, arg13, arg12, arg6, arg11, arg7, arg10, arg8, arg9); + + size_t num_vars = stan::math::count_vars( + arg1, arg18, arg17, arg2, arg16, arg3, arg15, arg4, arg14, arg5, arg13, + arg12, arg6, arg11, arg7, arg10, arg8, arg9); + + int total = 0; + for (int i = 0; i < arg18.size(); ++i) + for (int j = 0; j < arg18[i].size(); ++j) { + EXPECT_EQ(storage[total], arg18[i](j).vi_); + total++; + } + for (int i = 0; i < arg17.size(); ++i) + for (int j = 0; j < arg17[i].size(); ++j) { + EXPECT_EQ(storage[total], arg17[i](j).vi_); + total++; + } + for (int i = 0; i < arg16.size(); ++i) + for (int j = 0; j < arg16[i].size(); ++j) { + EXPECT_EQ(storage[total], arg16[i](j).vi_); + total++; } + for (int i = 0; i < arg15.size(); ++i) + for (int j = 0; j < arg15[i].size(); ++j) { + EXPECT_EQ(storage[total], arg15[i][j].vi_); + total++; + } + for (int i = 0; i < arg14.size(); ++i) { + EXPECT_EQ(storage[total], arg14(i).vi_); + total++; + } + for (int i = 0; i < arg13.size(); ++i) { + EXPECT_EQ(storage[total], arg13(i).vi_); + total++; + } + for (int i = 0; i < arg12.size(); ++i) { + EXPECT_EQ(storage[total], arg12(i).vi_); + total++; + } + for (int i = 0; i < arg11.size(); ++i) { + EXPECT_EQ(storage[total], arg11[i].vi_); + total++; + } + EXPECT_EQ(storage[total], arg10.vi_); + total++; + EXPECT_EQ(total, num_vars); + + for (int i = total; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data() + num_vars); } From 062d981a3af5f128f8ae94078af209e779bc4fdd Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Fri, 27 Mar 2020 16:32:30 -0400 Subject: [PATCH 04/11] [Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~exp1~20180509124008.99 (branches/release_50) --- stan/math/opencl/kernel_generator/load.hpp | 2 +- test/unit/math/rev/core/accumulate_adjoints_test.cpp | 1 - test/unit/math/rev/core/count_vars_test.cpp | 4 +--- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/stan/math/opencl/kernel_generator/load.hpp b/stan/math/opencl/kernel_generator/load.hpp index ae0f7d1eb6d..799cdb551a0 100644 --- a/stan/math/opencl/kernel_generator/load.hpp +++ b/stan/math/opencl/kernel_generator/load.hpp @@ -49,7 +49,7 @@ class load_ * Creates a deep copy of this expression. * @return copy of \c *this */ - inline load_ deep_copy() const& { return load_(a_); } + inline load_ deep_copy() const & { return load_(a_); } inline load_ deep_copy() && { return load_(std::forward(a_)); } /** diff --git a/test/unit/math/rev/core/accumulate_adjoints_test.cpp b/test/unit/math/rev/core/accumulate_adjoints_test.cpp index 23e6fb61fd4..644282f88eb 100644 --- a/test/unit/math/rev/core/accumulate_adjoints_test.cpp +++ b/test/unit/math/rev/core/accumulate_adjoints_test.cpp @@ -3,7 +3,6 @@ #include #include - TEST(AgradRev_accumulate_adjoints, zero_args) { Eigen::VectorXd storage = Eigen::VectorXd::Zero(1000); double* ptr = stan::math::accumulate_adjoints(storage.data()); diff --git a/test/unit/math/rev/core/count_vars_test.cpp b/test/unit/math/rev/core/count_vars_test.cpp index 23f4c6d2d2d..ec9a6b96e38 100644 --- a/test/unit/math/rev/core/count_vars_test.cpp +++ b/test/unit/math/rev/core/count_vars_test.cpp @@ -128,9 +128,7 @@ TEST(AgradRev_count_vars, std_vector_eigen_matrix_var_arg) { EXPECT_EQ(30, stan::math::count_vars(arg)); } -TEST(AgradRev_count_vars, zero_args) { - EXPECT_EQ(0, stan::math::count_vars()); -} +TEST(AgradRev_count_vars, zero_args) { EXPECT_EQ(0, stan::math::count_vars()); } TEST(AgradRev_count_vars, sum) { int arg1 = 1; From c8343c3100abd6bc5e18d41cc77a62d1547b7bd0 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Fri, 27 Mar 2020 16:33:16 -0400 Subject: [PATCH 05/11] [Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/stable/2017-11-14) --- stan/math/opencl/kernel_generator/load.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stan/math/opencl/kernel_generator/load.hpp b/stan/math/opencl/kernel_generator/load.hpp index 799cdb551a0..ae0f7d1eb6d 100644 --- a/stan/math/opencl/kernel_generator/load.hpp +++ b/stan/math/opencl/kernel_generator/load.hpp @@ -49,7 +49,7 @@ class load_ * Creates a deep copy of this expression. * @return copy of \c *this */ - inline load_ deep_copy() const & { return load_(a_); } + inline load_ deep_copy() const& { return load_(a_); } inline load_ deep_copy() && { return load_(std::forward(a_)); } /** From 1c4c84f7171c4d681a1a2b8ece02a034ebf0c77c Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 27 Mar 2020 17:06:32 -0400 Subject: [PATCH 06/11] Test deep_copy_vars to make sure adjoints aren't being propagated from output to input (design-doc #17, reduce_sum) --- .../math/rev/core/deep_copy_vars_test.cpp | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/test/unit/math/rev/core/deep_copy_vars_test.cpp b/test/unit/math/rev/core/deep_copy_vars_test.cpp index 3b687d15a22..ac9e067a589 100644 --- a/test/unit/math/rev/core/deep_copy_vars_test.cpp +++ b/test/unit/math/rev/core/deep_copy_vars_test.cpp @@ -107,10 +107,16 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_arg) { TEST(AgradRev_deep_copy_vars, var_arg) { var arg(5.0); + arg.vi_->adj_ = 2.0; decltype(stan::math::deep_copy_vars(arg)) out = stan::math::deep_copy_vars(arg); + out.grad(); + + EXPECT_EQ(out.vi_->adj_, 1.0); + EXPECT_EQ(arg.vi_->adj_, 2.0); + EXPECT_EQ(out, arg); EXPECT_NE(out.vi_, arg.vi_); } @@ -123,6 +129,13 @@ TEST(AgradRev_deep_copy_vars, std_vector_var_arg) { = stan::math::deep_copy_vars(arg); for (int i = 0; i < arg.size(); ++i) { + stan::math::set_zero_all_adjoints(); + arg[i].vi_->adj_ = 2.0; + + out[i].grad(); + + EXPECT_EQ(out[i].vi_->adj_, 1.0); + EXPECT_EQ(arg[i].vi_->adj_, 2.0); EXPECT_EQ(out[i], arg[i]); EXPECT_NE(out[i].vi_, arg[i].vi_); } @@ -139,6 +152,13 @@ TEST(AgradRev_deep_copy_vars, eigen_vector_var_arg) { = stan::math::deep_copy_vars(arg); for (int i = 0; i < arg.size(); ++i) { + stan::math::set_zero_all_adjoints(); + arg(i).vi_->adj_ = 2.0; + + out(i).grad(); + + EXPECT_EQ(out(i).vi_->adj_, 1.0); + EXPECT_EQ(arg(i).vi_->adj_, 2.0); EXPECT_EQ(out(i), arg(i)); EXPECT_NE(out(i).vi_, arg(i).vi_); } @@ -155,6 +175,13 @@ TEST(AgradRev_deep_copy_vars, eigen_row_vector_var_arg) { = stan::math::deep_copy_vars(arg); for (int i = 0; i < arg.size(); ++i) { + stan::math::set_zero_all_adjoints(); + arg(i).vi_->adj_ = 2.0; + + out(i).grad(); + + EXPECT_EQ(out(i).vi_->adj_, 1.0); + EXPECT_EQ(arg(i).vi_->adj_, 2.0); EXPECT_EQ(out(i), arg(i)); EXPECT_NE(out(i).vi_, arg(i).vi_); } @@ -171,6 +198,13 @@ TEST(AgradRev_deep_copy_vars, eigen_matrix_var_arg) { = stan::math::deep_copy_vars(arg); for (int i = 0; i < arg.size(); ++i) { + stan::math::set_zero_all_adjoints(); + arg(i).vi_->adj_ = 2.0; + + out(i).grad(); + + EXPECT_EQ(out(i).vi_->adj_, 1.0); + EXPECT_EQ(arg(i).vi_->adj_, 2.0); EXPECT_EQ(out(i), arg(i)); EXPECT_NE(out(i).vi_, arg(i).vi_); } @@ -188,6 +222,13 @@ TEST(AgradRev_deep_copy_vars, std_vector_std_vector_var_arg) { for (int i = 0; i < arg.size(); ++i) for (int j = 0; j < arg[i].size(); ++j) { + stan::math::set_zero_all_adjoints(); + arg[i][j].vi_->adj_ = 2.0; + + out[i][j].grad(); + + EXPECT_EQ(out[i][j].vi_->adj_, 1.0); + EXPECT_EQ(arg[i][j].vi_->adj_, 2.0); EXPECT_EQ(out[i][j], arg[i][j]); EXPECT_NE(out[i][j].vi_, arg[i][j].vi_); } @@ -205,6 +246,13 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_vector_var_arg) { for (int i = 0; i < arg.size(); ++i) for (int j = 0; j < arg[i].size(); ++j) { + stan::math::set_zero_all_adjoints(); + arg[i](j).vi_->adj_ = 2.0; + + out[i](j).grad(); + + EXPECT_EQ(out[i](j).vi_->adj_, 1.0); + EXPECT_EQ(arg[i](j).vi_->adj_, 2.0); EXPECT_EQ(out[i](j), arg[i](j)); EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); } @@ -222,6 +270,13 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_row_vector_var_arg) { for (int i = 0; i < arg.size(); ++i) for (int j = 0; j < arg[i].size(); ++j) { + stan::math::set_zero_all_adjoints(); + arg[i](j).vi_->adj_ = 2.0; + + out[i](j).grad(); + + EXPECT_EQ(out[i](j).vi_->adj_, 1.0); + EXPECT_EQ(arg[i](j).vi_->adj_, 2.0); EXPECT_EQ(out[i](j), arg[i](j)); EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); } @@ -239,6 +294,13 @@ TEST(AgradRev_deep_copy_vars, std_vector_eigen_matrix_var_arg) { for (int i = 0; i < arg.size(); ++i) for (int j = 0; j < arg[i].size(); ++j) { + stan::math::set_zero_all_adjoints(); + arg[i](j).vi_->adj_ = 2.0; + + out[i](j).grad(); + + EXPECT_EQ(out[i](j).vi_->adj_, 1.0); + EXPECT_EQ(arg[i](j).vi_->adj_, 2.0); EXPECT_EQ(out[i](j), arg[i](j)); EXPECT_NE(out[i](j).vi_, arg[i](j).vi_); } From 083de0aabd306e6df0cca6db9478825ac7d0a37f Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Fri, 27 Mar 2020 21:08:26 +0000 Subject: [PATCH 07/11] [Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (tags/RELEASE_500/final) --- stan/math/opencl/kernel_generator/load.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stan/math/opencl/kernel_generator/load.hpp b/stan/math/opencl/kernel_generator/load.hpp index ae0f7d1eb6d..799cdb551a0 100644 --- a/stan/math/opencl/kernel_generator/load.hpp +++ b/stan/math/opencl/kernel_generator/load.hpp @@ -49,7 +49,7 @@ class load_ * Creates a deep copy of this expression. * @return copy of \c *this */ - inline load_ deep_copy() const& { return load_(a_); } + inline load_ deep_copy() const & { return load_(a_); } inline load_ deep_copy() && { return load_(std::forward(a_)); } /** From 32ef30fbbc95529a1d661a7222241c6ca84a07c6 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Fri, 27 Mar 2020 17:09:11 -0400 Subject: [PATCH 08/11] [Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/stable/2017-11-14) --- stan/math/opencl/kernel_generator/load.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stan/math/opencl/kernel_generator/load.hpp b/stan/math/opencl/kernel_generator/load.hpp index 799cdb551a0..ae0f7d1eb6d 100644 --- a/stan/math/opencl/kernel_generator/load.hpp +++ b/stan/math/opencl/kernel_generator/load.hpp @@ -49,7 +49,7 @@ class load_ * Creates a deep copy of this expression. * @return copy of \c *this */ - inline load_ deep_copy() const & { return load_(a_); } + inline load_ deep_copy() const& { return load_(a_); } inline load_ deep_copy() && { return load_(std::forward(a_)); } /** From e28b18adc3e54032b523d3105d88394da911f8c2 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 30 Mar 2020 11:00:51 -0400 Subject: [PATCH 09/11] Added zero argument test for save_varis Moved count_vars_impl to internal namespace Added empty tuple test for apply (for reduce_sum, design-doc #17) --- stan/math/rev/core/count_vars.hpp | 236 ++++++++++---------- test/unit/math/prim/functor/apply_test.cpp | 9 + test/unit/math/rev/core/save_varis_test.cpp | 11 + 3 files changed, 139 insertions(+), 117 deletions(-) diff --git a/stan/math/rev/core/count_vars.hpp b/stan/math/rev/core/count_vars.hpp index fbd7557bcf5..e3e53a6f83d 100644 --- a/stan/math/rev/core/count_vars.hpp +++ b/stan/math/rev/core/count_vars.hpp @@ -11,128 +11,130 @@ namespace stan { namespace math { -template * = nullptr, - typename... Pargs> -inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args); - -template * = nullptr, - require_std_vector_vt* = nullptr, - typename... Pargs> -inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args); - -template * = nullptr, - typename... Pargs> -inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args); - -template -inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args); - -template >* = nullptr, - typename... Pargs> -inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args); - -inline size_t count_vars_impl(size_t count); - -/** - * Count the number of vars in x (a std::vector of vars), - * add it to the running total, - * count the number of vars in the remaining arguments - * and return the result. - * - * @tparam VecVar type of standard container holding vars - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x A std::vector holding vars. - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ -template *, - typename... Pargs> -inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args) { - return count_vars_impl(count + x.size(), std::forward(args)...); -} +namespace internal { + template * = nullptr, + typename... Pargs> + inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args); + + template * = nullptr, + require_std_vector_vt* = nullptr, + typename... Pargs> + inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args); + + template * = nullptr, + typename... Pargs> + inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args); + + template + inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args); + + template >* = nullptr, + typename... Pargs> + inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args); + + inline size_t count_vars_impl(size_t count); + + /** + * Count the number of vars in x (a std::vector of vars), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam VecVar type of standard container holding vars + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A std::vector holding vars. + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ + template *, + typename... Pargs> + inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args) { + return count_vars_impl(count + x.size(), std::forward(args)...); + } -/** - * Count the number of vars in x (a std::vector holding other containers), - * add it to the running total, - * count the number of vars in the remaining arguments - * and return the result. - * - * @tparam VecContainer std::vector holding arguments which contain Vars - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x A vector holding containers of vars - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ -template *, - require_std_vector_vt*, typename... Pargs> -inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args) { - for (auto&& x_iter : x) { - count = count_vars_impl(count, x_iter); + /** + * Count the number of vars in x (a std::vector holding other containers), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam VecContainer std::vector holding arguments which contain Vars + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A vector holding containers of vars + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ + template *, + require_std_vector_vt*, typename... Pargs> + inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args) { + for (auto&& x_iter : x) { + count = count_vars_impl(count, x_iter); + } + return count_vars_impl(count, std::forward(args)...); } - return count_vars_impl(count, std::forward(args)...); -} -/** - * Count the number of vars in x (an eigen container), - * add it to the running total, - * count the number of vars in the remaining arguments - * and return the result. - * - * @tparam EigT A type derived from `EigenBase` - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x An Eigen container holding vars - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ -template *, typename... Pargs> -inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args) { - return count_vars_impl(count + x.size(), std::forward(args)...); -} + /** + * Count the number of vars in x (an eigen container), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam EigT A type derived from `EigenBase` + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x An Eigen container holding vars + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ + template *, typename... Pargs> + inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args) { + return count_vars_impl(count + x.size(), std::forward(args)...); + } -/** - * Add one to the running total number of vars, - * count the number of vars in the remaining arguments - * and return the result. - * - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x A var - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ -template -inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args) { - return count_vars_impl(count + 1, std::forward(args)...); -} + /** + * Add one to the running total number of vars, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A var + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ + template + inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args) { + return count_vars_impl(count + 1, std::forward(args)...); + } -/** - * Arguments without vars contribute zero to the total number of vars. - * - * Return the running total number of vars plus the number of - * vars in the remaining aruments. - * - * @tparam Arith An object that is either arithmetic or holds arithmetic - * types - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x An arithmetic value or container - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ -template >*, - typename... Pargs> -inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args) { - return count_vars_impl(count, std::forward(args)...); -} + /** + * Arguments without vars contribute zero to the total number of vars. + * + * Return the running total number of vars plus the number of + * vars in the remaining aruments. + * + * @tparam Arith An object that is either arithmetic or holds arithmetic + * types + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x An arithmetic value or container + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ + template >*, + typename... Pargs> + inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args) { + return count_vars_impl(count, std::forward(args)...); + } -/** - * End count_vars_impl recursion and return total number of counted vars - */ -inline size_t count_vars_impl(size_t count) { return count; } + /** + * End count_vars_impl recursion and return total number of counted vars + */ + inline size_t count_vars_impl(size_t count) { return count; } +} // namespace internal /** * Count the number of vars in the input argument list @@ -142,7 +144,7 @@ inline size_t count_vars_impl(size_t count) { return count; } */ template inline size_t count_vars(Pargs&&... args) { - return count_vars_impl(0, std::forward(args)...); + return internal::count_vars_impl(0, std::forward(args)...); } } // namespace math diff --git a/test/unit/math/prim/functor/apply_test.cpp b/test/unit/math/prim/functor/apply_test.cpp index 429da239920..1eabbc1f315 100644 --- a/test/unit/math/prim/functor/apply_test.cpp +++ b/test/unit/math/prim/functor/apply_test.cpp @@ -11,6 +11,15 @@ struct func { } }; +TEST(MathFunctions, apply_basic_empty) { + std::tuple<> x; + + auto y = stan::math::apply([]() { return static_cast(1.7); }, x); + + EXPECT_EQ(1.7, y); + EXPECT_TRUE((std::is_same::value)); +} + TEST(MathFunctions, apply_basic_double) { std::tuple x = std::make_tuple(1.0); diff --git a/test/unit/math/rev/core/save_varis_test.cpp b/test/unit/math/rev/core/save_varis_test.cpp index 95decf54868..e7740d15cbc 100644 --- a/test/unit/math/rev/core/save_varis_test.cpp +++ b/test/unit/math/rev/core/save_varis_test.cpp @@ -5,6 +5,17 @@ using stan::math::var; using stan::math::vari; +TEST(AgradRev_save_varis, zero_args) { + std::vector storage(1000, nullptr); + vari** ptr = stan::math::save_varis(storage.data()); + + for (int i = 0; i < storage.size(); ++i) + EXPECT_EQ(storage[i], nullptr); + + EXPECT_EQ(ptr, storage.data()); + stan::math::recover_memory(); +} + TEST(AgradRev_save_varis, int_arg) { int arg = 5; From 8803029a67b68a9a8b8d581b94bed3aa37b037b9 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Mon, 30 Mar 2020 11:03:02 -0400 Subject: [PATCH 10/11] [Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~exp1~20180509124008.99 (branches/release_50) --- stan/math/opencl/kernel_generator/load.hpp | 2 +- stan/math/rev/core/count_vars.hpp | 232 ++++++++++----------- 2 files changed, 117 insertions(+), 117 deletions(-) diff --git a/stan/math/opencl/kernel_generator/load.hpp b/stan/math/opencl/kernel_generator/load.hpp index ae0f7d1eb6d..799cdb551a0 100644 --- a/stan/math/opencl/kernel_generator/load.hpp +++ b/stan/math/opencl/kernel_generator/load.hpp @@ -49,7 +49,7 @@ class load_ * Creates a deep copy of this expression. * @return copy of \c *this */ - inline load_ deep_copy() const& { return load_(a_); } + inline load_ deep_copy() const & { return load_(a_); } inline load_ deep_copy() && { return load_(std::forward(a_)); } /** diff --git a/stan/math/rev/core/count_vars.hpp b/stan/math/rev/core/count_vars.hpp index e3e53a6f83d..b0b536a27ab 100644 --- a/stan/math/rev/core/count_vars.hpp +++ b/stan/math/rev/core/count_vars.hpp @@ -12,128 +12,128 @@ namespace stan { namespace math { namespace internal { - template * = nullptr, - typename... Pargs> - inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args); - - template * = nullptr, - require_std_vector_vt* = nullptr, - typename... Pargs> - inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args); - - template * = nullptr, - typename... Pargs> - inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args); - - template - inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args); - - template >* = nullptr, - typename... Pargs> - inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args); - - inline size_t count_vars_impl(size_t count); - - /** - * Count the number of vars in x (a std::vector of vars), - * add it to the running total, - * count the number of vars in the remaining arguments - * and return the result. - * - * @tparam VecVar type of standard container holding vars - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x A std::vector holding vars. - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ - template *, - typename... Pargs> - inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args) { - return count_vars_impl(count + x.size(), std::forward(args)...); - } +template * = nullptr, + typename... Pargs> +inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args); - /** - * Count the number of vars in x (a std::vector holding other containers), - * add it to the running total, - * count the number of vars in the remaining arguments - * and return the result. - * - * @tparam VecContainer std::vector holding arguments which contain Vars - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x A vector holding containers of vars - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ - template *, - require_std_vector_vt*, typename... Pargs> - inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args) { - for (auto&& x_iter : x) { - count = count_vars_impl(count, x_iter); - } - return count_vars_impl(count, std::forward(args)...); - } +template * = nullptr, + require_std_vector_vt* = nullptr, + typename... Pargs> +inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args); - /** - * Count the number of vars in x (an eigen container), - * add it to the running total, - * count the number of vars in the remaining arguments - * and return the result. - * - * @tparam EigT A type derived from `EigenBase` - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x An Eigen container holding vars - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ - template *, typename... Pargs> - inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args) { - return count_vars_impl(count + x.size(), std::forward(args)...); - } +template * = nullptr, + typename... Pargs> +inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args); - /** - * Add one to the running total number of vars, - * count the number of vars in the remaining arguments - * and return the result. - * - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x A var - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ - template - inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args) { - return count_vars_impl(count + 1, std::forward(args)...); - } +template +inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args); + +template >* = nullptr, + typename... Pargs> +inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args); + +inline size_t count_vars_impl(size_t count); + +/** + * Count the number of vars in x (a std::vector of vars), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam VecVar type of standard container holding vars + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A std::vector holding vars. + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template *, + typename... Pargs> +inline size_t count_vars_impl(size_t count, VecVar&& x, Pargs&&... args) { + return count_vars_impl(count + x.size(), std::forward(args)...); +} - /** - * Arguments without vars contribute zero to the total number of vars. - * - * Return the running total number of vars plus the number of - * vars in the remaining aruments. - * - * @tparam Arith An object that is either arithmetic or holds arithmetic - * types - * @tparam Pargs Types of remaining arguments - * @param[in] count The current count of the number of vars - * @param[in] x An arithmetic value or container - * @param[in] args objects to be forwarded to recursive call of - * `count_vars_impl` - */ - template >*, - typename... Pargs> - inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args) { - return count_vars_impl(count, std::forward(args)...); +/** + * Count the number of vars in x (a std::vector holding other containers), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam VecContainer std::vector holding arguments which contain Vars + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A vector holding containers of vars + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template *, + require_std_vector_vt*, typename... Pargs> +inline size_t count_vars_impl(size_t count, VecContainer&& x, Pargs&&... args) { + for (auto&& x_iter : x) { + count = count_vars_impl(count, x_iter); } + return count_vars_impl(count, std::forward(args)...); +} - /** - * End count_vars_impl recursion and return total number of counted vars - */ - inline size_t count_vars_impl(size_t count) { return count; } +/** + * Count the number of vars in x (an eigen container), + * add it to the running total, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam EigT A type derived from `EigenBase` + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x An Eigen container holding vars + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template *, typename... Pargs> +inline size_t count_vars_impl(size_t count, EigT&& x, Pargs&&... args) { + return count_vars_impl(count + x.size(), std::forward(args)...); +} + +/** + * Add one to the running total number of vars, + * count the number of vars in the remaining arguments + * and return the result. + * + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x A var + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template +inline size_t count_vars_impl(size_t count, const var& x, Pargs&&... args) { + return count_vars_impl(count + 1, std::forward(args)...); +} + +/** + * Arguments without vars contribute zero to the total number of vars. + * + * Return the running total number of vars plus the number of + * vars in the remaining aruments. + * + * @tparam Arith An object that is either arithmetic or holds arithmetic + * types + * @tparam Pargs Types of remaining arguments + * @param[in] count The current count of the number of vars + * @param[in] x An arithmetic value or container + * @param[in] args objects to be forwarded to recursive call of + * `count_vars_impl` + */ +template >*, + typename... Pargs> +inline size_t count_vars_impl(size_t count, Arith& x, Pargs&&... args) { + return count_vars_impl(count, std::forward(args)...); +} + +/** + * End count_vars_impl recursion and return total number of counted vars + */ +inline size_t count_vars_impl(size_t count) { return count; } } // namespace internal /** From 58a7626a748c8d03da91f8c5bf113f9cf29928c9 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Tue, 31 Mar 2020 05:48:33 -0400 Subject: [PATCH 11/11] [Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/stable/2017-11-14) --- stan/math/opencl/kernel_generator/load.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stan/math/opencl/kernel_generator/load.hpp b/stan/math/opencl/kernel_generator/load.hpp index 799cdb551a0..ae0f7d1eb6d 100644 --- a/stan/math/opencl/kernel_generator/load.hpp +++ b/stan/math/opencl/kernel_generator/load.hpp @@ -49,7 +49,7 @@ class load_ * Creates a deep copy of this expression. * @return copy of \c *this */ - inline load_ deep_copy() const & { return load_(a_); } + inline load_ deep_copy() const& { return load_(a_); } inline load_ deep_copy() && { return load_(std::forward(a_)); } /**