#2925: overflow in rat<int64> in Arith
Reporter: Roland Haas
Status: new
Milestone:
Version:
Type: bug
Priority: minor
Component:
Comment (by Roland Haas):
using `uint64_t` rollover is indeed simpler though:
```
// TODO: need special code to handle the case if a or b is int64_min since -int64_min > int64_max (https://en.cppreference.com/w/cpp/numeric/math/abs#Notes)
int64_t save_mult(int64_t a, int64_t b) {
int64_t sign = (a > 0) ^ (b > 0);
uint64_t abs_a = std::abs(a);
uint64_t abs_b = std::abs(b);
uint64_t abs_ab = abs_a * abs_b;
assert(abs_ab < std::numeric_limits<int64_t>::max());
assert((abs_ab >= abs_a && abs_ab >= abs_b) || (abs_a == 0 || abs_b == 0));
return sign ? -abs_ab : abs_ab;
}
```
--
Ticket URL: https://bitbucket.org/einsteintoolkit/tickets/issues/2925/overflow-in-rat-i…
#2925: overflow in rat<int64> in Arith
Reporter: Roland Haas
Status: new
Milestone:
Version:
Type: bug
Priority: minor
Component:
Comment (by Roland Haas):
Following up on the discussion, one can do the multiplication manually:
```
// TODO: need special code to handle the case if a or b is int64_min since -int64_min > int64_max (https://en.cppreference.com/w/cpp/numeric/math/abs#Notes)
int64_t save_mult(int64_t a, int64_t b) {
uint64_t abs_a = std::abs(a);
uint64_t abs_b = std::abs(b);
auto upper = [](uint64_t x) -> uint32_t { return (x >> 32) & 0xffffffffu; };
auto lower = [](uint64_t x) -> uint32_t { return (x >> 0) & 0xffffffffu; };
assert(upper(abs_a) * upper(abs_b) == 0);
assert(upper(upper(abs_a) * lower(abs_b)) == 0);
assert(upper(lower(abs_a) * upper(abs_b)) == 0);
// so far: no overflow for uint64_t, now check that we are not exceeding int64_max (~ 1/2 of uint64_max)
assert(abs_a * abs_b <= std::numeric_limits<int64_t>::max());
return a*b;
}
```
this does require knowing the bit-width at compile though (so is difficult with the templated `rational`) and has to handle corner cases.
--
Ticket URL: https://bitbucket.org/einsteintoolkit/tickets/issues/2925/overflow-in-rat-i…
#2925: overflow in rat<int64> in Arith
Reporter: Roland Haas
Status: new
Milestone:
Version:
Type: bug
Priority: minor
Component:
Arith implements rational numbers which are used by CarpetX to track iterations on refinement levels, so that it can handle the fractional times of the coarse step that are used by refined levels.
In https://github.com/EinsteinToolkit/CarpetX/pull/377#pullrequestreview-39946… I had to find the maximum and minimum iteration used during interpolation and a code putting an elephant in a known location:
```
diff --git a/CarpetX/src/interpolate.cxx b/CarpetX/src/interpolate.cxx
index eee39a9a..2c490c68 100644
--- a/CarpetX/src/interpolate.cxx
+++ b/CarpetX/src/interpolate.cxx
@@ -664,6 +664,11 @@ extern "C" void CarpetX_Interpolate(const CCTK_POINTER_TO_CONST cctkGH_,
givis.at(v) = {gi, vi};
}
+ rat64 min_level_iteration_used =
+ std::numeric_limits<decltype(min_level_iteration_used.num)>::max();
+ rat64 max_level_iteration_used =
+ std::numeric_limits<decltype(max_level_iteration_used.num)>::min();
+ bool requires_interpolation_in_time = false;
for (const auto &patchdata : ghext->patchdata) {
const int patch = patchdata.patch;
for (const auto &leveldata : patchdata.leveldata) {
@@ -676,6 +681,11 @@ extern "C" void CarpetX_Interpolate(const CCTK_POINTER_TO_CONST cctkGH_,
const GridDesc grid(leveldata, mfp);
// const int component = mfp.index();
+ min_level_iteration_used =
+ std::min(min_level_iteration_used, leveldata.iteration);
+ max_level_iteration_used =
+ std::max(max_level_iteration_used, leveldata.iteration);
+
const int np = pti.numParticles();
const auto &particles = pti.GetArrayOfStructs();
```
fails as pointed out in the comment by Yosef since `min(rat64,rat64)` computes products of numerator and denominator which are guaranteed to overflow given that one numerator is `INT64_MAX`.
For this special case the workaround is to keep track of whether one has already set the min / max candidate, but the issue is present in general in that overflows can happen.
Generic routines to compare that avoid overflows would require for example repeated divisions with remainders or having access to a double-length variable type (but there's not `int128_t` in C++).
For use as an iteration counter (since Cactus's `cctk_iteration` is 32 bits only) a rat32 would be sufficient, which would provide access to `int64_t` for the multiplication as an intermediate result.
This ticket exists solely to record the fact that this is a known issue.
--
Ticket URL: https://bitbucket.org/einsteintoolkit/tickets/issues/2925/overflow-in-rat-i…
#2922: CarpetX does not compile with CUDA 12.9
Reporter: Steven R. Brandt
Status: new
Milestone: ET_2026_05
Version:
Type: bug
Priority: major
Component: CarpetX
Comment (by Roland Haas):
Could you provide the error message and the diff your workaround, please?
--
Ticket URL: https://bitbucket.org/einsteintoolkit/tickets/issues/2922/carpetx-does-not-…
#2909: Remove TAGS from interface.ccl
Reporter: Steven R. Brandt
Status: open
Milestone: ET_2025_05
Version: ET_2025_05
Type: enhancement
Priority: major
Component: Cactus
Comment (by Roland Haas):
Discussed in today’s ET call.
--
Ticket URL: https://bitbucket.org/einsteintoolkit/tickets/issues/2909/remove-tags-from-…
#2175: Test "Single, stable neutron star" example
Reporter: Roland Haas
Status: open
Milestone: ET_2026_05
Version: development version
Type: task
Priority: major
Component: EinsteinToolkit website
Comment (by Beyhan Karakaş):
The gallery example was successfully tested on 25 March, and website was updated.
--
Ticket URL: https://bitbucket.org/einsteintoolkit/tickets/issues/2175/test-single-stabl…
#2923: ADIOS2 compilation fails due to unknown type name ‘INT4’
Reporter: Cheng-Hsin Cheng
Status: new
Milestone:
Version: ET_2025_05
Type: bug
Priority: major
Component: EinsteinToolkit thorn
Comment (by Roland Haas):
has this been resolved?
--
Ticket URL: https://bitbucket.org/einsteintoolkit/tickets/issues/2923/adios2-compilatio…