EKAT
EKAT copied to clipboard
Potential enhancement to Mask interface to help avoid FPEs
As I'm cleaning up FPEs in SHOC, I'm encountering this pattern over and over (this pattern is widespread in P3 too):
Spack pack1(data1), pack2(data2);
pack2.set(pack1 != 0, val / pack1);
... which needs to be changed in over to avoid the FPE (if they are on) to:
Spack pack1(data1), pack2(data2);
const auto mask = pack1 != 0;
if (mask.any()) {
pack2.set(mask, val / pack1);
}
Because, even if pack2 is protected from getting infs by the mask, the divide-by-zero still occurs when val/pack1
gets evaluated. The code that needed to protect against this makes the code uglier and may impact performance since it introduces another branch.
I was thinking a macro like this would be nice:
#define FPE_SAFE_SET(pack, mask, val)
#if defined(SCREAM_FPE)
if (mask.any()) {
pack.set(mask, val);
}
#else
pack.set(mask, val);
#endif
Which would be used like this:
Spack pack1(data1), pack2(data2);
FPE_SAFE_SET(pack2, pack1 != 0, val / pack1);
Thoughts?