oprecomp / FloatX

Header-only C++ library for low precision floating point type emulation.
Apache License 2.0
163 stars 26 forks source link

Conversion Ambiguous #3

Closed norabarlow closed 3 years ago

norabarlow commented 3 years ago

Hello! I am trying to integrate FloatX into the Eigen library. One particular portion (Eigen::HouseholderQR matrix) is giving me some trouble. In particular, I'm getting the following error, which I think is the key to figuring out this compilation error:

error: conversion from 'long int' to 'const flx::floatx<8,23>' is ambiguous

Do you have an idea of how to address this? Thanks!

Here is a simple example:

#include <iostream>
#include <Eigen/Eigen>

#include "floatx.hpp"

using fx = flx::floatx<8,23>;

// support for eigen library
namespace Eigen {
    template<int E, int M>
    struct NumTraits<flx::floatx<E,M>> : NumTraits<double>
    {
        typedef flx::floatx<E,M> Real;
        typedef flx::floatx<E,M> NonInteger;
        typedef flx::floatx<E,M> Nested;

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

int main() {
    Eigen::Matrix<fx,3,3> m;
    m << fx(1), fx(2), fx(3),
         fx(4), fx(5), fx(6),
         fx(7), fx(8), fx(9);

    Eigen::Matrix<fx,3,1> v;
    v << fx(1), fx(2), fx(3);

    Eigen::Matrix<fx,3,1> m2 = m * v;
    Eigen::HouseholderQR<Eigen::Matrix<fx,Eigen::Dynamic,Eigen::Dynamic>> qr(m);
    Eigen::Matrix<fx,Eigen::Dynamic,Eigen::Dynamic> Q = qr.householderQ();

    std::cout << m << std::endl;
    std::cout << m2 << std::endl;
    std::cout << Q << std::endl;
}

I also had to make the following adjustments to floatx.hpp in the floatx class:

 177 //    template <typename T>
 178 //    FLOATX_ATTRIBUTES floatx(const T& other) noexcept
 179 //        : detail::floatx_base<floatx>(backend_float(other))
 180 //    {
 181 //        this->initialize();
 182 //    }
 183 
 184     template <int E, int M>
 185     FLOATX_ATTRIBUTES floatx(const floatx<E,M>& other) noexcept
 186         : detail::floatx_base<floatx>(backend_float(other))
 187     {
 188         this->initialize();
 189     }
 190 
 191     FLOATX_ATTRIBUTES floatx(const float other) noexcept
 192         : detail::floatx_base<floatx>(backend_float(other))
 193     {
 194         this->initialize();
 195     }
 196 
 197     FLOATX_ATTRIBUTES floatx(const int other) noexcept
 198         : detail::floatx_base<floatx>(backend_float(other))
 199     {
 200         this->initialize();
 201     }
 202 
 203     FLOATX_ATTRIBUTES floatx(const double other) noexcept
 204         : detail::floatx_base<floatx>(backend_float(other))
 205     {
 206         this->initialize();
 207     }
norabarlow commented 3 years ago

Solved by adding another explicit constructor:

FLOATX_ATTRIBUTES floatx(const Eigen::Index other) noexcept
    : detail::floatx_base<floatx>(backend_float(other))
{
    this->initialize();
}