120
120
find_in_path (name:: AbstractString , wd:: AbstractString = pwd ()) =
121
121
find_in_path (String (name), String (wd))
122
122
123
- function find_in_node_path (name:: String , srcpath, node:: Int = 1 )
124
- if myid () == node
125
- return find_in_path (name, srcpath)
126
- else
127
- return remotecall_fetch (find_in_path, node, name, srcpath)
128
- end
129
- end
130
-
131
123
function find_source_file (file:: String )
132
124
(isabspath (file) || isfile (file)) && return file
133
125
file2 = find_in_path (file)
@@ -158,51 +150,9 @@ function _include_from_serialized(path::String)
158
150
end
159
151
160
152
# returns an array of modules loaded, or an Exception that describes why it failed
161
- # and also attempts to load the same file across all nodes (if toplevel_node and myid() == master)
162
153
# and it reconnects the Base.Docs.META
163
- function _require_from_serialized (node:: Int , mod:: Symbol , path_to_try:: String , toplevel_load:: Bool )
164
- local restored = nothing
165
- local content:: Vector{UInt8}
166
- if toplevel_load && myid () == 1 && nprocs () > 1
167
- # broadcast top-level import/using from node 1 (only)
168
- if node == myid ()
169
- content = open (read, path_to_try)
170
- else
171
- content = remotecall_fetch (open, node, read, path_to_try)
172
- end
173
- restored = _include_from_serialized (content)
174
- isa (restored, Exception) && return restored
175
-
176
- results = sizehint! (Vector {Tuple{Int,Any}} (), nprocs ())
177
- @sync for p in procs ()
178
- if p != myid ()
179
- @async begin
180
- result = remotecall_fetch (p) do
181
- let m = try
182
- _include_from_serialized (content)
183
- catch ex
184
- isa (ex, Exception) ? ex : ErrorException (string (ex))
185
- end
186
- isa (m, Exception) ? m : nothing
187
- end
188
- end
189
- push! (results, (p, result))
190
- end
191
- end
192
- end
193
- for (id, m) in results
194
- if m != = nothing
195
- warn (" Node state is inconsistent: node $id failed to load cache from $path_to_try . Got:" )
196
- warn (m, prefix= " WARNING: " )
197
- end
198
- end
199
- elseif node == myid ()
200
- restored = _include_from_serialized (path_to_try)
201
- else
202
- content = remotecall_fetch (open, node, read, path_to_try)
203
- restored = _include_from_serialized (content)
204
- end
205
-
154
+ function _require_from_serialized (mod:: Symbol , path_to_try:: String )
155
+ restored = _include_from_serialized (path_to_try)
206
156
if ! isa (restored, Exception)
207
157
for M in restored:: Vector{Any}
208
158
if isdefined (M, Base. Docs. META)
@@ -216,24 +166,13 @@ end
216
166
# returns `true` if require found a precompile cache for this mod, but couldn't load it
217
167
# returns `false` if the module isn't known to be precompilable
218
168
# returns the set of modules restored if the cache load succeeded
219
- function _require_search_from_serialized (node:: Int , mod:: Symbol , sourcepath:: String , toplevel_load:: Bool )
220
- if node == myid ()
221
- paths = find_all_in_cache_path (mod)
222
- else
223
- paths = @fetchfrom node find_all_in_cache_path (mod)
224
- end
225
-
169
+ function _require_search_from_serialized (mod:: Symbol , sourcepath:: String )
170
+ paths = find_all_in_cache_path (mod)
226
171
for path_to_try in paths:: Vector{String}
227
- if node == myid ()
228
- if stale_cachefile (sourcepath, path_to_try)
229
- continue
230
- end
231
- else
232
- if @fetchfrom node stale_cachefile (sourcepath, path_to_try)
233
- continue
234
- end
172
+ if stale_cachefile (sourcepath, path_to_try)
173
+ continue
235
174
end
236
- restored = _require_from_serialized (node, mod, path_to_try, toplevel_load )
175
+ restored = _require_from_serialized (mod, path_to_try)
237
176
if isa (restored, Exception)
238
177
if isa (restored, ErrorException) && endswith (restored. msg, " uuid did not match cache file." )
239
178
# can't use this cache due to a module uuid mismatch,
@@ -270,15 +209,11 @@ const _track_dependencies = Ref(false) # set this to true to track the list of f
270
209
function _include_dependency (_path:: AbstractString )
271
210
prev = source_path (nothing )
272
211
if prev === nothing
273
- if myid () == 1
274
- path = abspath (_path)
275
- else
276
- path = joinpath (remotecall_fetch (abspath, 1 , " ." ), _path)
277
- end
212
+ path = abspath (_path)
278
213
else
279
214
path = joinpath (dirname (prev), _path)
280
215
end
281
- if myid () == 1 && _track_dependencies[]
216
+ if _track_dependencies[]
282
217
push! (_require_dependencies, (path, mtime (path)))
283
218
end
284
219
return path, prev
@@ -334,52 +269,31 @@ order to throw an error if Julia attempts to precompile it.
334
269
using `__precompile__()`. Failure to do so can result in a runtime error when loading the module.
335
270
"""
336
271
function __precompile__ (isprecompilable:: Bool = true )
337
- if (myid () == 1 &&
338
- JLOptions (). use_compilecache != 0 &&
272
+ if (JLOptions (). use_compilecache != 0 &&
339
273
isprecompilable != (0 != ccall (:jl_generating_output , Cint, ())) &&
340
- ! (isprecompilable && toplevel_load:: Bool ))
274
+ ! (isprecompilable && toplevel_load[] ))
341
275
throw (PrecompilableError (isprecompilable))
342
276
end
343
277
end
344
278
345
- function require_modname (name:: AbstractString )
346
- # This function can be deleted when the deprecation for `require`
347
- # is deleted.
348
- # While we could also strip off the absolute path, the user may be
349
- # deliberately directing to a different file than what got
350
- # cached. So this takes a conservative approach.
351
- if Bool (JLOptions (). use_compilecache)
352
- if endswith (name, " .jl" )
353
- tmp = name[1 : end - 3 ]
354
- for prefix in LOAD_CACHE_PATH
355
- path = joinpath (prefix, tmp* " .ji" )
356
- if isfile (path)
357
- return tmp
358
- end
359
- end
360
- end
361
- end
362
- return name
363
- end
364
-
365
279
"""
366
280
reload(name::AbstractString)
367
281
368
282
Force reloading of a package, even if it has been loaded before. This is intended for use
369
283
during package development as code is modified.
370
284
"""
371
285
function reload (name:: AbstractString )
372
- if isfile (name) || contains (name,Filesystem . path_separator )
286
+ if contains (name, Filesystem . path_separator ) || contains (name, " . " )
373
287
# for reload("path/file.jl") just ask for include instead
374
288
error (" use `include` instead of `reload` to load source files" )
375
289
else
376
290
# reload("Package") is ok
377
- require (Symbol (require_modname ( name) ))
291
+ require (Symbol (name))
378
292
end
379
293
end
380
294
381
295
# require always works in Main scope and loads files from node 1
382
- toplevel_load = true
296
+ const toplevel_load = Ref ( true )
383
297
384
298
"""
385
299
require(module::Symbol)
@@ -401,8 +315,19 @@ all platforms, including those with case-insensitive filesystems like macOS and
401
315
Windows.
402
316
"""
403
317
function require (mod:: Symbol )
404
- _require (mod:: Symbol )
405
- # After successfully loading notify downstream consumers
318
+ _require (mod)
319
+ # After successfully loading, notify downstream consumers
320
+ if toplevel_load[] && myid () == 1 && nprocs () > 1
321
+ # broadcast top-level import/using from node 1 (only)
322
+ @sync for p in procs ()
323
+ p == 1 && continue
324
+ @async remotecall_wait (p) do
325
+ if ! isbindingresolved (Main, mod) || ! isdefined (Main, mod)
326
+ _require (mod)
327
+ end
328
+ end
329
+ end
330
+ end
406
331
for callback in package_callbacks
407
332
invokelatest (callback, mod)
408
333
end
@@ -415,7 +340,7 @@ function _require(mod::Symbol)
415
340
_track_dependencies[] = false
416
341
DEBUG_LOADING[] = haskey (ENV , " JULIA_DEBUG_LOADING" )
417
342
418
- global toplevel_load
343
+ # handle recursive calls to require
419
344
loading = get (package_locks, mod, false )
420
345
if loading != = false
421
346
# load already in progress for this module
@@ -424,20 +349,20 @@ function _require(mod::Symbol)
424
349
end
425
350
package_locks[mod] = Condition ()
426
351
427
- last = toplevel_load:: Bool
352
+ last = toplevel_load[]
428
353
try
429
- toplevel_load = false
354
+ toplevel_load[] = false
430
355
# perform the search operation to select the module file require intends to load
431
356
name = string (mod)
432
- path = find_in_node_path (name, nothing , 1 )
357
+ path = find_in_path (name, nothing )
433
358
if path === nothing
434
359
throw (ArgumentError (" Module $name not found in current path.\n Run `Pkg.add(\" $name \" )` to install the $name package." ))
435
360
end
436
361
437
362
# attempt to load the module file via the precompile cache locations
438
363
doneprecompile = false
439
364
if JLOptions (). use_compilecache != 0
440
- doneprecompile = _require_search_from_serialized (1 , mod, path, last )
365
+ doneprecompile = _require_search_from_serialized (mod, path)
441
366
if ! isa (doneprecompile, Bool)
442
367
return # success
443
368
end
@@ -457,10 +382,10 @@ function _require(mod::Symbol)
457
382
end
458
383
459
384
if doneprecompile === true || JLOptions (). incremental != 0
460
- # spawn off a new incremental pre-compile task from node 1 for recursive `require` calls
385
+ # spawn off a new incremental pre-compile task for recursive `require` calls
461
386
# or if the require search declared it was pre-compiled before (and therefore is expected to still be pre-compilable)
462
387
cachefile = compilecache (mod)
463
- m = _require_from_serialized (1 , mod, cachefile, last )
388
+ m = _require_from_serialized (mod, cachefile)
464
389
if isa (m, Exception)
465
390
warn (" The call to compilecache failed to create a usable precompiled cache file for module $name . Got:" )
466
391
warn (m, prefix= " WARNING: " )
@@ -473,49 +398,35 @@ function _require(mod::Symbol)
473
398
# just load the file normally via include
474
399
# for unknown dependencies
475
400
try
476
- # include on node 1 first to check for PrecompilableErrors
477
- Base. include_from_node1 (Main, path)
478
-
479
- if last && myid () == 1 && nprocs () > 1
480
- # broadcast top-level import/using from node 1 (only)
481
- @sync begin
482
- for p in filter (x -> x != 1 , procs ())
483
- @async remotecall_fetch (p) do
484
- Base. include_from_node1 (Main, path)
485
- nothing
486
- end
487
- end
488
- end
489
- end
401
+ Base. include_relative (Main, path)
490
402
catch ex
491
403
if doneprecompile === true || JLOptions (). use_compilecache == 0 || ! precompilableerror (ex, true )
492
404
rethrow () # rethrow non-precompilable=true errors
493
405
end
494
406
# the file requested `__precompile__`, so try to build a cache file and use that
495
407
cachefile = compilecache (mod)
496
- m = _require_from_serialized (1 , mod, cachefile, last )
408
+ m = _require_from_serialized (mod, cachefile)
497
409
if isa (m, Exception)
498
410
warn (m, prefix= " WARNING: " )
499
411
# TODO : disable __precompile__(true) error and do normal include instead of error
500
412
error (" Module $mod declares __precompile__(true) but require failed to create a usable precompiled cache file." )
501
413
end
502
414
end
503
415
finally
504
- toplevel_load = last
416
+ toplevel_load[] = last
505
417
loading = pop! (package_locks, mod)
506
418
notify (loading, all= true )
507
419
_track_dependencies[] = old_track_dependencies
508
420
end
509
421
nothing
510
422
end
511
423
512
- # remote/parallel load
424
+ # relative-path load
513
425
514
426
"""
515
427
include_string(m::Module, code::AbstractString, filename::AbstractString="string")
516
428
517
- Like `include`, except reads code from the given string rather than from a file. Since there
518
- is no file path involved, no path processing or fetching from node 1 is done.
429
+ Like `include`, except reads code from the given string rather than from a file.
519
430
"""
520
431
include_string (m:: Module , txt:: String , fname:: String ) =
521
432
ccall (:jl_load_file_string , Any, (Ptr{UInt8}, Csize_t, Cstring, Any),
@@ -543,29 +454,22 @@ function source_dir()
543
454
p === nothing ? pwd () : dirname (p)
544
455
end
545
456
546
- include_from_node1 (mod:: Module , path:: AbstractString ) = include_from_node1 (mod, String (path))
547
- function include_from_node1 (mod:: Module , _path:: String )
457
+ include_relative (mod:: Module , path:: AbstractString ) = include_relative (mod, String (path))
458
+ function include_relative (mod:: Module , _path:: String )
548
459
path, prev = _include_dependency (_path)
549
460
tls = task_local_storage ()
550
461
tls[:SOURCE_PATH ] = path
551
462
local result
552
463
try
553
- if myid ()== 1
554
- # sleep a bit to process file requests from other nodes
555
- nprocs ()> 1 && sleep (0.005 )
556
- result = Core. include (mod, path)
557
- nprocs ()> 1 && sleep (0.005 )
558
- else
559
- result = include_string (mod, remotecall_fetch (readstring, 1 , path), path)
560
- end
464
+ result = Core. include (mod, path)
561
465
finally
562
466
if prev === nothing
563
467
delete! (tls, :SOURCE_PATH )
564
468
else
565
469
tls[:SOURCE_PATH ] = prev
566
470
end
567
471
end
568
- result
472
+ return result
569
473
end
570
474
571
475
"""
574
478
Evaluate the contents of the input source file into module `m`. Returns the result
575
479
of the last evaluated expression of the input file. During including, a task-local include
576
480
path is set to the directory containing the file. Nested calls to `include` will search
577
- relative to that path. All paths refer to files on node 1 when running in parallel, and
578
- files will be fetched from node 1. This function is typically used to load source
481
+ relative to that path. This function is typically used to load source
579
482
interactively, or to combine files in packages that are broken into multiple source files.
580
483
"""
581
484
include # defined in sysimg.jl
@@ -655,7 +558,6 @@ This can be used to reduce package load times. Cache files are stored in
655
558
for important notes.
656
559
"""
657
560
function compilecache (name:: String )
658
- myid () == 1 || error (" can only precompile from node 1" )
659
561
# decide where to get the source file from
660
562
path = find_in_path (name, nothing )
661
563
path === nothing && throw (ArgumentError (" $name not found in path" ))
@@ -777,7 +679,7 @@ function stale_cachefile(modpath::String, cachefile::String)
777
679
continue
778
680
end
779
681
name = string (mod)
780
- path = find_in_node_path (name, nothing , 1 )
682
+ path = find_in_path (name, nothing )
781
683
if path === nothing
782
684
return true # Won't be able to fullfill dependency
783
685
end
0 commit comments