Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profiling build defaults #4032

Open
parsonsmatt opened this issue May 18, 2018 · 17 comments
Open

Profiling build defaults #4032

parsonsmatt opened this issue May 18, 2018 · 17 comments

Comments

@parsonsmatt
Copy link
Contributor

@bitemyapp's Makefiles are a treasure trove of build tips. Here's a trick for profiling builds:

stack build --profile --work-dir .stack-work-profiling

This tremendously improves build caching, at the expense of disk space.

Can this be a default behavior, or at least, enabled via a global config flag or similar? It is soul crushing to have to rebuild all of the deps for a large project for profiling, and rebuild them again for normal mode.

@roman
Copy link

roman commented May 18, 2018

I do this all the time, Do you know if it is also required to have a --stack-root as well to make sure the snapshot dependencies are also profiled?

@snoyberg
Copy link
Contributor

Only downside I can see is screwing up gitignore files, but that seems a small price to pay. What about doing it as a subdir of .stack-work? I don't even know if that will work.

@bitemyapp
Copy link
Contributor

@snoyberg could be a good idea in part because of we always suffix the profiling version of a build then anyone making custom use of workdirs like I was would benefit from this behavior across the board.

Not sure if this is the ideal approach or not, though.

@gavwhela
Copy link

gavwhela commented Jun 6, 2018

Working on this from the hackathon: haskell-hackathon/#5.

@snoyberg
Copy link
Contributor

Hey @gavwhela, just bumping this. Any questions on the codebase?

@buecking
Copy link

buecking commented Jul 7, 2018

I just experienced this pain and agree --profile should, at the very least, be a sticky flag. I agree there needs to be a way to customize stack at some level. Has there been any thought into adding custom synonyms i.e. profile=build --profile --work-dir .stack-work-profiling.

@ntc2
Copy link
Contributor

ntc2 commented Jul 10, 2018

@snoyberg

Only downside I can see is screwing up gitignore files, but that seems a small price to pay. What about doing it as a subdir of .stack-work? I don't even know if that will work

I think using a subdir of .stack-work for the new profiling builds default is a great idea. It's not just .gitignore files that are affected by adding another top-level Stack related scratch dir, because various tools have hardcoded special treatment of standard Haskell build dirs (.stack-work, dist, dist-newstyle). For example, haskell-mode and projectile in Emacs ignore these build dirs by default when generating TAGS. Making the profiling cache a subdir of .stack-work would allow all of the existing special treatment to keep working unchanged.

However, using a subdir of .stack-work fails for me. For example, on one of my local projects:

stack --work-dir .stack-work/.stack-work-profile build --profile                    
flexdis86-0.1.2: configure (lib + exe)
flexdis86-0.1.2: build (lib + exe)                                                                     
macaw-base-0.3: configure (lib)                            
macaw-base-0.3: build (lib)                                
what4-0.4.0: configure (lib)                               
what4-0.4.0: build (lib)                                   
flexdis86-0.1.2: copy/register                             
macaw-base-0.3: copy/register                              
what4-0.4.0: copy/register                
Progress 8/27             
No directory could be located matching the supplied path: /tmp/stack13129/regex-1.0.0.0/.stack-work
No directory could be located matching the supplied path: /tmp/stack13129/s-cargot-0.1.4.0/.stack-work
No directory could be located matching the supplied path: /tmp/stack13129/located-base-0.1.1.1/.stack-work
No directory could be located matching the supplied path: /tmp/stack13129/monadLib-3.7.3/.stack-work
No directory could be located matching the supplied path: /tmp/stack13129/limp-0.3.2.2/.stack-work

A little experimentation makes me suspect the problem is that Stack doesn't do the equivalent mkdir --parents when creating the work dir. For example,

stack --work-dir no-such-parent-dir/.stack-work build

fails with

No directory could be located matching the supplied path: /home/conathan/brittle/sfe.git/no-such-parent-dir

Should be trivial to fix that.

@flip111
Copy link
Contributor

flip111 commented Aug 3, 2018

I'm a bit worried that choosing a new working directory will duplicate more than the absolute necessary. It's already the case that after stack clean or just delete the .stack-work directory and then rebuilding leaves a smaller .stack-work directory. So some dirty artifacts remain which are not needed for the rebuild. I hope this doesn't increase the amount of unneeded files. Also see #2244

@tdietert
Copy link
Contributor

Any update on this issue? This would be a lovely feature to have, and think that @ntc2 makes some good points regarding the implementation.

@snoyberg
Copy link
Contributor

Afaict, this issue is ready for someone to work on now. It seems like no one has volunteered to do it yet

@tdietert
Copy link
Contributor

Ahh, so do you think it's safe to assume @gavwhela has stopped working on it?

@snoyberg
Copy link
Contributor

Totally forgot that he'd been working on it and didn't see it when reviewing this issue :)

Yeah, I think it's safe to assume that at this point.

@qrilka
Copy link
Contributor

qrilka commented Mar 12, 2019

As #4412 and #4582 (with some tests, see #4308 (comment)) were merged I think this one was implemented by resolving #3922
@snoyberg are we OK with closing it?

@snoyberg
Copy link
Contributor

It's probably still worthwhile to have a separate .stack-work for profiling builds for all mutable packages. You're right that the implicit snapshots work will drastically improve the situation already.

@qrilka
Copy link
Contributor

qrilka commented Mar 12, 2019

Oh, right, that's about .stack-work which is a bit different thing, missed that

@thomasjm
Copy link

I have a general question about Stack's ability to reuse work when changing flags like --profile. Since this seems to be the main issue tracking this at the moment I'll leave it here.

I was reading this blog post about the current state of the cabal/stack divide, and it has this paragraph:

Although stack began its life with the best-of-class caching, cabal has now caught up and overtaken. stack struggles to support changing compiler flags (e.g. swapping between --fast builds and regular builds) whereas cabal can swap between -O0 / -O1 / -O2 without missing a beat. stack is unable to share the caches of extra-deps or git sources, whereas cabal treats everything equally and can share builds between projects .

I'm a longtime stack user but this one aspect of cabal seems really nice. I think it would be worth viewing this problem in the more general setting of keeping/reusing build artifacts compiled with different flags. The cabal behavior described above sounds like the ideal. Would it be possible for stack to solve the problem in the same general way?

@ntc2
Copy link
Contributor

ntc2 commented Oct 15, 2019

I have an SO answer on how to use --profile with Stack and someone just pointed out that Stack 2.X now requires --profile to also be passed to stack exec, in addition to stack build. I can't find this documented anywhere, but a little testing indicates that Stack is now keeping the profiling and non profiling builds separate automatically (the paths are different):

$ stack path --local-install-root
/tmp/prof-test/.stack-work/install/x86_64-linux/645ca5b89c41f1c9c1d95cd056827eb0ff49366e41dc71baafee7e8750f3202f/8.6.5
$ stack path --profile --local-install-root 
/tmp/prof-test/.stack-work/install/x86_64-linux/56dac42cad4cb0f4eed3c37ccc75047b71308bac53fbd2316970727a0981353f/8.6.5

Is this due to "implicit snapshots"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests