Closed jgreener64 closed 6 months ago
Add a Enzyme.API.strictAliasing!(false)
and see if it succeeds?
With Enzyme.API.strictAliasing!(false)
the error changes slightly:
ERROR: Enzyme cannot deduce type
Current scope:
; Function Attrs: mustprogress nofree noinline nosync readonly uwtable willreturn
define internal fastcc double @preprocess_julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %1, i64 signext %2) unnamed_addr #33 !dbg !1466 {
top:
%3 = call {}*** @julia.get_pgcstack() #43
%.not = icmp eq i64 %2, %1, !dbg !1467
br i1 %.not, label %L3, label %L5, !dbg !1468
common.ret.loopexit: ; preds = %L32
br label %common.ret, !dbg !1469
common.ret: ; preds = %common.ret.loopexit, %L59, %L8, %L3
%common.ret.op = phi double [ %9, %L3 ], [ %33, %L59 ], [ %19, %L8 ], [ %27, %common.ret.loopexit ]
ret double %common.ret.op, !dbg !1469
L3: ; preds = %top
%4 = add i64 %2, -1, !dbg !1470
%5 = bitcast {} addrspace(10)* %0 to double addrspace(13)* addrspace(10)*, !dbg !1470
%6 = addrspacecast double addrspace(13)* addrspace(10)* %5 to double addrspace(13)* addrspace(11)*, !dbg !1470
%7 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %6, align 16, !dbg !1470, !tbaa !82, !nonnull !4 %8 = getelementptr inbounds double, double addrspace(13)* %7, i64 %4, !dbg !1470
%9 = load double, double addrspace(13)* %8, align 8, !dbg !1470, !tbaa !124
br label %common.ret
L5: ; preds = %top
%10 = sub i64 %2, %1, !dbg !1472
%.not11 = icmp slt i64 %10, 1024, !dbg !1474
br i1 %.not11, label %L8, label %L59, !dbg !1473
L8: ; preds = %L5
%11 = add i64 %1, -1, !dbg !1475
%12 = bitcast {} addrspace(10)* %0 to double addrspace(13)* addrspace(10)*, !dbg !1475
%13 = addrspacecast double addrspace(13)* addrspace(10)* %12 to double addrspace(13)* addrspace(11)*, !dbg !1475
%14 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %13, align 16, !dbg !1475, !tbaa !82, !nonnull !4
%15 = getelementptr inbounds double, double addrspace(13)* %14, i64 %11, !dbg !1475
%16 = load double, double addrspace(13)* %15, align 8, !dbg !1475, !tbaa !124
%17 = getelementptr inbounds double, double addrspace(13)* %14, i64 %1, !dbg !1477
%18 = load double, double addrspace(13)* %17, align 8, !dbg !1477, !tbaa !124
%19 = fadd double %16, %18, !dbg !1479
%20 = add i64 %1, 2, !dbg !1482
%.not12 = icmp sgt i64 %20, %2, !dbg !1485
%21 = add i64 %1, 1, !dbg !1487
%value_phi = select i1 %.not12, i64 %21, i64 %2, !dbg !1487
%22 = sub i64 %value_phi, %20, !dbg !1490
%23 = icmp ugt i64 %22, 9223372036854775806, !dbg !1494
br i1 %23, label %common.ret, label %L32.preheader, !dbg !1495
L32.preheader: ; preds = %L8
br label %L32, !dbg !1496
L32: ; preds = %L32.preheader, %L32
%iv = phi i64 [ 0, %L32.preheader ], [ %iv.next, %L32 ]
%value_phi115 = phi double [ %27, %L32 ], [ %19, %L32.preheader ]
%iv.next = add nuw nsw i64 %iv, 1, !dbg !1497
%24 = add i64 %21, %iv, !dbg !1497
%25 = getelementptr inbounds double, double addrspace(13)* %14, i64 %24, !dbg !1497
%26 = load double, double addrspace(13)* %25, align 8, !dbg !1497, !tbaa !124
%27 = fadd fast double %value_phi115, %26, !dbg !1500
%exitcond.not = icmp eq i64 %iv, %22, !dbg !1503
br i1 %exitcond.not, label %common.ret.loopexit, label %L32, !dbg !1496, !llvm.loop !1504
L59: ; preds = %L5
%28 = ashr i64 %10, 1, !dbg !1505
%29 = add i64 %28, %1, !dbg !1508
%30 = call fastcc double @julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %1, i64 signext %29) #44, !dbg !1509
%31 = add i64 %29, 1, !dbg !1510
%32 = call fastcc double @julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %31, i64 signext %2) #44, !dbg !1511
%33 = fadd double %30, %32, !dbg !1512
br label %common.ret
}
Type analysis state:
<analysis>
%22 = sub i64 %value_phi, %20, !dbg !78: {[-1]:Integer}, intvals: {}
%31 = add i64 %29, 1, !dbg !102: {[-1]:Integer}, intvals: {}
%iv.next = add nuw nsw i64 %iv, 1, !dbg !87: {[-1]:Integer}, intvals: {1,}
%23 = icmp ugt i64 %22, 9223372036854775806, !dbg !84: {[-1]:Integer}, intvals: {}
%33 = fadd double %30, %32, !dbg !104: {[-1]:Float@double}, intvals: {}
%19 = fadd double %16, %18, !dbg !55: {[-1]:Float@double}, intvals: {}
%28 = ashr i64 %10, 1, !dbg !96: {[-1]:Integer}, intvals: {}
%20 = add i64 %1, 2, !dbg !61: {[-1]:Integer}, intvals: {3,}
%21 = add i64 %1, 1, !dbg !72: {[-1]:Integer}, intvals: {2,}
%27 = fadd fast double %value_phi115, %26, !dbg !91: {[-1]:Float@double}, intvals: {}
%11 = add i64 %1, -1, !dbg !51: {[-1]:Integer}, intvals: {0,}
%.not = icmp eq i64 %2, %1, !dbg !29: {[-1]:Integer}, intvals: {}
%.not11 = icmp slt i64 %10, 1024, !dbg !49: {[-1]:Integer}, intvals: {}
%4 = add i64 %2, -1, !dbg !34: {[-1]:Integer}, intvals: {}
%24 = add i64 %21, %iv, !dbg !87: {[-1]:Integer}, intvals: {2,}
%exitcond.not = icmp eq i64 %iv, %22, !dbg !94: {[-1]:Integer}, intvals: {}
%10 = sub i64 %2, %1, !dbg !45: {[-1]:Integer}, intvals: {}
%29 = add i64 %28, %1, !dbg !100: {[-1]:Integer}, intvals: {}
%.not12 = icmp sgt i64 %20, %2, !dbg !67: {[-1]:Integer}, intvals: {}
%15 = getelementptr inbounds double, double addrspace(13)* %14, i64 %11, !dbg !51: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
%25 = getelementptr inbounds double, double addrspace(13)* %14, i64 %24, !dbg !87: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
%17 = getelementptr inbounds double, double addrspace(13)* %14, i64 %1, !dbg !53: {[-1]:Pointer, [-1,0]:Float@double}, intvals: {}
%8 = getelementptr inbounds double, double addrspace(13)* %7, i64 %4, !dbg !34: {[-1]:Pointer}, intvals: {}
%26 = load double, double addrspace(13)* %25, align 8, !dbg !87, !tbaa !42: {[-1]:Float@double}, intvals: {}
%14 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %13, align 16, !dbg !51, !tbaa !37, !nonnull !4: {[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double}, intvals: {}
%13 = addrspacecast double addrspace(13)* addrspace(10)* %12 to double addrspace(13)* addrspace(11)*, !dbg !51: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@double, [-1,0,8]:Float@double}, intvals: {}
%5 = bitcast {} addrspace(10)* %0 to double addrspace(13)* addrspace(10)*, !dbg !34: {[-1]:Pointer, [-1,0]:Pointer}, intvals: {}
%16 = load double, double addrspace(13)* %15, align 8, !dbg !51, !tbaa !42: {[-1]:Float@double}, intvals: {}
%12 = bitcast {} addrspace(10)* %0 to double addrspace(13)* addrspace(10)*, !dbg !51: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@double, [-1,0,8]:Float@double}, intvals: {}
%9 = load double, double addrspace(13)* %8, align 8, !dbg !34, !tbaa !42: {}, intvals: {}
%18 = load double, double addrspace(13)* %17, align 8, !dbg !53, !tbaa !42: {[-1]:Float@double}, intvals: {}
%6 = addrspacecast double addrspace(13)* addrspace(10)* %5 to double addrspace(13)* addrspace(11)*, !dbg !34: {[-1]:Pointer, [-1,0]:Pointer}, intvals: {}
%7 = load double addrspace(13)*, double addrspace(13)* addrspace(11)* %6, align 16, !dbg !34, !tbaa !37, !nonnull !4: {[-1]:Pointer}, intvals: {}
%30 = call fastcc double @julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %1, i64 signext %29) #44, !dbg !101: {[-1]:Float@double}, intvals: {}
%32 = call fastcc double @julia_mapreduce_impl_6051({} addrspace(10)* nocapture nofree noundef nonnull readonly align 16 dereferenceable(40) %0, i64 signext %31, i64 signext %2) #44, !dbg !103: {[-1]:Float@double}, intvals: {}
i64 1024: {[-1]:Integer}, intvals: {1024,}
%value_phi = select i1 %.not12, i64 %21, i64 %2, !dbg !72: {[-1]:Integer}, intvals: {}
%3 = call {}*** @julia.get_pgcstack() #43: {}, intvals: {}
{} addrspace(10)* %0: {[-1]:Pointer}, intvals: {}
i64 %1: {[-1]:Integer}, intvals: {1,}
i64 %2: {[-1]:Integer}, intvals: {}
%common.ret.op = phi double [ %9, %L3 ], [ %33, %L59 ], [ %19, %L8 ], [ %27, %common.ret.loopexit ]: {}, intvals: {}
%value_phi115 = phi double [ %27, %L32 ], [ %19, %L32.preheader ]: {[-1]:Float@double}, intvals: {}
%iv = phi i64 [ 0, %L32.preheader ], [ %iv.next, %L32 ]: {[-1]:Integer}, intvals: {0,}
i64 2: {[-1]:Integer}, intvals: {2,}
i64 -1: {[-1]:Anything}, intvals: {-1,}
i64 0: {[-1]:Anything}, intvals: {0,}
i64 1: {[-1]:Integer}, intvals: {1,}
i64 9223372036854775806: {[-1]:Anything}, intvals: {9223372036854775806,}
</analysis>
Cannot deduce type of phi %common.ret.op = phi double [ %9, %L3 ], [ %33, %L59 ], [ %19, %L8 ], [ %27, %common.ret.loopexit ]
Caused by:
Stacktrace:
[1] julia_error(cstr::Cstring, val::Ptr{LLVM.API.LLVMOpaqueValue}, errtype::Enzyme.API.ErrorType, data::Ptr{Nothing})
@ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:5098
[2] EnzymeCreatePrimalAndGradient(logic::Enzyme.Logic, todiff::LLVM.Function, retType::Enzyme.API.CDIFFE_TYPE, constant_args::Vector{Enzyme.API.CDIFFE_TYPE}, TA::Enzyme.TypeAnalysis, returnValue::Bool, dretUsed::Bool, mode::Enzyme.API.CDerivativeMode, width::Int64, additionalArg::Ptr{LLVM.API.LLVMOpaqueType}, typeInfo::Enzyme.FnTypeInfo, uncacheable_args::Vector{Bool}, augmented::Ptr{Nothing}, atomicAdd::Bool)
@ Enzyme.API C:\Users\Joe\.julia\dev\Enzyme\src\api.jl:123
[3] enzyme!(job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}, mod::LLVM.Module, primalf::LLVM.Function, TT::Type, mode::Enzyme.API.CDerivativeMode, width::Int64, parallel::Bool, actualRetType::Type, wrap::Bool, modifiedBetween::Tuple{Bool, Bool}, returnPrimal::Bool, jlrules::Vector{String}, expectedTapeType::Type)
@ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:6551
[4] codegen(output::Symbol, job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}; libraries::Bool, deferred_codegen::Bool, optimize::Bool, ctx::LLVM.Context, strip::Bool, validate::Bool, only_entry::Bool, parent_job::Nothing)
@ Enzyme.Compiler C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:7817
[5] _thunk
@ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8329 [inlined]
[6] _thunk
@ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8326 [inlined]
[7] cached_compilation
@ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8362 [inlined]
[8] #s260#178
@ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8424 [inlined]
[9] var"#s260#178"(FA::Any, A::Any, TT::Any, Mode::Any, ModifiedBetween::Any, width::Any, ReturnPrimal::Any, ShadowInit::Any, parent_job::Any, World::Any, ::Any, ::Any, ::Any, ::Any, tt::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)
@ Enzyme.Compiler .\none:0
[10] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any})
@ Core .\boot.jl:582
[11] thunk
@ C:\Users\Joe\.julia\dev\Enzyme\src\compiler.jl:8379 [inlined]
[12] autodiff(#unused#::EnzymeCore.ReverseMode{false}, f::Const{typeof(f2)}, #unused#::Type{Active}, args::Duplicated{Vector{Float64}})
@ Enzyme C:\Users\Joe\.julia\dev\Enzyme\src\Enzyme.jl:187
[13] autodiff(::EnzymeCore.ReverseMode{false}, ::typeof(f2), ::Type, ::Duplicated{Vector{Float64}})
@ Enzyme C:\Users\Joe\.julia\dev\Enzyme\src\Enzyme.jl:214
[14] top-level scope
@ REPL[9]:1
This now works on main with strictaliasing!(false)
julia> using Enzyme
julia> Enzyme.API.strictAliasing!(false)
julia> f1(x) = sum([ifelse(i > 0, i, zero(i)) for i in x])
f1 (generic function with 1 method)
julia> x = randn(5)
5-element Vector{Float64}:
1.4054496275614226
-0.8542107477656112
1.2424602513442708
-1.1937151100828347
1.188920661214303
julia> dx = zero(x)
5-element Vector{Float64}:
0.0
0.0
0.0
0.0
0.0
julia> autodiff(Reverse, f1, Active, Duplicated(x, dx))
((nothing,),)
julia> f2(x) = sum([ifelse(i > 0, i, 0) for i in x])
f2 (generic function with 1 method)
julia> autodiff(Reverse, f2, Active, Duplicated(x, dx))
((nothing,),)
With strictaliasing and type analysis getting documentation here: https://github.com/EnzymeAD/Enzyme.jl/pull/1435, closing
I am on Julia 1.8.5 and Enzyme main (73285ce). The following works:
However if I specify integer zero, it errors:
This is not ideal coding style since the intermediate vector is the non-concrete
Vector{Real}
, however the function does run fine without gradients. The error: