Skip to content

Commit 4ce8c4f

Browse files
committed
Merge commit 'a426eea0ec9d9a7547061bc776a08e509d3406f3' into HEAD
2 parents ef5ee47 + a426eea commit 4ce8c4f

25 files changed

Lines changed: 1426 additions & 15 deletions

.github/workflows/header_checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,5 @@ jobs:
7878

7979
- name: Run header tests
8080
run: |
81-
echo "CXXFLAGS+=-DSTAN_NO_RANGE_CHECKS" > make/local
81+
echo "STAN_NO_RANGE_CHECKS=true" > make/local
8282
./runTests.py -j2 ./test/unit/math/prim/err/

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ directory `/path/to/math/lib/tbb` as absolute path to the system-wide
111111
Intel TBB
112112
---------
113113

114-
`math` now supports the new interface of Intel TBB and allows using external library (e.g., with [`oneTBB`](https://github.com/oneapi-src/oneTBB) or the system TBB library), using `TBB_LIB` and `TBB_INC` environment variables.
114+
`math` supports the new interface of Intel TBB, can be configured to use an external copy of TBB (e.g., with [`oneTBB`](https://github.com/oneapi-src/oneTBB) or the system TBB library), using the `TBB_LIB` and `TBB_INC` environment variables.
115115

116116
To build the development version of `math` with [`oneTBB`](https://github.com/oneapi-src/oneTBB):
117117

@@ -121,7 +121,7 @@ For example, installing [`oneTBB`](https://github.com/oneapi-src/oneTBB) on Linu
121121
```bash
122122
TBB_VERSION="2021.1.1"
123123

124-
wget https://github.com/oneapi-src/oneTBB/releases/download/v2021.1.1/oneapi-tbb-$TBB_VERSION-lin.tgz
124+
wget https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/oneapi-tbb-${TBB_VERSION}-lin.tgz
125125
tar zxvf oneapi-tbb-$TBB_VERSION-lin.tgz -C $HOME
126126

127127
export TBB="$HOME/oneapi-tbb-$TBB_VERSION"

make/compiler_flags

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ CXX_MINOR := $(word 2,$(subst ., ,$(CXX_VERSION)))
9090
# LDFLAGS_MPI_FLTO: For adding flto options to MPI build
9191
##
9292

93+
ifdef STAN_NO_RANGE_CHECKS
94+
CXXFLAGS_THREADS ?= -DSTAN_NO_RANGE_CHECKS
95+
endif
96+
9397
################################################################################
9498
# Set default compiler flags
9599
#

stan/math/opencl/kernel_generator/multi_result_kernel.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ struct multi_result_kernel_internal {
7878
if (is_colwise_reduction<T_current_expression>::value
7979
&& expression_cols == -1) {
8080
expression_cols = n_cols;
81+
expression_rows = expression.thread_rows();
8182
expression_rows = internal::colwise_reduction_wgs_rows(
82-
expression.thread_rows(), expression_cols);
83+
expression_rows < 0 ? n_rows : expression_rows, expression_cols);
8384
} else if (is_reduction_2d<T_current_expression>::value
8485
&& expression_cols == -1) {
8586
expression_rows = internal::colwise_reduction_wgs_rows(n_rows, n_cols);

stan/math/opencl/prim.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@
100100

101101
#include <stan/math/opencl/prim/add_diag.hpp>
102102
#include <stan/math/opencl/prim/append_array.hpp>
103+
#include <stan/math/opencl/prim/bernoulli_cdf.hpp>
104+
#include <stan/math/opencl/prim/bernoulli_lccdf.hpp>
105+
#include <stan/math/opencl/prim/bernoulli_lcdf.hpp>
103106
#include <stan/math/opencl/prim/bernoulli_lpmf.hpp>
104107
#include <stan/math/opencl/prim/bernoulli_logit_lpmf.hpp>
105108
#include <stan/math/opencl/prim/bernoulli_logit_glm_lpmf.hpp>
@@ -110,6 +113,9 @@
110113
#include <stan/math/opencl/prim/binomial_lpmf.hpp>
111114
#include <stan/math/opencl/prim/block.hpp>
112115
#include <stan/math/opencl/prim/categorical_logit_glm_lpmf.hpp>
116+
#include <stan/math/opencl/prim/cauchy_cdf.hpp>
117+
#include <stan/math/opencl/prim/cauchy_lccdf.hpp>
118+
#include <stan/math/opencl/prim/cauchy_lcdf.hpp>
113119
#include <stan/math/opencl/prim/cauchy_lpdf.hpp>
114120
#include <stan/math/opencl/prim/chi_square_lpdf.hpp>
115121
#include <stan/math/opencl/prim/cholesky_decompose.hpp>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#ifndef STAN_MATH_OPENCL_PRIM_BERNOULLI_CDF_HPP
2+
#define STAN_MATH_OPENCL_PRIM_BERNOULLI_CDF_HPP
3+
#ifdef STAN_OPENCL
4+
5+
#include <stan/math/prim/meta.hpp>
6+
#include <stan/math/prim/err.hpp>
7+
#include <stan/math/opencl/kernel_generator.hpp>
8+
#include <stan/math/prim/fun/constants.hpp>
9+
#include <stan/math/prim/functor/operands_and_partials.hpp>
10+
11+
namespace stan {
12+
namespace math {
13+
14+
/** \ingroup prob_dists
15+
* Returns the CDF of the Bernoulli distribution. If containers are
16+
* supplied, returns the product of the probabilities.
17+
*
18+
* @tparam T_n_cl type of integer parameter
19+
* @tparam T_prob_cl type of chance of success parameter
20+
* @param n integer parameter
21+
* @param theta logit-transformed chance of success parameter
22+
* @return log probability or log sum of probabilities
23+
* @throw std::domain_error if theta is not a valid probability
24+
* @throw std::invalid_argument if container sizes mismatch.
25+
*/
26+
template <
27+
typename T_n_cl, typename T_prob_cl,
28+
require_all_prim_or_rev_kernel_expression_t<T_n_cl, T_prob_cl>* = nullptr,
29+
require_any_not_stan_scalar_t<T_n_cl, T_prob_cl>* = nullptr>
30+
return_type_t<T_prob_cl> bernoulli_cdf(const T_n_cl& n,
31+
const T_prob_cl& theta) {
32+
static const char* function = "bernoulli_cdf(OpenCL)";
33+
using T_partials_return = partials_return_t<T_prob_cl>;
34+
using std::isnan;
35+
constexpr bool is_n_vector = !is_stan_scalar<T_n_cl>::value;
36+
constexpr bool is_theta_vector = !is_stan_scalar<T_prob_cl>::value;
37+
38+
check_consistent_sizes(function, "Random variable", n,
39+
"Probability parameter", theta);
40+
const size_t N = is_n_vector ? size(n) : size(theta);
41+
if (N == 0) {
42+
return 1.0;
43+
}
44+
45+
const auto& theta_col = as_column_vector_or_scalar(theta);
46+
const auto& theta_val = value_of(theta_col);
47+
48+
auto check_theta_bounded = check_cl(function, "Probability parameter",
49+
theta_val, "in the interval [0, 1]");
50+
auto theta_bounded_expr = 0.0 <= theta_val && theta_val <= 1.0;
51+
52+
auto any_n_negative = colwise_max(constant(0, N, 1) + (n < 0));
53+
auto cond = n >= 1;
54+
auto Pi_uncond = 1.0 - theta_val;
55+
auto Pi = select(cond, INFTY, Pi_uncond);
56+
auto P_expr = colwise_prod(select(cond, 1.0, Pi_uncond));
57+
58+
matrix_cl<double> any_n_negative_cl;
59+
matrix_cl<double> Pi_cl;
60+
matrix_cl<double> P_cl;
61+
62+
results(check_theta_bounded, any_n_negative_cl, Pi_cl, P_cl)
63+
= expressions(theta_bounded_expr, any_n_negative,
64+
calc_if<(!is_constant_all<T_prob_cl>::value)>(Pi), P_expr);
65+
66+
if (from_matrix_cl(any_n_negative_cl).maxCoeff()) {
67+
return 0.0;
68+
}
69+
70+
T_partials_return P = from_matrix_cl(P_cl).prod();
71+
operands_and_partials<decltype(theta_col)> ops_partials(theta_col);
72+
73+
if (!is_constant_all<T_prob_cl>::value) {
74+
ops_partials.edge1_.partials_ = elt_divide(-P, Pi_cl);
75+
}
76+
77+
return ops_partials.build(P);
78+
}
79+
80+
} // namespace math
81+
} // namespace stan
82+
#endif
83+
#endif
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#ifndef STAN_MATH_OPENCL_PRIM_BERNOULLI_LCCDF_HPP
2+
#define STAN_MATH_OPENCL_PRIM_BERNOULLI_LCCDF_HPP
3+
#ifdef STAN_OPENCL
4+
5+
#include <stan/math/prim/meta.hpp>
6+
#include <stan/math/prim/err.hpp>
7+
#include <stan/math/opencl/kernel_generator.hpp>
8+
#include <stan/math/prim/fun/constants.hpp>
9+
#include <stan/math/prim/fun/elt_divide.hpp>
10+
#include <stan/math/prim/functor/operands_and_partials.hpp>
11+
12+
namespace stan {
13+
namespace math {
14+
15+
/** \ingroup prob_dists
16+
* Returns the log CCDF of the Bernoulli distribution. If containers are
17+
* supplied, returns the log sum of the probabilities.
18+
*
19+
* @tparam T_n_cl type of integer parameter
20+
* @tparam T_prob_cl type of chance of success parameter
21+
* @param n integer parameter
22+
* @param theta logit-transformed chance of success parameter
23+
* @return log probability or log sum of probabilities
24+
* @throw std::domain_error if theta is not a valid probability
25+
* @throw std::invalid_argument if container sizes mismatch.
26+
*/
27+
template <
28+
typename T_n_cl, typename T_prob_cl,
29+
require_all_prim_or_rev_kernel_expression_t<T_n_cl, T_prob_cl>* = nullptr,
30+
require_any_not_stan_scalar_t<T_n_cl, T_prob_cl>* = nullptr>
31+
return_type_t<T_prob_cl> bernoulli_lccdf(const T_n_cl& n,
32+
const T_prob_cl& theta) {
33+
static const char* function = "bernoulli_lccdf(OpenCL)";
34+
using T_partials_return = partials_return_t<T_prob_cl>;
35+
using std::isnan;
36+
constexpr bool is_n_vector = !is_stan_scalar<T_n_cl>::value;
37+
constexpr bool is_theta_vector = !is_stan_scalar<T_prob_cl>::value;
38+
39+
check_consistent_sizes(function, "Random variable", n,
40+
"Probability parameter", theta);
41+
const size_t N = is_n_vector ? size(n) : size(theta);
42+
if (N == 0) {
43+
return 0.0;
44+
}
45+
46+
const auto& theta_col = as_column_vector_or_scalar(theta);
47+
const auto& theta_val = value_of(theta_col);
48+
49+
auto check_theta_bounded = check_cl(function, "Probability parameter",
50+
theta_val, "in the interval [0, 1]");
51+
auto theta_bounded_expr = 0.0 <= theta_val && theta_val <= 1.0;
52+
53+
auto any_n_negative = colwise_max(0 + (n < 0));
54+
auto any_n_over_one = colwise_max(constant(0, N, 1) + (n >= 1));
55+
auto P_expr = colwise_sum(log(theta_val));
56+
auto deriv = elt_divide(1.0, theta_val);
57+
58+
matrix_cl<double> any_n_negative_cl;
59+
matrix_cl<double> any_n_over_one_cl;
60+
matrix_cl<double> P_cl;
61+
matrix_cl<double> deriv_cl;
62+
63+
results(check_theta_bounded, any_n_negative_cl, any_n_over_one_cl, P_cl,
64+
deriv_cl)
65+
= expressions(theta_bounded_expr, any_n_negative, any_n_over_one, P_expr,
66+
calc_if<(!is_constant_all<T_prob_cl>::value)>(deriv));
67+
68+
if (from_matrix_cl(any_n_negative_cl).maxCoeff()) {
69+
return 0.0;
70+
}
71+
if (from_matrix_cl(any_n_over_one_cl).maxCoeff()) {
72+
return NEGATIVE_INFTY;
73+
}
74+
75+
T_partials_return P = from_matrix_cl(P_cl).sum();
76+
operands_and_partials<decltype(theta_col)> ops_partials(theta_col);
77+
78+
if (!is_constant_all<T_prob_cl>::value) {
79+
ops_partials.edge1_.partials_ = std::move(deriv_cl);
80+
}
81+
82+
return ops_partials.build(P);
83+
}
84+
85+
} // namespace math
86+
} // namespace stan
87+
#endif
88+
#endif
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#ifndef STAN_MATH_OPENCL_PRIM_BERNOULLI_LCDF_HPP
2+
#define STAN_MATH_OPENCL_PRIM_BERNOULLI_LCDF_HPP
3+
#ifdef STAN_OPENCL
4+
5+
#include <stan/math/prim/meta.hpp>
6+
#include <stan/math/prim/err.hpp>
7+
#include <stan/math/opencl/kernel_generator.hpp>
8+
#include <stan/math/prim/fun/constants.hpp>
9+
#include <stan/math/prim/fun/elt_divide.hpp>
10+
#include <stan/math/prim/functor/operands_and_partials.hpp>
11+
12+
namespace stan {
13+
namespace math {
14+
15+
/** \ingroup prob_dists
16+
* Returns the log CDF of the Bernoulli distribution. If containers are
17+
* supplied, returns the log sum of the probabilities.
18+
*
19+
* @tparam T_n_cl type of integer parameter
20+
* @tparam T_prob_cl type of chance of success parameter
21+
* @param n integer parameter
22+
* @param theta logit-transformed chance of success parameter
23+
* @return log probability or log sum of probabilities
24+
* @throw std::domain_error if theta is not a valid probability
25+
* @throw std::invalid_argument if container sizes mismatch.
26+
*/
27+
template <
28+
typename T_n_cl, typename T_prob_cl,
29+
require_all_prim_or_rev_kernel_expression_t<T_n_cl, T_prob_cl>* = nullptr,
30+
require_any_not_stan_scalar_t<T_n_cl, T_prob_cl>* = nullptr>
31+
return_type_t<T_prob_cl> bernoulli_lcdf(const T_n_cl& n,
32+
const T_prob_cl& theta) {
33+
static const char* function = "bernoulli_lcdf(OpenCL)";
34+
using T_partials_return = partials_return_t<T_prob_cl>;
35+
using std::isnan;
36+
constexpr bool is_n_vector = !is_stan_scalar<T_n_cl>::value;
37+
constexpr bool is_theta_vector = !is_stan_scalar<T_prob_cl>::value;
38+
39+
check_consistent_sizes(function, "Random variable", n,
40+
"Probability parameter", theta);
41+
const size_t N = is_n_vector ? size(n) : size(theta);
42+
if (N == 0) {
43+
return 0.0;
44+
}
45+
46+
const auto& theta_col = as_column_vector_or_scalar(theta);
47+
const auto& theta_val = value_of(theta_col);
48+
49+
auto check_theta_bounded = check_cl(function, "Probability parameter",
50+
theta_val, "in the interval [0, 1]");
51+
auto theta_bounded_expr = 0.0 <= theta_val && theta_val <= 1.0;
52+
53+
auto any_n_negative = colwise_max(0 + (n < 0));
54+
auto Pi = 1.0 - theta_val;
55+
auto cond = n >= 1;
56+
auto P_expr = colwise_sum(select(cond, 0.0, log(Pi)));
57+
auto deriv = select(cond, 0.0, elt_divide(-1.0, Pi));
58+
59+
matrix_cl<double> any_n_negative_cl;
60+
matrix_cl<double> P_cl;
61+
matrix_cl<double> deriv_cl;
62+
63+
results(check_theta_bounded, any_n_negative_cl, P_cl, deriv_cl)
64+
= expressions(theta_bounded_expr, any_n_negative, P_expr,
65+
calc_if<(!is_constant_all<T_prob_cl>::value)>(deriv));
66+
67+
if (from_matrix_cl(any_n_negative_cl).maxCoeff()) {
68+
return NEGATIVE_INFTY;
69+
}
70+
71+
T_partials_return P = from_matrix_cl(P_cl).sum();
72+
operands_and_partials<decltype(theta_col)> ops_partials(theta_col);
73+
74+
if (!is_constant_all<T_prob_cl>::value) {
75+
ops_partials.edge1_.partials_ = std::move(deriv_cl);
76+
}
77+
78+
return ops_partials.build(P);
79+
}
80+
81+
} // namespace math
82+
} // namespace stan
83+
#endif
84+
#endif

0 commit comments

Comments
 (0)