I have this code which compiles and runs normally, but gives bus errors or segfaults at run time when compiled with -prof -auto-all. ghc-5.04 SunOS cownose.cs.indiana.edu 5.8 Generic_108528-18 sun4u sparc SUNW,Ultra-5_10 What's wrong? import Numeric import Ratio import System top 1 = 1 top n = 9*n*top (n-2) + oddfact (n-2) lfact :: [Integer] lfact = 1 : zipWith (*) [3,5 .. ] lfact oddfact :: Integer -> Integer oddfact n = lfact!!ni where ni = nint `div` 2 nint = fromInteger n log_two :: Int -> Rational log_two lim = 2* top n % (3^lim * oddfact n) where n = fromIntegral lim log_tup :: Int -> (Rational, Rational) log_tup lim = -- TODO any chance I can drop the br? Would it get me more than a digit? (l + lo_err, l + hi_err) where l = log_two lim -- TODO double check these lo_err = (2)/(n+1)*(d/(1+c))^(lim+1) hi_err = (2)/(n+1)*d^(lim+1) -- original logs -- lo_err = (-2)/(n+1)*(d/(1+c))^(lim+1) -- hi_err = -lo_err -- lo_err = (-1)/(n+1)*x^(lim+1) -- c = 0 n = toRational lim d = 1%3 c = d log_tup_str lim = (floatlo, floathi, diff) where (lo, hi) = log_tup lim floatlo = floatRat lo lim floathi = floatRat hi lim diff = floathi - floatlo floatRat :: Rational -> Int -> Integer floatRat r lim = num*10^lim `div` den where num = numerator r den = denominator r main :: IO () main = do args <- System.getArgs let lim :: Int lim = read (args!!0) let (s1, s2, s3) = log_tup_str lim let sh1 = show s1 let l1 = length sh1 let shd = show s3 let ld = length shd putStrLn (show s1) putStrLn (show s2) putStrLn (show s3) putStr "digits: " putStrLn (show (l1-ld))
Have you removed the .o and .hi files before compiling with -prof? These are not compatible. -- Hal Daume III "Computer science is no more about computers | hdaume@isi.edu than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume On Tue, 25 Feb 2003, Damien R. Sullivan wrote:
I have this code which compiles and runs normally, but gives bus errors or segfaults at run time when compiled with -prof -auto-all. ghc-5.04 SunOS cownose.cs.indiana.edu 5.8 Generic_108528-18 sun4u sparc SUNW,Ultra-5_10
What's wrong?
import Numeric import Ratio import System
top 1 = 1 top n = 9*n*top (n-2) + oddfact (n-2)
lfact :: [Integer] lfact = 1 : zipWith (*) [3,5 .. ] lfact
oddfact :: Integer -> Integer oddfact n = lfact!!ni where ni = nint `div` 2 nint = fromInteger n
log_two :: Int -> Rational log_two lim = 2* top n % (3^lim * oddfact n) where n = fromIntegral lim
log_tup :: Int -> (Rational, Rational) log_tup lim = -- TODO any chance I can drop the br? Would it get me more than a digit? (l + lo_err, l + hi_err) where l = log_two lim -- TODO double check these lo_err = (2)/(n+1)*(d/(1+c))^(lim+1) hi_err = (2)/(n+1)*d^(lim+1) -- original logs -- lo_err = (-2)/(n+1)*(d/(1+c))^(lim+1) -- hi_err = -lo_err -- lo_err = (-1)/(n+1)*x^(lim+1) -- c = 0 n = toRational lim d = 1%3 c = d
log_tup_str lim = (floatlo, floathi, diff) where (lo, hi) = log_tup lim floatlo = floatRat lo lim floathi = floatRat hi lim diff = floathi - floatlo
floatRat :: Rational -> Int -> Integer floatRat r lim = num*10^lim `div` den where num = numerator r den = denominator r
main :: IO () main = do args <- System.getArgs let lim :: Int lim = read (args!!0) let (s1, s2, s3) = log_tup_str lim let sh1 = show s1 let l1 = length sh1 let shd = show s3 let ld = length shd putStrLn (show s1) putStrLn (show s2) putStrLn (show s3) putStr "digits: " putStrLn (show (l1-ld)) _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
On Tue, Feb 25, 2003 at 06:08:42PM -0800, Hal Daume III wrote:
Have you removed the .o and .hi files before compiling with -prof? These are not compatible.
Well, I got this code to run, although I thought I couldn't earlier from clean. But the longer code I'm really concerned with still bus errors. Compiled with profiling on a Linux box it seems to run okay, so perhaps it's a profiling-Sun interaction? import Numeric import Ratio import System -- less general; wants n to be power of 2, for faster logs -- version 2: memoing -- version 3: trying out sophisticated calculations -- TODO cache comb; try calculating H(n-1) - ln n directly; try grouping terms -- so fewer GCD calls are made; try figuring series for top and bottom -- directly so no GCD calls logtop 1 = 1 logtop n = 9*n*logtop (n-2) + oddfact (n-2) loddfact :: [Integer] loddfact = 1 : zipWith (*) [3,5 .. ] loddfact oddfact :: Integer -> Integer oddfact n = loddfact!!ni where ni = nint `div` 2 nint = fromInteger n log_two :: Int -> Rational log_two lim = 2* logtop n % (3^lim * oddfact n) where n = fromIntegral lim log_tup :: Int -> Int -> (Rational, Rational) log_tup lim b = (l + br*lo_err, l + br*hi_err) where br = toRational b l = br*log_two lim -- TODO double check these lo_err = (2)/(n+1)*(d/(1+c))^(lim+1) hi_err = (2)/(n+1)*d^(lim+1) -- original logs -- lo_err = (-2)/(n+1)*(d/(1+c))^(lim+1) -- hi_err = -lo_err -- lo_err = (-1)/(n+1)*x^(lim+1) -- c = 0 n = toRational lim d = 1%3 c = d floatRat :: Rational -> Int -> Integer floatRat r lim = num*10^lim `div` den where num = numerator r den = denominator r bernoulli :: Integer -> Rational bernoulli n = btab!!ni where ni = fromInteger n btab :: [Rational] -- TODO use zip bhelp [2..]; should be clearer, but check output -- might not work actually, With gives the function... btab = 1 : -1/2 : zipWith bhelp [2 .. ] btab bhelp n _ | odd n = 0 | otherwise = -1/fromIntegral(n+1) *sumbn n lfact :: [Integer] lfact = 1 : zipWith (*) [1 .. ] lfact fact :: Integer -> Integer fact 0 = 1 fact n = lfact!!ni where ni = fromInteger n -- 22% time spent here; improve? Probably needs smarts, not memo. Not clear -- if smarts would speed it up now, test separately -- yeah, memo worn't work; comb (n+1) i is only called once -- comb m n = comb m (n-1) * (m-n+1)/n ? Check. Guess this does call for -- memo. comb :: Integer -> Integer -> Integer comb m 0 = 1 comb m n = (numerator(toRational (fact m) / toRational (fact n * fact (m-n)))) sumbn :: Integer -> Rational sumbn n = sum [ bernoulli i * fromIntegral(comb (n+1) i) | i <- [0 .. n-1] ] harmonic :: Integer -> Rational harmonic n = harmtop n % fact n harmtop 1 = 1 harmtop n = n * harmtop (n-1) + fact (n-1) -- assuming one bound of the integral is zero, else use the abs line. Doesn't -- seem to make too much difference to accuracy. gamma_tup :: Int -> Integer -> Int -> (Rational, Rational) gamma_tup lim m b = (base - log_hi - integ_hi, base - log_lo - integ_lo) -- (base - log_hi - abs integ, base - log_lo + abs integ) where base = harmonic (n-1) - bigsum m n (log_lo, log_hi) = log_tup lim b n = 2^b -- bern of 4k is negative; bern of 4k+2 is positive; abs value of integral -- is capped by Bm/(m*n^m) integ_hi = if m `mod` 4 == 0 then 0 else integ integ_lo = if m `mod` 4 == 0 then integ else 0 integ = integral m n bigsum :: Integer -> Integer -> Rational bigsum m n = sum [(-1)^(i-1)*bernoulli i /fromInteger (i*n^i) | i <- 1:[2,4..m] ] integral :: Integer -> Integer -> Rational integral m n = bernoulli m/toRational m / toRational n^^m main :: IO () main = do args <- System.getArgs let (m, b) = (read (args!!0), read (args!!1)) let lim :: Int lim = read (args!!2) let (glo, ghi) = gamma_tup lim m b putStrLn (show glo) putStrLn (show ghi) putStrLn (show (floatRat glo lim)) putStrLn (show (floatRat ghi lim)) putStrLn (show (floatRat ghi lim - floatRat glo lim))
floatRat :: Rational -> Int -> Integer floatRat r lim = num*10^lim `div` den where num = numerator r den = denominator r
My guess is that the error is here. There's a bug in ghc where (x `div` 0) and (x `mod` 0) will results in a seg fault. For now (according to one of the Simons, this is fixed in the next version) you should do something like: floatRat r lim | den == 0 = error "division by zero" | otherwise = num * 10 ^ lim `div` den where num = numberator r den = denominator r If that doesn't fix the problem, perhaps you can try to whittle the example down to something shorter. - Hal
On Tue, Feb 25, 2003 at 09:12:23PM -0800, Hal Daume III wrote:
My guess is that the error is here. There's a bug in ghc where (x `div` 0) and (x `mod` 0) will results in a seg fault. For now (according to one of the Simons, this is fixed in the next version) you should do something
Doesn't help. I didn't expect it to -- my code shouldn't be divving by zero, and anyway the bus error happens *immediately* on startup, whereas it wouldn't call floatRat for half a minute if it were working.
If that doesn't fix the problem, perhaps you can try to whittle the example down to something shorter.
The first code I posted was my shorter attempt. At any rate, it's hard to pull stuff out of this and still have it work. And I've had versions which did compile with profiling when the version before or after wouldn't. This one doesn't, on my Sun. Does on the Linux box... -xx- Damien X-)
participants (2)
-
Damien R. Sullivan -
Hal Daume III