Cache misses when 'using' packages since upgrading to 1.11

Since upgrading to 1.11 I’ve been receiving messages about cache misses like this one:

julia> using GLMakie
[ Info: Precompiling GLMakie [e9467ef8-e4e7-5192-8a1a-b1aee30e663a] (cache misses: invalid header (8))

and this:

julia> using Verify
Precompiling Verify...
  1 dependency successfully precompiled in 178 seconds. 606 already precompiled.
[ Info: Precompiling Verify [156113c4-ddd8-477f-ab34-46faedf79717] (cache misses: include_dependency fsize change (1), wrong dep version loaded (1))

To clarify, precompiling works fine but when actually using packages the message about cache misses appear. And precompilation runs for a couple of minutes without any other messages. After this packages works as normal. The usual suspects are include_dependency, fsize and invalid header.

Has anyone else experienced something similar?

Versioninfo:

Julia Version 1.11.1
Commit 8f5b7ca12ad (2024-10-16 10:53 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, icelake-client)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)

@kristoffer.carlsson can correct me if I’m wrong but I think this is just additional information about stuff that was happening already anyway.

That is, when using a package sometimes Julia will find that a precompilation file created for that package can’t be loaded from the cache for some reason, and so it needs to re-precompile. This has always been the case, but in 1.11 Pkg tells you why it couldn’t use a cached precompiled file.

2 Likes

That sounds reasonabIe. I should clarify that I felt like packages were taking longer to load/cache misses happening more often but that might just be a feeling since I’m being told about it now by Pkg.

“invalid header” also probably sounds a little bit scarier than it was intended to be, maybe “incompatible header” would be a nicer wording.

1 Like

Wouldn’t it just be better to not print anything by default? It is not that most user can do anything with that information anyway. It does give the impression that something is broken.

That’s not something that one who does want to understand why precompilation is being triggered can retrieve afterwards.

2 Likes

I’ve also wondered about this message. It gives the incorrect impression that something has gone wrong, and there’s nothing the average user can, or should, do in response to the message. For beginning Julia programmers this will be confusing, and for experienced programmers it’s noise almost always.

An even more neutral phrasing, that doesn’t have any connotations of being in an error state, might be “rebuilding cache for xxx package, this might take a while”.

8 Likes

But couldn’t it be triggered by a julia command line argument?

1 Like

I think that’s what it used to be.

Just from personal experience there’s a lot of hard-to-make-precise griping from people - myself included - about excessive recompilation. When it happens to me I usually (in the nicest possible way) blame Kristoffer, who reasonably asks me for a reproducer. The problem with that of course is that its not easy to reproduce these things, especially if I don’t want to nuke my compile cache.

So to the extent that this change will help find sources of unnecessary recompilation, I’m all for it.

4 Likes

in that case you’d have to Ctrl-C to kill the current pre-compilation, and that may change the reason for the NEXT pre-compilation, so you still can’t know why it WAS pre-compiling, I think?

Here’s a proposal to change “invalid header” to “incompatible header”.

@Eliassj I suspect what’s happening in your case is indicated by wrong dep version loaded (1). It seems like you’ve loaded a package from within another environment before trying to load Verify in a different environment, which has a common dependency/ies that differ in version to the current environment.

A classic way this happens is

$ julia
# startup.jl runs loading, say Revise, from your default env
pkg> activate MyProject
julia> using Verify
# Julia precompiles Verify, but only considering the active env, not the 
# default env higher in the env stack, but some deps are already loaded by Revise
#
# Julia tries to load verify that it just precompiled but because different 
# dep versions are loaded it cannot, so has to precompile new versions with 
# those versions, which it does in the serial precompile process starting with
# [ Info: Precompiling

It’s an unfortunate limitation of stacked environments. Ways to avoid it:

  1. Always start up julia in the environment you are going to use, via --project, that way common dependencies will be the versions your env needs. i.e. avoid pkg> activate
  2. Avoid using startup.jl to load packages if you’re going to be switching project after launch, and only load once you’re in the main env.
  3. Use workspaces instead of the default env for common deps, which are coming in 1.12 10. Project.toml and Manifest.toml · Pkg.jl
  4. The ability to unload packages is added to julia… or something like that… There is some work around that ongoing.
2 Likes

Can someone clarify - if I don’t follow the advice of @ianshmean , and I do a bunch of activate switching on various projects, use of various packages in my startup.jl etc. etc., will I still get the correct versions of packages loaded, and the annoyance is just that I might get too much recompilation, which is a hassle?

Or is there a danger that I won’t even actually get the correct versions of packages loaded, if I’ve previously loaded something from the default env, say?

With that pattern, yes you can end up with incompatible deps being loaded, without notice.

I tried to add a warning about this, but there were some edge cases that meant it needed redoing, which hasn’t finished yet WIP: Reland "Warn if an already loaded package is attempted to be loaded from a different path" by IanButterworth · Pull Request #52798 · JuliaLang/julia · GitHub