Hi all,
There were a couple off-line conversations regarding removing tests for Eigen::Matrix<T, 1, -1>
from the distribution tests in the math library. I wanted to bring the conversation all back and get some feedback from any developers that are interested.
The question: is it ok to remove testing for Eigen::Matrix<T, 1, -1>
(what maps to Stan’s row_vector
type) from the distribution tests?
(This was from an email between myself and @seantalts)
The overall goal is to test the distributions over every possible instantiation that is possible from the Stan language.
There are two different things it’s testing:
- ability to be compiled. We’ve run into some odd compiler behavior in not being able to resolve certain template instantiations.
- correctness of the evaluation of the log probability distribution function + gradients. Since we specialize the gradients, bugs can pop up in certain instantiations and not others.
Both of these two things aren’t just hypothetical concerns. We’ve had to do a lot of rewriting templated code to look a different way to get around the first. The second is truly maddening when it happens, and it’s happened. It’s really hard to trace through a bug that only manifests under specific instantiations.
The basic idea was to have an easy way to specify tests with values that should be ok, values that should throw exceptions, and then all we want would be tested: every possible instantiation. If you look at the first line of test/prob/bernoulli/bernoulli_test.hpp
, it starts with:
// Arguments: Ints, Doubles
Using that information, we know that there are two arguments, the first can take on {int
, std::vector<int>
}, and the second can take on {double
, std::vector<double>
, Eigen::Matrix<double, -1, 1>
, Eigen::Matrix<double, 1, -1>
, var
, std::vector<var>
, Eigen::Matrix<var, -1, 1>
, Eigen::Matrix<var, 1, -1>
}. So here, we want 16 different instantiations. For something like student_t
, we need 8^4 = 4096 instantiations.
(I think we’ve gotten good enough where we treat Eigen::Matrix<T, -1, 1>
and Eigen::Matrix<T, 1, -1>
the same, so maybe we can drop two instantiations (one for var and one for double). But we should instantiate std::vector
and Eigen::Matrix
; they flex the compiler slightly differently.)
In short, I think the compilation errors should be picked up by a combination of unit tests of the template metaprograms and the instantiation with Eigen::Matrix<T, -1, 1>
. (C++ never ceases to amaze me, so perhaps someone could tell me that’s not true.)
Sorry about not keeping this discussion on-list. @Bob_Carpenter reached out and said:
It’s definitely good to get everyone’s opinion on
removing row vector tests. In the end, Daniel (cc-ed)
is in charge of the math lib. If he’s OK removing row
vector tests, I am—Daniel’s been the one most adamant
about test coverage.
I think the way we write the univariate distributions, we’re safe. (There was a point in Stan’s history where we wrote each template specialization by hand; that’s when we could have bugs that only manifest in one of the instantiations. Now that we use the template metaprograms, we should be ok as long as we use the metaprograms correctly.