# Determining source of failure to precompile when using PrecompileTools

**URL:** https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705
**Category:** General Usage
**Tags:** precompilation
**Created:** [September 9, 2023, 6:41pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705 "2023-09-09T18:41:55Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![pluie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pluie/32/35949_2.png) [@pluie](https://discourse.julialang.org/u/pluie)
#### Post date: [September 9, 2023, 6:41pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/1 "2023-09-09T18:41:55Z")

</div>

I have a module as defined below.

```julia
module MyModule

using PrecompileTools

export TV

@compile_workload begin
     include("foo.jl") #Defines TV
end 

end

```

When I run `using MyModule`, I have printouts that indicate that the contents of foo.jl run successfully as part of the include process. However, once `include("foo.jl")` finishes, I receive the following error.

```julia
ERROR: Failed to precompile MyModule [top-level] to "/Users/pluie/.julia/compiled/v1.9/jl_Dr5RS9".
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool)
    @ Base ./loading.jl:2300
  [3] compilecache
    @ ./loading.jl:2167 [inlined]
  [4] _require(pkg::Base.PkgId, env::String)
    @ Base ./loading.jl:1805
  [5] _require_prelocked(uuidkey::Base.PkgId, env::String)
    @ Base ./loading.jl:1660
  [6] macro expansion
    @ ./loading.jl:1648 [inlined]
  [7] macro expansion
    @ ./lock.jl:267 [inlined]
  [8] require(into::Module, mod::Symbol)
    @ Base ./loading.jl:1611
  [9] top-level scope
    @ ./timing.jl:273 [inlined]
 [10] top-level scope
    @ ./REPL[2]:0

```

I have confirmed that `include("foo.jl")` runs without error separate from its use in this module. Does anyone have an idea of what the source of this error may be or what I can do to produce a more meaningful error description? TIA.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [September 10, 2023, 2:54am UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/2 "2023-09-10T02:54:03Z")

</div>

> [@pluie](#):
>
> When I run `using MyModule`, I have printouts that indicate that the contents of foo.jl run successfully as part of the include process.

I’ve never seen `@compile_workload` surround an `include` call before, I would’ve expected `@compile_workload` to precompile the `include` call, not run it, so `TV` wouldn’t be assigned to. Does it work if you remove the `@compile_workload begin` block and just directly run the `include`?

---

<div class="post-metadata">

### Author: ![pluie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pluie/32/35949_2.png) [@pluie](https://discourse.julialang.org/u/pluie)
#### Post date: [September 10, 2023, 3:50pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/3 "2023-09-10T15:50:05Z")

</div>

Hi Benny, thank you for your response.

I have `@compile_workload` around an `include` call in other modules and it works fine. However, I went ahead and tried it without the `@compile_workload`. I got the same error.

Any other suggestions?

Edit: I should add that what happens in `include("foo.jl")` requires a lot of memory. My guess is the “save to disk” portion of pre-compilation is failing, but it would be helpful to verify this and better understand what the limits are.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [September 10, 2023, 11:21pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/4 "2023-09-10T23:21:35Z")

</div>

> [@pluie](#):
>
> I have `@compile_workload` around an `include` call in other modules and it works fine. However, I went ahead and tried it without the `@compile_workload`. I got the same error.

Good to know, and it rules out `@compile_workload` specifically. The error seems clear that it’s a precompilation failure, but maybe you could make certain by turning it off in a new process and seeing if the import works

> It is sometimes helpful during module development to turn off incremental precompilation. The command line flag `--compiled-modules={yes|no}` enables you to toggle module precompilation on and off. When Julia is started with `--compiled-modules=no` the serialized modules in the compile cache are ignored when loading modules and module dependencies. More fine-grained control is available with `--pkgimages=no` , which suppresses only native-code storage during precompilation. `Base.compilecache` can still be called manually. The state of this command line flag is passed to `Pkg.build` to disable automatic precompilation triggering when installing, updating, and explicitly building packages.

> [@pluie](#):
>
> `include("foo.jl")` requires a lot of memory. My guess is the “save to disk” portion of pre-compilation is failing

I’ve never heard of a memory limit, and since disk is usually much larger than RAM I would assume (with no basis) that if your RAM can handle it then it should be cacheable. But there are some things that [should be initialized with each runtime instead of precompiled and cached](https://docs.julialang.org/en/v1/manual/modules/#Module-initialization-and-precompilation), but it’s not clear which, if any, would throw the error you have. It might be crucial for people to see what foo.jl does.

---

<div class="post-metadata">

### Author: ![pluie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pluie/32/35949_2.png) [@pluie](https://discourse.julialang.org/u/pluie)
#### Post date: [September 11, 2023, 12:22pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/5 "2023-09-11T12:22:44Z")

</div>

I started Julia using `julia --compiled-modules=no` and then executed `using MyModule`. It completed running without error.

The purpose of `foo.jl` is to `include` several functions (formed from `Symbolics.build_function` in a separate process), execute them for the first time, then save their handle to an array (`TV`) to be used later.

```julia
include("indicesPerm.jl")
include("symLists.jl")

using Symbolics

ord = 4

## include all files
(goodSet,sumIJKM) = type1Ind(ord)

TV = []
println("start include")

rstWVLxyzDict,rstDictBuild,rCoefSyms,sCoefSyms,tCoefSyms=dictSyms(goodSet,sumIJKM,ord+1)
for ii= 1:length(rstDictBuild)
	fname = string("solns/order$(ord)/",rstDictBuild[ii],".jl")
	if isfile(fname)
		println(fname)
		fh2 = include(fname)
		m = first(methods(fh2))
		x00 = zeros(m.nargs-1)
		fh2(x00...);
		push!(TV, fh2)
	end
end

```

I’ll note that I use a similar `foo.jl` for a smaller set of functions (also found from using `Symbolics.build_function`), which works in `MyModule` without an issue. That’s what has led me to believe it is a memory issue.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [September 11, 2023, 11:51pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/6 "2023-09-11T23:51:01Z")

</div>

> [@pluie](#):
>
> I’ll note that I use a similar `foo.jl` for a smaller set of functions (also found from using `Symbolics.build_function`), which works in `MyModule` without an issue.

If it’s the exact same code but it just iterates over fewer `rstDictBuild`, then yes it’s reasonable to conclude it’s a memory problem. It’d be nice to find out how much memory gets used up throughout these processes (without or with `@compile_workload`, small or large set of functions), to verify if the error is thrown right after hitting some memory limit. Logging `Sys.free_memory()`, `Sys.total_memory()`, and `Sys.total_physical_memory()` before, throughout, and afterwards could help, but there might be easier ways of monitoring memory usage.

---

<div class="post-metadata">

### Author: ![pluie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pluie/32/35949_2.png) [@pluie](https://discourse.julialang.org/u/pluie)
#### Post date: [September 13, 2023, 9:35am UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/7 "2023-09-13T09:35:53Z")

</div>

The other versions of `MyModule` that include `foo.jl` use a smaller, different set of functions defined by `rstDictBuild`.

I re-ran `using MyModule` with the logging as you suggested. At the beginning (before `@compile_workload`) the total memory and total physical memory were both 17179869184. The free memory was 131940352. The free memory generally decreased throughout the include process (sometimes it increased between iterations but only slightly). At the end, the free memory was 272760832. This time during the save to disk process, a segmentation fault occurred (rather than the error I have previously shown).

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [September 13, 2023, 11:31am UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/8 "2023-09-13T11:31:47Z")

</div>

Am I reading this right? Your free memory starts at 131940352 (which is a _really_ low 0.768% of your total memory of 16 GiB), decreases throughout the `include("foo.jl")`, but then jumps up to a higher 272760832 (which would indicate the GC ran a cycle). And getting a segfault instead of a precompile failure error when the only change is printing the amount of free memory over time, it doesn’t seem like it’s as simple as just running out of working memory.

---

<div class="post-metadata">

### Author: ![pluie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pluie/32/35949_2.png) [@pluie](https://discourse.julialang.org/u/pluie)
#### Post date: [September 13, 2023, 12:17pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/9 "2023-09-13T12:17:03Z")

</div>

Yes, you are reading that correctly.

---

<div class="post-metadata">

### Author: ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)
#### Post date: [September 13, 2023, 12:44pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/10 "2023-09-13T12:44:13Z")

</div>

First, what’s your exact Julia version? It would be important to know if someone wants to figure out what those line numbers in your stacktrace correspond to.

Second, is there really nothing more to that error message than what you showed?

Third, that’s an unconventional (and possibly creative) use of PrecompileTools. I’m not sure what I think about it; it does make it hard to know what tasks will be precompiled and which ones won’t. Typically I leave definitions (methods, consts, etc) out of the `@compile_workload` and just run code from within the `@compile_workload` block. The only thing I see now that might be “wrong” with this approach is that you may cache more than you really want: for example, if any of the code in `foo.jl` is generated by metaprogramming (macros, etc.), then you’ll also be caching all the code that’s only needed to _define_ the methods. (Typically, you only want to cache the items that the package needs to _run_.) This may bloat your cache files and increase loading times somewhat.

---

<div class="post-metadata">

### Author: ![pluie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pluie/32/35949_2.png) [@pluie](https://discourse.julialang.org/u/pluie)
#### Post date: [September 13, 2023, 1:05pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/11 "2023-09-13T13:05:37Z")

</div>

> [@tim.holy](#):
>
> First, what’s your exact Julia version? It would be important to know if someone wants to figure out what those line numbers in your stacktrace correspond to.

Version 1.9.2

> [@tim.holy](#):
>
> Second, is there really nothing more to that error message than what you showed?

Correct, I pasted the entirety of the error message.

> [@tim.holy](#):
>
> Third, that’s an unconventional (and possibly creative) use of PrecompileTools. I’m not sure what I think about it; it does make it hard to know what tasks will be precompiled and which ones won’t. Typically I leave definitions (methods, consts, etc) out of the `@compile_workload` and just run code from within the `@compile_workload` block. The only thing I see now that might be “wrong” with this approach is that you may cache more than you really want: for example, if any of the code in `foo.jl` is generated by metaprogramming (macros, etc.), then you’ll also be caching all the code that’s only needed to _define_ the methods. (Typically, you only want to cache the items that the package needs to _run_ .) This may bloat your cache files and increase loading times somewhat.

`foo.jl` does not use any metaprogramming (if I understand that correctly). The point of `foo.jl` is just to include and initialize the functions that were created previously by `Symbolics.build_function`, whose filenames are recreated by using `rstDictBuild`. The `.jl` files included and initialized are just mathematical expressions.

---

<div class="post-metadata">

### Author: ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)
#### Post date: [September 13, 2023, 1:27pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/12 "2023-09-13T13:27:43Z")

</div>

So `loading.jl: 2300` likely corresponds to this line: [https://github.com/JuliaLang/julia/blob/bed2cd540a11544ed4be381d471bbf590f0b745e/base/loading.jl#L2300](https://github.com/JuliaLang/julia/blob/bed2cd540a11544ed4be381d471bbf590f0b745e/base/loading.jl#L2300)

(The `release-1.9` branch now tracks 1.9.3, but hopefully it’s close to 1.9.2.) That indeed is not a very informative error.

Since we don’t have `foo.jl`, you might have to debug this yourself. Using `Revise.track(Base)`, you should be able to make changes that, e.g., print out more information about that process `p` and/or the command that generated it: [https://github.com/JuliaLang/julia/blob/572fa5055ecb709edd3d227a10b46549f82b72b2/base/loading.jl#L2263-L2279](https://github.com/JuliaLang/julia/blob/572fa5055ecb709edd3d227a10b46549f82b72b2/base/loading.jl#L2263-L2279).

But first:

> This time during the save to disk process, a segmentation fault occurred (rather than the error I have previously shown).

It would also be good to see the segfault stacktrace, it may contain the key to the issue.

---

<div class="post-metadata">

### Author: ![pluie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pluie/32/35949_2.png) [@pluie](https://discourse.julialang.org/u/pluie)
#### Post date: [September 13, 2023, 1:37pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/13 "2023-09-13T13:37:32Z")

</div>

I’ll give `Revise.track(Base)` a go. But yes, unfortunately, the files `foo.jl` includes and initializes are too many and too large to include on this post.

> [@tim.holy](#):
>
> It would also be good to see the segfault stacktrace, it may contain the key to the issue.

```julia
[93082] signal (11.2): Segmentation fault: 11
in expression starting at REPL[4]:1
jl_crc32c at /Users/pluie/.julia/juliaup/julia-1.9.2+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
jl_restore_package_image_from_stream at /Users/pluie/.julia/juliaup/julia-1.9.2+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
Allocations: 7297647 (Pool: 7295376; Big: 2271); GC: 11
zsh: segmentation fault julia

```

---

<div class="post-metadata">

### Author: ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)
#### Post date: [September 13, 2023, 2:57pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/14 "2023-09-13T14:57:09Z")

</div>

The segfault occurs during CRC computation when a module is being loaded. That’s really surprising. Can you open a Julia issue? There may not be a lot we can do about this without more detail about what’s in `foo.jl`, but if there’s any way you can do a `make debug` build-from-source, that would greatly improve the quality of stack traces and the ability to guess what’s gone wrong.

---

<div class="post-metadata">

### Author: ![pluie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pluie/32/35949_2.png) [@pluie](https://discourse.julialang.org/u/pluie)
#### Post date: [September 13, 2023, 3:13pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/15 "2023-09-13T15:13:56Z")

</div>

Sure, I can open a Julia issue. Are you suggesting opening it with the same information I have here?

Unfortunately, `foo.jl` calls over 800 `.jl` files. Even just cutting those files in half results in no error being thrown.

Sorry, but what are you suggesting I do a `make debug` build-from-source on?

---

<div class="post-metadata">

### Author: ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)
#### Post date: [September 13, 2023, 4:42pm UTC](https://discourse.julialang.org/t/determining-source-of-failure-to-precompile-when-using-precompiletools/103705/16 "2023-09-13T16:42:32Z")

</div>

Check out the julia repo and build it locally (see [https://github.com/JuliaLang/julia/blob/master/README.md#building-julia](https://github.com/JuliaLang/julia/blob/master/README.md#building-julia)). But instead of running `make`, run `make debug`. Supply full stacktraces of any Julia errors or segfaults. You can link back to this discussion for any further info.
