swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.49k stars 10.35k forks source link

[SR-13325] No way to express conditional differentiability of function parameters based on that of generic parameter #55765

Open dabrahams opened 4 years ago

dabrahams commented 4 years ago
Previous ID SR-13325
Radar None
Original Reporter @dabrahams
Type Bug
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Swift for TensorFlow | |Labels | Bug, AutoDiff | |Assignee | None | |Priority | Medium | md5: 2bdd7e64a6b7e0424705c091ca000b07

Issue Description:

This method won't compile:

  /// Calls `updateElement(&myX, aX)` on each pair of corresponding elements `myX` and `aX` of
  /// `self` and `a`, using `combine` (if supplied) to initialize new storage when required.
  ///
  /// - Requires: `self.count == a.count`
  @differentiable(wrt: (self, a) where Element: Differentiable, E: Differentiable)
  mutating func update<E>(
    elementwiseWith a: ArrayBuffer<E>,
    _ updateElement: @differentiable (_ myX: inout Element, _ aX: E)->Void,
    _ combine: Optional<@differentiable (_ a0x: Element, _ a1x: E)->Element> = nil
  ) { fatalError() }

The fundamental limitation is that we have no way to say thats updateElement and combine are @differentiable(where: Element: Differentiable, E: Differentiable) (that's a syntax error).

rxwei commented 4 years ago

This is a limitation of the @differentiable function type attribute. Supporting a where-clause within a function type attribute may involve a non-trivial implementation given that there's no precedence of function type attributes containing generic constraints and because @differentiable/@differentiable(linear) is currently just a two-bit flag in AnyFunctionType::ExtInfo. Besides the potential implementation difficulty, function types with such constraints could be long and difficult to read:

@differentiable(where Element: Differentiable, E: Differentiable) (_ myX: inout Element, _ aX: E) -> Void

Have you tried defining additional update(elementwiseWith::🙂 overloads with more specific generic requirements such that the most specific one will win in overload resolution? What's the specific use case of this method?

theblixguy commented 4 years ago

@rxwei @_specialize supports where clauses so it should be possible to extract some code and reuse here, if you decide to go with this.

rxwei commented 4 years ago

@theblixguy If I remember correctly, @_specialize is a DeclAttr. And we did port @_specialize's support for where-clauses to the @differentiable declaration attribute, but this issue in this radar is mainly about the @differentiable function type attribute like @convention. Are you saying there also exists a @_specialize function type attribute today?

theblixguy commented 4 years ago

Oh, I see. Sorry, I overlooked the “function type” bit. I don’t think we have any function type attributes with where clauses at the moment. I suppose it should still be relatively straightforward to parse the where clause in such a context (with possibility to share code) but I haven’t given it much thought.

rxwei commented 4 years ago

@theblixguy Thanks for the pointer!