Open timothodge opened 9 years ago
Reading from the eigen documentation: https://eigen.tuxfamily.org/dox/structEigen_1_1NumTraits.html
They explain that ReadCost, MulCost, AddCost represent a rough estimate of the number of CPU cycles needed to use move / add / mul instructions respectively, They assume the data is already stored in CPU registers. As an additional note they do not do architecture specifics, and are purposely vague.
As for Dummy_Precision, it seems to be used to make a default tolerance for the "fuzzy operators".
Moving this issue forward, how best do we check the Num_Traits for MPFR_float?
I think that this kind of testing should be done perhaps via the bertini_timing suite. We need these kinds of numbers for not only eigen stuff, but also for some of the internals of adaptive precision. namely, in papers AMP1 and AMP2, there are some numbers computed that describe how expensive multiprecision is, as a function of the bitlength. we need to compute these numbers again
right now, here's what we have in include/bertini2/eigen_extensions.hpp:
using mpfr_float = bertini::mpfr_float;
template<> struct NumTraits<mpfr_float> : GenericNumTraits<mpfr_float> // permits to get the epsilon, dummy_precision, lowest, highest functions
{
typedef mpfr_float Real;
typedef mpfr_float NonInteger;
typedef mpfr_float Nested;
enum {
IsComplex = 0,
IsInteger = 0,
IsSigned = 1,
RequireInitialization = 1, // yes, require initialization, otherwise get crashes
ReadCost = 20,
AddCost = 30,
MulCost = 40
};
inline static Real highest() {
return (mpfr_float(1) - epsilon()) * pow(mpfr_float(2),mpfr_get_emax()-1);//);//DefaultPrecision());
}
inline static Real lowest() {
return -highest();
}
inline static Real dummy_precision()
{
using bertini::DefaultPrecision;
return pow( mpfr_float(10),-int(DefaultPrecision()-3));
}
inline static Real epsilon()
{
using bertini::DefaultPrecision;
return pow(mpfr_float(10),-int(DefaultPrecision()));
}
//http://www.manpagez.com/info/mpfr/mpfr-2.3.2/mpfr_31.php
};
are these 20/30/40 appropriate? should they be higher or lower? i think we need to test in order to answer this question.
and in amp_tracker.hpp:
inline
mpfr_float ArithmeticCost(unsigned precision)
{
if (precision==DoublePrecision())
return 1;
else
return mpfr_float("10.35") + mpfr_float("0.13") * precision;
}
these values are directly from the AMP papers, not empirical measurement on the current implementations. i would love for these to be computed on a particular environment, and read in from something like config.h
, etc. and i think the appropriate place might be in bertini_timing. thoughts?
Must check the following parameters in Num_Traits for trustworthy results in MPFR_float:
ReadCost MulCost AddCost Dummy_Precision
What are these?