Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using -with-rtsopts ghc option as a pragma

I'm trying to solve an algorithm puzzle in Haskell, and to do so I need quite a big data structure. However the problem solving site I submit my solution to, doesn't use any run time options to allow bigger stack, but I've heard that I can use compiler options as pragma. I've tried using following pragma in my code:

{-# OPTIONS_GHC -O2 -rtsopts -with-rtsopts=-K32m #-}

Then I compile with ghc --make algo.hs. However, when I run on my machine on some big tests, program crashes with stack overflow, and reports that current stack size is 8MB. On the other hand, when I compile like that:

ghc -rtsopts -with-rtsopts=-K32M --make algo.hs -fforce-recomp

The program works just fine on the same data, without adding any +RTS arguments. I use GHC 7.0.2, but the problem solving site is using 6.12.3, so preferably I'm looking for solution that could work with that old version too.

like image 704
fsh Avatar asked May 28 '12 15:05

fsh


1 Answers

Remember that the compilation of almost any kind of native binary consists of at least two steps: Actual object compilation (.hs -> .o), and linking (.o, .a, .lib -> executable/.exe/.so/.dll etc)

When you compile with this:

ghc -rtsopts -with-rtsopts=-K32M --make algo.hs -fforce-recomp

... what's actually happening behind the scenes is basically:

# object compilation - creates algo.o
ghc -c algo.hs -fforce-recomp
# linking - links together algo.o and libHSsomepackage.a into the "algo" binary
# (we assume that `algo.hs` included some module from the package `somepackage`
#  e.g. `Data.Package.Some`)
ghc -rtsopts -with-rtsopts=-K32M -o algo -package somepackage algo.o

I.e. the --make option tells GHC to compile object files automatically before linking the result, and it fills in a ton of blanks for you. Take note of where the individual command-line flags end up.

When you specify that pragma at the top of the file, this is instead what happens (with ghc --make algo.hs):

ghc -c algo.hs -rtsopts -with-rtsopts=-K32M
ghc -o algo -package somepackage algo.o

The OPTIONS_GHC pragma tells the compiler about options to add when compiling that specific module into an object file. Because -rtsopts is a linker option (it tells GHC to link in a different set of command-line handling stuff), you can't specify it when compiling an object file. You must specify it when linking, and such options cannot be specified in a module header.

There are two solutions:

  1. Use Cabal to build stuff for you and specify in your .cabal file what GHC options you want
  2. Fix your algorithm so that you don't need as much stack space, for example by using tail recursion and more strictness in folds. See the wiki for more info.
like image 183
dflemstr Avatar answered Sep 17 '22 14:09

dflemstr