Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve how tuples are converted into complex values #24184

Merged
merged 5 commits into from Jan 16, 2024

Conversation

bradcray
Copy link
Member

@bradcray bradcray commented Jan 12, 2024

This updates the implementation of the _chpl_complexNNN() routines in the runtime which are used to convert a Chapel 2-tuple of reals into a complex. Specifically, my rewrite tries to use the 'CMPLX()' initializer macros rather than math to initialize the complex values. The motivation for this is to work around an issue in which inf/nan values would creep in due to an apparent bug. See the output of the test added in this PR prior to this change to see the old, odd behavior.

When this macro isn't available (as with when using C++ compilers and potentially some others? CI failed when I didn't have this option available), I am currently falling back to an aliasing-based approach to poke the real and imaginary values into the complex and then returning it. This generates the correct values as well, though feels a bit squirrely.

By building the runtime with CHPL_DONT_USE_CMPLX_PTR_ALIASING, you can go back to the original implementation we've used, which performs math and gets the "mathematically wrong" answer.

If anyone going forward has suggestions for making these conversion routines work equally well in C as C++ with fewer options involved, I'm all ears. This was the best I was able to come up with after some internet browsing.

This changes the implementation of the _chpl_complexNNN() routines in
the runtime to use the 'CMPLX()' initializer macros rather than math
to initialize the complex values.  This seems to work around an issue
in which inf/nan values would creep in for reasons I don't (yet)
understand.

The one trick to this change is that I had to protect the code to not
compile it in C++ mode.  I believe this is fine because re2 is the
only runtime code we compile with C++ and it doesn't need our complex
types and routines.  This almost made me compelled to break the
complex types out of chpltypes.h and into their own header, but that
felt like a lot of trouble to go to for C++ when we're mostly focused
on C in the runtime.

If anyone going forward has suggestions for making these conversion
routines work equally well in C as C++, I'm all ears!

---
Signed-off-by: Brad Chamberlain <bradcray@users.noreply.github.com>
---
Signed-off-by: Brad Chamberlain <bradcray@users.noreply.github.com>
* use initialization macros, when available
* fall back to aliasing trick if not
* support the old implementation as a fallback if someone doesn't
  like the aliasing trick and wants to disable it

---
Signed-off-by: Brad Chamberlain <bradcray@users.noreply.github.com>
@bradcray bradcray marked this pull request as ready for review January 12, 2024 18:24
---
Signed-off-by: Brad Chamberlain <bradcray@users.noreply.github.com>
runtime/include/chpltypes.h Outdated Show resolved Hide resolved
runtime/include/chpltypes.h Show resolved Hide resolved
(I'd cleaned up some of what I'd found online, but not enough)

---
Signed-off-by: Brad Chamberlain <bradcray@users.noreply.github.com>
@bradcray bradcray merged commit c59a16e into chapel-lang:main Jan 16, 2024
7 checks passed
@bradcray bradcray deleted the simplify-tuple-to-complex branch January 16, 2024 20:24
bradcray added a commit to bradcray/chapel that referenced this pull request Jan 18, 2024
Though compiling PR chapel-lang#24184 with a back-end C++ compiler worked on my laptop
and chapcs11, it caused problems with other C++ compilers, like g++ (SUSE
Linux) 7.5.0 on [redacted] and some of our other nightly configurations.

At present, it's somewhat circumstantial that we compile this code with a C++
compiler: It only happens when compiling our qio re2 shim code, and that code
doesn't rely on these tuple-to-complex conversion routines anyway.  As a
result, what I've done here is to beef up my #ifndef to skip over the new
preferred path of code when we're compiling for C++ to be safe, and on the
assumption that it doesn't really matter anyway (won't be called); and even if
that changes in the future, the fallback paths from chapel-lang#24184 ought to work...

---
Signed-off-by: Brad Chamberlain <bradcray@users.noreply.github.com>
bradcray added a commit that referenced this pull request Jan 18, 2024
[reviewed by @mppf]

Though compiling PR #24184 with a back-end C++ compiler worked on my
laptop and [redacted], it caused problems with other C++ compilers, like
g++ (SUSE Linux) 7.5.0 on [redacted] and some of our other nightly
testing configurations.

At present, it's somewhat circumstantial that we compile this code with
a C++ compiler at all: It only happens when compiling our qio re2 shim
code, and that code doesn't rely on these tuple-to-complex conversion
routines anyway. As a result, what I've done here is to beef up my
#ifndef to skip over the new preferred path of code when we're compiling
for C++ to be safe, and on the assumption that it doesn't really matter
anyway (won't be called); and even if that changes in the future, the
fallback paths from #24184 ought to work...

(As potentiall future work, we could also refactor our header files so
that the re2 shim only gets definitions that it truly needs, which
probably would involve forking some portions of chpltypes.h out of it
and into another header. I started into this as part of #24184 before
deciding it was overkill for that PR).
mppf added a commit that referenced this pull request Jan 25, 2024
Follow-up to PR #24127.

After #24127, the new `sqrtparams` test started to fail on Mac OS X
system. Upon investigating, I identified that the difference in behavior
from what the test expects is due to differences in how `std::sqrt` is
implemented for complex numbers in libc++ vs stdlibc++. Also, I noticed
that the issue is limited to the C++ implementation of the complex
square root.

This PR changes the implementation to use a C implementation of complex
square root since it appears to have more reliable precision. Note that
this C implementation required some workarounds for `CMPLX` not being
available on all systems (as with PR #24184 and #24211). In particular,
`CMPLX` does not seem to be available when using `clang` on Ubuntu
23.10, even though it is available with `gcc` on that system.

I filed an issue against libc++ about the problem, but in discussion
there it sounds like complex `sqrt` isn't required to have any
particular precision.
 * llvm/llvm-project#78738

Reviewed by @DanilaFe - thanks!

- [x] full comm=none testing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants