Actions

icon Post
text/html Subscribe
text/html Unsubscribe

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch] RFA mercury's missing std::abs


  • To: VSIPL++ Developers List <vsipl++@xxxxxxxxxxxxxxxx>
  • Subject: [patch] RFA mercury's missing std::abs
  • From: Jules Bergmann <jules@xxxxxxxxxxxxxxxx>
  • Date: Fri, 11 Nov 2005 08:59:24 -0500

This patch checks for missing std::abs overloads for float and double at configure time. If missing (and ::abs overloads exist), VSIP_IMPL_FIX_MISSING_ABS is defined, which causes vsip::mag and vsip::magsq to use a blend of vsip::abs and ::abs.

This should be more robust than relying on the order of <cmath> and <cstdlib> (which might break if users include standard headers before including vsip headers -- something I tend to do).

Comments?

Patch also

 - uses vsip::mag in tests/test.hpp instead of std::abs.

 - throws an exception if general dispatch fails (instead of assert).
   Right thing to do, and fixes greenhills warning about function
   not returning a value.

				-- Jules
Index: ChangeLog
===================================================================
RCS file: /home/cvs/Repository/vpp/ChangeLog,v
retrieving revision 1.303
diff -c -p -r1.303 ChangeLog
*** ChangeLog	11 Nov 2005 00:07:59 -0000	1.303
--- ChangeLog	11 Nov 2005 13:50:40 -0000
***************
*** 1,3 ****
--- 1,14 ----
+ 2005-11-11 Jules Bergmann  <jules@xxxxxxxxxxxxxxxx>
+ 
+ 	* configure.ac (VSIP_IMPL_FIX_MISSING_ABS): New define, set if
+ 	  missing std::abs overloads for float and double.
+ 	* src/vsip/impl/fns_scalar.hpp (mag, magsq): Use abs_detail::abs
+ 	  instead of std::abs.  Set abs_detail::abs based on
+ 	  VSIP_IMPL_FIX_MISSING_ABS.
+ 	* src/vsip/impl/general_dispatch.hpp: When dispatch fail, throw
+ 	  exception rather than assert.
+ 	* tests/test.hpp: Use vsip::mag instead of std::abs.
+ 	
  2005-11-10  Don McCoy  <don@xxxxxxxxxxxxxxxx>
  
  	* tests/matvec-prod.cpp: Re-arranged tests to avoid running tests
Index: configure.ac
===================================================================
RCS file: /home/cvs/Repository/vpp/configure.ac,v
retrieving revision 1.48
diff -c -p -r1.48 configure.ac
*** configure.ac	10 Nov 2005 05:44:02 -0000	1.48
--- configure.ac	11 Nov 2005 13:50:40 -0000
*************** int main(int, char **)
*** 208,213 ****
--- 208,261 ----
  [AC_MSG_RESULT(yes)],
  [AC_MSG_ERROR([Incompatible std::complex types detected!])])
  
+ 
+ #
+ # Check for the std::abs(float) and std::abs(double) overloads.
+ #
+ # GreenHills <cmath> defines ::abs(float) and ::abs(double), but does
+ # not place them into the std namespace when targeting mercury (when
+ # _MC_EXEC is defined).
+ 
+ # First check if std::abs handles float and double:
+ AC_MSG_CHECKING([for std::abs(float) and std::abs(double).])
+ have_abs_float="no"
+ AC_COMPILE_IFELSE([
+ #include <cmath>
+ 
+ int main(int, char **)
+ {
+   float f1 = 1.f;
+   f1 = std::abs(f1); 
+   double d1 = 1.0;
+   d1 = std::abs(d1); 
+ }
+ ],
+ [have_abs_float="std"
+  AC_MSG_RESULT(yes)],
+ [AC_MSG_RESULT([missing!])])
+ 
+ if test "$have_abs_float" = "no"; then
+   # next check for them in ::
+   AC_MSG_CHECKING([for ::abs(float) and ::abs(double).])
+   AC_COMPILE_IFELSE([
+ #include <cmath>
+ 
+ int main(int, char **)
+ {
+   float f1 = 1.f;
+   f1 = ::abs(f1); 
+   double d1 = 1.0;
+   d1 = ::abs(d1); 
+ }
+ ],
+   [have_abs_float="global"
+    AC_MSG_RESULT(yes)],
+   [AC_MSG_ERROR([missing!])])
+   AC_DEFINE_UNQUOTED(VSIP_IMPL_FIX_MISSING_ABS, 1,
+       [Define to use both ::abs and std::abs for vsip::mag.])
+ fi
+ 
+ 
  #
  # Check for the exp10 function.  
  #
Index: src/vsip/impl/fns_scalar.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/fns_scalar.hpp,v
retrieving revision 1.13
diff -c -p -r1.13 fns_scalar.hpp
*** src/vsip/impl/fns_scalar.hpp	10 Nov 2005 05:44:02 -0000	1.13
--- src/vsip/impl/fns_scalar.hpp	11 Nov 2005 13:50:40 -0000
*************** template <typename T>
*** 110,124 ****
  inline T 
  lnot(T t) VSIP_NOTHROW { return !t;}
  
  template <typename T>
  inline typename impl::Scalar_of<T>::type 
! mag(T t) VSIP_NOTHROW { return std::abs(t);}
  
  template <typename T>
  inline typename impl::Scalar_of<T>::type 
  magsq(T t) VSIP_NOTHROW 
  {
!   typename impl::Scalar_of<T>::type tmp(std::abs(t)); 
    return tmp*tmp;
  }
  
--- 110,137 ----
  inline T 
  lnot(T t) VSIP_NOTHROW { return !t;}
  
+ namespace abs_detail
+ {
+ 
+ // GreenHills <cmath> defines ::abs(float) and ::abs(double), but does
+ // not place them into the std namespace when targeting mercury (when
+ // _MC_EXEC is defined).
+ 
+ #if VSIP_IMPL_FIX_MISSING_ABS
+ using ::abs;
+ #endif
+ using std::abs;
+ } // namespace abs_detail
+ 
  template <typename T>
  inline typename impl::Scalar_of<T>::type 
! mag(T t) VSIP_NOTHROW { return abs_detail::abs(t);}
  
  template <typename T>
  inline typename impl::Scalar_of<T>::type 
  magsq(T t) VSIP_NOTHROW 
  {
!   typename impl::Scalar_of<T>::type tmp(abs_detail::abs(t)); 
    return tmp*tmp;
  }
  
Index: src/vsip/impl/general_dispatch.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/general_dispatch.hpp,v
retrieving revision 1.2
diff -c -p -r1.2 general_dispatch.hpp
*** src/vsip/impl/general_dispatch.hpp	11 Nov 2005 00:08:21 -0000	1.2
--- src/vsip/impl/general_dispatch.hpp	11 Nov 2005 13:50:41 -0000
*************** struct General_dispatch<OpTag, Return_sc
*** 177,183 ****
      if (EvalExpr::rt_valid(op1, op2))
        return EvalExpr::exec(op1, op2);
      else
!       assert(0);
    }
  };
  
--- 177,183 ----
      if (EvalExpr::rt_valid(op1, op2))
        return EvalExpr::exec(op1, op2);
      else
!       VSIP_IMPL_THROW(impl::unimplemented("General_dispatch failed"));
    }
  };
  
*************** struct General_dispatch<OpTag, DstBlock,
*** 341,347 ****
      if (EvalExpr::rt_valid(res, param1, op1, op2, param2))
        EvalExpr::exec(res, param1, op1, op2, param2);
      else
!       assert(0);
    }
  };
  
--- 341,347 ----
      if (EvalExpr::rt_valid(res, param1, op1, op2, param2))
        EvalExpr::exec(res, param1, op1, op2, param2);
      else
!       VSIP_IMPL_THROW(impl::unimplemented("General_dispatch failed"));
    }
  };
  
Index: tests/test.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/test.hpp,v
retrieving revision 1.7
diff -c -p -r1.7 test.hpp
*** tests/test.hpp	27 Sep 2005 22:44:40 -0000	1.7
--- tests/test.hpp	11 Nov 2005 13:50:41 -0000
*************** almost_equal(
*** 40,54 ****
    T	rel_epsilon = 1e-4,
    T	abs_epsilon = 1e-6)
  {
!   if (std::abs(A - B) < abs_epsilon)
      return true;
  
    T relative_error;
  
!   if (std::abs(B) > std::abs(A))
!     relative_error = std::abs((A - B) / B);
    else
!     relative_error = std::abs((B - A) / A);
  
    return (relative_error <= rel_epsilon);
  }
--- 40,54 ----
    T	rel_epsilon = 1e-4,
    T	abs_epsilon = 1e-6)
  {
!   if (vsip::mag(A - B) < abs_epsilon)
      return true;
  
    T relative_error;
  
!   if (vsip::mag(B) > vsip::mag(A))
!     relative_error = vsip::mag((A - B) / B);
    else
!     relative_error = vsip::mag((B - A) / A);
  
    return (relative_error <= rel_epsilon);
  }
*************** almost_equal(
*** 63,77 ****
    T	rel_epsilon = 1e-4,
    T	abs_epsilon = 1e-6)
  {
!   if (std::abs(A - B) < abs_epsilon)
      return true;
  
    T relative_error;
  
!   if (std::abs(B) > std::abs(A))
!     relative_error = std::abs((A - B) / B);
    else
!     relative_error = std::abs((B - A) / A);
  
    return (relative_error <= rel_epsilon);
  }
--- 63,77 ----
    T	rel_epsilon = 1e-4,
    T	abs_epsilon = 1e-6)
  {
!   if (vsip::mag(A - B) < abs_epsilon)
      return true;
  
    T relative_error;
  
!   if (vsip::mag(B) > vsip::mag(A))
!     relative_error = vsip::mag((A - B) / B);
    else
!     relative_error = vsip::mag((B - A) / A);
  
    return (relative_error <= rel_epsilon);
  }