Re: profiling for stack usage

2003-08-15 Thread Alastair Reid

> I'm currently in a situation where my program runs easily out of
> stack.  Depending on the input, stack usage often exceeds 10Mb.

I have better than 75% success locating the source of these bugs with the 
following command:

  grep '+1' *.hs *.lhs

Reason: Lazy arithmetic can easily cause you to build thunks that look like 
this:

   1+1+1+1+  + 1 + 0

which take O(n) heap to store and O(n) stack to evaluate (with constant 
factors of around 10-20).

If you've already tried this approach, the tolols SimonM mentions are well 
worth using.

--
Alastair Reid

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: profiling for stack usage

2003-08-15 Thread Simon Marlow
 
> I'm currently in a situation where my program runs easily out of
> stack.  Depending on the input, stack usage often exceeds 10Mb.
> 
> 1. Is there a way to profile stack usage, so that I can identify the
> culprit and deal with the problem at the root?  Normal (time)
> profiling tells me how many times a function is called, but it would
> be interesting to know how many times it was recursively called, or
> the size of its stack frames.  Is that information available?
> 
> Heap profiling -- well, it doesn't *sound* as if it would incorporate
> the stack; does it anyway?

See:

  
http://www.haskell.org/ghc/docs/latest/html/users_guide/prof-heap.html#RTS-OPTIONS-HEAP-PROF+RTS

in particular, the -xt flag.

> 2. Is there a way to compile programs to use more than the default
> stack?  I can of course pass +RTS -K10M -RTS on the command line, but
> I would rather like to change the default, instead of kicking myself
> for forgetting it all the time.  And is there any reason (except
> excessive resource consumption and postponed failure from infinite
> loops) not to run with huge stacks? 

See:

  
http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#RTS-HOOKS

Cheers,
Simon "the only reason I write docs is so I can say RTFM" Marlow

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


a library for reifying values in GHC

2003-08-15 Thread Bernard James POPE
Hi all,

During my work on buddha (haskell debugger) I've had the need
to print arbitrary values from a running program.

Along the way I've written some code that works with GHC
to do this.

Just in case there are others who might benefit from this,
I've ripped some code out of buddha and made it into somewhat of
a library.

You can download it from here:

   http://www.cs.mu.oz.au/~bjpop/code.html

The main parts are:

   reify :: a -> IO Graph
   data Graph = ...
   prettyGraph :: Graph -> String 

The graph type is an ordinary data type:

   type Unique = Int   -- a unique label for each node
   type Tag = Int  -- what kind of node it is
   type NumKids = Int  -- how many children it has

   data Graph
  = AppNode Unique String Tag NumKids [Graph]  
  | CharNode Char
  | IntNode Int
  | IntegerNode Integer
  | FloatNode Float
  | DoubleNode Double
  | NullNode
  deriving Show

The main features are:

   - it is conservative wrt to evaluation (lazy). It does not
 make its argument evaluate any further,
   - it detects cycles in the heap representation and makes them
 visible in the Graph representation (though the current
 pretty printer does not take advantage of this), 
   - it knows about some "special" things like exceptions and
 some other oddities,
   - it ought to work on GHC 5 and 6, though I haven't tested it
 extensively on the latter

Functions are a sore point (they all get mapped to the one thing, sigh).

It makes use of the FFI and the nice API that GHC provides for the
RTS (is that enough TLAs in one sentence?)

Unfortunately to use the library you must compile with -prof. The reason
is to trick GHC into keeping names of data constructors on the heap.
I'd rather avoid this, and perhaps with the new HsDebug stuff in GHC there
is a better way to get such names, but I haven't looked too hard.
(Any ideas?)

An example is below.

Ooroo,
Bernie.



Here's an example:

   {- demonstrating the use of ReifyHs.reify -}
   
   module Main where
   
   import ReifyHs (reify)
   import PrettyGraph (prettyGraph)
   import Data.Char (toUpper)
   
   main :: IO ()
   main
  = do putStrLn $ "GHC version: " ++ show __GLASGOW_HASKELL__
   let listTups = zip "abcdefghij" [1..]
   putStr "\n\nForce the list to be evaluated a bit:\n\n"
   print $ take 3 listTups
   graph <- reify listTups
   putStr "\n\nhere's the graph representation: \n\n"
   print graph
   putStr "\n\nhere's a pretty print of the above: \n\n"
   putStrLn $ prettyGraph graph
   putStr "\n\nForce the list to be evaluated a bit more:\n\n"
   print $ take 5 listTups
   graph <- reify listTups
   putStr "\n\nthe graph pretty printed again: \n\n"
   putStrLn $ prettyGraph graph



Running the example after "make"

   [EMAIL PROTECTED]:/tmp/reify$ ./test 
   GHC version: 504
   
   
   Force the list to be evaluated a bit:
   
   [('a',1),('b',2),('c',3)]
   
   
   here's the graph representation: 
   
   AppNode 1076636796 ":" 1 2 [AppNode 1076636776 "(,)" 1 2 [CharNode 'a',
   IntNode 1],AppNode 1076637368 ":" 1 2 [AppNode 1076637348 "(,)" 1 2 
   [CharNode 'b',IntNode 2],AppNode 1076637932 ":" 1 2 [AppNode 1076637912 
   "(,)" 1 2 [CharNode 'c',IntNode 3],AppNode (-1) "" 3 0 [
   
   
   here's a pretty print of the above: 
   
   [('a',1),('b',2),('c',3) .. ?
   
   
   Force the list to be evaluated a bit more:
   
   [('a',1),('b',2),('c',3),('d',4),('e',5)]
   
   
   the graph pretty printed again: 
   
   [('a',1),('b',2),('c',3),('d',4),('e',5) .. ?


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


profiling for stack usage

2003-08-15 Thread Ketil Z. Malde

Hi again,

I'm currently in a situation where my program runs easily out of
stack.  Depending on the input, stack usage often exceeds 10Mb.

1. Is there a way to profile stack usage, so that I can identify the
culprit and deal with the problem at the root?  Normal (time)
profiling tells me how many times a function is called, but it would
be interesting to know how many times it was recursively called, or
the size of its stack frames.  Is that information available?

Heap profiling -- well, it doesn't *sound* as if it would incorporate
the stack; does it anyway?

2. Is there a way to compile programs to use more than the default
stack?  I can of course pass +RTS -K10M -RTS on the command line, but
I would rather like to change the default, instead of kicking myself
for forgetting it all the time.  And is there any reason (except
excessive resource consumption and postponed failure from infinite
loops) not to run with huge stacks? 

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users