stack run with profiling in haskell - 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

Related

Haskell standalone executable without using 'stack exec'

How would one go about creating an executable from a stack generated framework (stack new myprog simple)?
myprog.cabal shows myprog as executable that can be executed using stack exec myprog.
However: using ./myprog will not work. Not unless I call ghc --make src/Main.hs. This works obviously and nicely embeds the modules, but now the executable is called Main.
Is there a way to have stack compile myprog as a complete executable that can be called from anywhere assuming the environmental path is set?
As you may already be aware, stack build builds the executable, but then places it in a stack-specific path which can most easily be accessed using stack exec. However, there is another command: stack install, which then copies the executable to a convenient location. Normally the default location is in ~/.local/bin (I think), but you can use stack install --local-bin-path <PATH> to copy the executable to <PATH>. For instance, use stack install --local-bin-path . to place the executable in your current working directory, or use stack install --local-bin-path bin to place it in your ./bin/ directory. You can then run the executable using <PATH>/my-exe.

Passing RTS-opts to `stack test`

How can I pass RTS options to the test-suite of my project using stack?
stack exec allows for passing options to the executable, but since stack test is a synonym for stack build --test I can't see how to accomplish this.
I'm trying to generate some JSON-formatted profiler output for my test-suite using the RTS option -pj (GHC user guide).
I can see where stack places the regular executables, but not the executables for the test-suite.

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.

Using stack for profiling

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

Resources