[GPU] complex `sin` op results `nan`
- Dominant language
- Python
- Stars
- 16.8k
- Forks
- 603
- Avg merge
- 4d 23h
- Merged PRs (30d)
- 6
Description
### Summary
This issue appears to be a partial manifestation of #781, the uninitialized GV issue.
### MRE
```python
import cmath
import gpu
@gpu.kernel
def kernel(xs, out_real, out_imag):
z = cmath.sin(xs[0])
out_real[0] = z.real
out_imag[0] = z.imag
x = complex(0.5, 0.25)
cpu = cmath.sin(x)
out_real = [0.0]
out_imag = [0.0]
kernel([x], out_real, out_imag, grid=1, block=1)
gpu_result = complex(out_real[0], out_imag[0])
print("input:", x)
print("CPU cmath.sin:", cpu)
print("GPU cmath.sin:", gpu_result)
```
### results
```bash
$ codon run -release mre_complex_sin.codon
input: (0.5+0.25j)
CPU cmath.sin: (0.494486+0.221688j)
GPU cmath.sin: (nan+nanj)
```
### Root Cause
For complex values, `cmath.sin` is not lowered to the primitive `sin(float)` operation directly.
Instead, it is evaluated using the `Euler-based` complex formula:
```
For complex var C = a + bi
sin(C) = sin(a) * cosh(b) + i * cos(a) * sinh(b)
```
The CPU implementation appears to compute this correctly, while the GPU version returns `nan`.
In `cmath.codon`, the complex implementation uses GV-backed constants/functions:
```
if math.fabs(z.real) > _CM_LOG_LARGE_DOUBLE:
x_minus_one = z.real - math.copysign(1., z.real)
r_real = math.cos(z.imag) * math.sinh(x_minus_one) * e
r_imag = math.sin(z.imag) * math.cosh(x_minus_one) * e
else:
r_real = math.cos(z.imag) * math.sinh(z.real)
r_imag = math.sin(z.imag) * math.cosh(z.real)
```
As discussed in #781, this seems likely to be caused by the `uninitialized GV issue`.
Contributor guide
Assessment
This issue has not been assessed yet.