The red -
lines are produced by direct references to Tensor.dfoo
, which doesn't crash.
The green +
lines are produced by #adjoint(Tensor.foo)
, which does crashes.
diff --git a/a1.sil b/a2.sil | |
index 30ad601..7d92e01 100644 | |
--- a/a1.sil | |
+++ b/a2.sil | |
@@ -1,128 +1,142 @@ | |
sil_stage raw | |
import Builtin | |
import Swift | |
import SwiftShims | |
import TensorFlow | |
extension Tensor where Scalar : Numeric, Scalar : AccelerableByTensorFlow { | |
@differentiable(reverse, adjoint: dfoo) | |
static func foo(_ x: Tensor<Scalar>) -> Tensor<Scalar> | |
static func dfoo(_ x: Tensor<Scalar>, originalValue: Tensor<Scalar>, seed: Tensor<Scalar>) -> Tensor<Scalar> | |
} | |
let x: Tensor<Float> | |
// x | |
sil_global hidden [let] @$S7crasher1x10TensorFlow0B0VySfGvp : $Tensor<Float> | |
// main | |
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { | |
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): | |
alloc_global @$S7crasher1x10TensorFlow0B0VySfGvp // id: %2 | |
- %3 = global_addr @$S7crasher1x10TensorFlow0B0VySfGvp : $*Tensor<Float> // users: %34, %33, %32, %29, %28, %27, %14 | |
+ %3 = global_addr @$S7crasher1x10TensorFlow0B0VySfGvp : $*Tensor<Float> // users: %37, %36, %35, %31, %30, %29, %14 | |
%4 = metatype $@thin Tensor<Float>.Type // user: %12 | |
%5 = metatype $@thin Float.Type // user: %8 | |
%6 = integer_literal $Builtin.Int2048, 1 // user: %8 | |
// function_ref Float.init(_builtinIntegerLiteral:) | |
%7 = function_ref @$SSf22_builtinIntegerLiteralSfBi2048__tcfC : $@convention(method) (Builtin.Int2048, @thin Float.Type) -> Float // user: %8 | |
%8 = apply %7(%6, %5) : $@convention(method) (Builtin.Int2048, @thin Float.Type) -> Float // user: %10 | |
%9 = alloc_stack $Float // users: %13, %12, %10 | |
store %8 to [trivial] %9 : $*Float // id: %10 | |
// function_ref Tensor.init(_:) | |
%11 = function_ref @$S10TensorFlow0A0VyACyxGxcfC : $@convention(method) <τ_0_0 where τ_0_0 : AccelerableByTensorFlow> (@in τ_0_0, @thin Tensor<τ_0_0>.Type) -> @owned Tensor<τ_0_0> // user: %12 | |
%12 = apply %11<Float>(%9, %4) : $@convention(method) <τ_0_0 where τ_0_0 : AccelerableByTensorFlow> (@in τ_0_0, @thin Tensor<τ_0_0>.Type) -> @owned Tensor<τ_0_0> // user: %14 | |
dealloc_stack %9 : $*Float // id: %13 | |
store %12 to [init] %3 : $*Tensor<Float> // id: %14 | |
%15 = integer_literal $Builtin.Word, 1 // user: %17 | |
// function_ref _allocateUninitializedArray<A>(_:) | |
%16 = function_ref @$Ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %17 | |
%17 = apply %16<Any>(%15) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // users: %23, %22, %18 | |
%18 = begin_borrow %17 : $(Array<Any>, Builtin.RawPointer) // users: %22, %21, %19 | |
%19 = tuple_extract %18 : $(Array<Any>, Builtin.RawPointer), 0 // user: %20 | |
- %20 = copy_value %19 : $Array<Any> // users: %44, %41 | |
+ %20 = copy_value %19 : $Array<Any> // users: %48, %44 | |
%21 = tuple_extract %18 : $(Array<Any>, Builtin.RawPointer), 1 // user: %24 | |
end_borrow %18 from %17 : $(Array<Any>, Builtin.RawPointer), $(Array<Any>, Builtin.RawPointer) // id: %22 | |
destroy_value %17 : $(Array<Any>, Builtin.RawPointer) // id: %23 | |
%24 = pointer_to_address %21 : $Builtin.RawPointer to [strict] $*Any // user: %25 | |
- %25 = init_existential_addr %24 : $*Any, $Tensor<Float> // user: %35 | |
- %26 = metatype $@thin Tensor<Float>.Type // user: %31 | |
- %27 = load_borrow %3 : $*Tensor<Float> // users: %34, %31 | |
- %28 = load_borrow %3 : $*Tensor<Float> // users: %33, %31 | |
- %29 = load_borrow %3 : $*Tensor<Float> // users: %32, %31 | |
- // function_ref static Tensor<>.dfoo(_:originalValue:seed:) | |
- %30 = function_ref @$S10TensorFlow0A0V7crashers7NumericRzrlE4dfoo_13originalValue4seedACyxGAI_A2ItFZ : $@convention(method) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow> (@guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @thin Tensor<τ_0_0>.Type) -> @owned Tensor<τ_0_0> // user: %31 | |
- %31 = apply %30<Float>(%27, %28, %29, %26) : $@convention(method) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow> (@guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @thin Tensor<τ_0_0>.Type) -> @owned Tensor<τ_0_0> // user: %35 | |
- end_borrow %29 from %3 : $Tensor<Float>, $*Tensor<Float> // id: %32 | |
- end_borrow %28 from %3 : $Tensor<Float>, $*Tensor<Float> // id: %33 | |
- end_borrow %27 from %3 : $Tensor<Float>, $*Tensor<Float> // id: %34 | |
- store %31 to [init] %25 : $*Tensor<Float> // id: %35 | |
+ %25 = init_existential_addr %24 : $*Any, $Tensor<Float> // user: %38 | |
+ // function_ref curry thunk of static Tensor<>.dfoo(_:originalValue:seed:) | |
+ %26 = function_ref @$S10TensorFlow0A0V7crashers7NumericRzrlE4dfoo_13originalValue4seedACyxGAI_A2ItFZTc : $@convention(thin) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow> (@thin Tensor<τ_0_0>.Type) -> @owned @callee_guaranteed (@guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>) -> @owned Tensor<τ_0_0> // user: %28 | |
+ %27 = metatype $@thin Tensor<Float>.Type // user: %28 | |
+ %28 = apply %26<Float>(%27) : $@convention(thin) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow> (@thin Tensor<τ_0_0>.Type) -> @owned @callee_guaranteed (@guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>) -> @owned Tensor<τ_0_0> // users: %47, %34, %32 | |
+ %29 = load_borrow %3 : $*Tensor<Float> // users: %37, %33 | |
+ %30 = load_borrow %3 : $*Tensor<Float> // users: %36, %33 | |
+ %31 = load_borrow %3 : $*Tensor<Float> // users: %35, %33 | |
+ %32 = begin_borrow %28 : $@callee_guaranteed (@guaranteed Tensor<Float>, @guaranteed Tensor<Float>, @guaranteed Tensor<Float>) -> @owned Tensor<Float> // users: %34, %33 | |
+ %33 = apply %32(%29, %30, %31) : $@callee_guaranteed (@guaranteed Tensor<Float>, @guaranteed Tensor<Float>, @guaranteed Tensor<Float>) -> @owned Tensor<Float> // user: %38 | |
+ end_borrow %32 from %28 : $@callee_guaranteed (@guaranteed Tensor<Float>, @guaranteed Tensor<Float>, @guaranteed Tensor<Float>) -> @owned Tensor<Float>, $@callee_guaranteed (@guaranteed Tensor<Float>, @guaranteed Tensor<Float>, @guaranteed Tensor<Float>) -> @owned Tensor<Float> // id: %34 | |
+ end_borrow %31 from %3 : $Tensor<Float>, $*Tensor<Float> // id: %35 | |
+ end_borrow %30 from %3 : $Tensor<Float>, $*Tensor<Float> // id: %36 | |
+ end_borrow %29 from %3 : $Tensor<Float>, $*Tensor<Float> // id: %37 | |
+ store %33 to [init] %25 : $*Tensor<Float> // id: %38 | |
// function_ref default argument 1 of print(_:separator:terminator:) | |
- %36 = function_ref @$Ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %37 | |
- %37 = apply %36() : $@convention(thin) () -> @owned String // users: %43, %41 | |
+ %39 = function_ref @$Ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %40 | |
+ %40 = apply %39() : $@convention(thin) () -> @owned String // users: %46, %44 | |
// function_ref default argument 2 of print(_:separator:terminator:) | |
- %38 = function_ref @$Ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %39 | |
- %39 = apply %38() : $@convention(thin) () -> @owned String // users: %42, %41 | |
+ %41 = function_ref @$Ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %42 | |
+ %42 = apply %41() : $@convention(thin) () -> @owned String // users: %45, %44 | |
// function_ref print(_:separator:terminator:) | |
- %40 = function_ref @$Ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () // user: %41 | |
- %41 = apply %40(%20, %37, %39) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () | |
- destroy_value %39 : $String // id: %42 | |
- destroy_value %37 : $String // id: %43 | |
- destroy_value %20 : $Array<Any> // id: %44 | |
- %45 = integer_literal $Builtin.Int32, 0 // user: %46 | |
- %46 = struct $Int32 (%45 : $Builtin.Int32) // user: %47 | |
- return %46 : $Int32 // id: %47 | |
+ %43 = function_ref @$Ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () // user: %44 | |
+ %44 = apply %43(%20, %40, %42) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () | |
+ destroy_value %42 : $String // id: %45 | |
+ destroy_value %40 : $String // id: %46 | |
+ destroy_value %28 : $@callee_guaranteed (@guaranteed Tensor<Float>, @guaranteed Tensor<Float>, @guaranteed Tensor<Float>) -> @owned Tensor<Float> // id: %47 | |
+ destroy_value %20 : $Array<Any> // id: %48 | |
+ %49 = integer_literal $Builtin.Int32, 0 // user: %50 | |
+ %50 = struct $Int32 (%49 : $Builtin.Int32) // user: %51 | |
+ return %50 : $Int32 // id: %51 | |
} // end sil function 'main' | |
// static Tensor<>.foo(_:) | |
sil hidden [reverse_differentiable source 0 wrt 0 primal @$S10TensorFlow0A0V7crashers7NumericRzrlE3fooyACyxGAGFZ adjoint @$S10TensorFlow0A0V7crashers7NumericRzrlE4dfoo_13originalValue4seedACyxGAI_A2ItFZ] @$S10TensorFlow0A0V7crashers7NumericRzrlE3fooyACyxGAGFZ : $@convention(method) <Scalar where Scalar : Numeric, Scalar : AccelerableByTensorFlow> (@guaranteed Tensor<Scalar>, @thin Tensor<Scalar>.Type) -> @owned Tensor<Scalar> { | |
// %0 // users: %4, %2 | |
// %1 // user: %3 | |
bb0(%0 : $Tensor<Scalar>, %1 : $@thin Tensor<Scalar>.Type): | |
debug_value %0 : $Tensor<Scalar>, let, name "x", argno 1 // id: %2 | |
debug_value %1 : $@thin Tensor<Scalar>.Type, let, name "self", argno 2 // id: %3 | |
%4 = copy_value %0 : $Tensor<Scalar> // user: %5 | |
return %4 : $Tensor<Scalar> // id: %5 | |
} // end sil function '$S10TensorFlow0A0V7crashers7NumericRzrlE3fooyACyxGAGFZ' | |
// static Tensor<>.dfoo(_:originalValue:seed:) | |
sil hidden @$S10TensorFlow0A0V7crashers7NumericRzrlE4dfoo_13originalValue4seedACyxGAI_A2ItFZ : $@convention(method) <Scalar where Scalar : Numeric, Scalar : AccelerableByTensorFlow> (@guaranteed Tensor<Scalar>, @guaranteed Tensor<Scalar>, @guaranteed Tensor<Scalar>, @thin Tensor<Scalar>.Type) -> @owned Tensor<Scalar> { | |
// %0 // users: %9, %4 | |
// %1 // user: %5 | |
// %2 // users: %9, %6 | |
// %3 // user: %7 | |
bb0(%0 : $Tensor<Scalar>, %1 : $Tensor<Scalar>, %2 : $Tensor<Scalar>, %3 : $@thin Tensor<Scalar>.Type): | |
debug_value %0 : $Tensor<Scalar>, let, name "x", argno 1 // id: %4 | |
debug_value %1 : $Tensor<Scalar>, let, name "originalValue", argno 2 // id: %5 | |
debug_value %2 : $Tensor<Scalar>, let, name "seed", argno 3 // id: %6 | |
debug_value %3 : $@thin Tensor<Scalar>.Type, let, name "self", argno 4 // id: %7 | |
// function_ref Tensor<>.unbroadcast<A>(like:) | |
%8 = function_ref @$S10TensorFlow0A0VAAs7NumericRzrlE11unbroadcast4likeACyxGACyqd__G_tAA013AccelerableByaB0Rd__lF : $@convention(method) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow><τ_1_0 where τ_1_0 : AccelerableByTensorFlow> (@guaranteed Tensor<τ_1_0>, @guaranteed Tensor<τ_0_0>) -> @owned Tensor<τ_0_0> // user: %9 | |
%9 = apply %8<Scalar, Scalar>(%0, %2) : $@convention(method) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow><τ_1_0 where τ_1_0 : AccelerableByTensorFlow> (@guaranteed Tensor<τ_1_0>, @guaranteed Tensor<τ_0_0>) -> @owned Tensor<τ_0_0> // user: %10 | |
return %9 : $Tensor<Scalar> // id: %10 | |
} // end sil function '$S10TensorFlow0A0V7crashers7NumericRzrlE4dfoo_13originalValue4seedACyxGAI_A2ItFZ' | |
// Tensor<>.unbroadcast<A>(like:) | |
sil [serialized] [always_inline] @$S10TensorFlow0A0VAAs7NumericRzrlE11unbroadcast4likeACyxGACyqd__G_tAA013AccelerableByaB0Rd__lF : $@convention(method) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow><τ_1_0 where τ_1_0 : AccelerableByTensorFlow> (@guaranteed Tensor<τ_1_0>, @guaranteed Tensor<τ_0_0>) -> @owned Tensor<τ_0_0> | |
// Float.init(_builtinIntegerLiteral:) | |
sil [transparent] [serialized] @$SSf22_builtinIntegerLiteralSfBi2048__tcfC : $@convention(method) (Builtin.Int2048, @thin Float.Type) -> Float | |
// Tensor.init(_:) | |
sil [serialized] [always_inline] @$S10TensorFlow0A0VyACyxGxcfC : $@convention(method) <τ_0_0 where τ_0_0 : AccelerableByTensorFlow> (@in τ_0_0, @thin Tensor<τ_0_0>.Type) -> @owned Tensor<τ_0_0> | |
// _allocateUninitializedArray<A>(_:) | |
sil [serialized] [always_inline] @$Ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) | |
+// curry thunk of static Tensor<>.dfoo(_:originalValue:seed:) | |
+sil shared [thunk] @$S10TensorFlow0A0V7crashers7NumericRzrlE4dfoo_13originalValue4seedACyxGAI_A2ItFZTc : $@convention(thin) <Scalar where Scalar : Numeric, Scalar : AccelerableByTensorFlow> (@thin Tensor<Scalar>.Type) -> @owned @callee_guaranteed (@guaranteed Tensor<Scalar>, @guaranteed Tensor<Scalar>, @guaranteed Tensor<Scalar>) -> @owned Tensor<Scalar> { | |
+// %0 // user: %2 | |
+bb0(%0 : $@thin Tensor<Scalar>.Type): | |
+ // function_ref static Tensor<>.dfoo(_:originalValue:seed:) | |
+ %1 = function_ref @$S10TensorFlow0A0V7crashers7NumericRzrlE4dfoo_13originalValue4seedACyxGAI_A2ItFZ : $@convention(method) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow> (@guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @thin Tensor<τ_0_0>.Type) -> @owned Tensor<τ_0_0> // user: %2 | |
+ %2 = partial_apply [callee_guaranteed] %1<Scalar>(%0) : $@convention(method) <τ_0_0 where τ_0_0 : Numeric, τ_0_0 : AccelerableByTensorFlow> (@guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @guaranteed Tensor<τ_0_0>, @thin Tensor<τ_0_0>.Type) -> @owned Tensor<τ_0_0> // user: %3 | |
+ return %2 : $@callee_guaranteed (@guaranteed Tensor<Scalar>, @guaranteed Tensor<Scalar>, @guaranteed Tensor<Scalar>) -> @owned Tensor<Scalar> // id: %3 | |
+} // end sil function '$S10TensorFlow0A0V7crashers7NumericRzrlE4dfoo_13originalValue4seedACyxGAI_A2ItFZTc' | |
+ | |
// default argument 1 of print(_:separator:terminator:) | |
sil [noinline] @$Ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String | |
// default argument 2 of print(_:separator:terminator:) | |
sil [noinline] @$Ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String | |
// print(_:separator:terminator:) | |
sil [noinline] @$Ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () |
import TensorFlow | |
extension Tensor where Scalar : Numeric { | |
@differentiable(reverse, adjoint: dfoo) | |
static func foo(_ x: Tensor) -> Tensor { | |
return x | |
} | |
static func dfoo( | |
_ x: Tensor, originalValue: Tensor, seed: Tensor | |
) -> Tensor { | |
return seed.unbroadcast(like: x) | |
} | |
} | |
let x = Tensor<Float>(1) | |
// Line 1: This works. | |
// print(Tensor<Float>.dfoo(x, originalValue: x, seed: x)) | |
// Line 2: This crashes when uncommented. | |
print(#adjoint(Tensor<Float>.foo)(x, originalValue: x, seed: x)) |