# Standalone functions, need code generator help

**URL:** <https://discourse.mc-stan.org/t/standalone-functions-need-code-generator-help/2005>\
**Category:** Developers\
**Tags:** features\
**Created:** [September 25, 2017, 2:12pm UTC](https://discourse.mc-stan.org/t/standalone-functions-need-code-generator-help/2005 "2017-09-25T14:12:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sakrejda](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/sakrejda/32/845_2.png) [@sakrejda](https://discourse.mc-stan.org/u/sakrejda)\
**Post date:** [September 25, 2017, 2:12pm UTC](https://discourse.mc-stan.org/t/standalone-functions-need-code-generator-help/2005/1 "2017-09-25T14:12:19Z")

</div>

Hey, so the rstan standalone functions thing is close but when Rcpp and Boost template metaprogramming come together it creates something uglier than I want to think about. Either I need to resolve some of that _or_ get a workaround from the parser.

The problem is Rcpp generates code based on our current stan-dev/stan code that doesn’t quite match the explicit doubles instantiation. So the compiler skips our instantiation and then tries to use Rcpp’s traits with our templated function and that doesn’t work (boost::promote\_args chokes on Rcpp’s input\_parameter traits). If I put the templated version in it’s own namespace (“stan”) and I call it from the instantiation explicitly ( `double f_rng(...) {return stan::f_rng<double....>(...); }` ). Could someone familiar with the code generation (@Bob_Carpenter or @mitzimorris?) suggest how to make this change?

Alternatively, does someone understand off hand why hiding the templated function within a namespace is necessary within the following code? This code is as-generated _except_ I hid the templated version in the namespace and called it from the instantiation (`stan::f_rng`). The error you get otherwise is (so promote\_args isn’t made to work with Rcpp or vice-versa, that makes sense):

```
 In instantiation of ‘typename boost::math::tools::promote_args<T>::type f_rng(const T0__&, RNG&, std::ostream*) [with T0__ = Rcpp::ConstReferenceInputParameter<double>; RNG = Rcpp::ConstReferenceInputParameter<boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014u, 0u, 2147483563u>, boost::random::linear_congruential_engine<unsigned int, 40692u, 0u, 2147483399u> >&>; typename boost::math::tools::promote_args<T>::type = Rcpp::ConstReferenceInputParameter<double>; std::ostream = std::basic_ostream<char>]’:
file2e5a2ea9e478.cpp:103:65: required from here
file2e5a2ea9e478.cpp:38:76: error: no matching function for call to ‘Rcpp::ConstReferenceInputParameter<double>::ConstReferenceInputParameter(double)’
         fun_scalar_t __DUMMY_VAR__ (std::numeric_limits<double>::quiet_NaN());

```

```
// Code generated by Stan version 2.17.0

// [[Rcpp::depends(rstan)]]
#include <exporter.h>
#include <RcppEigen.h>
#include <stan/model/standalone_functions_header.hpp>
#include <stan/model/model_header.hpp>

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
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;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "unkown file name");
    reader.add_event(8, 8, "end", "unkown file name");
    return reader;
}

namespace stan {
  template <typename T0__, class RNG>
  typename boost::math::tools::promote_args<T0__>::type
  f_rng(const T0 __& mu, RNG& base_rng__ , 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__ = 4;
          fun_scalar_t__ x;
          (void) x; // dummy to suppress unused var warning
  
          stan::math::initialize(x, std::numeric_limits<double>::quiet_NaN());
          stan::math::fill(x,DUMMY_VAR__);
          stan::math::assign(x,normal_rng(mu,1, base_rng__));
  
  
          current_statement_begin__ = 5;
          return stan::math::promote_scalar<fun_return_scalar_t__>(x);
          }
      } catch (const std::exception& e) {
          stan::lang::rethrow_located(e, current_statement_begin __, prog_reader__ ());
          // Next line prevents compiler griping about no return
          throw std::runtime_error(" ***IF YOU SEE THIS, PLEASE REPORT A BUG***");
      }
  }
  
  
  struct f_rng_functor__ {
      template <typename T0__, class RNG>
          typename boost::math::tools::promote_args<T0__>::type
      operator()(const T0 __& mu, RNG& base_rng__ , std::ostream* pstream__) const {
          return f_rng(mu, base_rng __, pstream__ );
      }
  };
}

// [[Rcpp::export]]
double
f_rng(const double& mu, boost::ecuyer1988& base_rng __, std::ostream* pstream__ = 0){
  return stan::f_rng<double, boost::ecuyer1988>(mu, base_rng __, pstream__ );
}

#include <Rcpp.h>
// __create_rng
boost::ecuyer1988 __create_rng(int seed);
RcppExport SEXP sourceCpp_1___create_rng(SEXP seedSEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< int >::type seed(seedSEXP);
    rcpp_result_gen = Rcpp::wrap(__create_rng(seed));
    return rcpp_result_gen;
END_RCPP
}
// f_rng
double f_rng(const double& mu, boost::ecuyer1988& base_rng __, std::ostream* pstream__ );
RcppExport SEXP sourceCpp_1_f_rng(SEXP muSEXP, SEXP base_rng __SEXP, SEXP pstream__ SEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< const double& >::type mu(muSEXP);
    Rcpp::traits::input_parameter< boost::ecuyer1988& >::type base_rng__(base_rng__SEXP);
    Rcpp::traits::input_parameter< std::ostream* >::type pstream__(pstream__SEXP);
    rcpp_result_gen = Rcpp::wrap(f_rng(mu, base_rng __, pstream__ ));
    return rcpp_result_gen;
END_RCPP
}

```

---

<div class="post-metadata">

**Author:** ![Bob\_Carpenter](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bob_carpenter/32/9230_2.png) [@Bob\_Carpenter](https://discourse.mc-stan.org/u/Bob_Carpenter)\
**Post date:** [October 2, 2017, 7:44pm UTC](https://discourse.mc-stan.org/t/standalone-functions-need-code-generator-help/2005/2 "2017-10-02T19:44:00Z")

</div>

> [@sakrejda](#):
>
> Could someone familiar with the code generation (@Bob_Carpenter or @mitzimorris?) suggest how to make this change?

Missed this a week ago. Do you still need help with the generator? It’s relatively simple other than the handling of variant types.

No idea about the specifics of your matching case or what all that Rcpp stuff does.

C++ name lookup looks at all the included names that match, then chooses the one with the best matching signature (if there are two equally specific matches, it fails due to ambiguity). Only base templates are included at this stage, not specializations. If there are arguments defined in a namespace, functions in that namespace are automatically included (argument-dependent lookup). Then, if you matched a template, the compiler will find the most specific template specialization that matches your arguments, which again has to be unique.

I’d be a bit worried about the include of all of the Stan namespace leaking. We should start just qualifying all the Stan math that’s being used.

---

<div class="post-metadata">

**Author:** ![sakrejda](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/sakrejda/32/845_2.png) [@sakrejda](https://discourse.mc-stan.org/u/sakrejda)\
**Post date:** [October 3, 2017, 12:56am UTC](https://discourse.mc-stan.org/t/standalone-functions-need-code-generator-help/2005/3 "2017-10-03T00:56:12Z")

</div>

I haven’t managed to get to this yet. Could we do a chat to figure out a  
few details? I think ideally the generated Stan functions should go in a  
namespace (stan::functions? stan::math? Stan::generated?) and for Rcpp we  
can dump an instantiated version into the global namespace that calls the  
templated version with full namespace qualification. Does that seem  
reasonable on the Stan end?

---

<div class="post-metadata">

**Author:** ![Bob\_Carpenter](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bob_carpenter/32/9230_2.png) [@Bob\_Carpenter](https://discourse.mc-stan.org/u/Bob_Carpenter)\
**Post date:** [October 3, 2017, 10:08pm UTC](https://discourse.mc-stan.org/t/standalone-functions-need-code-generator-help/2005/4 "2017-10-03T22:08:39Z")

</div>

How about Thursday afternoon some time for chatting?

Yes, I thought that was the plan. I don’t think it should go in the the `stan::` namespace if that can be avoided—the code isn’t part of Stan per se.

There’s a namespace automatically generated for the model and we could just follow that. Otherwise, just make something up like `rstan::rcpp` or something.

---

<div class="post-metadata">

**Author:** ![sakrejda](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/sakrejda/32/845_2.png) [@sakrejda](https://discourse.mc-stan.org/u/sakrejda)\
**Post date:** [October 4, 2017, 11:10am UTC](https://discourse.mc-stan.org/t/standalone-functions-need-code-generator-help/2005/5 "2017-10-04T11:10:43Z")

</div>

If the namespace shouldn’t be in `stan::` it’s easier, that was one of my  
questions (I wasn’t sure why we set up the namespaces vector but now it  
makes sense). I’ll just pass the namepaces vector further down and rstan  
can call it with an ‘rstan::’ namespace. I’m driving to Boston Thursday  
afternoon so I’ll get in touch separately to find a time.
