From 822bf755dccd8d7035a80422097fbfddee3d8865 Mon Sep 17 00:00:00 2001 From: "Hamada S. Badr" Date: Wed, 22 Dec 2021 20:47:44 -0500 Subject: [PATCH] Remove custom C++ functions --- cleanup.win | 1 - dev-notes/rstanarm_dev_notes.md | 6 --- inst/include/csr_matrix_times_vector2.hpp | 54 ------------------- inst/include/meta_header.hpp | 5 -- inst/include/tests.cpp | 18 ------- src/stan_files/continuous.stan | 16 ------ .../functions/common_functions.stan | 15 ------ src/stan_files/model/eta_add_Zb.stan | 2 +- src/stan_files/model/make_eta.stan | 2 +- src/stan_files/model/make_eta_bern.stan | 8 +-- src/stan_files/polr.stan | 14 ----- tests/testthat/include | 1 - tests/testthat/test_stan_functions.R | 7 --- tools/make_cc.R | 2 - 14 files changed, 6 insertions(+), 145 deletions(-) delete mode 100644 inst/include/csr_matrix_times_vector2.hpp delete mode 100644 inst/include/meta_header.hpp delete mode 100644 inst/include/tests.cpp delete mode 120000 tests/testthat/include diff --git a/cleanup.win b/cleanup.win index 097441dd3..d2f6d3477 100755 --- a/cleanup.win +++ b/cleanup.win @@ -3,5 +3,4 @@ # Note to Windows users: This is not actually platform specific. "${R_HOME}/bin/R" --vanilla --slave -e 'roxygen2::roxygenize(load_code = roxygen2::load_source, clean = TRUE)' cp -r src/stan_files tests/testthat/stan_files -cp -r inst/include tests/testthat/include exit $? diff --git a/dev-notes/rstanarm_dev_notes.md b/dev-notes/rstanarm_dev_notes.md index 6148b03de..5ce329310 100644 --- a/dev-notes/rstanarm_dev_notes.md +++ b/dev-notes/rstanarm_dev_notes.md @@ -268,12 +268,6 @@ A brief description of what (generally) goes into each the various files/folders For example, `continuous.stan` contains all the models that can be declared by `stan_glm` (as well as some others). You can view the compiled model in R by executing `rstanarm:::stanmodels$continuous`. -**`inst/include/` ** - -This folder can include separate header files (ending with `.hpp`) that implement custom C++ -functions. If you add something, be sure to include it in `meta_header.hpp` and test it inside -`tests.cpp`. - **`data`** * Example data used in the examples/tests. diff --git a/inst/include/csr_matrix_times_vector2.hpp b/inst/include/csr_matrix_times_vector2.hpp deleted file mode 100644 index 9c708d10e..000000000 --- a/inst/include/csr_matrix_times_vector2.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef RSTANARM__CSR_MATRIX_TIMES_VECTOR2_HPP -#define RSTANARM__CSR_MATRIX_TIMES_VECTOR2_HPP - -/* - * This works exactly like csr_matrix_times_vector but faster and less safe - */ -template -inline -Eigen::Matrix::type, - Eigen::Dynamic, 1> -csr_matrix_times_vector2(const int& m, - const int& n, - const Eigen::Matrix& w, - const std::vector& v, - const std::vector& u, - const Eigen::Matrix& b, - std::ostream* pstream__) { - Eigen::Map > - sm(m, n, w.size(), &u[0], &v[0], &w[0]); - return sm * b; -} - -/* This specialization is slower than the above templated version -stan::math::vector_v -csr_matrix_times_vector2(const int& m, - const int& n, - const Eigen::VectorXd& w, - const std::vector& v, - const std::vector& u, - const stan::math::vector_v& b, - std::ostream* pstream__) { - Eigen::Map > - sm(m, n, w.size(), &u[0], &v[0], &w[0]); - Eigen::VectorXd result = sm * value_of(b); - stan::math::vector_v out(m); - int pos = 0; - for (int k = 0; k < m; k++) { - int nnz = u[k + 1] - u[k]; - if (nnz > 0) { - std::vector operands(nnz); - std::vector gradients(nnz); - for (int j = 0; j < nnz; j++) { - operands[j] = b.coeff(v[pos]); - gradients[j] = w.coeff(pos++); - } - out.coeffRef(k) = precomputed_gradients(result.coeff(k), - operands, gradients); - } - else out.coeffRef(k) = 0.0; - } - return out; -} -*/ -#endif diff --git a/inst/include/meta_header.hpp b/inst/include/meta_header.hpp deleted file mode 100644 index 2f2204da2..000000000 --- a/inst/include/meta_header.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef RSTANARM__META_HEADER_HPP -#define RSTANARM__META_HEADER_HPP - -#include "csr_matrix_times_vector2.hpp" -#endif diff --git a/inst/include/tests.cpp b/inst/include/tests.cpp deleted file mode 100644 index ed84ae338..000000000 --- a/inst/include/tests.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// [[Rcpp::depends(BH)]] -// [[Rcpp::depends(RcppEigen)]] -// [[Rcpp::depends(StanHeaders)]] -#include -#include -#include -#include "meta_header.hpp" - -// [[Rcpp::export]] -Eigen::VectorXd -csr_matrix_times_vector2_test(const int& m, - const int& n, - const Eigen::VectorXd& w, - const std::vector& v, - const std::vector& u, - const Eigen::VectorXd& b) { - return csr_matrix_times_vector2(m,n,w,v,u,b,0); -} diff --git a/src/stan_files/continuous.stan b/src/stan_files/continuous.stan index 360c2b2e9..95990d20e 100644 --- a/src/stan_files/continuous.stan +++ b/src/stan_files/continuous.stan @@ -23,22 +23,6 @@ functions { return -0.5 * (quad_form(XtX, coeff - OLS) + SSR) / square(sigma) - N * (log(sigma) + log(sqrt(2 * pi()))); } - - /** - * test function for csr_matrix_times_vector - * - * @param m Integer number of rows - * @param n Integer number of columns - * @param w Vector (see reference manual) - * @param v Integer array (see reference manual) - * @param u Integer array (see reference manual) - * @param b Vector that is multiplied from the left by the CSR matrix - * @return A vector that is the product of the CSR matrix and b - */ - vector test_csr_matrix_times_vector(int m, int n, vector w, - int[] v, int[] u, vector b) { - return csr_matrix_times_vector(m, n, w, v, u, b); - } } data { // declares N, K, X, xbar, dense_X, nnz_x, w_x, v_x, u_x diff --git a/src/stan_files/functions/common_functions.stan b/src/stan_files/functions/common_functions.stan index b288c1902..25ada737b 100644 --- a/src/stan_files/functions/common_functions.stan +++ b/src/stan_files/functions/common_functions.stan @@ -247,21 +247,6 @@ return V; } - /** - * faster version of csr_matrix_times_vector - * declared here and defined in C++ - * - * @param m Integer number of rows - * @param n Integer number of columns - * @param w Vector (see reference manual) - * @param v Integer array (see reference manual) - * @param u Integer array (see reference manual) - * @param b Vector that is multiplied from the left by the CSR matrix - * @return A vector that is the product of the CSR matrix and b - */ - vector csr_matrix_times_vector2(int m, int n, vector w, - int[] v, int[] u, vector b); - /** * Calculate lower bound on intercept * diff --git a/src/stan_files/model/eta_add_Zb.stan b/src/stan_files/model/eta_add_Zb.stan index b079a567d..14a09d59e 100644 --- a/src/stan_files/model/eta_add_Zb.stan +++ b/src/stan_files/model/eta_add_Zb.stan @@ -1,2 +1,2 @@ if (special_case) for (i in 1:t) eta += b[V[i]]; - else eta += csr_matrix_times_vector2(N, q, w, v, u, b); + else eta += csr_matrix_times_vector(N, q, w, v, u, b); diff --git a/src/stan_files/model/make_eta.stan b/src/stan_files/model/make_eta.stan index b065cd172..6e8885969 100644 --- a/src/stan_files/model/make_eta.stan +++ b/src/stan_files/model/make_eta.stan @@ -1,7 +1,7 @@ vector[N] eta; // linear predictor if (K > 0) { if (dense_X) eta = X[1] * beta; - else eta = csr_matrix_times_vector2(N, K, w_X, v_X, u_X, beta); + else eta = csr_matrix_times_vector(N, K, w_X, v_X, u_X, beta); } else eta = rep_vector(0.0, N); if (has_offset == 1) eta += offset_; diff --git a/src/stan_files/model/make_eta_bern.stan b/src/stan_files/model/make_eta_bern.stan index d9c4886da..4f21729fe 100644 --- a/src/stan_files/model/make_eta_bern.stan +++ b/src/stan_files/model/make_eta_bern.stan @@ -6,8 +6,8 @@ eta1 = N[2] > 0 ? X1[1] * beta : rep_vector(0.0, 0); } else { - eta0 = csr_matrix_times_vector2(N[1], K, w_X0, v_X0, u_X0, beta); - eta1 = csr_matrix_times_vector2(N[2], K, w_X1, v_X1, u_X1, beta); + eta0 = csr_matrix_times_vector(N[1], K, w_X0, v_X0, u_X0, beta); + eta1 = csr_matrix_times_vector(N[2], K, w_X1, v_X1, u_X1, beta); } } else { @@ -31,6 +31,6 @@ if (N[1] > 0) eta0 += b[V0[i]]; if (N[2] > 0) eta1 += b[V1[i]]; } else if (t > 0) { - if (N[1] > 0) eta0 += csr_matrix_times_vector2(N[1], q, w0, v0, u0, b); - if (N[2] > 0) eta1 += csr_matrix_times_vector2(N[2], q, w1, v1, u1, b); + if (N[1] > 0) eta0 += csr_matrix_times_vector(N[1], q, w0, v0, u0, b); + if (N[2] > 0) eta1 += csr_matrix_times_vector(N[2], q, w1, v1, u1, b); } diff --git a/src/stan_files/polr.stan b/src/stan_files/polr.stan index ef51dcf8a..601fa1e63 100644 --- a/src/stan_files/polr.stan +++ b/src/stan_files/polr.stan @@ -122,20 +122,6 @@ functions { else reject("invalid link"); return ystar; } - - /** - * faster version of csr_matrix_times_vector - * declared here and defined in C++ - * - * @param m Integer number of rows - * @param n Integer number of columns - * @param w Vector (see reference manual) - * @param v Integer array (see reference manual) - * @param u Integer array (see reference manual) - * @param b Vector that is multiplied from the left by the CSR matrix - * @return A vector that is the product of the CSR matrix and b - */ - vector csr_matrix_times_vector2(int m, int n, vector w, int[] v, int[] u, vector b); } data { // declares N, K, X, xbar, dense_X, nnz_x, w_x, v_x, u_x diff --git a/tests/testthat/include b/tests/testthat/include deleted file mode 120000 index 79818b409..000000000 --- a/tests/testthat/include +++ /dev/null @@ -1 +0,0 @@ -../../inst/include/ \ No newline at end of file diff --git a/tests/testthat/test_stan_functions.R b/tests/testthat/test_stan_functions.R index 3a80d3ed3..89a66151d 100644 --- a/tests/testthat/test_stan_functions.R +++ b/tests/testthat/test_stan_functions.R @@ -50,9 +50,6 @@ functions <- sapply(dir(MODELS_HOME, pattern = "stan$", full.names = TRUE), func } else return(as.character(NULL)) }) names(functions) <- basename(names(functions)) -functions$polr.stan <- grep("csr_matrix_times_vector2", - functions$polr.stan, - value = TRUE, fixed = TRUE, invert = TRUE) functions <- c(unlist(lapply(file.path(MODELS_HOME, "functions", c("common_functions.stan", "bernoulli_likelihoods.stan", @@ -65,7 +62,6 @@ model_code <- paste(c("functions {", functions, "}"), collapse = "\n") stanc_ret <- stanc(model_code = model_code, model_name = "Stan Functions", allow_undefined = TRUE) expose_stan_functions(stanc_ret, rebuild = TRUE, verbose = TRUE) -Rcpp::sourceCpp(file.path(INCLUDE_DIR, "tests.cpp"), rebuild = TRUE, verbose = TRUE) N <- 99L # bernoulli @@ -399,8 +395,6 @@ if (require(lme4) && require(HSAUR3)) test_that("the Stan equivalent of lme4's Z tol = 1e-14) parts <- extract_sparse_parts(Z) - Zb <- csr_matrix_times_vector2_test(nrow(Z), ncol(Z), parts$w, - parts$v - 1L, parts$u - 1L, b) expect_equal(Zb, as.vector(Z %*% b), tol = 1e-14) if (all(sapply(group$cnms, FUN = function(x) { length(x) == 1 && x == "(Intercept)" @@ -408,7 +402,6 @@ if (require(lme4) && require(HSAUR3)) test_that("the Stan equivalent of lme4's Z V <- matrix(parts$v, nrow = sum(p), ncol = nrow(Z)) expect_true(all(V == t(as.matrix(as.data.frame(make_V(nrow(Z), nrow(V), parts$v - 1L)))))) - expect_equal(Zb, apply(V, 2, FUN = function(v) sum(b[v]))) } } test_lme4(glFormula(Reaction ~ Days + (Days | Subject), data = sleepstudy)$reTrms) diff --git a/tools/make_cc.R b/tools/make_cc.R index f199cba9e..e3f0c1b57 100644 --- a/tools/make_cc.R +++ b/tools/make_cc.R @@ -21,8 +21,6 @@ make_cc <- function(file) { file <- sub("\\.cc$", ".stan", file) cppcode <- rstan::stanc(file, allow_undefined = TRUE, obfuscate_model_name = FALSE)$cppcode - cppcode <- sub("(class[[:space:]][A-Za-z_][A-Za-z0-9_]*[[:space:]])", - paste("#include \n", "\\1"), cppcode) cat(readLines(dir("stan_files", pattern = "license.stan", recursive = TRUE, full.names = TRUE)), "#ifndef MODELS_HPP", "#define MODELS_HPP", "#define STAN__SERVICES__COMMAND_HPP",