Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass RTS options to runghc?

Tags:

haskell

ghc

For ghci, I can limit the memory ghci can use by

$ ghci +RTS -M10m -RTS

When I compile the whole program, I can

$ ghc -rtsopts a.hs 

then

$ ./a +RTS -M10m

How can I do this for runghc a.hs? I've tried several ways, like runghc a.hs +RTS -M10m , but none of them seem to work. The only option I could limit the memory was by

$ export GHCRTS='-M10m'
$ runghc a.hs

, but I want this to be one time only, so I prefer doing this by passing arguments to runghc.


Edit : I'm checking whether the option is working or not using the following strategy (just because I don't know better ways):

-- a.hs
f x = f (f x)
main = print $ seq (f 0) 0

Open two terminals, one for top command and another for executing the code. If the execution stops saying "Heap exhausted", I conclude that -M[number]m is working. If the execution continues and uses huge amount of memory, I kill the process and conclude that it didn't succeed.

like image 356
Yosh Avatar asked Mar 30 '15 06:03

Yosh


1 Answers

Using GHCRTS=... runghc ... as chi says is the only way. Because of the way runghc interprets its command line, +RTS is interpreted as RTS options to runghc itself (if it's at the end) or as a program name (if it's at the beginning). It never reaches the runtime. You can force it to be passed to the program using --RTS +RTS ... but then it's treated as a program argument and it's still not seen by the runtime.

To investigate this, I wrote a wrapper shell script for ghc that traces its arguments, and passed this to runghc with the -f option.

Create a file ghc-wrapper containing:

#!/bin/sh -x
exec ghc "$@"

The -x option tells /bin/sh to trace every line. Use this with runghc:

$ runghc -f ./ghc-wrapper Hello.hs
+ exec ghc -ignore-dot-ghci -x hs -e :set prog "Hello.hs" -e :main [] Hello.hs
Hello, World!

$ runghc -f ./ghc-wrapper Hello.hs +RTS -s
+ exec ghc -ignore-dot-ghci -x hs -e :set prog "Hello.hs" -e :main [] Hello.hs
Hello, World!
    114,016 bytes allocated in the heap # runghc's heap, not Hello's
    ...

$ runghc -f ./ghc-wrapper Hello.hs --RTS +RTS -s
+ exec ghc -ignore-dot-ghci -x hs -e :set prog "Hello.hs" -e :main ["+RTS","-s"] Hello.hs
Hello, World!

$ runghc -f ./ghc-wrapper -- +RTS -s -RTS Hello.hs
+ exec ghc -ignore-dot-ghci -e :set prog "+RTS" -e :main ["-s","-RTS","Hello.hs"] +RTS
+RTS:1:55:
    Not in scope: `main'
    Perhaps you meant `min' (imported from Prelude)

What we really want runghc to execute is:

$ ghc -ignore-dot-ghci -x hs +RTS -s -RTS -e ':set prog "Hello.hs"' -e ':main []' Hello.hs
Hello, World!
      80,654,256 bytes allocated in the heap
      ...

But there's no way to specify that because runghc doesn't treat +RTS specially.

like image 80
Neil Mayhew Avatar answered Oct 21 '22 05:10

Neil Mayhew