Changeset 2962

Show
Ignore:
Timestamp:
06/06/08 19:09:43 (3 months ago)
Author:
pernet
Message:

* Upgrade to fflas-ffpack v 1.3.3
* rename all the modular-balance into modular-balanced
* fix the few remaining compilation warning with gcc-4.3

Location:
trunk/linbox
Files:
4 removed
18 modified

Legend:

Unmodified
Added
Removed
  • trunk/linbox/linbox/fflas/fflas.h

    r2898 r2962  
    2424#include "linbox/config-blas.h" 
    2525#include "linbox/field/unparametric.h" 
    26  
     26#include "linbox/field/modular-double.h" 
     27#include "linbox/field/modular-float.h" 
     28#include "linbox/field/modular-balanced-double.h" 
     29#include "linbox/field/modular-balanced-float.h" 
    2730namespace LinBox { 
    2831#else 
    2932#include "config-blas.h" 
    30 #include "unparametric.h" 
     33#include "fflas-ffpack/unparametric.h" 
     34#include "fflas-ffpack/modular-positive.h" 
     35#include "fflas-ffpack/modular-balanced.h" 
    3136#endif 
    3237         
     
    5863         * FflasDouble: to use the double precision BLAS 
    5964         * FflasFloat: to use the single precison BLAS 
    60          * FflasFloat: for any other domain, that can not be converted to floating point integers 
     65         * FflasGeneric: for any other domain, that can not be converted to floating point integers 
    6166         */ 
    6267        enum FFLAS_BASE      { FflasDouble = 151, FflasFloat = 152, FflasGeneric = 153}; 
     
    238243 
    239244                if (!(m && n && k)) return C; 
    240                  
    241                 FFLAS_BASE base = BaseCompute<typename Field::Element> ()(F, w); 
    242                 size_t d = DotProdBound (F, w, beta, base); 
    243                 //std::cerr<<"d = "<<d<<std::endl; 
     245 
     246                if (F.isZero (alpha)){ 
     247                        for (size_t i = 0; i<m; ++i) 
     248                                fscal(F, n, beta, C + i*ldc, 1); 
     249                        return C; 
     250                } 
     251                 
     252                size_t kmax = 0; 
     253                size_t winolevel = w; 
     254                FFLAS_BASE base; 
     255                MatMulParameters (F, MIN(MIN(m,n),k), beta, kmax, base, 
     256                                  winolevel, true); 
    244257                WinoMain (F, ta, tb, m, n, k, alpha, A, lda, B, ldb, beta, 
    245                                  C, ldc, d, w, base); 
     258                                 C, ldc, kmax, winolevel, base); 
    246259                return C; 
    247260                }; 
     
    262275               const size_t k, 
    263276               const typename Field::Element alpha, 
    264                const typename Field::Element* A,  
    265                const size_t lda, 
    266                const typename Field::Element* B, 
    267                const size_t ldb,  
     277               const typename Field::Element* A, const size_t lda, 
     278               const typename Field::Element* B, const size_t ldb,  
    268279               const typename Field::Element beta, 
    269                typename Field::Element* C,  
    270                const size_t ldc){ 
     280               typename Field::Element* C, const size_t ldc){ 
    271281 
    272282                if (!(m && n && k)) return C; 
    273  
    274                 size_t w, kmax=0; 
     283                if (F.isZero (alpha)){ 
     284                        for (size_t i = 0; i<m; ++i) 
     285                                fscal(F, n, beta, C + i*ldc, 1); 
     286                        return C; 
     287                } 
     288                 
     289                size_t w, kmax; 
    275290                FFLAS_BASE base; 
    276291 
    277                 setMatMulParam<typename Field::Element> ()(F, MIN(MIN(m,n),k), beta, 
    278                                                            w, base, kmax); 
     292                MatMulParameters (F, MIN(MIN(m,n),k), beta, kmax, base, w); 
    279293 
    280294                WinoMain (F, ta, tb, m, n, k, alpha, A, lda, B, ldb, beta, 
     
    447461        } 
    448462 
    449         /** @brief Bound for the delayed modulus matrix multiplication 
    450          * 
    451          *  @param F  - the finite field 
    452          *  @param w  - the number of recursive levels of Winograds algorithm being used 
    453          *  @param beta - for the computation of C <- AB + beta C 
    454          * 
    455          *  Compute the maximal dimension k, such that a matrix multiplication (m,k)x(k,n) 
    456          *  can be performed over Z without overflow of the 53 bits of the double 
    457          *  mantissa. 
    458          *  See [Dumas, Gautier, Pernet ISSAC'2002] 
     463        /** 
     464         * MatMulParameters 
     465         * 
     466         * \brief Computes the threshold parameters for the cascade 
     467         *        Matmul algorithm 
     468         * 
     469         *  
     470         * \param F Finite Field/Ring of the computation. 
     471         * \param k Common dimension of A and B, in the product A x B 
     472         * \param bet Computing AB + beta C 
     473         * \param delayedDim Returns the size of blocks that can be multiplied 
     474         *                   over Z with no overflow 
     475         * \param base Returns the type of BLAS representation to use 
     476         * \param winoRecLevel Returns the number of recursion levels of 
     477         *                     Strassen-Winograd's algorithm to perform 
     478         * \param winoLevelProvided tells whether the user forced the number of 
     479         *                          recursive level of Winograd's algorithm 
     480         * 
     481         * See [Dumas, Giorgi, Pernet, arXiv cs/0601133] 
     482         * http://arxiv.org/abs/cs.SC/0601133 
    459483         */ 
    460484        template <class Field> 
    461         static size_t DotProdBound (const Field& F, const size_t w, 
    462                                     const typename Field::Element& beta, 
    463                                     const FFLAS_BASE base); 
    464  
     485        static void MatMulParameters (const Field& F, 
     486                                      const size_t k, 
     487                                      const typename Field::Element& beta, 
     488                                      size_t& delayedDim, 
     489                                      FFLAS_BASE& base, 
     490                                      size_t& winoRecLevel, 
     491                                      bool winoLevelProvided=false); 
     492 
     493         
     494        /** 
     495         * DotprodBound 
     496         * 
     497         * \brief  computes the maximal size for delaying the modular reduction 
     498         *         in a dotproduct 
     499         * 
     500         * This is the default version assuming a conversion to a positive modular representation 
     501         *  
     502         * \param F Finite Field/Ring of the computation 
     503         * \param winoRecLevel Number of recusrive Strassen-Winograd levels (if any, 0 otherwise) 
     504         * \param beta Computing AB + beta C 
     505         * \param base Type of floating point representation for delayed modular computations 
     506         *  
     507         */ 
    465508        template <class Field> 
    466         static size_t DotProdBoundCompute (const Field& F, const size_t w, 
    467                                            const typename Field::Element& beta, 
    468                                            const FFLAS_BASE base); 
    469          
    470  
     509        static size_t DotProdBound (const Field& F, 
     510                             const size_t w,  
     511                             const typename Field::Element& beta, 
     512                             const FFLAS_BASE base); 
     513         
     514 
     515        /** 
     516         * Internal function for the bound computation 
     517         * Generic implementation for positive representations 
     518         */ 
     519        template <class Field> 
     520        static double computeFactor (const Field& F, const size_t w); 
     521         
     522 
     523        /** 
     524         * Winosteps 
     525         * 
     526         * \brief Computes the number of recursive levels to perform 
     527         * 
     528         * \param m the common dimension in the product AxB 
     529         */ 
    471530        static size_t WinoSteps (const size_t m); 
    472531         
    473         //      template <class Element> 
    474 //      class callDotProdBoundCompute; 
    475  
    476         /** @brief Bound for the delayed modulus triangular system solving 
    477          * 
    478          *  @param F  - the finite field 
     532        /** 
     533         * BaseCompute 
     534         * 
     535         * \brief Determines the type of floating point representation to convert to, 
     536         *        for BLAS computations 
     537         * \param F Finite Field/Ring of the computation 
     538         * \param w Number of recursive levels in Winograd's algorithm 
     539         */ 
     540        template <class Field> 
     541        static FFLAS_BASE BaseCompute (const Field& F, const size_t w); 
     542                 
     543        /** 
     544         * TRSMBound 
     545         * 
     546         * \brief  computes the maximal size for delaying the modular reduction 
     547         *         in a triangular system resolution 
    479548         * 
    480549         *  Compute the maximal dimension k, such that a unit diagonal triangular 
    481550         *  system of dimension k can be solved over Z without overflow of the 
    482          *  53 bits of the double mantissa. 
    483          *  See [Dumas, Giorgi, Pernet ISSAC'2004] 
     551         *  underlying floating point representation. 
     552         *  See [Dumas, Giorgi, Pernet 06, arXiv:cs/0601133 ] 
     553         *  
     554         * \param F Finite Field/Ring of the computation 
     555         *  
    484556         */ 
    485557        template <class Field> 
    486558        static size_t TRSMBound (const Field& F); 
    487  
    488         template <class Element> 
    489         class callTRSMBound; 
    490  
    491         /** @brief Set the optimal parameters for the Matrix Multiplication 
    492          */ 
    493         template <class Element> 
    494         class setMatMulParam; 
    495  
    496         template <class Element> 
    497         class BaseCompute; 
    498559 
    499560        template <class Field> 
     
    557618                              const size_t kmax, const size_t w, const FFLAS_BASE base); 
    558619 
    559  
    560         template<class Element> 
    561         class callWinoMain; 
    562  
    563         template<class Element> 
    564         class callClassicMatmul; 
    565  
    566         template<class Element> 
    567         class callFsquare; 
    568  
    569         template<class Element> 
    570         class callMatVectProd; 
    571                  
    572620        // Specialized routines for ftrsm 
    573621        template <class Element> 
  • trunk/linbox/linbox/fflas/fflas_bounds.inl

    </
    r2954 r2962  
    22 
    33/* fflas/fflas_bounds.inl 
    4  * Copyright (C) 2007 Clement Pernet 
     4 * Copyright (C) 2008 Clement Pernet 
    55 * 
    66 * Written by Clement Pernet <Clement.Pernet@imag.fr> 
     
    1515#endif 
    1616 
    17 /* From M Abshoff */ 
    18 #if defined(__sun)  
    19 #define lround(x) my_lround(x) 
    20 static long my_lround(double x) 
    21 { 
    22        return (long) ((x) >= 0 ? (x) + 0.5 : (x) - 0.5); 
    23 } 
    24 #endif 
    25  
    26 //--------------------------------------------------------------------- 
    27 // DotProdBound : 
    28 // Computes the maximal dimension k so that the product A*B+beta.C over Z, 
    29 // where A is m*k and B is k*n can be performed correctly with w Winograd 
    30 // recursion levels on the number of bits of the floating point mantissa 
    31 //--------------------------------------------------------------------- 
    32 template  <class Field>  
    33 inline size_t FFLAS::DotProdBoundCompute (const Field& F, const size_t w,  
    34                                           const typename Field::Element& beta, 
    35                                           const FFLAS_BASE base){ 
     17/** 
     18 * MatMulParameters 
     19 * 
     20 * \brief Computes the threshold parameters for the cascade 
     21 *        Matmul algorithm 
     22 * 
     23 *  
     24 * \param F Finite Field/Ring of the computation. 
     25 * \param k Common dimension of A and B, in the product A x B 
     26 * \param bet Computing AB + beta C 
     27 * \param delayedDim Returns the size of blocks that can be multiplied 
     28 *                   over Z with no overflow 
     29 * \param base Returns the type of BLAS representation to use 
     30 * \param winoRecLevel Returns the number of recursion levels of 
     31 *                     Strassen-Winograd's algorithm to perform 
     32 * \param winoLevelProvided tells whether the user forced the number of 
     33 *                          recursive level of Winograd's algorithm 
     34 */ 
     35template <class Field> 
     36inline void FFLAS::MatMulParameters (const Field& F, 
     37                                     const size_t k, 
     38                                     const typename Field::Element& beta, 
     39                                     size_t& delayedDim, 
     40                                     FFLAS_BASE& base, 
     41                                     size_t& winoRecLevel, 
     42                                     bool winoLevelProvided) { 
     43 
     44        // Strategy : determine Winograd's recursion first, then choose appropriate 
     45        // floating point representation, and finally the blocking dimension. 
     46        // Can be improved for some cases. 
     47 
     48        if (!winoLevelProvided) 
     49                winoRecLevel = WinoSteps (k); 
     50        base = BaseCompute (F, winoRecLevel); 
     51        delayedDim = DotProdBound (F, winoRecLevel, beta, base); 
     52 
     53        size_t n = k; 
     54        size_t winoDel = winoRecLevel; 
     55 
     56        // Computes the delayedDim, only depending on the recursive levels 
     57        // that must be performed over Z 
     58        while (winoDel > 0 && delayedDim < n) { 
     59                winoDel--; 
     60                delayedDim = DotProdBound (F, winoDel, beta, base); 
     61                n >>= 1; 
     62        } 
     63        delayedDim = MIN (n, delayedDim); 
     64} 
     65 
     66/** 
     67 * DotProdBound 
     68 * 
     69 * \brief  computes the maximal size for delaying the modular reduction 
     70 *         in a dotproduct 
     71 * 
     72 * This is the default version assuming a conversion to a positive modular representation 
     73 *  
     74 * \param F Finite Field/Ring of the computation 
     75 * \param winoRecLevel Number of recusrive Strassen-Winograd levels (if any, 0 otherwise) 
     76 * \param beta Computing AB + beta C 
     77 * \param base Type of floating point representation for delayed modular computations 
     78 *  
     79 */ 
     80template <class Field> 
     81inline size_t FFLAS::DotProdBound (const Field& F, 
     82                                   const size_t w,  
     83                                   const typename Field::Element& beta, 
     84                                   const FFLAS_BASE base) { 
    3685         
     86        FFLAS_INT_TYPE p; 
     87        F.characteristic(p); 
    3788        typename Field::Element mone; 
    38         static FFLAS_INT_TYPE p; 
     89        F.init (mone, -1.0); 
     90 
     91        unsigned long mantissa = 
     92                (base == FflasDouble) ? DOUBLE_MANTISSA : FLOAT_MANTISSA; 
     93 
     94        if (p == 0) 
     95                return 1; 
     96         
     97        double kmax; 
     98        if (w > 0) { 
     99                double c = computeFactor (F,w); 
     100                double d = (double (1ULL << mantissa) /(c*c) + 1); 
     101                if (d < 2) 
     102                        return 1; 
     103                kmax = floor (d * (1ULL << w)); 
     104        } else { 
     105                ////// A fixer: (p-1)/2 si balanced 
     106 
     107                double c = p-1; 
     108                double cplt=0; 
     109                if (!F.isZero (beta)){ 
     110                        if (F.isOne (beta) || F.areEqual (beta, mone)) cplt = c; 
     111                        else cplt = c*c; 
     112                } 
     113                kmax = floor ( (double ((1ULL << mantissa) - cplt)) / (c*c)); 
     114                if (kmax  <= 1) 
     115                        return 1; 
     116                } 
     117        //kmax--; // we computed a strict upper bound 
     118        return  (size_t) MIN (kmax, 1ULL << 31); 
     119} 
     120 
     121/** 
     122 * Internal function for the bound computation 
     123 * Generic implementation for positive representations 
     124 */ 
     125template <class Field> 
     126inline double FFLAS::computeFactor (const Field& F, const size_t w){ 
     127        FFLAS_INT_TYPE p; 
    39128        F.characteristic(p); 
    40         F.init (mone, -1.0); 
    41         size_t kmax; 
    42  
    43         unsigned long mantissa = (base == FflasDouble)? DOUBLE_MANTISSA : FLOAT_MANTISSA; 
     129        size_t ex=1; 
     130        for (size_t i=0; i < w; ++i)    ex *= 3; 
     131        return double(p - 1) * (1 + ex) / 2; 
     132} 
     133 
     134/** 
     135 * WinoSteps 
     136 * 
     137 * \brief Computes the number of recursive levels to perform 
     138 * 
     139 * \param m the common dimension in the product AxB 
     140 *  
     141 */ 
     142inline size_t FFLAS::WinoSteps (const size_t m) { 
     143        size_t w = 0; 
     144        size_t mt = m; 
     145        while (mt >= WINOTHRESHOLD) {w++; mt >>= 1;} 
     146        return w; 
     147} 
     148 
     149/** 
     150 * BaseCompute 
     151 * 
     152 * \brief Determines the type of floating point representation to convert to, 
     153 *        for BLAS computations 
     154 * \param F Finite Field/Ring of the computation 
     155 * \param w Number of recursive levels in Winograd's algorithm 
     156 *  
     157 */ 
     158template <class Field> 
     159inline FFLAS::FFLAS_BASE FFLAS::BaseCompute (const Field& F, const size_t w){ 
    44160         
    45         if (p == 0) 
    46                 kmax = 2; 
    47         else 
    48                 if (w > 0) { 
    49                         size_t ex=1; 
    50                         for (size_t i=0; i < w; ++i)    ex *= 3; 
    51                         //FFLAS_INT_TYPE c = (p-1)*(ex)/2; //bound for a centered representation 
    52                         FFLAS_INT_TYPE c; 
    53 #ifndef _LINBOX_LINBOX_CONFIG_H 
    54                         if (F.balanced) 
    55                                 c = (p-1)*(ex)/2; // balanced representation 
    56                         else 
    57 #endif 
    58                                 c = (p-1)*(1+ex)/2; 
    59                         kmax =  lround(( double(1ULL << mantissa) /double(c*c) + 1)*(1ULL << w)); 
    60                         if (kmax ==  ( 1ULL << w)) 
    61                                 kmax = 2; 
    62                 } 
    63                 else{ 
    64                         FFLAS_INT_TYPE c = p-1; 
    65                         FFLAS_INT_TYPE cplt=0; 
    66                         if (!F.isZero (beta)) { 
    67                                 if (F.isOne (beta) || F.areEqual (beta, mone)) 
    68                                         cplt = c; 
    69                                 else cplt = c*c; 
    70                         } 
    71                         kmax =  lround(( double((1ULL << mantissa) - cplt)) /double(c*c)); 
    72                         if (kmax  < 2) 
    73                                 kmax = 2; 
    74                 } 
    75         //cerr<<"kmax = "<<kmax<<endl; 
    76         return  (size_t) MIN(kmax,1ULL<<31); 
    77 } 
    78  
    79  
    80  
    81 template  < class Field >  
    82 inline size_t FFLAS::DotProdBound (const Field& F, const size_t w,  
    83                                    const typename Field::Element& beta, 
    84                                    const FFLAS_BASE base) 
    85 { 
    86         static Field G = F; 
    87         static FFLAS_INT_TYPE pig; 
    88         G.characteristic(pig); 
    89         FFLAS_INT_TYPE pif; 
    90         F.characteristic(pif); 
    91         static typename Field::Element b = beta; 
    92         static size_t w2 = w; 
    93         static FFLAS_BASE base2 = base; 
    94         static size_t kmax = DotProdBoundCompute (F, w, beta, base); 
    95         if ((b != beta) || (pif != pig) ||  (w2 != w) || (base2!=base)) { 
    96                 G = F; 
    97                 w2 = w; 
    98                 b = beta; 
    99                 base2 = base; 
    100                 kmax =  DotProdBoundCompute (F, w, beta, base); 
    101         }        
    102         return kmax; 
    103 } 
    104  
    105 //--------------------------------------------------------------------- 
    106 // TRSMBound 
    107 // Computes nmax s.t. (p-1)/2*(p^{nmax-1} + (p-2)^{nmax-1}) < 2^53 
    108 //--------------------------------------------------------------------- 
    109 inline size_t bound_compute_double(const FFLAS_INT_TYPE pi) { 
    110          
    111         FFLAS_INT_TYPE p=pi,p1=1,p2=1; 
    112         size_t nmax = 1; 
    113         FFLAS_INT_TYPE max = ( FFLAS_INT_TYPE(  1ULL<<(DOUBLE_MANTISSA+1) )/(p-1)); 
     161        FFLAS_INT_TYPE pi; 
     162        F.characteristic(pi); 
     163        FFLAS_BASE base; 
     164        switch (w) { 
     165        case 0: base = (pi < FLOAT_DOUBLE_THRESHOLD_0)? FflasFloat : FflasDouble; 
     166                break; 
     167        case 1:  base = (pi < FLOAT_DOUBLE_THRESHOLD_1)? FflasFloat : FflasDouble; 
     168                break; 
     169        case 2:  base = (pi < FLOAT_DOUBLE_THRESHOLD_2)? FflasFloat : FflasDouble; 
     170                break; 
     171        default: base = FflasDouble; 
     172                break; 
     173        } 
     174        return base; 
     175} 
     176 
     177 
     178/************************************************************************************* 
     179 * Specializations for ModularPositive and ModularBalanced over double and float 
     180 *************************************************************************************/ 
     181 
     182template <class Element> 
     183inline double computeFactor (const ModularBalanced<Element>& F, const size_t w){ 
     184        FFLAS_INT_TYPE p; 
     185        F.characteristic(p); 
     186        size_t ex=1; 
     187        for (size_t i=0; i < w; ++i)    ex *= 3; 
     188        return  (p - 1) * ex / 2;  
     189} 
     190 
     191template <> 
     192inline FFLAS::FFLAS_BASE FFLAS::BaseCompute (const Modular<double>& F, 
     193                                             const size_t w){ 
     194        return FflasDouble; 
     195} 
     196 
     197template <> 
     198inline FFLAS::FFLAS_BASE FFLAS::BaseCompute (const Modular<float>& F, 
     199                                             const size_t w){ 
     200        return FflasFloat; 
     201} 
     202 
     203template <> 
     204inline FFLAS::FFLAS_BASE FFLAS::BaseCompute (const ModularBalanced<double>& F, 
     205                                             const size_t w){ 
     206        return FflasDouble; 
     207} 
     208 
     209template <> 
     210inline FFLAS::FFLAS_BASE FFLAS::BaseCompute (const ModularBalanced<float>& F, 
     211                                             const size_t w){ 
     212        return FflasFloat; 
     213} 
     214 
     215/** 
     216 * TRSMBound 
     217 * 
     218 * \brief  computes the maximal size for delaying the modular reduction 
     219 *         in a triangular system resolution 
     220 * 
     221 * This is the default version over an arbitrary field. 
     222 * It is currently never used (the recursive algorithm is run until n=1 in this case) 
     223 *  
     224 * \param F Finite Field/Ring of the computation 
     225 *  
     226 */ 
     227template <class Field> 
     228inline size_t FFLAS::TRSMBound (const Field& F) { 
     229        return 1;        
     230} 
     231 
     232/** 
     233 * Specialization for positive modular representation over double 
     234 * Computes nmax s.t. (p-1)/2*(p^{nmax-1} + (p-2)^{nmax-1}) < 2^53 
     235 * See [Dumas Giorgi Pernet 06, arXiv:cs/0601133] 
     236 */ 
     237template<> 
     238inline size_t FFLAS::TRSMBound (const Modular<double>& F){ 
     239 
     240        FFLAS_INT_TYPE pi; 
     241        F.characteristic(pi); 
     242        unsigned long long p = pi, p1 = 1, p2 = 1; 
     243        size_t nmax = 0; 
     244        unsigned long long max = ( (1ULL << (DOUBLE_MANTISSA + 1) ) / (p - 1)); 
    114245        while ( (p1 + p2) < max ){ 
    115246                p1*=p; 
     
    117248                nmax++; 
    118249        } 
    119         nmax--; 
    120250        return nmax; 
    121251} 
    122 inline size_t bound_compute_double_balanced(const FFLAS_INT_TYPE pi) { 
    123          
    124         FFLAS_INT_TYPE p=(pi+1)/2,p1=1; 
    125         size_t nmax=0; 
    126         FFLAS_INT_TYPE max = ( FFLAS_INT_TYPE(  1ULL<<(DOUBLE_MANTISSA))/(p-1)); 
    127         while ( (p1) < max ){ 
    128                 p1*=p; 
    129                 nmax++; 
    130         } 
    131         return nmax; 
    132 } 
    133 inline size_t bound_compute_float(const FFLAS_INT_TYPE pi) { 
    134          
    135         FFLAS_INT_TYPE p=pi,p1=1,p2=1; 
    136         size_t nmax=1; 
    137         FFLAS_INT_TYPE max = (FFLAS_INT_TYPE(   1ULL<<(FLOAT_MANTISSA+1) )/(p-1)); 
     252 
     253 
     254/** 
     255 * Specialization for positive modular representation over float 
     256 * Computes nmax s.t. (p-1)/2*(p^{nmax-1} + (p-2)^{nmax-1}) < 2^24 
     257 * See [Dumas Giorgi Pernet 06, arXiv:cs/0601133] 
     258 */ 
     259template<> 
     260inline size_t FFLAS::TRSMBound (const Modular<float>& F){ 
     261 
     262        FFLAS_INT_TYPE pi; 
     263        F.characteristic(pi); 
     264        unsigned long long p = pi, p1 = 1, p2 = 1; 
     265        size_t nmax = 0; 
     266        unsigned long long max = ( (1ULL << (FLOAT_MANTISSA + 1) ) / (p - 1)); 
    138267        while ( (p1 + p2) < max ){ 
    139268                p1*=p; 
     
    141270                nmax++; 
    142271        } 
    143         nmax--; 
    144272        return nmax; 
    145273} 
    146 inline size_t bound_compute_float_balanced(const FFLAS_INT_TYPE pi) { 
    147