math: Inconsistent error handling

Description

Error handling is not consistent between different mathematical functions. Most primitive functions only call std implementation and return NaN in case of invalid input. Some check for invalid input and throw exceptions.

Example

stan::math::log() directely calls std::log(). So any negative argument results in NaN return value.

stan::math::log1p() checks if its argument is less than -1 and throws std::domain_error if it is.

Expected Output

Consistent error handling.

Current Version:

v3.0.0

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Comments: 15 (13 by maintainers)

Most upvoted comments

Do they satisfy the IEEE standard or are they taking shortcuts?

No idea. This page seems to vaguely claim they are based on standard library.

Do we not he -march=native turned on in our compilation? If not, should we?

I think we do not. In most cases Stan programs are run on the same computer they are compiled on, so we could use -march=native. But there might be exceptions? I don’t know.

Even if there are exceptions we could document that in most cases user can add that to make/local and expect improved performance.

Wow. That’s interesting news on the performance of Eigen implementations of exp() and sqrt(). Do they satisfy the IEEE standard or are they taking shortcuts? If they’re accurate enough, we should be able to just plug and play.

There are also ways to turn down compiler implementations of checks and lower precision to get speedups (which is partly what the Intel library does).

Do we not he -march=native turned on in our compilation? If not, should we?

On Nov 29, 2019, at 5:22 AM, Tadej Ciglarič notifications@github.com wrote:

Here is the benchmark and results: https://gist.github.com/t4c1/ba3231f488ae217dbb22c1e064a84b75

I compare std and eigen implementations of functions. I also figured a simple way to add checks to Eigen implementations, so both versions are also tested with check_infinite() (i just picked one check function - they should be similar performance-wise). Std versions have checks added in two different ways. First is to check the container beforehand - this is often used in more complex functions that work on matrices in stan. Second is checking each value as it is used in calculations - that is how log1p() and log1m() work.

With default compiler options I see little difference for all functions, except for exp() and sqrt(). Eigen seems to have much faster implementation for these two. If we use Eigen implementation for these slowdowns from checks become significant.

Than I figured that my compiler by default does not enable any vectorization. I reran the benchmarks with -march=native, which on my CPU enables AVX instuction set. In this case also exp(), sqrt(), floor(), round() and ceil() show significant speedup from using Eigen and slowdown from checks.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.