Skip to content

Commit c1f91c8

Browse files
Address review: fix int64 truncation clipping bounds and add float64 unit test
1 parent 4af85a4 commit c1f91c8

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

warp/native/builtin.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,20 @@ typedef const char* str;
110110
template <typename F>
111111
CUDA_CALLABLE inline int64 safe_float_to_int64(F x) {
112112
if (!(x == x)) return 0;
113-
constexpr F min_int64 = static_cast<F>(-9223372036854775808.0);
114-
constexpr F max_int64 = static_cast<F>(9223372036854774784.0);
115-
if (x <= min_int64) return -9223372036854775807LL - 1LL;
116-
if (x >= max_int64) return 9223372036854775807LL;
113+
constexpr F min_int64 = static_cast<F>(-9223372036854775808.0); // -2^63
114+
constexpr F max_overflow = static_cast<F>(9223372036854775808.0); // 2^63
115+
if (x < min_int64) return -9223372036854775807LL - 1LL;
116+
if (x >= max_overflow) return 9223372036854775807LL;
117117
return static_cast<int64>(x);
118118
}
119119

120120
template <typename F>
121121
CUDA_CALLABLE inline uint64 safe_float_to_uint64(F x) {
122122
if (!(x == x)) return 0;
123123
if (x <= 0.0) return static_cast<uint64>(safe_float_to_int64(x));
124-
constexpr F pow2_63 = static_cast<F>(9223372036854775808.0);
125-
constexpr F max_uint64 = static_cast<F>(18446744073709551615.0);
126-
if (x >= max_uint64) return 18446744073709551615ULL;
124+
constexpr F pow2_63 = static_cast<F>(9223372036854775808.0); // 2^63
125+
constexpr F overflow_uint64 = static_cast<F>(18446744073709551616.0); // 2^64
126+
if (x >= overflow_uint64) return 18446744073709551615ULL;
127127
if (x >= pow2_63) return static_cast<uint64>(safe_float_to_int64(x - pow2_63)) + 9223372036854775808ULL;
128128
return static_cast<uint64>(safe_float_to_int64(x));
129129
}

warp/tests/test_codegen_instancing.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,15 @@ def k(input: float, expected: float):
10901090
type_closure_kernel_float = create_type_closure_scalar(float)
10911091
type_closure_kernel_uint8 = create_type_closure_scalar(wp.uint8)
10921092

1093+
def create_type_closure_scalar_f64(scalar_type):
1094+
@wp.kernel
1095+
def k(input: wp.float64, expected: wp.float64):
1096+
x = scalar_type(input)
1097+
wp.expect_eq(wp.float64(x), expected)
1098+
return k
1099+
1100+
type_closure_kernel_uint64_f64 = create_type_closure_scalar_f64(wp.uint64)
1101+
10931102

10941103
def test_type_closure_scalar(test, device):
10951104
with wp.ScopedDevice(device):
@@ -1101,6 +1110,9 @@ def test_type_closure_scalar(test, device):
11011110
wp.launch(type_closure_kernel_uint8, dim=1, inputs=[255.1, 255.0])
11021111
wp.launch(type_closure_kernel_uint8, dim=1, inputs=[128.0, 128.0])
11031112
wp.launch(type_closure_kernel_uint8, dim=1, inputs=[-100.0, 156.0])
1113+
1114+
# Test boundary cases for uint64 truncation safety with float64 precision
1115+
wp.launch(type_closure_kernel_uint64_f64, dim=1, inputs=[9223372036854774784.0, 9223372036854774784.0])
11041116

11051117

11061118
# =======================================================================

0 commit comments

Comments
 (0)