How to add memory profiling options to stack test - haskell

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.

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

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.

rust, WebAssembly, and passing arguments for increased total memory

I have a rust project I am compiling to webasm per http://asquera.de/blog/2017-04-10/the-path-to-rust-on-the-web/
Project compiles. When I run it in Chrome Canary, it runs out of memory and gives me a very helpful error message:
abort("Cannot enlarge memory arrays. Either (1) compile with -s
TOTAL_MEMORY=X with X higher than the current value 16777216, (2) compile
with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime,
...
Problem is, its not clear how to pass those flags to rustc / the build tool chain.
Neither setting EMMAKEN_CFLAGS or the following work:
cargo rustc -v --target=wasm32-unknown-emscripten --release -- -Clink-args="-s TOTAL_MEMORY=33554432"
This blog post offers a solution that I think can be applied in your case too:
As best as I can tell there is no way to pass most linker arguments through cargo. Instead, hack around the limitation by specifying a custom linker that is actually a shell script wrapping the real linker.
Create a shell script like emcc_link that calls emscripten with the appropriate options:
emcc "-s" "TOTAL_MEMORY=33554432" $#
(You may need other options to make it work. Check the blog post for details.)
And specify to use it for your project by editing/creating .cargo/config:
[target.wasm32-unknown-emscripten]
linker = "/your/project/dir/emcc_sdl"
[target.asmjs-unknown-emscripten]
linker = "/your/project/dir/emcc_sdl"
I ruthlessly assumed the build environment is Linux or the like. On Windows the shell script should probably be a batch script and I'm not sure if there are any differences in .cargo/config.
Disclaimer: I have not tried any of this.

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