[math] Comeau can't match math::tools::fmod_workaround

Hi, I'm not sure if I should submit this issue directly to Trac, so I decided to post it here first. Compiling Boost.Math using Comeau + GCC on Linux throws error that suggests mismatch of dobule and long double where single type T is expected: como-linux.compile.c++ ../../../bin.v2/libs/math/build/como-linux/debug/link-static/ellint_3l.o Comeau C/C++ 4.3.10.1 (May 7 2008 12:23:21) for LINUX_INTEL_ELF_Beta Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:non-strict warnings C++ noC++0x_extensions "../../../boost/math/special_functions/ellint_3.hpp", line 185: error: no instance of function template "boost::math::tools::fmod_workaround" matches the argument list argument types are: (double, long double) T rphi = boost::math::tools::fmod_workaround(fabs(phi), T(constants::pi<T>() / 2)); ^ detected during instantiation of "T boost::math::detail::ellint_pi_imp(T, T, T, T, const Policy &) [with T=long double, Policy=c_policies::c_policy]" at line 309 1 error detected in the compilation of "../../../libs/math/build/../src/tr1/ellint_3l.cpp". como -tused -c --long_long -DBOOST_ALL_NO_LIB=1 -D_GNU_SOURCE=1 --no_inlining -O0 -g --exceptions -I"../../.." -I"../../../libs/math/src/tr1" -o "../../../bin.v2/libs/math/build/como-linux/debug/link-static/ellint_3l.o" "../../../libs/math/build/../src/tr1/ellint_3l.cpp" Could any one confirm if it is an error indeed? Should I submit ticket? Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

Mateusz Loskot wrote:
Hi,
I'm not sure if I should submit this issue directly to Trac, so I decided to post it here first. Compiling Boost.Math using Comeau + GCC on Linux throws error that suggests mismatch of dobule and long double where single type T is expected:
como-linux.compile.c++ ../../../bin.v2/libs/math/build/como-linux/debug/link-static/ellint_3l.o Comeau C/C++ 4.3.10.1 (May 7 2008 12:23:21) for LINUX_INTEL_ELF_Beta Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:non-strict warnings C++ noC++0x_extensions
"../../../boost/math/special_functions/ellint_3.hpp", line 185: error: no instance of function template "boost::math::tools::fmod_workaround" matches the argument list argument types are: (double, long double) T rphi = boost::math::tools::fmod_workaround(fabs(phi), T(constants::pi<T>() / 2)); ^ detected during instantiation of "T boost::math::detail::ellint_pi_imp(T, T, T, T, const Policy &) [with T=long double, Policy=c_policies::c_policy]" at line 309
Replacing single line 185 with call to math::tools::fmod_workaround in file trunk/boost/math/special_functions/ellint_3.hpp with separately cached results of fabs and pi<T> functions enables compilation without errors: T f = fabs(phi); T pi2 = T(constants::pi<T>() / 2); T rphi = boost::math::tools::fmod_workaround(f, pi2); T m = floor((2 * fabs(phi)) / constants::pi<T>()); Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

Mateusz Loskot wrote:
Hi,
I'm not sure if I should submit this issue directly to Trac, so I decided to post it here first. Compiling Boost.Math using Comeau + GCC on Linux throws error that suggests mismatch of dobule and long double where single type T is expected:
I've just found very similar issue in other place. It is std::pow specialisations seem ambiguous for Comeau C/C++ compiler. "../../../boost/math/special_functions/spherical_harmonic.hpp", line 39: error: more than one instance of overloaded function "pow" matches the argument list: function "std::pow(const std::complex<long double> &, const long double &)" function "std::pow(const double &, const std::complex<double> &)" function "std::pow(long double, long double)" function "std::pow(double, int)" function "std::pow(double, double)" argument types are: (double, long double) T leg = detail::legendre_p_imp(n, m, x, pow(fabs(sin_theta), T(m)), pol); ^ detected during: instantiation of "T boost::math::detail::spherical_harmonic_prefix(unsigned int, unsigned int, T, const Policy &) [with T=long double, Policy=c_policies::c_policy]" at line 71 instantiation of "T boost::math::detail::spherical_harmonic_r(unsigned int, int, T, T, const Policy &) [with T=long double, Policy=c_policies::c_policy]" at line 172 I thought it may be of interest. Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

Mateusz Loskot wrote:
Mateusz Loskot wrote:
Hi,
I'm not sure if I should submit this issue directly to Trac, so I decided to post it here first. Compiling Boost.Math using Comeau + GCC on Linux throws error that suggests mismatch of dobule and long double where single type T is expected:
I've just found very similar issue in other place. It is std::pow specialisations seem ambiguous for Comeau C/C++ compiler.
"../../../boost/math/special_functions/spherical_harmonic.hpp", line 39: error: more than one instance of overloaded function "pow" matches the argument list: function "std::pow(const std::complex<long double> &, const long double &)" function "std::pow(const double &, const std::complex<double> &)" function "std::pow(long double, long double)" function "std::pow(double, int)" function "std::pow(double, double)" argument types are: (double, long double) T leg = detail::legendre_p_imp(n, m, x, pow(fabs(sin_theta), T(m)), pol); ^ detected during: instantiation of "T
boost::math::detail::spherical_harmonic_prefix(unsigned int, unsigned int, T, const Policy &) [with T=long double, Policy=c_policies::c_policy]" at line 71 instantiation of "T boost::math::detail::spherical_harmonic_r(unsigned int, int, T, T, const Policy &) [with T=long double, Policy=c_policies::c_policy]" at line 172
Similarly to original issue with math::tools::fmod_workaround, caching intermediate values solves the problem. Replacing line 39 in boost/math/special_functions/spherical_harmonic.hpp with cached fabs and pow results: T f = fabs(sin_theta); T pfm = pow(f, T(m)); T leg = detail::legendre_p_imp(n, m, x, pfm, pol); By the way, I'm wondering, is it intentional, in Boost.Math, to omit const qualifier for intermediate results? I know modern compilers can optimise perfectly well even if const is not present, but *perhaps* it would help some compilers to in optimisation. Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

Could any one confirm if it is an error indeed?
These all look to be related, and indicate a genuine issue: fabs(long_double_value) is returning a double (ie truncated) result :-( Can you confirm whether #include <cmath> results in fabs(long double) being defined? Thanks, John.

John Maddock wrote:
Could any one confirm if it is an error indeed?
These all look to be related, and indicate a genuine issue:
fabs(long_double_value)
is returning a double (ie truncated) result :-(
Can you confirm whether #include <cmath> results in fabs(long double) being defined?
John, I made quick test and it looks std::fabs(long double) is missing: $ cat long_double_fabs.cpp #include <cmath> template <typename T> T foo(T a, T b) { return a + b; } int main() { long double a = -1.23; long double b = std::fabs(a); // compiles foo( std::fabs(a), b ); // does not compile } $ como --strict --c++ long_double_fabs.cpp Comeau C/C++ 4.3.10.1 (May 7 2008 12:23:21) for LINUX_INTEL_ELF_Beta Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:strict errors C++ noC++0x_extensions "long_double_fabs.cpp", line 11: error: no instance of function template "foo" matches the argument list argument types are: (double, long double) foo( std::fabs(a), b ); // does not compile ^ 1 error detected in the compilation of "long_double_fabs.cpp". The <cmath> comes from libcomo library: /opt/libcomo36/include/cnames/cmath and it includes <math.h> from GNU C Library. I generated raw listing (preprocessed, etc.) and it looks that actual definition of fabs being used comes from GNU C Library and it truncates input argument to double: /* Absolute value of X. */ __MATHCALLX (fabs,, (_Mdouble_ __x), (__const__)); It may look like Comeau/libcomo issue, as long double fabs(long double) should be well defined so the simple template test above is supposed to work. Am I correct? Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

It may look like Comeau/libcomo issue, as long double fabs(long double) should be well defined so the simple template test above is supposed to work. Am I correct?
Nod, I think so. It's easy enough to disable long double support in Boost.Math, it's just a case of working out what macros the std lib sets when it's not available so we can hook into that. Is __NO_LONG_DOUBLE_MATH defined after including math.h by any chance? Thanks, John.

John Maddock wrote:
It may look like Comeau/libcomo issue, as long double fabs(long double) should be well defined so the simple template test above is supposed to work. Am I correct?
Nod, I think so.
It's easy enough to disable long double support in Boost.Math, it's just a case of working out what macros the std lib sets when it's not available so we can hook into that. Is __NO_LONG_DOUBLE_MATH defined after including math.h by any chance?
No, this macro is not defined. I contacted with Comeau team and, as they are always helpful, I've received a quick fix for this issue. It is possible to compile using Comeau with gcc/g++ compatibility mode [1] enabled. [1] http://www.comeaucomputing.com/4.3.0/minor/linux/compat.html In this mode g++ built-in functions are available, so it is possible to define missing fabs for Linux-specific configuration in which toolset includes Comeau frontend + GNU C++ compiler + GLIBC: #if defined(__linux__) && defined(__COMO__) \ && defined(__GNUG__) && defined(__GLIBC__) namespace std { inline long double fabs(long double value) { return __builtin_fabsl(value); } } #endif I've confirmed using the simple test program that this option works. The only issue with the compatibility mode is that: - it does not allow strict mode compilation using Comeau, though I don't believe it's possible to use strict mode with Boost as even relaxed mode is still not working for me - it requires --g++ option, perhaps bjam could specify it for user Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

It's easy enough to disable long double support in Boost.Math, it's just a case of working out what macros the std lib sets when it's not available so we can hook into that. Is __NO_LONG_DOUBLE_MATH defined after including math.h by any chance?
No, this macro is not defined.
I contacted with Comeau team and, as they are always helpful, I've received a quick fix for this issue. It is possible to compile using Comeau with gcc/g++ compatibility mode [1] enabled.
[1] http://www.comeaucomputing.com/4.3.0/minor/linux/compat.html
In this mode g++ built-in functions are available, so it is possible to define missing fabs for Linux-specific configuration in which toolset includes Comeau frontend + GNU C++ compiler + GLIBC:
#if defined(__linux__) && defined(__COMO__) \ && defined(__GNUG__) && defined(__GLIBC__) namespace std { inline long double fabs(long double value) { return __builtin_fabsl(value); } } #endif
I've confirmed using the simple test program that this option works.
Right, that could be a workaround for that one function, but isn't the whole lot of the long double functions missing? John.

John Maddock wrote:
It's easy enough to disable long double support in Boost.Math, it's just a case of working out what macros the std lib sets when it's not available so we can hook into that. Is __NO_LONG_DOUBLE_MATH defined after including math.h by any chance?
No, this macro is not defined.
I contacted with Comeau team and, as they are always helpful, I've received a quick fix for this issue. It is possible to compile using Comeau with gcc/g++ compatibility mode [1] enabled.
[1] http://www.comeaucomputing.com/4.3.0/minor/linux/compat.html
In this mode g++ built-in functions are available, so it is possible to define missing fabs for Linux-specific configuration in which toolset includes Comeau frontend + GNU C++ compiler + GLIBC:
#if defined(__linux__) && defined(__COMO__) \ && defined(__GNUG__) && defined(__GLIBC__) namespace std { inline long double fabs(long double value) { return __builtin_fabsl(value); } } #endif
I've confirmed using the simple test program that this option works.
Right, that could be a workaround for that one function, but isn't the whole lot of the long double functions missing?
John, I'm sorry for the long long silence about this issue. I have to admit I've sort of given up with making Boost libraries compilable with Comeau C/C++ back again. This is due to time constraints as well as the fact that it seems I'm "alone", meaning nobody seems to be using Boost with Comeau any more so there seems to be no such need to keep supporting Comeau. So, I've suspended my efforts for a while and going to take them up as soon as time permits. Thank you for your help and apologies for shutting the thread up. Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

Right, that could be a workaround for that one function, but isn't the whole lot of the long double functions missing?
John,
I'm sorry for the long long silence about this issue.
I have to admit I've sort of given up with making Boost libraries compilable with Comeau C/C++ back again. This is due to time constraints as well as the fact that it seems I'm "alone", meaning nobody seems to be using Boost with Comeau any more so there seems to be no such need to keep supporting Comeau.
So, I've suspended my efforts for a while and going to take them up as soon as time permits.
Thank you for your help and apologies for shutting the thread up.
No problem, I quite understand. If you get more time to investigate later then please do reopen this. Regards, John.
participants (2)
-
John Maddock
-
Mateusz Loskot