multicore parallelism with stack runghc - haskell

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.

Related

Compile stack script instead of running it

The build tool stack has the feature to treat a usually compiled haskell source file as a script. (https://docs.haskellstack.org/en/stable/GUIDE/#script-interpreter)
Is it also possible to create a compiled executable the same way?
I searched the help section of stack and stack script, but could not find an options that make this possible.
script.hs:
#!/usr/bin/env stack
{-
stack script
--resolver lts-13.14
--package turtle
-}
main = print "hello"
So if given it the right permissions, this file can be executed. I guess behind the scenes stack compiles the file and then just runs it. And I'd like to just get the compiled intermediate binary.
No, it's not compiled. It's run through runhaskell which is a Haskell interpreter. If you want to compile it... do that. Instead of running the script,
take the --resolver and --package options from the script comment and pass them like this
stack ghc --resolver lts-13.14 --package turtle test.hs
The script command takes both --compile and --optimize as flags, which will instruct Stack to first compile to an executable (optionally with -O2 optimization level) before running.

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.

Running a haskell program in ghci

I am new to Haskell and trying to learn it from "Learn you a Haskell." I have run into a problem that I cannot find an answer to anywhere. I have a simple program that I want to run, but nothing will I do will make it run. What the book is telling me to do doesn't work. I can compile the program and run individual functions, but I can't get main to run unless I call that particular function. That seemed fine to me until I tried to pass a text file into it and it doesn't work.
So what do I do to run the program after typing :load program.hs?
I have tried...
$ ./program
--make program
--make program.exe
and about a thousand variations of these things. What the hell do I do to get my program running so that I can pass it a text file?
Picture of results in GHCi
cmd "Assembler failure"
It looks like you got confused between ghci and the command line. You can only type Haskell code in ghci. The command ./capslocker < haiku.txt is meant to be run from the command line and will run your compiled program capslocker. The $ sign is the command prompt in Linux and you're not meant to type that in. The book suggests using
$ ghc --make capslocker
beforehand to compile the code. It doesn't actually use ghci in this section. If you're on Windows then some of the commands may not work, since it assumes you are using Linux (it explains this earlier in the "input and output" section and suggests cygwin as an alternative).
Haskell can be compiled or interpreted. To use a python-like interpreter do runhaskell and you can use the same parameters as you would compile it.
More information here:
What's the difference between runghc and runhaskell?

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

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