-
Notifications
You must be signed in to change notification settings - Fork 32
/
install.jl
134 lines (109 loc) · 4.64 KB
/
install.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
function replace_libblas(base_dir, name)
file = joinpath(base_dir, "build_h.jl")
lines = readlines(file)
libblas_idx = findfirst(match.(r"const libblas_name", lines) .!= nothing)
liblapack_idx = findfirst(match.(r"const liblapack_name", lines) .!= nothing)
useblas64_idx = findfirst(match.(r"USE_BLAS64", lines) .!= nothing)
revertline = lines[useblas64_idx] #save to revert to previously set variable
@assert libblas_idx !== nothing && liblapack_idx !== nothing
lines[libblas_idx] = "const libblas_name = $(repr(name))"
lines[liblapack_idx] = "const liblapack_name = $(repr(name))"
if useblas64_idx != nothing
if USEBLAS64
lines[useblas64_idx] = "const USE_BLAS64 = true"
else
lines[useblas64_idx] = "const USE_BLAS64 = false"
end
end
write(file, string(join(lines, '\n'), '\n'))
return revertline
end
function revert_blas64(base_dir, name,revertline)
file = joinpath(base_dir, "build_h.jl")
lines = readlines(file)
useblas64_idx = findfirst(match.(r"USE_BLAS64", lines) .!= nothing)
lines[useblas64_idx] = revertline
write(file, string(join(lines, '\n'), '\n'))
end
# Used to insert a load of MKL.jl before the stdlibs and run the __init__ explicitly
# since these need to have been run when LinearAlgebra loads and determines
# what BLAS vendor is used.
# We also have to push to LOAD_PATH since at this stage only @stdlibs
# is in LOAD_PATH and MKL.jl can thus not be found.
const MKL_PAYLOAD = """
# START MKL INSERT
pushfirst!(LOAD_PATH, "@v#.#")
pushfirst!(LOAD_PATH, "@")
MKL = Base.require(Base, :MKL)
MKL.MKL_jll.__init__()
MKL.__init__()
popfirst!(LOAD_PATH)
popfirst!(LOAD_PATH)
# END MKL INSERT"""
const MKL_PAYLOAD_LINES = split(MKL_PAYLOAD, '\n')
function insert_MKL_load(base_dir)
file = joinpath(base_dir, "sysimg.jl")
@info "Splicing in code to load MKL in $(file)"
lines = readlines(file)
# Be idempotent
if MKL_PAYLOAD_LINES[1] in lines
return
end
# After this the stdlibs get included, so insert MKL to be loaded here
start_idx = findfirst(match.(r"Base._track_dependencies\[\] = true", lines) .!= nothing)
splice!(lines, (start_idx + 1):start_idx, MKL_PAYLOAD_LINES)
write(file, string(join(lines, '\n'), '\n'))
return
end
function remove_MKL_load(base_dir)
file = joinpath(base_dir, "sysimg.jl")
@info "Removing code to load MKL in $(file)"
lines = readlines(file)
start_idx = findfirst(==(MKL_PAYLOAD_LINES[1]), lines)
end_idx = findfirst(==(MKL_PAYLOAD_LINES[end]), lines)
if start_idx === nothing || end_idx === nothing
return
end
splice!(lines, start_idx:end_idx)
write(file, string(join(lines, '\n'), '\n'))
return
end
function get_precompile_statments_file()
jl_dev_ver = length(VERSION.prerelease) == 2 && (VERSION.prerelease)[1] == "DEV" # test if running nightly/unreleased version
jl_gh_tag = jl_dev_ver ? "master" : "release-$(VERSION.major).$(VERSION.minor)"
prec_jl_url = "https://raw.githubusercontent.com/JuliaLang/julia/$jl_gh_tag/contrib/generate_precompile.jl"
@info "getting precompile script from: $prec_jl_url"
prec_jl_fn = tempname()
download(prec_jl_url, prec_jl_fn)
prec_jl_content = read(prec_jl_fn, String)
# PackageCompiler.jl already inits stdio and double initing it leads to bad things
write(prec_jl_fn, replace(prec_jl_content, "Base.reinit_stdio()" => "# Base.reinit_stdio()"))
return prec_jl_fn
end
enable_mkl_startup() = change_blas_library(MKL_jll.libmkl_rt)
enable_openblas_startup() = change_blas_library("libopenblas")
function change_blas_library(libblas)
# First, we need to modify a few files in Julia's base directory
base_dir = joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "base")
if libblas == "libopenblas"
if Sys.WORD_SIZE == 64
libblas = "$(libblas)64_"
end
remove_MKL_load(base_dir)
else
insert_MKL_load(base_dir)
end
# Replace definitions of `libblas_name`, etc.. to point to MKL or OpenBLAS
revertline = replace_libblas(base_dir, libblas)
# Next, build a new system image
# We don't want to load PackageCompiler in top level scope because
# we will put MKL.jl in the sysimage and having PackageCompiler loaded
# means it will also be put there
@eval begin
using PackageCompiler
PackageCompiler.create_sysimage(; incremental=false, replace_default=true,
script=get_precompile_statments_file())
end
# revert const USE_BLAS64 to initial state
revert_blas64(base_dir,libblas,revertline)
end