Using stack for profiling - haskell

I'm trying to do some profiling using stack --enable-profiling and I'm a bit confused about what's happening exactly.
Do I need to use also --enable-library ?.
Also, is it build in a separate directory ?What happend next I build it, will remember that am I in profiling mode or do I have to use the --enable-profiling all the time.
It is generally recommended to profile in conjonction with the -O2 option. Does --enable-profiling set it automatically ?

Stack support for enabling profiling works great, example:
stack build --profile --executable-profiling --library-profiling
stack exec -- example <your prog args> +RTS -p
Then see example.prof for the default output.
Update: the stack support pointed me to the right correct for exec, see https://github.com/commercialhaskell/stack/issues/1655

Related

stack run with profiling in haskell

I tried running
$ stack build --profile && stack run myexec --rts-options -p
But I get
...
Registering library for mylibrary-0.1.0.1..
Completed 2 action(s).
myexec: the flag -p requires the program to be built with -prof
...
I know I could run
$ .stack-work/dist/x86_64-linux/Cabal-2.4.0.1/build/myexe/myexe +RTS -p
But what's the point of stack run then? I don't want to have to know the version of cabal and the architecture etc (this all happens in a makefile).
The command that you use stack run is a convenience command that not only runs the binary, but also builds it prior to that. So when you run stack build --profile it compiles you binary with all of the necessary ghc flags, but when you call stack run it compiles it again, but now without all of the profiling flags. So there are two way to do it properly:
Don't run stack build, since it is redundant:
$ stack --profile run myexec --rts-options -p
or call the executable directly with +RTS flags, but make sure to pass --profile to both stack invocations, otherwise the stack exec will be looking in the wrong place for the binary (namely non-profiling build) and will fail to find it.
$ stack --profile build
$ stack --profile exec -- myexec +RTS -p

How can I get GHC Core output via stack?

How do I get a stack build command to dump the GHC Core?
I've tried this, to no avail:
stack build :hello_world --ghc-options '-ddump-simpl'
Make sure to clean before, or force recompilation via the stack option --force-dirty and ghc option -fforce-recomp.
The files are dumped somewhere around .stack-work/dist/.../build/hello_world/hello_world-tmp/.

multicore parallelism with stack runghc

I had been working on a script in which I hoped to take advantage of multiple processors in my machine by swapping out mapM with Async.mapConcurrently.
Observing no speed increase in that instance, I wanted to verify that runghc can indeed utilize multiple cores.
Given a file Foo.hs:
import Control.Concurrent
main = print =<< Control.Concurrent.getNumCapabilities
If I compile the file as follows:
stack ghc -- -threaded Foo.hs
and then run it as follows:
./Foo
it returns the result 1. This is expected, as no RTS options have been supplied. Running it instead as follows:
./Foo +RTS -N
returns the number 6, as there are 6 processors in my machine (agreeing with nproc).
However, when I run the script in "interpreted mode" like so:
GHCRTS="-N" stack runghc Foo.hs
It yields the following error text:
Running /home/kostmo/.stack/programs/x86_64-linux/ghc-nopie-8.0.2/bin/ghc-pkg --no-user-package-db list --global exited with ExitFailure 1
ghc-pkg: the flag -N requires the program to be built with -threaded
Is it possible to utilize multiple cores with stack "scripts"?
Thanks for asking this question, I think stack should handle the GHCRTS environment variable specially, and opened this issue https://github.com/commercialhaskell/stack/issues/3444 and made this change https://github.com/commercialhaskell/stack/pull/3445
Unfortunately, it does not solve this case, because runghc itself (ghc) will process GHCRTS, and it is not built with the threaded runtime. So the environment variable solution cannot be used.
I think it should be possible to provide -with-rtsopts -N flag to stack script --compile, but that doesn't seem to be working, needs further investigation. This doesn't work with runghc, because it uses the interpreter.

How to add memory profiling options to stack test

when running stack test --profile it automatically adds the -p rts option.
I am trying to do some memory profiling on my test suite and so would like to add the hc, or hy rts option.
This doesn't seem to work
stack test --profile --ghc-options="+RTS -hc -RTS"
it gives the error
ghc: the flag -hc requires the program to be built with -prof
If I have to guess, you intend the +RTS options to be passed to the final test program, but in your invocation above it might be that those options are being received by the ghc executable itself; like you are telling to ghc "compile this code but please profile your memory while you do that". My suggestion is to build the tests with profiling enabled (for example by running the tests first with stack test --profile, although probably you can also use some form of stack build) and then run the generated test executable (with profiling) passing the RTS options.

How can I increase the stack size with runhaskell?

I'm writing some disposable Haskell scripts to solve some of the Project Euler problems. I don't really want to have to compile them because of the number of changes I'm constantly having to make, but in a few cases I've found that I've run out of stack space.
The documentation for runhaskell says that the following syntax should increase the stack space:
runhaskell +RTS -K5M -RTS Script.hs
This never, ever works (in any permutation I've tried). The stack size always remains 8,388,608. This is maddening, and I haven't found much help on Google.
Any suggestions? What am I doing wrong?
I'm guessing you're using GHC. Chapter 4 of the User's Guide of the newly released 6.10.1 says:
The only runghc flag currently is -f
/path/to/ghc, which tells runghc which
GHC to use to run the program.
I don't see a bug logged at http://hackage.haskell.org/trac/ghc . Seems pretty lame to me. I'd suggest asking on irc #ghc, or the cvs-ghc mailing list.
Of the other Haskell compilers/interpreters, only nhc98 seems allow you to set the max stack size. Depending on your OS, nhc98 could be an option.
I'm doing the same thing (Project Euler) and have been using ghc. The trick (thanks #haskell!) is to tell the executable to have more stack size rather than the compiler.
$ ghc -O2 -o 23 23.hs
$ ./23 +RTS -K128M
Just compile it.
Problem123.hs:
module Main where
main = do
print solution
solution = ...
Short and sweet command line:
ghc --make -O3 Problem123.hs
./Problem123
Final note: I'm not sure I would call them "scripts".

Resources