Skip to content

Rounding issue with the power function on integers #1233

@magnatelee

Description

@magnatelee

@ejmeitz recently reported this weird behavior that the power function on 32-bit integers don't produce correct results:

> LEGATE_TEST=1 LEGATE_CONFIG="--gpus 1 --auto-config 0" python
Python 3.13.7 [...]
>>> import cupynumeric as np
>>> a = np.array([117] * 10, dtype="int32")
>>> b = np.array([1] * 10, dtype="int32")
>>> print(a ** b)
[116 116 116 116 116 116 116 116 116 116]         # Oops

This happens only when the code goes through the GPU code path, and as it turns out, the correctness issue is due to GPU's rounding behavior: because the power function on integer values is implemented using the power function on doubles and type conversions, the float-to-integer conversions can cause correctness issues.

Unfortunately, there's no single correct rounding mode we can consistently use blindly for all values, here's a CUDA program that checks the correctness of roundtrip conversion (int32->double->int32) up to 1024. It'd report only one of two rounding modes (round-up vs. round-down) is correct for some of the values and it's not always the same one that is correct.

I can't think of a reasonable solution here other than implementing a power function on integer values that doesn't do type conversions. Here's a CuPy implementation we can copy from: https://github.com/cupy/cupy/blob/39dcf763dd339afcd49e51f4e5a0311370baa61c/cupy/_core/_routines_math.pyx#L983-L997

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions