Is there a proper base class for stan_model?


#1

I’d like to refer to an instance of a stan_model (i.e., an instance of a class which is defined in the stanc generated file) without having the specific class known at compile time. The parent class of is stan::model::prob_grad, so I thought I could use that, but I’m hitting problems using a pointer to a stan::model::prob_grad instance because prob_grad doesn’t define:

  • write_array
  • log_prob

which are used in the stan_model.

Is there a reason why there isn’t an (abstract?) parent class of the stan models which do define these things?


#2

My sense is that the answer is this: class member functions cannot be templated and virtual.


#3

No, there’s no base class. It’s just a concept. A base class, even with virtual functions, wouldn’t be a big performance hit here. But as you point out, inheritance and templating don’t play nicely together.

I’m not sure what you mean by “refer to”. The way to do pass it as an argument is with the type defined by a template parameter:

template <class M>
void foo(const M& m, ...);

Then you can pass in a model of any type and type inference will fill in M for you. You see that pattern in all the code that uses models in Stan.


#4

Thanks. This makes sense. By “refer to” I just mean use a pointer to
prob_grad instead of a pointer to the specific model.

I can see that C++ doesn’t support what I’m trying to do: figure out the
type/class of the specific stan model at runtime. It would be very cool
indeed if it did.

I wonder if I could use boost::any here [1]. I’ll have to look into this
at some point.

[1] http://www.artima.com/cppsource/type_erasure2.html


#5

Could you say more about the use case? The main one we’ve considered is that we can compile an object file that could be linked to different models. By requiring the template parmameter, the class type indeed needs to be resolved at compile time.

Suppose we wanted to compile the Stan algorithms (L-BFGS, HMC, ADVI, diagnosis) once ahead of time. Then we’d compile a model when we got it. In order to link those, we need some interface that doesn’t depend on the algorithms being instantiated with the model class they work on. I don’t think a base class would be too much work or induce too much overhead. We’d just need to define it.

We may be forced to confront this. I’d very much like to work with @seantalts and @syclik on cutting down compile times. I don’t see any reason in principle why we can’t precompile our math and matrix library. We’d still need a header-only density library because of the crazy number of possible instantiations. Or we’d need to figure out a way to have those resolve at runtime—I don’t think the dispatch would be that bad.


#6

That’s exactly the case I’m thinking about.

The particular case that prompted the question is written in Cython, so
I don’t think sharing it would help much.