Open alashworth opened 5 years ago
Issue by mitzimorris Thursday Feb 16, 2017 at 01:31 GMT Originally opened as https://github.com/stan-dev/stan/issues/2233
Cleanup generated c++ code - lp_functions no longer need to argument "lp__" in generated code.
Typedefs and args for "lp__" are generated by the following files:
src/stan/lang/generator/generate_function_arguments.hpp
src/stan/lang/generator/generate_function_template_parameters.hpp
src/stan/lang/generator/generate_functor_arguments.hpp
The current output. Knowing what is the current behavior is useful.
stan program:
functions { real foo_lp(real x) { x ~ normal(0, 1); return x^2; } } parameters { real y; } model { real z = foo_lp(y); }
currently produces the following C++ code:
// Code generated by Stan version 2.14.0 #include <stan/model/model_header.hpp> namespace test_lp_model_namespace { using std::istream; using std::string; using std::stringstream; using std::vector; using stan::io::dump; using stan::math::lgamma; using stan::model::prob_grad; using namespace stan::math; typedef Eigen::Matrix<double,Eigen::Dynamic,1> vector_d; typedef Eigen::Matrix<double,1,Eigen::Dynamic> row_vector_d; typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> matrix_d; static int current_statement_begin__; template <typename T0__, typename T_lp__, typename T_lp_accum__> typename boost::math::tools::promote_args<T0__, T_lp__>::type foo_lp(const T0__& x, T_lp__& lp__, T_lp_accum__& lp_accum__, std::ostream* pstream__) { typedef typename boost::math::tools::promote_args<T0__, T_lp__>::type fun_scalar_t__; typedef fun_scalar_t__ fun_return_scalar_t__; const static bool propto__ = true; (void) propto__; fun_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); (void) DUMMY_VAR__; // suppress unused var warning int current_statement_begin__ = -1; try { current_statement_begin__ = 3; lp_accum__.add(normal_log<propto__>(x, 0, 1)); current_statement_begin__ = 4; return stan::math::promote_scalar<fun_return_scalar_t__>(pow(x,2)); } catch (const std::exception& e) { stan::lang::rethrow_located(e,current_statement_begin__); // Next line prevents compiler griping about no return throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***"); } } struct foo_lp_functor__ { template <typename T0__, typename T_lp__, typename T_lp_accum__> typename boost::math::tools::promote_args<T0__, T_lp__>::type operator()(const T0__& x, T_lp__& lp__, T_lp_accum__& lp_accum__, std::ostream* pstream__) const { return foo_lp(x, lp__, lp_accum__, pstream__); } }; template <typename T0__> typename boost::math::tools::promote_args<T0__>::type foo(const T0__& x, std::ostream* pstream__) { typedef typename boost::math::tools::promote_args<T0__>::type fun_scalar_t__; typedef fun_scalar_t__ fun_return_scalar_t__; const static bool propto__ = true; (void) propto__; fun_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); (void) DUMMY_VAR__; // suppress unused var warning int current_statement_begin__ = -1; try { current_statement_begin__ = 7; return stan::math::promote_scalar<fun_return_scalar_t__>(pow(x,2)); } catch (const std::exception& e) { stan::lang::rethrow_located(e,current_statement_begin__); // Next line prevents compiler griping about no return throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***"); } } struct foo_functor__ { template <typename T0__> typename boost::math::tools::promote_args<T0__>::type operator()(const T0__& x, std::ostream* pstream__) const { return foo(x, pstream__); } }; class test_lp_model : public prob_grad { private: public: test_lp_model(stan::io::var_context& context__, std::ostream* pstream__ = 0) : prob_grad(0) { typedef boost::ecuyer1988 rng_t; rng_t base_rng(0); // 0 seed default ctor_body(context__, base_rng, pstream__); } template <class RNG> test_lp_model(stan::io::var_context& context__, RNG& base_rng__, std::ostream* pstream__ = 0) : prob_grad(0) { ctor_body(context__, base_rng__, pstream__); } template <class RNG> void ctor_body(stan::io::var_context& context__, RNG& base_rng__, std::ostream* pstream__) { current_statement_begin__ = -1; static const char* function__ = "test_lp_model_namespace::test_lp_model"; (void) function__; // dummy to suppress unused var warning size_t pos__; (void) pos__; // dummy to suppress unused var warning std::vector<int> vals_i__; std::vector<double> vals_r__; double DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); (void) DUMMY_VAR__; // suppress unused var warning // initialize member variables // validate, data variables // initialize data variables try { } catch (const std::exception& e) { stan::lang::rethrow_located(e,current_statement_begin__); // Next line prevents compiler griping about no return throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***"); } // validate transformed data // validate, set parameter ranges num_params_r__ = 0U; param_ranges_i__.clear(); ++num_params_r__; } ~test_lp_model() { } void transform_inits(const stan::io::var_context& context__, std::vector<int>& params_i__, std::vector<double>& params_r__, std::ostream* pstream__) const { stan::io::writer<double> writer__(params_r__,params_i__); size_t pos__; (void) pos__; // dummy call to supress warning std::vector<double> vals_r__; std::vector<int> vals_i__; if (!(context__.contains_r("y"))) throw std::runtime_error("variable y missing"); vals_r__ = context__.vals_r("y"); pos__ = 0U; context__.validate_dims("initialization", "y", "double", context__.to_vec()); // generate_declaration y double y(0); y = vals_r__[pos__++]; try { writer__.scalar_unconstrain(y); } catch (const std::exception& e) { throw std::runtime_error(std::string("Error transforming variable y: ") + e.what()); } params_r__ = writer__.data_r(); params_i__ = writer__.data_i(); } void transform_inits(const stan::io::var_context& context, Eigen::Matrix<double,Eigen::Dynamic,1>& params_r, std::ostream* pstream__) const { std::vector<double> params_r_vec; std::vector<int> params_i_vec; transform_inits(context, params_i_vec, params_r_vec, pstream__); params_r.resize(params_r_vec.size()); for (int i = 0; i < params_r.size(); ++i) params_r(i) = params_r_vec[i]; } template <bool propto__, bool jacobian__, typename T__> T__ log_prob(vector<T__>& params_r__, vector<int>& params_i__, std::ostream* pstream__ = 0) const { T__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); (void) DUMMY_VAR__; // suppress unused var warning T__ lp__(0.0); stan::math::accumulator<T__> lp_accum__; // model parameters stan::io::reader<T__> in__(params_r__,params_i__); T__ y; (void) y; // dummy to suppress unused var warning if (jacobian__) y = in__.scalar_constrain(lp__); else y = in__.scalar_constrain(); // transformed parameters try { } catch (const std::exception& e) { stan::lang::rethrow_located(e,current_statement_begin__); // Next line prevents compiler griping about no return throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***"); } // validate transformed parameters const char* function__ = "validate transformed params"; (void) function__; // dummy to suppress unused var warning // model body try { { T__ z1; (void) z1; // dummy to suppress unused var warning stan::math::initialize(z1, DUMMY_VAR__); stan::math::fill(z1,DUMMY_VAR__); stan::math::assign(z1,foo_lp(y, lp__, lp_accum__, pstream__)); T__ z2; (void) z2; // dummy to suppress unused var warning stan::math::initialize(z2, DUMMY_VAR__); stan::math::fill(z2,DUMMY_VAR__); stan::math::assign(z2,foo(y, pstream__)); } } catch (const std::exception& e) { stan::lang::rethrow_located(e,current_statement_begin__); // Next line prevents compiler griping about no return throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***"); } lp_accum__.add(lp__); return lp_accum__.sum(); } // log_prob() template <bool propto, bool jacobian, typename T_> T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r, std::ostream* pstream = 0) const { std::vector<T_> vec_params_r; vec_params_r.reserve(params_r.size()); for (int i = 0; i < params_r.size(); ++i) vec_params_r.push_back(params_r(i)); std::vector<int> vec_params_i; return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream); } void get_param_names(std::vector<std::string>& names__) const { names__.resize(0); names__.push_back("y"); } void get_dims(std::vector<std::vector<size_t> >& dimss__) const { dimss__.resize(0); std::vector<size_t> dims__; dims__.resize(0); dimss__.push_back(dims__); } template <typename RNG> void write_array(RNG& base_rng__, std::vector<double>& params_r__, std::vector<int>& params_i__, std::vector<double>& vars__, bool include_tparams__ = true, bool include_gqs__ = true, std::ostream* pstream__ = 0) const { vars__.resize(0); stan::io::reader<double> in__(params_r__,params_i__); static const char* function__ = "test_lp_model_namespace::write_array"; (void) function__; // dummy to suppress unused var warning // read-transform, write parameters double y = in__.scalar_constrain(); vars__.push_back(y); if (!include_tparams__) return; // declare and define transformed parameters double lp__ = 0.0; (void) lp__; // dummy to suppress unused var warning stan::math::accumulator<double> lp_accum__; double DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); (void) DUMMY_VAR__; // suppress unused var warning try { } catch (const std::exception& e) { stan::lang::rethrow_located(e,current_statement_begin__); // Next line prevents compiler griping about no return throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***"); } // validate transformed parameters // write transformed parameters if (!include_gqs__) return; // declare and define generated quantities try { } catch (const std::exception& e) { stan::lang::rethrow_located(e,current_statement_begin__); // Next line prevents compiler griping about no return throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***"); } // validate generated quantities // write generated quantities } template <typename RNG> void write_array(RNG& base_rng, Eigen::Matrix<double,Eigen::Dynamic,1>& params_r, Eigen::Matrix<double,Eigen::Dynamic,1>& vars, bool include_tparams = true, bool include_gqs = true, std::ostream* pstream = 0) const { std::vector<double> params_r_vec(params_r.size()); for (int i = 0; i < params_r.size(); ++i) params_r_vec[i] = params_r(i); std::vector<double> vars_vec; std::vector<int> params_i_vec; write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream); vars.resize(vars_vec.size()); for (int i = 0; i < vars.size(); ++i) vars(i) = vars_vec[i]; } static std::string model_name() { return "test_lp_model"; } void constrained_param_names(std::vector<std::string>& param_names__, bool include_tparams__ = true, bool include_gqs__ = true) const { std::stringstream param_name_stream__; param_name_stream__.str(std::string()); param_name_stream__ << "y"; param_names__.push_back(param_name_stream__.str()); if (!include_gqs__ && !include_tparams__) return; if (!include_gqs__) return; } void unconstrained_param_names(std::vector<std::string>& param_names__, bool include_tparams__ = true, bool include_gqs__ = true) const { std::stringstream param_name_stream__; param_name_stream__.str(std::string()); param_name_stream__ << "y"; param_names__.push_back(param_name_stream__.str()); if (!include_gqs__ && !include_tparams__) return; if (!include_gqs__) return; } }; // model } typedef test_lp_model_namespace::test_lp_model stan_model;
v2.14.0
Summary:
Cleanup generated c++ code - lp_functions no longer need to argument "lp__" in generated code.
Description:
Typedefs and args for "lp__" are generated by the following files:
src/stan/lang/generator/generate_function_arguments.hpp
src/stan/lang/generator/generate_function_template_parameters.hpp
src/stan/lang/generator/generate_functor_arguments.hpp
Current Output:
The current output. Knowing what is the current behavior is useful.
stan program:
currently produces the following C++ code:
Current Version:
v2.14.0