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

ccache support #3761

Merged
merged 1 commit into from
Jul 9, 2018
Merged

ccache support #3761

merged 1 commit into from
Jul 9, 2018

Conversation

junghans
Copy link
Contributor

@junghans junghans commented Apr 7, 2017

Fix #5504

export SPACK_ENABLE_CCACHE=yes
export PATH="/path/to/cache${PATH:+:}${PATH}"
spack install libelf
ccache -z
spack uninstall libelf && spack install libelf
ccache -s

and yeah

cache directory                     /home/junghans/.ccache
primary config                      /home/junghans/.ccache/ccache.conf
secondary config      (readonly)    /etc/ccache.conf
cache hit (direct)                   114
cache hit (preprocessed)               0
cache miss                             4
called for link                        1
called for preprocessing              18
compile failed                         2
autoconf compile/link                 21
files in cache                       394
cache size                           5.8 MB
max cache size                       5.0 GB

@adamjstewart
Copy link
Member

adamjstewart commented Apr 7, 2017

It might be better to provide this support through Spack's configuration file: ~/.spack/configuration.yaml. I don't like relying on environment variables. I don't actually know how to add entries to configuration.yaml or use them in Spack, but @tgamblin should be able to help.

@junghans
Copy link
Contributor Author

junghans commented Apr 7, 2017

It is a start! If you tell me how to query Spack's configuration in cc, I will do that.
Plus, it would be nice to point it at a ccache binary installed by spack itself instead of relying on $PATH.

@junghans
Copy link
Contributor Author

junghans commented Apr 7, 2017

On a related note, for clang we should export CCACHE_CPP2=yes to avoid endless warnings like:

clang: warning: argument unused during compilation: '-c'
clang: warning: argument unused during compilation: '-I .'

(Details on why here: http://peter.eisentraut.org/blog/2014/12/01/ccache-and-clang-part-3/)

@citibeth
Copy link
Member

citibeth commented Apr 8, 2017

What is the expected use case here?

@junghans
Copy link
Contributor Author

junghans commented Apr 9, 2017

@citibeth : I like the idea to give the users an easy way to enable compiler caching.

@citibeth
Copy link
Member

citibeth commented Apr 10, 2017 via email

@davydden
Copy link
Member

@junghans:

My understanding is similar to @citibeth 's in that we won't get anything from ccache in Spack unless it's integrated with spack setup to help developers use Spack's machinery to setup/config their package and get all benefits of caching when re-building their library while developing.

If that is not the case, maybe you could illustrate the difference in compile time on some big package like trilinos?

I also agree with @adamjstewart that such things should be configured through yaml files.

@junghans
Copy link
Contributor Author

@citibeth: There are hundreds of blog posts out there showing that ccache is or isn't useful for a particular package, however, from my own experience (on Gentoo) ccache comes in handy if you need to compile similar variants of the same package (same compiler, but different features or different patch sets). Also the time saving depends a lot on the machine and the filesystem, where the cache is store, it is the usual compute vs. I/O trade-off.

@davydden: The libelf example above shows that spack can useccache (cache hit (direct) 114) by simply prefixing the compiler with the ccache binary. Sure, as discussed it would be nicer to integrate this feature using spack setup instead of an environment variable, but let's first decide if we want to support compiler caching.

@citibeth
Copy link
Member

citibeth commented Apr 10, 2017 via email

@@ -336,6 +337,10 @@ def set_build_environment_variables(pkg, env, dirty=False):
env.set(SPACK_SHORT_SPEC, pkg.spec.short_spec)
env.set(SPACK_DEBUG_LOG_DIR, spack.spack_working_dir)

# Find ccache binary and hand it to build environment
if spack.ccache:
env.set(SPACK_CCACHE_BINARY, 'ccache')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the crux, how would I detect a ccache binary built by spack previously.

@junghans
Copy link
Contributor Author

@citibeth: see my latest commit.

Should this PR also try to integrate f90cache?

I will do that in another pull request.

Copy link
Member

@citibeth citibeth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start, more complete docs would be great!

When set to ``true`` Spack will use ccache to cache compiles. This is
useful specifically un two cases: (1) Use with ``spack setup``, (2)
Build the same package with many different variants. The default is
``false``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could more documentation be useful? For example... How does Spack find ccache? Are you supposed to ask Spack to build it first? How should ccache be configured?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does Spack find ccache?

You tell me, how you want it (see my comment above). Currently spack just assumes ccache is in PATH. And I can certainly write that here.

Are you supposed to ask Spack to build it first?

Sure, if you don't have it on your system that is an option.

How should ccache be configured?

ccache works nicely out of the box, but we can of course refer the user to the Configuration settings of man ccache.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

ccache`. ``ccache`` comes with reasonable defaults for cache size
and location. (See the *Configuration settings* secion of `man
ccache` to learn more about the default settings and how change
them.)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spack install ccache and man ccache need double backticks around them.

--------------------

When set to ``true`` Spack will use ccache to cache compiles. This is
useful specifically un two cases: (1) Use with `spack setup`, (2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spack setup needs double backticks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@junghans
Copy link
Contributor Author

@citibeth: Any further comments?

lib/spack/env/cc Outdated
@@ -339,7 +339,11 @@ case "$mode" in
args=("${args[@]}" ${SPACK_LDLIBS[@]}) ;;
esac

full_command=("$command" "${args[@]}")
if [[ ${lang_flags} != "F" && ${SPACK_CCACHE_BINARY} ]]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment explaining what ${lang_flags}!="F" means. I think you're filtering out the Fortran compiler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@junghans junghans force-pushed the ccache branch 2 times, most recently from 188b30f to 6d73800 Compare April 12, 2017 02:25
@junghans
Copy link
Contributor Author

So, can somebody test this please, e.g.:

git fetch origin pull/3761/head && git checkout FETCH_HEAD
spack install ccache
sed -i '/ccache:/s/false/true/' config.yaml
spack install libelf
ccache -z
spack uninstall libelf && spack install libelf
ccache -s

@junghans junghans changed the title Rudimentary ccache support ccache support Apr 12, 2017
@healther
Copy link
Contributor

healther commented Apr 13, 2017

$ ccache -z
$ spack uninstall libelf && spack install libelf
$ ccache -s
cache directory                     ~/.ccache
primary config                      ~/.ccache/ccache.conf
secondary config      (readonly)   ~/Documents/git/spack/opt/spack/1-debian8-x86_64/gcc-4.9.2/ccache-3.3.4-n5cd2eq5a47jcidgkq7ffejlp3g7wuhx/etc/ccache.conf
cache hit (direct)                     0
cache hit (preprocessed)               0
cache miss                           118
cache hit rate                      0.00 %
called for link                        1
called for preprocessing              18
compile failed                         2
autoconf compile/link                 19
cleanups performed                     0
files in cache                       415
cache size                           5.6 MB
max cache size                       5.0 GB

@junghans
Copy link
Contributor Author

@healther : Hmm, strange.

files in cache 415

The good news is that ccache was used, so the code in this PR works.

cache miss 118

The bad news is, there were no hits, so for some reason ccache thought it couldn't reuse cache.

@junghans
Copy link
Contributor Author

@healther: Which compiler were you using?

@healther
Copy link
Contributor

The system-provided compiler

gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

@healther
Copy link
Contributor

The number of files in the cache increases each time I uninstall and reinstall

@healther
Copy link
Contributor

FYI: on my private machine (MacOS, with python3) I get the same behaviour:

$ ccache -s
cache directory                     /Users/healther/.ccache
primary config                      /Users/healther/.ccache/ccache.conf
secondary config      (readonly)    /Users/healther/Documents/git/spack/opt/spack/darwin-sierra-x86_64/clang-8.0.0-apple/ccache-3.3.3-3h5lzitlf55lxrzq7vnyuoy5qq7bgno4/etc/ccache.conf
cache hit (direct)                     0
cache hit (preprocessed)               0
cache miss                           112
cache hit rate                      0.00 %
called for preprocessing              36
compile failed                         2
autoconf compile/link                 36
cleanups performed                     0
files in cache                       220
cache size                           2.4 MB
max cache size                       5.0 GB

@junghans junghans force-pushed the ccache branch 2 times, most recently from e0cea99 to 4ae964e Compare November 28, 2017 17:47
@junghans
Copy link
Contributor Author

@scheibelp SC17 is over, so time to merge!

@healther
Copy link
Contributor

healther commented Jan 5, 2018

Could we please merge this? We would like to start autodeploying software with spack builds, and as long as spack is not stackable (using one spack's packages as external ones for another instance) ccache would at least somewhat speedup our build process.

@JavierCVilla
Copy link
Contributor

Could we please merge this? We would like to start autodeploying software with spack builds, and as long as spack is not stackable

Same case here, it would be nice to have such a feature.

@healther
Copy link
Contributor

@junghans do you have any known-issues or similar that I should be aware of when using this PR?

@junghans
Copy link
Contributor Author

@healther: it should just work ;-) Can you give it another test run? So that @tgamblin or @scheibelp can finally merge this.

@healther
Copy link
Contributor

I'll take a look and report back :)

@healther
Copy link
Contributor

Mh, I see a massive slow down of the configure step.
without ccache

==> Successfully installed perl
Fetch: 0.94s.  Build: 6m 12.32s.  Total: 6m 13.26s.

[+] /wang/users/wv385/cluster_home/tmp/20180122_staging/opt/spack/linux-debian8-x86_64/gcc-4.9.2/perl-5.24.1-xtnzd3og6g3kbzvqhwhqqdyswcepnhap

with ccache the

==> Building perl [Package]
==> Executing phase: 'configure'

takes significantly longer than that. Now that might be a problem of our nfs filesystem mount (which currently has some timeout problems). I'll test it also on a scratch filesystem (i.e. locally mounted, not sure about the terminology)
Here I see a difference of (with ccache)

==> Successfully installed perl 
  Fetch: 0.03s.  Build: 2m 34.52s.  Total: 2m 34.55s.
[+] /tmp/blub1/20180122_staging/opt/spack/linux-debian8-x86_64/gcc-4.9.2/perl-5.24.1-xtnzd3og6g3kbzvqhwhqqdyswcepnhap

without ccache

==> Successfully installed perl
  Fetch: 0.51s.  Build: 1m 36.99s.  Total: 1m 37.50s. 
[+] /tmp/blub1/20180122_staging/opt/spack/linux-debian8-x86_64/gcc-4.9.2/perl-5.24.1-xtnzd3og6g3kbzvqhwhqqdyswcepnhap

and the with ccache is with a warm cache (i.e. perl was already build with it once, albeit in a different folder) and I see a lot of hits in the statistics!

Any ideas what is happening here @junghans ?

@healther
Copy link
Contributor

Can I get timings for the single steps from spack? I'd expect that build is actually faster and it's only configure that is slow

@healther
Copy link
Contributor

Okay @junghans current status:

  • Good news: The weird build-time increase was due to our nfs-filesystem, changing the cache location seems to remove the penalty
  • Bad news: Even though I see some cachehits (O(20%)), the build-time does not significantly change (even after spack install && spack uninstall && spack install). Do I need to set additional environment variables besides CCACHE_DIR?

@junghans
Copy link
Contributor Author

It really depends on how reproducible the build is, __DATE__ and friends are bad!

@junghans
Copy link
Contributor Author

junghans commented May 3, 2018

Ping @tgamblin

@paul-chelarescu
Copy link
Contributor

This feature is working for my case as well, and giving significant built time improvements. Could this be merged soon?

@junghans
Copy link
Contributor Author

Ping @tgamblin @scheibelp

@adamjstewart
Copy link
Member

It looks like the unit tests are failing.

@@ -335,6 +336,13 @@ def set_build_environment_variables(pkg, env, dirty):
env.set(SPACK_DEBUG_LOG_ID, pkg.spec.format('${PACKAGE}-${HASH:7}'))
env.set(SPACK_DEBUG_LOG_DIR, spack.main.spack_working_dir)

# Find ccache binary and hand it to build environment
if spack.config.get('ccache'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is causing the latest failing tests - it should be something like if spack.config.get('config:ccache'):

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Copy link
Member

@scheibelp scheibelp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the tests are still failing based on retrieving the value of ccache from config.yaml (you are using a . instead of a : to specify a property of a section)

I also have a minor request for deciding when to enable ccache support in the cc wrapper.

Other than that this looks good (which is to say I'm of a mind to finally merge it). I won't get a chance to merge this until 7/9 though.

@@ -335,6 +336,13 @@ def set_build_environment_variables(pkg, env, dirty):
env.set(SPACK_DEBUG_LOG_ID, pkg.spec.format('${PACKAGE}-${HASH:7}'))
env.set(SPACK_DEBUG_LOG_DIR, spack.main.spack_working_dir)

# Find ccache binary and hand it to build environment
if spack.config.get('config.ccache'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be config:ccache vs config.ccache (need a colon vs. a period)

lib/spack/env/cc Outdated
@@ -342,7 +342,15 @@ case "$mode" in
args=("${args[@]}" ${SPACK_LDLIBS[@]}) ;;
esac

full_command=("$command" "${args[@]}")
#ccache only supports C languages, so filtering out Fortran
if [[ ${lang_flags} != "F" && ${SPACK_CCACHE_BINARY} ]]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we whitelist vs. blacklist here? e.g. if ${lang_flags} = "C" || ${lang_flags} = "CXX" (i probably didn't get that syntax right).

I'm aware that C/CXX/F are the only possible values currently but it's generally less fragile to specify the cases where it should enable ccache.

@scheibelp scheibelp merged commit 8bc3f7d into spack:develop Jul 9, 2018
@scheibelp
Copy link
Member

Thanks!

@junghans junghans deleted the ccache branch July 10, 2018 23:14
This was referenced Jul 30, 2018
alalazo pushed a commit to epfl-scitas/spack that referenced this pull request Oct 23, 2018
If the user sets "ccache: true" in spack's config.yaml, Spack will use an available
ccache executable when compiling c/c++ code. This feature is disabled by default
(i.e. "ccache: false") and the documentation is updated with how to enable
ccache support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet