Enzyme.jl
Enzyme.jl copied to clipboard
Add test for MultiRequest
MPI.jl has a useful abstraction for handling multiple request that currently breaks AD.
L37: ; preds = %L11
%19 = addrspacecast {} addrspace(10)* %getfield4 to {} addrspace(11)*, !dbg !1268
%20 = call nonnull "enzyme_type"="{[-1]:Pointer, [-1,0]:Pointer, [-1,0,-1]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}" {}* @julia.pointer_from_objref({} addrspace(11)* noundef %19) #35, !dbg !1268
%21 = bitcast {}* %20 to i8**, !dbg !1268
%arrayptr8 = load i8*, i8** %21, align 8, !dbg !1268, !tbaa !322, !alias.scope !140, !noalias !141, !nonnull !0, !enzyme_type !426, !enzymejl_byref_BITS_VALUE !0, !enzymejl_source_type_Ptr\7BFloat64\7D !0
%22 = ptrtoint i8* %arrayptr8 to i64, !dbg !1268
%23 = addrspacecast {} addrspace(10)* %getfield6 to i32 addrspace(11)*, !dbg !1270, !enzyme_inactive !0
%24 = load i32, i32 addrspace(11)* %23, align 4, !dbg !1270, !tbaa !71, !alias.scope !41, !noalias !73, !enzyme_type !35, !enzyme_inactive !0, !enzymejl_byref_BITS_VALUE !0, !enzymejl_source_type_Int32 !0
%25 = load i32, i32 addrspace(11)* addrspacecast (i32* inttoptr (i64 139895257720736 to i32*) to i32 addrspace(11)*), align 32, !dbg !1272, !tbaa !71, !alias.scope !41, !noalias !73
%26 = call nonnull "enzyme_inactive" "enzyme_type"="{[-1]:Pointer, [-1,0]:Pointer, [-1,0,-1]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer, [-1,16]:Integer, [-1,17]:Integer, [-1,18]:Integer, [-1,19]:Integer, [-1,20]:Integer, [-1,21]:Integer, [-1,22]:Integer, [-1,23]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer}" {}* @julia.pointer_from_objref({} addrspace(11)* noundef %11) #35, !dbg !1274
%27 = bitcast {}* %26 to i8**, !dbg !1274, !enzyme_inactive !0
%arrayptr12 = load i8*, i8** %27, align 8, !dbg !1274, !tbaa !322, !alias.scope !140, !noalias !141, !nonnull !0, !enzyme_type !390, !enzyme_inactive !0, !enzymejl_byref_BITS_VALUE !0, !enzymejl_source_type_Ptr\7BInt32\7D !0
%28 = shl i64 %10, 2, !dbg !1277
%29 = getelementptr i8, i8* %arrayptr12, i64 %28, !dbg !1279
%30 = ptrtoint i8* %29 to i64, !dbg !1279
%unbox14.unpack36 = insertvalue [1 x {} addrspace(10)*] undef, {} addrspace(10)* %getfield, 0, !dbg !1266
%31 = insertvalue { [1 x {} addrspace(10)*], i64 } undef, [1 x {} addrspace(10)*] %unbox14.unpack36, 0, !dbg !1266
%unbox1435 = insertvalue { [1 x {} addrspace(10)*], i64 } %31, i64 %unbox2, 1, !dbg !1266
%unbox15 = load i32, i32 addrspace(11)* %15, align 8, !dbg !1266, !tbaa !21, !alias.scope !27, !noalias !30, !enzyme_type !35, !enzyme_inactive !0, !enzymejl_byref_BITS_VALUE !0, !enzymejl_source_type_Int32 !0
%32 = call i32 @MPI_Isend(i64 %22, i32 %unbox15, i32 %24, i32 %16, i32 noundef 0, i32 %25, i64 %30) #33 [ "jl_roots"({ [1 x {} addrspace(10)*], i64 } %unbox1435, {} addrspace(10)* addrspacecast ({}* inttoptr (i64 139895257720736 to {}*) to {} addrspace(10)*), {} addrspace(10)* %getfield6, {} addrspace(10)* %getfield4) ], !dbg !1266
%.not37 = icmp eq i32 %32, 0, !dbg !1280
br i1 %.not37, label %L59, label %L56, !dbg !126
So we can see a call to MPI_Isend with the request argument being %30 being loaded from arrayptr12 which is array of integers on the Julia level (MPICH convention) and explicitly marked as !enzyme_inactive
Backtrace is:
[79106] signal (6.-6): Aborted
in expression starting at /home/vchuravy/src/Enzyme/test/integration/MPI/multi_request.jl:56
unknown function (ip: 0x7f3c4209894c)
gsignal at /usr/lib/libc.so.6 (unknown line)
abort at /usr/lib/libc.so.6 (unknown line)
unknown function (ip: 0x7f3c420254e2)
handleMPI at /home/vchuravy/src/enzyme/enzyme/Enzyme/CallDerivatives.cpp:53
handleKnownCallDerivatives at /home/vchuravy/src/enzyme/enzyme/Enzyme/CallDerivatives.cpp:2254
visitCallInst at /home/vchuravy/src/enzyme/enzyme/Enzyme/AdjointGenerator.h:6405
delegateCallInst at /home/vchuravy/.julia/artifacts/414276a44b10b52ca36eff2db0e9085c785fac9d/include/llvm/IR/InstVisitor.h:301
visitCall at /home/vchuravy/.julia/artifacts/414276a44b10b52ca36eff2db0e9085c785fac9d/include/llvm/IR/Instruction.def:209
visit at /home/vchuravy/.julia/artifacts/414276a44b10b52ca36eff2db0e9085c785fac9d/include/llvm/IR/Instruction.def:209
visit at /home/vchuravy/.julia/artifacts/414276a44b10b52ca36eff2db0e9085c785fac9d/include/llvm/IR/InstVisitor.h:111
CreateAugmentedPrimal at /home/vchuravy/src/enzyme/enzyme/Enzyme/EnzymeLogic.cpp:2589
recursivelyHandleSubfunction at /home/vchuravy/src/enzyme/enzyme/Enzyme/AdjointGenerator.h:5390
visitCallInst at /home/vchuravy/src/enzyme/enzyme/Enzyme/AdjointGenerator.h:660
I am thinking this is due to:
julia> Enzyme.Compiler.guaranteed_const(MPI.API.MPI_Request)
true
julia> MPI.API.MPI_Request
Int32
But also true for OpenMPI where this is a Ptr{Cvoid}.
@wsmoses is there a way to change that query. Do I need to overwrite active_reg_inner?