Skip to content

Commit 6fdc607

Browse files
precompile out of env deps in serial within precompilepkgs
1 parent f356a40 commit 6fdc607

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

base/loading.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,8 +2625,7 @@ function __require_prelocked(pkg::PkgId, env)
26252625
if JLOptions().use_compiled_modules == 1
26262626
if !generating_output(#=incremental=#false)
26272627
project = active_project()
2628-
if !generating_output() && !parallel_precompile_attempted && !disable_parallel_precompile && @isdefined(Precompilation) && project !== nothing &&
2629-
isfile(project) && project_file_manifest_path(project) !== nothing
2628+
if !generating_output() && !parallel_precompile_attempted && !disable_parallel_precompile && @isdefined(Precompilation)
26302629
parallel_precompile_attempted = true
26312630
unlock(require_lock)
26322631
try

base/precompilation.jl

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,24 @@ struct ExplicitEnv
2626
#local_prefs::Union{Nothing, Dict{String, Any}}
2727
end
2828

29-
function ExplicitEnv(envpath::String=Base.active_project())
29+
ExplicitEnv() = ExplicitEnv(Base.active_project())
30+
function ExplicitEnv(::Nothing, envpath::String="")
31+
ExplicitEnv(envpath,
32+
Dict{String, UUID}(), # project_deps
33+
Dict{String, UUID}(), # project_weakdeps
34+
Dict{String, UUID}(), # project_extras
35+
Dict{String, Vector{UUID}}(), # project_extensions
36+
Dict{UUID, Vector{UUID}}(), # deps
37+
Dict{UUID, Vector{UUID}}(), # weakdeps
38+
Dict{UUID, Dict{String, Vector{UUID}}}(), # extensions
39+
Dict{UUID, String}(), # names
40+
Dict{UUID, Union{SHA1, String, Nothing, Missing}}())
41+
end
42+
function ExplicitEnv(envpath::String)
43+
# Handle missing project file by creating an empty environment
3044
if !isfile(envpath)
31-
error("expected a project file at $(repr(envpath))")
45+
envpath = abspath(envpath)
46+
return ExplicitEnv(::Nothing, envpath)
3247
end
3348
envpath = abspath(envpath)
3449
project_d = parsed_toml(envpath)
@@ -468,6 +483,7 @@ function precompilepkgs(pkgs::Vector{String}=String[];
468483
fancyprint::Bool = can_fancyprint(io) && !timing,
469484
manifest::Bool=false,
470485
ignore_loaded::Bool=true)
486+
@debug "precompilepkgs called with: pkgs=$(pkgs), internal_call=$(internal_call), strict=$(strict), warn_loaded=$(warn_loaded), timing=$(timing), _from_loading=$( _from_loading), configs=$(configs), io=$(io), fancyprint=$(fancyprint), manifest=$(manifest), ignore_loaded=$(ignore_loaded)"
471487
# monomorphize this to avoid latency problems
472488
_precompilepkgs(pkgs, internal_call, strict, warn_loaded, timing, _from_loading,
473489
configs isa Vector{Config} ? configs : [configs],
@@ -518,9 +534,12 @@ function _precompilepkgs(pkgs::Vector{String},
518534
# inverse map of `parent_to_ext` above (ext → parent)
519535
ext_to_parent = Dict{Base.PkgId, Base.PkgId}()
520536

521-
function describe_pkg(pkg::PkgId, is_project_dep::Bool, flags::Cmd, cacheflags::Base.CacheFlags)
537+
function describe_pkg(pkg::PkgId, is_project_dep::Bool, is_serial_dep::Bool, flags::Cmd, cacheflags::Base.CacheFlags)
522538
name = full_name(ext_to_parent, pkg)
523539
name = is_project_dep ? name : color_string(name, :light_black)
540+
if is_serial_dep
541+
name *= color_string(" (serial)", :light_black)
542+
end
524543
if nconfigs > 1 && !isempty(flags)
525544
config_str = join(flags, " ")
526545
name *= color_string(" `$config_str`", :light_black)
@@ -630,15 +649,28 @@ function _precompilepkgs(pkgs::Vector{String},
630649
end
631650
@debug "precompile: extensions collected"
632651

652+
serial_deps = Base.PkgId[] # packages that are being precompiled in serial
653+
654+
if _from_loading && !isempty(requested_pkgs)
655+
# if called from loading precompilation it may be a package from another environment stack
656+
# where we don't have access to the dep graph, so just add as a single package and do serial
657+
# precompilation of its deps within the job.
658+
for pkg in requested_pkgs # In case loading asks for multiple packages
659+
pkgid = Base.identify_package(pkg)
660+
pkgid === nothing && continue
661+
if !haskey(direct_deps, pkgid)
662+
@debug "precompile: package `$(pkgid)` is outside of the environment, so adding as single package serial job"
663+
direct_deps[pkgid] = Base.PkgId[] # no deps, do them in serial in the job
664+
push!(project_deps, pkgid) # add to project_deps so it doesn't show up in gray
665+
push!(serial_deps, pkgid)
666+
end
667+
end
668+
end
669+
633670
# return early if no deps
634671
if isempty(direct_deps)
635672
if isempty(pkgs)
636673
return
637-
elseif _from_loading
638-
# if called from loading precompilation it may be a package from another environment stack so
639-
# don't error and allow serial precompilation to try
640-
# TODO: actually handle packages from other envs in the stack
641-
return
642674
else
643675
error("No direct dependencies outside of the sysimage found matching $(pkgs)")
644676
end
@@ -846,7 +878,7 @@ function _precompilepkgs(pkgs::Vector{String},
846878
dep, config = pkg_config
847879
loaded = warn_loaded && haskey(Base.loaded_modules, dep)
848880
flags, cacheflags = config
849-
name = describe_pkg(dep, dep in project_deps, flags, cacheflags)
881+
name = describe_pkg(dep, dep in project_deps, dep in serial_deps, flags, cacheflags)
850882
line = if pkg_config in precomperr_deps
851883
string(color_string(" ? ", Base.warn_color()), name)
852884
elseif haskey(failed_deps, pkg_config)
@@ -929,12 +961,13 @@ function _precompilepkgs(pkgs::Vector{String},
929961
if !circular && is_stale
930962
Base.acquire(parallel_limiter)
931963
is_project_dep = pkg in project_deps
964+
is_serial_dep = pkg in serial_deps
932965

933966
# std monitoring
934967
std_pipe = Base.link_pipe!(Pipe(); reader_supports_async=true, writer_supports_async=true)
935968
t_monitor = @async monitor_std(pkg_config, std_pipe; single_requested_pkg)
936969

937-
name = describe_pkg(pkg, is_project_dep, flags, cacheflags)
970+
name = describe_pkg(pkg, is_project_dep, is_serial_dep, flags, cacheflags)
938971
@lock print_lock begin
939972
if !fancyprint && isempty(pkg_queue)
940973
printpkgstyle(io, :Precompiling, something(target[], "packages..."))

0 commit comments

Comments
 (0)