help wanted
Repository metrics
- Stars
- (563 stars)
- PR merge metrics
- (Avg merge 5d 1h) (76 merged PRs in 30d)
Description
MWE:
module MWE
using SpecialFunctions: libopenspecfun
using Enzyme
Enzyme.API.printall!(true)
function besseli(nu, z)
kode = Int32(1)
ai1, ai2 = Ref{Float64}(), Ref{Float64}()
ae1, ae2 = Ref{Int32}(), Ref{Int32}()
ccall((:zbesi_,libopenspecfun), Cvoid,
(Ref{Float64}, Ref{Float64}, Ref{Float64}, Ref{Int32}, Ref{Int32},
Ref{Float64}, Ref{Float64}, Ref{Int32}, Ref{Int32}),
z, 0.0, 1.0, kode, 1,
ai1, ai2, ae1, ae2)
if ae2[] == 0
return 2*nu
else
throw(AssertionError())
end
end
f(x) = besseli(x, 2.7)
Enzyme.autodiff(Enzyme.Forward, f, Duplicated(1.0, 1.0))
end
Output:
after simplification :
; Function Attrs: mustprogress willreturn
define "enzyme_type"="{[-1]:Float@double}" double @preprocess_julia_f_15293(double "enzyme_type"="{[-1]:Float@double}" "enzymejl_parmtype"="4897950928" "enzymejl_parmtype_ref"="0" %0) local_unnamed_addr #7 !dbg !63 {
top:
%1 = call {}*** @julia.get_pgcstack() #8
%ptls_field3 = getelementptr inbounds {}**, {}*** %1, i64 2
%2 = bitcast {}*** %ptls_field3 to i64***
%ptls_load45 = load i64**, i64*** %2, align 8, !tbaa !10
%3 = getelementptr inbounds i64*, i64** %ptls_load45, i64 2
%safepoint = load i64*, i64** %3, align 8, !tbaa !14
fence syncscope("singlethread") seq_cst
call void @julia.safepoint(i64* %safepoint) #8, !dbg !64
fence syncscope("singlethread") seq_cst
%4 = call fastcc double @julia_besseli_15296(double %0) #8, !dbg !64
ret double %4, !dbg !64
}
after simplification :
; Function Attrs: mustprogress willreturn
define internal fastcc "enzyme_type"="{[-1]:Float@double}" double @preprocess_julia_besseli_15296(double "enzyme_type"="{[-1]:Float@double}" "enzymejl_parmtype"="4897950928" "enzymejl_parmtype_ref"="0" %0) unnamed_addr #8 !dbg !77 {
top:
%1 = alloca i64, align 16
%2 = bitcast i64* %1 to i8*
%3 = alloca i64, align 16
%4 = bitcast i64* %3 to i8*
%5 = alloca i32, align 8
%6 = bitcast i32* %5 to i8*
%7 = alloca i32, align 8
%8 = bitcast i32* %7 to i8*
%9 = alloca i64, align 16
%10 = bitcast i64* %9 to i8*
%11 = alloca i64, align 16
%12 = bitcast i64* %11 to i8*
%13 = alloca i64, align 16
%14 = bitcast i64* %13 to i8*
%15 = alloca i32, align 8
%16 = bitcast i32* %15 to i8*
%17 = alloca i32, align 8
%18 = bitcast i32* %17 to i8*
%19 = call {}*** @julia.get_pgcstack() #9
%ptls_field67 = getelementptr inbounds {}**, {}*** %19, i64 2
%20 = bitcast {}*** %ptls_field67 to i64***
%ptls_load6869 = load i64**, i64*** %20, align 8, !tbaa !10
%21 = getelementptr inbounds i64*, i64** %ptls_load6869, i64 2
%safepoint = load i64*, i64** %21, align 8, !tbaa !14
fence syncscope("singlethread") seq_cst
call void @julia.safepoint(i64* %safepoint) #9, !dbg !78
fence syncscope("singlethread") seq_cst
%22 = bitcast i64* %9 to double*, !dbg !79
store double 2.700000e+00, double* %22, align 16, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
%memcpy_refined_dst = bitcast i64* %11 to double*, !dbg !79
store double 0.000000e+00, double* %memcpy_refined_dst, align 16, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
%memcpy_refined_dst15 = bitcast i64* %13 to double*, !dbg !79
store double 1.000000e+00, double* %memcpy_refined_dst15, align 16, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
store i32 1, i32* %15, align 8, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
store i32 1, i32* %17, align 8, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
call void @zbesi_(i8* noundef nonnull %10, i8* noundef nonnull %12, i8* noundef nonnull %14, i8* noundef nonnull %16, i8* noundef nonnull %18, i8* noundef nonnull %2, i8* noundef nonnull %4, i8* noundef nonnull %6, i8* noundef nonnull %8) #9 [ "jl_roots"({} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null) ], !dbg !82
%23 = load i32, i32* %7, align 8, !dbg !86, !tbaa !29, !alias.scope !33, !noalias !49
%.not = icmp eq i32 %23, 0, !dbg !89
br i1 %.not, label %L114, label %L116, !dbg !88
L114: ; preds = %top
%24 = fmul double %0, 2.000000e+00, !dbg !91
ret double %24, !dbg !93
L116: ; preds = %top
%current_task166 = getelementptr inbounds {}**, {}*** %19, i64 -14
%current_task1 = bitcast {}*** %current_task166 to {}**
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %2) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %4) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull %6) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull %8) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %10) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %12) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %14) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull %16) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull %18) #9
%box = call noalias nonnull dereferenceable(8) "enzyme_inactive" "enzyme_type"="{[-1]:Pointer, [-1,-1]:Pointer}" {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task1, i64 noundef 8, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 4826099712 to {}*) to {} addrspace(10)*)) #10, !dbg !94
%25 = bitcast {} addrspace(10)* %box to [1 x {} addrspace(10)*] addrspace(10)*, !dbg !94
%26 = getelementptr [1 x {} addrspace(10)*], [1 x {} addrspace(10)*] addrspace(10)* %25, i64 0, i64 0, !dbg !94
store {} addrspace(10)* addrspacecast ({}* inttoptr (i64 4965887920 to {}*) to {} addrspace(10)*), {} addrspace(10)* addrspace(10)* %26, align 8, !dbg !94, !tbaa !61, !alias.scope !33, !noalias !83
%27 = addrspacecast {} addrspace(10)* %box to {} addrspace(12)*, !dbg !94
call void @ijl_throw({} addrspace(12)* %27) #11, !dbg !94
unreachable, !dbg !94
}
; Function Attrs: mustprogress willreturn
define internal fastcc double @fwddiffejulia_besseli_15296(double "enzyme_type"="{[-1]:Float@double}" "enzymejl_parmtype"="4897950928" "enzymejl_parmtype_ref"="0" %0, double "enzyme_type"="{[-1]:Float@double}" "enzymejl_parmtype"="4897950928" "enzymejl_parmtype_ref"="0" %"'") unnamed_addr #8 !dbg !95 {
top:
%"'ipa" = alloca i64, align 16
store i64 0, i64* %"'ipa", align 16
%1 = alloca i64, align 16
%"'ipc" = bitcast i64* %"'ipa" to i8*
%2 = bitcast i64* %1 to i8*
%"'ipa16" = alloca i64, align 16
store i64 0, i64* %"'ipa16", align 16
%3 = alloca i64, align 16
%"'ipc17" = bitcast i64* %"'ipa16" to i8*
%4 = bitcast i64* %3 to i8*
%"'ipa18" = alloca i32, align 8
store i32 0, i32* %"'ipa18", align 8
%5 = alloca i32, align 8
%"'ipc19" = bitcast i32* %"'ipa18" to i8*
%6 = bitcast i32* %5 to i8*
%"'ipa20" = alloca i32, align 8
store i32 0, i32* %"'ipa20", align 8
%7 = alloca i32, align 8
%"'ipc21" = bitcast i32* %"'ipa20" to i8*
%8 = bitcast i32* %7 to i8*
%"'ipa22" = alloca i64, align 16
store i64 0, i64* %"'ipa22", align 16
%9 = alloca i64, align 16
%"'ipc23" = bitcast i64* %"'ipa22" to i8*
%10 = bitcast i64* %9 to i8*
%"'ipa24" = alloca i64, align 16
store i64 0, i64* %"'ipa24", align 16
%11 = alloca i64, align 16
%"'ipc25" = bitcast i64* %"'ipa24" to i8*
%12 = bitcast i64* %11 to i8*
%"'ipa26" = alloca i64, align 16
store i64 0, i64* %"'ipa26", align 16
%13 = alloca i64, align 16
%"'ipc27" = bitcast i64* %"'ipa26" to i8*
%14 = bitcast i64* %13 to i8*
%15 = alloca i32, align 8
%16 = bitcast i32* %15 to i8*
%17 = alloca i32, align 8
%18 = bitcast i32* %17 to i8*
%19 = call {}*** @julia.get_pgcstack() #9
%ptls_field67 = getelementptr inbounds {}**, {}*** %19, i64 2
%20 = bitcast {}*** %ptls_field67 to i64***
%ptls_load6869 = load i64**, i64*** %20, align 8, !tbaa !10, !alias.scope !96, !noalias !99
%21 = getelementptr inbounds i64*, i64** %ptls_load6869, i64 2
%safepoint = load i64*, i64** %21, align 8, !tbaa !14, !alias.scope !101, !noalias !104
fence syncscope("singlethread") seq_cst
call void @julia.safepoint(i64* %safepoint) #9, !dbg !106
fence syncscope("singlethread") seq_cst
%"'ipc28" = bitcast i64* %"'ipa22" to double*, !dbg !107
%22 = bitcast i64* %9 to double*, !dbg !107
store double 0.000000e+00, double* %"'ipc28", align 16, !dbg !107, !tbaa !29, !alias.scope !111, !noalias !114
store double 2.700000e+00, double* %22, align 16, !dbg !107, !tbaa !29, !alias.scope !116, !noalias !117
%"memcpy_refined_dst'ipc" = bitcast i64* %"'ipa24" to double*, !dbg !107
%memcpy_refined_dst = bitcast i64* %11 to double*, !dbg !107
store double 0.000000e+00, double* %"memcpy_refined_dst'ipc", align 16, !dbg !107, !tbaa !29, !alias.scope !118, !noalias !121
store double 0.000000e+00, double* %memcpy_refined_dst, align 16, !dbg !107, !tbaa !29, !alias.scope !123, !noalias !124
%"memcpy_refined_dst15'ipc" = bitcast i64* %"'ipa26" to double*, !dbg !107
%memcpy_refined_dst15 = bitcast i64* %13 to double*, !dbg !107
store double 0.000000e+00, double* %"memcpy_refined_dst15'ipc", align 16, !dbg !107, !tbaa !29, !alias.scope !125, !noalias !128
store double 1.000000e+00, double* %memcpy_refined_dst15, align 16, !dbg !107, !tbaa !29, !alias.scope !130, !noalias !131
store i32 1, i32* %15, align 8, !dbg !107, !tbaa !29, !alias.scope !33, !noalias !132
store i32 1, i32* %17, align 8, !dbg !107, !tbaa !29, !alias.scope !33, !noalias !132
call void inttoptr (i64 13170132768 to void (i8*)*)(i8* getelementptr inbounds ([5193 x i8], [5193 x i8]* @0, i32 0, i32 0)) #10, !dbg !110
call void @fwddiffezbesi_(i8* %10, i8* %"'ipc23", i8* %12, i8* %"'ipc25", i8* %14, i8* %"'ipc27", i8* %16, i8* %18, i8* %2, i8* %"'ipc", i8* %4, i8* %"'ipc17", i8* %6, i8* %"'ipc19", i8* %8, i8* %"'ipc21") [ "jl_roots"({} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null) ], !dbg !110
%23 = load i32, i32* %7, align 8, !dbg !135, !tbaa !29, !alias.scope !138, !noalias !141
%.not = icmp eq i32 %23, 0, !dbg !143
br i1 %.not, label %L114, label %L116, !dbg !137
L114: ; preds = %top
%24 = fmul fast double %"'", 2.000000e+00, !dbg !145
ret double %24
L116: ; preds = %top
%current_task166 = getelementptr inbounds {}**, {}*** %19, i64 -14
%current_task1 = bitcast {}*** %current_task166 to {}**
%box = call noalias nonnull dereferenceable(8) "enzyme_inactive" "enzyme_type"="{[-1]:Pointer, [-1,-1]:Pointer}" {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task1, i64 noundef 8, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 4826099712 to {}*) to {} addrspace(10)*)) #11, !dbg !146
%25 = bitcast {} addrspace(10)* %box to [1 x {} addrspace(10)*] addrspace(10)*, !dbg !146
%26 = getelementptr [1 x {} addrspace(10)*], [1 x {} addrspace(10)*] addrspace(10)* %25, i64 0, i64 0, !dbg !146
store {} addrspace(10)* addrspacecast ({}* inttoptr (i64 4965887920 to {}*) to {} addrspace(10)*), {} addrspace(10)* addrspace(10)* %26, align 8, !dbg !146, !tbaa !61, !alias.scope !33, !noalias !132
%27 = addrspacecast {} addrspace(10)* %box to {} addrspace(12)*, !dbg !146
call void @ijl_throw({} addrspace(12)* %27) #12, !dbg !146
unreachable, !dbg !146
}
; Function Attrs: mustprogress willreturn
define internal double @fwddiffejulia_f_15293(double "enzyme_type"="{[-1]:Float@double}" "enzymejl_parmtype"="4897950928" "enzymejl_parmtype_ref"="0" %0, double "enzyme_type"="{[-1]:Float@double}" "enzymejl_parmtype"="4897950928" "enzymejl_parmtype_ref"="0" %"'") local_unnamed_addr #7 !dbg !65 {
top:
%1 = call {}*** @julia.get_pgcstack() #9
%ptls_field3 = getelementptr inbounds {}**, {}*** %1, i64 2
%2 = bitcast {}*** %ptls_field3 to i64***
%ptls_load45 = load i64**, i64*** %2, align 8, !tbaa !10, !alias.scope !66, !noalias !69
%3 = getelementptr inbounds i64*, i64** %ptls_load45, i64 2
%safepoint = load i64*, i64** %3, align 8, !tbaa !14, !alias.scope !71, !noalias !74
fence syncscope("singlethread") seq_cst
call void @julia.safepoint(i64* %safepoint) #9, !dbg !76
fence syncscope("singlethread") seq_cst
%4 = call fast fastcc double @fwddiffejulia_besseli_15296(double %0, double %"'"), !dbg !76
ret double %4
}
ERROR: Enzyme execution failed.
Enzyme compilation failed.
Current scope:
; Function Attrs: mustprogress willreturn
define internal fastcc "enzyme_type"="{[-1]:Float@double}" double @preprocess_julia_besseli_15296(double "enzyme_type"="{[-1]:Float@double}" "enzymejl_parmtype"="4897950928" "enzymejl_parmtype_ref"="0" %0) unnamed_addr #8 !dbg !77 {
top:
%1 = alloca i64, align 16
%2 = bitcast i64* %1 to i8*
%3 = alloca i64, align 16
%4 = bitcast i64* %3 to i8*
%5 = alloca i32, align 8
%6 = bitcast i32* %5 to i8*
%7 = alloca i32, align 8
%8 = bitcast i32* %7 to i8*
%9 = alloca i64, align 16
%10 = bitcast i64* %9 to i8*
%11 = alloca i64, align 16
%12 = bitcast i64* %11 to i8*
%13 = alloca i64, align 16
%14 = bitcast i64* %13 to i8*
%15 = alloca i32, align 8
%16 = bitcast i32* %15 to i8*
%17 = alloca i32, align 8
%18 = bitcast i32* %17 to i8*
%19 = call {}*** @julia.get_pgcstack() #9
%ptls_field67 = getelementptr inbounds {}**, {}*** %19, i64 2
%20 = bitcast {}*** %ptls_field67 to i64***
%ptls_load6869 = load i64**, i64*** %20, align 8, !tbaa !10
%21 = getelementptr inbounds i64*, i64** %ptls_load6869, i64 2
%safepoint = load i64*, i64** %21, align 8, !tbaa !14
fence syncscope("singlethread") seq_cst
call void @julia.safepoint(i64* %safepoint) #9, !dbg !78
fence syncscope("singlethread") seq_cst
%22 = bitcast i64* %9 to double*, !dbg !79
store double 2.700000e+00, double* %22, align 16, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
%memcpy_refined_dst = bitcast i64* %11 to double*, !dbg !79
store double 0.000000e+00, double* %memcpy_refined_dst, align 16, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
%memcpy_refined_dst15 = bitcast i64* %13 to double*, !dbg !79
store double 1.000000e+00, double* %memcpy_refined_dst15, align 16, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
store i32 1, i32* %15, align 8, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
store i32 1, i32* %17, align 8, !dbg !79, !tbaa !29, !alias.scope !33, !noalias !83
call void @zbesi_(i8* noundef nonnull %10, i8* noundef nonnull %12, i8* noundef nonnull %14, i8* noundef nonnull %16, i8* noundef nonnull %18, i8* noundef nonnull %2, i8* noundef nonnull %4, i8* noundef nonnull %6, i8* noundef nonnull %8) #9 [ "jl_roots"({} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null) ], !dbg !82
%23 = load i32, i32* %7, align 8, !dbg !86, !tbaa !29, !alias.scope !33, !noalias !49
%.not = icmp eq i32 %23, 0, !dbg !89
br i1 %.not, label %L114, label %L116, !dbg !88
L114: ; preds = %top
%24 = fmul double %0, 2.000000e+00, !dbg !91
ret double %24, !dbg !93
L116: ; preds = %top
%current_task166 = getelementptr inbounds {}**, {}*** %19, i64 -14
%current_task1 = bitcast {}*** %current_task166 to {}**
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %2) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %4) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull %6) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull %8) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %10) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %12) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 8, i8* noundef nonnull %14) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull %16) #9
call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull %18) #9
%box = call noalias nonnull dereferenceable(8) "enzyme_inactive" "enzyme_type"="{[-1]:Pointer, [-1,-1]:Pointer}" {} addrspace(10)* @julia.gc_alloc_obj({}** nonnull %current_task1, i64 noundef 8, {} addrspace(10)* noundef addrspacecast ({}* inttoptr (i64 4826099712 to {}*) to {} addrspace(10)*)) #10, !dbg !94
%25 = bitcast {} addrspace(10)* %box to [1 x {} addrspace(10)*] addrspace(10)*, !dbg !94
%26 = getelementptr [1 x {} addrspace(10)*], [1 x {} addrspace(10)*] addrspace(10)* %25, i64 0, i64 0, !dbg !94
store {} addrspace(10)* addrspacecast ({}* inttoptr (i64 4965887920 to {}*) to {} addrspace(10)*), {} addrspace(10)* addrspace(10)* %26, align 8, !dbg !94, !tbaa !61, !alias.scope !33, !noalias !83
%27 = addrspacecast {} addrspace(10)* %box to {} addrspace(12)*, !dbg !94
call void @ijl_throw({} addrspace(12)* %27) #11, !dbg !94
unreachable, !dbg !94
}
No forward mode derivative found for zbesi_
at context: call void @zbesi_(i8* noundef nonnull %10, i8* noundef nonnull %12, i8* noundef nonnull %14, i8* noundef nonnull %16, i8* noundef nonnull %18, i8* noundef nonnull %2, i8* noundef nonnull %4, i8* noundef nonnull %6, i8* noundef nonnull %8) #9 [ "jl_roots"({} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null, {} addrspace(10)* null) ], !dbg !26
Stacktrace:
[1] besseli
@ ./REPL[10]:13
Stacktrace:
[1] throwerr(cstr::Cstring)
@ Enzyme.Compiler ~/.julia/packages/Enzyme/7ZLaZ/src/compiler.jl:1620
[2] besseli
@ ./REPL[10]:13
[3] f
@ ./REPL[10]:26 [inlined]
[4] fwddiffejulia_f_15293wrap
@ ./REPL[10]:0
[5] macro expansion
@ ~/.julia/packages/Enzyme/7ZLaZ/src/compiler.jl:6606 [inlined]
[6] enzyme_call
@ ~/.julia/packages/Enzyme/7ZLaZ/src/compiler.jl:6207 [inlined]
[7] ForwardModeThunk
@ ~/.julia/packages/Enzyme/7ZLaZ/src/compiler.jl:6087 [inlined]
[8] autodiff
@ ~/.julia/packages/Enzyme/7ZLaZ/src/Enzyme.jl:417 [inlined]
[9] autodiff
@ ~/.julia/packages/Enzyme/7ZLaZ/src/Enzyme.jl:333 [inlined]
[10] autodiff(mode::ForwardMode{FFIABI}, f::typeof(Main.MWE.f), args::Duplicated{Float64})
@ Enzyme ~/.julia/packages/Enzyme/7ZLaZ/src/Enzyme.jl:318
[11] top-level scope
@ REPL[10]:28