From ca3f57968e7be3501e40ae0c3d4dbc4742eadc4b Mon Sep 17 00:00:00 2001 From: Michael Ferguson Date: Thu, 18 Jan 2024 17:37:01 -0500 Subject: [PATCH 1/5] Add a suppressif for sqrtrparams --- Signed-off-by: Michael Ferguson --- test/library/standard/AutoMath/sqrtparams.suppressif | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/library/standard/AutoMath/sqrtparams.suppressif diff --git a/test/library/standard/AutoMath/sqrtparams.suppressif b/test/library/standard/AutoMath/sqrtparams.suppressif new file mode 100644 index 000000000000..5ff569b7c338 --- /dev/null +++ b/test/library/standard/AutoMath/sqrtparams.suppressif @@ -0,0 +1,2 @@ +# libc++ does not have an IEEE standard compliant sqrt +CHPL_TARGET_PLATFORM == darwin From 8cae620254bfc99a1154803c85500df16460e9dc Mon Sep 17 00:00:00 2001 From: Michael Ferguson Date: Fri, 19 Jan 2024 10:40:38 -0500 Subject: [PATCH 2/5] Avoid libc++ complex sqrt problem by using C --- Signed-off-by: Michael Ferguson --- frontend/lib/immediates/CMakeLists.txt | 8 +++- frontend/lib/immediates/complex-support.c | 39 +++++++++++++++++ frontend/lib/immediates/complex-support.h | 42 +++++++++++++++++++ frontend/lib/immediates/num.cpp | 23 +++------- frontend/lib/immediates/num.h | 11 +---- .../standard/AutoMath/sqrtparams.suppressif | 2 - 6 files changed, 94 insertions(+), 31 deletions(-) create mode 100644 frontend/lib/immediates/complex-support.c create mode 100644 frontend/lib/immediates/complex-support.h delete mode 100644 test/library/standard/AutoMath/sqrtparams.suppressif diff --git a/frontend/lib/immediates/CMakeLists.txt b/frontend/lib/immediates/CMakeLists.txt index 2a887a1ddf17..9bba661fbccd 100644 --- a/frontend/lib/immediates/CMakeLists.txt +++ b/frontend/lib/immediates/CMakeLists.txt @@ -18,10 +18,14 @@ target_sources(ChplFrontend-obj PRIVATE - ifa_vars.cpp + # C sources + complex-support.h + complex-support.c + + # C++ sources hash_multipliers.cpp + ifa_vars.cpp num.cpp num.h prim_data.h - ) diff --git a/frontend/lib/immediates/complex-support.c b/frontend/lib/immediates/complex-support.c new file mode 100644 index 000000000000..f9baaa8366f9 --- /dev/null +++ b/frontend/lib/immediates/complex-support.c @@ -0,0 +1,39 @@ +/* + * Copyright 2024 Hewlett Packard Enterprise Development LP + * Other additional copyright holders may be indicated within. + * + * The entirety of this work is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "complex-support.h" + +#include + +struct complex64 complexSqrt64(struct complex64 x) { + float complex c = CMPLXF(x.r, x.i); + float complex n = csqrtf(c); + struct complex64 ret; + ret.r = crealf(n); + ret.i = cimagf(n); + return ret; +} +struct complex128 complexSqrt128(struct complex128 x) { + double complex c = CMPLX(x.r, x.i); + double complex n = csqrt(c); + struct complex128 ret; + ret.r = creal(n); + ret.i = cimag(n); + return ret; +} diff --git a/frontend/lib/immediates/complex-support.h b/frontend/lib/immediates/complex-support.h new file mode 100644 index 000000000000..9b57e3d731c5 --- /dev/null +++ b/frontend/lib/immediates/complex-support.h @@ -0,0 +1,42 @@ +/* + * Copyright 2024 Hewlett Packard Enterprise Development LP + * Other additional copyright holders may be indicated within. + * + * The entirety of this work is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IMMEDIATES_COMPLEX_SQRT_H +#define IMMEDIATES_COMPLEX_SQRT_H + +/* + + This header exists to work around a problem with complex square root being + innacurate on libc++ by using C functions to do the complex square root. + + */ + +struct complex64 { + float r; + float i; +}; +struct complex128 { + double r; + double i; +}; + +struct complex64 complexSqrt64(struct complex64 x); +struct complex128 complexSqrt128(struct complex128 x); + +#endif diff --git a/frontend/lib/immediates/num.cpp b/frontend/lib/immediates/num.cpp index 40e26582cc37..2f90bf344d69 100644 --- a/frontend/lib/immediates/num.cpp +++ b/frontend/lib/immediates/num.cpp @@ -31,7 +31,11 @@ #include #include #include -#include +//#include + +extern "C" { +#include "complex-support.h" +} #include "num.h" #include "prim_data.h" @@ -489,23 +493,6 @@ coerce_immediate(chpl::Context* context, Immediate *from, Immediate *to) { break; \ } -static complex64 complexSqrt64(complex64 x) { - auto c = std::complex(x.r, x.i); - auto n = std::sqrt(c); - complex64 ret; - ret.r = std::real(n); - ret.i = std::imag(n); - return ret; -} -static complex128 complexSqrt128(complex128 x) { - auto c = std::complex(x.r, x.i); - auto n = std::sqrt(c); - complex128 ret; - ret.r = std::real(n); - ret.i = std::imag(n); - return ret; -} - static void doFoldSqrt(chpl::Context* context, Immediate &im1, /* input */ Immediate *imm /* output */) { diff --git a/frontend/lib/immediates/num.h b/frontend/lib/immediates/num.h index 29a2e426e766..ea85c0a17714 100644 --- a/frontend/lib/immediates/num.h +++ b/frontend/lib/immediates/num.h @@ -24,6 +24,8 @@ #include "chpl/framework/Context.h" #include "chpl/framework/UniqueString.h" +#include "complex-support.h" + #include #include #include @@ -38,15 +40,6 @@ extern unsigned int open_hash_multipliers[256]; -struct complex64 { - float r; - float i; -}; -struct complex128 { - double r; - double i; -}; - using ImmString = chpl::detail::PODUniqueString; // diff --git a/test/library/standard/AutoMath/sqrtparams.suppressif b/test/library/standard/AutoMath/sqrtparams.suppressif deleted file mode 100644 index 5ff569b7c338..000000000000 --- a/test/library/standard/AutoMath/sqrtparams.suppressif +++ /dev/null @@ -1,2 +0,0 @@ -# libc++ does not have an IEEE standard compliant sqrt -CHPL_TARGET_PLATFORM == darwin From c2f0424e46fc1150931b35ec9b4fdd916f5c4804 Mon Sep 17 00:00:00 2001 From: Michael Ferguson Date: Fri, 19 Jan 2024 12:03:36 -0500 Subject: [PATCH 3/5] Adjust to work on systems without CMPLX --- Signed-off-by: Michael Ferguson --- frontend/lib/immediates/complex-support.c | 44 +++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/frontend/lib/immediates/complex-support.c b/frontend/lib/immediates/complex-support.c index f9baaa8366f9..d5e17f65c28c 100644 --- a/frontend/lib/immediates/complex-support.c +++ b/frontend/lib/immediates/complex-support.c @@ -21,8 +21,48 @@ #include +static double complex makeDoubleComplex(double re, double im) { + // Some test environments don't have a working CMPLXF + // so use another way to set if needed. +#if defined(CMPLX) + return CMPLX(re, im); +#else +#ifndef CHPL_DONT_USE_CMPLX_PTR_ALIASING +#define cmplx_re64(c) (((double *)&(c))[0]) +#define cmplx_im64(c) (((double *)&(c))[1]) + double complex val; + cmplx_re64(val) = re; + cmplx_im64(val) = im; + return val; +#else + // This can generate bad values in the face of inf/nan values + return re + im*_Complex_I; +#endif +#endif +} + +static float complex makeFloatComplex(float re, float im) { + // Some test environments don't have a working CMPLXF + // so use another way to set if needed. +#if defined(CMPLXF) + return CMPLXF(re, im); +#else +#ifndef CHPL_DONT_USE_CMPLX_PTR_ALIASING +#define cmplx_re32(c) (((float *)&(c))[0]) +#define cmplx_im32(c) (((float *)&(c))[1]) + float complex val; + cmplx_re32(val) = re; + cmplx_im32(val) = im; + return val; +#else + // This can generate bad values in the face of inf/nan values + return re + im*_Complex_I; +#endif +#endif +} + struct complex64 complexSqrt64(struct complex64 x) { - float complex c = CMPLXF(x.r, x.i); + float complex c = makeFloatComplex(x.r, x.i); float complex n = csqrtf(c); struct complex64 ret; ret.r = crealf(n); @@ -30,7 +70,7 @@ struct complex64 complexSqrt64(struct complex64 x) { return ret; } struct complex128 complexSqrt128(struct complex128 x) { - double complex c = CMPLX(x.r, x.i); + double complex c = makeDoubleComplex(x.r, x.i); double complex n = csqrt(c); struct complex128 ret; ret.r = creal(n); From 58c304eec752a07399491e6f98bc56ba1f7655e0 Mon Sep 17 00:00:00 2001 From: Michael Ferguson Date: Fri, 19 Jan 2024 12:18:30 -0500 Subject: [PATCH 4/5] Only include complex-support.h once, and do it in C linkage --- Signed-off-by: Michael Ferguson --- frontend/lib/immediates/num.cpp | 5 ----- frontend/lib/immediates/num.h | 4 +++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/frontend/lib/immediates/num.cpp b/frontend/lib/immediates/num.cpp index 2f90bf344d69..aaadb1b8563f 100644 --- a/frontend/lib/immediates/num.cpp +++ b/frontend/lib/immediates/num.cpp @@ -31,11 +31,6 @@ #include #include #include -//#include - -extern "C" { -#include "complex-support.h" -} #include "num.h" #include "prim_data.h" diff --git a/frontend/lib/immediates/num.h b/frontend/lib/immediates/num.h index ea85c0a17714..09fcb1c7ed9f 100644 --- a/frontend/lib/immediates/num.h +++ b/frontend/lib/immediates/num.h @@ -24,7 +24,9 @@ #include "chpl/framework/Context.h" #include "chpl/framework/UniqueString.h" -#include "complex-support.h" +extern "C" { + #include "complex-support.h" +} #include #include From fbbc30ca730f2569199b61f0111da1f9ee89dde8 Mon Sep 17 00:00:00 2001 From: Michael Ferguson Date: Thu, 25 Jan 2024 10:09:25 -0500 Subject: [PATCH 5/5] Edit a comment --- Signed-off-by: Michael Ferguson --- frontend/lib/immediates/complex-support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/lib/immediates/complex-support.c b/frontend/lib/immediates/complex-support.c index d5e17f65c28c..8bc06560c169 100644 --- a/frontend/lib/immediates/complex-support.c +++ b/frontend/lib/immediates/complex-support.c @@ -22,7 +22,7 @@ #include static double complex makeDoubleComplex(double re, double im) { - // Some test environments don't have a working CMPLXF + // Some test environments don't have a working CMPLX // so use another way to set if needed. #if defined(CMPLX) return CMPLX(re, im);