Re: heap profiling

2010-07-01 Thread Claus Reinke

Indeed, though I don't think this is the case, because I get lots of
lag even when no logs are written.

In the part you deleted I mentioned one source of lag that does
not disappear when no logs are written, and a way of using
profiling cost centers to track down other sources (the ones
I mentioned accounted for 2/3 of lag in the profile_logging
profile, according to -hblag -hc -L40 on SCC-annotated
source).


You mean !s on the intermediate numbers?  


No, I wrote about your 'm' parameter to 'runprof', which gets
passed all the way through the recursion tree of run_lots before
it finally gets used at the leaf level. If I recall correctly, I put one 
SCC on the log constructors and another on the actual parameter 
passed to runprof.


The comments on strictness were less about lag than about
total memory usage - unevaluated computations piling up
in logs or recursion parameters are a frequent source of out
of memory issues (from dramatic slowdown to termination).
Even for your simple test, that changes the profile (the 
graphic is scaled, but the numbers matter).



I could have sworn I tried
that but no luck.  Thanks for reminding me about manual SCC pragmas,
somehow I totally forgot you could add your own.  Just out of
curiosity, what affect could return $! 1 have?  A constant should
never be a thunk, so 'seq' on it should have no effect, right?


I was surprised by that myself. In principle, numeric constants
translate to calls to fromInteger (Haskell 98 report, 3.2), and can 
return anything with a Num instance (such as the literal '1' 
translating into an infinite list of ones), so they can't simply be 
pre-evaluated. 

But you did specify the type to be Int, so the compiler could 
have avoided the thunk (one would need to look at GHC's
output to check). Then again, we were looking at lag, not at 
heap size, and those 1s (small, but lots of them) were built 
before they are used.



Yes, you are right of course, and thank you for the help.  It's just
frustrating when every step toward simpler instead brings new problems
out of the woodwork... but I suppose with enough experience I can
begin to understand those too.  I will resume my testing when I get
some time again!


Understood. You don't have to understand everything at once,
and simplified test setups often have issues that don't occur in
the real application. But analyzing real applications needs some
intuition about what might be going on, and that is easier to
acquire in simple test setups. There, you can apply the old 
Holmes maxime of debugging: once you've excluded everything 
that can't be the problem, what is left, however unlikely or hard

to understand, has to be it (with apologies to Doyle;-).

Claus

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Space leak with unsafePerformIO

2010-07-01 Thread Simon Marlow

On 30/06/2010 18:13, Yitzchak Gale wrote:

Henning Thielemann wrote on Haskell Cafe:

Attached is a program with a space leak...
I have coded a simple 'map' function, once using unsafePerformIO and
once without. UnsafePerformIO has a space leak in some circumstances.
In the main program I demonstrate cases with and without space leak.
Without space leak the program writes a file to the disk until it
is full.


Bertram Felgenhauer wrote:

The program relies on the GC doing short-cut evaluation of record
selectors to avoid a space leak...
Use of suffix: Due to the call of  Main.go1  this is *not* a record
selector. It is compiled to an actual case expression, which to the
garbage collector looks just like an ordinary thunk. A reference to
Main.ds is kept around until the suffix is about to be processed
and a memory leak ensues.
The good news is that the problem is completely unrelated to
unsafePerformIO (the presence of unsafePerformIO makes optimisations
more difficult, but any pure function of sufficient complexity would
have the same effect).


Is there already a GHC Trac bug for this?


This is it:

http://hackage.haskell.org/trac/ghc/ticket/2607


Link to Bertram's original email, with detailed analysis of the
GHC Core:

http://www.haskell.org/pipermail/haskell-cafe/2010-June/079479.html


Added to the ticket, thanks.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Help with Win64 port

2010-07-01 Thread Simon Marlow

On 30/06/2010 22:15, George Brewster wrote:

Hey,
I'd really like to see ghc working on 64-bit Windows, so I've decided to
take at least a quick stab at getting it going.
Having talked to some of the people on #ghc, it sounds like the first
thing to do is get an unregisterised build going, which sounded like it
may be managable. So to that end, I've pulled the 6.12 branch, done a
32-bit build, changed the build config to do an unregisterised build and
turn off the native code generator, found a version of mingw64 which
seems to work for me, stuffed it in in place of the in-tree mingw, and
got my build to fail.

At this point, I'd like to get a general idea of what my strategy should
be. I read the Building/Porting page on the wiki, and used the config
file there as an example of how to do an unregisterised build, but have
been ignoring anything related to the hc file bootstrapping process, as
I have a working ghc on my platform, just of the wrong bitness.

In particular, if there are any changes that you know I'll need to make
to the source to get this working, please let me know. The more of those
I learn about now, the less fumbling around I'll have to do as things
break. In particular, is there some place where I indicate that I'm
build a 64-bit compiler? I didn't find anything with a quick look.

I have very little time to work on it, and no familiarity with ghc
internals, so I wouldn't expect much, but I'm hoping I can get it going...


We'd like to support cross-compilation for this kind of scenario, but it 
isn't working right now.  I just created this ticket and wiki page:


  http://hackage.haskell.org/trac/ghc/ticket/4163

HC bootstrapping in theory works, but is suffering from bitrot at the 
moment, see


  http://hackage.haskell.org/trac/ghc/ticket/3472

a lot of manual intervention is required to bootstrap right now.

The way forward is to get cross-compilation working, if you'd like to 
help us out that would be great.


Cheers,
Simon
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: [Haskell-cafe] checking types with type families

2010-07-01 Thread Simon Peyton-Jones
|  Here's a concrete case I recently ran into:
|  
|  type family SomeOtherTypeFamily a
|  class SomeClass a where type SomeType a
|  instance a ~ SomeOtherTypeFamily b = SomeClass a where 
|type SomeType a = (b,Int)  
|--  (error) Not in scope: type variable `b'
|  
|  The same thing with fundeps:
|  
|  class SomeClass a b | a - b
|  instance a ~ SomeOtherTypeFamily b = SomeClass a (b,Int) 
|  -- works fine

It's not the same thing at all!  The code you give certainly should fail.

Suppose you use fundeps thus:
   class C a b | a-b where
 op :: a - b - b

The idiomatic way to replace this with type functions is to remove the 'b' 
parameter, thus:
   class C a where
 type B a 
 op :: a - B a - B a

Sometimes you don't want to do this.  For example, you might have a 
bidirectional fundep.  Then you can (or rather will be able to) use a 
superclass thus:
   class (B a ~ b) = C a b where
  type B a

The superclass says that you can only instantiate this class with a second 
argument b that is equal to (B a).  Thus you might have an instance
   instance C Int Bool where
 type B Int = Bool

Meanwhile we are working hard on the new type inference engine, which will 
allow superclass equalities like these.

Simon
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: BlockedIndefinitelyOnMVar exception

2010-07-01 Thread Neil Mitchell
Hi Simon,

Thanks for the excellent information. I've now debugged my problem,
and think I've got the last of the MVar blocking problems out.

 * How confident are people that this exception does really mean that
 it is in a blocked state? Is there any chance the error could be
 raised incorrectly?

 There have been one or two bugs in the past that could lead to this
 exception being raised incorrectly, but I'm not aware of any right now.
  It's not inconceivable of course.

I have no reason to think it's broken. I found at least 3 separate
concurrency bugs in various parts (one added the day before, one over
a year old, one of which had been introduced while trying to work
around the MVar problem).

My suspicion for the root cause of the problem is that Concurrent.Chan
is incorrect. In the course of debugging this problem we found 2 bugs
in Chan, and while I never tracked down any other bugs in Chan, I no
longer trust it. By rewriting parts of the program, including avoiding
Chan, the bugs disappeared.I don't think I'll be using Chan again
until after someone has proven in correct.

 * Any debugging tips for this problem?

 I'd use the event log: compile with -debug, run with +RTS -Ds -l, and dump
 the event log with show-ghc-events (cabal install ghc-events).  Or just dump
 it to stderr with +RTS -Ds, if the log isn't too large.  Use
 GHC.Exts.traceEvent to add your own events to the trace.

The event log is fantastic!

Thanks, Neil
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users