This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Eigen and Intel _Quad type - NumTraits definition

Tags: None
(comma "," separated)
jdohan
Registered Member
Posts
7
Karma
0
Hi,

I am trying to get Eigen to work with the _Quad quadruple precision type provided by the intel compiler. I have used the basic definition for the NumTraits file that was posted about a year ago, but it is not sufficient because of various reasons. I am not sure, which information I have to provide and where I can find it. For now, the errors suggest that I need to define an epsilon and tell Eigen which math functions it should use. I have the following NumTraits definition:

Code: Select all
#ifndef QUADSUPPORT_H
#define QUADSUPPORT_H

#include <Eigen/Core>
#include "mkl.h"
#include <math.h>

namespace Eigen {
    template<> struct NumTraits<_Quad> {
   typedef _Quad Real;
   typedef _Quad NonInteger;
   typedef _Quad Nested;

   enum {
            IsComplex = 0,
            IsInteger = 0,
            IsSigned = 1,
            RequireInitialization = 1,
            ReadCost = 2,
            AddCost = 2,
            MulCost = 2
   };
    };
}

namespace std {
    inline _Quad abs(const _Quad q) { return __fabsq(q); }
    inline _Quad sqrt(const _Quad& q) { return __sqrtq(q); }
    inline _Quad log(const _Quad& q) { return __logq(q); }
}

inline _Quad abs(const _Quad q) { return __fabsq(q); }
inline _Quad sqrt(const _Quad& q) { return __sqrtq(q); }
inline _Quad log(const _Quad& q) { return __logq(q); }

namespace _Quad {
    inline _Quad abs(const _Quad q) { return __fabsq(q); }
    inline _Quad sqrt(const _Quad& q) { return __sqrtq(q); }
    inline _Quad log(const _Quad& q) { return __logq(q); }
}


but I still get errors like the following:

Code: Select all
[...]include/Eigen/src/Core/MathFunctions.h(264): error: more than one instance of overloaded function "abs" matches the argument list:
            function "std::abs(long double)"
            function "std::abs(float)"
            function "std::abs(double)"
            function "__gnu_cxx::abs(long long)"
            function "std::abs(long)"
            function "abs(int)"
            argument types are: (const _Quad)
      return abs(x);
             ^
          detected during:
            instantiation of "Eigen::NumTraits<Scalar>::Real Eigen::internal::abs_impl<Scalar>::run(const Scalar &) [with Scalar=_Quad]" at line 277
            instantiation of "Eigen::internal::abs_retval<Eigen::internal::global_math_functions_filtering_base<Scalar, void>::type>::type Eigen::internal::abs(const Scalar &) [with Scalar=scalar={_Quad}]" at line 283 of "[...]/include/Eigen/src/Core/Functors.h"


Also, how do I go about defining an ostream for this class? I would be very grateful if you could help me out!
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Regarding NumTraits<> itself, it is documented there: http://eigen.tuxfamily.org/dox-devel/st ... raits.html

Your version is missing a few functions.

Then, your type must support standard operators (+, -, *, etc.) as well as standard functions (abs, sqrt, etc.). If Intel does not provide such functions, then you have to implement them in the same namespace than _Quad.
jdohan
Registered Member
Posts
7
Karma
0
Thanks for your answer! I have looked up the epsilon value, which is 2^ -113. I am still having trouble with the definition of the fuzzy epsilon and the highest and lowest functions. Should the last two return values of type _Quad? In the example http://eigen.tuxfamily.org/dox-devel/TopicCustomizingEigen.html I have read, these things are already taken care of.

Regarding the missing function definitions, I have not yet written all of them down, because Eigen still can't seem to find the abs function although it is defined in three different ways and I am pretty sure that there is no namespace _Quad - I just added it for trial and error. Do you have any clue why abs is not found?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
What if you try:
Code: Select all
int main() {
  _Quad x;
  abs(x);
}

and
Code: Select all
int main() {
  using std::abs;
  _Quad x;
  abs(x);
}


??

(btw, which Eigen version are you using?)
jdohan
Registered Member
Posts
7
Karma
0
Hi! For the first:

Code: Select all
quad_test.cpp(5): error: identifier "abs" is undefined
     abs(q);
     ^


and the second:

Code: Select all
quad_test.cpp(6): error: more than one instance of overloaded function "abs" matches the argument list:
            function "std::abs(long double)"
            function "std::abs(float)"
            function "std::abs(double)"
            argument types are: (_Quad)
     abs(q);
     ^


and then if I use __fabsq, it works fine. I am running 3.1.2
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
You must define:

Code: Select all
_Quad abs(const _Quad& x) { return __fabsq(x); }


and the others (e.g., sqrt) in your QuadSupport header file.
jdohan
Registered Member
Posts
7
Karma
0
That's what I did (see my first post) which is why I am surprised that it doesn't work.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Please, make sure your abs function is not in Eigen's namespace.
The following must work:

Code: Select all
_Quad abs(const _Quad& x) { return __fabsq(x); }
int main() {
  _Quad x;
  abs(x);
}
jdohan
Registered Member
Posts
7
Karma
0
Yes this does work. I am not sure if I explained myself well. In my first post, I showed you my definition of NumTraits and I defined three sample functions in three different namespaces, as was done for the adouble type. These functions are defined just like you defined them in your last post but they still can't seem to be found in the compile process.


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Sogou [Bot], Yahoo [Bot]