Testing map_rect & its implementations


#1

Hi!

I would like to start implementing tests for the map_rect along with the usual input checking of the inputs to the function and I was wondering how to do it most efficiently. So the structure of the code is roughly as

map_rect(...input...) {
#ifdef STAN_HAS_MPI
  return (map_rect_mpi(...input...));
#else
  return (map_rect_serial(...input...));
#endif
}

The question I have are

  • Can I put the input checking code inside map_rect only? This would mean that map_rect_mpi and map_rect_serial would always expect that the input given is already correct.
  • If the answer to above is “yes” => should I move the _mpi and _serial flavor into our internal namespace?
  • Should the answer to the above be “no” => may I then at least write the tests which check that a wrong input is being rejected only once, but basically ensure that the same code gets compiled once with STAN_HAS_MPI and once without?

Other proposals to make this efficient?

Thanks!

Best,
Sebastian


#2

Which branch are you working on? I see a bunch of MPI branches and now don’t know which one to base the language changes on.

Yes, that is the right thing to do. Only check user inputs once, then it’s up to the programmer to keep everything correct on the inside.

Yes, that sounds reasonable.

Hopefully this won’t be too hard to test beyond config. Ideally, you’ll be able to have a single set of tests that applies to both serial and MPI with the flip of a config switch somehow.


#3

Great. Makes all sense to me. The switch will be a compile time switch, but we can manage that in the tests.

The one with the serial version of map_rect is here:


#4

I’m working through the code that’s there now in feature/issue-686-map_rect_serial and I see usages of things I don’t understand.

You have

#pragma once

at the beginning of the hard_work.hpp test functor include. I looked it up and it’s a widely supported, but non-standard replacement for header guards. I don’t think we want to go down the route of using non-standard pragmas. Maybe @syclik has an opinion.

On another note, in the actual map_rect.hpp file in prim, what is

#define STAN_REGISTER_MAP_RECT(CALLID, FUNCTOR)

doing? I couldn’t find STAN_REGISTER_MAP_RECT used anywhere. Something like this probably needs doc.


#5

The pragma once needs to be replaced, yes.

The macro definition is left empty on purpose. The parser needs to add a call to the macro for every call of map rect. For the mpi case the macro is redefined to inject the required code which registers the map rect call with the boost serialization library which is needed to trigger remote calls of the function. This needs to be documented, of course.


#6

I have started to add the usual checking logic to the map_rect function along with tests.

Is there a testing framework which you think I can use to check the rev part of the function? I remember there is a finite diff testing framework, but I have never used it.


#7

The testing framework is really just for univariate functions.

For this, it’s easy to implement the mapped function directly, so I’d just use that to compare rather than finite differences (though you could use finite differences). Both the finite diffs and autodiff are available as functionals (e.g., gradient, hessian, etc.).