E3SM-Project / E3SM-Project/EKAT
Potential enhancement to Mask interface to help avoid FPEs
- Dominant language
- C++
- Stars
- 22
- Forks
- 12
- PR merge metrics
- No merged PRs in 30d
Description
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?
Contributor guide
Assessment
This issue has not been assessed yet.