Skip to content

Commit d5c2cb5

Browse files
t4c1yashiknostan-buildbot
authored
Add holder (#1914)
* implemented holder * use holder in funcs * [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2 (tags/RELEASE_600/final) * fixed xplicit constructor and non-unique test name * another explicit constructor * missing include * added missing typedef * addressed review comments * [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2 (tags/RELEASE_600/final) * [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2 (tags/RELEASE_600/final) * bugfix to_ref and add more tests * addressed second batch of comments. * [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) * bugfix * simplified evaluator flags * [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) * added extended doc * fixed doxygen * [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2 (tags/RELEASE_600/final) * added an example * [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2 (tags/RELEASE_600/final) * grammar Co-authored-by: Jenkins <nobody@nowhere> Co-authored-by: Stan Jenkins <[email protected]>
1 parent a77c5bf commit d5c2cb5

File tree

12 files changed

+684
-57
lines changed

12 files changed

+684
-57
lines changed

stan/math/opencl/kernel_generator/holder_cl.hpp

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -74,35 +74,6 @@ auto holder_cl(T&& a, Ptrs*... ptrs) {
7474
}
7575

7676
namespace internal {
77-
/**
78-
* Handles single element (moving rvalues to heap) for construction of
79-
* `holder_cl` from a functor. For lvalues just sets the `res` pointer.
80-
* @tparam T type of the element
81-
* @param a element to handle
82-
* @param res resulting pointer to element
83-
* @return tuple of pointer allocated on heap (empty).
84-
*/
85-
template <typename T>
86-
auto holder_cl_handle_element(const T& a, const T*& res) {
87-
res = &a;
88-
return std::make_tuple();
89-
}
90-
91-
/**
92-
* Handles single element (moving rvalues to heap) for construction of
93-
* `holder_cl` from a functor. Rvalue is moved to heap and the pointer to heap
94-
* memory is assigned to res and returned in a tuple.
95-
* @tparam T type of the element
96-
* @param a element to handle
97-
* @param res resulting pointer to element
98-
* @return tuple of pointer allocated on heap (containing single pointer).
99-
*/
100-
template <typename T>
101-
auto holder_cl_handle_element(std::remove_reference_t<T>&& a, const T*& res) {
102-
res = new T(std::move(a));
103-
return std::make_tuple(res);
104-
}
105-
10677
/**
10778
* Second step in implementation of construction `holder_cl` from a functor.
10879
* @tparam T type of the result expression
@@ -114,8 +85,8 @@ auto holder_cl_handle_element(std::remove_reference_t<T>&& a, const T*& res) {
11485
* @return `holder_cl` referencing given expression
11586
*/
11687
template <typename T, std::size_t... Is, typename... Args>
117-
auto make_holder_cl_impl2(T&& expr, std::index_sequence<Is...>,
118-
const std::tuple<Args*...>& ptrs) {
88+
auto make_holder_cl_impl_step2(T&& expr, std::index_sequence<Is...>,
89+
const std::tuple<Args*...>& ptrs) {
11990
return holder_cl(std::forward<T>(expr), std::get<Is>(ptrs)...);
12091
}
12192

@@ -129,12 +100,12 @@ auto make_holder_cl_impl2(T&& expr, std::index_sequence<Is...>,
129100
* @return `holder_cl` referencing given expression
130101
*/
131102
template <typename T, std::size_t... Is, typename... Args>
132-
auto make_holder_cl_impl(const T& func, std::index_sequence<Is...>,
133-
Args&&... args) {
134-
std::tuple<const std::remove_reference_t<Args>*...> res;
103+
auto make_holder_cl_impl_step1(const T& func, std::index_sequence<Is...>,
104+
Args&&... args) {
105+
std::tuple<std::remove_reference_t<Args>*...> res;
135106
auto ptrs = std::tuple_cat(
136-
holder_cl_handle_element(std::forward<Args>(args), std::get<Is>(res))...);
137-
return make_holder_cl_impl2(
107+
holder_handle_element(std::forward<Args>(args), std::get<Is>(res))...);
108+
return make_holder_cl_impl_step2(
138109
func(*std::get<Is>(res)...),
139110
std::make_index_sequence<std::tuple_size<decltype(ptrs)>::value>(), ptrs);
140111
}
@@ -156,7 +127,7 @@ template <typename T, typename... Args,
156127
decltype(std::declval<T>()(std::declval<Args&>()...)),
157128
Args...>* = nullptr>
158129
auto make_holder_cl(const T& func, Args&&... args) {
159-
return internal::make_holder_cl_impl(
130+
return internal::make_holder_cl_impl_step1(
160131
func, std::make_index_sequence<sizeof...(Args)>(),
161132
std::forward<Args>(args)...);
162133
}

stan/math/prim/fun/value_of.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,12 @@ inline Vec value_of(Vec&& x) {
106106
**/
107107
template <typename EigMat, require_eigen_t<EigMat>* = nullptr,
108108
require_not_vt_double_or_int<EigMat>* = nullptr>
109-
inline auto value_of(const EigMat& M) {
110-
return M.unaryExpr([](const auto& scal) { return value_of(scal); });
109+
inline auto value_of(EigMat&& M) {
110+
return make_holder(
111+
[](auto& a) {
112+
return a.unaryExpr([](const auto& scal) { return value_of(scal); });
113+
},
114+
std::forward<EigMat>(M));
111115
}
112116

113117
/**

stan/math/prim/fun/value_of_rec.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,12 @@ inline T value_of_rec(T&& x) {
104104
**/
105105
template <typename T, typename = require_not_st_same<T, double>,
106106
typename = require_eigen_t<T>>
107-
inline auto value_of_rec(const T& M) {
108-
return M.unaryExpr([](auto x) { return value_of_rec(x); });
107+
inline auto value_of_rec(T&& M) {
108+
return make_holder(
109+
[](auto& m) {
110+
return m.unaryExpr([](auto x) { return value_of_rec(x); });
111+
},
112+
std::forward<T>(M));
109113
}
110114

111115
/**

stan/math/prim/meta.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@
179179
#include <stan/math/prim/meta/contains_vector.hpp>
180180
#include <stan/math/prim/meta/error_index.hpp>
181181
#include <stan/math/prim/meta/forward_as.hpp>
182+
#include <stan/math/prim/meta/holder.hpp>
182183
#include <stan/math/prim/meta/include_summand.hpp>
183184
#include <stan/math/prim/meta/index_type.hpp>
184185
#include <stan/math/prim/meta/index_apply.hpp>

stan/math/prim/meta/as_array_or_scalar.hpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#define STAN_MATH_PRIM_META_AS_ARRAY_OR_SCALAR_HPP
33

44
#include <stan/math/prim/fun/Eigen.hpp>
5+
#include <stan/math/prim/meta/holder.hpp>
6+
#include <stan/math/prim/meta/is_vector.hpp>
57
#include <stan/math/prim/meta/is_eigen.hpp>
68
#include <stan/math/prim/meta/is_stan_scalar.hpp>
79
#include <vector>
@@ -29,8 +31,8 @@ inline T as_array_or_scalar(T&& v) {
2931
* @return Matrix converted to an array.
3032
*/
3133
template <typename T, typename = require_eigen_t<T>>
32-
inline auto as_array_or_scalar(const T& v) {
33-
return v.array();
34+
inline auto as_array_or_scalar(T&& v) {
35+
return make_holder([](auto& x) { return x.array(); }, std::forward<T>(v));
3436
}
3537

3638
/** \ingroup type_trait
@@ -40,11 +42,12 @@ inline auto as_array_or_scalar(const T& v) {
4042
* @param v Specified vector.
4143
* @return Matrix converted to an array.
4244
*/
43-
template <typename T>
44-
inline Eigen::Map<const Eigen::Array<T, Eigen::Dynamic, 1>> as_array_or_scalar(
45-
const std::vector<T>& v) {
46-
return Eigen::Map<const Eigen::Array<T, Eigen::Dynamic, 1>>(v.data(),
47-
v.size());
45+
template <typename T, require_std_vector_t<T>* = nullptr>
46+
inline auto as_array_or_scalar(T&& v) {
47+
using T_map
48+
= Eigen::Map<const Eigen::Array<value_type_t<T>, Eigen::Dynamic, 1>>;
49+
return make_holder([](auto& x) { return T_map(x.data(), x.size()); },
50+
std::forward<T>(v));
4851
}
4952

5053
} // namespace math

stan/math/prim/meta/as_column_vector_or_scalar.hpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define STAN_MATH_PRIM_META_AS_COLUMN_VECTOR_OR_SCALAR_HPP
33

44
#include <stan/math/prim/fun/Eigen.hpp>
5+
#include <stan/math/prim/meta/holder.hpp>
56
#include <stan/math/prim/meta/is_stan_scalar.hpp>
67
#include <stan/math/prim/meta/is_eigen.hpp>
78
#include <stan/math/prim/meta/is_vector.hpp>
@@ -16,11 +17,11 @@ namespace math {
1617
*
1718
* @tparam T Type of scalar element.
1819
* @param a Specified scalar.
19-
* @return 1x1 matrix that contains the value of scalar.
20+
* @return the scalar.
2021
*/
2122
template <typename T, require_stan_scalar_t<T>* = nullptr>
22-
inline T&& as_column_vector_or_scalar(T&& a) {
23-
return std::forward<T>(a);
23+
inline T as_column_vector_or_scalar(const T& a) {
24+
return a;
2425
}
2526

2627
/** \ingroup type_trait
@@ -46,7 +47,7 @@ inline T&& as_column_vector_or_scalar(T&& a) {
4647
*/
4748
template <typename T, require_t<is_eigen_row_vector<T>>* = nullptr>
4849
inline auto as_column_vector_or_scalar(T&& a) {
49-
return a.transpose();
50+
return make_holder([](auto& x) { return x.transpose(); }, std::forward<T>(a));
5051
}
5152

5253
/** \ingroup type_trait
@@ -63,7 +64,9 @@ inline auto as_column_vector_or_scalar(T&& a) {
6364
using optionally_const_vector
6465
= std::conditional_t<std::is_const<std::remove_reference_t<T>>::value,
6566
const plain_vector, plain_vector>;
66-
return Eigen::Map<optionally_const_vector>(a.data(), a.size());
67+
using T_map = Eigen::Map<optionally_const_vector>;
68+
return make_holder([](auto& x) { return T_map(x.data(), x.size()); },
69+
std::forward<T>(a));
6770
}
6871

6972
} // namespace math

0 commit comments

Comments
 (0)