Enzyme.jl icon indicating copy to clipboard operation
Enzyme.jl copied to clipboard

Add example of workgroupsize breaking Enzyme

Open vchuravy opened this issue 1 month ago • 10 comments

julia> Enzyme.autodiff(Forward, mul_caller_static, Duplicated(A, dA), Duplicated(1.2, 1.0))
C = max(64 ÷ prod(size(A)), 1) = 1
ERROR: 
No forward mode derivative found for jl_get_builtin_fptr
 at context:   %15 = call {} addrspace(10)* ({} addrspace(10)*, {} addrspace(10)**, i32)* @jl_get_builtin_fptr({} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 139935955039648 to {}*) to {} addrspace(10)*)) #20, !dbg !53

Stacktrace:
 [1] construct
   @ ~/.julia/packages/KernelAbstractions/X5fk1/src/KernelAbstractions.jl:779
 [2] _mul!
   @ ~/.julia/packages/KernelAbstractions/X5fk1/src/macros.jl:61
 [3] mul!
   @ ~/.julia/packages/KernelAbstractions/X5fk1/src/macros.jl:68
 [4] mul_caller_static
   @ ./REPL[11]:4


Stacktrace:
  [1] construct
    @ ~/.julia/packages/KernelAbstractions/X5fk1/src/KernelAbstractions.jl:779 [inlined]
  [2] _mul!
    @ ~/.julia/packages/KernelAbstractions/X5fk1/src/macros.jl:61 [inlined]
  [3] mul!
    @ ~/.julia/packages/KernelAbstractions/X5fk1/src/macros.jl:68 [inlined]
  [4] mul_caller_static
    @ ./REPL[11]:4 [inlined]
  [5] fwddiffejulia_mul_caller_static_23728wrap
    @ ./REPL[11]:0
  [6] macro expansion
    @ ~/src/Enzyme/src/compiler.jl:5887 [inlined]
  [7] enzyme_call
    @ ~/src/Enzyme/src/compiler.jl:5421 [inlined]
  [8] ForwardModeThunk
    @ ~/src/Enzyme/src/compiler.jl:5323 [inlined]
  [9] autodiff
    @ ~/src/Enzyme/src/Enzyme.jl:673 [inlined]
 [10] autodiff
    @ ~/src/Enzyme/src/Enzyme.jl:562 [inlined]
 [11] autodiff(::ForwardMode{…}, ::typeof(mul_caller_static), ::Duplicated{…}, ::Duplicated{…})
    @ Enzyme ~/src/Enzyme/src/Enzyme.jl:534
 [12] top-level scope
    @ REPL[12]:1
Some type information was truncated. Use `show(err)` to see complete types.

vchuravy avatar Nov 08 '25 00:11 vchuravy

what exactly is jl_get_builtin_fptr

and can we define a relevant custom derivative handler for it?

it's come up a few times

wsmoses avatar Nov 08 '25 00:11 wsmoses

per https://github.com/JuliaLang/julia/pull/55803

it looks like its a different way of throwing a method error?

which would explain why the unreachable thing happened?

wsmoses avatar Nov 08 '25 00:11 wsmoses

The primal code doesn't throw, so it might be something that is emitted as a fallback.

Now I have a small enough example that I can stare at Monday

vchuravy avatar Nov 08 '25 00:11 vchuravy

Benchmark Results

main a81b1bc388ff7d... main / a81b1bc388ff7d...
basics/make_zero/namedtuple 0.053 ± 0.0025 μs 0.0523 ± 0.0027 μs 1.01 ± 0.07
basics/make_zero/struct 0.285 ± 0.0082 μs 0.271 ± 0.0068 μs 1.05 ± 0.04
basics/overhead 4.03 ± 0.001 ns 4.64 ± 0.01 ns 0.868 ± 0.0019
basics/remake_zero!/namedtuple 0.234 ± 0.0072 μs 0.235 ± 0.0061 μs 0.995 ± 0.04
basics/remake_zero!/struct 0.234 ± 0.0066 μs 0.248 ± 0.0073 μs 0.943 ± 0.039
fold_broadcast/multidim_sum_bcast/1D 10.3 ± 0.37 μs 10.3 ± 0.26 μs 1 ± 0.044
fold_broadcast/multidim_sum_bcast/2D 12.2 ± 0.29 μs 12.1 ± 0.25 μs 1 ± 0.032
time_to_load 1.01 ± 0.0046 s 1.02 ± 0.0044 s 0.993 ± 0.0062

Benchmark Plots

A plot of the benchmark results has been uploaded as an artifact at https://github.com/EnzymeAD/Enzyme.jl/actions/runs/19854289811/artifacts/4735610205.

github-actions[bot] avatar Nov 10 '25 18:11 github-actions[bot]

@wsmoses with Cthulhu:

; │┌ @ /home/vchuravy/.julia/packages/KernelAbstractions/X5fk1/src/macros.jl:61 within `_mul!`
; ││┌ @ /home/vchuravy/.julia/packages/KernelAbstractions/X5fk1/src/KernelAbstractions.jl:779 within `construct`
     %12 = call ptr @jl_get_builtin_fptr(ptr nonnull @"+Core.#_compute_sparams#20514.jit")
builtins.c
2181:JL_CALLABLE(jl_f__compute_sparams)
2183:    JL_NARGSV(_compute_sparams, 1);
2185:    JL_TYPECHK(_compute_sparams, method, (jl_value_t*)m);

But the error that Enzyme gives only the pointer:

  Enzyme: jl_call calling convention not implemented in forward for   %15 = call nonnull "enzyme_type"="{[-1]:Pointer}" {} addrspace(10)* ({} addrspace(10)* ({} addrspace(10)*, {} addrspace(10)**, i32)*, {} addrspace(10)*, ...) @julia.call({} addrspace(10)* ({} addrspace(10)*, {} addrspace(10)**, i32)* %14, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 137585066522080 to {}*) to {} addrspace(10)*), {} addrspace(10)* addrspacecast ({}* inttoptr (i64 137578224249072 to {}*) to {} addrspace(10)*), {} addrspace(10)* addrspacecast ({}* inttoptr (i64 137578224248752 to {}*) to {} addrspace(10)*), {} addrspace(10)* addrspacecast ({}* inttoptr (i64 137577969042512 to {}*) to {} addrspace(10)*), {} addrspace(10)* nonnull %13, {} addrspace(10)* addrspacecast ({}* inttoptr (i64 137578224222272 to {}*) to {} addrspace(10)*), {} addrspace(10)* addrspacecast ({}* inttoptr (i64 137580755331088 to {}*) to {} addrspace(10)*)) #17, !dbg !48

vchuravy avatar Nov 10 '25 21:11 vchuravy

Your PR requires formatting changes to meet the project's style guidelines. Please consider running Runic (git runic main) to apply these changes.

Click here to view the suggested changes.
diff --git a/src/compiler/validation.jl b/src/compiler/validation.jl
index aab84faa..a617c0b8 100644
--- a/src/compiler/validation.jl
+++ b/src/compiler/validation.jl
@@ -100,8 +100,8 @@ function __init__()
         "jl_array_typetagdata",
         "ijl_array_typetagdata",
         "jl_idtable_rehash",
-        "jl_f__compute_sparams",
-        "ijl_f__compute_sparams",
+            "jl_f__compute_sparams",
+            "ijl_f__compute_sparams",
     )
     for name in known_names
         sym = LLVM.find_symbol(name)
diff --git a/src/llvm/attributes.jl b/src/llvm/attributes.jl
index c1989bf3..279aea19 100644
--- a/src/llvm/attributes.jl
+++ b/src/llvm/attributes.jl
@@ -130,8 +130,8 @@ const nofreefns = Set{String}((
     "ijl_f__typevar",
     "jl_f_isa",
     "ijl_f_isa",
-    "jl_f__compute_sparams",
-    "ijl_f__compute_sparams",
+        "jl_f__compute_sparams",
+        "ijl_f__compute_sparams",
     "jl_set_task_threadpoolid",
     "ijl_set_task_threadpoolid",
     "jl_types_equal",
@@ -270,8 +270,8 @@ const inactivefns = Set{String}((
     "ijl_f_sizeof",
     "jl_f_isa",
     "ijl_f_isa",
-    "jl_f__compute_sparams",
-    "ijl_f__compute_sparams",
+        "jl_f__compute_sparams",
+        "ijl_f__compute_sparams",
     "jl_set_task_threadpoolid",
     "ijl_set_task_threadpoolid",
     "jl_types_equal",

github-actions[bot] avatar Nov 10 '25 21:11 github-actions[bot]

@wsmoses adding jl_f__compute_sparams to the list is not effective... I assume this is because the pointer to name thing failed? Which is why the error message is not helpful?

vchuravy avatar Nov 10 '25 21:11 vchuravy

Codecov Report

:white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 67.77%. Comparing base (3cd3c65) to head (a81b1bc).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2751   +/-   ##
=======================================
  Coverage   67.76%   67.77%           
=======================================
  Files          58       58           
  Lines       20913    20913           
=======================================
+ Hits        14172    14173    +1     
+ Misses       6741     6740    -1     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

codecov[bot] avatar Nov 10 '25 22:11 codecov[bot]

also add it to the list of names to lookup? https://github.com/EnzymeAD/Enzyme.jl/blob/6b30dda03763357b12b338275470a18df97bc7a8/src/compiler/validation.jl#L102

wsmoses avatar Nov 11 '25 17:11 wsmoses

None of the other jl_f_ functions are listed there? And it doesn't help.

vchuravy avatar Nov 11 '25 18:11 vchuravy