Skip to content

Instantly share code, notes, and snippets.

@dan-zheng
Last active June 23, 2018 02:49
Show Gist options
  • Save dan-zheng/d06f9e0275f9034b2ae3781195f14c09 to your computer and use it in GitHub Desktop.
Save dan-zheng/d06f9e0275f9034b2ae3781195f14c09 to your computer and use it in GitHub Desktop.
#adjoint expression crasher (https://bugs.swift.org/browse/SR-8087)

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))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment